zigbee-herdsman-converters 14.0.465 → 14.0.466
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/converters/fromZigbee.js +26 -15
- package/converters/toZigbee.js +19 -5
- package/devices/lidl.js +11 -0
- package/devices/tuya.js +10 -6
- package/lib/exposes.js +6 -0
- package/lib/tuya.js +63 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/converters/fromZigbee.js
CHANGED
|
@@ -4580,10 +4580,33 @@ const converters = {
|
|
|
4580
4580
|
} else if (meta.device.manufacturerName === '_TZE200_swaamsoy') {
|
|
4581
4581
|
// https://github.com/Koenkk/zigbee-herdsman-converters/pull/3004
|
|
4582
4582
|
if (dpValue.dp === 2) {
|
|
4583
|
+
if (value < 10) {
|
|
4584
|
+
tuya.logUnexpectedDataValue('tuya_dimmer', msg, dpValue, meta, 'brightness', 10, 1000);
|
|
4585
|
+
}
|
|
4583
4586
|
return {brightness: mapNumberRange(value, 10, 1000, 0, 254)};
|
|
4584
4587
|
}
|
|
4585
|
-
} else
|
|
4586
|
-
|
|
4588
|
+
} else if (meta.device.manufacturerName === '_TZE200_3p5ydos3') {
|
|
4589
|
+
if (dpValue.dp === tuya.dataPoints.eardaDimmerLevel) {
|
|
4590
|
+
return {brightness: mapNumberRange(value, 0, 1000, 0, 254)};
|
|
4591
|
+
} else if (dpValue.dp === tuya.dataPoints.dimmerMinLevel) {
|
|
4592
|
+
return {min_brightness: mapNumberRange(value, 0, 1000, 1, 255)};
|
|
4593
|
+
} else if (dpValue.dp === tuya.dataPoints.dimmerMaxLevel) {
|
|
4594
|
+
return {max_brightness: mapNumberRange(value, 0, 1000, 1, 255)};
|
|
4595
|
+
} else {
|
|
4596
|
+
tuya.logUnexpectedDataPoint('tuya_dimmer', msg, dpValue, meta);
|
|
4597
|
+
}
|
|
4598
|
+
} else {
|
|
4599
|
+
if (dpValue.dp !== tuya.dataPoints.dimmerLevel) {
|
|
4600
|
+
tuya.logUnexpectedDataPoint('tuya_dimmer', msg, dpValue, meta);
|
|
4601
|
+
}
|
|
4602
|
+
if (dpValue.datatype !== tuya.dataTypes.value) {
|
|
4603
|
+
tuya.logUnexpectedDataType('tuya_dimmer', msg, dpValue, meta);
|
|
4604
|
+
} else {
|
|
4605
|
+
if (value < 10) {
|
|
4606
|
+
tuya.logUnexpectedDataValue('tuya_dimmer', msg, dpValue, meta, 'brightness', 10, 1000);
|
|
4607
|
+
}
|
|
4608
|
+
return {brightness: mapNumberRange(value, 10, 1000, 0, 254), level: value};
|
|
4609
|
+
}
|
|
4587
4610
|
}
|
|
4588
4611
|
},
|
|
4589
4612
|
},
|
|
@@ -4593,14 +4616,6 @@ const converters = {
|
|
|
4593
4616
|
convert: (model, msg, publis, options, meta) => {
|
|
4594
4617
|
// Don't use in production!
|
|
4595
4618
|
// Used in: https://www.zigbee2mqtt.io/how_tos/how_to_support_new_tuya_devices.html
|
|
4596
|
-
const getType = (datatype) => {
|
|
4597
|
-
const entry = Object.entries(tuya.dataTypes).find(([typeName, typeId]) => typeId === datatype);
|
|
4598
|
-
return (entry ? entry[0] : 'unknown');
|
|
4599
|
-
};
|
|
4600
|
-
const getAllDpIds = (dp) => {
|
|
4601
|
-
const entries = Object.entries(tuya.dataPoints).filter(([dpName, dpId]) => dpId === dp);
|
|
4602
|
-
return entries.map(([dpName, dpId]) => dpName);
|
|
4603
|
-
};
|
|
4604
4619
|
const getHex = (value) => {
|
|
4605
4620
|
let hex = value.toString(16);
|
|
4606
4621
|
if (hex.length < 2) {
|
|
@@ -4611,11 +4626,7 @@ const converters = {
|
|
|
4611
4626
|
const now = Date.now().toString();
|
|
4612
4627
|
let dataStr = '';
|
|
4613
4628
|
for (const [i, dpValue] of msg.data.dpValues.entries()) {
|
|
4614
|
-
|
|
4615
|
-
meta.logger.info(`zigbee-herdsman-converters:tuya_data_point_dump: Received DP #${
|
|
4616
|
-
dpValue.dp} from ${meta.device.ieeeAddr} with raw data '${JSON.stringify(dpValue)}': type='${msg.type}', datatype='${
|
|
4617
|
-
getType(dpValue.datatype)}', value='${value}', known DP# usage: ${JSON.stringify(getAllDpIds(dpValue.dp))}`);
|
|
4618
|
-
|
|
4629
|
+
tuya.logDataPoint('tuya_data_point_dump', msg, dpValue, meta);
|
|
4619
4630
|
dataStr +=
|
|
4620
4631
|
now + ' ' +
|
|
4621
4632
|
meta.device.ieeeAddr + ' ' +
|
package/converters/toZigbee.js
CHANGED
|
@@ -3516,7 +3516,7 @@ const converters = {
|
|
|
3516
3516
|
},
|
|
3517
3517
|
},
|
|
3518
3518
|
tuya_dimmer_level: {
|
|
3519
|
-
key: ['brightness_min', 'brightness', 'brightness_percent', 'level'],
|
|
3519
|
+
key: ['brightness_min', 'min_brightness', 'max_brightness', 'brightness', 'brightness_percent', 'level'],
|
|
3520
3520
|
convertSet: async (entity, key, value, meta) => {
|
|
3521
3521
|
// upscale to 1000
|
|
3522
3522
|
let newValue;
|
|
@@ -3531,6 +3531,20 @@ const converters = {
|
|
|
3531
3531
|
} else {
|
|
3532
3532
|
throw new Error('Dimmer brightness_min is out of range 0..100');
|
|
3533
3533
|
}
|
|
3534
|
+
} else if (key === 'min_brightness') {
|
|
3535
|
+
if (value >= 1 && value <= 255) {
|
|
3536
|
+
newValue = utils.mapNumberRange(value, 1, 255, 0, 1000);
|
|
3537
|
+
dp = tuya.dataPoints.dimmerMinLevel;
|
|
3538
|
+
} else {
|
|
3539
|
+
throw new Error('Dimmer min_brightness is out of range 1..255');
|
|
3540
|
+
}
|
|
3541
|
+
} else if (key === 'max_brightness') {
|
|
3542
|
+
if (value >= 1 && value <= 255) {
|
|
3543
|
+
newValue = utils.mapNumberRange(value, 1, 255, 0, 1000);
|
|
3544
|
+
dp = tuya.dataPoints.dimmerMaxLevel;
|
|
3545
|
+
} else {
|
|
3546
|
+
throw new Error('Dimmer min_brightness is out of range 1..255');
|
|
3547
|
+
}
|
|
3534
3548
|
} else if (key === 'level') {
|
|
3535
3549
|
if (value >= 0 && value <= 1000) {
|
|
3536
3550
|
newValue = Math.round(Number(value));
|
|
@@ -3543,11 +3557,11 @@ const converters = {
|
|
|
3543
3557
|
} else {
|
|
3544
3558
|
throw new Error('Dimmer brightness_percent is out of range 0..100');
|
|
3545
3559
|
}
|
|
3546
|
-
} else {
|
|
3547
|
-
if (value >= 0 && value <=
|
|
3548
|
-
newValue = utils.mapNumberRange(value, 0,
|
|
3560
|
+
} else { // brightness
|
|
3561
|
+
if (value >= 0 && value <= 254) {
|
|
3562
|
+
newValue = utils.mapNumberRange(value, 0, 254, 0, 1000);
|
|
3549
3563
|
} else {
|
|
3550
|
-
throw new Error('Dimmer brightness is out of range 0..
|
|
3564
|
+
throw new Error('Dimmer brightness is out of range 0..254');
|
|
3551
3565
|
}
|
|
3552
3566
|
}
|
|
3553
3567
|
// Always use same transid as tuya_dimmer_state (https://github.com/Koenkk/zigbee2mqtt/issues/6366)
|
package/devices/lidl.js
CHANGED
|
@@ -507,6 +507,17 @@ module.exports = [
|
|
|
507
507
|
device.getEndpoint(1).saveClusterAttributeKeyValue('lightingColorCtrl', {colorCapabilities: 29});
|
|
508
508
|
},
|
|
509
509
|
},
|
|
510
|
+
{
|
|
511
|
+
fingerprint: [{modelID: 'TS0505B', manufacturerName: '_TZ3210_z1vlyufu'}],
|
|
512
|
+
model: '14158704L',
|
|
513
|
+
vendor: 'Lidl',
|
|
514
|
+
description: 'Livarno Home LED floor lamp, RGBW',
|
|
515
|
+
...extend.light_onoff_brightness_colortemp_color({disableColorTempStartup: true, colorTempRange: [153, 500]}),
|
|
516
|
+
meta: {applyRedFix: true, enhancedHue: false},
|
|
517
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
518
|
+
device.getEndpoint(1).saveClusterAttributeKeyValue('lightingColorCtrl', {colorCapabilities: 29});
|
|
519
|
+
},
|
|
520
|
+
},
|
|
510
521
|
{
|
|
511
522
|
fingerprint: [{modelID: 'TS0505B', manufacturerName: '_TZ3000_quqaeew6'}],
|
|
512
523
|
model: 'HG07834A',
|
package/devices/tuya.js
CHANGED
|
@@ -450,7 +450,9 @@ module.exports = [
|
|
|
450
450
|
const endpoint = device.getEndpoint(1);
|
|
451
451
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
|
|
452
452
|
},
|
|
453
|
-
exposes: [e.light_brightness().
|
|
453
|
+
exposes: [e.light_brightness().withMinBrightness().withMaxBrightness().setAccess(
|
|
454
|
+
'state', ea.STATE_SET).setAccess('brightness', ea.STATE_SET).setAccess(
|
|
455
|
+
'min_brightness', ea.STATE_SET).setAccess('max_brightness', ea.STATE_SET)],
|
|
454
456
|
whiteLabel: [
|
|
455
457
|
{vendor: 'Larkkey', model: 'ZSTY-SM-1DMZG-EU'},
|
|
456
458
|
{vendor: 'Earda', model: 'EDM-1ZAA-EU'},
|
|
@@ -703,10 +705,7 @@ module.exports = [
|
|
|
703
705
|
extend: extend.light_onoff_brightness_colortemp_color(),
|
|
704
706
|
},
|
|
705
707
|
{
|
|
706
|
-
fingerprint: [
|
|
707
|
-
{type: 'EndDevice', manufacturerID: 4098, endpoints: [{ID: 1, inputClusters: [], outputClusters: []}]},
|
|
708
|
-
{manufacturerName: '_TZ2000_a476raq2'},
|
|
709
|
-
],
|
|
708
|
+
fingerprint: [{manufacturerName: '_TZ2000_a476raq2'}],
|
|
710
709
|
zigbeeModel: ['TS0201', 'SNTZ003'],
|
|
711
710
|
model: 'TS0201',
|
|
712
711
|
vendor: 'TuYa',
|
|
@@ -715,6 +714,10 @@ module.exports = [
|
|
|
715
714
|
fromZigbee: [fzLocal.TS0201_battery, fz.temperature, fz.humidity],
|
|
716
715
|
toZigbee: [],
|
|
717
716
|
exposes: [e.battery(), e.temperature(), e.humidity(), e.battery_voltage()],
|
|
717
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
718
|
+
const endpoint = device.getEndpoint(1);
|
|
719
|
+
await endpoint.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
|
|
720
|
+
},
|
|
718
721
|
},
|
|
719
722
|
{
|
|
720
723
|
fingerprint: [{modelID: 'TS0201', manufacturerName: '_TZ3000_bguser20'}],
|
|
@@ -2176,7 +2179,8 @@ module.exports = [
|
|
|
2176
2179
|
exposes: [e.illuminance_lux(), e.brightness_state()],
|
|
2177
2180
|
},
|
|
2178
2181
|
{
|
|
2179
|
-
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_kltffuzl'}, {modelID: 'TS0601', manufacturerName: '_TZE200_fwoorn8y'}
|
|
2182
|
+
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_kltffuzl'}, {modelID: 'TS0601', manufacturerName: '_TZE200_fwoorn8y'},
|
|
2183
|
+
{modelID: 'TS0601', manufacturerName: '_TZE200_pay2byax'}],
|
|
2180
2184
|
model: 'TM001-ZA/TM081',
|
|
2181
2185
|
vendor: 'TuYa',
|
|
2182
2186
|
description: 'Door and window sensor',
|
package/lib/exposes.js
CHANGED
|
@@ -218,6 +218,12 @@ class Light extends Base {
|
|
|
218
218
|
return this;
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
+
withMaxBrightness() {
|
|
222
|
+
assert(!this.endpoint, 'Cannot add feature after adding endpoint');
|
|
223
|
+
this.features.push(new Numeric('max_brightness', access.ALL).withValueMin(1).withValueMax(255).withDescription('Maximum light brightness'));
|
|
224
|
+
return this;
|
|
225
|
+
}
|
|
226
|
+
|
|
221
227
|
withLevelConfig() {
|
|
222
228
|
assert(!this.endpoint, 'Cannot add feature after adding endpoint');
|
|
223
229
|
const levelConfig = new Composite('level_config', 'level_config')
|
package/lib/tuya.js
CHANGED
|
@@ -58,6 +58,61 @@ function getDataValue(dpValue) {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
function getTypeName(dpValue) {
|
|
62
|
+
const entry = Object.entries(dataTypes).find(([typeName, typeId]) => typeId === dpValue.datatype);
|
|
63
|
+
return (entry ? entry[0] : 'unknown');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function getDataPointNames(dpValue) {
|
|
67
|
+
const entries = Object.entries(dataPoints).filter(([dpName, dpId]) => dpId === dpValue.dp);
|
|
68
|
+
return entries.map(([dpName, dpId]) => dpName);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function logDataPoint(where, msg, dpValue, meta) {
|
|
72
|
+
meta.logger.info(`zigbee-herdsman-converters:${where}: Received Tuya DataPoint #${
|
|
73
|
+
dpValue.dp} from ${meta.device.ieeeAddr} with raw data '${JSON.stringify(dpValue)}': type='${
|
|
74
|
+
msg.type}', datatype='${getTypeName(dpValue)}', value='${
|
|
75
|
+
getDataValue(dpValue)}', known DP# usage: ${JSON.stringify(getDataPointNames(dpValue))}`);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function logUnexpectedDataPoint(where, msg, dpValue, meta) {
|
|
79
|
+
meta.logger.warn(`zigbee-herdsman-converters:${where}: Received unexpected Tuya DataPoint #${
|
|
80
|
+
dpValue.dp} from ${meta.device.ieeeAddr} with raw data '${JSON.stringify(dpValue)}': type='${
|
|
81
|
+
msg.type}', datatype='${getTypeName(dpValue)}', value='${
|
|
82
|
+
getDataValue(dpValue)}', known DP# usage: ${JSON.stringify(getDataPointNames(dpValue))}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function logUnexpectedDataType(where, msg, dpValue, meta, expectedDataType) {
|
|
86
|
+
meta.logger.warn(`zigbee-herdsman-converters:${where}: Received Tuya DataPoint #${
|
|
87
|
+
dpValue.dp} with unexpected datatype from ${meta.device.ieeeAddr} with raw data '${
|
|
88
|
+
JSON.stringify(dpValue)}': type='${msg.type}', datatype='${
|
|
89
|
+
getTypeName(dpValue)}' (instead of '${expectedDataType}'), value='${
|
|
90
|
+
getDataValue(dpValue)}', known DP# usage: ${JSON.stringify(getDataPointNames(dpValue))}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function logUnexpectedDataValue(where, msg, dpValue, meta, valueKind, expectedMinValue=null, expectedMaxValue=null) {
|
|
94
|
+
if (expectedMinValue === null) {
|
|
95
|
+
if (expectedMaxValue === null) {
|
|
96
|
+
meta.logger.warn(`zigbee-herdsman-converters:${where}: Received Tuya DataPoint #${dpValue.dp
|
|
97
|
+
} with invalid value ${getDataValue(dpValue)} for ${valueKind} from ${meta.device.ieeeAddr}`);
|
|
98
|
+
} else {
|
|
99
|
+
meta.logger.warn(`zigbee-herdsman-converters:${where}: Received Tuya DataPoint #${dpValue.dp
|
|
100
|
+
} with invalid value ${getDataValue(dpValue)} for ${valueKind} from ${meta.device.ieeeAddr
|
|
101
|
+
} which is higher than the expected maximum of ${expectedMaxValue}`);
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
if (expectedMaxValue === null) {
|
|
105
|
+
meta.logger.warn(`zigbee-herdsman-converters:${where}: Received Tuya DataPoint #${dpValue.dp
|
|
106
|
+
} with invalid value ${getDataValue(dpValue)} for ${valueKind} from ${meta.device.ieeeAddr
|
|
107
|
+
} which is lower than the expected minimum of ${expectedMinValue}`);
|
|
108
|
+
} else {
|
|
109
|
+
meta.logger.warn(`zigbee-herdsman-converters:${where}: Received Tuya DataPoint #${dpValue.dp
|
|
110
|
+
} with invalid value ${getDataValue(dpValue)} for ${valueKind} from ${meta.device.ieeeAddr
|
|
111
|
+
} which is outside the expected range from ${expectedMinValue} to ${expectedMaxValue}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
61
116
|
function convertDecimalValueTo4ByteHexArray(value) {
|
|
62
117
|
const hexValue = Number(value).toString(16).padStart(8, '0');
|
|
63
118
|
const chunk1 = hexValue.substr(0, 2);
|
|
@@ -229,11 +284,13 @@ const dataPoints = {
|
|
|
229
284
|
heatingSetpoint: 2,
|
|
230
285
|
coverPosition: 2,
|
|
231
286
|
dimmerLevel: 3,
|
|
287
|
+
dimmerMinLevel: 3,
|
|
232
288
|
localTemp: 3,
|
|
233
289
|
coverArrived: 3,
|
|
234
290
|
occupancy: 3,
|
|
235
291
|
mode: 4,
|
|
236
292
|
fanMode: 5,
|
|
293
|
+
dimmerMaxLevel: 5,
|
|
237
294
|
motorDirection: 5,
|
|
238
295
|
config: 5,
|
|
239
296
|
childLock: 7,
|
|
@@ -873,6 +930,12 @@ module.exports = {
|
|
|
873
930
|
sendDataPointStringBuffer,
|
|
874
931
|
firstDpValue,
|
|
875
932
|
getDataValue,
|
|
933
|
+
getTypeName,
|
|
934
|
+
getDataPointNames,
|
|
935
|
+
logDataPoint,
|
|
936
|
+
logUnexpectedDataPoint,
|
|
937
|
+
logUnexpectedDataType,
|
|
938
|
+
logUnexpectedDataValue,
|
|
876
939
|
dataTypes,
|
|
877
940
|
dataPoints,
|
|
878
941
|
dpValueFromIntValue,
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zigbee-herdsman-converters",
|
|
3
|
-
"version": "14.0.
|
|
3
|
+
"version": "14.0.466",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "zigbee-herdsman-converters",
|
|
9
|
-
"version": "14.0.
|
|
9
|
+
"version": "14.0.466",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"axios": "^0.26.1",
|