summaryrefslogtreecommitdiff
path: root/topology.py
diff options
context:
space:
mode:
authorBen Connors <benconnors@outlook.com>2019-09-25 23:05:14 -0400
committerBen Connors <benconnors@outlook.com>2019-09-25 23:05:14 -0400
commit2b8a53f98c44e6e78d49b7c246731deef75ed6d3 (patch)
treed85e383c0d54d662ea93384b177a0ad59a40917e /topology.py
parent7f85bd8ed84b23fc4e683ab90fc7babe288f1a27 (diff)
Change module layout; start chaser work
- Fix up callbacks - Clean up function implementations - More properties to prevent editing of attributes - Start work on chasers - Implement framework for chaser steps
Diffstat (limited to 'topology.py')
-rw-r--r--topology.py135
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