disable smoothing for effects (#425)

* no smooth for efx
rework fade effect

* join strobe and fade effects
new effect "breath"

* - make transition efx to smooth mode more smooth
- fixes for pacman
- rework fade base effect - make it more versatile
- fix prios in schema files
- new notify blue effect to demonstrate capability of fade effect
This commit is contained in:
redPanther 2017-03-30 06:20:20 +02:00 committed by GitHub
parent 230c403bba
commit e9040f885d
25 changed files with 271 additions and 133 deletions

View File

@ -602,7 +602,11 @@
"edt_eff_rotationtime_title" : "Rotationszeit",
"edt_eff_sleeptime_title" : "Schlafzeit",
"edt_eff_reversedirection_title" : "Richtung umkehren",
"edt_eff_fadetime_title" : "Übergangszeit",
"edt_eff_fadeintime_title" : "Zeit für Einblendung",
"edt_eff_fadeouttime_title" : "Zeit für Ausblendung",
"edt_eff_repeat_title" : "Wiederholung",
"edt_eff_colorendtime_title" : "Zeit für Start-Farbe",
"edt_eff_colorstarttime_title" : "Zeit für End-Farbe",
"edt_eff_colorstart_title" : "Farbe Start",
"edt_eff_colorend_title" : "Farbe Ende",
"edt_eff_colorshift_title" : "Farbverschiebung",

View File

@ -603,7 +603,11 @@
"edt_eff_rotationtime_title" : "Rotation time",
"edt_eff_sleeptime_title" : "Sleep time",
"edt_eff_reversedirection_title" : "Reverse direction",
"edt_eff_fadetime_title" : "Fade time",
"edt_eff_fadeintime_title" : "Fade in time",
"edt_eff_fadeouttime_title" : "Fade out time",
"edt_eff_repeat_title" : "Repeat",
"edt_eff_colorendtime_title" : "Time to hold start color",
"edt_eff_colorstarttime_title" : "Time to hold end color",
"edt_eff_colorstart_title" : "Color start",
"edt_eff_colorend_title" : "Color end",
"edt_eff_colorshift_title" : "Color Shift",

View File

@ -106,41 +106,53 @@ $(document).ready(function() {
var btn_type = "default";
var btn_text = $.i18n('remote_input_setsource_btn');
var btn_state = "enabled";
if (active) btn_type = "primary";
if (active)
btn_type = "primary";
if(priority > 254)
continue;
if(priority < 254 && (compId == "EFFECT" || compId == "COLOR") )
clearAll = true;
if (visible)
{
btn_state = "disabled";
btn_type = "success";
btn_text = $.i18n('remote_input_sourceactiv_btn');
}
if(ip)
origin += '<br/><span style="font-size:80%; color:grey;">'+$.i18n('remote_input_ip')+' '+ip+'</span>';
if(compId == "EFFECT")
switch (compId)
{
case "EFFECT":
owner = $.i18n('remote_effects_label_effects')+' '+owner;
if(priority != 255)
clearAll = true;
}
if(compId == "COLOR")
{
break;
case "COLOR":
owner = $.i18n('remote_color_label_color')+' '+'<div style="width:18px; height:18px; border-radius:20px; margin-bottom:-4px; border:1px grey solid; background-color: rgb('+prios[i].value.RGB+'); display:inline-block" title="RGB: ('+prios[i].value.RGB+')"></div>';
if(priority != 255)
clearAll = true;
}
if(compId == "GRABBER")
break;
case "GRABBER":
owner = $.i18n('general_comp_GRABBER')+': ('+owner+')';
if(compId == "V4L")
break;
case "V4L":
owner = $.i18n('general_comp_V4L')+': ('+owner+')';
if(compId == "BOBLIGHTSERVER")
break;
case "BOBLIGHTSERVER":
owner = $.i18n('general_comp_BOBLIGHTSERVER');
if(compId == "UDPLISTENER")
break;
case "UDPLISTENER":
owner = $.i18n('general_comp_UDPLISTENER');
break;
}
if(duration && compId != "GRABBER" && compId != "PROTOSERVER")
owner += '<br/><span style="font-size:80%; color:grey;">'+$.i18n('remote_input_duration')+' '+duration.toFixed(0)+$.i18n('edt_append_s')+'</span>';
var btn = '<button id="srcBtn'+i+'" type="button" '+btn_state+' class="btn btn-'+btn_type+' btn_input_selection" onclick="requestSetSource('+priority+');">'+btn_text+'</button>';
if((compId == "EFFECT" || compId == "COLOR") && priority != 255)
if((compId == "EFFECT" || compId == "COLOR") && priority < 254)
btn += '<button type="button" class="btn btn-sm btn-danger" style="margin-left:10px;" onclick="requestPriorityClear('+priority+');"><i class="fa fa-close"></button>';
if(btn_type != 'default')

15
effects/breath.json Normal file
View File

@ -0,0 +1,15 @@
{
"name" : "Breath",
"script" : "fade.py",
"args" :
{
"color-end": [ 255, 255, 255 ],
"color-start": [ 50, 50, 50 ],
"fade-in-time" : 4000,
"fade-out-time" : 1000,
"color-start-time" : 50,
"color-end-time" : 250,
"repeat-count" : 0,
"maintain-end-color" : true
}
}

View File

@ -3,7 +3,7 @@
"script" : "candle.py",
"args" :
{
"sleepTime" : 0.15,
"sleepTime" : 0.20,
"brightness" : 100,
"color" : [ 255, 138, 0 ],
"candles" : "all"

View File

@ -3,8 +3,13 @@
"script" : "fade.py",
"args" :
{
"fade-time" : 5.0,
"color-start" : [ 136, 97, 7 ],
"color-end" : [ 238, 173, 47 ]
"color-end" : [ 238, 173, 47 ],
"fade-in-time" : 5000,
"fade-out-time" : 0,
"color-start-time" : 0,
"color-end-time" : 0,
"repeat-count" : 1,
"maintain-end-color" : true
}
}

View File

@ -3,8 +3,13 @@
"script" : "fade.py",
"args" :
{
"fade-time" : 5.0,
"color-start" : [ 238, 173, 47 ],
"color-end" : [ 136, 97, 7 ]
"color-start" : [ 136, 97, 7 ],
"color-end" : [ 238, 173, 47 ],
"fade-in-time" : 0,
"fade-out-time" : 5000,
"color-start-time" : 0,
"color-end-time" : 0,
"repeat-count" : 1,
"maintain-end-color" : true
}
}

View File

@ -1,27 +1,88 @@
import hyperion, time
# Get the parameters
fadeTime = float(hyperion.args.get('fade-time', 5.0))
fadeInTime = float(hyperion.args.get('fade-in-time', 2000)) / 1000.0
fadeOutTime = float(hyperion.args.get('fade-out-time', 2000)) / 1000.0
colorStart = hyperion.args.get('color-start', (255,174,11))
colorEnd = hyperion.args.get('color-end', (100,100,100))
colorEnd = hyperion.args.get('color-end', (0,0,0))
colorStartTime = float(hyperion.args.get('color-start-time', 1000)) / 1000
colorEndTime = float(hyperion.args.get('color-end-time', 1000)) / 1000
repeat = hyperion.args.get('repeat-count', 0)
maintainEndCol = hyperion.args.get('maintain-end-color', True)
minStepTime = 0.03
currentR = currentG = currentB = 0
# create color table for fading from start to end color
color_step = (
(colorEnd[0] - colorStart[0]) / 256.0,
(colorEnd[1] - colorStart[1]) / 256.0,
(colorEnd[2] - colorStart[2]) / 256.0
)
# fade color
calcChannel = lambda i: min(max(int(colorStart[i] + color_step[i]*step),0),255)
colors = []
for step in range(256):
if hyperion.abort():
break
colors.append( (calcChannel(0),calcChannel(1),calcChannel(2)) )
hyperion.setColor( calcChannel(0),calcChannel(1),calcChannel(2) )
time.sleep( fadeTime / 256 )
# calculate timings
if fadeInTime>0:
incrementIn = max(1,int(round(256.0 / (fadeInTime / minStepTime) )))
sleepTimeIn = fadeInTime / (256.0 / incrementIn)
else:
incrementIn = sleepTimeIn = 1
# maintain color until effect end
hyperion.setColor(colorEnd[0],colorEnd[1],colorEnd[2])
if fadeOutTime>0:
incrementOut = max(1,int(round(256.0 / (fadeOutTime / minStepTime) )))
sleepTimeOut = fadeOutTime / (256.0 / incrementOut)
else:
incrementOut = sleepTimeOut = 1
def setColor(r,g,b):
global currentR,currentG,currentB
currentR = r
currentG = g
currentB = b
hyperion.setColor(r,g,b)
# loop
repeatCounter = 1
while not hyperion.abort():
# fade in
if fadeInTime > 0:
for step in range(0,256,incrementIn):
if hyperion.abort(): break
setColor( colors[step][0],colors[step][1],colors[step][2] )
time.sleep(sleepTimeIn)
# end color
t = 0.0
while t<colorStartTime and not hyperion.abort():
setColor( colors[255][0],colors[255][1],colors[255][2] )
time.sleep(0.01)
t += 0.01
# fade out
if fadeOutTime > 0:
for step in range(255,-1,-incrementOut):
if hyperion.abort(): break
hyperion.setColor( colors[step][0],colors[step][1],colors[step][2] )
time.sleep(sleepTimeOut)
# start color
t = 0.0
while t<colorEndTime and not hyperion.abort():
setColor( colors[0][0],colors[0][1],colors[0][2] )
time.sleep(0.01)
t += 0.01
# repeat
if repeat > 0 and repeatCounter >= repeat : break
repeatCounter += 1
time.sleep(0.5)
# maintain end color until effect end
while not hyperion.abort() and maintainEndCol:
hyperion.setColor( currentR, currentG, currentB )
time.sleep(1)

16
effects/notify-blue.json Normal file
View File

@ -0,0 +1,16 @@
{
"name" : "Notify blue",
"script" : "fade.py",
"args" :
{
"color-start": [ 0, 0, 50 ],
"color-end": [ 0, 0, 255 ],
"fade-in-time" : 200,
"fade-out-time" : 100,
"color-start-time" : 40,
"color-end-time" : 150,
"repeat-count" : 3,
"maintain-end-color" : false
}
}

View File

@ -4,6 +4,6 @@
"args" :
{
"margin-pos" : 2.0,
"rotationTime" : 8
"rotationTime" : 4
}
}

View File

@ -1,11 +1,9 @@
import hyperion
import time
import colorsys
import hyperion, time, colorsys
from random import randint
#get args
rotationTime = int(hyperion.args.get('rotationTime', 8))
marginPos = float(hyperion.args.get('margin-pos', 1.5))
rotationTime = float(hyperion.args.get('rotationTime', 4))
marginPos = float(hyperion.args.get('margin-pos', 2))
# define pacman
pacman = bytearray((255, 255, 0))
@ -23,7 +21,7 @@ background = bytearray((0, 0, 0))
posPac = 1
diffPac = 6*marginPos
diffGuys = 3*marginPos
sleepTime = rotationTime/ledCount
sleepTime = max(0.02,rotationTime/hyperion.ledCount)
posPinkGuy = posPac + diffPac
posBlueGuy = posPinkGuy + diffGuys
@ -92,4 +90,5 @@ while not hyperion.abort():
shift = 3*(hyperion.ledCount - random)
ledData = ledDataChase[shift:]+ledDataChase[:shift]
shiftLED(ledData, -increment, 2*hyperion.ledCount-random)
time.sleep(sleepTime)

View File

@ -4,14 +4,6 @@
"title":"edt_eff_fade_header_title",
"required":true,
"properties":{
"fade-time": {
"type": "number",
"title":"edt_eff_fadetime_title",
"default": 5.0,
"minimum" : 0.1,
"append" : "edt_append_s",
"propertyOrder" : 1
},
"color-start": {
"type": "array",
"title":"edt_eff_colorstart_title",
@ -25,8 +17,24 @@
},
"minItems": 3,
"maxItems": 3,
"propertyOrder" : 1
},
"color-start-time": {
"type": "integer",
"title":"edt_eff_colorstarttime_title",
"default": 1000,
"minimum" : 0,
"append" : "edt_append_ms",
"propertyOrder" : 2
},
"fade-in-time": {
"type": "integer",
"title":"edt_eff_fadeintime_title",
"default": 2000,
"minimum" : 0,
"append" : "edt_append_ms",
"propertyOrder" : 3
},
"color-end": {
"type": "array",
"title":"edt_eff_colorend_title",
@ -39,7 +47,35 @@
},
"minItems": 3,
"maxItems": 3,
"propertyOrder" : 3
"propertyOrder" : 4
},
"color-end-time": {
"type": "integer",
"title":"edt_eff_colorendtime_title",
"default": 1000,
"minimum" : 0,
"append" : "edt_append_ms",
"propertyOrder" : 5
},
"fade-out-time": {
"type": "integer",
"title":"edt_eff_fadeouttime_title",
"default": 2000,
"minimum" : 0,
"append" : "edt_append_ms",
"propertyOrder" : 6
},
"repeat-count": {
"type": "integer",
"title":"edt_eff_repeatcount_title",
"default": 0,
"propertyOrder" : 7
},
"maintain-end-color": {
"type": "boolean",
"title":"edt_eff_maintain_end_color_title",
"default": true,
"propertyOrder" : 8
}
},
"additionalProperties": false

View File

@ -1,31 +0,0 @@
{
"type":"object",
"script" : "strobe.py",
"title":"edt_eff_storbe_header_title",
"required":true,
"properties":{
"color": {
"type": "array",
"title":"edt_eff_color_title",
"format":"colorpicker",
"default": [255,0,0],
"items" : {
"type": "integer",
"minimum": 0,
"maximum": 255
},
"minItems": 3,
"maxItems": 3,
"propertyOrder" : 1
},
"frequency": {
"type": "number",
"title":"edt_eff_frequency_title",
"default": 10.0,
"minimum" : 0.1,
"append" : "edt_append_hz",
"propertyOrder" : 2
}
},
"additionalProperties": false
}

View File

@ -1,9 +0,0 @@
{
"name" : "Strobe blue",
"script" : "strobe.py",
"args" :
{
"color" : [ 0, 0, 255 ],
"frequency" : 5.0
}
}

15
effects/strobe-red.json Normal file
View File

@ -0,0 +1,15 @@
{
"name" : "Strobe red",
"script" : "fade.py",
"args" :
{
"color-start": [ 255, 0, 0 ],
"color-end": [ 0, 0, 0 ],
"fade-in-time" : 100,
"fade-out-time" : 100,
"color-start-time" : 100,
"color-end-time" : 100,
"repeat-count" : 0,
"maintain-end-color" : true
}
}

View File

@ -1,9 +1,15 @@
{
"name" : "Strobe white",
"script" : "strobe.py",
"script" : "fade.py",
"args" :
{
"color" : [ 255, 255, 255 ],
"frequency" : 5.0
"color-start": [ 255, 255, 255 ],
"color-end": [ 0, 0, 0 ],
"fade-in-time" : 0,
"fade-out-time" : 100,
"color-start-time" : 50,
"color-end-time" : 10,
"repeat-count" : 0,
"maintain-end-color" : true
}
}

View File

@ -1,18 +0,0 @@
import hyperion, time
# Get the rotation time
color = hyperion.args.get('color', (255,255,255))
frequency = float(hyperion.args.get('frequency', 10.0))
# Check parameters
frequency = min(100.0, frequency)
# Compute the strobe interval
sleepTime = 0.5 / frequency
# Start the write data loop
while not hyperion.abort():
hyperion.setColor(0, 0, 0)
time.sleep(sleepTime)
hyperion.setColor(color[0], color[1], color[2])
time.sleep(sleepTime)

View File

@ -846,9 +846,12 @@ void Hyperion::update()
// Write the data to the device
if (_device->enabled())
{
if (_deviceSmooth->enabled())
_deviceSmooth->setPause(priorityInfo.componentId == hyperion::COMP_EFFECT);
// feed smoothing in pause mode to maintain a smooth transistion back to smoth mode
if (_deviceSmooth->enabled() || _deviceSmooth->pause())
_deviceSmooth->setLedValues(_ledBuffer);
else
if (! _deviceSmooth->enabled())
_device->setLedValues(_ledBuffer);
}

View File

@ -17,6 +17,7 @@ LinearColorSmoothing::LinearColorSmoothing( LedDevice * ledDevice, double ledUpd
, _outputDelay(updateDelay)
, _writeToLedsEnable(true)
, _continuousOutput(continuousOutput)
, _pause(false)
{
_log = Logger::getInstance("Smoothing");
_timer.setSingleShot(false);
@ -118,7 +119,7 @@ void LinearColorSmoothing::queueColors(const std::vector<ColorRgb> & ledColors)
if (_outputDelay == 0)
{
// No output delay => immediate write
if ( _writeToLedsEnable )
if ( _writeToLedsEnable && !_pause)
_ledDevice->setLedValues(ledColors);
}
else
@ -131,8 +132,11 @@ void LinearColorSmoothing::queueColors(const std::vector<ColorRgb> & ledColors)
if (_outputQueue.size() > 0 )
{
if ( _outputQueue.size() > _outputDelay || !_writeToLedsEnable )
{
if (!_pause)
{
_ledDevice->setLedValues(_outputQueue.front());
}
_outputQueue.pop_front();
}
}
@ -148,6 +152,11 @@ void LinearColorSmoothing::setEnable(bool enable)
{
_timer.stop();
_previousValues.clear();
}
}
void LinearColorSmoothing::setPause(bool pause)
{
_pause = pause;
}
}

View File

@ -41,6 +41,9 @@ public:
virtual int switchOff();
void setEnable(bool enable);
void setPause(bool pause);
bool pause() { return _pause; } ;
bool enabled() { return LedDevice::enabled() && !_pause; };
private slots:
/// Timer callback which writes updated led values to the led device
@ -88,4 +91,7 @@ private:
/// Flag for dis/enable continuous output to led device regardless there is new data or not
bool _continuousOutput;
/// Flag for pausing
bool _pause;
};

View File

@ -78,7 +78,7 @@ void PriorityMuxer::clearAll()
{
for(auto key : _activeInputs.keys())
{
if (key < LOWEST_PRIORITY)
if (key < LOWEST_PRIORITY-1)
{
_activeInputs.remove(key);
}

View File

@ -617,7 +617,7 @@ void JsonClientConnection::handleServerInfoCommand(const QJsonObject&, const QSt
const Hyperion::InputInfo & priorityInfo = _hyperion->getPriorityInfo(priority);
QJsonObject item;
item["priority"] = priority;
if (priorityInfo.timeoutTime_ms != -1 && (priorityInfo.componentId == hyperion::COMP_COLOR || priorityInfo.componentId == hyperion::COMP_EFFECT))
if (priorityInfo.timeoutTime_ms != -1 )
{
item["duration_ms"] = int(priorityInfo.timeoutTime_ms - now);
}

View File

@ -13,7 +13,7 @@
"priority": {
"type": "integer",
"minimum" : 1,
"maximum" : 254,
"maximum" : 253,
"required": true
},
"duration": {

View File

@ -13,7 +13,7 @@
"priority": {
"type": "integer",
"minimum" : 1,
"maximum" : 254,
"maximum" : 253,
"required": true
},
"duration": {

View File

@ -210,7 +210,7 @@ void HyperionDaemon::startInitialEffect()
const QJsonObject & BGEffectConfig = _qconfig["backgroundEffect"].toObject();
const int FG_PRIORITY = 0;
const int DURATION_INFINITY = 0;
const int BG_PRIORITY = PriorityMuxer::LOWEST_PRIORITY;
const int BG_PRIORITY = PriorityMuxer::LOWEST_PRIORITY-1;
// clear the leds
hyperion->setColor(FG_PRIORITY, ColorRgb::BLACK, 100, false);