Open toy3375 opened 2 years ago
@mrctorres caan you asking @Tropaion hi was setting up one CC-2531 and have sniffing tuya ZBGW for some hours ago perhaps hi is knowing how to getting it working.
https://github.com/zigpy/zha-device-handlers/issues/1302#issuecomment-1027216533
Now I capture packets with Texas Instrument firmware and Texas Instrument Smart RF Packet Sniffer vs1 software, but it doesn't work with Wireshark. Generated this file when I turned on the child device and I stopped capturing when updated the clock.
@mrctorres Under windows I'm just using this sniffer with WireShark, works perfectly fine: https://dsr-iot.com/downloads Here a tutorial: https://community.oh-lalabs.com/t/guide-build-a-zigbee-cc2531-sniffer-how-to-use-it/469
Here first packets
You need to set key properly in Wireshark. https://www.youtube.com/watch?v=4vG4CVNAm_A Attached file has payload encrypted
@mrctorres The key is working from the paring the device. I looking little if i can find some "tuya magic" in the sniffs :))
@jacekk015 I think this device is needing the same treatment as the TS004F that i need sending attributes to then its joining but its looks it dont need being in INIT more do tuya ia not kicking it for rejoining.
First they is reading some attribute of cluster both known and unknown ones:
Frame 33: 60 bytes on wire (480 bits), 58 bytes captured (464 bits) on interface \\.\pipe\zboss_sniffer_COM10, id 0
IEEE 802.15.4 Data, Dst: 0x083a, Src: 0x0000
ZigBee Network Layer Data, Dst: 0x083a, Src: 0x0000
Frame Control Field: 0x0208, Frame Type: Data, Discover Route: Suppress, Security Data
.... .... .... ..00 = Frame Type: Data (0x0)
.... .... ..00 10.. = Protocol Version: 2
.... .... 00.. .... = Discover Route: Suppress (0x0)
.... ...0 .... .... = Multicast: False
.... ..1. .... .... = Security: True
.... .0.. .... .... = Source Route: False
.... 0... .... .... = Destination: False
...0 .... .... .... = Extended Source: False
..0. .... .... .... = End Device Initiator: False
Destination: 0x083a
Source: 0x0000
Radius: 30
Sequence Number: 207
[Extended Source: SiliconL_ff:fe:eb:6d:9f (80:4b:50:ff:fe:eb:6d:9f)]
[Origin: 1]
ZigBee Security Header
ZigBee Application Support Layer Data, Dst Endpt: 255, Src Endpt: 1
Frame Control Field: Data (0x40)
.... ..00 = Frame Type: Data (0x0)
.... 00.. = Delivery Mode: Unicast (0x0)
..0. .... = Security: False
.1.. .... = Acknowledgement Request: True
0... .... = Extended Header: False
Destination Endpoint: 255
Cluster: Basic (0x0000)
Profile: Home Automation (0x0104)
Source Endpoint: 1
Counter: 62
ZigBee Cluster Library Frame, Command: Read Attributes, Seq: 44
Frame Control Field: Profile-wide (0x10)
.... ..00 = Frame Type: Profile-wide (0x0)
.... .0.. = Manufacturer Specific: False
.... 0... = Direction: Client to Server
...1 .... = Disable Default Response: True
Sequence Number: 44
Command: Read Attributes (0x00)
Attribute: Manufacturer Name (0x0004)
Attribute: ZCL Version (0x0000)
Attribute: Application Version (0x0001)
Attribute: Model Identifier (0x0005)
Attribute: Power Source (0x0007)
Attribute: Unknown (0xfffe)
Then writing to attribute 0xffde on the basic cluster with data Uint8: 19 (0x13)
.
Frame 78: 52 bytes on wire (416 bits), 50 bytes captured (400 bits) on interface \\.\pipe\zboss_sniffer_COM10, id 0
IEEE 802.15.4 Data, Dst: 0x083a, Src: 0x0000
ZigBee Network Layer Data, Dst: 0x083a, Src: 0x0000
Frame Control Field: 0x0208, Frame Type: Data, Discover Route: Suppress, Security Data
.... .... .... ..00 = Frame Type: Data (0x0)
.... .... ..00 10.. = Protocol Version: 2
.... .... 00.. .... = Discover Route: Suppress (0x0)
.... ...0 .... .... = Multicast: False
.... ..1. .... .... = Security: True
.... .0.. .... .... = Source Route: False
.... 0... .... .... = Destination: False
...0 .... .... .... = Extended Source: False
..0. .... .... .... = End Device Initiator: False
Destination: 0x083a
Source: 0x0000
Radius: 30
Sequence Number: 219
[Extended Source: SiliconL_ff:fe:eb:6d:9f (80:4b:50:ff:fe:eb:6d:9f)]
[Origin: 1]
ZigBee Security Header
ZigBee Application Support Layer Data, Dst Endpt: 1, Src Endpt: 1
Frame Control Field: Data (0x00)
.... ..00 = Frame Type: Data (0x0)
.... 00.. = Delivery Mode: Unicast (0x0)
..0. .... = Security: False
.0.. .... = Acknowledgement Request: False
0... .... = Extended Header: False
Destination Endpoint: 1
Cluster: Basic (0x0000)
Profile: Home Automation (0x0104)
Source Endpoint: 1
Counter: 66
ZigBee Cluster Library Frame, Command: Write Attributes, Seq: 45
Frame Control Field: Profile-wide (0x10)
.... ..00 = Frame Type: Profile-wide (0x0)
.... .0.. = Manufacturer Specific: False
.... 0... = Direction: Client to Server
...1 .... = Disable Default Response: True
Sequence Number: 45
Command: Write Attributes (0x02)
Attribute Field, Uint8: 19
Attribute: Unknown (0xffde)
Data Type: 8-Bit Unsigned Integer (0x20)
Uint8: 19 (0x13)
Its made 2 times with the same information.
Then reading the Node Descriptor
and they using Silabs manufacture code in it Manufacturer Code: 0x1002`. (Frame 104:)
Then writing one unknown command to basic cluster Unknown (0xf0)
.
Frame 185: 48 bytes on wire (384 bits), 46 bytes captured (368 bits) on interface \\.\pipe\zboss_sniffer_COM10, id 0
IEEE 802.15.4 Data, Dst: 0x083a, Src: 0x0000
ZigBee Network Layer Data, Dst: 0x083a, Src: 0x0000
Frame Control Field: 0x0208, Frame Type: Data, Discover Route: Suppress, Security Data
.... .... .... ..00 = Frame Type: Data (0x0)
.... .... ..00 10.. = Protocol Version: 2
.... .... 00.. .... = Discover Route: Suppress (0x0)
.... ...0 .... .... = Multicast: False
.... ..1. .... .... = Security: True
.... .0.. .... .... = Source Route: False
.... 0... .... .... = Destination: False
...0 .... .... .... = Extended Source: False
..0. .... .... .... = End Device Initiator: False
Destination: 0x083a
Source: 0x0000
Radius: 30
Sequence Number: 232
[Extended Source: SiliconL_ff:fe:eb:6d:9f (80:4b:50:ff:fe:eb:6d:9f)]
[Origin: 1]
ZigBee Security Header
ZigBee Application Support Layer Data, Dst Endpt: 1, Src Endpt: 1
Frame Control Field: Data (0x40)
.... ..00 = Frame Type: Data (0x0)
.... 00.. = Delivery Mode: Unicast (0x0)
..0. .... = Security: False
.1.. .... = Acknowledgement Request: True
0... .... = Extended Header: False
Destination Endpoint: 1
Cluster: Basic (0x0000)
Profile: Home Automation (0x0104)
Source Endpoint: 1
Counter: 71
ZigBee Cluster Library Frame
Frame Control Field: Cluster-specific (0x11)
.... ..01 = Frame Type: Cluster-specific (0x1)
.... .0.. = Manufacturer Specific: False
.... 0... = Direction: Client to Server
...1 .... = Disable Default Response: True
Sequence Number: 47
Command: Unknown (0xf0)
After that the device is start sending "normal tuya DP commands":
Frame 193: 48 bytes on wire (384 bits), 46 bytes captured (368 bits) on interface \\.\pipe\zboss_sniffer_COM10, id 0
IEEE 802.15.4 Data, Dst: 0x083a, Src: 0x0000
ZigBee Network Layer Data, Dst: 0x083a, Src: 0x0000
Frame Control Field: 0x0208, Frame Type: Data, Discover Route: Suppress, Security Data
.... .... .... ..00 = Frame Type: Data (0x0)
.... .... ..00 10.. = Protocol Version: 2
.... .... 00.. .... = Discover Route: Suppress (0x0)
.... ...0 .... .... = Multicast: False
.... ..1. .... .... = Security: True
.... .0.. .... .... = Source Route: False
.... 0... .... .... = Destination: False
...0 .... .... .... = Extended Source: False
..0. .... .... .... = End Device Initiator: False
Destination: 0x083a
Source: 0x0000
Radius: 30
Sequence Number: 234
[Extended Source: SiliconL_ff:fe:eb:6d:9f (80:4b:50:ff:fe:eb:6d:9f)]
[Origin: 1]
ZigBee Security Header
ZigBee Application Support Layer Data, Dst Endpt: 1, Src Endpt: 1
Frame Control Field: Data (0x00)
.... ..00 = Frame Type: Data (0x0)
.... 00.. = Delivery Mode: Unicast (0x0)
..0. .... = Security: False
.0.. .... = Acknowledgement Request: False
0... .... = Extended Header: False
Destination Endpoint: 1
Cluster: Unknown (0xef00)
Profile: Home Automation (0x0104)
Source Endpoint: 1
Counter: 72
ZigBee Cluster Library Frame
Frame Control Field: Cluster-specific (0x11)
.... ..01 = Frame Type: Cluster-specific (0x1)
.... .0.. = Manufacturer Specific: False
.... 0... = Direction: Client to Server
...1 .... = Disable Default Response: True
Sequence Number: 48
Command: Unknown (0x03)
Frame 197: 48 bytes on wire (384 bits), 46 bytes captured (368 bits) on interface \\.\pipe\zboss_sniffer_COM10, id 0
IEEE 802.15.4 Data, Dst: 0x083a, Src: 0x0000
ZigBee Network Layer Data, Dst: 0x083a, Src: 0x0000
Frame Control Field: 0x0208, Frame Type: Data, Discover Route: Suppress, Security Data
.... .... .... ..00 = Frame Type: Data (0x0)
.... .... ..00 10.. = Protocol Version: 2
.... .... 00.. .... = Discover Route: Suppress (0x0)
.... ...0 .... .... = Multicast: False
.... ..1. .... .... = Security: True
.... .0.. .... .... = Source Route: False
.... 0... .... .... = Destination: False
...0 .... .... .... = Extended Source: False
..0. .... .... .... = End Device Initiator: False
Destination: 0x083a
Source: 0x0000
Radius: 30
Sequence Number: 236
[Extended Source: SiliconL_ff:fe:eb:6d:9f (80:4b:50:ff:fe:eb:6d:9f)]
[Origin: 1]
ZigBee Security Header
ZigBee Application Support Layer Data, Dst Endpt: 1, Src Endpt: 1
Frame Control Field: Data (0x00)
.... ..00 = Frame Type: Data (0x0)
.... 00.. = Delivery Mode: Unicast (0x0)
..0. .... = Security: False
.0.. .... = Acknowledgement Request: False
0... .... = Extended Header: False
Destination Endpoint: 1
Cluster: Unknown (0xef00)
Profile: Home Automation (0x0104)
Source Endpoint: 1
Counter: 73
ZigBee Cluster Library Frame
Frame Control Field: Cluster-specific (0x11)
.... ..01 = Frame Type: Cluster-specific (0x1)
.... .0.. = Manufacturer Specific: False
.... 0... = Direction: Client to Server
...1 .... = Disable Default Response: True
Sequence Number: 49
Command: Unknown (0x03)
I have not looking on the DP command then i cant decoding them but it can being that they is sending somthing interesting in this 2 then starting initiating the device.
The first frame send to DP cluster is not flagged manufacturer specific.... .0.. = Manufacturer Specific: False
.
If like looking on the DP command sequences please do so.
I think its worth trying getting the quirk reading and sending attribute on initiating the device and also sending command to it and see if its behaving better.
Also finding then the device is doing on time request with DP commands and how they is handshaking it with DP commands.
Pleas more feedback and if i shall looking more for "normal" zigbee things in the sniffs.
I think this device is needing the same treatment as the TS004F that i need sending attributes to then its joining but its looks it dont need being in INIT more do tuya ia not kicking it for rejoining.
I can confirm the above. Sending the multi-attribute read command :
Command: Read Attributes (0x00) Attribute: Manufacturer Name (0x0004) Attribute: ZCL Version (0x0000) Attribute: Application Version (0x0001) Attribute: Model Identifier (0x0005) Attribute: Power Source (0x0007) Attribute: Unknown (0xfffe)
at any time (not neccesery during the pairing process as for TS004F!) was enough for successful date/time setup.
More tuya magic for implanting in Hubitat !! This is number 2 @kkossev have pinpointing and verified working (the first was TS004F). Thanks for verifying it working !!
I only hope i getting help implanting sending attributes and commands from quirks in ZHA and i can getting my TS004F working also for normal users.
The unknown attribute is known but not implanted in wireshark and most system then its one global attribute. 2.3.4.5 Global Attributes in ZCL R8 https://github.com/zigpy/zigpy/discussions/595#discussioncomment-1656808
So where does this stand now? Which quirk is the best one to use?
I is knowing how the command need being implanted for the devices but i cant doing the coding for getting it working. For the moment we is having 4 tuya / LIDL devices that is needs the "tuya magic" for working OK or at all in our systems.
@jacekk015 I think then we can getting sending the reading attributes from quirks we shall testing if more tuya TS0602 is needing it / working better. Its looks like many "normal" tuya Zigbee devices is needing this then Z2M have finding 2 and we is having 3 (2 with help of @kkossev) and i think is more is coming.
Is there anything else I can do to help with the sniffer or on the device itself?
I think this device is needing the same treatment as the TS004F that i need sending attributes to then its joining but its looks it dont need being in INIT more do tuya ia not kicking it for rejoining.
I can confirm the above. Sending the multi-attribute read command :
Command: Read Attributes (0x00) Attribute: Manufacturer Name (0x0004) Attribute: ZCL Version (0x0000) Attribute: Application Version (0x0001) Attribute: Model Identifier (0x0005) Attribute: Power Source (0x0007) Attribute: Unknown (0xfffe)
at any time (not neccesery during the pairing process as for TS004F!) was enough for successful date/time setup.
Any example line code?
Puddly have making one example python code version of @kkossev code but i cant getting it working then i have not enough knowledge implanting it in one quirk https://github.com/zigpy/zha-device-handlers/pull/969#issuecomment-1006935550.
The TS004f is needed being kicked (leave with rejoining) or having very tight timing for populating the 3 extra EPs but it shall being possible fixing then have get read and writing attributes from the quirk.
@MattWestb it may turn out that the Basic Cluster attributes read sequence has an effect only when is sent during the pairing process only... same as TS004F. I had a user whose device didn't work (no reporting at all!) until I added the Manufacturer ID to the list of fingerprints and the device was then excluded and re-paired again to the Zigbee concentrator.
Thanks for information @kkossev !! Then i can getting the read and writing i can doing the testing of your timing and also kicking if needed for the normal dimmer.
And likely devices is working OK if being pared with tuya ZBGW until battery is being removed as we have seen before :-)
@kkossev One more device that i have on the list for "tuya magic" is more or less confirmed https://github.com/dresden-elektronik/deconz-rest-plugin/issues/5493#issuecomment-1034174883 and we is have many Portuguese user that the device is only using one endpoint.
I dont really follow the last few comments. Is there anything more to be done here? Would like to be able to change to Fahrenheit plus have reliable datetime settings.
The only way to change Fahrenheit is first to pair to a TUYA Gateway. Change settings to Fahrenheit. Then pairing to ZHA again. Time/Date sync when paired with TUYA. After pairing to ZHA , the Time wont sync anymore and the Time slides away..
James Benjamin Goff @.***> schrieb am Sa., 19. Feb. 2022, 20:11:
I dont really follow the last few comments. Is there anything more to be done here? Would like to be able to change to Fahrenheit plus have reliable datetime settings.
— Reply to this email directly, view it on GitHub https://github.com/zigpy/zha-device-handlers/issues/1286#issuecomment-1046086022, or unsubscribe https://github.com/notifications/unsubscribe-auth/ARNNXMZWKYJV5QUQQYMVIRTU37TOXANCNFSM5MA4XE2A . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
You are receiving this because you were mentioned.Message ID: @.***>
Since HA update 2022.4 there have been some changes in ZHA handlers. manufacturing_attributes has been replaced by attributes and some other changes. I already found a few and updated the file for this quirk, but still not able to get it to work. Does any know what has to be changed in the previous shared files to get it to work with release 2022.4?
Help is much appreciated. Attached the attempt that I've made, but it is generating errors:
2022-04-14 13:24:21 ERROR (MainThread) [homeassistant.util.logging] Exception in functools.partial(<function async_add_entities at 0x7f77488d2ca0>, <bound method EntityPlatform._async_schedule_add_entities of <EntityPlatform domain=sensor platform_name=zha config_entry=<homeassistant.config_entries.ConfigEntry object at 0x7f77520b1f40>>>, [(<class 'homeassistant.components.zha.sensor.RSSISensor'>, ('00:12:4b:00:21:a8:e4:a2-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7749afb2b0>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f77364157c0>])), (<class 'homeassistant.components.zha.sensor.LQISensor'>, ('00:12:4b:00:21:a8:e4:a2-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7749afb2b0>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f77364157c0>])), (<class 'homeassistant.components.zha.sensor.RSSISensor'>, ('00:12:4b:00:21:a8:e4:a2-2-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7749afb2b0>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f77363d86a0>])), (<class 'homeassistant.components.zha.sensor.LQISensor'>, ('00:12:4b:00:21:a8:e4:a2-2-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7749afb2b0>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f77363d86a0>])), (<class 'homeassistant.components.zha.sensor.RSSISensor'>, ('b4:e3:f9:ff:fe:a5:3a:62-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f77363d8850>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f7737566e80>])), (<class 'homeassistant.components.zha.sensor.LQISensor'>, ('b4:e3:f9:ff:fe:a5:3a:62-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f77363d8850>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f7737566e80>])), (<class 'homeassistant.components.zha.sensor.Battery'>, ('50:32:5f:ff:fe:24:45:05-1-1', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f77363fe2e0>, [<homeassistant.components.zha.core.channels.general.PowerConfigurationChannel object at 0x7f773ca7b5b0>])), (<class 'homeassistant.components.zha.sensor.RSSISensor'>, ('50:32:5f:ff:fe:24:45:05-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f77363fe2e0>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f773ca7ba90>])), (<class 'homeassistant.components.zha.sensor.LQISensor'>, ('50:32:5f:ff:fe:24:45:05-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f77363fe2e0>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f773ca7ba90>])), (<class 'homeassistant.components.zha.sensor.RSSISensor'>, ('8c:f6:81:ff:fe:4b:3b:2f-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f774bb8ba60>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f773cb66160>])), (<class 'homeassistant.components.zha.sensor.LQISensor'>, ('8c:f6:81:ff:fe:4b:3b:2f-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f774bb8ba60>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f773cb66160>])), (<class 'homeassistant.components.zha.sensor.Battery'>, ('60:a4:23:ff:fe:ee:ec:82-1-1', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f774bc654c0>, [<homeassistant.components.zha.core.channels.general.PowerConfigurationChannel object at 0x7f7737b72640>])), (<class 'homeassistant.components.zha.sensor.RSSISensor'>, ('60:a4:23:ff:fe:ee:ec:82-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f774bc654c0>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f774bbda610>])), (<class 'homeassistant.components.zha.sensor.LQISensor'>, ('60:a4:23:ff:fe:ee:ec:82-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f774bc654c0>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f774bbda610>])), (<class 'homeassistant.components.zha.sensor.Battery'>, ('a4:c1:38:3d:47:f2:e7:c6-1-1', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7736408b50>, [<homeassistant.components.zha.core.channels.general.PowerConfigurationChannel object at 0x7f7741832e80>])), (<class 'homeassistant.components.zha.sensor.Temperature'>, ('a4:c1:38:3d:47:f2:e7:c6-1-1026', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7736408b50>, [<homeassistant.components.zha.core.channels.measurement.TemperatureMeasurement object at 0x7f7737da3fd0>])), (<class 'homeassistant.components.zha.sensor.RSSISensor'>, ('a4:c1:38:3d:47:f2:e7:c6-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7736408b50>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f7737da38e0>])), (<class 'homeassistant.components.zha.sensor.LQISensor'>, ('a4:c1:38:3d:47:f2:e7:c6-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7736408b50>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f7737da38e0>])), (<class 'homeassistant.components.zha.sensor.Humidity'>, ('a4:c1:38:3d:47:f2:e7:c6-1-1029', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7736408b50>, [<homeassistant.components.zha.core.channels.measurement.RelativeHumidity object at 0x7f773cd3b790>])), (<class 'homeassistant.components.zha.sensor.RSSISensor'>, ('00:12:4b:00:21:a8:e4:a2-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f77417e4550>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f77365298e0>])), (<class 'homeassistant.components.zha.sensor.LQISensor'>, ('00:12:4b:00:21:a8:e4:a2-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f77417e4550>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f77365298e0>])), (<class 'homeassistant.components.zha.sensor.RSSISensor'>, ('00:12:4b:00:21:a8:e4:a2-2-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f77417e4550>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f77365297f0>])), (<class 'homeassistant.components.zha.sensor.LQISensor'>, ('00:12:4b:00:21:a8:e4:a2-2-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f77417e4550>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f77365297f0>])), (<class 'homeassistant.components.zha.sensor.RSSISensor'>, ('b4:e3:f9:ff:fe:a5:3a:62-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7737cc96a0>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f773cba7b80>])), (<class 'homeassistant.components.zha.sensor.LQISensor'>, ('b4:e3:f9:ff:fe:a5:3a:62-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7737cc96a0>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f773cba7b80>])), (<class 'homeassistant.components.zha.sensor.Battery'>, ('50:32:5f:ff:fe:24:45:05-1-1', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f77363ca3a0>, [<homeassistant.components.zha.core.channels.general.PowerConfigurationChannel object at 0x7f77365296a0>])), (<class 'homeassistant.components.zha.sensor.RSSISensor'>, ('50:32:5f:ff:fe:24:45:05-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f77363ca3a0>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f77365294c0>])), (<class 'homeassistant.components.zha.sensor.LQISensor'>, ('50:32:5f:ff:fe:24:45:05-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f77363ca3a0>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f77365294c0>])), (<class 'homeassistant.components.zha.sensor.RSSISensor'>, ('8c:f6:81:ff:fe:4b:3b:2f-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7736529a60>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f7735de73d0>])), (<class 'homeassistant.components.zha.sensor.LQISensor'>, ('8c:f6:81:ff:fe:4b:3b:2f-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7736529a60>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f7735de73d0>])), (<class 'homeassistant.components.zha.sensor.Battery'>, ('60:a4:23:ff:fe:ee:ec:82-1-1', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7735de7610>, [<homeassistant.components.zha.core.channels.general.PowerConfigurationChannel object at 0x7f7735de7c70>])), (<class 'homeassistant.components.zha.sensor.RSSISensor'>, ('60:a4:23:ff:fe:ee:ec:82-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7735de7610>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f7735de7c40>])), (<class 'homeassistant.components.zha.sensor.LQISensor'>, ('60:a4:23:ff:fe:ee:ec:82-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7735de7610>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f7735de7c40>])), (<class 'homeassistant.components.zha.sensor.Battery'>, ('a4:c1:38:3d:47:f2:e7:c6-1-1', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7735de7f40>, [<homeassistant.components.zha.core.channels.general.PowerConfigurationChannel object at 0x7f7735dec640>])), (<class 'homeassistant.components.zha.sensor.Temperature'>, ('a4:c1:38:3d:47:f2:e7:c6-1-1026', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7735de7f40>, [<homeassistant.components.zha.core.channels.measurement.TemperatureMeasurement object at 0x7f7735dec5e0>])), (<class 'homeassistant.components.zha.sensor.RSSISensor'>, ('a4:c1:38:3d:47:f2:e7:c6-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7735de7f40>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f7735dec520>])), (<class 'homeassistant.components.zha.sensor.LQISensor'>, ('a4:c1:38:3d:47:f2:e7:c6-1-0', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7735de7f40>, [<homeassistant.components.zha.core.channels.general.BasicChannel object at 0x7f7735dec520>])), (<class 'homeassistant.components.zha.sensor.Humidity'>, ('a4:c1:38:3d:47:f2:e7:c6-1-1029', <homeassistant.components.zha.core.device.ZHADevice object at 0x7f7735de7f40>, [<homeassistant.components.zha.core.channels.measurement.RelativeHumidity object at 0x7f7735dec610>]))], update_before_add=False) when dispatching 'zha_add_new_entities': ()
ts0601_temperature.zip
Missing .id on the end of: self.attributes_by_name["measured_value"].id
Yes that's it! Thanks
Do you currently have a custom working quirk for this device for Home Assistant 2022.4.5? If so, it would be nice if you could PR the changes to this repo or just send the latest quirk file here, so someone else can do it. Then, a custom quirk wouldn't be needed in the future anymore. Thanks!
Hi, These is the extensive version with all the entities as described earlier. However updating the values (frequency, date/time etc) does not work and generate errors. But as far as I can tell there has not been a working version for that ts0601_temperature.py.zip .
This is the version with only three entities (temperature, humidity and power). This version works without any errors. Date/time is not updated. ts0601_temperature.py.zip
The device is more then likely need "tuya magic spell" being casted on it then paring it for getting the reporting and clock setting working. We have implanting one working version for one device that can being tested if some like to so it. The code looks lik this and is implanted in the device class so its being run then the quirk is loaded but then restart HA its doing it but the network is not online so its only being casted then doing new joining of device. https://github.com/zigpy/zha-device-handlers/blob/16f298e9ce293d241592f86573e909f9c32809d0/zhaquirks/tuya/ts004f.py#L180-L195
There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates. Please make sure to update to the latest version and check if that solves the issue. Let us know if that works for you by adding a comment 👍 This issue has now been marked as stale and will be closed if no further activity occurs. Thank you for your contributions.
I managed to get clock updates with this quirk: https://github.com/zigpy/zha-device-handlers/issues/1702#issuecomment-1238612059
(slightly modified by adding ("_TZE200_3towulqd", "TS0601")
to the Models_info)
I managed to get clock updates with this quirk: #1702 (comment)
(slightly modified by adding
("_TZE200_3towulqd", "TS0601")
to the Models_info)
Worked for me also. Here is my revised code...
"""Tuya temp and humidity sensor with screen."""
from typing import Dict
################## clean this up
import zigpy.types as t
from zigpy.zcl import foundation
from zhaquirks.tuya import TuyaTimePayload, TuyaCommand
import datetime
from typing import Tuple, Optional, Union
##################
from zigpy.profiles import zha
from zigpy.quirks import CustomDevice
from zigpy.zcl.clusters.general import Basic, Groups, Ota, Scenes, Time, AnalogOutput
from zigpy.zcl.clusters.measurement import RelativeHumidity, TemperatureMeasurement
from zhaquirks.const import (
DEVICE_TYPE,
ENDPOINTS,
INPUT_CLUSTERS,
MODELS_INFO,
OUTPUT_CLUSTERS,
PROFILE_ID,
SKIP_CONFIGURATION,
)
from zhaquirks.tuya import TuyaLocalCluster, TuyaPowerConfigurationCluster2AAA
from zhaquirks.tuya.mcu import DPToAttributeMapping, TuyaDPType, TuyaMCUCluster
TUYA_SET_TIME = 0x24
# NOTES:
# The data comes in as a string on cluster, if there is nothing set up you may see these lines in the logs:
# Unknown message (b'19830100a40102000400000118') on cluster 61184: unknown endpoint or cluster id: 'No cluster ID 0xef00 on (a4:c1:38:d0:18:8b:64:aa, 1)'
# 28.0 degrees
# Unknown message (b'19840100a5020200040000022c') on cluster 61184: unknown endpoint or cluster id: 'No cluster ID 0xef00 on (a4:c1:38:d0:18:8b:64:aa, 1)'
# 55.6% humid
# Unknown message (b'19850100a60402000400000064') on cluster 61184: unknown endpoint or cluster id: 'No cluster ID 0xef00 on (a4:c1:38:d0:18:8b:64:aa, 1)'
# 100% battery
class TemperatureUnitConvert(t.enum8):
"""Tuya Temp unit convert enum."""
Celsius = 0x00
Fahrenheit = 0x01
class TuyaTemperatureMeasurement(TemperatureMeasurement, TuyaLocalCluster):
"""Tuya local TemperatureMeasurement cluster."""
attributes = TemperatureMeasurement.attributes.copy()
attributes.update(
{
0x8001: ("temp_unit_convert", t.enum8),
0x8002: ("alarm_max_temperature", t.Single),
0x8003: ("alarm_min_temperature", t.Single),
0x8004: ("temperature_sensitivity", t.Single),
}
)
class TuyaRelativeHumidity(RelativeHumidity, TuyaLocalCluster):
"""Tuya local RelativeHumidity cluster."""
class TemperatureHumidityManufCluster(TuyaMCUCluster):
"""Tuya Manufacturer Cluster with Temperature and Humidity data points."""
dp_to_attribute: Dict[int, DPToAttributeMapping] = {
1: DPToAttributeMapping(
TuyaTemperatureMeasurement.ep_attribute,
"measured_value",
dp_type=TuyaDPType.VALUE,
converter=lambda x: x * 10, # decidegree to centidegree
),
2: DPToAttributeMapping(
TuyaRelativeHumidity.ep_attribute,
"measured_value",
dp_type=TuyaDPType.VALUE,
converter=lambda x: x * 100, # 0.01 to 1.0
),
4: DPToAttributeMapping(
TuyaPowerConfigurationCluster2AAA.ep_attribute,
"battery_percentage_remaining",
dp_type=TuyaDPType.VALUE,
converter=lambda x: x * 2, # reported percentage is doubled
),
9: DPToAttributeMapping(
TuyaTemperatureMeasurement.ep_attribute,
"temp_unit_convert",
dp_type=TuyaDPType.ENUM,
converter=lambda x: TemperatureUnitConvert(x)
),
10: DPToAttributeMapping(
TuyaTemperatureMeasurement.ep_attribute,
"alarm_max_temperature",
dp_type=TuyaDPType.VALUE,
converter=lambda x: x / 10
),
11: DPToAttributeMapping(
TuyaTemperatureMeasurement.ep_attribute,
"alarm_min_temperature",
dp_type=TuyaDPType.VALUE,
converter=lambda x: x / 10
),
19: DPToAttributeMapping(
TuyaTemperatureMeasurement.ep_attribute,
"temperature_sensitivity",
dp_type=TuyaDPType.VALUE,
converter=lambda x: x / 10
)
}
set_time_offset = 1970
set_time_local_offset = 1970
data_point_handlers = {
1: "_dp_2_attr_update",
2: "_dp_2_attr_update",
4: "_dp_2_attr_update",
9: "_dp_2_attr_update",
10: "_dp_2_attr_update",
11: "_dp_2_attr_update",
19: "_dp_2_attr_update",
}
def handle_set_time_request(self, sequence_number: t.uint16_t) -> foundation.Status:
payload = TuyaTimePayload()
utc_now = datetime.datetime.utcnow()
now = datetime.datetime.now()
offset_time = datetime.datetime(self.set_time_offset, 1, 1)
offset_time_local = datetime.datetime(self.set_time_local_offset, 1, 1)
utc_timestamp = int((utc_now - offset_time).total_seconds())
local_timestamp = int((now - offset_time).total_seconds())
payload.extend(utc_timestamp.to_bytes(4, "big", signed=False))
payload.extend(local_timestamp.to_bytes(4, "big", signed=False))
self.create_catching_task(
self.command(TUYA_SET_TIME, payload, manufacturer=foundation.ZCLHeader.NO_MANUFACTURER_ID, expect_reply=False)
)
return foundation.Status.SUCCESS
class TuyaNousE6TempHumiditySensor(CustomDevice):
"""Custom device representing tuya temp and humidity sensor with a screen (NOUS E6)."""
signature = {
# <SimpleDescriptor endpoint=1, profile=260, device_type=81
# device_version=1
# input_clusters=[4, 5, 61184, 0]
# output_clusters=[25, 10]>
MODELS_INFO: [
("_TZE200_bq5c8xfe", "TS0601"),
("_TZE200_locansqn", "TS0601"),
("_TZE200_nnrfa68v", "TS0601")
],
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.SMART_PLUG, # this is how the device reports itself
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TemperatureHumidityManufCluster.cluster_id,
],
OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id],
}
},
}
replacement = {
SKIP_CONFIGURATION: True,
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR,
INPUT_CLUSTERS: [
Basic.cluster_id,
TemperatureHumidityManufCluster, # Single bus for temp, humidity, and battery
TuyaTemperatureMeasurement,
TuyaRelativeHumidity,
TuyaPowerConfigurationCluster2AAA,
],
OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id],
}
},
}
Hey Everybody,
I can confirm. Each of my 3 devices has the right time and date . And i get current temperature , humidity and Batterie values at Home Assistant. Thanks to all
Hey @toy3375 Pleas reformat the log with starting on one blank line with ```
and the same after on one blank line so its can being red without loosing formatting.
Frohe . . .
@MattWestb : My mistake . I replyed to the E-Mail. i fixed it .
Quirk corrected, now using EnchantedDevice class, which sends multi-attribute read. Worth of trying if date/time is in sync now. ts0601_temperature.py.zip
Logger: homeassistant.config_entries
Source: custom_zha_quirks/ts0601_temperature.py:145
First occurred: 9:25:39 AM (2 occurrences)
Last logged: 9:27:39 AM
Error setting up entry SkyConnect v1.0 for zha
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/config_entries.py", line 382, in async_setup
result = await component.async_setup_entry(hass, self)
File "/usr/src/homeassistant/homeassistant/components/zha/__init__.py", line 100, in async_setup_entry
setup_quirks(config)
File "/usr/local/lib/python3.10/site-packages/zhaquirks/__init__.py", line 409, in setup
importer.find_module(modname).load_module(modname)
File "<frozen importlib._bootstrap_external>", line 548, in _check_name_wrapper
File "<frozen importlib._bootstrap_external>", line 1063, in load_module
File "<frozen importlib._bootstrap_external>", line 888, in load_module
File "<frozen importlib._bootstrap>", line 290, in _load_module_shim
File "<frozen importlib._bootstrap>", line 719, in _load
File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 883, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "/config/custom_zha_quirks/ts0601_temperature.py", line 145, in <module>
class TuyaSensorManufCluster(TuyaManufClusterAttributes):
File "/usr/local/lib/python3.10/site-packages/zigpy/zcl/__init__.py", line 84, in __init_subclass__
raise TypeError(
TypeError: `manufacturer_attributes` is deprecated. Copy the parent class's `attributes` dictionary and update it with your manufacturer-specific `attributes`. Make sure to specify that it is manufacturer-specific through the appropriate constructor or tuple!
--
@relighted Use ts0601_temperature.py file from https://github.com/jacekk015/zha_quirks
Referring to @JeffPixelSplash 's solution including the time and date. With the latest HomeAssitant update it seems to be broken. My solution, maybe crude: (An sorry, for not the bad formatting here... New here:)
Change this:
from`` zhaquirks.tuya import TuyaLocalCluster, TuyaPowerConfigurationCluster2AAA
#` old: from zhaquirks.tuya.mcu import DPToAttributeMapping, TuyaDPType, TuyaMCUCluster
Change all of them to explicit type conversion:
19: DPToAttributeMapping(
TuyaTemperatureMeasurement.ep_attribute,
"temperature_sensitivity",
#dp_type=TuyaDPType.VALUE,
converter=lambda x: float(x / 10)
The whole file like it works for my _TZE200_locansqn:
"""Tuya temp and humidity sensor with screen."""
from typing import Dict
################## clean this up
import zigpy.types as t
from zigpy.zcl import foundation
from zhaquirks.tuya import TuyaTimePayload, TuyaCommand
import datetime
from typing import Tuple, Optional, Union
##################
from zigpy.profiles import zha
from zigpy.quirks import CustomDevice
from zigpy.zcl.clusters.general import Basic, Groups, Ota, Scenes, Time, AnalogOutput
from zigpy.zcl.clusters.measurement import RelativeHumidity, TemperatureMeasurement
from zhaquirks.const import (
DEVICE_TYPE,
ENDPOINTS,
INPUT_CLUSTERS,
MODELS_INFO,
OUTPUT_CLUSTERS,
PROFILE_ID,
SKIP_CONFIGURATION,
)
from zhaquirks.tuya import TuyaLocalCluster, TuyaPowerConfigurationCluster2AAA
# old: from zhaquirks.tuya.mcu import DPToAttributeMapping, TuyaDPType, TuyaMCUCluster
from zhaquirks.tuya.mcu import DPToAttributeMapping, TuyaMCUCluster
TUYA_SET_TIME = 0x24
# NOTES:
# The data comes in as a string on cluster, if there is nothing set up you may see these lines in the logs:
# Unknown message (b'19830100a40102000400000118') on cluster 61184: unknown endpoint or cluster id: 'No cluster ID 0xef00 on (a4:c1:38:d0:18:8b:64:aa, 1)'
# 28.0 degrees
# Unknown message (b'19840100a5020200040000022c') on cluster 61184: unknown endpoint or cluster id: 'No cluster ID 0xef00 on (a4:c1:38:d0:18:8b:64:aa, 1)'
# 55.6% humid
# Unknown message (b'19850100a60402000400000064') on cluster 61184: unknown endpoint or cluster id: 'No cluster ID 0xef00 on (a4:c1:38:d0:18:8b:64:aa, 1)'
# 100% battery
class TemperatureUnitConvert(t.enum8):
"""Tuya Temp unit convert enum."""
Celsius = 0x00
Fahrenheit = 0x01
class TuyaTemperatureMeasurement(TemperatureMeasurement, TuyaLocalCluster):
"""Tuya local TemperatureMeasurement cluster."""
attributes = TemperatureMeasurement.attributes.copy()
attributes.update(
{
0x8001: ("temp_unit_convert", t.enum8),
0x8002: ("alarm_max_temperature", t.Single),
0x8003: ("alarm_min_temperature", t.Single),
0x8004: ("temperature_sensitivity", t.Single),
}
)
class TuyaRelativeHumidity(RelativeHumidity, TuyaLocalCluster):
"""Tuya local RelativeHumidity cluster."""
class TemperatureHumidityManufCluster(TuyaMCUCluster):
"""Tuya Manufacturer Cluster with Temperature and Humidity data points."""
dp_to_attribute: Dict[int, DPToAttributeMapping] = {
1: DPToAttributeMapping(
TuyaTemperatureMeasurement.ep_attribute,
"measured_value",
#dp_type=TuyaDPType.VALUE,
converter=lambda x: float(x * 10), # decidegree to centidegree
),
2: DPToAttributeMapping(
TuyaRelativeHumidity.ep_attribute,
"measured_value",
#dp_type=TuyaDPType.VALUE,
converter=lambda x: float(x * 100), # 0.01 to 1.0
),
4: DPToAttributeMapping(
TuyaPowerConfigurationCluster2AAA.ep_attribute,
"battery_percentage_remaining",
#dp_type=TuyaDPType.VALUE,
converter=lambda x: float(x * 2), # reported percentage is doubled
),
9: DPToAttributeMapping(
TuyaTemperatureMeasurement.ep_attribute,
"temp_unit_convert",
#dp_type=TuyaDPType.ENUM,
converter=lambda x: TemperatureUnitConvert(x)
),
10: DPToAttributeMapping(
TuyaTemperatureMeasurement.ep_attribute,
"alarm_max_temperature",
#dp_type=TuyaDPType.VALUE,
converter=lambda x: float(x / 10)
),
11: DPToAttributeMapping(
TuyaTemperatureMeasurement.ep_attribute,
"alarm_min_temperature",
#dp_type=TuyaDPType.VALUE,
converter=lambda x: float(x / 10)
),
19: DPToAttributeMapping(
TuyaTemperatureMeasurement.ep_attribute,
"temperature_sensitivity",
#dp_type=TuyaDPType.VALUE,
converter=lambda x: float(x / 10)
)
}
set_time_offset = 1970
set_time_local_offset = 1970
data_point_handlers = {
1: "_dp_2_attr_update",
2: "_dp_2_attr_update",
4: "_dp_2_attr_update",
9: "_dp_2_attr_update",
10: "_dp_2_attr_update",
11: "_dp_2_attr_update",
19: "_dp_2_attr_update",
}
def handle_set_time_request(self, sequence_number: t.uint16_t) -> foundation.Status:
payload = TuyaTimePayload()
utc_now = datetime.datetime.utcnow()
now = datetime.datetime.now()
offset_time = datetime.datetime(self.set_time_offset, 1, 1)
offset_time_local = datetime.datetime(self.set_time_local_offset, 1, 1)
utc_timestamp = int((utc_now - offset_time).total_seconds())
local_timestamp = int((now - offset_time).total_seconds())
payload.extend(utc_timestamp.to_bytes(4, "big", signed=False))
payload.extend(local_timestamp.to_bytes(4, "big", signed=False))
self.create_catching_task(
self.command(TUYA_SET_TIME, payload, manufacturer=foundation.ZCLHeader.NO_MANUFACTURER_ID, expect_reply=False)
)
return foundation.Status.SUCCESS
class TuyaNousE6TempHumiditySensor(CustomDevice):
"""Custom device representing tuya temp and humidity sensor with a screen (NOUS E6)."""
signature = {
# <SimpleDescriptor endpoint=1, profile=260, device_type=81
# device_version=1
# input_clusters=[4, 5, 61184, 0]
# output_clusters=[25, 10]>
MODELS_INFO: [
("_TZE200_bq5c8xfe", "TS0601"),
("_TZE200_locansqn", "TS0601"),
("_TZE200_nnrfa68v", "TS0601")
],
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.SMART_PLUG, # this is how the device reports itself
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TemperatureHumidityManufCluster.cluster_id,
],
OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id],
}
},
}
replacement = {
SKIP_CONFIGURATION: True,
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR,
INPUT_CLUSTERS: [
Basic.cluster_id,
TemperatureHumidityManufCluster, # Single bus for temp, humidity, and battery
TuyaTemperatureMeasurement,
TuyaRelativeHumidity,
TuyaPowerConfigurationCluster2AAA,
],
OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id],
}
},
}
I managed to get clock updates with this quirk: #1702 (comment) (slightly modified by adding
("_TZE200_3towulqd", "TS0601")
to the Models_info)Worked for me also. Here is my revised code...
"""Tuya temp and humidity sensor with screen.""" from typing import Dict ################## clean this up import zigpy.types as t from zigpy.zcl import foundation from zhaquirks.tuya import TuyaTimePayload, TuyaCommand import datetime from typing import Tuple, Optional, Union ################## from zigpy.profiles import zha from zigpy.quirks import CustomDevice from zigpy.zcl.clusters.general import Basic, Groups, Ota, Scenes, Time, AnalogOutput from zigpy.zcl.clusters.measurement import RelativeHumidity, TemperatureMeasurement from zhaquirks.const import ( DEVICE_TYPE, ENDPOINTS, INPUT_CLUSTERS, MODELS_INFO, OUTPUT_CLUSTERS, PROFILE_ID, SKIP_CONFIGURATION, ) from zhaquirks.tuya import TuyaLocalCluster, TuyaPowerConfigurationCluster2AAA from zhaquirks.tuya.mcu import DPToAttributeMapping, TuyaDPType, TuyaMCUCluster TUYA_SET_TIME = 0x24 # NOTES: # The data comes in as a string on cluster, if there is nothing set up you may see these lines in the logs: # Unknown message (b'19830100a40102000400000118') on cluster 61184: unknown endpoint or cluster id: 'No cluster ID 0xef00 on (a4:c1:38:d0:18:8b:64:aa, 1)' # 28.0 degrees # Unknown message (b'19840100a5020200040000022c') on cluster 61184: unknown endpoint or cluster id: 'No cluster ID 0xef00 on (a4:c1:38:d0:18:8b:64:aa, 1)' # 55.6% humid # Unknown message (b'19850100a60402000400000064') on cluster 61184: unknown endpoint or cluster id: 'No cluster ID 0xef00 on (a4:c1:38:d0:18:8b:64:aa, 1)' # 100% battery class TemperatureUnitConvert(t.enum8): """Tuya Temp unit convert enum.""" Celsius = 0x00 Fahrenheit = 0x01 class TuyaTemperatureMeasurement(TemperatureMeasurement, TuyaLocalCluster): """Tuya local TemperatureMeasurement cluster.""" attributes = TemperatureMeasurement.attributes.copy() attributes.update( { 0x8001: ("temp_unit_convert", t.enum8), 0x8002: ("alarm_max_temperature", t.Single), 0x8003: ("alarm_min_temperature", t.Single), 0x8004: ("temperature_sensitivity", t.Single), } ) class TuyaRelativeHumidity(RelativeHumidity, TuyaLocalCluster): """Tuya local RelativeHumidity cluster.""" class TemperatureHumidityManufCluster(TuyaMCUCluster): """Tuya Manufacturer Cluster with Temperature and Humidity data points.""" dp_to_attribute: Dict[int, DPToAttributeMapping] = { 1: DPToAttributeMapping( TuyaTemperatureMeasurement.ep_attribute, "measured_value", dp_type=TuyaDPType.VALUE, converter=lambda x: x * 10, # decidegree to centidegree ), 2: DPToAttributeMapping( TuyaRelativeHumidity.ep_attribute, "measured_value", dp_type=TuyaDPType.VALUE, converter=lambda x: x * 100, # 0.01 to 1.0 ), 4: DPToAttributeMapping( TuyaPowerConfigurationCluster2AAA.ep_attribute, "battery_percentage_remaining", dp_type=TuyaDPType.VALUE, converter=lambda x: x * 2, # reported percentage is doubled ), 9: DPToAttributeMapping( TuyaTemperatureMeasurement.ep_attribute, "temp_unit_convert", dp_type=TuyaDPType.ENUM, converter=lambda x: TemperatureUnitConvert(x) ), 10: DPToAttributeMapping( TuyaTemperatureMeasurement.ep_attribute, "alarm_max_temperature", dp_type=TuyaDPType.VALUE, converter=lambda x: x / 10 ), 11: DPToAttributeMapping( TuyaTemperatureMeasurement.ep_attribute, "alarm_min_temperature", dp_type=TuyaDPType.VALUE, converter=lambda x: x / 10 ), 19: DPToAttributeMapping( TuyaTemperatureMeasurement.ep_attribute, "temperature_sensitivity", dp_type=TuyaDPType.VALUE, converter=lambda x: x / 10 ) } set_time_offset = 1970 set_time_local_offset = 1970 data_point_handlers = { 1: "_dp_2_attr_update", 2: "_dp_2_attr_update", 4: "_dp_2_attr_update", 9: "_dp_2_attr_update", 10: "_dp_2_attr_update", 11: "_dp_2_attr_update", 19: "_dp_2_attr_update", } def handle_set_time_request(self, sequence_number: t.uint16_t) -> foundation.Status: payload = TuyaTimePayload() utc_now = datetime.datetime.utcnow() now = datetime.datetime.now() offset_time = datetime.datetime(self.set_time_offset, 1, 1) offset_time_local = datetime.datetime(self.set_time_local_offset, 1, 1) utc_timestamp = int((utc_now - offset_time).total_seconds()) local_timestamp = int((now - offset_time).total_seconds()) payload.extend(utc_timestamp.to_bytes(4, "big", signed=False)) payload.extend(local_timestamp.to_bytes(4, "big", signed=False)) self.create_catching_task( self.command(TUYA_SET_TIME, payload, manufacturer=foundation.ZCLHeader.NO_MANUFACTURER_ID, expect_reply=False) ) return foundation.Status.SUCCESS class TuyaNousE6TempHumiditySensor(CustomDevice): """Custom device representing tuya temp and humidity sensor with a screen (NOUS E6).""" signature = { # <SimpleDescriptor endpoint=1, profile=260, device_type=81 # device_version=1 # input_clusters=[4, 5, 61184, 0] # output_clusters=[25, 10]> MODELS_INFO: [ ("_TZE200_bq5c8xfe", "TS0601"), ("_TZE200_locansqn", "TS0601"), ("_TZE200_nnrfa68v", "TS0601") ], ENDPOINTS: { 1: { PROFILE_ID: zha.PROFILE_ID, DEVICE_TYPE: zha.DeviceType.SMART_PLUG, # this is how the device reports itself INPUT_CLUSTERS: [ Basic.cluster_id, Groups.cluster_id, Scenes.cluster_id, TemperatureHumidityManufCluster.cluster_id, ], OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id], } }, } replacement = { SKIP_CONFIGURATION: True, ENDPOINTS: { 1: { PROFILE_ID: zha.PROFILE_ID, DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR, INPUT_CLUSTERS: [ Basic.cluster_id, TemperatureHumidityManufCluster, # Single bus for temp, humidity, and battery TuyaTemperatureMeasurement, TuyaRelativeHumidity, TuyaPowerConfigurationCluster2AAA, ], OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id], } }, }
Thanks! This solutions works for me as well. ~I only had to adapt the quirk file and restart home assistant. No need to remove and re-add the device.~
edit: this is not correct, turns out I had to remove and re-add the device as no new values were received since I update the quirk file
I'm having trouble with this. I get an error....
ImportError: cannot import name 'TuyaDPType' from 'zhaquirks.tuya.mcu'
does anyone have any suggestions?
Did you use the updated quirk at the top of the post off @adrianschneider1977 He quoted the old version as well, that might be a bit confusing.
If you updated your file manualy, make sure that you're not only replacing the include on top, but also remove the line "dp_type=TuyaDPType.VALUE" on the other 7 locations.
Attached the updated version with all modifications. ts0601_temperature.zip
... or you can just use ready to work version from: https://github.com/jacekk015/zha_quirks/blob/main/ts0601_temperature.py
Awesome community! The two devices I have finally started to behave somewhat icw the HA sky Connect. However only one of the two returns the temp en humidity in HA as sensors. I removed and re-added multiple times. Any magic option I missed?
Awesome community! The two devices I have finally started to behave somewhat icw the HA sky Connect. However only one of the two returns the temp en humidity in HA as sensors. I removed and re-added multiple times. Any magic option I missed?
It only worked for me when I restarted Home Assistant. Even reloading the integration and pairing again did not show the temperature and humidity.
@relighted @mrctorres Which file did you both use?? From my repository?? https://github.com/jacekk015/zha_quirks/blob/main/ts0601_temperature.py
User below successfully used my quirk. https://github.com/jacekk015/zha_quirks/issues/6
For getting the device you working OK you need deleting it and waiting one minute and then adding it new after the quirk have being installed or the tuya magic is not working.
Yes I used the one mentioned here https://github.com/zigpy/zha-device-handlers/issues/1286#issuecomment-1463798600
I have one device working ok with temp & hum HA sensors as output in HA. The other one, which I deleted, powered off 2 hours, now re-added also is well detected but simply does not show these 2 as sensors, only 4 binary states, and the settings options.
But using the zigbee management I am able read the values manually for these temp and hum Clusters.
Otherwise, could be they have different tuya FW on them?
Do you use latest version from: https://github.com/jacekk015/zha_quirks ???
Use latest version quirk file. Enable debug logging https://github.com/jacekk015/zha_quirks#in-case-of-errors-or-to-support-new-function Restart HA
Remove that non working device, and pair like a new. After pairing wait at least 10 minutes. Post full HA logs here. Don't cut out anything.
I have it working after a bit of a voodoo dance...
My steps were:
At this point it is functioning correctly. The only anomaly is the 4 unidentified Binaryinput sensors and the "switch" control. I wonder what they all do?
What'd be awesome is some way to set the display to F rather than C.
Hi everybody,
My Tuya devices has no entities/controls in home assistant. It´s Zigbee Tuya Temp & Humi Display with integr. Clock.
Thanks in advance for the support.
Log.txt