Skip to content

DDF support Tuya manufacturer specific cluster - #5868

Merged
manup merged 2 commits into
dresden-elektronik:masterfrom
manup:ddf_tuya
Mar 16, 2022
Merged

manup merged 2 commits into
dresden-elektronik:masterfrom
manup:ddf_tuya

Conversation

@manup

@manup manup commented Mar 15, 2022 •

Copy link
Copy Markdown
Member

This PR adds support of DDF "read", "write" and "parse" functions for the Tuya manufacturer specific cluster (0xEF00).

Example: MoesGo Smart Dimmer Module (_TZE200_e3oitdyu): (PR #5869)

[
        {
          "name": "state/on",
          "parse": {"fn": "tuya", "dpid": 1, "eval": "Item.val = Attr.val;" },
          "write": {"fn": "tuya", "dpid": 1, "dt": "0x10", "eval": "Item.val == 1 ? 1 : 0;"},
          "read": {"fn": "tuya"},
          "refresh.interval": 300
        },
        {
          "name": "state/bri",
          "parse": {"fn": "tuya", "dpid": 2, "eval": "Item.val = (Attr.val / 1000.0) * 254.0;"},
          "write": {"fn": "tuya", "dpid": 2, "dt": "0x2b", "eval": "(Item.val / 254.0) * 1000.0;"},
          "read": {"fn": "none"}
        }
]
  1. The parse function needs to specify the datapoint dpid to be parsed. The actual data type is part of the message and processed accordingly.

  2. The write function further has to specify the data type via dt with a subset of ZCL data types:

          bool           0x10
          s32 value      0x2b
          enum           0x30
          8-bit bitmap   0x18
          16-bit bitmap  0x19
          32-bit bitmap  0x1b

In C++ code the write function is best used by the StateChange class, as this PR does for REST-API PUT /lights/<id>/state endpoint when settings {"on": bool, "bri": number}. This has the benefit that if commands didn't workout they are repeated automatically. ... more on that soon in the updated docs.

  1. The read function is special and must only be specified on one item (here state/on). It doesn't actually read a single value but triggers the Tuya device to report all datapoints.

The read and parse functions are available via DDF editor, write will be added soon

image


How to know which datapoints a Tuya device provides?

Exec the Data Query command in the Cluster Info panel of the Tuya specific cluster:

image

After a few seconds the debug log shows incoming reports for all datapoints.

02:35:23:168 TY_DATA_REPORT: seq 455, dpid: 0x03, type: 0x02, length: 4, val: 18328
02:35:23:279 TY_DATA_REPORT: seq 456, dpid: 0x01, type: 0x01, length: 1, val: 1
02:35:23:393 TY_DATA_REPORT: seq 457, dpid: 0x07, type: 0x01, length: 1, val: 0
02:35:23:512 TY_DATA_REPORT: seq 458, dpid: 0x02, type: 0x02, length: 4, val: 1000
02:35:23:822 TY_DATA_REPORT: seq 459, dpid: 0x08, type: 0x02, length: 4, val: 1000
02:35:24:391 TY_DATA_REPORT: seq 462, dpid: 0x09, type: 0x02, length: 4, val: 0
02:35:24:485 TY_DATA_REPORT: seq 463, dpid: 0x04, type: 0x04, length: 1, val: 0
02:35:24:595 TY_DATA_REPORT: seq 464, dpid: 0x0A, type: 0x04, length: 1, val: 0

Note the type here is the Tuya data type not the ZCL data type.

          raw     0x00
          bool    0x01
          value   0x02
          string  0x03
          enum    0x04
          bitmap  0x05

@manup
manup requested a review from Smanar March 15, 2022 01:44
@manup manup added this to the v2.15.0-beta milestone Mar 15, 2022
@manup

manup commented Mar 15, 2022

Copy link
Copy Markdown
Member Author

@SwoopX I have changed the compare operator to not overwrite different existing StateChange objects if they are different:

Might not be the best solution but should work for the issue you've seen.

bool StateChange::operator==(const StateChange &other) const
{
     if (m_changeFunction == other.m_changeFunction && m_items.size() == other.m_items.size())
     {
         for (size_t i = 0; i < m_items.size(); i++)
         {
             if (m_items[i].suffix != other.m_items[i].suffix)
             {
                 return false;
             }
         }
         return true;
     }
     return false;
}

@SwoopX

SwoopX commented Mar 15, 2022

Copy link
Copy Markdown
Collaborator

@manup That's great, thanks. I also fiddled something together doing the trick, however, you know the code better than me and probably know the better approach.

Happy to give it a test for the device I'm currently on this evening.

@Smanar

Smanar commented Mar 15, 2022 •

Copy link
Copy Markdown
Collaborator

So much to read ^^

    Example MoesGo switch TY_DATA_REPORT
    00 4c        sequence number
    02           DPID
    02           Type: Value
    00 04        Length: 4
    00 00 00 15

You have better documentation than me ? Because on mine it s

    00 4c        sequence number
    02           DPID
    02           Type: Value
    00           Fn
    04        Length: 4
    00 00 00 15

But no more information on what id fn, execpt it s always 00

The parse function needs to specify the datapoint dpid to be parsed. The actual data type is part of the message and processed accordingly.

I haven't checked the code yet, but you are sure it s not hazardous to not use the datapoint AND the type ?

"parse": {"fn": "tuya", "dpid": 1, "eval": "Item.val = Attr.val;" },

What will happen if we have for exemple 2 return with the same dpid but 2 different types ?
For exemple, both wih dpid 0x02
0x01 0x02 on / off for a switch type 01 bool
0x02 0x02 set level for a switch type 02 value

@manup

manup commented Mar 15, 2022

Copy link
Copy Markdown
Member Author

So much to read ^^

    Example MoesGo switch TY_DATA_REPORT
    00 4c        sequence number
    02           DPID
    02           Type: Value
    00 04        Length: 4
    00 00 00 15

You have better documentation than me ? Because on mine it s

    00 4c        sequence number
    02           DPID
    02           Type: Value
    00           Fn
    04        Length: 4
    00 00 00 15

But no more information on what id fn, execpt it s always 00

Not sure if my docs are better, but I simply followed the Tuya description, here is no fn mentioned only a 2 bytes length, given that all is big-endian it makes sense for numbers < 256 that the first byte is always 0 :)

https://developer.tuya.com/en/docs/iot-device-dev/tuya-zigbee-universal-docking-access-standard?id=K9ik6zvofpzql

The parse function needs to specify the datapoint dpid to be parsed. The actual data type is part of the message and processed accordingly.

I haven't checked the code yet, but you are sure it s not hazardous to not use the datapoint AND the type ?

"parse": {"fn": "tuya", "dpid": 1, "eval": "Item.val = Attr.val;" },

What will happen if we have for exemple 2 return with the same dpid but 2 different types ? For exemple, both wih dpid 0x02 0x01 0x02 on / off for a switch type 01 bool 0x02 0x02 set level for a switch type 02 value

It's only a guess, I'd assume that a specific datapoint for one device has always the same type, but I could be wrong here. Do you know any devices which use one datapoint with different types?

DDF support can be easily added if needed.

@manup

manup commented Mar 16, 2022

Copy link
Copy Markdown
Member Author

Merging this for now to get the other PRs which depend on this in.

If needed the "dt" parameter for the "parse" function can be added in a further PR.

@manup
manup merged commit 9f26cd6 into dresden-elektronik:master Mar 16, 2022
@Smanar

Smanar commented Mar 16, 2022

Copy link
Copy Markdown
Collaborator

It's only a guess, I'd assume that a specific datapoint for one device has always the same type, but I could be wrong here. Do you know any devices which use one datapoint with different types?

Posssible, the dimmer switch for exemple (from my previous post) , but can't confirm a model, will see on usage.

@manup

manup commented Mar 16, 2022

Copy link
Copy Markdown
Member Author

Guess we should check what the logs say about available datapoints, can be triggered from Cluster Info panel of the Tuya specific cluster in the new release.

image

@BabaIsYou

Copy link
Copy Markdown
Contributor

FYI, I made a wiki page from this PR ... feel free to update it if needed https://github.com/dresden-elektronik/deconz-rest-plugin/wiki/DDF-support-Tuya-manufacturer-specific-cluster-&-How-to-know-which-datapoints-a-Tuya-device-provides%3F

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants