Fix file mismatch

This commit is contained in:
Constantin Gierczak--Galle 2023-12-15 11:00:40 +01:00
parent c39f065872
commit 71ce2661a5
2 changed files with 124 additions and 98 deletions

View file

@ -2,7 +2,7 @@
from colour import Color from colour import Color
from .lights import AbstractLight from .lights import AbstractLight
from .reactive import L, RBool, RInt, RList from .reactive import RBool, RColor, RInt, RList
class Strob(AbstractLight): class Strob(AbstractLight):
@ -11,6 +11,12 @@ class Strob(AbstractLight):
dim = RInt(0, 0) dim = RInt(0, 0)
class UVBar(AbstractLight):
address_size = 3
strob = RInt(0, 1)
dim = RInt(0, 0)
class StrobInv(AbstractLight): class StrobInv(AbstractLight):
address_size = 2 address_size = 2
freq = RInt(0, 0) freq = RInt(0, 0)
@ -27,9 +33,7 @@ class Wash(AbstractLight):
pan = RInt(0, 0) pan = RInt(0, 0)
tilt = RInt(0, 1) tilt = RInt(0, 1)
speed = RInt(0, 2) speed = RInt(0, 2)
red = RInt(0, 3) color = RColor(Color("black"), 3)
green = RInt(0, 4)
blue = RInt(0, 5)
white = RInt(0, 6) white = RInt(0, 6)
dimmer = RInt(255, 9) dimmer = RInt(255, 9)
shutter = RBool(True, 10, true_val=b"\x15") shutter = RBool(True, 10, true_val=b"\x15")
@ -43,21 +47,18 @@ class Tradi(AbstractLight):
address_size = 3 address_size = 3
red = RInt(0, 0) color = RColor(Color("black"), 3)
green = RInt(0, 1)
blue = RInt(0, 2)
class ParMiskin(AbstractLight): class ParMKII(AbstractLight):
""" """
Par 56 led Par 56 led
""" """
address_size = 8 address_size = 8
red = RInt(0, 0) color = RColor(Color("black"), 0)
green = RInt(0, 1) amber = RInt(0, 3)
blue = RInt(0, 2)
dimmer = RInt(255, 7) dimmer = RInt(255, 7)
@ -67,10 +68,7 @@ class ParLed(AbstractLight):
""" """
address_size = 7 address_size = 7
color = RColor(Color("black"), 0)
red = RInt(0, 0)
green = RInt(0, 1)
blue = RInt(0, 2)
dimmer = RInt(255, 6) dimmer = RInt(255, 6)
@ -88,8 +86,8 @@ class Blinder(AbstractLight):
[Color(rgb=(0, 0, 0)) for i in range(16)], [Color(rgb=(0, 0, 0)) for i in range(16)],
3, 3,
3, 3,
from_byte=lambda x: Color(f"#{x.hex()}"), from_byte=RColor.from_bytes,
to_byte=lambda x: bytes.fromhex(x.hex_l[1:]), to_byte=RColor.to_bytes,
) )

View file

@ -1,107 +1,135 @@
"""""" """
from colour import Color Module providing class for handling fixtures and generating the appropriate DMX.
"""
from copy import deepcopy
from typing import Any, Callable, Optional, Union
from .lights import AbstractLight from .reactive import BaseReactiveValue, ReactiveMixin
from .reactive import RBool, RColor, RInt, RList from .widget import Widget
class Strob(AbstractLight): class Universe:
address_size = 2 """Represents a DMX universe.
freq = RInt(0, 1)
dim = RInt(0, 0)
Manages the adress space and responsibles for sending DMX to widget when
class UVBar(AbstractLight): `Universe.update_dmx()` is called.
address_size = 3
strob = RInt(0, 1)
dim = RInt(0, 0)
class StrobInv(AbstractLight):
address_size = 2
freq = RInt(0, 0)
dim = RInt(0, 1)
class Wash(AbstractLight):
"""
Wash
""" """
address_size = 14 lights = {}
pan = RInt(0, 0) def __init__(self, widget):
tilt = RInt(0, 1) """
speed = RInt(0, 2) Initializes the Universe
color = RColor(Color("black"), 3)
white = RInt(0, 6) widget must be a class providing `widget.set_dmx(data, address)`
dimmer = RInt(255, 9) """
shutter = RBool(True, 10, true_val=b"\x15") self.widget: Widget = widget
zoom = RInt(0, 11)
def register(self, light: "AbstractLight", address: int) -> None:
"""
Register a light at the specified address
"""
# TODO: add checks for address overlapping
self.lights[light] = address
light.register_universe(self)
light.update_dmx()
def update_dmx(self, light: "AbstractLight", data: Union[bytearray, bytes]) -> None:
"""
Update the dmx data of the specified light
"""
# TODO: add checks for length
self.widget.set_dmx(self.lights[light], data)
class Tradi(AbstractLight): class AbstractLight:
""" """
Tradi RGB Abstract class for lights
""" """
address_size = 3 address_size: int = 0
color = RColor(Color("black"), 3) def __init__(self):
self._universe: Optional[Universe] = None
# The dmx values
self._dmx: bytes = bytearray(self.address_size)
# dmx memory_view to change in O(1) the values
self._dmx_mv = memoryview(self._dmx)
# Dict holdin conversion functions for attr values to dmx:
# { attr_name => (address, length, converter function) }
self._attrs_to_dmx: dict[str, tuple[int, int, Callable[[Any], bytes]]] = {}
class ParMKII(AbstractLight): # List holding conversion functions from dmx bytes to attrs.
""" # [ ( "attr_name", dmx_addr, length, converter function ) ]
Par 56 led self._dmx_to_attrs: list[
""" Optional[tuple[str, int, int, Callable[[bytes], Any]]]
] = [None for _ in range(self.address_size)]
address_size = 8 self._enable_auto_update: bool = False
color = RColor(Color("black"), 0) for key, rValueObject in self.__class__.__dict__.items():
amber = RInt(0, 3) if isinstance(rValueObject, BaseReactiveValue):
dimmer = RInt(255, 7) # On copie la valeur
val = deepcopy(rValueObject.value)
if isinstance(val, ReactiveMixin):
val.light = self
val.key = key
self._attrs_to_dmx[key] = rValueObject.attr_to_dmx()
for i, length, callback in rValueObject.dmx_to_attr():
for k in range(i, i + length):
self._dmx_to_attrs[k] = (key, i, length, callback)
# Finally set the attributes to their value
setattr(self, key, val)
self._enable_auto_update: bool = True
class ParLed(AbstractLight): def register_universe(self, universe: "Universe") -> None:
""" """Assign a universe to this light"""
Par Led Theatre if self._universe is not None:
""" raise ValueError("Can't assign light to more than one universe")
self._universe = universe
address_size = 7 def update_dmx(self) -> None:
color = RColor(Color("black"), 0) """
Method to be called when the DMX values may have changed.
dimmer = RInt(255, 6) This method sends DMX velues to the Universe. It is automatically
triggered by property assignments.
"""
if self._universe is not None and self._enable_auto_update:
self._universe.update_dmx(self, self._dmx)
def __setattr__(self, name: str, value: Any) -> None:
"""
Automatically update dmx when a fixture param is set
"""
self.__dict__[name] = value
if not name.startswith("_"):
self.attr_set_hook(name, value)
class Blinder(AbstractLight): def attr_set_hook(self, name, value):
""" """
Blinder Hook to be called when an attribute is set in order to update DMX
""" values
"""
if name in self._attrs_to_dmx:
# if the attr is linked to dmx, update self._dmx
position, length, converter = self._attrs_to_dmx[name]
self._dmx_mv[position : position + length] = converter(value)
self.update_dmx()
address_size = 51 def __getitem__(self, key) -> bytes:
return self._dmx[key]
dimmer = RInt(255, 1) def __setitem__(self, key: int, value: bytes) -> None:
flash = RInt(0, 2) self._dmx_mv[key : key + 1] = value
colors = RList(
[Color(rgb=(0, 0, 0)) for i in range(16)],
3,
3,
from_byte=RColor.from_bytes,
to_byte=RColor.to_bytes,
)
if self._dmx_to_attrs[key] is not None:
class LedBar48Ch(AbstractLight): attr, position, length, converter = self._dmx_to_attrs[
""" key
Led Bar addressed on 48 channels ] # pyright: ignore
""" self._enable_auto_update = False
setattr(self, attr, converter(self._dmx[position : position + length]))
address_size = 48 self._enable_auto_update = True
self.update_dmx()
colors = RList(
[Color(rgb=(0, 0, 0)) for i in range(16)],
0,
3,
from_byte=lambda x: Color(f"#{x.hex()}"),
to_byte=lambda x: bytes.fromhex(x.hex_l[1:]),
)