Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use custom clusters for casting Tuya spell #2287

Merged
merged 17 commits into from
Mar 28, 2023

Conversation

TheJulianJES
Copy link
Collaborator

@TheJulianJES TheJulianJES commented Mar 21, 2023

This addresses a part of #2271
This is not a final solution forever though. This should be improved when significant parts of ZHA and zha-quirks change.

IMO, the current "solution" is far worse, as it creates a task to read attributes in a class constructor. So the only time this happens when it's useful is when the device is first added and the quirk is initialized.
Re-pairing or re-configuring do not cast the spell again (as the quirk class is already loaded). (This often causes problems)
Reading attributes during restarting (when the device was added previously) is also broken with the current implementation.
Some tests are also left in a bad state with the current implementation.

This new implementation currently requires all Tuya devices that need the spell to implement a subclass of TuyaEnchantableCluster and set the TUYA_SPELL attribute to True or inherit EnchantedDevice (which just sets TUYA_SPELL to True). This is somewhat to provide backwards compatibility with custom quirks (although those quirks need to implement a subclass of TuyaEnchantableCluster which should be given for most "enchantable" Tuya devices though).

This all needs to be checked and tested still, but from what I can see, all devices that are currently an EnchantedDevice already implement a subclass of TuyaEnchantableCluster. So the spell will work properly for them now.
(only one remote needed to be changed in this PR)

Test code to "dynamically inject" into clusters that are bound (although the code only does it for OnOff) is provided in this comment when expanding: #2271 (comment)
I wouldn't go with that approach though, as it's way too much of a hack. I think the solution implemented here is the best we can do at the moment. A proper solution will require multiple changes in ZHA, zigpy, and possibly zha-quirks from what I can see.
IMO, I would go with this for now to fix the current implementation.

Another PR should also move the LIDL quirk into Tuya classes and make it use EnchantedDevice.

@TheJulianJES TheJulianJES added the Tuya Request/PR regarding a Tuya device label Mar 21, 2023
@coveralls
Copy link

coveralls commented Mar 21, 2023

Pull Request Test Coverage Report for Build 4515141014

  • 19 of 19 (100.0%) changed or added relevant lines in 3 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.02%) to 83.984%

Totals Coverage Status
Change from base Build 4514482681: 0.02%
Covered Lines: 6922
Relevant Lines: 8242

💛 - Coveralls

@MattWestb
Copy link
Contributor

Only one side not for implement in the right way it must being sent is between the device have get the network key and before its requesting / getting the updated TC-Link key and the last millisecond is then the device is doing device accouterments after have confirming the valid of the TC-Link key but i think then its too later for device that need it then being in init mode..
So the problem is how fast the coordinator is reading the device descriptions / attributes so the system is knowing it one tuya device that need the spell.
One way that is very ugly is sending it to all joining devices but can doing problems with some other brands.

@TheJulianJES
Copy link
Collaborator Author

At the moment, there's no way to do this properly and that early in the pairing process.
I'd expect that Z2M also doesn't do it that early? And the current code (reading in the constructor of the quirk) also doesn't do it that early? Does the binding happen way later than that?

What happens if the spell is cast later? Does the device still "unlock" with the only difference being that the signature might look differently?

@MattWestb
Copy link
Contributor

It is possible doing with EZSP then tuya is doing it with standard firmware in there ZBGW but that is out of this question then its only Bellows and we must doing it with all radios.
If the timing is not OK = fast enough and the device have updating the TC-Link key OK and doing device accouterments its have doing the INIT and most devices is also sending one permit join with time 180 = over and out.

With the TS004F is only sending commands from EP1 and nothing from EP 2-4 if being too late and the device have not getting one spell after being retested and the battery was out (only one its keeping the spell) and the user is not getting the device working until the spell is casted then the device its in INIT mode.

Many other devices is not need it in INIT mode (only devices that doing "hardware changes" like adding EPs and so on must having it in the INIT mode) and can being done every time but then sniffing tuya ZBGW they is configuring the device network parameters and then sending one leave with rejoin flag sett and the device is rejoining and is being in INIT mode and the ZBGW is first casting the spell and then doing normal other configuration of it that was not done in the first phase.
I was testing getting sending leave with rejoin flag from quirk but was not getting it working (the flags was not implemented in the code) so was testing with doing the casting first in the quirk looks working 100% in current (Z)HA but can being broken in the future with code changes.

@TheJulianJES
Copy link
Collaborator Author

With the TS004F is only sending commands from EP1 and nothing from EP 2-4 if being too late

So this PR would cast the spell again when reconfiguring the device through the UI. Without re-pairing, would reconfiguring (so casting the spell after it's in the network) make that device magically work? (so sending commands on the other endpoints)

@MattWestb
Copy link
Contributor

If its casting the spell then doing reconfigure its helping may devices that dont need it in INIT mode and user dont need deleting the device and joining it new the device for getting it working.
But for TS004F and some other device its not making any bad things but the code must casting the spell then its joining devices new then the device is in IINIT mode or its not working.

I can testing it but after the IKEA changes that is waiting or one to 2 week now than i cant having 10 different devices is test mode in 3 different test systems (i have getting my windows 10 WSL not working after some aggressive device cleaning so i cant using it for fast testing).

Then i need sniffing the device then joining and resetting it and removing the battery and verifying its that it have loosing the spell and then applying the patch and see its applying it and working well and redoing the same at least 10 times for knowing its working well as it doing today so users is not getting problems in the future and we is hunting problems we have implanting in the code and making some devices not working OK all the time and getting many strange issues from our users.

@MattWestb
Copy link
Contributor

I was putting the INITs in the HA container and patching the device class to not use the EnchantedDevice and only CustomDevice and they was already using the TuyaSmartRemoteOnOffCluster in replacment so i think the casting shall working then its getting it from tuya INIT. But with wireshark is only doing binding and also then doing reconfigure.

Did i making somthing wrong ??

Used files the device quirk in cunstom quirk and the INITs in the HA container.
Homeassistant_Bellows.zip

@TheJulianJES
Copy link
Collaborator Author

TheJulianJES commented Mar 24, 2023

From the PR description:

This new implementation currently requires all Tuya devices that need the spell to implement TuyaEnchantableOnOffCluster (or a subclass of it) AND set the TUYA_SPELL attribute to True or inherit EnchantedDevice (which just sets TUYA_SPELL to True).

You can use any Tuya OnOff cluster (that implements TuyaEnchantableOnOffCluster).
TuyaSmartRemoteOnOffCluster does that. However, that cluster will only cast the spell if the TUYA_SPELL attribute is set to True for the device.

When applying all changes from this PR, this is the new EnchantedDevice:

class EnchantedDevice(CustomDevice):
    TUYA_SPELL = True

So it just sets the TUYA_SPELL attribute to True. The TuyaEnchantableOnOffCluster (or classes that inherit that) then check if that attribute is set to True and if so, they cast the spell when binding.

So in order for the spell to apply, ideally you just inherit from that new EnchantedDevice, but you can also only inherit from CustomDevice and set TUYA_SPELL = True:

class SomeTuyaDevice(CustomDevice):
    """Tuya device."""

    TUYA_SPELL = True

    signature = {...

But ideally, the device quirks all stay the same. All quirks which use a custom Tuya OnOff cluster (all of them should extend TuyaEnchantableOnOffCluster with the changes of this PR) and still inherit (from the now new) EnchantedDevice will cast the spell.
So the quirks can basically stay as-is, you just need to import the new EnchantedDevice and the new/custom Tuya OnOff clusters.

@codecov-commenter
Copy link

codecov-commenter commented Mar 24, 2023

Codecov Report

Patch coverage: 100.00% and project coverage change: +0.06 🎉

Comparison is base (892b87b) 83.91% compared to head (c4ebc5d) 83.98%.

📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more

Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #2287      +/-   ##
==========================================
+ Coverage   83.91%   83.98%   +0.06%     
==========================================
  Files         260      261       +1     
  Lines        8214     8242      +28     
==========================================
+ Hits         6893     6922      +29     
+ Misses       1321     1320       -1     
Impacted Files Coverage Δ
zhaquirks/tuya/__init__.py 76.33% <100.00%> (+0.71%) ⬆️
zhaquirks/tuya/mcu/__init__.py 99.48% <100.00%> (-0.02%) ⬇️
zhaquirks/tuya/sm0202_motion.py 100.00% <100.00%> (ø)
zhaquirks/tuya/ts000x.py 100.00% <100.00%> (ø)
zhaquirks/tuya/ts0041.py 100.00% <100.00%> (ø)
zhaquirks/tuya/ts0042.py 100.00% <100.00%> (ø)
zhaquirks/tuya/ts0043.py 100.00% <100.00%> (ø)
zhaquirks/tuya/ts0044.py 100.00% <100.00%> (ø)
zhaquirks/tuya/ts0046.py 100.00% <100.00%> (ø)
zhaquirks/tuya/ts004f.py 100.00% <100.00%> (ø)
... and 1 more

... and 1 file with indirect coverage changes

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@TheJulianJES
Copy link
Collaborator Author

TheJulianJES commented Mar 24, 2023

Hmm, I'll need to have a look at how to deal with devices that use multiple enchantable clusters (so on multiple endpoints).
The issue is that I don't know if bind() on another endpoint is called through a reconfiguration or because it's another endpoint.

It would all be easier if there's something like a "pre-bind" function that always gets called (even on the Basic cluster).

@MattWestb
Copy link
Contributor

Hold your horses @TheJulianJES !!

I have getting it working and its very good only then adding the TUYA_SPELL = True but its taking time getting the device in not spell mode and variegating its without and then adding it agen and testing.

For the moment i testing adding it and its getting spell and then resetting the device and taking out the battery before its rejoining for loosing the spell and then resetting it and letting it rejoining without getting spell and later doing reconfigure.
I have getting 2 times the reconfigure is fixing the device but i need waiting longer time and more test for see if its 100%.

Shall i putting the last commitment or is it OK running the test with the 1d36fb4 ?

@TheJulianJES
Copy link
Collaborator Author

The latest commit will only "cast the spell" before actually binding the OnOff cluster. (Previously, it first bound the OnOff cluster and then cast the spell)
Not sure if it makes any real difference though.

@MattWestb
Copy link
Contributor

I have looking and all the times i have getting it working is the spell casted before the device is requesting updating the TC-Link key and it shall being in the safe time window but i testing more for see i can repeating it at last 10 time with successes or i must looking if need more work.
The TS004F DMS is having 4 endpoints with OnOff on all but only one is active before it getting the casted spell and it shall being the worse device getting working OK.

@TheJulianJES
Copy link
Collaborator Author

TheJulianJES commented Mar 24, 2023

The TS004F DMS is having 4 endpoints with OnOff on all but only one is active before it getting the casted spell and it shall being the worse device getting working OK.

Yeah. But zha-quirks already replaces the 1 endpoint signature with the 4 endpoint signature, right?
So ZHA will try to read the Tuya attributes four times. (I'm not sure if that's actually an issue though, since it will only happen when pairing and on reconfiguration and re-reading those attributes should be fine?)

It looks like all quirks have an enchantable OnOff cluster on endpoint 1, so that's good.

@MattWestb
Copy link
Contributor

Its have only one EP 1 without the spell and the quirk is adding 3 new one but the sepll is only being casted one time on EP 1 (all is sniffed with wireshark) so no problems.
I think the LIDL power stripes is doing the same but it dont need it INIT mode and is one router so shall not being any problems with it.

Shall looking one more time if reconfigure is casting on all or only EP 1.

@MattWestb
Copy link
Contributor

Reconfigure is only doing EP1 and its very good and no binding of EP 2-4 = OK so not getting strange problems with the device (tuya is not doing any bindings at all on this devices).

No.	Time	PAN	Protocol	IEEE Src	IEEE Dst	Zigbee Src	Zigbee Dst	ZBN Dst	Group Nr	ZBN Seq	ZBA Seq	ZDP Seq	Nwk Seq	Src EP	Dst EP	Info
9263	17:20:48,560519	0x1a62	ZigBee HA	0xb502	0x0000	0xb502	0x0000	0x0000		202	62		247	1	1	ZCL OnOff: Unknown Command, Seq: 13
9269	17:20:48,709428	0x1a62	ZigBee	0xb502	0x0000	0xb502	0x0000	0x0000		203	80		250	1	1	APS: Ack, Dst Endpt: 1, Src Endpt: 1
9270	17:20:48,718708	0x1a62	ZigBee	0xb502	0x0000	0xb502	0x0000	0x0000		204	80		251	1	1	APS: Ack, Dst Endpt: 1, Src Endpt: 1
9473	17:21:31,367527	0x1a62	ZigBee HA	0xb502	0x0000	0xb502	0x0000	0x0000		206	63		19	1	1	ZCL OnOff: Unknown Command, Seq: 16
9491	17:21:31,694858	0x1a62	ZigBee ZDP	0xb502	0x0000	0xb502	0x0000	0x0000		208	64	148	28	0	0	Bind Response, Status: Success
9492	17:21:31,705130	0x1a62	ZigBee HA	0xb502	0x0000	0xb502	0x0000	0x0000		210	65		29	1	1	ZCL: Default Response, Seq: 150
9493	17:21:31,715313	0x1a62	ZigBee ZDP	0xb502	0x0000	0xb502	0x0000	0x0000		212	66	152	30	0	0	Bind Response, Status: Success
9494	17:21:31,724774	0x1a62	ZigBee ZDP	0xb502	0x0000	0xb502	0x0000	0x0000		214	67	154	31	0	0	Bind Response, Status: Success
9495	17:21:31,734247	0x1a62	ZigBee ZDP	0xb502	0x0000	0xb502	0x0000	0x0000		216	68	156	32	0	0	Bind Response, Status: Success
9496	17:21:31,743780	0x1a62	ZigBee ZDP	0xb502	0x0000	0xb502	0x0000	0x0000		218	69	158	33	0	0	Bind Response, Status: Success
9497	17:21:31,753901	0x1a62	ZigBee	0xb502	0x0000	0xb502	0x0000	0x0000		219	88		34	1	1	APS: Ack, Dst Endpt: 1, Src Endpt: 1
9508	17:21:32,323970	0x1a62	ZigBee HA	0xb502	0x0000	0xb502	0x0000	0x0000		221	70		40	1	1	ZCL: Configure Reporting Response, Seq: 161
9509	17:21:32,341197	0x1a62	ZigBee HA	0xb502	0x0000	0xb502	0x0000	0x0000		223	71		41	1	1	ZCL: Read Attributes Response, Seq: 163
9512	17:21:33,241892	0x1a62	ZigBee HA	0xb502	0x0000	0xb502	0x0000	0x0000		225	72		42	1	1	ZCL: Report Attributes, Seq: 18
9521	17:21:33,457538	0x1a62	ZigBee HA	0xb502	0x0000	0xb502	0x0000	0x0000		227	73		47	1	1	ZCL: Default Response, Seq: 165
9522	17:21:33,467750	0x1a62	ZigBee HA	0xb502	0x0000	0xb502	0x0000	0x0000		227	73		47	1	1	ZCL: Default Response, Seq: 165
9523	17:21:33,475744	0x1a62	ZigBee	0xb502	0x0000	0xb502	0x0000	0x0000		228	92		48	1	1	APS: Ack, Dst Endpt: 1, Src Endpt: 1
9576	17:21:47,834266	0x1a62	ZigBee HA	0xb502	0x0000	0xb502	0x0000	0x0000		230	74		53	3	1	ZCL OnOff: Unknown Command, Seq: 19
9580	17:21:47,998796	0x1a62	ZigBee	0xb502	0x0000	0xb502	0x0000	0x0000		231	93		56	3	3	APS: Ack, Dst Endpt: 3, Src Endpt: 3
9585	17:21:48,651629	0x1a62	ZigBee HA	0xb502	0x0000	0xb502	0x0000	0x0000		233	75		59	3	1	ZCL OnOff: Unknown Command, Seq: 19
9590	17:21:49,350619	0x1a62	ZigBee HA	0xb502	0x0000	0xb502	0x0000	0x0000		235	76		63	3	1	ZCL OnOff: Unknown Command, Seq: 19

And it was not casted and the EP 2-4 was not working and after reconfigure its start using them (the last OnOff command is send from EP 3) :-))))))

@TheJulianJES TheJulianJES force-pushed the tjj/tuya_spell_in_clusters_clean branch from 6778fae to abc434e Compare March 24, 2023 17:51
@MattWestb
Copy link
Contributor

I is filtering only showing commands sent from the device and its looks like this then joining it:

No.	Time	PAN	Protocol	IEEE Src	IEEE Dst	Zigbee Src	Zigbee Dst	ZBN Dst	Group Nr	ZBN Seq	ZBA Seq	ZDP Seq	Nwk Seq	Src EP	Dst EP	Info
522	17:41:33,604536	0x1a62	ZigBee ZDP	0xb502	0x0000	0xb502	Broadcast	0xfffd		247	231	129	213	0	0	Device Announcement, Nwk Addr: 0xb502, Ext Addr: SiliconL_ff:fe:fd:dc:14
523	17:41:33,615583	0x1a62	ZigBee	0xb502	0x0000	0xb502	0x0000	0x0000		248			214			End Device Timeout Request
525	17:41:33,632139	0x1a62	ZigBee ZDP	0x0000	0xffff	0xb502	Broadcast	0xfffd		247	231	129	18	0	0	Device Announcement, Nwk Addr: 0xb502, Ext Addr: SiliconL_ff:fe:fd:dc:14
526	17:41:33,649692	0x1a62	ZigBee ZDP	0xb0c4	0xffff	0xb502	Broadcast	0xfffd		247	231	129	193	0	0	Device Announcement, Nwk Addr: 0xb502, Ext Addr: SiliconL_ff:fe:fd:dc:14
535	17:41:34,019298	0x1a62	ZigBee ZDP	0xb502	0x0000	0xb502	0x0000	0x0000		252	233	98	220	0	0	Node Descriptor Response, Rev: 22, Nwk Addr: 0xb502, Status: Success
541	17:41:34,240813	0x1a62	ZigBee ZDP	0xb502	0x0000	0xb502	0x0000	0x0000		254	234	100	224	0	0	Active Endpoint Response, Nwk Addr: 0xb502, Status: Success
547	17:41:34,845877	0x1a62	ZigBee ZDP	0xb502	0x0000	0xb502	0x0000	0x0000		0	235	102	228	0	0	Simple Descriptor Response, Nwk Addr: 0xb502, Status: Success
554	17:41:35,343695	0x1a62	ZigBee HA	0xb502	0x0000	0xb502	0x0000	0x0000		2	236		231	1	1	ZCL: Read Attributes Response, Seq: 104
570	17:41:35,948966	0x1a62	ZigBee ZDP	0xb502	0x0000	0xb502	0x0000	0x0000		4	237	106	239	0	0	Bind Response, Status: Success
571	17:41:35,959772	0x1a62	ZigBee HA	0xb502	0x0000	0xb502	0x0000	0x0000		6	238		240	1	1	ZCL: Default Response, Seq: 108
572	17:41:35,969413	0x1a62	ZigBee ZDP	0xb502	0x0000	0xb502	0x0000	0x0000		8	239	110	241	0	0	Bind Response, Status: Success
573	17:41:35,979857	0x1a62	ZigBee ZDP	0xb502	0x0000	0xb502	0x0000	0x0000		10	240	112	242	0	0	Bind Response, Status: Success
574	17:41:35,987977	0x1a62	ZigBee ZDP	0xb502	0x0000	0xb502	0x0000	0x0000		12	241	114	243	0	0	Bind Response, Status: Success
575	17:41:35,998718	0x1a62	ZigBee ZDP	0xb502	0x0000	0xb502	0x0000	0x0000		14	242	116	244	0	0	Bind Response, Status: Success
585	17:41:36,408050	0x1a62	ZigBee HA	0xb502	0x0000	0xb502	0x0000	0x0000		16	243		249	1	1	ZCL: Configure Reporting Response, Seq: 118
586	17:41:36,424107	0x1a62	ZigBee HA	0xb502	0x0000	0xb502	0x0000	0x0000		18	244		250	1	1	ZCL: Read Attributes Response, Seq: 120
592	17:41:36,868340	0x1a62	ZigBee HA	0xb502	0x0000	0xb502	0x0000	0x0000		20	245		254	1	1	ZCL: Default Response, Seq: 122
600	17:41:37,323630	0x1a62	ZigBee ZDP	0xb502	0x0000	0xb502	0x0000	0x0000		22	246	130	2	0	0	Node Descriptor Request, Nwk Addr: 0x0000
601	17:41:37,334269	0x1a62	ZigBee HA	0xb502	0x0000	0xb502	0x0000	0x0000		24	247		3	1	1	ZCL: Read Attributes Response, Seq: 124
611	17:41:37,903443	0x1a62	ZigBee	0xb502	0x0000	0xb502	0x0000	0x0000		25	248		9			Request Key
612	17:41:37,912055	0x1a62	ZigBee	0xb502	0x0000	0xb502	0x0000	0x0000		26	137		10	0	0	APS: Ack, Dst Endpt: 0, Src Endpt: 0
613	17:41:37,921732	0x1a62	ZigBee HA	0xb502	0x0000	0xb502	0x0000	0x0000		28	249		11	1	1	ZCL: Read Attributes Response, Seq: 126

554 is reading manufacture and model so quirk can being matched and loaded.
586 is the spell being casted and its red before the joiner is requesting node description of the TC so its knowing if it can updating the TC-Link key or not and is doing it in frame 611.
Need doing little more test but its looks very good !!!!
Also then restarting HA its not casting the spell then the radio is not on the air as the 3 other methods used and no error in the log.

@TheJulianJES
Copy link
Collaborator Author

Rebased to fix a conflict.
I've changed the internal structure a bit, so that (theoretically) we're not as dependent on OnOff clusters, but we can also use other clusters that ZHA binds(!) in the future.

I've also added a test to make sure that all quirks which use TUYA_SPELL/EnchantedDevice also have at least one "enchantable cluster" on endpoint 1.

@TheJulianJES
Copy link
Collaborator Author

TheJulianJES commented Mar 24, 2023

I can double check later, but does ZHA also call bind() for OUTPUT_CLUSTERS or only INPUT_CLUSTERS?

Edit: Does both, but there's another issue if a cluster changes the ep_attribute ...

@MattWestb
Copy link
Contributor

MattWestb commented Mar 24, 2023

I think the check on EP 1 is very OK then tuya is always making EP 1 with basic and identify and so on (but they can changing) like many other is not doing,

Im not 100% sure that some tuya devices is using in cluster then some plugs (like LIDL power strip) can have only in clusters but normally controllers shall having out cluster (but we is doing with tuya devices here).

Can you putting TUYA_SPELL = True in TuyaZBOnOffAttributeCluster and TuyaSmartRemoteOnOffCluster classes that all this devices is needing the spell and we have converted most of them to TuyaEnchantableCluster in the quirks and its little double wok doing it in the quirk and i think if we is finding one that dont can handling it we can putting false in one new device class for fixing it.

Then you have getting all tests working OK give my one sign and i installing the lasts commit and redoing most of the testing but its taking time doing it well for being sure and i think we and @javicalle dont like braking devices for our users so i like being sure its working OK.

@TheJulianJES
Copy link
Collaborator Author

Can you putting TUYA_SPELL = True in TuyaZBOnOffAttributeCluster and TuyaSmartRemoteOnOffCluster classes that all this devices is needing the spell and we have converted most of them to TuyaEnchantableCluster in the quirks and its little double wok doing it in the quirk and i think if we is finding one that dont can handling it we can putting false in one new device class for fixing it.

The TUYA_SPELL attribute is used on a device level. The TuyaEnchantableCluster is used on a cluster level.
For a device, it's preferred to keep inheriting EnchantedDevice (which then sets TUYA_SPELL).

As long as the EnchantedDevices have at least one cluster that's a subclass of TuyaEnchantableCluster, they should keep getting the Tuya spell.

If a device does not have TUYA_SPELL set (so is just a CustomDevice, it won't get the spell even if they use an EnchantableCluster.
So a device both needs to have an enchantable cluster and the device needs to use TUYA_SPELL/EnchantedDevice for them to get the spell applied.

I'm still working on some stuff and doing some more testing. I'll need to have a look at when ZHA exactly calls bind() too.

@TheJulianJES
Copy link
Collaborator Author

TheJulianJES commented Mar 24, 2023

Uhh, I see why TuyaSmartRemoteOnOffCluster is not working for the spell. ZHA doesn't call bind(), as that cluster changes the ep_attribute.

... did we ever confirm if the remotes actually need the spell? If yes, we have an issue lol
But I guess we could hijack the PowerConfiguration cluster for those? But it'll conflict slightly (at first) with these changes:

... uh, the TuyaSmartRemote004FROK quirks also use TuyaSmartRemoteOnOffCluster which changes the ep_attribute, but they're also not battery-powered, so this is becoming a bit more messy than I wanted it to

EDIT: Nvm, they have a PowerConfiguration cluster. Do we also want to prevent binding for the PowerConfiguration cluster: #2288 for those?
EDIT 2: Z2M doesn't do it for those, so let's not to it either, I guess?

@MattWestb
Copy link
Contributor

You have without spell in #2287 (comment) and was only sending command OnOff from EP1 and after the spell its was start using the new EPs.

And i using the TuyaSmartRemoteOnOffCluster plus TUYA_SPELL = True in the quirk device class and its working.

@MattWestb
Copy link
Contributor

Also not all devices that need the spell is having power config cluster like the LIDL power stripe and other plugs.

@TheJulianJES
Copy link
Collaborator Author

Also not all devices that need the spell is having power config cluster like the LIDL power stripe and other plugs.

Yeah, I was specifically talking about the remotes which use TuyaSmartRemoteOnOffCluster and that changes the ep_attribute, so ZHA doesn't call bind():

class TuyaSmartRemoteOnOffCluster(OnOff, EventableCluster):
"""TuyaSmartRemoteOnOffCluster: fire events corresponding to press type."""
rotate_type = {
0x00: RIGHT,
0x01: LEFT,
0x02: STOP,
}
press_type = {
0x00: SHORT_PRESS,
0x01: DOUBLE_PRESS,
0x02: LONG_PRESS,
}
name = "TS004X_cluster"
ep_attribute = "TS004X_cluster"

For those remotes, we could make the PowerConfiguration cluster enchantable.

And i using the TuyaSmartRemoteOnOffCluster plus TUYA_SPELL = True in the quirk device class and its working.

I'd recommend to use EnchantedDevice instead of CustomDevice (that's what quirks will keep doing). (and EnchantedDevice only sets TUYA_SPELL = True)

@TheJulianJES
Copy link
Collaborator Author

This version is not good then its triggering constant MAC pulling of its parent until i was sending commands from it.
And very likely is is the reason that its binding 0x0008, 0x0006, 0x0005, 0x0300 plus reading ZLL group that all is not needed and making the device behaving bad.

  1. Is all of the above in regards to your TS004F?
  2. If so, that devices matches the TuyaSmartRemote004FDMS quirk, correct?
  3. The changes are very minimal and can't really cause anything like that. Are you saying this behavior didn't occur before these changes? (So ZHA didn't try to configure binding and so on?)
  4. The first version for TS004F could not work, as the OnOff cluster wasn't bound, so no spell is sent. You likely still used the older EnchantedDevice.
  5. Did you replace the entire quirks library with my branch and test it then?
  6. Does the TS004F need battery binding + attribute reporting or should we block it?

@MattWestb
Copy link
Contributor

This is little role the dice hwo the system / device is doing the things.
2/3 times its working OK and 1/3 is doing it very strange (i have testing around 15 times).
Then its working OK its sending the spell then doing new joining, being retested and being joined then ZHA have its is Zogbee.DB and the being reconfigured.

Then doing reconfigure its not sending power config to the device but failing after timeout most of the time but also can doing it without errors.

I have only updating tuya INIT and the MCU INIT in the container and is having this quirk in the local folder: tu_ts004f.py.txt.

My feeling is that all the binding that is not needed that is making the problems with the timing but the good thing is looks like its fixing one device that is not having getting the spell also with reconfigure that was not possible code used before (it can being that redoing the bindings and the device is doing some configure and being in INIT mode but i dont knowing).

Im spitted if its 100% and can going in production then its not doing the same thing all the times and i dont like that. I have not getting the continues MAC pull from the device but i looking if i see it then i doing more testing and sniffing it.

This device is having the most extreme "personality" i have see !!!

Do you need more information or test being done ?

@TheJulianJES
Copy link
Collaborator Author

TheJulianJES commented Mar 26, 2023

  1. If so, that devices matches the TuyaSmartRemote004FDMS quirk, correct?

To confirm, that is the quirk that your device matches, correct?

Then doing reconfigure its not sending power config to the device but failing after timeout most of the time but also can doing it without errors.

Do you still get "Executing Tuya spell" and "Executed Tuya spell" in the logs? (Those log entries are printed by the "new Tuya spell". In between those lines, you should see if reading the attributes was successful)

You can also try to use the TuyaNoBindPowerConfigurationCluster for your device (instead of TuyaPowerConfigurationClusterEnchantable). This cluster will still do the new Tuya spell (if TUYA_SPELL = True or you're using the updated EnchantedDevice which just sets that to true), but that cluster will block binding and attribute reporting of the PowerConfiguration cluster.

@MattWestb
Copy link
Contributor

I only doing testing with TS004FDMS then its the most problematic one and later i can doing the ROK (Smart Rotating Knob).

If you looking in the attached quirk i is using the TuyaNoBindPowerConfigurationCluster.

I shall doing more testing later but i only looking in the online sniffs for see have the commands is getting to and from the device with the timing so i can looking in the log then.

@javicalle
Copy link
Collaborator

Just a side comment, if the timing is critical while casting the Tuya spell, enabling the debug logs add a significant overhead (writing to file is expensive in time) and maybe can impact in the results.

@MattWestb
Copy link
Contributor

Its one small NanoPi Neo running armbian32 RCP without OTBR and only Zigbeed and 1 IKEA VINDSTYRKA that is sitting in karantene for not getting OTA updates so its very small system but if its working OK with some debug logging its very likely not getting problem then taking it away and also in larger system but cant knowing for 100% until tested.

@TheJulianJES
Copy link
Collaborator Author

TheJulianJES commented Mar 27, 2023

Do you think we can merge this for the next HA release/beta?

It won't break any currently working devices and should be lots better than the current implementation IMO.
But I'm not sure if (or how much) timing is affected.

@MattWestb
Copy link
Contributor

I have using this for the DMS:

class TuyaSmartRemote004FDMS(EnchantedDevice):
    """Tuya 4 btton dimmer switch / remote device."""

    TUYA_SPELL = True

    signature = {
        # "node_descriptor": "NodeDescriptor(byte1=2, byte2=64, mac_capability_flags=128, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=0, *allocate_address=True, *complex_descriptor_available=False, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False, *is_valid=True, *logical_type=<LogicalType.EndDevice: 2>, *user_descriptor_available=False)",
        # SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=260, device_version=1, input_clusters=[0, 1, 3, 4, 6, 4096], output_clusters=[25, 10, 3, 4, 5, 6, 8, 4096])
        MODELS_INFO: [
            ("_TZ3000_xabckq1v", "TS004F"),
            ("_TZ3000_czuyt8lz", "TS004F"),
        ],
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.DIMMER_SWITCH,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    PowerConfiguration.cluster_id,
                    Identify.cluster_id,
                    Groups.cluster_id,
                    OnOff.cluster_id,
                    LightLink.cluster_id,
                ],
                OUTPUT_CLUSTERS: [
                    Ota.cluster_id,
                    Time.cluster_id,
                    Identify.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    OnOff.cluster_id,
                    LevelControl.cluster_id,
                    LightLink.cluster_id,
                ],
            },
        },
    }

    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    TuyaNoBindPowerConfigurationCluster,
                    Identify.cluster_id,
                    Groups.cluster_id,  # Is needed for adding group then binding is not working.
                    LightLink.cluster_id,
                    TuyaSmartRemoteOnOffCluster,
                    ],
                OUTPUT_CLUSTERS: [
                    Ota.cluster_id,
                    Time.cluster_id,
                    Identify.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaSmartRemoteOnOffCluster,
                    LevelControl.cluster_id,
                    Color.cluster_id,
                    LightLink.cluster_id,
                ],
            },
            2: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER,
                INPUT_CLUSTERS: [
                    TuyaSmartRemoteOnOffCluster,
                ],
                OUTPUT_CLUSTERS: [
                    TuyaSmartRemoteOnOffCluster,
                ],
            },
            3: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER,
                INPUT_CLUSTERS: [
                    TuyaSmartRemoteOnOffCluster,
                ],
                OUTPUT_CLUSTERS: [
                    TuyaSmartRemoteOnOffCluster,
                ],
            },
            4: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER,
                INPUT_CLUSTERS: [
                    TuyaSmartRemoteOnOffCluster,
                ],
                OUTPUT_CLUSTERS: [
                    TuyaSmartRemoteOnOffCluster,
                ],
            },
        },
    }

You must say if i have changing my quirk OK or if its somthing wrong !!

I think the timing looks good as long the system is not slowed down but then its one external problem with SD-Card or so.

Also if the spell is being casted then doing reconfigure 90% of all device is working with it and can being easy fixed for our users.

For devices that have getting the spell its shall not being one braking thing then they is keeping it and normally only need it one time then its joining the system.

First taking on look on my quirk if i have doing all right and then i doing the same tests with ROK (RotatingKnob) so we is knowing it working well.

Your last wish moving LIDL to tuya i think shall waiting after 2023.4 release so not getting all problem at the same time and we need one with the power stripe that can testing it and i have 2 but with the old good working firmware that not need the spell for working OK.

@MattWestb
Copy link
Contributor

I was copy your last tuya INIT and mcu-INIT to the container and updated the local quirk but i was not liking the power config binding so i was putting in the TuyaNoBindPowerConfigurationCluster so its not doing it.
The device is reporting battery itself then paring so its looks OK the tuya is not doing more an we is not getting battery draning if all is working as expected.

Then testing the ROK and its looks working very well but is not so tricky as the DMS.

If joining one device new its casting the spell OK as long ZHA is doing its parts OK.
Some time ZHA is reading the device OK but is displaying it as unknown then its not loading the quirk and so spell is being casted.
The good thing is looks like reconfigure is casting the spell OK and and the device is reacting at it then is reporting the mode change attribute and start using the extra functions. With the timing its also look OK then its normally being sent before the decide is requesting node description of the coordinator and start updating the TC-Link key procedure so its very early and that is good so not being the the last "minute" and can getting problems.

I think we cant getting it better and i think updating the INITs and the TS004F quirk is OK and its not braking any devices that is working for our users.
Only updating all classes in the quirk so all device is getting it. and use the TuyaNoBindPowerConfigurationCluster then its looks working better.

@javicalle
Copy link
Collaborator

javicalle commented Mar 28, 2023

I haven't reviewed all the implementation in detail (and I'm very sorry for that), but I have an idea in my head that I want to expose. Maybe is a dumb idea.

I was guessing, it would posible to cast the spell from the tuya_manufacturer cluster?
All the devices that require the spell will have it. We don't have to worry about the OnOff or the PowerConfiguration (or any other 'EnchantablefCluster').
If I had understand how it works, it would require to identify the cluster in ZHA and make it a 'fisrts class citizen'. This way, ZHA will trigger always the bind for the tuya_manufacturer cluster. And would be up to us to identify the device as a EnchantedDevice (or TUYA_SPELL = True).

What do you think?

I'm sorry to come here in the last minute when all the discuccion is already setted. I'm impressed for all the work made here I don't want to generate noise now that it seems already done.

@TheJulianJES
Copy link
Collaborator Author

Yeah, not a bad idea. I've also thought of that at one point. When I looked at it, I realized that not all (enchanted) devices even expose a Tuya manufacturer cluster (we could "fake one", but I don't know if that's the best idea).

I'm not completely sure on this, but I also think that ZHA binds the cluster from id 0 onwards, so the Tuya manufacturer cluster would probably get bound at the end which might "dramatically" delay the spell.
The PowerConfig/OnOff clusters have lower ids and basically all enchanted Tuya devices already use custom Tuya OnOff/PowerConfig ones.

This implementation definitely isn't "a final solution", but I think it's the best(?) we can do for now (until ZHA/zigpy/quirks is changed).

@MattWestb
Copy link
Contributor

Hola JC !!
You is never to late with your knowledge !!
Most "normal" tuya Zigbee device like all in the TS004F class is not having the tuya cluster then they is in ground light controller. With the rest of TS004X is little like old without and new have extra tuya clusters.
My concern is how doing it with some device like sensors and MCU devices that is not heaving OnOff cluster that we can using for triggering casting the spell.

And tuya is using normal zigbee chips with normal MAC so we cant doing like Xiami and fixing MAC range for triggering it then we is casting it on over 50% of all devices then Silicon labs is IKEA and new HUE device and many more.

@javicalle
Copy link
Collaborator

Now I can see a little more of the full picture.
Nothing more to argue from my side.

Thanks to both of you!

@MattWestb
Copy link
Contributor

You is having most experience with strange tuya device from the code side and is knowing how to tricking them. Its one mess and we must living with it then tuya have not implanting all things at all of was forgetting reading the book so in very glad i have most IKEA devices but they is not enough for functionality for all my needs.

@TheJulianJES
Copy link
Collaborator Author

TheJulianJES commented Mar 28, 2023

This isn't really related to this PR, but for the TS004F, there are four quirks/devices:

  • TuyaSmartRemote004FROK (rotating knob)
  • TuyaSmartRemote004FDMS (four button remote)
  • TuyaSmartRemote004F (four button remote)

Only the TuyaSmartRemote004F seems to use TuyaZBOnOffAttributeCluster instead of TuyaSmartRemoteOnOffCluster. From what I can see in the Z2M code, they treat them somewhat similar (only difference if the other endpoints are there)(?)
Is there a reason why the one remote uses that other custom cluster?

And Z2M binds the power configuration cluster for all of these remotes. But you're saying we don't need to do that (for all three devices)?

@TheJulianJES
Copy link
Collaborator Author

TheJulianJES commented Mar 28, 2023

Any issues with the TS004F remotes should probably be addressed in another PR. This behavior shouldn't change the current behavior.
(LIDL power strip will also need to be converted to an "enchanted Tuya device")

This one should be ready now.

@TheJulianJES TheJulianJES marked this pull request as ready for review March 28, 2023 12:20
@MattWestb
Copy link
Contributor

I have sniffing tuya ZBGW setting it up and they is doing no binding or reporting only normal Zigbee 3 joining then kicking the device then its in the network with leave and rejoin flag set and is casting the spell then its coming back in the network and then is doing nearly nothing. And our experience of the rest TS004F is not doing strange things so you not getting problems like battery draining or device leaving the network.

The TS004F is one trick then the system is first matching the device with model info and if its not being matched the device with the same cluster / EP is using the last class with only model and is getting the attribute you need changing its working mode.
If the user like have more functionality they need requesting device support for it.

We have 2 more device that is the same type but is not getting in to PR the single knob and the LIDL that i have not getting (they dont had it in AT so i was not getting any one for testing). plus one more LIDL 4 button remote but its one other TS type but is using the same commands.

@TheJulianJES TheJulianJES added the needs final review PR is ready for a final review from a maintainer label Mar 28, 2023
@MattWestb
Copy link
Contributor

Was looking little before moving both device back to the large RCP test system and the DMS is updating the battery (was 100% after last paring) it have being 100% for over one year and not is going down little an i think its the normal after having doing so mush testing with it.
TS004F06
Also its always reporting battery then pressing button 2 but i have not looking if its reporting it if letting it sleeping for some days.

@TheJulianJES
Copy link
Collaborator Author

Are we good to get this in for now? Should be somewhat "well-tested"

@MattWestb
Copy link
Contributor

My devices is working OK and have moving them to its normal system now.
If someone have more device for testing it good but i think it cant being braking for all device that need it and is already paired with ZHA.

@javicalle
Copy link
Collaborator

Sorry, no exotic devices around here 😅

@TheJulianJES TheJulianJES merged commit e341f0d into zigpy:dev Mar 28, 2023
@MattWestb
Copy link
Contributor

´Thanks J & J for the work done !!

@TheJulianJES
Copy link
Collaborator Author

Thanks for all the testing too!

@erikproper
Copy link
Contributor

erikproper commented Mar 29, 2023

Dear all,
I've had some issues regarding Zigbee devices in my apartment, and going through things sequentially in fixing this.

I have several Tuya based remotes, where I have indeed noticed a battery drain and the habit of reporting a 100% level (right up until the end ... when the battery dies).
I'm using the quirks that come with the latest (am up-to-date) home assistant release, and see that the following quirks are used (across my "fleet" of Tuya remotes):
zhaquirks.tuya.ts0042.TuyaSmartRemote0042TO
zhaquirks.tuya.ts0043.TuyaSmartRemote0043TO
zhaquirks.tuya.ts0044.TuyaSmartRemote0044TO
The 44 one seems to work well in the sense of showing an 84% battery level after a three months of use.

The 42 and 43 share the ill-behaviour as reported in this thread:

  • Battery level = 100
  • Fast draining of battery (but not all of them ... but occurs across both 42 and 43)

So ... knowing of the done/ongoing work ... can I help in "testing"/"debugging" solutions?
Or, should I wait for the next home assistant release (due in the next week I guess).

Still have a pile of the needed batteries, so not in a big hurry ;-)
Also happy to see the steady progress! Great work.

Cheers,
Erik

@TheJulianJES
Copy link
Collaborator Author

You can update to Home Assistant Core 2023.4.0 (beta releases today) and then remove and re-pair all battery draining remotes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs final review PR is ready for a final review from a maintainer Tuya Request/PR regarding a Tuya device
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants