xknx: Wrong structure of DPT 251.600 payload in remote_value_color_rgbw.py

The structure of the DPT 251.600 payload in file remote_value_color_rgbw.py is wrong.

It should be:

Structure of DPT 251.600

  • Byte 0: R value
  • Byte 1: G value
  • Byte 2: B value
  • Byte 3: W value
  • Byte 4: 0x00 (reserved)
  • Byte 5:
    • Bit 0: W value valid?
    • Bit 1: B value valid?
    • Bit 2: G value valid?
    • Bit 3: R value valid?
    • Bit 4-7: 0

The bitfield which defines whether an value (R,G,B,W) is valid or not should be in the last byte of the array and not at the beginning. This can be verified by trying to send a DPT 251.600 telegram in the BUS monitor of the ETS5 application.

In the following I already added a fix for this issue (function to_knx() and from_knx() in remote_value_color_rgbw.py):

    def to_knx(self, value):
        """
        Convert value (4-6 bytes) to payload (6 bytes).

        * Structure of DPT 251.600
        ** Byte 0: R value
        ** Byte 1: G value
        ** Byte 2: B value
        ** Byte 3: W value
        ** Byte 4: 0x00 (reserved)
        ** Byte 5:
        *** Bit 0: W value valid?
        *** Bit 1: B value valid?
        *** Bit 2: G value valid?
        *** Bit 3: R value valid?
        *** Bit 4-7: 0

        In case we receive
        * > 6 bytes: error
        * 6 bytes: all bytes are passed through
        * 5 bytes: 0x0f right padding
        * 4 bytes: 0x000f right padding
        * < 4 bytes: error
        """
        if not isinstance(value, (list, tuple)):
            raise ConversionError("Cannot serialize RemoteValueColorRGBW (wrong type, expecting list of 4-6 bytes))",
                                  value=value, type=type(value))
        if len(value) < 4 or len(value) > 6:
            raise ConversionError("Cannot serialize value to DPT 251.600 (wrong length, expecting list of 4-6 bytes)",
                                  value=value, type=type(value))
        rgbw = value[:4]
        if any(not isinstance(color, int) for color in rgbw) \
                or any(color < 0 for color in rgbw) \
                or any(color > 255 for color in rgbw):
            raise ConversionError("Cannot serialize DPT 251.600 (wrong RGBW values)", value=value)
        return DPTArray(list(value) + [0x00, 0x0f][len(value)-4:])

    def from_knx(self, payload):
        """
        Convert current payload to value. Always 4 byte (RGBW).

        If one element is invalid, use the previous value. All previous element
        values are initialized to 0.
        """
        result = []
        for i in range(0, len(payload.value) - 2):
            valid = (payload.value[5] & (0x08 >> i)) != 0  # R,G,B,W value valid?
            result.append(payload.value[i] if valid else self.previous_value[i])
        self.previous_value = result
        return result

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 28 (27 by maintainers)

Most upvoted comments

@marvin-w , @dstrigl: finally managed to test the PR. It doesn’t work for me … unfortunately. Colour control and status completely useless. I’ll try to contact MDT and ask them how their devices are supposed to work.

Will keep you posted.

@marvin-w will do one I am back home and find some free time. @dstrigl: thanks!

We cannot accept this PR if it breaks stuff for other people that before the PR worked fine.

That’s clear!

If MDT doesn’t supply a useful answer maybe we should just implement a feature toggle of some sort (or implement a reverse DPT) that you can switch between even if that sucks.

That would really suck. There should be a clear statement from the KNX Association how the DPT 251.600 should look like.

True. Honestly, from what I see I believe the PR is actually doing it right. It would also reflect the bitorder in ETS, so lets wait for MDT.

The official KNX specification doesn’t contain this DPT, unfortunetly.