Skip to content

[New device support]: Linptech Presence Sensor ES1 (TS0225__TZ3218_awarhusb) #18637

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

Open
aatifk opened this issue Aug 17, 2023 · 149 comments
Open
Labels
new device support New device support request

Comments

@aatifk
Copy link

aatifk commented Aug 17, 2023

Link

https://www.amazon.com/dp/B0C7C6L66J?ref=ppx_yo2ov_dt_b_product_details&th=1

Database entry

{"id":29,"type":"Router","ieeeAddr":"0xb43a31fffe265666","nwkAddr":29864,"manufId":4098,"manufName":"_TZ3218_awarhusb","powerSource":"Mains (single phase)","modelId":"TS0225","epList":[1],"endpoints":{"1":{"profId":260,"epId":1,"devId":1026,"inClusterList":[0,3,4,5,57346,16384,61184,1280],"outClusterList":[10,25],"clusters":{"genBasic":{"attributes":{"modelId":"TS0225","manufacturerName":"_TZ3218_awarhusb","powerSource":1,"zclVersion":3,"appVersion":65,"stackVersion":1,"hwVersion":1,"dateCode":""}},"ssIasZone":{"attributes":{"iasCieAddr":"0x00124b0026b884c4","zoneState":0}}},"binds":[],"configuredReportings":[],"meta":{}}},"appVersion":65,"stackVersion":1,"hwVersion":1,"dateCode":"","zclVersion":3,"interviewCompleted":true,"meta":{},"lastSeen":1692243468779,"defaultSendRequestWhen":"immediate"}

Comments

I see another thread requesting support for TS0225 but the manufacturer and the product pages seem to be different for this one.

External converter

No response

Supported color modes

No response

Color temperature range

No response

@aatifk aatifk added the new device support New device support request label Aug 17, 2023
@kkossev
Copy link

kkossev commented Aug 25, 2023

This device is rather different than the rest of the presence sensors based on the Tuya platform.
It uses the standard ZCL cluster 0x0400 for illuminance reporting and the IAS cluster 0x0500 for occupancy reporting.
It also uses a manufacturer-specific cluster 0xE002 for the configurable parameters and for reporting.

@aatifk
Copy link
Author

aatifk commented Aug 25, 2023

ah, I see. I should probably just return this device, then.

@kkossev
Copy link

kkossev commented Aug 25, 2023

Amazon reviews are good, I would wait some more days or weeks, it will be surely supported in Z2M sooner or later ...

The form factor of this device is the same as the Xiaomi Mi-Home Bluetooth presence detector, and Xiaomi devices are typically of a much better quality than most of the similar things coming from AliExpress.

@makeitworktech
Copy link

It would be great to see this one work! Would this method still work to find the Tuya Data Points?
https://www.zigbee2mqtt.io/advanced/support-new-devices/03_find_tuya_data_points.html

@makeitworktech
Copy link

makeitworktech commented Sep 6, 2023

Not sure if this information will help, but I can't get very far with an external converter.

Here's the illuminance cluster when my office light is off:
2023-09-06 17:37:35Received Zigbee message from '0xb43a31fffe265417', type 'raw', cluster 'msIlluminanceMeasurement', data '{"data":[8,90,10,0,0,33,1,0,0,0],"type":"Buffer"}' from endpoint 1 with groupID 0

Here's the illuminance cluster when my office light is turned on:
2023-09-06 17:43:17Received Zigbee message from '0xb43a31fffe265417', type 'raw', cluster 'msIlluminanceMeasurement', data '{"data":[8,89,10,0,0,33,134,111,0,0],"type":"Buffer"}' from endpoint 1 with groupID 0

And here is the manuSpecificTuya_2 cluster. It's at a distance and the value (shown as 214 below) goes down as i get closer to the device. Thinking distance?
2023-09-06 17:39:12Received Zigbee message from '0xb43a31fffe265417', type 'attributeReport', cluster 'manuSpecificTuya_2', data '{"57354":214}' from endpoint 1 with groupID 0

When I get really close to it, the cluster changes like this, the 57354 changing to 57345 and the 214 number jumping way up. It's like the distance measurement jumps to smaller units?
2023-09-06 17:50:48Received Zigbee message from '0xb43a31fffe265417', type 'attributeReport', cluster 'manuSpecificTuya_2', data '{"57345":4260}' from endpoint 1

And here's the IasZone cluster:
2023-09-06 17:43:49Received Zigbee message from '0xb43a31fffe265417', type 'commandStatusChangeNotification', cluster 'ssIasZone', data '{"extendedstatus":0,"zonestatus":1}' from endpoint 1 with groupID 0

I also get this genTime cluster, not sure what that does:
2023-09-06 17:44:17Received Zigbee message from '0xb43a31fffe265417', type 'read', cluster 'genTime', data '["localTime"]' from endpoint 1 with groupID 0

There's also a genBasic cluster that only shows up sometimes.
2023-09-06 17:54:55Received Zigbee message from '0xb43a31fffe265417', type 'attributeReport', cluster 'genBasic', data '{"65508":0,"appVersion":65}' from endpoint 1 with groupID 0

I just need to understand how these work rather than the typical Tuya "data points".

@VikeDragon
Copy link

Greetings! Acquired a rebranding from MOES with the same designation.

@Koenkk
Copy link
Owner

Koenkk commented Sep 8, 2023

Let's start simple, does battery and occupancy work with this? https://gist.github.com/Koenkk/2e438754fac949869e5c2cf5219382aa

  • save this as file next to configuration.yaml as ext_converter.js
  • add it to configuration.yaml:
external_converters:
  - ext_converter.js
  • start z2m

@aatifk
Copy link
Author

aatifk commented Sep 9, 2023

I had returned this because I assumed it won't work. Let me try getting a hold of this again and try the external converter.

@VikeDragon
Copy link

  • ext_converter.js

Greetings, Koenkk!
I checked this converter. For my sensor, everything works out - detects the presence. The sensor is not on batteries - it is on Type - With USB. Here are photos of the packaging and sensor, as well as the Myhome interface of the bluetooth analog Lamptech ES1, which I also have in stock. The settings of the analogue in MiHome are visible.
I also attached analogs of sensor data files and logs.

main
occupancy
photo_2023-09-09_19-18-55
photo_2023-09-09_19-19-12
photo_2023-09-09_19-19-16
photo_2023-09-09_19-19-19
photo_2023-09-09_19-19-22
photo_2023-09-09_19-19-25
logs.log
database.db.log
state.json.log

@makeitworktech
Copy link

makeitworktech commented Sep 11, 2023

external_converters:
  - ext_converter.js

I've tried the external converter. Same as @VikeDragon, I get Occupancy, Battery, and Linkquality. Occupancy and Linkquality seem to work, but Battery is "Null" since it is USB powered.

image

@kkossev
Copy link

kkossev commented Sep 11, 2023

This device also exposes the illuminance via the standard ZCL cluster 0x0400

@Koenkk
Copy link
Owner

Koenkk commented Sep 11, 2023

Added illuminance, removed battery: https://gist.github.com/Koenkk/2e438754fac949869e5c2cf5219382aa

@makeitworktech
Copy link

makeitworktech commented Sep 11, 2023

Added illuminance, removed battery: https://gist.github.com/Koenkk/2e438754fac949869e5c2cf5219382aa

Getting an error with the illuminance:
Error 2023-09-11 19:19:38Failed to configure '0xb43a31fffe265417', attempt 3 (Error: ConfigureReporting 0xb43a31fffe265417/1 msIlluminanceMeasurement([{"attribute":"measuredValue","minimumReportInterval":10,"maximumReportInterval":3600,"reportableChange":5}], {"sendWhen":"immediate","timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":true,"direction":0,"srcEndpoint":null,"reservedBits":0,"manufacturerCode":null,"transactionSequenceNumber":null,"writeUndiv":false}) failed (Timeout - 52598 - 1 - 6 - 1024 - 7 after 10000ms) at Timeout._onTimeout (/app/node_modules/zigbee-herdsman/src/utils/waitress.ts:64:35) at listOnTimeout (node:internal/timers:559:17) at processTimers (node:internal/timers:502:7))

image

@kkossev
Copy link

kkossev commented Sep 12, 2023

Try just binding the illuminance cluster without configuring the reporting.
Also, send the Tuya BlackMagic packet during the pairing, although I don't know if it has any effect or not.

This is a rather weird device... Not typical Tuya data points implementation. It uses cluster 0xE002 for configuring the parameters:
Cluster 0xE002, attribute 0xE00B - maximum detection distance, min:75, max:600, step:75, rw
Cluster 0xE002, attribute 0xE004 - 'Large motion detection sensitivity', range 0 to 5, rw
Cluster 0xE002, attribute 0xE005 - 'Small motion detection sensitivity', range 0 to 5, rw
Cluster 0xE002, attribute 0xE00A - the measured distance to the moving object, ro
Cluster 0xE002, attribute 0xE001 - 'existence time' (tuyaVersion 1.0.1 - in seconds, tuyaVersion 1.0.5 - in minutes), ro

Tuya cluster 0xEF00, data point 101 - the 'fading time', range 10..10000, rw

@iculookn
Copy link

iculookn commented Sep 12, 2023

Added illuminance, removed battery: https://gist.github.com/Koenkk/2e438754fac949869e5c2cf5219382aa

I also just got the MOES Human Presence Sensor and tried this ext converter and Lux is NULL

image

FYI - This is the correct image for the MOES Plug
https://moeshouse.com/cdn/shop/products/moes-zigbee-human-presence-sensor-detector-radar-wave-detection-sensor-for-home-security-596265.png?v=1692258238&width=600

@kkossev
Copy link

kkossev commented Sep 12, 2023

Does the MOES sensor have exactly the same fingerprint: tuya.fingerprint('TS0225', ['_TZ3218_awarhusb']) as the Linptech?

@iculookn
Copy link

Does the MOES sensor have exactly the same fingerprint: tuya.fingerprint('TS0225', ['_TZ3218_awarhusb']) as the Linptech?

Yes looks like it

image

@makeitworktech
Copy link

Try just binding the illuminance cluster without configuring the reporting. Also, send the Tuya BlackMagic packet during the pairing, although I don't know if it has any effect or not.

Still showing Illuminance as Null, but, the error has gone away. Sending configure: tuya.configureMagicPacket didn't seem to make a difference either unfortunately.

image

I've sent an email to Linptech to see if they can help out.

@xinsdr
Copy link

xinsdr commented Sep 12, 2023

Does the MOES sensor have exactly the same fingerprint: tuya.fingerprint('TS0225', ['_TZ3218_awarhusb']) as the Linptech?

Yes looks like it

image

Same thing with MOES sensor.

@iculookn
Copy link

Does the MOES sensor have exactly the same fingerprint: tuya.fingerprint('TS0225', ['_TZ3218_awarhusb']) as the Linptech?

Yes looks like it

image

Same thing with MOES sensor.

This is a screencap for the MOES version

@iculookn
Copy link

with

The MOES model number is:

ZSS-LP-HP02 CB03

image

@alexvaltchev
Copy link

Any update on the the Moes wwmave human presence sensor? Mine also shows as _TZ3218_awarhusb TS0225. What is the latest and best so far converter that exist? thanks

Screenshot_2

@alexvaltchev
Copy link

Screenshot_2023-09-14-15-42-37-690_com tuya smartlife
Screenshot_2023-09-14-15-42-40-608_com tuya smartlife
Screenshot_2023-09-14-15-42-30-903_com tuya smartlife
Screenshot_2023-09-14-15-42-35-256_com tuya smartlife

Here are some screenshots from the Smart Home app. It is pretty basic sensor. IT shows only 4 variables.

  1. Motion sensitivity - 1 to 5
  2. MotionLESS sensitivity - 1 to 5
  3. Distance 75 cm to 600 cm (6 meters)
  4. Nobody time (10 sec to 10000 sec) - not sure what this is ? Probably like "fade time"

This is everything that can be changed, only 4 settings.

It shows the following:

  1. Presence/no presence
  2. Presence time (in minutes)
  3. Current distance (in cm)
  4. Illumination value (in lux)
  5. Presnece record.
  6. Illumination record.

@joohann
Copy link

joohann commented Sep 15, 2023

IMG_8185
and
IMG_8186

Some inside details 😉

@makeitworktech
Copy link

Some inside details 😉

Wow, so many of these devices have that same sensor inside! I'm testing a bunch of these and I'm finding that! Hopefully we can get this one working with Z2M as well!

PXL_20230915_113536308.jpg

@alexvaltchev
Copy link

Anything new on the subject? How can we use this mmwave sensor with Zigbee2MQTT?

@makeitworktech
Copy link

makeitworktech commented Sep 19, 2023

Still not able to figure out these messages:
Debug 2023-09-18 19:56:17No converter available for 'ZG-205ZL' with cluster 'manuSpecificTuya_2' and type 'attributeReport' and data '{"57354":287}' Debug 2023-09-18 19:56:19No converter available for 'ZG-205ZL' with cluster 'manuSpecificTuya_2' and type 'attributeReport' and data '{"57354":121}'

I've tried adding fzLocal and tzLocal to the converter file to help describe the messages, which I believe is a target distance. Here's my converter:

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 legacy = require('zigbee-herdsman-converters/lib/legacy');
const extend = require('zigbee-herdsman-converters/lib/extend');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const e = exposes.presets;
const ea = exposes.access;
const {KeyValue, Definition, Tz, Fz, Expose, KeyValueAny, KeyValueNumberString, KeyValueString} = require('zigbee-herdsman-converters/lib/types');

const fzLocal = {
    target_distance: {
        cluster: 'manuSpecificTuya_2',
        type: ['attributeReport', 'readResponse'],
        convert: (model, msg, publish, options, meta) => {
            const result: KeyValue = {};
            if (msg.data.hasOwnProperty('57354')) {
                result.target_distance = msg.data['57354'];
            }
            return result;
        },
    } as Fz.Converter,
};


const tzLocal = {
    target_distance: {
        key: ['target_distance'],
        convertSet: async (entity, key, value, meta) => {
            switch (key) {
            case 'target_distance': {
                utils.assertString(value, 'target_distance');
                await entity.write('manuSpecificTuya_2', {'57354': {value});
                break;
            }
            default: // Unknown key
                meta.logger.warn(`Unhandled key ${key}`);
            }
        },
    } as Tz.Converter,
    
    
const definition = {
    fingerprint: tuya.fingerprint('TS0225', ['_TZ3218_awarhusb']),
    model: 'TS0225',
    vendor: 'TuYa',
    description: 'Presence sensor',
    fromZigbee: [fz.ias_occupancy_alarm_1, fz.illuminance, fzLocal.target_distance],
    toZigbee: [tzLocal.target_distance],
    configure: tuya.configureMagicPacket,
    exposes: [e.occupancy(), e.illuminance_lux(), e.target_distance()],
    // configure: async (device, coordinatorEndpoint, logger) => {
    //     const endpoint = device.getEndpoint(1);
    //     await reporting.bind(endpoint, coordinatorEndpoint, ['msIlluminanceMeasurement']);
    //     await reporting.illuminance(endpoint);
    // },
};

module.exports = definition;

But I'm getting an error:
[19:58:41] INFO: Preparing to start... [19:58:42] INFO: Socat not enabled [19:58:43] INFO: Starting Zigbee2MQTT... /app/data/extension/externally-loaded.js:20 const result: KeyValue = {}; ^^^^^^ SyntaxError: Missing initializer in const declaration at new Script (node:vm:100:7) at createScript (node:vm:265:10) at Object.runInNewContext (node:vm:306:10) at loadModuleFromText (/app/lib/util/utils.ts:152:8) at loadModuleFromFile (/app/lib/util/utils.ts:159:12) at Object.getExternalConvertersDefinitions (/app/lib/util/utils.ts:169:25) at getExternalConvertersDefinitions.next (<anonymous>) at new ExternalConverters (/app/lib/extension/externalConverters.ts:12:20) at new Controller (/app/lib/controller.ts:84:58) at start (/app/index.js:106:18)

I just don't know enough about this stuff to do much more. Any help would be appreciated.

@makeitworktech
Copy link

Ok, I'm getting somewhere! I have the target distance working (sort of).

image

Here's my latest converter.

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 legacy = require('zigbee-herdsman-converters/lib/legacy');
const extend = require('zigbee-herdsman-converters/lib/extend');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const e = exposes.presets;
const ea = exposes.access;
const {KeyValue, Definition, Tz, Fz, Expose, KeyValueAny, KeyValueNumberString, KeyValueString} = require('zigbee-herdsman-converters/lib/types');

const fzLocal = {
    target_distance: {
        cluster: 'manuSpecificTuya_2',
        type: ['attributeReport'],
        // type: ['attributeReport', 'readResponse'],
        convert: (model, msg, publish, options, meta) => {
            const result = {};
            if (msg.data.hasOwnProperty('57354')) {
                result['target_distance'] = msg.data['57354'];
            }
            // if (msg.data.hasOwnProperty('57345')) {
            //     result['target_distance'] = msg.data['57345'];
            // }
            return result;
        },
    },
};


const tzLocal = {
    target_distance: {
        key: ['target_distance'],
        convertSet: async (entity, key, value, meta) => {
            switch (key) {
            case 'target_distance': {
                utils.assertString(value, 'target_distance');
                await entity.write('manuSpecificTuya_2', {'57354': {value}});
                break;
            }
            default: // Unknown key
                meta.logger.warn(`Unhandled key ${key}`);
            }
        },
    },
};    
    
const definition = {
    fingerprint: tuya.fingerprint('TS0225', ['_TZ3218_awarhusb']),
    model: 'TS0225',
    vendor: 'TuYa',
    description: 'Presence sensor',
    // fromZigbee: [fz.ias_occupancy_alarm_1, fz.illuminance, fzLocal.target_distance],
    fromZigbee: [fz.ias_occupancy_alarm_1, fz.illuminance, fzLocal.target_distance],
    toZigbee: [tzLocal.target_distance, tzLocal.target_distance],
    configure: tuya.configureMagicPacket,
    exposes: [e.occupancy(),
                e.illuminance_lux(),
                e.numeric('target_distance', ea.STATE).withDescription('Distance to target').withUnit('cm'),
                e.numeric('radar_sensitivity',ea.STATE_SET).withValueMin(1).withValueMax(5).withValueStep(1)
                    .withDescription('sensitivity of the radar')],
                
    // configure: async (device, coordinatorEndpoint, logger) => {
    //     const endpoint = device.getEndpoint(1);
    //     await reporting.bind(endpoint, coordinatorEndpoint, ['msIlluminanceMeasurement']);
    //     await reporting.illuminance(endpoint);
    // },
};

module.exports = definition;

My biggest issue right now is figuring out the difference between these two messages:

Debug 2023-09-06 17:32:52No converter available for 'TS0225' with cluster 'manuSpecificTuya_2' and type 'attributeReport' and data '{"57345":3180}'

Debug 2023-09-06 17:32:54No converter available for 'TS0225' with cluster 'manuSpecificTuya_2' and type 'attributeReport' and data '{"57354":221}'

@makeitworktech
Copy link

makeitworktech commented Sep 19, 2023

It uses the standard ZCL cluster 0x0400 for illuminance reporting and the IAS cluster 0x0500 for occupancy reporting. It also uses a manufacturer-specific cluster 0xE002 for the configurable parameters and for reporting.

So this comment has prompted me to read up on ZCL clusters. I'm literally over my head here, but it looks like the standard Illuminance Measurement cluster (0x0400) has only 5 attributes, while the one reported here seems to have 10:

Debug 2023-09-19 06:22:36No converter available for 'TS0225' with cluster 'msIlluminanceMeasurement' and type 'raw' and data '{"data":[8,59,10,0,0,33,134,23,0,0],"type":"Buffer"}'

Does this indicate that the cluster is non-standard, so we kinda have to guess at what the attributes are?
If we number the attribute positions in the array like this: [1,2,3,4,5,6,7,8,9,10], then positions 1,3,4,5,6,9,10 don't seem to change when I change the light level.

Soon @blakadder may have some input :-D

@kkossev
Copy link

kkossev commented Sep 27, 2024

Sorry @marazmarci , I have already updated my Linptech ES1 (MOES) device using a Tuya GW.

@marazmarci
Copy link

@kkossev true, sad thing, but thx anyways!

@makeitworktech
Copy link

makeitworktech commented Sep 30, 2024 via email

@felafel
Copy link

felafel commented Oct 1, 2024

Firmware updates from TUYA would be great. I would love to have the LED light accessible from Z2M. Buying a gateway just to turn it off seems wasteful.

@ryangu
Copy link

ryangu commented Oct 13, 2024

If the Linptech/Moes TS0225 _TZ3218_awarhusb firmware is upgraded using a Tuya GW to version 1.0.6 (0x46), then the blinking LED can be controlled from cluster 0xE002 attribute 0xE009, (data type 0x10) 0=disable, 1=enable LED.
@kkossev
`
tzLocal:
case 'motion_indicator': {
utils.assertNumber(value, 'motion_indicator');
await entity.write('manuSpecificTuya_2', {57353: {value, type: 0x10}});
break;
}

fzLocal:
if (msg.data.hasOwnProperty('57353')) {
result['motion_indicator'] = msg.data['57353'];
}

e.numeric('motion_indicator', ea.STATE_SET)
.withValueMin(0)
.withValueMax(1)
.withValueStep(1)
.withDescription('LED Indicator'),`

this is my setting for the led indicator light , but it return No converter available for 'motion_indicator' (0)
please help me.

@ryangu
Copy link

ryangu commented Oct 14, 2024

I have everything working now except "Leave time"! image

Setting up illuminance is pretty janky, but here was my method. I'm ignoring all of the values in the illuminance buffer object except for position 7. For reference, here are the position numbers: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]. In position 7 there is a number that increases with more light, and decreases with less light. I used a handheld lux meter shown below to record actual lux measurements vs the number that shows up in position 7. image https://www.amazon.com/gp/product/B075DC6X25/

I plotted the corresponding values, and got an exponential curve shown below. I used that equation to convert the values in position 7 to "actual Lux values. image

Anyway, here's my converter so far. If I shouldn't keep posting every time I make progress, let me know and I'll reduce how often I post updates.

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 legacy = require('zigbee-herdsman-converters/lib/legacy');
const extend = require('zigbee-herdsman-converters/lib/extend');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const e = exposes.presets;
const ea = exposes.access;
const {KeyValue, Definition, Tz, Fz, Expose, KeyValueAny, KeyValueNumberString, KeyValueString} = require('zigbee-herdsman-converters/lib/types');

const fzLocal = {
    illuminance: {
        cluster: 'msIlluminanceMeasurement',
        type: 'raw',
        convert: (model, msg, publish, options, meta) => {
            const result = {};
            const buffer = msg.data;
            result['illuminance'] = Math.round(0.0001 * Math.pow(Number(buffer[7]), 3.413));
            return result;
        },
    },
// below is good
    target_distance: {
        cluster: 'manuSpecificTuya_2',
        type: ['attributeReport'],
        convert: (model, msg, publish, options, meta) => {
            const result = {};
            if (msg.data.hasOwnProperty('57354')) {
                result['target_distance'] = msg.data['57354'];
            }
            return result;
        },
    },
    motion_detection_distance: {
        cluster: 'manuSpecificTuya_2',
        type: ['attributeReport'],
        convert: (model, msg, publish, options, meta) => {
            const result = {};
            if (msg.data.hasOwnProperty('57355')) {
                result['motion_detection_distance'] = msg.data['57355'];
            }
            return result;
        },
    },
    motion_detection_sensitivity: {
        cluster: 'manuSpecificTuya_2',
        type: ['attributeReport'],
        convert: (model, msg, publish, options, meta) => {
            const result = {};
            if (msg.data.hasOwnProperty('57348')) {
                result['motion_detection_sensitivity'] = msg.data['57348'];
            }
            return result;
        },
    },
    static_detection_sensitivity: {
        cluster: 'manuSpecificTuya_2',
        type: ['attributeReport'],
        convert: (model, msg, publish, options, meta) => {
            const result = {};
            if (msg.data.hasOwnProperty('57349')) {
                result['static_detection_sensitivity'] = msg.data['57349'];
            }
            return result;
        },
    },
    // Presence Keep Time: Updates every 40 seconds
    presence_keep_time: {
        cluster: 'manuSpecificTuya_2',
        type: ['attributeReport'],
        convert: (model, msg, publish, options, meta) => {
            const result = {};
            if (msg.data.hasOwnProperty('57345')) {
                result['presence_keep_time'] = msg.data['57345'];
            }
            return result;
        },
    },
};


const tzLocal = {
    motion_detection_distance: {
        key: ['motion_detection_distance'],
        convertSet: async (entity, key, value, meta) => {
            let newDist = null;
            switch (key) {
            case 'motion_detection_distance': {
                utils.assertNumber(value, 'motion_detection_distance');
                await entity.write('manuSpecificTuya_2', {57355: {value, type: 0x21}});
                break;
            }
            default: // Unknown key
                meta.logger.warn(`Unhandled key ${key}`);
            }
        },
    },
    motion_detection_sensitivity: {
        key: ['motion_detection_sensitivity'],
        convertSet: async (entity, key, value, meta) => {
            switch (key) {
            case 'motion_detection_sensitivity': {
                utils.assertNumber(value, 'motion_detection_sensitivity');
                await entity.write('manuSpecificTuya_2', {57348: {value, type: 0x20}});
                break;
            }
            default: // Unknown key
                meta.logger.warn(`Unhandled key ${key}`);
            }
        },
    },
    static_detection_sensitivity: {
        key: ['static_detection_sensitivity'],
        convertSet: async (entity, key, value, meta) => {
            switch (key) {
            case 'static_detection_sensitivity': {
                utils.assertNumber(value, 'static_detection_sensitivity');
                await entity.write('manuSpecificTuya_2', {57349: {value, type: 0x20}});
                break;
            }
            default: // Unknown key
                meta.logger.warn(`Unhandled key ${key}`);
            }
        },
    },
};    
    
const definition = {
    fingerprint: tuya.fingerprint('TS0225', ['_TZ3218_awarhusb']),
    model: 'TS0225',
    vendor: 'TuYa',
    description: 'Presence sensor',
    fromZigbee: [fz.ias_occupancy_alarm_1, fzLocal.target_distance,fzLocal.motion_detection_distance,fzLocal.motion_detection_sensitivity,fzLocal.static_detection_sensitivity,fzLocal.illuminance,fzLocal.presence_keep_time],
    toZigbee: [tzLocal.motion_detection_distance,tzLocal.motion_detection_sensitivity,tzLocal.static_detection_sensitivity],
    configure: tuya.configureMagicPacket,
    exposes: [
        e.occupancy().withDescription('Presence state'),
        e.numeric('illuminance', ea.STATE).withDescription('Illuminance in lux').withUnit('lx'),
        e.numeric('target_distance', ea.STATE).withDescription('Distance to target').withUnit('cm'),
        e.numeric('motion_detection_distance',ea.STATE_SET).withValueMin(75).withValueMax(600).withValueStep(75).withDescription('Motion detection distance').withUnit('cm'),
        e.numeric('presence_keep_time',ea.STATE).withDescription('Presence keep time').withUnit('s'), 
        e.numeric('motion_detection_sensitivity', ea.STATE_SET).withValueMin(0).withValueMax(5).withValueStep(1).withDescription('Motion detection sensitivity'),
        e.numeric('static_detection_sensitivity', ea.STATE_SET).withValueMin(0).withValueMax(5).withValueStep(1).withDescription('Static detection sensitivity'),
        e.numeric('leave_time', ea.STATE).withValueMin(0).withValueMax(9999).withValueStep(1).withUnit('min').withDescription('Shows the duration of the absence in minutes')

    ],
                
    meta: {
        tuyaDatapoints: [
            [1, 'presence', tuya.valueConverter.trueFalse1],
            [4, 'motion_detection_distance', tuya.valueConverter.raw],
            [12, 'keep_time', tuya.valueConverter.raw],
            [15, 'motion_detection_sensitivity', tuya.valueConverter.raw],
            [16, 'static_detection_sensitivity', tuya.valueConverter.raw],
            [19, 'target_distance', tuya.valueConverter.raw],
            [20, 'localilluminance', tuya.valueConverter.raw],
            [101, 'leave_time', tuya.valueConverter.raw],
        ],
    },
};

module.exports = definition;

I've figured the calculation of Lux !!!!!!!!!

const measuredValue = Number(buffer[7]) * 256 + Number(buffer[6]);
return {illuminance: measuredValue === 0 ? 0 : Math.pow(10, (measuredValue - 1) / 10000)};

i think it fits perfect, though i don't use a lux meter to compare the numbers, but i've confirmed the formula through the max buffer value i got with [8,19,10,0,0,33,65,156,0,0], 156 * 256 + 65 - 1 = 40000, which is exactly the same max Lux number 10000 lx as the product introduces. Also i noticed that the calculation is same as in fromZigbee.ts.

@Koenkk @makeitworktech @kkossev

@makeitworktech
Copy link

Awesome!!

@felafel
Copy link

felafel commented Oct 14, 2024

If the Linptech/Moes TS0225 _TZ3218_awarhusb firmware is upgraded using a Tuya GW to version 1.0.6 (0x46),

Does anyone have a way to update the firmware without getting a Tuya hub?

@Koenkk
Copy link
Owner

Koenkk commented Oct 15, 2024

@ryangu great, could you make a PR to update the code?

@felafel
Copy link

felafel commented Oct 25, 2024

Well .......... I bought the hub for about US$10 on aliexpress. I tried to use the old app according to the docs but this device is too new to view it for some reason. I upgraded the linptech presence sensor using my phone and latest app. V1.0.5 to V1.0.6. I turned off the stupid blinking light and then removed it from the app and put it back in HA. I will try with wireshark to see if I can figure out the OTA link but I only have one more device to try it on. It would be helpful if HA and/or Z2M folks could get the links from Tuya.

@nyok92
Copy link

nyok92 commented Oct 26, 2024

Hi @felafel ,
Could you try with the following guide ?
z2mqtt Tuya ota url

@felafel
Copy link

felafel commented Oct 30, 2024

Hi @felafel , Could you try with the following guide ? z2mqtt Tuya ota url

That was the document I referred to in my info; "I tried to use the old app according to the docs". BTW, the link to the APK is not working so I did find that version on another APK mirror. I only have one more device to try this on so I need to figure out how I can capture the URLs the app will try to use. Maybe if I can get a log from my internet router? I am a dev so this network traffic stuff is not my thing. I have wireshark but I think it won't hit my computer's NIC so that probably is not worth it. I will try some stuff.

@ryangu
Copy link

ryangu commented Oct 30, 2024

@ryangu great, could you make a PR to update the code?

done. also add the led indicator attribute

@eremem
Copy link

eremem commented Nov 4, 2024

@ryangu Could it be possible to bring the previous illuminance value back, e.g. as an additional "raw" sensor reading?
This new logic seems to introduce less resolution, at least when it's darker and/or when the light is indirect.
I'm using the sensor to control auxiliary lighting for my desk, which stands next to and also with its back to the window, so the sensor is indirectly lit. I was able to define a well working automation based on these previous "raw" illumination values, whereas now it's not possible anymore. I tried to adjust the threshold values for the automation's triggers but the new values simply doesn't reflect the smaller illuminance changes. They seem also to change less frequently than before.
My light conditions before and after the code change are (subjectively of course) comparable, so this doesn't seem to play any essential role in my case.

@ryangu
Copy link

ryangu commented Nov 4, 2024

@eremem Well, nothing has changed but the value, you can do the reverse calculation to convert the old lux value to the new formula.

@RenzoBeux
Copy link

Please let us know if someone found a way of updating the firmware using Z2M instead of having to buy a Hub!

@felafel
Copy link

felafel commented Nov 18, 2024

Two things:

I have the Linptech version. I cannot change the distance or the sensitivity and make it save. Is there a reason we cannot change the values? Do I need to change them with the TUYA hub and then get the device back into z2m? It is annoying.

I am away from home until the end of the month. I will look into finding the URL when I get back.

@bobbergen
Copy link

I have the Linptech version. I cannot change the distance or the sensitivity and make it save.

Had the same issue on one of mine, had to re-pair it and works perfectly now.

@Phenix51
Copy link

Any update on the the Moes wwmave human presence sensor? Mine also shows as _TZ3218_awarhusb TS0225. What is the latest and best so far converter that exist? thanks

Screenshot_2

Were you ever able to get your Moes sensor working? I can't get mine to show anything other than Disabled in my system.

Copy link
Contributor

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days

@github-actions github-actions bot added the stale Stale issues label Jan 21, 2025
@Phenix51
Copy link

Any update on the the Moes wwmave human presence sensor? Mine also shows as _TZ3218_awarhusb TS0225. What is the latest and best so far converter that exist? thanks

@github-actions github-actions bot removed the stale Stale issues label Jan 23, 2025
@Popoff-fr
Copy link

led
hi !

For me ledindicator doesn't work. When i push true or false i have this message :

Image

does anyone else have this problem ?

@kineticscreen
Copy link

Have you updated to the latest firmware via connecting to a Tuya hub / app?

@Popoff-fr
Copy link

Have you updated to the latest firmware via connecting to a Tuya hub / app?

No, it's stupid but I didn't think about it.😅

@YanisKyr
Copy link

Anyone managed to update the Firmware using the Sonoff Zigbee 3.0?

@felafel
Copy link

felafel commented Feb 23, 2025

We need the update link I think. I have the hub and tried to get the firmware using the steps mentioned above. Due to this device being after the version of the Tuya app those steps did not work. We just need to figure out a way to see the link the hub is using. One thing I find very weird is that I think I read where Z2M or ZHA devs have been in contact with Tuya devs about devices but we do not have a structured way to get the endpoints for the devices. Very annoying.

@bapesupreme
Copy link

Is it possible to change the distance measurement to meters?

Is there a reason distance is reported in cm?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new device support New device support request
Projects
None yet
Development

No branches or pull requests