Wait.
There seems to be a specific query that must be sent to the devie after it joins the Zigbee network, and there is no such code in the driver at this time. I will try to implement it in the next days.
Logs after humidity change if it helps:
debug logs
dev:1342025-08-12 04:13:51.708 PM
warn
Bathroom clock Unprocessed Tuya cluster command: cluster=EF00 command=11 attrId=null value=null data=[00, 03, 40]
dev:1342025-08-12 04:13:51.703 PM
debug
Bathroom clock parse() descMap =[raw:catchall: 0104 EF00 01 01 0040 00 3D81 01 00 0000 11 01 000340, profileId:0104, clusterId:EF00, clusterInt:61184, sourceEndpoint:01, destinationEndpoint:01, options:0040, messageType:00, dni:3D81, isClusterSpecific:true, isManufacturerSpecific:false, manufacturerId:0000, command:11, direction:01, data:[00, 03, 40]] description = catchall: 0104 EF00 01 01 0040 00 3D81 01 00 0000 11 01 000340
dev:1342025-08-12 04:13:51.638 PM
debug
Bathroom clock Tuya check-in message (attribute 0001 reported: 49)
dev:1342025-08-12 04:13:51.631 PM
debug
Bathroom clock parse() descMap =[raw:3D810100001801002049E2FF2038E4FF2001, dni:3D81, endpoint:01, cluster:0000, size:18, attrId:0001, encoding:20, command:0A, value:49, clusterInt:0, attrInt:1, additionalAttrs:[[value:38, encoding:20, attrId:FFE2, consumedBytes:4, attrInt:65506], [value:01, encoding:20, attrId:FFE4, consumedBytes:4, attrInt:65508]]] description = read attr - raw: 3D810100001801002049E2FF2038E4FF2001, dni: 3D81, endpoint: 01, cluster: 0000, size: 18, attrId: 0001, encoding: 20, command: 0A, value: 49E2FF2038E4FF2001
dev:1342025-08-12 04:13:38.144 PM
info
Bathroom clock device announcement
dev:1342025-08-12 04:13:38.139 PM
debug
Bathroom clock parse() descMap =[raw:catchall: 0000 0013 00 00 0040 00 3D81 00 00 0000 00 00 00813D4C3F248F8D38C1A480, profileId:0000, clusterId:0013, clusterInt:19, sourceEndpoint:00, destinationEndpoint:00, options:0040, messageType:00, dni:3D81, isClusterSpecific:false, isManufacturerSpecific:false, manufacturerId:0000, command:00, direction:00, data:[00, 81, 3D, 4C, 3F, 24, 8F, 8D, 38, C1, A4, 80]] description = catchall: 0000 0013 00 00 0040 00 3D81 00 00 0000 00 00 00813D4C3F248F8D38C1A480
dev:1342025-08-12 04:13:07.191 PM
debug
Bathroom clock NOT PARSED : [raw:3D8101000026DFFF420F9D9E2D30199D9E2D30070000000011, dni:3D81, endpoint:01, cluster:0000, size:26, attrId:FFDF, encoding:42, command:0A, value:-0-0a, clusterInt:0, attrInt:65503]
dev:1342025-08-12 04:13:07.186 PM
debug
Bathroom clock parse() descMap =[raw:3D8101000026DFFF420F9D9E2D30199D9E2D30070000000011, dni:3D81, endpoint:01, cluster:0000, size:26, attrId:FFDF, encoding:42, command:0A, value:-0-0a, clusterInt:0, attrInt:65503] description = read attr - raw: 3D8101000026DFFF420F9D9E2D30199D9E2D30070000000011, dni: 3D81, endpoint: 01, cluster: 0000, size: 26, attrId: FFDF, encoding: 42, command: 0A, value: 0F9D9E2D30199D9E2D30070000000011
Matt, you can try the new version - timestamp '2025/08/12 1:18 PM'
It sends the expected query command to Tuya TS0601 devices when requested and automatically when rejoining the Zigbee network. Hopefully, this extra magic will allow the device to report changes in temperature and humidity automatically.
Seems to be working great now!
Thanks @kkossev!
Driver update (for manual updates, it is not pushed via HPM yet) :
- ver. 1.9.0 2025-08-31 - added a total of 31 new devices:
- added missing TS0601 variants (_TZE200_44af8vyi _TZE284_qyflbnbj _TZE284_yjjdcqsq _TZE200_utkemkbs _TZE204_utkemkbs _TZE284_utkemkbs _TZE284_upagmta9 _TZE284_vvmbj46n _TZE200_w6n8jeuu _TZE200_s1xgth2u _TZE200_vzqtvljm _TZE200_rbbx5mfq _TZE200_nvups4nh);
- added TS0201 variants (_TZ3210_alxkwn0h _TZ3000_0s1izerx _TZ3000_v1w2k9dd _TZ3000_lqmvrwa2 _TZ3000_f2bw0b6k _TZ3000_mxzo5rhf _TZ3000_1twfmkcc _TZ3000_fie1dpkm _TZ3000_saiqcn0y _TZ3000_akqdg6g7 _TZE200_iq4ygaai _TZE200_01fvxamo);
- added TS0601 _TZE284_33bwcga2 to TS0601_Soil_II group; added missing model map _TZE200_bjawzodf.
- added Nous devices _TZE200_qrztc3ev, _TZE200_snloy4rw, _TZE200_eanjj2pa, _TZE200_ydrdfkim
Hi @kkossev
I've just purchased a Tuya Temp and Soil moisture sensor.
Pairing it selects this driver but it isn't working as it should.
I manually selected TS0601_Soil_II but it doesn't seem to work.
Here is some info for you should you need it.
Here is the Get Info logs.
Any chance you can add this to your driver or perhaps it should already work.
Any help/advice much appreciated.
Many Thanks.
Try the updated ver. 1.9.1 2025-09-02 (dev. branch)
- added TS0601 _TZE284_oitavov2 and _TZE200_2se8efxh to 'TS0601_Soil' group;
- added TS0601 _TZE284_ap9owrsa to 'TS0601_Soil_2' group
Thanks @kkossev. The driver is working a treat.
There is one thing that I noticed.
If the humidity value is 0, which I appreciate it should never be, it does throw an error and the value does not update in the driver.
Here is the error.
[dev:768](http://192.168.0.23/logs#)2025-09-02 15:43:05.343 warn Outside-Basket T+H ignored invalid humidity 0 (0.0)
[dev:768](http://192.168.0.23/logs#)2025-09-02 15:43:05.333 debug Outside-Basket T+H Soil Sensor humidity raw = 0
Just thought it worth a mention and thanks again.
Hi @kkossev.
Sorry to be a pain in the butt but the temperature reporting is coming in with no decimal points.
Is there any chance the code could be amended to give one decimal place or does the device report in whole numbers and therefore not be configurable.
Thanks again.
As long as the whole number is the temperature (ex: 235 is 23.5) a decimal can be added.
Find the case 0x05 section in the driver code,
case 0x05 : // Soil Monitor
if (fncmd > 32767) {
// not good for the plants ...
fncmd = fncmd - 65536
}
if (getModelGroup() in ['TS0601_Soil']) {
temperatureEvent( fncmd )
}
else if (getModelGroup() in ['TS0601_Soil', 'TS0601_Soil_II']) {
temperatureEvent( fncmd / 10.0 )
}
else {
if (settings?.logEnable) { log.warn "${device.displayName} Soil Monitor reported value ${fncmd}" }
}
break
and replace it with,
case 0x05 : // Soil Monitor
if (fncmd > 32767) {
// not good for the plants ...
fncmd = fncmd - 65536
}
// Check for specific manufacturer that needs decimal points
if (device.getDataValue('manufacturer') == '_TZE284_oitavov2') {
temperatureEvent( fncmd / 10.0 )
}
else if (getModelGroup() in ['TS0601_Soil']) {
temperatureEvent( fncmd )
}
else if (getModelGroup() in ['TS0601_Soil', 'TS0601_Soil_II']) {
temperatureEvent( fncmd / 10.0 )
}
else {
if (settings?.logEnable) { log.warn "${device.displayName} Soil Monitor reported value ${fncmd}" }
}
break
Give that a try.
It's only going to add a decimal for your specific device type, to not mess with other peoples devices so if it works @kkossev can adopt it into his code.
I'm trying to get 2 TS0201 TZ3000_fllyghyj temperature sensors working but they aren't reporting anything.
The events says it's online:
healthStatus online kkossev Driver healthStatus set to online digital Tb2 9/06/2025 11:54:50.583 am
healthStatus unknown kkossev Driver healthStatus set to unknown digital Tb2 9/06/2025 11:54:50.033 am
_info installed Tb2 9/06/2025 11:54:49.880 am
healthStatus online kkossev Driver healthStatus set to online digital Tb2 9/06/2025 11:54:49.872 am
healthStatus unknown kkossev Driver healthStatus set to unknown digital Tb2 9/06/2025 11:54:49.865 am
But the logs have some warnings:
dev:3542025-09-06 11:55:15.103 AMwarn
Tb2 Unprocessed ZDO command: cluster=0000 command=00 attrId=null value=null data=[0C, D0, 0C, C1, FE, FF, ED, 2C, C0, 00, 00]
dev:3542025-09-06 11:55:15.101 AMdebug
Tb2 parse() descMap =[raw:catchall: 0000 0000 00 00 0040 00 5F0C 00 00 0000 00 00 0CD00CC1FEFFED2CC00000, profileId:0000, clusterId:0000, clusterInt:0, sourceEndpoint:00, destinationEndpoint:00, options:0040, messageType:00, dni:5F0C, isClusterSpecific:false, isManufacturerSpecific:false, manufacturerId:0000, command:00, direction:00, data:[0C, D0, 0C, C1, FE, FF, ED, 2C, C0, 00, 00]] description = catchall: 0000 0000 00 00 0040 00 5F0C 00 00 0000 00 00 0CD00CC1FEFFED2CC00000
dev:3542025-09-06 11:55:14.953 AMwarn
Tb2 Unprocessed ZDO command: cluster=0002 command=00 attrId=null value=null data=[0B, 00, 00]
dev:3542025-09-06 11:55:14.951 AMdebug
Tb2 parse() descMap =[raw:catchall: 0000 0002 00 00 0040 00 5F0C 00 00 0000 00 00 0B0000, profileId:0000, clusterId:0002, clusterInt:2, sourceEndpoint:00, destinationEndpoint:00, options:0040, messageType:00, dni:5F0C, isClusterSpecific:false, isManufacturerSpecific:false, manufacturerId:0000, command:00, direction:00, data:[0B, 00, 00]] description = catchall: 0000 0002 00 00 0040 00 5F0C 00 00 0000 00 00 0B0000
dev:3542025-09-06 11:55:13.761 AMinfo
Tb2 device announcement
dev:3542025-09-06 11:55:13.759 AMdebug
Tb2 parse() descMap =[raw:catchall: 0000 0013 00 00 0040 00 5F0C 00 00 0000 00 00 0A0C5FBCD94CD69338C1A480, profileId:0000, clusterId:0013, clusterInt:19, sourceEndpoint:00, destinationEndpoint:00, options:0040, messageType:00, dni:5F0C, isClusterSpecific:false, isManufacturerSpecific:false, manufacturerId:0000, command:00, direction:00, data:[0A, 0C, 5F, BC, D9, 4C, D6, 93, 38, C1, A4, 80]] description = catchall: 0000 0013 00 00 0040 00 5F0C 00 00 0000 00 00 0A0C5FBCD94CD69338C1A480
dev:3542025-09-06 11:55:04.251 AMwarn
Tb2 Unprocessed ZDO command: cluster=0002 command=00 attrId=null value=null data=[09, 00, 00]
dev:3542025-09-06 11:55:04.249 AMdebug
Tb2 parse() descMap =[raw:catchall: 0000 0002 00 00 0040 00 5F0C 00 00 0000 00 00 090000, profileId:0000, clusterId:0002, clusterInt:2, sourceEndpoint:00, destinationEndpoint:00, options:0040, messageType:00, dni:5F0C, isClusterSpecific:false, isManufacturerSpecific:false, manufacturerId:0000, command:00, direction:00, data:[09, 00, 00]] description = catchall: 0000 0002 00 00 0040 00 5F0C 00 00 0000 00 00 090000
dev:3542025-09-06 11:54:59.370 AMwarn
Tb2 Unprocessed ZDO command: cluster=0000 command=00 attrId=null value=null data=[08, D0, 0C, C1, FE, FF, ED, 2C, C0, 00, 00]
dev:3542025-09-06 11:54:59.368 AMdebug
Tb2 parse() descMap =[raw:catchall: 0000 0000 00 00 0040 00 5F0C 00 00 0000 00 00 08D00CC1FEFFED2CC00000, profileId:0000, clusterId:0000, clusterInt:0, sourceEndpoint:00, destinationEndpoint:00, options:0040, messageType:00, dni:5F0C, isClusterSpecific:false, isManufacturerSpecific:false, manufacturerId:0000, command:00, direction:00, data:[08, D0, 0C, C1, FE, FF, ED, 2C, C0, 00, 00]] description = catchall: 0000 0000 00 00 0040 00 5F0C 00 00 0000 00 00 08D00CC1FEFFED2CC00000
dev:3542025-09-06 11:54:59.270 AMwarn
Tb2 Unprocessed ZDO command: cluster=0002 command=00 attrId=null value=null data=[07, 00, 00]
dev:3542025-09-06 11:54:59.245 AMdebug
Tb2 parse() descMap =[raw:catchall: 0000 0002 00 00 0040 00 5F0C 00 00 0000 00 00 070000, profileId:0000, clusterId:0002, clusterInt:2, sourceEndpoint:00, destinationEndpoint:00, options:0040, messageType:00, dni:5F0C, isClusterSpecific:false, isManufacturerSpecific:false, manufacturerId:0000, command:00, direction:00, data:[07, 00, 00]] description = catchall: 0000 0002 00 00 0040 00 5F0C 00 00 0000 00 00 070000
dev:3542025-09-06 11:54:54.241 AMwarn
kkossev Driver Unprocessed ZDO command: cluster=0002 command=00 attrId=null value=null data=[06, 00, 00]
dev:3542025-09-06 11:54:54.238 AMdebug
kkossev Driver parse() descMap =[raw:catchall: 0000 0002 00 00 0040 00 5F0C 00 00 0000 00 00 060000, profileId:0000, clusterId:0002, clusterInt:2, sourceEndpoint:00, destinationEndpoint:00, options:0040, messageType:00, dni:5F0C, isClusterSpecific:false, isManufacturerSpecific:false, manufacturerId:0000, command:00, direction:00, data:[06, 00, 00]] description = catchall: 0000 0002 00 00 0040 00 5F0C 00 00 0000 00 00 060000
dev:3542025-09-06 11:54:51.085 AMtrace
kkossev Driver sendZigbeeCommands(cmd=[])
dev:3542025-09-06 11:54:51.083 AMinfo
kkossev Driver Debug logging will be turned off after 24 hours
dev:3542025-09-06 11:54:51.072 AMinfo
kkossev Driver Debug logging is true; Description text logging is true
dev:3542025-09-06 11:54:51.070 AMinfo
kkossev Driver Updating null (kkossev Driver) model TS0201 manufacturer _TZ3000_fllyghyj modelGroupPreference = Auto detect (TS0201)
dev:3542025-09-06 11:54:50.649 AMdebug
kkossev Driver NOT PARSED : [raw:5F0C01000068040042105F545A333030305F666C6C796768796A0000002003010000204605000042065453303230310700003003FEFF003000, dni:5F0C, endpoint:01, cluster:0000, size:68, attrId:0004, encoding:42, command:01, value:_TZ3000_fllyghyj, clusterInt:0, attrInt:4, additionalAttrs:[[value:03, encoding:20, attrId:0000, consumedBytes:4, attrInt:0], [value:46, encoding:20, attrId:0001, consumedBytes:4, attrInt:1], [value:TS0201, encoding:42, attrId:0005, consumedBytes:9, attrInt:5]]]
dev:3542025-09-06 11:54:50.642 AMdebug
kkossev Driver parse() descMap =[raw:5F0C01000068040042105F545A333030305F666C6C796768796A0000002003010000204605000042065453303230310700003003FEFF003000, dni:5F0C, endpoint:01, cluster:0000, size:68, attrId:0004, encoding:42, command:01, value:_TZ3000_fllyghyj, clusterInt:0, attrInt:4, additionalAttrs:[[value:03, encoding:20, attrId:0000, consumedBytes:4, attrInt:0], [value:46, encoding:20, attrId:0001, consumedBytes:4, attrInt:1], [value:TS0201, encoding:42, attrId:0005, consumedBytes:9, attrInt:5]]] description = read attr - raw: 5F0C01000068040042105F545A333030305F666C6C796768796A0000002003010000204605000042065453303230310700003003FEFF003000, dni: 5F0C, endpoint: 01, cluster: 0000, size: 68, attrId: 0004, encoding: 42, command: 01, value: 105F545A333030305F666C6C796768796A0000002003010000204605000042065453303230310700003003FEFF003000
dev:3542025-09-06 11:54:50.635 AMinfo
kkossev Driver Received Write Attribute Response for cluster:0000 , data=[00] (Status: Success)
dev:3542025-09-06 11:54:50.632 AMdebug
kkossev Driver parse() descMap =[raw:catchall: 0104 0000 01 01 0040 00 5F0C 00 00 0000 04 01 00, profileId:0104, clusterId:0000, clusterInt:0, sourceEndpoint:01, destinationEndpoint:01, options:0040, messageType:00, dni:5F0C, isClusterSpecific:false, isManufacturerSpecific:false, manufacturerId:0000, command:04, direction:01, data:[00]] description = catchall: 0104 0000 01 01 0040 00 5F0C 00 00 0000 04 01 00
dev:3542025-09-06 11:54:50.596 AMdebug
kkossev Driver NOT PARSED : [raw:5F0C01000068040042105F545A333030305F666C6C796768796A0000002003010000204605000042065453303230310700003003FEFF003000, dni:5F0C, endpoint:01, cluster:0000, size:68, attrId:0004, encoding:42, command:01, value:_TZ3000_fllyghyj, clusterInt:0, attrInt:4, additionalAttrs:[[value:03, encoding:20, attrId:0000, consumedBytes:4, attrInt:0], [value:46, encoding:20, attrId:0001, consumedBytes:4, attrInt:1], [value:TS0201, encoding:42, attrId:0005, consumedBytes:9, attrInt:5]]]
dev:3542025-09-06 11:54:50.590 AMdebug
kkossev Driver parse() descMap =[raw:5F0C01000068040042105F545A333030305F666C6C796768796A0000002003010000204605000042065453303230310700003003FEFF003000, dni:5F0C, endpoint:01, cluster:0000, size:68, attrId:0004, encoding:42, command:01, value:_TZ3000_fllyghyj, clusterInt:0, attrInt:4, additionalAttrs:[[value:03, encoding:20, attrId:0000, consumedBytes:4, attrInt:0], [value:46, encoding:20, attrId:0001, consumedBytes:4, attrInt:1], [value:TS0201, encoding:42, attrId:0005, consumedBytes:9, attrInt:5]]] description = read attr - raw: 5F0C01000068040042105F545A333030305F666C6C796768796A0000002003010000204605000042065453303230310700003003FEFF003000, dni: 5F0C, endpoint: 01, cluster: 0000, size: 68, attrId: 0004, encoding: 42, command: 01, value: 105F545A333030305F666C6C796768796A0000002003010000204605000042065453303230310700003003FEFF003000
Any ideas @kkossev ?
I've tried repairing, near the hub and away, using without zigbee repeater option, pairing to smartthings hub (works on it) then repairing to Hubitat.
Using the Run and refresh commands but the health status just changes to Unknown and Not Present Counter starts counting up.
Repairing the sensor without removing it from Hubitat also doesn't work.
I've currently got these sensors inside my 3D printer enclosure to see if them heating up forces an update buy so far, nothing.
When pairing, the light is blinking and once Hubitat says device found, initializing, the light stops blinking so it seems like it is pairing properly.
I've updated my hub to 2.4.2.158 version and it still didn't work even after a repair.
I'm going to get AI to write me a driver to see if it can even get it to report temp/humidity data though I am pretty sure my sensors are not faulty.
The soil sensors from ''TS0601_Soil'' group are reporting integer values to the hub, so dividing by 10 will result in a temperature reading 10 times less than the real one. Only the soild sensors from the 'TS0601_Soil_II' group report decimal precision values.
I see now there is a leftover/bug in the code, the second 'else if' should not contain 'TS0601_Soil' (as it was already checked in the previous 'else if') - I will fix it in the next update, although it does not affect the functionality.
The problem with this device seems very similar to this one :
That magical sequence worked. Thanks
Is that something that would end up getting fixed or is it not a fixable issue.
Just purchased the Tuya ts0601 soil moisture sensor.
Have gotten it to pair fine with your driver. But can’t the states to populate correctly if at all. There is no soil moisture state.
I tried all various was of resetting and repairing to no avail.
Any guidance is appreciated
Most probably the Zigbee pairing fails... If your hub is a C-8, use this pairing procedure.
If your hub is C-7 (or older) - first reboot the hub and pair the device as soon as the HE web interface becomes accessible.
There are dozens of totally different Tuya soil moisture sensors, all built by different manufacturers on the Tuya TS0601 base firmware. See how to identify a Zigbee device.
Appreciate the prompt reply.
Gave your suggestion a try on my C7. Paired it right next to the hub as well.
Still not getting all states to populate.
Will keep trying
Enable the Debug logging from the Preferences tab. Anything in the live logs following a new pairing attempt?
Please share your device Zigbee model and Manufacturer (seen at the bottom of the device web page 'Device Info' tab. Also share a screenshot of the 'State Variables' section (from the first 'Commands' tab)
Appreciate your kind willingness to help.
This one was an impulse buy! Don't really have much of a use for it. Most likely going to return it. Not worth the trouble.
Thank you!
Edited: Temperature offset increase? @kkossev
It appears that increasing offset is not available. The increase icon is grayed out and a positive entry is not accepted. Is this limited by the device or the driver? Everything else works well.