diff --git a/aprslib/packets/telemetry.py b/aprslib/packets/telemetry.py index b0e4d1d..b1cf22c 100644 --- a/aprslib/packets/telemetry.py +++ b/aprslib/packets/telemetry.py @@ -1,7 +1,10 @@ +from aprslib import string_type from aprslib.packets.base import APRSPacket __all__ = [ 'TelemetryReport', + 'TelemetryUnit', + 'TelemetryParm', ] class TelemetryAddon(object): @@ -9,7 +12,6 @@ class TelemetryAddon(object): _sequence_number = 0 _digital_value = 0 - def __init__(self, *args, **kwargs): self._analog_values = AnalogValueList() super(TelemetryAddon, self).__init__( *args, **kwargs) @@ -81,10 +83,27 @@ class AnalogValueList(ImmutableList): def __setitem__(self, i, v): if not 0 <= i <= 4: raise IndexError("Index outside of range 0-4, got %d" % i) - if not 0 <= v <= 999: + if not isinstance(v, int) or not 0 <= v <= 999: raise ValueError("Value outside of range 0-999, got %d" % v) - else: - list.__setitem__(self, i, v) + + list.__setitem__(self, i, v) + + +class UnitParmList(ImmutableList): + _lengths = (7, 7, 6, 6, 5, 6, 5, 4, 4, 4, 3, 3, 3) + + def __init__(self): + list.__init__(self, [''] * 13) + + def __setitem__(self, i, v): + if not 0 <= i <= 12: + raise IndexError("Index outside of range 0-12, got %d" % i) + if not isinstance(v, string_type): + raise TypeError("Expected type to be str, got %s" % type(v)) + if len(v) > self._lengths[i]: + raise ValueError("Expected length index %d is %d, got %d" % (i, self._lengths[i], len(v))) + + list.__setitem__(self, i, v) class TelemetryReport(TelemetryAddon, APRSPacket): @@ -113,3 +132,75 @@ class TelemetryReport(TelemetryAddon, APRSPacket): self.digital_value, self.comment, ) + +class TelemetryMessage(APRSPacket): + format = 'telemetry-messsage' + addressee = 'N0CALL' + + def _serialize_body(self): + return ":{: <9s}:".format(self.addressee) + +class TelemetryUnit(TelemetryMessage): + _tUNIT = None + + def __init__(self, *args, **kwargs): + self._tUNIT = UnitParmList() + super(TelemetryUnit, self).__init__( *args, **kwargs) + + @property + def tUNIT(self): + return self._tUNIT + + @tUNIT.setter + def tUNIT(self, v): + if not isinstance(v, list): + raise TypeError("Expected analog_values to be list, got %s" % type(v)) + if len(v) != 13: + raise ValueError("Expected a list of 13 elements, got a list of %d" % len(v)) + + for i, elm in enumerate(v): + self._tUNIT[i] = elm + + def _serialize_body(self): + last = 0 + for i, elm in enumerate(self.tUNIT): + if elm: last = i + + return "{:s}{:s}{:s}".format( + TelemetryMessage._serialize_body(self), + 'UNIT.', + ','.join(self.tUNIT[:last+1]), + ) + + +class TelemetryParm(TelemetryMessage): + _tPARM = None + + def __init__(self, *args, **kwargs): + self._tPARM = UnitParmList() + super(TelemetryParm, self).__init__( *args, **kwargs) + + @property + def tPARM(self): + return self._tPARM + + @tPARM.setter + def tPARM(self, v): + if not isinstance(v, list): + raise TypeError("Expected analog_values to be list, got %s" % type(v)) + if len(v) != 13: + raise ValueError("Expected a list of 13 elements, got a list of %d" % len(v)) + + for i, elm in enumerate(v): + self._tPARM[i] = elm + + def _serialize_body(self): + last = 0 + for i, elm in enumerate(self.tPARM): + if elm: last = i + + return "{:s}{:s}{:s}".format( + TelemetryMessage._serialize_body(self), + 'PARM.', + ','.join(self.tPARM[:last+1]), + )