Ejemplo n.º 1
0
class DPTXlator4ByteSigned(DPTXlatorBase):
    """ DPTXlator class for 4-Byte-Signed (V32) KNX Datapoint Type

     - 4 Byte Signed: VVVVVVVV VVVVVVVV VVVVVVVV VVVVVVVV
     - V: Bytes [-2147483648:2147483647]

    .
    """
    DPT_Generic = DPT("13.xxx", "Generic", (-2147483648, 2147483647))

    DPT_Value_4_Count = DPT("13.001", "Signed count", (-2147483648, 2147483647), "pulses")
    DPT_Value_FlowRate_m3h = DPT("13.002", "Flow rate", (-214748.3648, 214748.3647), "m³/h")
    DPT_ActiveEnergy = DPT("13.010", "Active energy", (-214748.3648, 214748.3647), "W.h")
    DPT_ApparentEnergy = DPT("13.011", "Apparent energy", (-214748.3648, 214748.3647), "VA.h")
    DPT_ReactiveEnergy = DPT("13.012", "Reactive energy", (-214748.3648, 214748.3647), "VAR.h")
    DPT_ActiveEnergy_kWh = DPT("13.013", "Active energy (kWh)", (-214748.3648, 214748.3647), "kW.h")
    DPT_ApparentEnergy_kVAh = DPT("13.014", "Apparent energy (kVAh)", (-214748.3648, 214748.3647), "kVA.h")
    DPT_ReactiveEnergy_KVARh = DPT("13.015", "Reactive energy (kVARh)", (-214748.3648, 214748.3647), "kVAR.h")
    DPT_LongDeltaTimeSec = DPT("13.100", "Long delta time", (-214748.3648, 214748.3647), "s")

    def __init__(self, dptId):
        super(DPTXlator4ByteSigned, self).__init__(dptId, 4)

    def checkData(self, data):
        if not 0x00000000 <= data <= 0xffffffff:
            raise DPTXlatorValueError("data %s not in (0x00000000, 0xffffffff)" % hex(data))

    def checkValue(self, value):
        if not self._dpt.limits[0] <= value <= self._dpt.limits[1]:
            raise DPTXlatorValueError("Value not in range %r" % repr(self._dpt.limits))

    def dataToValue(self, data):
        if data >= 0x80000000:
            data = -((data - 1) ^ 0xffffffff)  # invert twos complement
        else:
            data = data
        if self._dpt is self.DPT_Value_FlowRate_m3h:
            value = data / 10000.
        else:
            value = data
        #Logger().debug("DPTXlator4ByteSigned._toValue(): value=%d" % value)
        return value

    def valueToData(self, value):
        if value < 0:
            value = (abs(value) ^ 0xffffffff) + 1  # twos complement
        if self._dpt is self.DPT_Value_FlowRate_m3h:
            data = int(round(value * 10000.))
        else:
            data = value
        #Logger().debug("DPTXlator4ByteSigned.valueToData(): data=%s" % hex(data))
        return data

    def dataToFrame(self, data):
        return bytearray(struct.pack(">L", data))

    def frameToData(self, frame):
        data = struct.unpack(">L", str(frame))[0]
        return data
Ejemplo n.º 2
0
class DPTXlator3BitControl(DPTXlatorBase):
    """ DPTXlator class for 3-Bit-Control (B1U3) KNX Datapoint Type

    This is a composite DPT.

     - 1 Byte: 0000CSSSS
     - C: Control bit [0, 1]
     - S: StepCode [0:7]

    The _data param of this DPT only handles the stepCode; the control bit is handled by the sub-DPT.

    @todo: create and use a DPTCompositeConverterBase?

    @ivar _dpt: sub-DPT
    @type _dpt: L{DPT}
    """
    DPT_Generic = DPT("3.xxx", "Generic", (-7, 7))

    DPT_Control_Dimming = DPT("3.007", "Dimming", (-7, 7))
    DPT_Control_Blinds = DPT("3.008", "Blinds", (-7, 7))

    def __init__(self, dptId):
        super(DPTXlator3BitControl, self).__init__(dptId, 0)

        mainId, subId = dptId.split('.')
        dptId_ = "1.%s" % subId
        self._dpt2 = DPTXlatorBoolean(dptId_)

    def checkData(self, data):
        if not 0x00 <= data <= 0x0f:
            raise DPTXlatorValueError("data %s not in (0x00, 0x0f)" % hex(data))

    def checkValue(self, value):
        if not self._dpt.limits[0] <= value <= self._dpt.limits[1]:
            raise DPTXlatorValueError("value %d not in range %r" % (value, repr(self._dpt.limits)))

    def dataToValue(self, data):
        ctrl = (data & 0x08) >> 3
        stepCode = data & 0x07
        value = stepCode if ctrl else -stepCode
        return value

    def valueToData(self, value):
        ctrl = 1 if value > 0 else 0
        stepCode = abs(value) & 0x07
        data = ctrl << 3 | stepCode
        return data

    # Add properties control and stepCode + helper methods (+ intervals?)

    def dataToFrame(self, data):
        return bytearray(struct.pack(">B", data))

    def frameToData(self, frame):

        # Note the usage of self.data, and not data!
        data = struct.unpack(">B", str(frame))[0]
        return data
Ejemplo n.º 3
0
class DPTXlatorScene(DPTXlatorBase):
    """ DPTXlator class for Scene (B1r1U6) KNX Datapoint Type

     - 1 Byte: CrUUUUUU
     - C: Control bit [0, 1]
     - U: Value [0:63]
     - r: reserved (0)

    .
    """
    DPT_Generic = DPT("17.xxx", "Generic", (0, 255))

    DPT_Date = DPT("17.001", "Scene", ((0, 0), (1, 63)))

    def __init__(self, dptId):
        super(DPTXlatorScene, self).__init__(dptId, 1)

    def checkData(self, data):
        if not 0x00 <= data <= 0xff:
            raise DPTXlatorValueError("data %s not in (0x00, 0xff)" %
                                      hex(data))

    def checkValue(self, value):
        for index in range(2):
            if not self._dpt.limits[0][index] <= value[
                    index] <= self._dpt.limits[1][index]:
                raise DPTXlatorValueError("value not in range %r" %
                                          repr(self._dpt.limits))

    def dataToValue(self, data):
        ctrl = (data >> 7) & 0x01
        scene = data & 0x3f
        value = (ctrl, scene)
        #Logger().debug("DPTXlatorScene._toValue(): value=%d" % value)
        return value

    def valueToData(self, value):
        ctrl = value[0]
        scene = value[1]
        data = ctrl << 7 | scene
        #Logger().debug("DPTXlatorScene.valueToData(): data=%s" % hex(data))
        return data

    def dataToFrame(self, data):
        return bytearray(struct.pack(">B", data))

    def frameToData(self, frame):
        data = struct.unpack(">B", str(frame))[0]
        return data

    @property
    def ctrl(self):
        return self.value[0]

    @property
    def scene(self):
        return self.value[1]
Ejemplo n.º 4
0
class DPTXlator8BitSigned(DPTXlatorBase):
    """ DPTXlator class for 8-Bit-Signed (V8) KNX Datapoint Type

     - 1 Byte: VVVVVVVV
     - V: Byte [-128:127]

    .
    """
    DPT_Generic = DPT("6.xxx", "Generic", (-128, 127))

    DPT_Percent_V8 = DPT("6.001", "Percent (8 bit)", (-128, 127), "%")
    DPT_Value_1_Count = DPT("6.010", "Signed count", (-128, 127), "pulses")

    #DPT_Status_Mode3 = DPT("6.020", "Status mode 3", (, ))

    def __init__(self, dptId):
        super(DPTXlator8BitSigned, self).__init__(dptId, 1)

    def checkData(self, data):
        if not 0x00 <= data <= 0xff:
            raise DPTXlatorValueError("data %s not in (0x00, 0xff)" %
                                      hex(data))

    def checkValue(self, value):
        if not self._dpt.limits[0] <= value <= self._dpt.limits[1]:
            raise DPTXlatorValueError("value not in range %r" %
                                      repr(self._dpt.limits))

    def dataToValue(self, data):
        if data >= 0x80:
            value = -((data - 1) ^ 0xff)  # invert twos complement
        else:
            value = data
        #Logger().debug("DPTXlator8BitSigned._toValue(): value=%d" % value)
        return value

    def valueToData(self, value):
        if value < 0:
            value = (abs(value) ^ 0xff) + 1  # twos complement
        data = value
        #Logger().debug("DPTXlator8BitSigned.valueToData(): data=%s" % hex(data))
        return data

    def dataToFrame(self, data):
        return bytearray(struct.pack(">B", data))

    def frameToData(self, frame):
        data = struct.unpack(">B", str(frame))[0]
        return data
Ejemplo n.º 5
0
class DPTXlator8BitEncAbsValue(DPTXlatorBase):
    """ DPTXlator class for 8-Bit-Absolute-Encoding-Value (N8) KNX Datapoint Type

     - 1 Byte: NNNNNNNN
     - N: Byte [0:255]

    .
    """
    DPT_Generic = DPT("20.xxx", "Generic", (0, 255))

    DPT_OccMode = DPT("20.003", "Occupancy mode",
                      ("occupied", "standby", "not occupied"))

    def __init__(self, dptId):
        super(DPTXlator8BitEncAbsValue, self).__init__(dptId, 1)

    def checkData(self, data):
        if not 0x00 <= data <= 0xff:
            raise DPTXlatorValueError("data %s not in (0x00, 0xff)" %
                                      hex(data))

    def checkValue(self, value):
        if value not in self._dpt.limits:
            raise DPTXlatorValueError("value not in %r" %
                                      repr(self._dpt.limits))

    def dataToValue(self, data):
        value = self._dpt.limits[data]
        #Logger().debug("DPTXlator8BitEncAbsValue.dataToValue(): value=%d" % value)
        return value

    def valueToData(self, value):
        #Logger().debug("DPTXlator8BitEncAbsValue.valueToData(): value=%d" % value)
        self.checkValue(value)
        data = self._dpt.limits.index(value)
        #Logger().debug("DPTXlator8BitEncAbsValue.valueToData(): data=%s" % hex(data))
        return data

    def dataToFrame(self, data):
        return bytearray(struct.pack(">B", data))

    def frameToData(self, frame):
        data = struct.unpack(">B", str(frame))[0]
        return data
Ejemplo n.º 6
0
class DPTXlator8BitUnsigned(DPTXlatorBase):
    """ DPTXlator class for 8-Bit-Unsigned (U8) KNX Datapoint Type

     - 1 Byte: UUUUUUUU
     - U: Byte [0:255]

    .
    """
    DPT_Generic = DPT("5.xxx", "Generic", (0, 255))

    DPT_Scaling = DPT("5.001", "Scaling", (0, 100), "%")
    DPT_Angle = DPT("5.003", "Angle", (0, 360), "°")
    DPT_Percent_U8 = DPT("5.004", "Percent (8 bit)", (0, 255), "%")
    DPT_DecimalFactor = DPT("5.005", "Decimal factor", (0, 1), "ratio")
    DPT_Tariff = DPT("5.006", "Tariff", (0, 254), "ratio")
    DPT_Value_1_Ucount = DPT("5.010", "Unsigned count", (0, 255), "pulses")

    def __init__(self, dptId):
        super(DPTXlator8BitUnsigned, self).__init__(dptId, 1)

    def checkData(self, data):
        if not 0x00 <= data <= 0xff:
            raise DPTXlatorValueError("data %s not in (0x00, 0xff)" %
                                      hex(data))

    def checkValue(self, value):
        if not self._dpt.limits[0] <= value <= self._dpt.limits[1]:
            raise DPTXlatorValueError("value not in range %r" %
                                      repr(self._dpt.limits))

    def dataToValue(self, data):
        value = data
        if self._dpt is self.DPT_Scaling:
            value = value * 100. / 255.
        elif self._dpt is self.DPT_Angle:
            value = value * 360. / 255.
        elif self._dpt is self.DPT_DecimalFactor:
            value = value / 255.
        #Logger().debug("DPTXlator8BitUnsigned.dataToValue(): value=%d" % value)
        return value

    def valueToData(self, value):
        if self._dpt is self.DPT_Scaling:
            data = int(round(value * 255 / 100.))
        elif self._dpt is self.DPT_Angle:
            data = int(round(value * 255 / 360.))
        elif self._dpt is self.DPT_DecimalFactor:
            data = int(round(value * 255))
        else:
            data = value
        #Logger().debug("DPTXlator8BitUnsigned.valueToData(): data=%s" % hex(data))
        return data

    def dataToFrame(self, data):
        return bytearray(struct.pack(">B", data))

    def frameToData(self, frame):
        data = struct.unpack(">B", str(frame))[0]
        return data
Ejemplo n.º 7
0
class DPTXlator4ByteUnsigned(DPTXlatorBase):
    """ DPTXlator class for 4-Byte-Unsigned (U32) KNX Datapoint Type

     - 4 Byte Unsigned: UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU
     - U: Bytes [0:4294967295]

    .
    """
    DPT_Generic = DPT("12.xxx", "Generic", (0, 4294967295))

    DPT_Value_4_Ucount = DPT("12.001", "Unsigned count", (0, 4294967295),
                             "pulses")

    def __init__(self, dptId):
        super(DPTXlator4ByteUnsigned, self).__init__(dptId, 4)

    def checkData(self, data):
        if not 0x00000000 <= data <= 0xffffffff:
            raise DPTXlatorValueError(
                "data %s not in (0x00000000, 0xffffffff)" % hex(data))

    def checkValue(self, value):
        if not self._dpt.limits[0] <= value <= self._dpt.limits[1]:
            raise DPTXlatorValueError("Value not in range %r" %
                                      repr(self._dpt.limits))

    def dataToValue(self, data):
        value = data
        #Logger().debug("DPTXlator4ByteUnsigned._toValue(): value=%d" % value)
        return value

    def valueToData(self, value):
        data = value
        #Logger().debug("DPTXlator4ByteUnsigned.valueToData(): data=%s" % hex(data))
        return data

    def dataToFrame(self, data):
        return bytearray(struct.pack(">L", data))

    def frameToData(self, frame):
        data = struct.unpack(">L", str(frame))[0]
        return data
Ejemplo n.º 8
0
class DPTXlatorString(DPTXlatorBase):
    """ DPTXlator class for String (A112) KNX Datapoint Type

     - 14 Byte: AAAAAAAA ... AAAAAAAA
     - A: Char [0:255]

    .
    """
    DPT_Generic = DPT("16.xxx", "Generic",
                      (0, 5192296858534827628530496329220095))

    DPT_String_ASCII = DPT("16.000", "String", (14 * (0, ), 14 * (127, )))
    DPT_String_8859_1 = DPT("16.001", "String", (14 * (0, ), 14 * (255, )))

    def __init__(self, dptId):
        super(DPTXlatorString, self).__init__(dptId, 14)

    def checkData(self, data):
        if not 0x0000000000000000000000000000 <= data <= 0xffffffffffffffffffffffffffff:
            raise DPTXlatorValueError(
                "data %s not in (0x0000000000000000000000000000, 0xffffffffffffffffffffffffffff)"
                % hex(data))

    def checkValue(self, value):
        for index in range(14):
            if not self._dpt.limits[0][index] <= value[
                    index] <= self._dpt.limits[1][index]:
                raise DPTXlatorValueError("value not in range %r" %
                                          repr(self._dpt.limits))

    def dataToValue(self, data):
        value = tuple(
            [int((data >> shift) & 0xff) for shift in range(104, -1, -8)])
        #Logger().debug("DPTXlatorString._toValue(): value=%d" % value)
        return value

    def valueToData(self, value):
        data = 0x00
        for shift in range(104, -1, -8):
            data |= value[13 - shift / 8] << shift
        #Logger().debug("DPTXlatorString.valueToData(): data=%s" % hex(data))
        return data

    def dataToFrame(self, data):
        return bytearray(struct.pack(">14B", *self.dataToValue(data)))

    def frameToData(self, frame):
        value = struct.unpack(">14B", str(frame))
        data = self.valueToData(value)
        return data

    @property
    def day(self):
        return self.value[0]

    @property
    def month(self):
        return self.value[1]

    @property
    def year(self):
        return self.value[2]
Ejemplo n.º 9
0
class DPTXlator2ByteSigned(DPTXlatorBase):
    """ DPTXlator class for 2-Byte-Unsigned (V16) KNX Datapoint Type

     - 2 Byte Signed: VVVVVVVV VVVVVVVV
     - V: Bytes [-32768:32767]

    .
    """
    DPT_Generic = DPT("8.xxx", "Generic", (-32768, 32767))

    DPT_Value_2_Count = DPT("8.001", "Signed count", (-32768, 32767), "pulses")
    DPT_DeltaTimeMsec = DPT("8.002", "Delta time (ms)", (-32768, 32767), "ms")
    DPT_DeltaTime10Msec = DPT("8.003", "Delta time (10ms)", (-327680, 327670),
                              "ms")
    DPT_DeltaTime100Msec = DPT("8.004", "Delta time (100ms)",
                               (-3276800, 3276700), "ms")
    DPT_DeltaTimeSec = DPT("8.005", "Delta time (s)", (-32768, 32767), "s")
    DPT_DeltaTimeMin = DPT("8.006", "Delta time (min)", (-32768, 32767), "min")
    DPT_DeltaTimeHrs = DPT("8.007", "Delta time (h)", (-32768, 32767), "h")
    DPT_Percent_V16 = DPT("8.010", "Percent (16 bit)", (-327.68, 327.67), "%")
    DPT_Rotation_Angle = DPT("8.011", "Rotation angle", (-32768, 32767), "°")

    def __init__(self, dptId):
        super(DPTXlator2ByteSigned, self).__init__(dptId, 2)

    def checkData(self, data):
        if not 0x0000 <= data <= 0xffff:
            raise DPTXlatorValueError("data %s not in (0x0000, 0xffff)" %
                                      hex(data))

    def checkValue(self, value):
        if not self._dpt.limits[0] <= value <= self._dpt.limits[1]:
            raise DPTXlatorValueError("Value not in range %r" %
                                      repr(self._dpt.limits))

    def dataToValue(self, data):
        if data >= 0x8000:
            data = -((data - 1) ^ 0xffff)  # invert twos complement
        else:
            data = data
        if self._dpt is self.DPT_DeltaTime10Msec:
            value = data * 10.
        elif self._dpt is self.DPT_DeltaTime100Msec:
            value = data * 100.
        elif self._dpt is self.DPT_Percent_V16:
            value = data / 100.
        else:
            value = data
        #Logger().debug("DPTXlator2ByteSigned._toValue(): value=%d" % value)
        return value

    def valueToData(self, value):
        if value < 0:
            value = (abs(value) ^ 0xffff) + 1  # twos complement
        if self._dpt is self.DPT_DeltaTime10Msec:
            data = int(round(value / 10.))
        elif self._dpt is self.DPT_DeltaTime100Msec:
            data = int(round(value / 100.))
        elif self._dpt is self.DPT_Percent_V16:
            data = int(round(value * 100.))
        else:
            data = value
        #Logger().debug("DPTXlator2ByteSigned.valueToData(): data=%s" % hex(data))
        return data

    def dataToFrame(self, data):
        return bytearray(struct.pack(">H", data))

    def frameToData(self, frame):
        data = struct.unpack(">H", str(frame))[0]
        return data
Ejemplo n.º 10
0
class DPTXlator2ByteUnsigned(DPTXlatorBase):
    """ DPTXlator class for 2-Byte-Unsigned (U16) KNX Datapoint Type

      - 2 Byte Unsigned: UUUUUUUU UUUUUUUU
      - U: Bytes [0:65535]

    .
    """
    DPT_Generic = DPT("7.xxx", "Generic", (0, 65535))

    DPT_Value_2_Ucount = DPT("7.001", "Unsigned count", (0, 65535), "pulses")
    DPT_TimePeriodMsec = DPT("7.002", "Time period (resol. 1ms)", (0, 65535),
                             "ms")
    DPT_TimePeriod10Msec = DPT("7.003", "Time period (resol. 10ms)",
                               (0, 655350), "ms")
    DPT_TimePeriod100Msec = DPT("7.004", "Time period (resol. 100ms)",
                                (0, 6553500), "ms")
    DPT_TimePeriodSec = DPT("7.005", "Time period (resol. 1s)", (0, 65535),
                            "s")
    DPT_TimePeriodMin = DPT("7.006", "Time period (resol. 1min)", (0, 65535),
                            "min")
    DPT_TimePeriodHrs = DPT("7.007", "Time period (resol. 1h)", (0, 65535),
                            "h")
    DPT_PropDataType = DPT("7.010", "Interface object property ID", (0, 65535))
    DPT_Length_mm = DPT("7.011", "Length", (0, 65535), "mm")
    #DPT_UEICurrentmA = DPT("7.012", "Electrical current", (0, 65535), "mA")  # Add special meaning for 0 (create Limit object)
    DPT_Brightness = DPT("7.013", "Brightness", (0, 65535), "lx")

    def __init__(self, dptId):
        super(DPTXlator2ByteUnsigned, self).__init__(dptId, 2)

    def checkData(self, data):
        if not 0x0000 <= data <= 0xffff:
            raise DPTXlatorValueError("data %s not in (0x0000, 0xffff)" %
                                      hex(data))

    def checkValue(self, value):
        if not self._dpt.limits[0] <= value <= self._dpt.limits[1]:
            raise DPTXlatorValueError("Value not in range %r" %
                                      repr(self._dpt.limits))

    def dataToValue(self, data):
        if self._dpt is self.DPT_TimePeriod10Msec:
            value = data * 10.
        elif self._dpt is self.DPT_TimePeriod100Msec:
            value = data * 100.
        else:
            value = data
        #Logger().debug("DPTXlator2ByteUnsigned._toValue(): value=%d" % value)
        return value

    def valueToData(self, value):
        if self._dpt is self.DPT_TimePeriod10Msec:
            data = int(round(value / 10.))
        elif self._dpt is self.DPT_TimePeriod100Msec:
            data = int(round(value / 100.))
        else:
            data = value
        #Logger().debug("DPTXlator2ByteUnsigned.valueToData(): data=%s" % hex(data))
        return data

    def dataToFrame(self, data):
        return bytearray(struct.pack(">H", data))

    def frameToData(self, frame):
        data = struct.unpack(">H", str(frame))[0]
        return data
Ejemplo n.º 11
0
class DPTXlator4ByteFloat(DPTXlatorBase):
    """ DPTXlator class for 4-Byte-Float (F32) KNX Datapoint Type

     - 2 Byte Float: SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF (IEEE 754)
     - S: Sign [0, 1]
     - E: Exponent [0:255]
     - F: Fraction [0:8388607]

    .
    """
    DPT_Generic = DPT("14.xxx", "Generic",
                      (-3.4028234663852886e+38, 3.4028234663852886e+38))
    #DPT_Generic = DPT("14.xxx", "Generic", (-340282346638528859811704183484516925440, 340282346638528859811704183484516925440))

    DPT_Value_Acceleration = DPT(
        "14.000", "Acceleration",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "m/s²")
    DPT_Value_Acceleration_Angular = DPT(
        "14.001", "Acceleration, angular",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "rad/s²")
    DPT_Value_Activation_Energy = DPT(
        "14.002", "Activation energy",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "J/mol")
    DPT_Value_Activity = DPT("14.003", "Activity (radioactive)",
                             (-3.4028234663852886e+38, 3.4028234663852886e+38),
                             "s⁻¹")
    DPT_Value_Mol = DPT("14.004", "Amount of substance",
                        (-3.4028234663852886e+38, 3.4028234663852886e+38),
                        "mol")
    DPT_Value_Amplitude = DPT(
        "14.005", "Amplitude",
        (-3.4028234663852886e+38, 3.4028234663852886e+38))
    DPT_Value_AngleRad = DPT("14.006", "Angle, radiant",
                             (-3.4028234663852886e+38, 3.4028234663852886e+38),
                             "rad")
    DPT_Value_AngleDeg = DPT("14.007", "Angle, degree",
                             (-3.4028234663852886e+38, 3.4028234663852886e+38),
                             "°")
    DPT_Value_Angular_Momentum = DPT(
        "14.008", "Angular momentum",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "J.s")
    DPT_Value_Angular_Velocity = DPT(
        "14.009", "Angular velocity",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "rad/s")
    DPT_Value_Area = DPT("14.010", "Area",
                         (-3.4028234663852886e+38, 3.4028234663852886e+38),
                         "m²")
    DPT_Value_Capacitance = DPT(
        "14.011", "Capacitance",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "F")
    DPT_Value_Charge_DensitySurface = DPT(
        "14.012", "Charge density (surface)",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "C/m²")
    DPT_Value_Charge_DensityVolume = DPT(
        "14.013", "Charge density (volume)",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "C/m³")
    DPT_Value_Compressibility = DPT(
        "14.014", "Compressibility",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "m²/N")
    DPT_Value_Conductance = DPT(
        "14.015", "Conductance",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "S")
    DPT_Value_Electrical_Conductivity = DPT(
        "14.016", "Conductivity, electrical",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "S/m")
    DPT_Value_Density = DPT("14.017", "Density",
                            (-3.4028234663852886e+38, 3.4028234663852886e+38),
                            "kg/m³")
    DPT_Value_Electric_Charge = DPT(
        "14.018", "Electric charge",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "C")
    DPT_Value_Electric_Current = DPT(
        "14.019", "Electric current",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "A")
    DPT_Value_CurrentDensity = DPT(
        "14.020", "Electric current density",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "A/m²")
    DPT_Value_Electric_DipoleMoment = DPT(
        "14.021", "Electric dipole moment",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "Cm")
    DPT_Value_Electric_Displacement = DPT(
        "14.022", "Electric displacement",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "C/m²")
    DPT_Value_Electric_FieldStrength = DPT(
        "14.023", "Electric field strength",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "V/m")
    DPT_Value_Electric_Flux = DPT(
        "14.024", "Electric flux",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "c")  # unit??? C
    DPT_Value_Electric_FluxDensity = DPT(
        "14.025", "Electric flux density",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "C/m²")
    DPT_Value_Electric_Polarization = DPT(
        "14.026", "Electric polarization",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "C/m²")
    DPT_Value_Electric_Potential = DPT(
        "14.027", "Electric potential",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "V")
    DPT_Value_Electric_PotentialDifference = DPT(
        "14.028", "Electric potential difference",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "V")
    DPT_Value_ElectromagneticMoment = DPT(
        "14.029", "Electromagnetic moment",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "A.m²")
    DPT_Value_Electromotive_Force = DPT(
        "14.030", "Electromotive force",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "V")
    DPT_Value_Energy = DPT("14.031", "Energy",
                           (-3.4028234663852886e+38, 3.4028234663852886e+38),
                           "J")
    DPT_Value_Force = DPT("14.032", "Force",
                          (-3.4028234663852886e+38, 3.4028234663852886e+38),
                          "N")
    DPT_Value_Frequency = DPT(
        "14.033", "Frequency",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "Hz")
    DPT_Value_Angular_Frequency = DPT(
        "14.034", "Frequency, angular (pulsatance)",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "rad/s")
    DPT_Value_Heat_Capacity = DPT(
        "14.035", "Heat capacity",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "J/K")
    DPT_Value_Heat_FlowRate = DPT(
        "14.036", "Heat flow rate",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "W")
    DPT_Value_Heat_Quantity = DPT(
        "14.037", "Heat quantity",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "J")
    DPT_Value_Impedance = DPT(
        "14.038", "Impedance",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "Ohm")
    DPT_Value_Length = DPT("14.039", "Length",
                           (-3.4028234663852886e+38, 3.4028234663852886e+38),
                           "m")
    DPT_Value_Light_Quantity = DPT(
        "14.040", "Light quantity",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "J")
    DPT_Value_Luminance = DPT(
        "14.041", "Luminance",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "cd/m²")
    DPT_Value_Luminous_Flux = DPT(
        "14.042", "Luminous flux",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "lm")
    DPT_Value_Luminous_Intensity = DPT(
        "14.043", "Luminous intensity",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "cd")
    DPT_Value_Magnetic_FieldStrength = DPT(
        "14.044", "Magnetic field strengh",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "A/m")
    DPT_Value_Magnetic_FLux = DPT(
        "14.045", "Magnetic flux",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "Wb")
    DPT_Value_Magnetic_FluxDensity = DPT(
        "14.046", "Magnetic flux density",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "T")
    DPT_Value_Magnetic_Moment = DPT(
        "14.047", "Magnetic moment",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "A.m²")
    DPT_Value_Magnetic_Polarization = DPT(
        "14.048", "Magnetic polarization",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "T")
    DPT_Value_Magnetization = DPT(
        "14.049", "Magnetization",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "A/m")
    DPT_Value_MagnetomotiveForce = DPT(
        "14.050", "Magnetomotive force",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "A")
    DPT_Value_Mass = DPT("14.051", "Mass",
                         (-3.4028234663852886e+38, 3.4028234663852886e+38),
                         "kg")
    DPT_Value_MassFlux = DPT("14.052", "Mass flux",
                             (-3.4028234663852886e+38, 3.4028234663852886e+38),
                             "kg/s")
    DPT_Value_Momentum = DPT("14.053", "Momentum",
                             (-3.4028234663852886e+38, 3.4028234663852886e+38),
                             "N/s")
    DPT_Value_Phase_AngleRad = DPT(
        "14.054", "Phase angle, radiant",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "rad")
    DPT_Value_Phase_AngleDeg = DPT(
        "14.055", "Phase angle, degree",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "°")
    DPT_Value_Power = DPT("14.056", "Power",
                          (-3.4028234663852886e+38, 3.4028234663852886e+38),
                          "W")
    DPT_Value_Power_Factor = DPT(
        "14.057", "Power factor",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "cos phi")
    DPT_Value_Pressure = DPT("14.058", "Pressure",
                             (-3.4028234663852886e+38, 3.4028234663852886e+38),
                             "Pa")
    DPT_Value_Reactance = DPT(
        "14.059", "Reactance",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "Ohm")
    DPT_Value_Resistance = DPT(
        "14.060", "Resistance",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "Ohm")
    DPT_Value_Resistivity = DPT(
        "14.061", "Resistivity",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "Ohm.m")
    DPT_Value_SelfInductance = DPT(
        "14.062", "Self inductance",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "H")
    DPT_Value_SolidAngle = DPT(
        "14.063", "Solid angle",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "sr")
    DPT_Value_Sound_Intensity = DPT(
        "14.064", "Sound intensity",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "W/m²")
    DPT_Value_Speed = DPT("14.065", "Speed",
                          (-3.4028234663852886e+38, 3.4028234663852886e+38),
                          "m/s")
    DPT_Value_Stress = DPT("14.066", "Stress",
                           (-3.4028234663852886e+38, 3.4028234663852886e+38),
                           "Pa")
    DPT_Value_Surface_Tension = DPT(
        "14.067", "Surface tension",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "N/m")
    DPT_Value_Common_Temperature = DPT(
        "14.068", "Temperature, common",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "°C")
    DPT_Value_Absolute_Temperature = DPT(
        "14.069", "Temperature, absolute",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "K")
    DPT_Value_TemperatureDifference = DPT(
        "14.070", "Temperature difference",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "K")
    DPT_Value_Thermal_Capacity = DPT(
        "14.071", "Thermal capacity",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "J/K")
    DPT_Value_Thermal_Conductivity = DPT(
        "14.072", "Thermal conductivity",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "W/m/K")
    DPT_Value_ThermoelectricPower = DPT(
        "14.073", "Thermoelectric power",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "V/K")
    DPT_Value_Time = DPT("14.074", "Time",
                         (-3.4028234663852886e+38, 3.4028234663852886e+38),
                         "s")
    DPT_Value_Torque = DPT("14.075", "Torque",
                           (-3.4028234663852886e+38, 3.4028234663852886e+38),
                           "N.m")
    DPT_Value_Volume = DPT("14.076", "Volume",
                           (-3.4028234663852886e+38, 3.4028234663852886e+38),
                           "m³")
    DPT_Value_Volume_Flux = DPT(
        "14.077", "Volume flux",
        (-3.4028234663852886e+38, 3.4028234663852886e+38), "m³/s")
    DPT_Value_Weight = DPT("14.078", "Weight",
                           (-3.4028234663852886e+38, 3.4028234663852886e+38),
                           "N")
    DPT_Value_Work = DPT("14.079", "Work",
                         (-3.4028234663852886e+38, 3.4028234663852886e+38),
                         "J")

    def __init__(self, dptId):
        super(DPTXlator4ByteFloat, self).__init__(dptId, 4)

    def checkData(self, data):
        if not 0x00000000 <= data <= 0xffffffff:
            raise DPTXlatorValueError(
                "data %s not in (0x00000000, 0xffffffff)" % hex(data))

    def checkValue(self, value):
        if not self._dpt.limits[0] <= value <= self._dpt.limits[1]:
            raise DPTXlatorValueError("Value not in range %r" %
                                      repr(self._dpt.limits))

    def dataToValue(self, data):
        value = struct.unpack(">f", struct.pack(
            ">L", data))[0]  # struct.unpack(">f", self.toFrame())[0]
        #Logger().debug("DPTXlator4ByteFloat.dataToValue(): value=%f" % value)
        return value

    def valueToData(self, value):
        data = struct.unpack(">L", struct.pack(
            ">f", value))[0]  # self.frameToData(struct.pack(">f", value))
        #Logger().debug("DPTXlator4ByteFloat.valueToData(): data=%s" % hex(data))
        return data

    def dataToFrame(self, data):
        return bytearray(struct.pack(">L", data))

    def frameToData(self, frame):
        data = struct.unpack(">L", str(frame))[0]
        return data
Ejemplo n.º 12
0
class DPTXlator2ByteFloat(DPTXlatorBase):
    """ DPTXlator class for 2-Byte-Float (F16) KNX Datapoint Type

     - 2 Byte Float: SEEEEMMM MMMMMMMM
     - S: Sign [0, 1]
     - E: Exponent [0:15]
     - M: Significand (Mantissa) [-2048:2047]

    For all Datapoint Types 9.xxx, the encoded value 7FFFh shall always be used to denote invalid data.
    """
    DPT_Generic = DPT("9.xxx", "Generic", (-671088.64, +670760.96))

    DPT_Value_Temp = DPT("9.001", "Temperature", (-273., +670760.), "°C")
    DPT_Value_Tempd = DPT("9.002", "Temperature difference", (-670760., +670760.), "K")
    DPT_Value_Tempa = DPT("9.003", "Temperature gradient", (-670760., +670760.), "K/h")
    DPT_Value_Lux = DPT("9.004", "Luminous emittance", (0., +670760.), "lx")
    DPT_Value_Wsp = DPT("9.005", "Wind speed", (0., +670760.), "m/s")
    DPT_Value_Pres = DPT("9.006", "Air pressure", (0., +670760.), "Pa")
    DPT_Value_Humidity = DPT("9.007", "Humidity", (0., +670760.), "%")
    DPT_Value_AirQuality = DPT("9.008", "Air quality", (0., +670760.), "ppm")
    DPT_Value_Time1 = DPT("9.010", "Time difference 1", (-670760., +670760.), "s")
    DPT_Value_Time2 = DPT("9.011", "Time difference 2", (-670760., +670760.), "ms")
    DPT_Value_Volt = DPT("9.020", "Electrical voltage", (-670760., +670760.), "mV")
    DPT_Value_Current = DPT("9.021", "Electric current", (-670760., +670760.), "mA")
    DPT_PowerDensity = DPT("9.022", "Power density", (-670760., +670760.), "W/m²")
    DPT_KelvinPerPercent = DPT("9.023", "Kelvin/percent", (-670760., +670760.), "K/%")
    DPT_Power = DPT("9.024", "Power", (-670760., +670760.), "kW")
    DPT_Value_Volume_Flow = DPT("9.025", "Volume flow", (-670760., 670760.), "l/h")
    DPT_Rain_Amount = DPT("9.026", "Rain amount", (-670760., 670760.), "l/m²")
    DPT_Value_Temp_F = DPT("9.027", "Temperature (°F)", (-459.6, 670760.), "°F")
    DPT_Value_Wsp_kmh = DPT("9.028", "Wind speed (km/h)", (0., 670760.), "km/h")

    def __init__(self, dptId):
        super(DPTXlator2ByteFloat, self).__init__(dptId, 2)

    def checkData(self, data):
        if not 0x0000 <= data <= 0xffff:
            raise DPTXlatorValueError("data %s not in (0x0000, 0xffff)" % hex(data))

    def checkValue(self, value):
        if not self._dpt.limits[0] <= value <= self._dpt.limits[1]:
            raise DPTXlatorValueError("Value not in range %r" % repr(self._dpt.limits))

    def dataToValue(self, data):
        sign = (data & 0x8000) >> 15
        exp = (data & 0x7800) >> 11
        mant = data & 0x07ff
        if sign != 0:
            mant = -(~(mant - 1) & 0x07ff)
        value = (1 << exp) * 0.01 * mant
        #Logger().debug("DPT2ByteFloat.dataToValue(): sign=%d, exp=%d, mant=%r" % (sign, exp, mant))
        #Logger().debug("DPT2ByteFloat.dataToValue(): value=%.2f" % value)
        return value

    def valueToData(self, value):
        sign = 0
        exp = 0
        if value < 0:
            sign = 1
        mant = int(value * 100)
        while not -2048 <= mant <= 2047:
            mant = mant >> 1
            exp += 1
        #Logger().debug("DPT2ByteFloat.valueToData(): sign=%d, exp=%d, mant=%r" % (sign, exp, mant))
        data = (sign << 15) | (exp << 11) | (int(mant) & 0x07ff)
        #Logger().debug("DPT2ByteFloat.valueToData(): data=%s" % hex(data))
        return data

    def dataToFrame(self, data):
        return bytearray(struct.pack(">H", data))

    def frameToData(self, frame):
        data = struct.unpack(">H", str(frame))[0]
        return data
Ejemplo n.º 13
0
class DPTXlatorDate(DPTXlatorBase):
    """ DPTXlator class for Date (r3U5r4U4r1U7) KNX Datapoint Type

     - 3 Byte: rrrDDDDD rrrrMMMM rYYYYYYY
     - D: Day [1:31]
     - M: Month [1:12]
     - Y: Year [0:99]
     - r: reserved (0)

    .
    """
    DPT_Generic = DPT("11.xxx", "Generic", (0, 16777215))

    DPT_Date = DPT("11.001", "Date", ((1, 1, 1969), (31, 12, 2068)))

    def __init__(self, dptId):
        super(DPTXlatorDate, self).__init__(dptId, 3)

    def checkData(self, data):
        if not 0x000000 <= data <= 0xffffff:
            raise DPTXlatorValueError("data %s not in (0x000000, 0xffffff)" %
                                      hex(data))

    def checkValue(self, value):
        for index in range(3):
            if not self._dpt.limits[0][index] <= value[
                    index] <= self._dpt.limits[1][index]:
                raise DPTXlatorValueError("value not in range %r" %
                                          repr(self._dpt.limits))

    def dataToValue(self, data):
        day = (data >> 16) & 0x1f
        month = (data >> 8) & 0x0f
        year = data & 0x7f
        if year >= 69:
            year += 1900
        else:
            year += 2000
        value = (day, month, year)
        #Logger().debug("DPTXlatorDate._toValue(): value=%d" % value)
        return value

    def valueToData(self, value):
        day = value[0]
        month = value[1]
        year = value[2]
        if year >= 2000:
            year -= 2000
        else:
            year -= 1900
        data = day << 16 | month << 8 | year
        #Logger().debug("DPTXlatorDate.valueToData(): data=%s" % hex(data))
        return data

    def dataToFrame(self, data):
        data = [(data >> shift) & 0xff for shift in range(16, -1, -8)]
        return bytearray(struct.pack(">3B", *data))

    def frameToData(self, frame):
        data = struct.unpack(">3B", str(frame))
        data = data[0] << 16 | data[1] << 8 | data[2]
        return data

    @property
    def day(self):
        return self.value[0]

    @property
    def month(self):
        return self.value[1]

    @property
    def year(self):
        return self.value[2]
Ejemplo n.º 14
0
class DPTXlatorBoolean(DPTXlatorBase):
    """ DPTXlator class for 1-Bit (B1) KNX Datapoint Type

     - 1 Byte: 00000000B
     - B: Binary [0, 1]

    .
    """
    DPT_Generic = DPT("1.xxx", "Generic", (0, 1))

    DPT_Switch = DPT("1.001", "Switch", ("Off", "On"))
    DPT_Bool = DPT("1.002", "Boolean", (False, True))
    DPT_Enable = DPT("1.003", "Enable", ("Disable", "Enable"))
    DPT_Ramp = DPT("1.004", "Ramp", ("No ramp", "Ramp"))
    DPT_Alarm = DPT("1.005", "Alarm", ("No alarm", "Alarm"))
    DPT_BinaryValue = DPT("1.006", "Binary value", ("Low", "High"))
    DPT_Step = DPT("1.007", "Step", ("Decrease", "Increase"))
    DPT_UpDown = DPT("1.008", "Up/Down", ("Up", "Down"))
    DPT_OpenClose = DPT("1.009", "Open/Close", ("Open", "Close"))
    DPT_Start = DPT("1.010", "Start", ("Stop", "Start"))
    DPT_State = DPT("1.011", "State", ("Inactive", "Active"))
    DPT_Invert = DPT("1.012", "Invert", ("Not inverted", "Inverted"))
    DPT_DimSendStyle = DPT("1.013", "Dimmer send-style",
                           ("Start/stop", "Cyclically"))
    DPT_InputSource = DPT("1.014", "Input source", ("Fixed", "Calculated"))
    DPT_Reset = DPT("1.015", "Reset", ("No action", "Reset"))
    DPT_Ack = DPT("1.016", "Acknowledge", ("No action", "Acknowledge"))
    DPT_Trigger = DPT("1.017", "Trigger", ("Trigger", "Trigger"))
    DPT_Occupancy = DPT("1.018", "Occupancy", ("Not occupied", "Occupied"))
    DPT_Window_Door = DPT("1.019", "Window/Door", ("Closed", "Open"))
    DPT_LogicalFunction = DPT("1.021", "Logical function", ("OR", "AND"))
    DPT_Scene_AB = DPT("1.022", "Scene A/B", ("Scene A", "Scene B"))
    DPT_ShutterBlinds_Mode = DPT(
        "1.023", "Shutter/Blinds mode",
        ("Only move Up/Down", "Move Up/Down + StepStop"))

    def __init__(self, dptId):
        super(DPTXlatorBoolean, self).__init__(dptId, 0)

    def checkData(self, data):
        if data not in (0x00, 0x01):
            try:
                raise DPTXlatorValueError("data %s not in (0x00, 0x01)" %
                                          hex(data))
            except TypeError:
                raise DPTXlatorValueError("data not in (0x00, 0x01)")

    def checkValue(self, value):
        if value not in self._dpt.limits and value not in self.DPT_Generic.limits:
            raise DPTXlatorValueError("value %d not in %s" %
                                      (value, str(self._dpt.limits)))

    def dataToValue(self, data):
        value = self._dpt.limits[data]
        #Logger().debug("DPTXlatorBoolean.dataToValue(): value=%d" % value)
        return value

    def valueToData(self, value):
        #Logger().debug("DPTXlatorBoolean.valueToData(): value=%d" % value)
        self.checkValue(value)
        data = self._dpt.limits.index(value)
        #Logger().debug("DPTXlatorBoolean.valueToData(): data=%s" % hex(data))
        return data

    def dataToFrame(self, data):
        return bytearray(struct.pack(">B", data))

    def frameToData(self, frame):
        data = struct.unpack(">B", str(frame))[0]
        return data
Ejemplo n.º 15
0
class DPTXlatorTime(DPTXlatorBase):
    """ DPTXlator class for Time (N3U5r2U6r2U6) KNX Datapoint Type

     - 3 Byte: NNNHHHHH rrMMMMMM rrSSSSSS
     - N: Week day [0:7]
     - H: Hour [0:23]
     - M: Minute [0:59]
     - S: Second [0:59]
     - r: reserved (0)

    .
    """
    DPT_Generic = DPT("10.xxx", "Generic", (0, 16777215))

    DPT_TimeOfDay = DPT("10.001", "Time of day",
                        ((0, 0, 0, 0), (7, 23, 59, 59)))

    def __init__(self, dptId):
        super(DPTXlatorTime, self).__init__(dptId, 3)

    def checkData(self, data):
        if not 0x000000 <= data <= 0xffffff:
            raise DPTXlatorValueError("data %s not in (0x000000, 0xffffff)" %
                                      hex(data))

    def checkValue(self, value):
        for index in range(4):
            if not self._dpt.limits[0][index] <= value[
                    index] <= self._dpt.limits[1][index]:
                raise DPTXlatorValueError("value not in range %r" %
                                          repr(self._dpt.limits))

    def dataToValue(self, data):
        wDay = (data >> 21) & 0x07
        hour = (data >> 16) & 0x1f
        min_ = (data >> 8) & 0x3f
        sec = data & 0x3f
        value = (wDay, hour, min_, sec)
        #Logger().debug("DPTXlatorTime._toValue(): value=%d" % value)
        return value

    def valueToData(self, value):
        # add from string and from int (sec)?
        wDay = value[0]
        hour = value[1]
        min_ = value[2]
        sec = value[3]
        data = wDay << 21 | hour << 16 | min_ << 8 | sec
        #Logger().debug("DPTXlatorTime.valueToData(): data=%s" % hex(data))
        return data

    def dataToFrame(self, data):
        data = [(data >> shift) & 0xff for shift in range(16, -1, -8)]
        return bytearray(struct.pack(">3B", *data))

    def frameToData(self, frame):
        data = struct.unpack(">3B", str(frame))
        data = data[0] << 16 | data[1] << 8 | data[2]
        return data

    @property
    def weekDay(self):
        wDay = self.value[0]
        hour = self.value[1]
        min_ = self.value[2]
        sec = self.value[3]
        if wDay == 0:
            format_ = "No day"  # "No day, %H:%M:%S"
        else:
            format_ = "%a"
        s = time.strftime(format_, (0, 0, 0, hour, min_, sec, wDay - 1, 0, 0))
        return s

    @property
    def hour(self):
        return self.value[1]

    @property
    def minute(self):
        return self.value[2]

    @property
    def second(self):
        return self.value[3]