zigbee-herdsman-converters 26.120.0 → 26.121.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/dist/devices/tuya.d.ts.map +1 -1
- package/dist/devices/tuya.js +85 -9
- package/dist/devices/tuya.js.map +1 -1
- package/dist/devices/visonic.d.ts.map +1 -1
- package/dist/devices/visonic.js +2 -0
- package/dist/devices/visonic.js.map +1 -1
- package/dist/lib/tuya.d.ts +13 -0
- package/dist/lib/tuya.d.ts.map +1 -1
- package/dist/lib/tuya.js +21 -0
- package/dist/lib/tuya.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [26.121.0](https://github.com/Koenkk/zigbee-herdsman-converters/compare/v26.120.0...v26.121.0) (2026-10-18)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* Tuya MTG235-ZB-RL: expose `distance_report` ([#13520](https://github.com/Koenkk/zigbee-herdsman-converters/issues/13520)) ([28c54f7](https://github.com/Koenkk/zigbee-herdsman-converters/commit/28c54f7e58c8bca909dbf5df5ab3131e0ffe7c38))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **ignore:** bump @types/node from 26.6.4 to 26.6.5 in the minor-patch group ([#13523](https://github.com/Koenkk/zigbee-herdsman-converters/issues/13523)) ([623d6df](https://github.com/Koenkk/zigbee-herdsman-converters/commit/623d6df277884dfe4c2c3c8417db52fd512445c4))
|
|
14
|
+
* Tuya ME201WZ: ignore false and out-of-range level readings ([#13504](https://github.com/Koenkk/zigbee-herdsman-converters/issues/13504)) ([62086f6](https://github.com/Koenkk/zigbee-herdsman-converters/commit/62086f63283f4c23d36188e607befc5471e187d6))
|
|
15
|
+
* Tuya ZS-304Z: support negative humidity and temperature calibration ([#13524](https://github.com/Koenkk/zigbee-herdsman-converters/issues/13524)) ([2d506ca](https://github.com/Koenkk/zigbee-herdsman-converters/commit/2d506caf7c71e33d8fbb5d2c244f1b0a31aa2cf3))
|
|
16
|
+
* Visonic MCT-350 SMA: prevent rapid polling after a battery swap ([#13518](https://github.com/Koenkk/zigbee-herdsman-converters/issues/13518)) ([84a2ab4](https://github.com/Koenkk/zigbee-herdsman-converters/commit/84a2ab479b2859d7823ce28d722f54c9ebb54275))
|
|
17
|
+
|
|
3
18
|
## [26.120.0](https://github.com/Koenkk/zigbee-herdsman-converters/compare/v26.119.0...v26.120.0) (2026-10-16)
|
|
4
19
|
|
|
5
20
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tuya.d.ts","sourceRoot":"","sources":["../../src/devices/tuya.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAC,oBAAoB,EAAkD,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"tuya.d.ts","sourceRoot":"","sources":["../../src/devices/tuya.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAC,oBAAoB,EAAkD,MAAM,cAAc,CAAC;AAs0ExG,eAAO,MAAM,WAAW,EAAE,oBAAoB,EA4q3B7C,CAAC"}
|
package/dist/devices/tuya.js
CHANGED
|
@@ -2197,6 +2197,81 @@ const sp107eLedChips = {
|
|
|
2197
2197
|
TM1814: tuya.enum(8),
|
|
2198
2198
|
SK6812: tuya.enum(9),
|
|
2199
2199
|
};
|
|
2200
|
+
// The ME201WZ regularly picks up false echoes (e.g. -1.1 m, 5 m, 0.24 m), sometimes for hours. A real level changes
|
|
2201
|
+
// gradually, so drop readings outside the tank or jumping > 5 cm, unless the new level has been read steadily for 12 hours.
|
|
2202
|
+
const me201wzFilterGlitches = (result, state, device) => {
|
|
2203
|
+
const depth = result.liquid_depth;
|
|
2204
|
+
const percent = result.liquid_level_percent;
|
|
2205
|
+
const lastDepth = state.liquid_depth;
|
|
2206
|
+
const height = (result.installation_height ?? state.installation_height);
|
|
2207
|
+
const depthMax = (result.liquid_depth_max ?? state.liquid_depth_max);
|
|
2208
|
+
let glitch = false;
|
|
2209
|
+
if (depth !== undefined) {
|
|
2210
|
+
if (depth < 0 || (height !== undefined && depth > height)) {
|
|
2211
|
+
glitch = true;
|
|
2212
|
+
}
|
|
2213
|
+
else if (lastDepth !== undefined && Math.abs(depth - lastDepth) > 0.05) {
|
|
2214
|
+
const candidate = globalStore.getValue(device, "me201wzCandidate");
|
|
2215
|
+
if (candidate && Math.abs(depth - candidate.depth) <= 0.03) {
|
|
2216
|
+
glitch = Date.now() - candidate.since < 12 * 60 * 60 * 1000;
|
|
2217
|
+
}
|
|
2218
|
+
else {
|
|
2219
|
+
globalStore.putValue(device, "me201wzCandidate", { depth, since: Date.now() });
|
|
2220
|
+
glitch = true;
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2223
|
+
if (!glitch)
|
|
2224
|
+
globalStore.clearValue(device, "me201wzCandidate");
|
|
2225
|
+
}
|
|
2226
|
+
else if (percent !== undefined && lastDepth !== undefined && depthMax) {
|
|
2227
|
+
glitch = Math.abs(percent - Math.min(100, (lastDepth / depthMax) * 100)) > 5 / depthMax;
|
|
2228
|
+
}
|
|
2229
|
+
if (glitch) {
|
|
2230
|
+
delete result.liquid_depth;
|
|
2231
|
+
delete result.liquid_level_percent;
|
|
2232
|
+
delete result.liquid_state;
|
|
2233
|
+
return result;
|
|
2234
|
+
}
|
|
2235
|
+
// Hold back a liquid state that doesn't match the level, publish it once an accepted level matches it.
|
|
2236
|
+
const minSet = (result.min_set ?? state.min_set);
|
|
2237
|
+
const maxSet = (result.max_set ?? state.max_set);
|
|
2238
|
+
const level = (percent ?? state.liquid_level_percent);
|
|
2239
|
+
if (minSet === undefined || maxSet === undefined || level === undefined)
|
|
2240
|
+
return result;
|
|
2241
|
+
const matches = (s) => (s === "low" && level <= minSet + 1) ||
|
|
2242
|
+
(s === "high" && level >= maxSet - 1) ||
|
|
2243
|
+
(s === "normal" && level >= minSet - 1 && level <= maxSet + 1);
|
|
2244
|
+
if (result.liquid_state !== undefined && !matches(result.liquid_state)) {
|
|
2245
|
+
globalStore.putValue(device, "me201wzPendingState", result.liquid_state);
|
|
2246
|
+
delete result.liquid_state;
|
|
2247
|
+
}
|
|
2248
|
+
else if (result.liquid_state === undefined && percent !== undefined) {
|
|
2249
|
+
const pending = globalStore.getValue(device, "me201wzPendingState");
|
|
2250
|
+
if (pending !== undefined && pending !== state.liquid_state && matches(pending))
|
|
2251
|
+
result.liquid_state = pending;
|
|
2252
|
+
}
|
|
2253
|
+
if (result.liquid_state !== undefined)
|
|
2254
|
+
globalStore.clearValue(device, "me201wzPendingState");
|
|
2255
|
+
return result;
|
|
2256
|
+
};
|
|
2257
|
+
// Shared by the liquid state, depth and percent datapoints, which are filtered together once per message.
|
|
2258
|
+
const me201wzFiltered = new WeakMap();
|
|
2259
|
+
const me201wzLevel = {
|
|
2260
|
+
from: (v, meta, options, publish, msg) => {
|
|
2261
|
+
if (!me201wzFiltered.has(msg)) {
|
|
2262
|
+
const dp = Object.fromEntries(msg.data.dpValues.map((d) => [d.dp, tuya.getDataValue(d)]));
|
|
2263
|
+
const result = {};
|
|
2264
|
+
if (dp[1] !== undefined)
|
|
2265
|
+
result.liquid_state = tvc.level.from(dp[1], meta, options);
|
|
2266
|
+
if (dp[2] !== undefined)
|
|
2267
|
+
result.liquid_depth = dp[2] / 100;
|
|
2268
|
+
if (dp[22] !== undefined)
|
|
2269
|
+
result.liquid_level_percent = dp[22];
|
|
2270
|
+
me201wzFiltered.set(msg, me201wzFilterGlitches(result, meta.state, meta.device));
|
|
2271
|
+
}
|
|
2272
|
+
return me201wzFiltered.get(msg);
|
|
2273
|
+
},
|
|
2274
|
+
};
|
|
2200
2275
|
exports.definitions = [
|
|
2201
2276
|
{
|
|
2202
2277
|
fingerprint: tuya.fingerprint("TS0601", ["_TZE284_5qfrnbqs"]),
|
|
@@ -19903,12 +19978,13 @@ exports.definitions = [
|
|
|
19903
19978
|
"it will continue to maintain presence regardless of whether someone is present or not. If set to unoccupied, the unoccupied " +
|
|
19904
19979
|
"state will be maintained permanently."),
|
|
19905
19980
|
];
|
|
19906
|
-
if (!device || device.manufacturerName
|
|
19907
|
-
// MTG275-ZB-RL: DP 116 switches the continuous target_distance reports (about 1/s) on/off.
|
|
19908
|
-
// Requires MCU firmware 1.0.5 or newer.
|
|
19981
|
+
if (!device || ["_TZE204_dtzziy1e", "_TZE204_clrdrnya"].includes(device.manufacturerName)) {
|
|
19982
|
+
// MTG275-ZB-RL / MTG235-ZB-RL: DP 116 switches the continuous target_distance reports (about 1/s) on/off.
|
|
19983
|
+
// Requires MCU firmware 1.0.5 (MTG275-ZB-RL) or 1.0.4 (MTG235-ZB-RL) or newer.
|
|
19909
19984
|
exps.push(e
|
|
19910
19985
|
.binary("distance_report", ea.STATE_SET, "ON", "OFF")
|
|
19911
|
-
.withDescription("Report target distance continuously (about once per second), requires MCU firmware 1.0.5
|
|
19986
|
+
.withDescription("Report target distance continuously (about once per second), requires MCU firmware 1.0.5 (MTG275-ZB-RL) " +
|
|
19987
|
+
"or 1.0.4 (MTG235-ZB-RL) or newer"));
|
|
19912
19988
|
}
|
|
19913
19989
|
return exps;
|
|
19914
19990
|
},
|
|
@@ -23091,14 +23167,14 @@ exports.definitions = [
|
|
|
23091
23167
|
],
|
|
23092
23168
|
meta: {
|
|
23093
23169
|
tuyaDatapoints: [
|
|
23094
|
-
[1,
|
|
23095
|
-
[2,
|
|
23170
|
+
[1, null, me201wzLevel],
|
|
23171
|
+
[2, null, me201wzLevel],
|
|
23096
23172
|
[5, "voltage", tvc.divideBy10], // power_level
|
|
23097
23173
|
[7, "max_set", tvc.raw],
|
|
23098
23174
|
[8, "min_set", tvc.raw],
|
|
23099
23175
|
[19, "installation_height", tvc.divideBy100],
|
|
23100
23176
|
[21, "liquid_depth_max", tvc.divideBy100],
|
|
23101
|
-
[22,
|
|
23177
|
+
[22, null, me201wzLevel],
|
|
23102
23178
|
[24, "relay_switch", tvc.onOff],
|
|
23103
23179
|
[101, "pump_mode", tvc.pumpMode],
|
|
23104
23180
|
[102, "pump_control", tvc.pumpControl], // auto_pump_control
|
|
@@ -25799,9 +25875,9 @@ exports.definitions = [
|
|
|
25799
25875
|
[102, "illuminance", tuya.valueConverter.multiplyBy10],
|
|
25800
25876
|
[103, "soil_sampling", tuya.valueConverter.raw],
|
|
25801
25877
|
[104, "soil_calibration", tuya.valueConverter.raw],
|
|
25802
|
-
[105, "humidity_calibration", tuya.valueConverter.
|
|
25878
|
+
[105, "humidity_calibration", tuya.valueConverter.twosComplement8Bit],
|
|
25803
25879
|
[106, "illuminance_calibration", tuya.valueConverter.raw],
|
|
25804
|
-
[107, "temperature_calibration", tuya.valueConverter.
|
|
25880
|
+
[107, "temperature_calibration", tuya.valueConverter.twosComplement8BitScaled10x],
|
|
25805
25881
|
// DP 110 is asymmetric: device reports the warning state, but setting it configures the threshold.
|
|
25806
25882
|
// First entry is used for incoming reports, the second one for setting.
|
|
25807
25883
|
[110, "soil_moisture_warning", { from: tuya.valueConverter.raw.from }],
|