Source code for tslumd.tallyobj

try:
    from loguru import logger
except ImportError: # pragma: no cover
    import logging
    logger = logging.getLogger(__name__)
from typing import Dict, Set

from pydispatch import Dispatcher, Property

from tslumd import TallyType, TallyColor

__all__ = ('Tally',)

[docs]class Tally(Dispatcher): """A single tally object Properties: rh_tally (TallyColor): State of the "right-hand" tally indicator txt_tally (TallyColor): State of the "text" tally indicator lh_tally (TallyColor): State of the "left-hand" tally indicator brightness (int): Tally indicator brightness from 0 to 3 text (str): Text to display control (bytes): Any control data received for the tally indicator normalized_brightness (float): The :attr:`brightness` value normalized as a float from ``0.0`` to ``1.0`` :Events: .. event:: on_update(instance: Tally, props_changed: Sequence[str]) Fired when any property changes .. event:: on_control(instance: Tally, data: bytes) Fired when control data is received for the tally indicator .. versionadded:: 0.0.2 The :event:`on_control` event """ rh_tally = Property(TallyColor.OFF) txt_tally = Property(TallyColor.OFF) lh_tally = Property(TallyColor.OFF) brightness = Property(3) normalized_brightness = Property(1.) text = Property('') control = Property(b'') _events_ = ['on_update', 'on_control'] _prop_attrs = ('rh_tally', 'txt_tally', 'lh_tally', 'brightness', 'text', 'control') def __init__(self, index_, **kwargs): self.__index = index_ self._updating_props = False self.update(**kwargs) self.bind(**{prop:self._on_prop_changed for prop in self._prop_attrs}) @property def index(self) -> int: """Index of the tally object from 0 to 65534 (``0xfffe``) """ return self.__index @property def is_broadcast(self) -> bool: """``True`` if the tally is to be "broadcast", meaning sent to all :attr:`display indices<.messages.Display.index>`. (if the :attr:`index` is ``0xffff``) .. versionadded:: 0.0.2 """ return self.index == 0xffff
[docs] @classmethod def broadcast(cls, **kwargs) -> 'Tally': """Create a :attr:`broadcast <is_broadcast>` tally (with :attr:`index` set to ``0xffff``) .. versionadded:: 0.0.2 """ return cls(0xffff, **kwargs)
[docs] @classmethod def from_display(cls, display: 'tslumd.Display') -> 'Tally': """Create an instance from the given :class:`~.messages.Display` object """ attrs = set(cls._prop_attrs) if display.type.name == 'control': attrs.discard('text') else: attrs.discard('control') kw = {attr:getattr(display, attr) for attr in cls._prop_attrs} return cls(display.index, **kw)
[docs] def update(self, **kwargs) -> Set[str]: """Update any known properties from the given keyword-arguments Returns: set: The property names, if any, that changed """ log_updated = kwargs.pop('LOG_UPDATED', False) props_changed = set() self._updating_props = True for attr in self._prop_attrs: if attr not in kwargs: continue val = kwargs[attr] if getattr(self, attr) == val: continue props_changed.add(attr) setattr(self, attr, val) if attr == 'brightness': self.normalized_brightness = (val + 1) / 4 if log_updated: logger.debug(f'{self!r}.{attr} = {val!r}') self._updating_props = False if len(props_changed): self.emit('on_update', self, props_changed) return props_changed
[docs] def update_from_display(self, display: 'tslumd.messages.Display') -> Set[str]: """Update this instance from the values of the given :class:`~.messages.Display` object Returns: set: The property names, if any, that changed """ attrs = set(self._prop_attrs) is_control = display.type.name == 'control' if is_control: attrs.discard('text') else: attrs.discard('control') kw = {attr:getattr(display, attr) for attr in attrs} kw['LOG_UPDATED'] = True props_changed = self.update(**kw) if is_control: self.emit('on_control', self, display.control) return props_changed
[docs] def to_dict(self) -> Dict: """Serialize to a :class:`dict` """ d = {attr:getattr(self, attr) for attr in self._prop_attrs} d['index'] = self.index return d
# def to_display(self) -> 'tslumd.messages.Display': # """Create a :class:`~.messages.Display` from this instance # """ # kw = self.to_dict() # return Display(**kw) def _on_prop_changed(self, instance, value, **kwargs): if self._updating_props: return prop = kwargs['property'] if prop.name == 'brightness': self.normalized_brightness = (value + 1) / 4 self.emit('on_update', self, [prop.name]) def __eq__(self, other): if not isinstance(other, Tally): return NotImplemented return self.to_dict() == other.to_dict() def __ne__(self, other): if not isinstance(other, Tally): return NotImplemented return self.to_dict() != other.to_dict() def __repr__(self): return f'<{self.__class__.__name__}: ({self})>' def __str__(self): return f'{self.index} - "{self.text}"'