Koenkk / zigbee2mqtt

Zigbee 🐝 to MQTT bridge 🌉, get rid of your proprietary Zigbee bridges 🔨
https://www.zigbee2mqtt.io
GNU General Public License v3.0
11.68k stars 1.64k forks source link

[New device support]: _TZE284_sgabhwa6 Smart Soil Sensor #23260

Open syphernl opened 1 month ago

syphernl commented 1 month ago

Link

https://www.aliexpress.com/item/1005007044173080.html

Database entry

{"id":51,"type":"EndDevice","ieeeAddr":"xxxxxxxxxx","nwkAddr":xxxxx,"manufId":4417,"manufName":"_TZE284_sgabhwa6","powerSource":"Battery","modelId":"TS0601","epList":[1],"endpoints":{"1":{"profId":260,"epId":1,"devId":81,"inClusterList":[4,5,61184,0,60672],"outClusterList":[25,10],"clusters":{"genBasic":{"attributes":{"65487":14400,"65503":"\u0004\u0000\u0000\u0000e\u0006\u0000\u0000\u0000\u0012�Q\u0019.\u0019�Q\u0019.\u0007\u0000\u0000\u0000\u0000\u0011","65506":56,"65508":1,"65534":0,"modelId":"TS0601","manufacturerName":"_TZE284_sgabhwa6","powerSource":3,"zclVersion":3,"appVersion":77,"stackVersion":0,"hwVersion":1,"dateCode":""}}},"binds":[],"configuredReportings":[],"meta":{}}},"appVersion":77,"stackVersion":0,"hwVersion":1,"dateCode":"","zclVersion":3,"interviewCompleted":true,"meta":{"configured":332242049},"lastSeen":1720095939380}

Comments

In debug mode, pushing the button results in the following Datapoints to be sent:

[2024-07-04 14:28:16] debug:    zhc:tuya: Datapoint 3 not defined for '_TZE284_sgabhwa6' with value 0
[2024-07-04 14:28:16] debug:    zhc:tuya: Datapoint 5 not defined for '_TZE284_sgabhwa6' with value 213
[2024-07-04 14:28:16] debug:    zhc:tuya: Datapoint 110 not defined for '_TZE284_sgabhwa6' with value 703

All DP's increase once I touch the prongs of the device and click the button on it. DP3 might the be temperature as it went to ~22 once held but I'm not sure what other datapoints are and how to convert them to correct values. Neither seem to be battery as it increases when held and decreases when not.

I expect this device to report:

External definition

const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const modernExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const e = exposes.presets;
const ea = exposes.access;
const tuya = require('zigbee-herdsman-converters/lib/tuya');

const definition =   {
        fingerprint: tuya.fingerprint('TS0601', ['_TZE284_g2e6cpnw']),
        fingerprint: tuya.fingerprint('TS0601', ['_TZE284_g2e6cpnw','_TZE284_sgabhwa6']),
        model: 'TS0601_soil_2',
        vendor: 'Tuya',
        description: 'Soil sensor',
        fromZigbee: [tuya.fz.datapoints],
        toZigbee: [tuya.tz.datapoints],
        configure: tuya.configureMagicPacket,
        exposes: [e.temperature(), e.soil_moisture(), e.battery(), tuya.exposes.batteryState()],
        meta: {
            tuyaDatapoints: [
                [3, 'soil_moisture', tuya.valueConverter.raw],
                [5, 'temperature', tuya.valueConverter.divideBy10],
                [102, 'battery_state', tuya.valueConverter.batteryState],
                [110, 'battery', tuya.valueConverter.divideBy10],
            ],
        },
    },
};

module.exports = definition;
syphernl commented 1 month ago

Seems it is already supported, but not fingerprinted properly. I have opened a PR to add this.

https://github.com/Koenkk/zigbee-herdsman-converters/pull/7741

syphernl commented 1 month ago

Reopening this as this device appears to be different from the _TZE284_g2e6cpnw one.

The battery_state is only reporting on 1 of the 3 devices I have (and is reporting low). The battery is being reported by all 3 but their graphs are identical to the one of the temperature, except there are different values.

It appears that DP 110 is the temperature, but in Fahrenheit.. DP5 (divide by 10) = 20,5 °C, DP110 (divide by 10) is "68,9%". According to an online fahrenheid-to-celcius conversion this matches the celcius temperature

That leaves me with 2 questions:

-- edit:

These observations are also being made in https://github.com/Koenkk/zigbee-herdsman-converters/pull/7710

nikito7 commented 1 month ago

Tuya app

Screenshot_20240708_153320_Tuya Smart

Maybe sensitivity can be changed on device

Temp sensitivity 0.5-3.0 Moisture sensitivity 5-10

setfire2 commented 1 month ago

Hello @syphernl Thanks for sharing your external definition. My TS0601 Soil Sensor identifies as _TZE284_sgabhwa6 as well. I copied your external definition to the same directory as z2m configuration.yaml and named it TS0601_soil_2.js In configuration.yaml I added

external_converters:
  - TS0601_soil_2.js

After restarting z2m and pairing the device, z2m still says the device is not supported. Am I missing anything? It's my first time using external converters.

steenlarsen commented 1 month ago

Regarding the above Tyua app information. I read the manual that came with my sensor and from that I assume the following : 1) Temp and moisture sensitivity defines after what amount of change the sensor sends the new values to the Zigbee gateway. (to save battery) 2) The 10 minutes time defines how often the sensor reports it status to the Zigbee gateway even if the sensitivity levels are not triggered. 3) The max and minimum temp and humidity seems to be linked to a kind of alarm feature which will trigger scenes that can be used to turn on watering systems.

Some text from the manual :

  1. Detection logic

    (1) Logic for reporting soil temperature and humidity. The device will trigger a report based on the detection time, temperature sensitivity and humidity sensitivity.

    If the detection time is set to 20 minutes, the temperature sensitivity is 0.5 degrees Celcius and the humidity sensitivity is 10%. The device will detect every 20 minutes. If the soil temperature changes by more than 0.5 or the soil humidity changes by more than 10% the main interface of the APP will update the soil temperature and humidity values.

    (2) Soil temperature and humidity alarm logic.

The device will trigger an alarm based on whether it is above the upper limit or below the lower limit of temperature and humidity. For example, if the device is set to a maximum humidity of 90% and the soil humidity exceeds 90%, the device will trigger a high humidity alarm.

Other function

(1) Scene linkage

Eg: When the soil temperature and humidity are detected to be below 50%, the scene linkage will automatically turn on the watering equipment and count down to 5 minutes for watering.

Hope this is useful for you.

jvrodrisan commented 1 month ago

Hi, it seems this device will be covered under this new definition https://github.com/Koenkk/zigbee-herdsman-converters/pull/7803.

I am testing this def. as an external definition, but some things such as the humidity are not yet reliable... we will wait for this PR to be merged in dev and will further test it.

In the meantime, I have debugged the tuya DPs, here they are for this device should someone need them:

{"3":"Moisture",
"5":"Temperature",
"9":"Temp Unit ",
"14":"Battery Level ",
"15":"Battery level",
"101":"Temp Alarm",
"102":"Moisture Alarm",
"103":"Maxtemp Set",
"104":"Minitemp Set",
"105":"Maxhum Set",
"106":"Minihum Set",
"107":"Temp Sensitivity",
"108":"Moisture Sensitivity",
"109":"Detection time",
"110":"Temperature",
"111":"Temp Sensitivity",
"112":"Maxtemp Set",
"113":"Minitemp Set"}
goberhammer commented 4 weeks ago

So I gave it a try and tried to somewhat merge the external definition suggested in a previous comment https://github.com/Koenkk/zigbee2mqtt/issues/23260#issue-2390785832 with this PR https://github.com/Koenkk/zigbee-herdsman-converters/pull/7710/files Note that is my first ever external definition and I'm basically doing copy and paste (C developer here, knows nothing about Java/TypeScript :-) )

const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const modernExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const e = exposes.presets;
const ea = exposes.access;
const tuya = require('zigbee-herdsman-converters/lib/tuya');

const definition =   {
    fingerprint: tuya.fingerprint('TS0601', ['_TZE284_sgabhwa6']),
    model: 'TS0601_soil_2',
    vendor: 'Tuya',
    description: 'Soil sensor',
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tuya.tz.datapoints],
    configure: tuya.configureMagicPacket,
    exposes: [
        e.temperature(),
        e.soil_moisture(),
        e.battery(),
        tuya.exposes.batteryState(),
        tuya.exposes.temperatureUnit(),
        e.detection_interval(),
    ],
    meta: {
        tuyaDatapoints: [
            [3, 'soil_moisture', tuya.valueConverter.raw],
            [5, 'soil_temperature_celsius', tuya.valueConverter.divideBy10],
            [9, 'temperature_unit', tuya.valueConverter.temperatureUnitEnum],
            [14, 'battery_state', tuya.valueConverter.batteryState],
            [15, 'battery', tuya.valueConverter.raw],
            [101, 'soil_temperature_alarm', tuya.valueConverter.raw],
            [102, 'soil_moisture_alarm', tuya.valueConverter.raw],
            [103, 'max_soil_temperature_set_celsius', tuya.valueConverter.raw],
            [104, 'min_soil_temperature_set_celsius', tuya.valueConverter.raw],
            [105, 'max_soil_moisture_set', tuya.valueConverter.raw],
            [106, 'min_soil_moisture_set', tuya.valueConverter.raw],
            [107, 'soil_temperature_sensitivity_celsius', tuya.valueConverter.raw],
            [108, 'soil_moisture_sensitivity', tuya.valueConverter.raw],
            [109, 'detection_interval', tuya.valueConverter.raw],
            [110, 'soil_temperature_fahrenheit', tuya.valueConverter.divideBy10],
            [111, 'soil_temperature_sensitivity_fahrenheit', tuya.valueConverter.raw],
            [112, 'max_soil_temperature_set_fahrenheit', tuya.valueConverter.raw],
            [113, 'min_soil_temperature_set_fahrenheit', tuya.valueConverter.raw],
        ],
    },
};

module.exports = definition;

With the above code, I get this for Exposes: Screenshot from 2024-07-29 17-37-52

And this for State:

{
    "battery": null,
    "linkquality": 156,
    "soil_moisture": 0,
    "temperature": null,
    "battery_state": null,
    "detection_interval": null,
    "soil_temperature_celsius": 31,
    "soil_temperature_fahrenheit": 87.8,
    "temperature_unit": "celsius",
    "soil_moisture_alarm": 0
}

Which do not seem ok/correct. As I said, I'm out of my deeps here, any help/correction would be appreciated :-)

For @setfire2 : to use this:

rare-magma commented 4 weeks ago

@goberhammer probably better to give this one a try https://github.com/Koenkk/zigbee-herdsman-converters/pull/7803/files it seems to have been created by the manufacturer

setfire2 commented 4 weeks ago

@goberhammer: thanks for your commitment and trying to help me out. I'll try out both versions, yours and the one from the manufacturer.

goberhammer commented 4 weeks ago

@rare-magma thanks for pointing me to the PR. I've quickly updated my external definition from that, here it is:

import fz from '../converters/fromZigbee';
import * as exposes from '../lib/exposes';
import * as legacy from '../lib/legacy';
const e = exposes.presets;
const ea = exposes.access;
import * as tuya from '../lib/tuya';
import {Definition} from '../lib/types';

const definition =   {
    fingerprint: tuya.fingerprint('TS0601', ['_TZE284_sgabhwa6']),
    model: 'NAS-STH01B2',
    vendor: 'NEO',
    description: 'Soil moisture and temperature',
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tuya.tz.datapoints],
    configure: tuya.configureMagicPacket,
    exposes: [
        e.numeric('humidity', ea.STATE).withUnit('%').withValueMin(0).withValueMax(100).withDescription('Soil humidity'),
        e.numeric('temperature', ea.STATE).withUnit('°C').withValueMin(-10).withValueMax(60).withDescription('Soil temperature'),
        e.numeric('temperature_f', ea.STATE).withUnit('°F').withValueMin(14).withValueMax(140).withDescription('Soil temperature'),
        e
            .numeric('temperature_sensitivity', ea.STATE_SET)
            .withUnit('°C')
            .withValueMin(0.3)
            .withValueMax(1)
            .withValueStep(0.1)
            .withDescription('Upper temperature limit'),
        e.numeric('humidity_sensitivity', ea.STATE_SET).withUnit('%').withValueMin(1).withValueMax(5).withDescription('Upper temperature limit'),
        e.enum('temperature_alarm', ea.STATE, ['lower_alarm', 'upper_alarm', 'cancel']).withDescription('Temperature alarm state'),
        e.enum('humidity_alarm', ea.STATE, ['lower_alarm', 'upper_alarm', 'cancel']).withDescription('Humidity alarm state'),
        e
            .numeric('max_temperature_alarm', ea.STATE_SET)
            .withUnit('°C')
            .withValueMin(0)
            .withValueMax(60)
            .withDescription('Upper temperature limit'),
        e
            .numeric('min_temperature_alarm', ea.STATE_SET)
            .withUnit('°C')
            .withValueMin(0)
            .withValueMax(60)
            .withDescription('Lower temperature limit'),
        e.numeric('max_humidity_alarm', ea.STATE_SET).withUnit('%').withValueMin(0).withValueMax(100).withDescription('Upper humidity limit'),
        e.numeric('min_humidity_alarm', ea.STATE_SET).withUnit('%').withValueMin(0).withValueMax(100).withDescription('Lower humidity limit'),
        e.numeric('schedule_periodic', ea.STATE_SET).withUnit('min').withValueMin(5).withValueMax(60).withDescription('Report sensitivity'),
        e.numeric('battery_percentage', ea.STATE).withUnit('%').withValueMin(0).withValueMax(100).withDescription('Battery percentage'),
    ],
    meta: {
        tuyaDatapoints: [
            [
                101,
                'temperature_alarm',
                tuya.valueConverterBasic.lookup({
                    lower_alarm: tuya.enum(0),
                    upper_alarm: tuya.enum(1),
                    cancel: tuya.enum(2),
                }),
            ],
            [
                102,
                'humidity_alarm',
                tuya.valueConverterBasic.lookup({
                    lower_alarm: tuya.enum(0),
                    upper_alarm: tuya.enum(1),
                    cancel: tuya.enum(2),
                }),
            ],
            [3, 'humidity', tuya.valueConverter.divideBy10],
            [5, 'temperature', tuya.valueConverter.divideBy10],
            [110, 'temperature_f', tuya.valueConverter.divideBy10],
            [107, 'temperature_sensitivity', tuya.valueConverter.divideBy10],
            [108, 'humidity_sensitivity', tuya.valueConverter.raw],
            [103, 'max_temperature_alarm', tuya.valueConverter.divideBy10],
            [104, 'min_temperature_alarm', tuya.valueConverter.divideBy10],
            [105, 'max_humidity_alarm', tuya.valueConverter.raw],
            [106, 'min_humidity_alarm', tuya.valueConverter.raw],
            [109, 'schedule_periodic', tuya.valueConverter.raw],
            [15, 'battery_percentage', tuya.valueConverter.raw],
        ],
    },
};

module.exports = definition;

But this seems not to work, and strangely enough the sensor is still recognized with the old external definition even if I've removed it from config and deleted from disk. Does Z2M cache the definitions of found devices somewhere ?

setfire2 commented 4 weeks ago

From https://github.com/Koenkk/zigbee-herdsman-converters/pull/7803/files I added lines 291-363 to my neo,js and removed the definitions from tuya.js and seems to work quite well. I see much more values and configuration options now. @baggiowu: Only the following description seems wrong: image

setfire2 commented 4 weeks ago

@baggiowu: please notice my comment on line 350 of neo.ts. Also I get no value for the battery level.

goberhammer commented 3 weeks ago

So this device is driving me a little insane... I've grepped though all the sources and confirmed that there is no other tuya fingerprint of device type _TZE284_sgabhwa6 and the only definition is in my added external definition from a previous comment ( https://github.com/Koenkk/zigbee2mqtt/issues/23260#issuecomment-2256635278 ) Yet if I remove the device, restart Z2M and re-add it, it still is wrongly identified as another device (see image): Screenshot from 2024-07-31 12-16-14 As you can see vendor is not NEO and description is different from the one in my external definition (soil sensor instad of Soil moisture and temperature). How could this be ? It seems that Z2M remembers some old definitions that is doesn't exist anymore and use that instead of the new one.... I'm lost...

goberhammer commented 3 weeks ago

Just an update: I've removed the device, updated Z2M to the latest version 1.39.1 and now the sensor works perfectly. Not all the settings available in Tuya app are visible, but at least temperature, humidity, battery seems to be correct. Battery state reports always low.

setfire2 commented 3 weeks ago

@goberhammer: unfortunately not. What you see as battery level in reality is the temperature in fahrenheit. Theres already a really good integration for this device checked in to the repo but it seems like it didn't make it into 1.39.1: https://github.com/Koenkk/zigbee-herdsman-converters/pull/7816/commits/14406fce7cecb7b94c18a91c5e9f1b79e33bf7ac See also this conversation: https://github.com/Koenkk/zigbee-herdsman-converters/pull/7816

goberhammer commented 3 weeks ago

Thanks for the heads-up :-D I was able to patch my tuya.js (into the Docker container) directly from the tuya.ts file in the patch you linked and now it works a lot better.

setfire2 commented 3 weeks ago

You're welcome!