diff options
Diffstat (limited to 'topology.py')
-rw-r--r-- | topology.py | 135 |
1 files changed, 0 insertions, 135 deletions
diff --git a/topology.py b/topology.py deleted file mode 100644 index 331c4e2..0000000 --- a/topology.py +++ /dev/null @@ -1,135 +0,0 @@ -"""Topology module. - -Contains the topology classes for representing the physical and virtual topology of the -lighting setup. -""" - -import xml.etree.ElementTree as et - -from .constants import BXW -from .interfaces import XMLSerializable -from .exceptions import LoadError - -class Fixture(XMLSerializable): - """Class representing a lighting fixture. - - Each lighting fixture has a number of channels, which are mapped to the physical - topology. - - Channels must be added by changing the value of ``Fixture.channel_count``, which will - create the necessary channel objects and handle deletion. - """ - def __init__(self, w: "Workspace", id_: int = None, name: str = None, channel_count: int = 0): - self.w = w - self.id = id_ if id_ is not None else w.next_fixture_id - self.name = name if name else "Fixture %d" % self.id - - self.channels = () - self.channel_count = channel_count - - self.w.register_fixture(self) - - class Channel: - """Class representing a single channel on a Fixture. - - The physical address of the channel is stored in the ``Channel.address`` attribute - and may be changed at will. - - This program takes a very lax approach to channel addressing: the address is not - parsed in any way and duplicate addresses are not handled. For convenience with - OLA, Channel is iterable and iteration returns an iterator over its ``address`` - attribute. - """ - def __init__(self, f: "Fixture", id_: int, name: str = "Intensity", address = (-1,-1)): - self.f = f - self.id = id_ - self.name = name - self.address = address - self._hash = hash((f.id, id_)) - - def __hash__(self): - return self._hash - - def __iter__(self): - return iter(self.address) - - def __repr__(self): - return "Channel(fixture={c.f.id}, index={c.id}, name={c.name})".format(c=self) - - @property - def channel_count(self): - """Return the current number of channels on the fixture.""" - return len(self.channels) - - @channel_count.setter - def channel_count(self, value): - """Change the number of channels on the fixture. - - This function handles deletion of removed channels from functions as well. - """ - if value < 0: - raise ValueError("Number of channels must be nonnegative") - elif value < len(self.channels): - for i in range(value, len(self.channels)): - self.w.delete_channel(self.channels[i]) - self.channels = self.channels[:value] - elif value > len(self.channels): - self.channels += tuple((Fixture.Channel(self, i) for i in range(len(self.channels), value))) - - def __repr__(self): - return "Fixture({f.name}, id={f.id}, channels={f.channel_count})".format(f=self) - - def serialize(self): - e = et.Element(BXW+"fixture") - e.set("name", self.name) - e.set("id", str(self.id)) - - for c in self.channels: - ce = et.SubElement(e, BXW+"channel") - ce.set("name", c.name) - if c.address is not None: - ## TODO: Other addressing modes - try: - univ, addr = c.address - ae = et.SubElement(ce, BXW+"ola") - ae.set("universe", str(univ)) - ae.set("address", str(addr)) - except ValueError: - pass - - return e - - @classmethod - def deserialize(cls, w, e): - if e.tag != BXW+"fixture": - raise LoadError("Invalid fixture tag") - - id_ = cls.int_or_none(e.get("id")) - if id_ is None: - raise LoadError("Fixture tag has invalid/missing ID") - - name = e.get("name") - - f = cls(w, id_=id_, name=name, channel_count=len(e)) - for n, channel in enumerate(e): - if channel.tag != BXW+"channel": - raise LoadError("Invalid channel tag") - - name = channel.get("name") - if name is not None: - f.channels[n].name = name - - if len(channel) > 1: - raise LoadError("Channel can have at most one address") - elif len(channel) == 1: - address, = channel - if address.tag == BXW+"ola": - try: - address = (int(address.get("universe")), int(address.get("address")),) - except (ValueError, TypeError): - raise LoadError("Invalid OLA address on channel") - else: - raise LoadError("Unknown address tag \"%s\"" % address.tag) - f.channels[n].address = address - - return f |