Compare commits

..

1 commit

Author SHA1 Message Date
djerun
92adc6ea9b [hotfix] disable trap for photosensitive creatures 2024-07-29 22:36:15 +02:00
7 changed files with 42 additions and 102 deletions

View file

@ -48,9 +48,9 @@ class RandomSingle(Animation):
by Max & Lightmoll (https://lght.ml) by Max & Lightmoll (https://lght.ml)
from 2022-06-08 from 2022-06-08
""" """
def __init__(self, color): def __init__(self, color, looptime=60):
super().__init__() super().__init__()
self.PERIOD = 4 * 30 #frames self.PERIOD = looptime * 30 #frames
self.color = self._rand_color() self.color = self._rand_color()
self.last_colors = [] self.last_colors = []
self.frame_counter = 0 self.frame_counter = 0
@ -92,10 +92,10 @@ class TwoColor(Steady):
by Max & Lightmoll (https://lght.ml) by Max & Lightmoll (https://lght.ml)
from 2022-06-08 from 2022-06-08
""" """
def __init__(self, color): def __init__(self, color, looptime=60):
super().__init__(color) super().__init__(color)
self.start_time = time() self.start_time = time()
self.PERIOD = 0.5 #s self.PERIOD = looptime * 0.5 #s
self.COL_1 = color #input color self.COL_1 = color #input color
self.COL_2 = (255-self.r, 255-self.g, 255-self.b) #compl. color self.COL_2 = (255-self.r, 255-self.g, 255-self.b) #compl. color
@ -120,7 +120,6 @@ class TwoColor(Steady):
def name(self): def name(self):
return str(self) return str(self)
class Caramelldansen(Steady): class Caramelldansen(Steady):
""" """
by Max & Lightmoll (https://lght.ml) by Max & Lightmoll (https://lght.ml)
@ -175,7 +174,7 @@ class Caramelldansen(Steady):
class FadeTo(Steady): class FadeTo(Steady):
def __init__(self, color, t=2.0): def __init__(self, color, t=60.0):
super(FadeTo, self).__init__(color) super(FadeTo, self).__init__(color)
self.t = t self.t = t
self.start = time() self.start = time()
@ -193,7 +192,7 @@ class FadeTo(Steady):
class RotatingRainbow(Animation): class RotatingRainbow(Animation):
def __init__(self, looptime=50.0): def __init__(self, looptime=60.0):
super(RotatingRainbow, self).__init__() super(RotatingRainbow, self).__init__()
self.looptime = looptime self.looptime = looptime
pass pass
@ -217,7 +216,7 @@ class RotatingRainbow(Animation):
class Chase(Steady): class Chase(Steady):
def __init__(self, color, looptime=1.0): def __init__(self, color, looptime=60.0):
super(Chase, self).__init__(color) super(Chase, self).__init__(color)
self.looptime = looptime self.looptime = looptime
@ -234,34 +233,9 @@ class Chase(Steady):
return "chase" return "chase"
class Hackertours(Steady): class ChaseRandom(Animation):
""" def __init__(self, color, looptime=60.0):
Base color yellow, with green wandering back and forth super(Chase, self).__init__(color)
"""
def __init__(self, color, base=(255,223,0), looptime=4.0):
super(Hackertours, self).__init__(color)
self.looptime = looptime
self.base = base
def update(self, index, count):
# angle is the position of the highlight on a circle, range [0, 1]
angle = (time() / self.looptime + (index + 0.0) / count) % 1.0
l = 1 - min(abs(angle - 1 / count) * .9, 1.0 / count) * count
return (
int(self.r * l + self.base[0] * (1-l)),
int(self.g * l + self.base[1] * (1-l)),
int(self.b * l + self.base[2] * (1-l)))
def __str__(self):
return f"{type(self).__name__}({self.r}, {self.g}, {self.b}, {self.looptime:.2f})"
def name(self):
return "hackertours"
class ChaseRandom(Steady):
def __init__(self, color, looptime=1.0):
super(ChaseRandom, self).__init__(color)
self.looptime = looptime self.looptime = looptime
def update(self, index, count): def update(self, index, count):
@ -282,4 +256,4 @@ def hsv_to_rgb(h, s, v):
return [int(r * 255), int(g * 255), int(b * 255)] return [int(r * 255), int(g * 255), int(b * 255)]
def rgb_to_hsv(r, g, b): def rgb_to_hsv(r, g, b):
return colorsys.rgb_to_hsv(r/255,g/255,b/255) return colorsys.rgb_to_hsv(r/255,g/255,b/255)

31
dmx.py
View file

@ -5,8 +5,7 @@ from threading import Thread
from time import sleep from time import sleep
from typing import Union from typing import Union
from animation import Animation, Off, RandomSingle, Steady, FadeTo, RotatingRainbow, Chase, TwoColor, Caramelldansen, \ from animation import Animation, Off, RandomSingle, Steady, FadeTo, RotatingRainbow, Chase, TwoColor, Caramelldansen
Hackertours
def ledlog(value): def ledlog(value):
@ -21,13 +20,9 @@ class RGB:
def rgb(self, color): def rgb(self, color):
(r, g, b) = color (r, g, b) = color
try: self.dmx.set(self.slot + self.offset + 0, ledlog(r))
self.dmx.set(self.slot + self.offset + 0, ledlog(r)) self.dmx.set(self.slot + self.offset + 1, ledlog(g))
self.dmx.set(self.slot + self.offset + 1, ledlog(g)) self.dmx.set(self.slot + self.offset + 2, ledlog(b))
self.dmx.set(self.slot + self.offset + 2, ledlog(b))
except Exception as e:
print(f'slot={self.slot}, offset={self.offset}')
raise(e)
class Bar252(RGB): class Bar252(RGB):
@ -52,20 +47,6 @@ class StairvilleLedPar56(RGB):
dmx.set(self.slot + 6, 255) dmx.set(self.slot + 6, 255)
class ZhennbyPar(RGB):
def __init__(self, dmx, slot=1):
super(ZhennbyPar, self).__init__(dmx, slot, 1)
dmx.set(self.slot + 0, 255)
dmx.set(self.slot + 4, 0)
dmx.set(self.slot + 5, 0)
dmx.set(self.slot + 6, 0)
class Entec6RGBW(RGB):
def __init__(self, dmx, slot=1):
super(Entec6RGBW, self).__init__(dmx, slot)
class DMX: class DMX:
def __init__(self, host, port=0x1936, universe=1, maxchan=512): def __init__(self, host, port=0x1936, universe=1, maxchan=512):
self._host = host self._host = host
@ -150,8 +131,6 @@ class DMX:
animation = Caramelldansen(self._color) animation = Caramelldansen(self._color)
elif animation == "randomsingle": elif animation == "randomsingle":
animation = RandomSingle(self._color) animation = RandomSingle(self._color)
elif animation == "hackertours":
animation = Hackertours(self._color)
else: else:
raise ValueError(f"No such animation {animation}") raise ValueError(f"No such animation {animation}")
self._animation = animation self._animation = animation
@ -174,5 +153,5 @@ class DMX:
@color.setter @color.setter
def color(self, color): def color(self, color):
if self._color != color: if self._color != color:
self._color = [int(c) for c in color] self._color = color
self.animation = self.animation self.animation = self.animation

View file

@ -7,7 +7,7 @@ from typing import Tuple
from bottle import post, request, route, run, static_file, view from bottle import post, request, route, run, static_file, view
from animation import Off from animation import Off
from dmx import DMX, Bar252, StairvilleLedPar56, REDSpot18RGB, ZhennbyPar, Entec6RGBW from dmx import DMX, Bar252, StairvilleLedPar56, REDSpot18RGB
room = '' room = ''
@ -51,12 +51,10 @@ def main(args):
parser.add_argument('-l', '--listen', type=int, required=False, default=8080, help="TCP port to listen on for web") parser.add_argument('-l', '--listen', type=int, required=False, default=8080, help="TCP port to listen on for web")
parser.add_argument('-r', '--room', type=str, required=True, help="light setup for room: shop or big") parser.add_argument('-r', '--room', type=str, required=True, help="light setup for room: shop or big")
parser.add_argument('-u', '--universe', type=int, required=False, default=1, help="Universe to send to") parser.add_argument('-u', '--universe', type=int, required=False, default=1, help="Universe to send to")
parser.add_argument('-A', '--animation', type=str, required=False, default="off", help="Initial animation")
parser.add_argument('-C', '--color', type=str, required=False, default="255,255,0", help="Initial color")
args = parser.parse_args(args) args = parser.parse_args(args)
print(f"Starting DMX via Art-Net to {args.artnet}", file=sys.stderr) print(f"Starting DMX via Art-Net to {args.artnet}", file=sys.stderr)
dmx = DMX(args.artnet, maxchan=512, universe=args.universe) dmx = DMX(args.artnet, maxchan=128, universe=args.universe)
if args.room == "shop": if args.room == "shop":
dmx._rgbs = [ dmx._rgbs = [
@ -76,22 +74,13 @@ def main(args):
Bar252(dmx, 51), Bar252(dmx, 51),
Bar252(dmx, 62), Bar252(dmx, 62),
] ]
elif args.room == "hackertours":
dmx._rgbs = [
ZhennbyPar(dmx, 1),
ZhennbyPar(dmx, 8),
ZhennbyPar(dmx, 15),
ZhennbyPar(dmx, 22),
]
elif args.room == "defrag":
dmx._rgbs = [Entec6RGBW(dmx, 300 + i*4) for i in range(19)]
else: else:
print(f"Unknown room {args.room}", file=sys.stderr) print(f"Unknown room {args.room}", file=sys.stderr)
sys.exit(64) sys.exit(64)
room = args.room room = args.room
dmx.animation = Off() dmx.animation = Off()
dmx.color = args.color.split(',') dmx.color = (0, 0, 0)
dmx.animation = args.animation dmx.animation = "off"
run(host='0.0.0.0', port=args.listen, reloader=False, debug=True) run(host='0.0.0.0', port=args.listen, reloader=False, debug=True)

View file

@ -1,13 +0,0 @@
[Unit]
Description=Run foobazdmx controller in Hackertours config
[Service]
Type=simple
ExecStart=poetry run python ./foobaz.py -a 127.0.0.1 -r hackertours -A hackertours -C 0,255,32
WorkingDirectory=%h/working/foobazdmx
Restart=on-failure
[Install]
WantedBy=default.target
# link or copy me to ~/.config/systemd/user

17
poetry.lock generated
View file

@ -1,17 +1,18 @@
# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand.
[[package]] [[package]]
name = "bottle" name = "bottle"
version = "0.12.25" version = "0.12.21"
description = "Fast and simple WSGI-framework for small web-applications." description = "Fast and simple WSGI-framework for small web-applications."
category = "main"
optional = false optional = false
python-versions = "*" python-versions = "*"
files = [
{file = "bottle-0.12.25-py3-none-any.whl", hash = "sha256:d6f15f9d422670b7c073d63bd8d287b135388da187a0f3e3c19293626ce034ea"},
{file = "bottle-0.12.25.tar.gz", hash = "sha256:e1a9c94970ae6d710b3fb4526294dfeb86f2cb4a81eff3a4b98dc40fb0e5e021"},
]
[metadata] [metadata]
lock-version = "2.0" lock-version = "1.1"
python-versions = "^3.9" python-versions = "^3.9"
content-hash = "861e3ad9d0b00deb876d2ca7797a608f215c7b91ec9b38f367b24bd096a28478" content-hash = "861e3ad9d0b00deb876d2ca7797a608f215c7b91ec9b38f367b24bd096a28478"
[metadata.files]
bottle = [
{file = "bottle-0.12.21-py3-none-any.whl", hash = "sha256:6e1c9817019dae3a8c20adacaf09035251798d2ae2fcc8ce43157ee72965f257"},
{file = "bottle-0.12.21.tar.gz", hash = "sha256:787c61b6cc02b9c229bf2663011fac53dd8fc197f7f8ad2eeede29d888d7887e"},
]

View file

@ -3,7 +3,6 @@ name = "foobazdmx"
version = "0.1.0" version = "0.1.0"
description = "" description = ""
authors = ["Stefan Bethke <stb@lassitu.de>"] authors = ["Stefan Bethke <stb@lassitu.de>"]
#package-mode = false
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.9" python = "^3.9"

View file

@ -17,13 +17,24 @@
<input type="radio" class="js_animation" name="state" id="animation_white" value="steady"/> <input type="radio" class="js_animation" name="state" id="animation_white" value="steady"/>
<label for="animation_white">Steady</label> <label for="animation_white">Steady</label>
</div> </div>
<div>
<input type="radio" class="js_animation" name="state" id="animation_chase" value="chase"/>
<label for="animation_chase">Chase</label>
</div>
<div> <div>
<input type="radio" class="js_animation" name="state" id="animation_rainbow" value="rainbow"/> <input type="radio" class="js_animation" name="state" id="animation_rainbow" value="rainbow"/>
<label for="animation_rainbow">Rainbow</label> <label for="animation_rainbow">Rainbow</label>
</div> </div>
<div> <div>
<input type="radio" class="js_animation" name="state" id="animation_hackertours" value="hackertours"/> <input type="radio" class="js_animation" name="state" id="animation_randomsingle" value="randomsingle"/>
<label for="animation_hackertours">Hackertours</label> <label for="animation_randomsingle">Random Single</label>
<div>
<input type="radio" class="js_animation" name="state" id="animation_twocolor" value="twocolor"/>
<label for="animation_twocolor">Complementary</label>
</div>
<div>
<input type="radio" class="js_animation" name="state" id="animation_caramelldansen" value="caramelldansen"/>
<label for="animation_caramelldansen">Caramelldansen</label>
</div> </div>
</fieldset> </fieldset>
<fieldset class="colors"> <fieldset class="colors">