From 2b3a3be0d3b7d3a8c9a734bb61535309c01afd8a Mon Sep 17 00:00:00 2001 From: Fabian Hertwig Date: Sat, 24 May 2014 13:03:46 +0200 Subject: [PATCH] Added the possibility to change the base color of the mood blobs over time. The base Color is moved 1 degree in baseColorChangeRate seconds if activated. It is moved between baseColorRangeLeft and baseColorRangeRight. These Values are in degrees. When these borders are set to the full circle (eg. 0 and 360), the base color moves around the colorwheel, otherwise it moves from left to right and back again. Furthermore there are three effects script for this feature: "Full color mood blobs" which moves around the full circle, "Warm mood blobs" and "Cold mood blobs" which only shows the warm, cold colors. This update wont change the functionality of the old scripts. Former-commit-id: 0c7a2ad280e49cd1ac0d6a9fbc9d1a9ff0eea236 --- effects/mood-blobs-cold.json | 16 +++++++ effects/mood-blobs-full.json | 16 +++++++ effects/mood-blobs-warm.json | 16 +++++++ effects/mood-blobs.py | 93 ++++++++++++++++++++++++++++-------- 4 files changed, 121 insertions(+), 20 deletions(-) create mode 100644 effects/mood-blobs-cold.json create mode 100644 effects/mood-blobs-full.json create mode 100644 effects/mood-blobs-warm.json diff --git a/effects/mood-blobs-cold.json b/effects/mood-blobs-cold.json new file mode 100644 index 00000000..d259b9f1 --- /dev/null +++ b/effects/mood-blobs-cold.json @@ -0,0 +1,16 @@ +{ + "name" : "Cold mood blobs", + "script" : "mood-blobs.py", + "args" : + { + "rotationTime" : 60.0, + "color" : [0,0,255], + "hueChange" : 30.0, + "blobs" : 5, + "reverse" : false, + "baseChange" : true, + "baseColorRangeLeft" : 160, + "baseColorRangeRight" : 320, + "baseColorChangeRate" : 2.0 + } +} diff --git a/effects/mood-blobs-full.json b/effects/mood-blobs-full.json new file mode 100644 index 00000000..8b230010 --- /dev/null +++ b/effects/mood-blobs-full.json @@ -0,0 +1,16 @@ +{ + "name" : "Full color mood blobs", + "script" : "mood-blobs.py", + "args" : + { + "rotationTime" : 60.0, + "color" : [0,0,255], + "hueChange" : 30.0, + "blobs" : 5, + "reverse" : false, + "baseChange" : true, + "baseColorRangeLeft" : 0, + "baseColorRangeRight" : 360, + "baseColorChangeRate" : 0.2 + } +} diff --git a/effects/mood-blobs-warm.json b/effects/mood-blobs-warm.json new file mode 100644 index 00000000..39443092 --- /dev/null +++ b/effects/mood-blobs-warm.json @@ -0,0 +1,16 @@ +{ + "name" : "Warm mood blobs", + "script" : "mood-blobs.py", + "args" : + { + "rotationTime" : 60.0, + "color" : [255,0,0], + "hueChange" : 30.0, + "blobs" : 5, + "reverse" : false, + "baseChange" : true, + "baseColorRangeLeft" : 333, + "baseColorRangeRight" : 151, + "baseColorChangeRate" : 2.0 + } +} diff --git a/effects/mood-blobs.py b/effects/mood-blobs.py index c0ce3d15..b638f3d3 100644 --- a/effects/mood-blobs.py +++ b/effects/mood-blobs.py @@ -6,14 +6,31 @@ import math # Get the parameters rotationTime = float(hyperion.args.get('rotationTime', 20.0)) color = hyperion.args.get('color', (0,0,255)) -hueChange = float(hyperion.args.get('hueChange', 60.0)) / 360.0 +hueChange = float(hyperion.args.get('hueChange', 60.0)) blobs = int(hyperion.args.get('blobs', 5)) reverse = bool(hyperion.args.get('reverse', False)) +baseColorChange = bool(hyperion.args.get('baseChange', False)) +baseColorRangeLeft = float(hyperion.args.get('baseColorRangeLeft',0.0)) # Degree +baseColorRangeRight = float(hyperion.args.get('baseColorRangeRight',360.0)) # Degree +baseColorChangeRate = float(hyperion.args.get('baseColorChangeRate',10.0)) # Seconds for one Degree + +# switch baseColor change off if left and right are too close together to see a difference in color +if (baseColorRangeRight > baseColorRangeLeft and (baseColorRangeRight - baseColorRangeLeft) < 10) or \ + (baseColorRangeLeft > baseColorRangeRight and ((baseColorRangeRight + 360) - baseColorRangeLeft) < 10): + baseColorChange = False + +# 360 -> 1 +fullColorWheelAvailable = (baseColorRangeRight % 360) == (baseColorRangeLeft % 360) +baseColorChangeIncreaseValue = 1.0 / 360.0 # 1 degree +hueChange /= 360.0 +baseColorRangeLeft = (baseColorRangeLeft / 360.0) +baseColorRangeRight = (baseColorRangeRight / 360.0) # Check parameters rotationTime = max(0.1, rotationTime) hueChange = max(0.0, min(abs(hueChange), .5)) blobs = max(1, blobs) +baseColorChangeRate = max(0, baseColorChangeRate) # > 0 # Calculate the color data baseHsv = colorsys.rgb_to_hsv(color[0]/255.0, color[1]/255.0, color[2]/255.0) @@ -27,6 +44,7 @@ for i in range(hyperion.ledCount): sleepTime = 0.1 amplitudePhaseIncrement = blobs * math.pi * sleepTime / rotationTime colorDataIncrement = 3 +baseColorChangeRate /= sleepTime # Switch direction if needed if reverse: @@ -39,23 +57,58 @@ colors = bytearray(hyperion.ledCount * (0,0,0)) # Start the write data loop amplitudePhase = 0.0 rotateColors = False -while not hyperion.abort(): - # Calculate new colors - for i in range(hyperion.ledCount): - amplitude = max(0.0, math.sin(-amplitudePhase + 2*math.pi * blobs * i / hyperion.ledCount)) - colors[3*i+0] = int(colorData[3*i+0] * amplitude) - colors[3*i+1] = int(colorData[3*i+1] * amplitude) - colors[3*i+2] = int(colorData[3*i+2] * amplitude) +baseColorChangeStepCount = 0 +baseHSVValue = baseHsv[0] +numberOfRotates = 0 - # set colors - hyperion.setColor(colors) - - # increment the phase - amplitudePhase = (amplitudePhase + amplitudePhaseIncrement) % (2*math.pi) - - if rotateColors: - colorData = colorData[-colorDataIncrement:] + colorData[:-colorDataIncrement] - rotateColors = not rotateColors - - # sleep for a while - time.sleep(sleepTime) +while not hyperion.abort(): + + # move the basecolor + if baseColorChange: + # every baseColorChangeRate seconds + if baseColorChangeStepCount >= baseColorChangeRate: + baseColorChangeStepCount = 0 + # cyclic increment when the full colorwheel is available, move up and down otherwise + if fullColorWheelAvailable: + baseHSVValue = (baseHSVValue + baseColorChangeIncreaseValue) % baseColorRangeRight + else: + # switch increment direction if baseHSV <= left or baseHSV >= right + if baseColorChangeIncreaseValue < 0 and baseHSVValue > baseColorRangeLeft and (baseHSVValue + baseColorChangeIncreaseValue) <= baseColorRangeLeft: + baseColorChangeIncreaseValue = abs(baseColorChangeIncreaseValue) + elif baseColorChangeIncreaseValue > 0 and baseHSVValue < baseColorRangeRight and (baseHSVValue + baseColorChangeIncreaseValue) >= baseColorRangeRight : + baseColorChangeIncreaseValue = -abs(baseColorChangeIncreaseValue) + + baseHSVValue = (baseHSVValue + baseColorChangeIncreaseValue) % 1.0 + + # update color values + colorData = bytearray() + for i in range(hyperion.ledCount): + hue = (baseHSVValue + hueChange * math.sin(2*math.pi * i / hyperion.ledCount)) % 1.0 + rgb = colorsys.hsv_to_rgb(hue, baseHsv[1], baseHsv[2]) + colorData += bytearray((int(255*rgb[0]), int(255*rgb[1]), int(255*rgb[2]))) + + # set correct rotation after reinitialisation of the array + colorData = colorData[-colorDataIncrement*numberOfRotates:] + colorData[:-colorDataIncrement*numberOfRotates] + + baseColorChangeStepCount += 1 + + # Calculate new colors + for i in range(hyperion.ledCount): + amplitude = max(0.0, math.sin(-amplitudePhase + 2*math.pi * blobs * i / hyperion.ledCount)) + colors[3*i+0] = int(colorData[3*i+0] * amplitude) + colors[3*i+1] = int(colorData[3*i+1] * amplitude) + colors[3*i+2] = int(colorData[3*i+2] * amplitude) + + # set colors + hyperion.setColor(colors) + + # increment the phase + amplitudePhase = (amplitudePhase + amplitudePhaseIncrement) % (2*math.pi) + + if rotateColors: + colorData = colorData[-colorDataIncrement:] + colorData[:-colorDataIncrement] + numberOfRotates = (numberOfRotates + 1) % hyperion.ledCount + rotateColors = not rotateColors + + # sleep for a while + time.sleep(sleepTime)