diff --git a/vban_cmd/factory.py b/vban_cmd/factory.py index 471c73d..b158927 100644 --- a/vban_cmd/factory.py +++ b/vban_cmd/factory.py @@ -10,7 +10,9 @@ from .config import request_config as configs from .error import VBANCMDError from .kinds import KindMapClass from .kinds import request_kind_map as kindmap +from .macrobutton import MacroButton from .strip import request_strip_obj as strip +from .vban import request_vban_obj as vban from .vbancmd import VbanCmd logger = logging.getLogger(__name__) @@ -23,7 +25,9 @@ class FactoryBuilder: Separates construction from representation. """ - BuilderProgress = IntEnum("BuilderProgress", "strip bus command", start=0) + BuilderProgress = IntEnum( + "BuilderProgress", "strip bus command macrobutton vban", start=0 + ) def __init__(self, factory, kind: KindMapClass): self._factory = factory @@ -32,6 +36,8 @@ class FactoryBuilder: f"Finished building strips for {self._factory}", f"Finished building buses for {self._factory}", f"Finished building commands for {self._factory}", + f"Finished building macrobuttons for {self._factory}", + f"Finished building vban in/out streams for {self._factory}", ) self.logger = logger.getChild(self.__class__.__name__) @@ -58,6 +64,14 @@ class FactoryBuilder: self._factory.command = Command.make(self._factory) return self + def make_macrobutton(self): + self._factory.button = tuple(MacroButton(self._factory, i) for i in range(80)) + return self + + def make_vban(self): + self._factory.vban = vban(self._factory) + return self + class FactoryBase(VbanCmd): """Base class for factories, subclasses VbanCmd.""" @@ -86,6 +100,8 @@ class FactoryBase(VbanCmd): self.builder.make_strip, self.builder.make_bus, self.builder.make_command, + self.builder.make_macrobutton, + self.builder.make_vban, ) self._configs = None diff --git a/vban_cmd/macrobutton.py b/vban_cmd/macrobutton.py new file mode 100644 index 0000000..9965897 --- /dev/null +++ b/vban_cmd/macrobutton.py @@ -0,0 +1,36 @@ +from .iremote import IRemote + + +class MacroButton(IRemote): + """A placeholder class in case this interface is being used interchangeably with the Remote API""" + + def __str__(self): + return f"{type(self).__name__}{self._remote.kind}{self.index}" + + @property + def identifier(self): + return f"button[{self.index}]" + + @property + def state(self) -> bool: + self.logger.warning("button.state commands are not supported over VBAN") + + @state.setter + def state(self, _): + self.logger.warning("button.state commands are not supported over VBAN") + + @property + def stateonly(self) -> bool: + self.logger.warning("button.stateonly commands are not supported over VBAN") + + @stateonly.setter + def stateonly(self, v): + self.logger.warning("button.stateonly commands are not supported over VBAN") + + @property + def trigger(self) -> bool: + self.logger.warning("button.trigger commands are not supported over VBAN") + + @trigger.setter + def trigger(self, _): + self.logger.warning("button.trigger commands are not supported over VBAN") diff --git a/vban_cmd/vban.py b/vban_cmd/vban.py new file mode 100644 index 0000000..e5e985e --- /dev/null +++ b/vban_cmd/vban.py @@ -0,0 +1,187 @@ +from abc import abstractmethod + +from .iremote import IRemote + + +class VbanStream(IRemote): + """ + Implements the common interface + + Defines concrete implementation for vban stream + """ + + @abstractmethod + def __str__(self): + pass + + @property + def identifier(self) -> str: + return f"vban.{self.direction}stream[{self.index}]" + + @property + def on(self) -> bool: + return + + @on.setter + def on(self, val: bool): + self.setter("on", 1 if val else 0) + + @property + def name(self) -> str: + return + + @name.setter + def name(self, val: str): + self.setter("name", val) + + @property + def ip(self) -> str: + return + + @ip.setter + def ip(self, val: str): + self.setter("ip", val) + + @property + def port(self) -> int: + return + + @port.setter + def port(self, val: int): + if not 1024 <= val <= 65535: + self.logger.warning( + f"port got: {val} but expected a value from 1024 to 65535" + ) + self.setter("port", val) + + @property + def sr(self) -> int: + return + + @sr.setter + def sr(self, val: int): + opts = (11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000) + if val not in opts: + self.logger.warning(f"sr got: {val} but expected a value in {opts}") + self.setter("sr", val) + + @property + def channel(self) -> int: + return + + @channel.setter + def channel(self, val: int): + if not 1 <= val <= 8: + self.logger.warning(f"channel got: {val} but expected a value from 1 to 8") + self.setter("channel", val) + + @property + def bit(self) -> int: + return + + @bit.setter + def bit(self, val: int): + if val not in (16, 24): + self.logger.warning(f"bit got: {val} but expected value 16 or 24") + self.setter("bit", 1 if (val == 16) else 2) + + @property + def quality(self) -> int: + return + + @quality.setter + def quality(self, val: int): + if not 0 <= val <= 4: + self.logger.warning(f"quality got: {val} but expected a value from 0 to 4") + self.setter("quality", val) + + @property + def route(self) -> int: + return + + @route.setter + def route(self, val: int): + if not 0 <= val <= 8: + self.logger.warning(f"route got: {val} but expected a value from 0 to 8") + self.setter("route", val) + + +class VbanInstream(VbanStream): + """ + class representing a vban instream + + subclasses VbanStream + """ + + def __str__(self): + return f"{type(self).__name__}{self._remote.kind}{self.index}" + + @property + def direction(self) -> str: + return "in" + + @property + def sr(self) -> int: + return + + @property + def channel(self) -> int: + return + + @property + def bit(self) -> int: + return + + +class VbanOutstream(VbanStream): + """ + class representing a vban outstream + + Subclasses VbanStream + """ + + def __str__(self): + return f"{type(self).__name__}{self._remote.kind}{self.index}" + + @property + def direction(self) -> str: + return "out" + + +class Vban: + """ + class representing the vban module + + Contains two tuples, one for each stream type + """ + + def __init__(self, remote): + self.remote = remote + num_instream, num_outstream = remote.kind.vban + self.instream = tuple(VbanInstream(remote, i) for i in range(num_instream)) + self.outstream = tuple(VbanOutstream(remote, i) for i in range(num_outstream)) + + def enable(self): + """if VBAN disabled there can be no communication with it""" + + def disable(self): + self.remote._set_rt("vban.Enable", 0) + + +def vban_factory(remote) -> Vban: + """ + Factory method for vban + + Returns a class that represents the VBAN module. + """ + VBAN_cls = Vban + return type(f"{VBAN_cls.__name__}", (VBAN_cls,), {})(remote) + + +def request_vban_obj(remote) -> Vban: + """ + Vban entry point. + + Returns a reference to a Vban class of a kind + """ + return vban_factory(remote)