From f4f545820977373aa7663a3eac7b35346ed7a19f Mon Sep 17 00:00:00 2001 From: Stefan Bethke Date: Sat, 23 Jul 2022 17:47:19 +0200 Subject: [PATCH] Allow None animation, stopping the update thread --- dmx.py | 62 ++++++++++++++++++++++++++++++++++--------------------- foobaz.py | 2 +- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/dmx.py b/dmx.py index 984ad19..758fbce 100644 --- a/dmx.py +++ b/dmx.py @@ -12,7 +12,7 @@ def hsv_to_rgb(h, s, v): def ledlog(value): - return int(pow(float(value)/255.0, 2)*255) + return int(pow(float(value) / 255.0, 2) * 255) class RGB: @@ -23,30 +23,31 @@ class RGB: def rgb(self, color): (r, g, b) = color - 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+2, ledlog(b)) + 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 + 2, ledlog(b)) + class Bar252(RGB): def __init__(self, dmx, slot=1): super(Bar252, self).__init__(dmx, slot, 2) - dmx.set(self.slot+0, 81) - dmx.set(self.slot+1, 0) + dmx.set(self.slot + 0, 81) + dmx.set(self.slot + 1, 0) class REDSpot18RGB(RGB): def __init__(self, dmx, slot=1): super(REDSpot18RGB, self).__init__(dmx, slot, 1) - dmx.set(self.slot+0, 0) + dmx.set(self.slot + 0, 0) class StairvilleLedPar56(RGB): def __init__(self, dmx, slot=1): super(StairvilleLedPar56, self).__init__(dmx, slot, 0) - dmx.set(self.slot+3, 0) - dmx.set(self.slot+4, 0) - dmx.set(self.slot+5, 0) - dmx.set(self.slot+6, 255) + dmx.set(self.slot + 3, 0) + dmx.set(self.slot + 4, 0) + dmx.set(self.slot + 5, 0) + dmx.set(self.slot + 6, 255) class Steady: @@ -122,7 +123,7 @@ class DMX: self.data = bytearray(maxchan) packet = bytearray() packet.extend(map(ord, "Art-Net")) - packet.append(0x00) # Null terminate Art-Net + packet.append(0x00) # Null terminate Art-Net packet.extend([0x00, 0x50]) # Opcode ArtDMX 0x5000 (Little endian) packet.extend([0x00, 0x0e]) # Protocol version 14 self.header = packet @@ -130,30 +131,35 @@ class DMX: self.animation = FadeTo(255, 255, 255) self.rgbs = [] self.thread = None + self.updating = False def start(self): if self.thread and self.thread.is_alive(): return self.thread = Thread(daemon=True, target=self.background) + self.updating = True self.thread.start() def background(self): - while True: - animation = self.animation - for i in range(0, len(self.rgbs)): - self.rgbs[i].rgb(animation.update(i, len(self.rgbs))) + while self.updating: self.update() # print("updating") # print(self.data) # break - sleep(1.0/30) + sleep(1.0 / 30) def update(self): + if not self.animation: + return + + for i in range(0, len(self.rgbs)): + self.rgbs[i].rgb(self.animation.update(i, len(self.rgbs))) + packet = self.header[:] - packet.append(self.sequence) # Sequence, - packet.append(0x00) # Physical - packet.append(self.universe & 0xFF) # Universe LowByte - packet.append(self.universe >> 8 & 0xFF) # Universe HighByte + packet.append(self.sequence) # Sequence, + packet.append(0x00) # Physical + packet.append(self.universe & 0xFF) # Universe LowByte + packet.append(self.universe >> 8 & 0xFF) # Universe HighByte packet.extend(struct.pack('>h', len(self.data))) # Pack the number of channels Big endian packet.extend(self.data) @@ -165,8 +171,16 @@ class DMX: self.sequence = 1 def set(self, slot, value): - self.data[slot-1] = value + self.data[slot - 1] = value def setAnimation(self, animation): - self.animation = animation - print(f"Animation: {animation}", file=sys.stderr) \ No newline at end of file + if not animation: + self.updating = False + self.thread.join() + # one frame black + self.animation = Steady(0, 0, 0) + self.update() + else: + self.animation = animation + self.start() + print(f"Animation: {animation}", file=sys.stderr) diff --git a/foobaz.py b/foobaz.py index ebdc450..0f86e4c 100644 --- a/foobaz.py +++ b/foobaz.py @@ -20,7 +20,7 @@ def static(path): @route('/api/state/') def update(state): if state == "off": - dmx.setAnimation(Steady(0, 0, 0)) + dmx.setAnimation(None) elif state == "white": dmx.setAnimation(Steady(255, 255, 255)) elif state == "red":