dresden-elektronik / deconz-rest-plugin

deCONZ REST-API plugin to control ZigBee devices
BSD 3-Clause "New" or "Revised" License
1.9k stars 503 forks source link

Add support for Tuya (Abalon, Zemismart, ...) Curtain Motor #7548

Closed thertweck closed 7 months ago

thertweck commented 9 months ago

Is there already an existing issue for this?

Product name

Abalon Motorized Curtains, Zemismart Smart Curtain

Manufacturer

_TZE200_rmymn92d

Model identifier

TS0601

Device type to add

Other

Node info

node_info

Endpoints and clusters

clusters

Basic

basic

Further relevant clusters

Tuya Specific (EF00)

Does not show any attributes.

Mimiix commented 9 months ago

@Smanar is anything missing?

Smanar commented 9 months ago

Yep a support for tuya covering using DDF ^^. For the moment not possible using DDF for covering, siren or other device using the tuya cluster and need other command than state/on or state/bri.

thertweck commented 9 months ago

I see, thank you for the swift feedback! There seems to be some preliminary support though, right? E.g. here, here and here. In particular the YS-MT750 device also looks very similar to the ones I got. I'd be happy to work on this if it's in scope currently. Would appreciate any pointers on where to start though.

ebeasant-arm commented 9 months ago

Hi there @thertweck : I'm also looking at Tuya Cluster using blinds (AM43, see current bugs) and would be happy help out as well.

The DDF can be used to recognise and bind the device, but IIRC there is a missing property that associates between the open/close condition of the resource, and sending commands to the Tuya cluster to achieve it. There's an On/Off hack, but it's very unsatisfactory.

The current legacy Tuya code for window coverings is somewhat hit/miss in terms of actually getting the bindings to work, so a longer term transition to DDF for them would be amazing! (If it's technically possible....)

Smanar commented 9 months ago

The support using the legacy code is possible but

It's possible to using a "hacky DDF" but unoffocial too, using state/on for open and state/bri for lift.

thertweck commented 9 months ago

@ebeasant-arm Thank you for the pointer, I'll have a look! IIUC bindings are for direct device to device communication, circumventing the gateway? For me that would be secondary, since I'm using iobroker anyway to "bind" devices also apart from the Zigbee network.

@Smanar That sounds great, it would be amazing to have a temporary hacky solution - no problem compiling deconz. Also if it's easier, a hacky DDF would be ok for me too. Would the idea be to use "state/on" / "state/bri" together with fn: "tuya" to map it to the correct dpids?

Smanar commented 9 months ago

Here you have a post where we make a "hacky DDF" for a covering https://github.com/dresden-elektronik/deconz-rest-plugin/issues/5960#issuecomment-1616634196

The procedure is explained.

I can help you to find dpid if needed. Or I can make you a c++ branch to support your device, but it meen a every new deconz version you need to re complile the code again.

What do you prefering ?

github-actions[bot] commented 9 months ago

As there has not been any response in 21 days, this issue has been automatically marked as stale. At OP: Please either close this issue or keep it active It will be closed in 7 days if no further activity occurs.

nabossha commented 8 months ago

@thertweck did you find a solution to control your device without applying the "light"-hack? i have an identical device and can only control open/close via REST API but not "stop" as lights only have a boolean on/off value. any advice/hint would be appreciated!

thertweck commented 8 months ago

Just got to work on this again as I now have one of the tracks properly installed.

@Smanar I followed the thread you mentioned with some success. I couldn't get the "on" attribute to work properly though. I think the reason is that after moving in one direction, the curtain will move a slight bit in the opposite direction again (e.g. when closing the curtain, it will reach the end position and then open again just a little bit). I assume (but I have to double check) that in this situation the curtain would report "close" while closing, "stop" when reaching the end position and then report "open" for a fraction of a second while moving back. I think this also explains what @patrusco observed in the other thread.

The "bri" attribute (with dpid 2 on the curtain) however does work well and that is absolutely sufficient for me, since I'm using this through iobroker / yahka and Alexa anyway.

I tried faking the "on" attribute based on dpid 2 - was thinking to do something like:

"write": {
    "dpid": 2,
    "dt": "0x2b",
    "eval": "Item.val == 1 ? 100 : 0;",
    "fn": "tuya"
},
"parse": {
     "dpid": 2,
     "eval": "Item.val = Attr.val > 0;",
     "fn": "tuya"
}

But that didn't work, maybe two attributes cannot use the same dpid? Now I'm just using a static value for on, which makes the deconz adapter in iobroker happy.

What's a little odd though is that the motor doesn't report position updates when using the curtain's remote or when moving the curtain manually. Even though the curtain is closing and position would go to 0 in reality, the value available in deconz is e.g. still 255 (fully open).

Not sure whether the refresh.interval is a solution to this - I tried, but it didn't make a difference.

The curtain reporting its real position is however very useful for UIs like Homekit, where one always has a "current" position and a "target" position. That allows to visualize the direction in which movement happens as well as detecting when the requested movement is finished (when current == target). I'm currently faking this too in iobroker, by estimating the time it would take for a movement to finish and am setting current = target after this time. That works well so far, since the curtain motors move fairly deterministically.

@nabossha I don't have a solution for the "on" attribute, but for me percentage control is sufficient. Instead of requesting "open" and then "stop" at the position I want, I can just directly have the curtain move to a certain position.

Smanar commented 8 months ago

The "bri" field is a numeric value in percent. It's the "lift" value on classic covering. Can use like in previous post


        {
          "name": "state/bri",
          "parse": {"fn": "tuya", "dpid": 2, "eval": "Item.val = (Attr.val / 100.0) * 254.0;"},
          "write": {"fn": "tuya", "dpid": 2, "dt": "0x2b", "eval": "(Item.val / 254.0) * 100.0;"},
          "read": {"fn": "none"}
        }

refresh.interval is useless, the tuya cluster don't use it.

thertweck commented 8 months ago

Right, I'm currently doing exactly that and it's working great so far. Thank you for all the pointers. Only problem is, that the curtain motor doesn't report its position when a movement is triggered from outside of deconz (via the remote or manual operation). But that's not a big issue for me at the moment, I'd use Homekit or Alexa for interacting with the curtain most of the time anyway.

But is it true that two attributes cannot use the same dpid? Because what I was trying to say above was that I'd like to use dpid 2 for the "bri" state as you mentioned above but also for the "on" state with the write and parse fns from the previous post (mapping it to a boolean value). This could be used to work around the issue with dpid 1 being unreliable on that motor.

Just curious: Is there a reason you're using 254 as the maximum value in the eval? I was assuming this is a byte, with maximum value 255. But not sure what this might cause under the hood. Is 255 treated in a special way somewhere else?

Smanar commented 8 months ago

Only problem is, that the curtain motor doesn't report its position when a movement is triggered from outside of deconz (via the remote or manual operation). But that's not a big issue for me at the moment, I'd use Homekit or Alexa for interacting with the curtain most of the time anyway

With deconz log enabled "info+info_l2" you will see all request made by the device, so can take a look if the device don't make one or if we miss it.

But is it true that two attributes cannot use the same dpid?

No, it's not a problem, there is lot of DDF that are using the same dpid or attribute for different field.

Is there a reason you're using 254 as the maximum value in the eval?

Yes, probably ^^, good question (I will ask to other devs by curiosity) it's same in native code for classic covering https://github.com/dresden-elektronik/deconz-rest-plugin/blob/master/window_covering.cpp#L200 But honneslty I don't see the utility for tuya covering.

Smanar commented 8 months ago

@thertweck I have the answer from Ebaauw

Because the max value for Current Level is 254, as defined in the Level Control cluster

github-actions[bot] commented 7 months ago

As there has not been any response in 21 days, this issue has been automatically marked as stale. At OP: Please either close this issue or keep it active It will be closed in 7 days if no further activity occurs.

github-actions[bot] commented 7 months ago

As there has not been any response in 28 days, this issue will be closed. @ OP: If this issue is solved post what fixed it for you. If it is not solved, request to get this opened again.