zigbee-herdsman-converters 21.27.0 → 21.28.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 +27 -0
- package/devices/adurosmart.d.ts.map +1 -1
- package/devices/adurosmart.js +7 -0
- package/devices/adurosmart.js.map +1 -1
- package/devices/avatto.d.ts.map +1 -1
- package/devices/avatto.js +36 -1
- package/devices/avatto.js.map +1 -1
- package/devices/enbrighten.d.ts.map +1 -1
- package/devices/enbrighten.js +95 -68
- package/devices/enbrighten.js.map +1 -1
- package/devices/inovelli.d.ts.map +1 -1
- package/devices/inovelli.js +172 -145
- package/devices/inovelli.js.map +1 -1
- package/devices/namron.js +1 -1
- package/devices/namron.js.map +1 -1
- package/devices/tuya.js +2 -2
- package/devices/tuya.js.map +1 -1
- package/devices/yokis.d.ts.map +1 -1
- package/devices/yokis.js +88 -9
- package/devices/yokis.js.map +1 -1
- package/lib/modernExtend.d.ts.map +1 -1
- package/lib/modernExtend.js +2 -5
- package/lib/modernExtend.js.map +1 -1
- package/lib/namron.js +35 -35
- package/lib/namron.js.map +1 -1
- package/package.json +6 -6
package/devices/inovelli.js
CHANGED
|
@@ -98,12 +98,13 @@ const individualLedEffects = {
|
|
|
98
98
|
aurora: 8,
|
|
99
99
|
clear_effect: 255,
|
|
100
100
|
};
|
|
101
|
+
const INOVELLI_CLUSTER_NAME = 'manuSpecificInovelli';
|
|
101
102
|
const inovelliExtend = {
|
|
102
|
-
addCustomClusterInovelli: () => m.deviceAddCustomCluster(
|
|
103
|
+
addCustomClusterInovelli: () => m.deviceAddCustomCluster(INOVELLI_CLUSTER_NAME, {
|
|
103
104
|
ID: 64561,
|
|
104
105
|
manufacturerCode: 0x122f,
|
|
105
106
|
attributes: {
|
|
106
|
-
dimmingSpeedUpRemote: { ID:
|
|
107
|
+
dimmingSpeedUpRemote: { ID: 0x0001, type: zigbee_herdsman_1.Zcl.DataType.UINT8 },
|
|
107
108
|
dimmingSpeedUpLocal: { ID: 0x0002, type: zigbee_herdsman_1.Zcl.DataType.UINT8 },
|
|
108
109
|
rampRateOffToOnRemote: { ID: 0x0003, type: zigbee_herdsman_1.Zcl.DataType.UINT8 },
|
|
109
110
|
rampRateOffToOnLocal: { ID: 0x0004, type: zigbee_herdsman_1.Zcl.DataType.UINT8 },
|
|
@@ -127,7 +128,7 @@ const inovelliExtend = {
|
|
|
127
128
|
quickStartTime: { ID: 0x0017, type: zigbee_herdsman_1.Zcl.DataType.UINT8 },
|
|
128
129
|
quickStartLevel: { ID: 0x0018, type: zigbee_herdsman_1.Zcl.DataType.UINT8 },
|
|
129
130
|
higherOutputInNonNeutral: { ID: 0x0019, type: zigbee_herdsman_1.Zcl.DataType.BOOLEAN },
|
|
130
|
-
|
|
131
|
+
dimmingMode: { ID: 0x001a, type: zigbee_herdsman_1.Zcl.DataType.BOOLEAN },
|
|
131
132
|
nonNeutralAuxMediumGear: { ID: 0x001e, type: zigbee_herdsman_1.Zcl.DataType.UINT8 },
|
|
132
133
|
nonNeutralAuxLowGear: { ID: 0x001f, type: zigbee_herdsman_1.Zcl.DataType.UINT8 },
|
|
133
134
|
internalTemperature: { ID: 0x0020, type: zigbee_herdsman_1.Zcl.DataType.UINT8 },
|
|
@@ -898,6 +899,13 @@ const COMMON_ATTRIBUTES = {
|
|
|
898
899
|
description: 'Level display of the LED Strip',
|
|
899
900
|
},
|
|
900
901
|
};
|
|
902
|
+
/**
|
|
903
|
+
* Common Dimmer Attributes
|
|
904
|
+
*
|
|
905
|
+
* These attributes are shared between all devices that act like dimmers (including dimmers + fan switches) with
|
|
906
|
+
* the manufacturer specific Inovelli cluster. These are not shared with on/off switches.
|
|
907
|
+
* Some of the descriptions, max, min or value properties may be overridden for each device
|
|
908
|
+
*/
|
|
901
909
|
const COMMON_DIMMER_ATTRIBUTES = {
|
|
902
910
|
...COMMON_ATTRIBUTES,
|
|
903
911
|
minimumLevel: {
|
|
@@ -937,6 +945,58 @@ const COMMON_DIMMER_ATTRIBUTES = {
|
|
|
937
945
|
displayType: 'enum',
|
|
938
946
|
},
|
|
939
947
|
};
|
|
948
|
+
/**
|
|
949
|
+
* Common Dimmable light Attributes
|
|
950
|
+
*
|
|
951
|
+
* These attributes are shared between all devices that are dimmable light switches with
|
|
952
|
+
* the manufacturer specific Inovelli cluster. These are not shared with fans or on/off switches.
|
|
953
|
+
* Some of the descriptions, max, min or value properties may be overridden for each device
|
|
954
|
+
*/
|
|
955
|
+
const COMMON_DIMMABLE_LIGHT_ATTRIBUTES = {
|
|
956
|
+
quickStartTime: {
|
|
957
|
+
ID: 23,
|
|
958
|
+
dataType: zigbee_herdsman_1.Zcl.DataType.UINT8,
|
|
959
|
+
min: 0,
|
|
960
|
+
max: 60,
|
|
961
|
+
description: 'Duration of full power output while lamp transitions from Off to On. In 60th of second. 0 = disable, 1 = 1/60s, 60 = 1s',
|
|
962
|
+
},
|
|
963
|
+
quickStartLevel: {
|
|
964
|
+
ID: 24,
|
|
965
|
+
dataType: zigbee_herdsman_1.Zcl.DataType.UINT8,
|
|
966
|
+
min: 1,
|
|
967
|
+
max: 254,
|
|
968
|
+
description: 'Level of power output during Quick Start Light time (P23).',
|
|
969
|
+
},
|
|
970
|
+
higherOutputInNonNeutral: {
|
|
971
|
+
ID: 25,
|
|
972
|
+
dataType: zigbee_herdsman_1.Zcl.DataType.BOOLEAN,
|
|
973
|
+
displayType: 'enum',
|
|
974
|
+
values: { 'Disabled (default)': 0, Enabled: 1 },
|
|
975
|
+
min: 0,
|
|
976
|
+
max: 1,
|
|
977
|
+
description: 'Increase level in non-neutral mode',
|
|
978
|
+
},
|
|
979
|
+
dimmingMode: {
|
|
980
|
+
ID: 26,
|
|
981
|
+
dataType: zigbee_herdsman_1.Zcl.DataType.BOOLEAN,
|
|
982
|
+
displayType: 'enum',
|
|
983
|
+
values: { 'Leading edge': 0, 'Trailing edge': 1 },
|
|
984
|
+
min: 0,
|
|
985
|
+
max: 1,
|
|
986
|
+
readOnly: true,
|
|
987
|
+
description: 'Switches the dimming mode from leading edge (default) to trailing edge. ' +
|
|
988
|
+
'1. Trailing Edge is only available on neutral single-pole and neutral multi-way with an ' +
|
|
989
|
+
'aux/add-on switch (multi-way with a dumb/existing switch and non-neutral setups are not supported and ' +
|
|
990
|
+
'will default back to Leading Edge). This parameter can only be changed at the switch.',
|
|
991
|
+
},
|
|
992
|
+
};
|
|
993
|
+
/**
|
|
994
|
+
* Common Dimmer or On/Off Attributes
|
|
995
|
+
*
|
|
996
|
+
* These attributes are shared between all devices that are light switches (either dimmers or on/off) with
|
|
997
|
+
* the manufacturer specific Inovelli cluster. These are not shared with fans.
|
|
998
|
+
* Some of the descriptions, max, min or value properties may be overridden for each device
|
|
999
|
+
*/
|
|
940
1000
|
const COMMON_DIMMER_ON_OFF_ATTRIBUTES = {
|
|
941
1001
|
ledBarScaling: {
|
|
942
1002
|
ID: 100,
|
|
@@ -980,29 +1040,7 @@ const VZM30_ATTRIBUTES = {
|
|
|
980
1040
|
const VZM31_ATTRIBUTES = {
|
|
981
1041
|
...COMMON_DIMMER_ATTRIBUTES,
|
|
982
1042
|
...COMMON_DIMMER_ON_OFF_ATTRIBUTES,
|
|
983
|
-
|
|
984
|
-
ID: 23,
|
|
985
|
-
dataType: zigbee_herdsman_1.Zcl.DataType.UINT8,
|
|
986
|
-
min: 0,
|
|
987
|
-
max: 60,
|
|
988
|
-
description: 'Duration of full power output while lamp tranisitions from Off to On. In 60th of second. 0 = disable, 1 = 1/60s, 60 = 1s',
|
|
989
|
-
},
|
|
990
|
-
quickStartLevel: {
|
|
991
|
-
ID: 24,
|
|
992
|
-
dataType: zigbee_herdsman_1.Zcl.DataType.UINT8,
|
|
993
|
-
min: 1,
|
|
994
|
-
max: 254,
|
|
995
|
-
description: 'Level of power output during Quick Start Light time (P23).',
|
|
996
|
-
},
|
|
997
|
-
higherOutputInNonNeutral: {
|
|
998
|
-
ID: 25,
|
|
999
|
-
dataType: zigbee_herdsman_1.Zcl.DataType.BOOLEAN,
|
|
1000
|
-
displayType: 'enum',
|
|
1001
|
-
values: { 'Disabled (default)': 0, Enabled: 1 },
|
|
1002
|
-
min: 0,
|
|
1003
|
-
max: 1,
|
|
1004
|
-
description: 'Increase level in non-neutral mode',
|
|
1005
|
-
},
|
|
1043
|
+
...COMMON_DIMMABLE_LIGHT_ATTRIBUTES,
|
|
1006
1044
|
relayClick: {
|
|
1007
1045
|
ID: 261,
|
|
1008
1046
|
dataType: zigbee_herdsman_1.Zcl.DataType.BOOLEAN,
|
|
@@ -1092,38 +1130,17 @@ const VZM36_ATTRIBUTES = {
|
|
|
1092
1130
|
...COMMON_ATTRIBUTES.stateAfterPowerRestored,
|
|
1093
1131
|
description: 'The state the light should return to when power is restored after power failure. 0 = off, 1-254 = level, 255 = previous.',
|
|
1094
1132
|
},
|
|
1133
|
+
quickStartTime_1: { ...COMMON_DIMMABLE_LIGHT_ATTRIBUTES.quickStartTime },
|
|
1134
|
+
quickStartLevel_1: { ...COMMON_DIMMABLE_LIGHT_ATTRIBUTES.quickStartLevel },
|
|
1095
1135
|
higherOutputInNonNeutral_1: {
|
|
1096
|
-
|
|
1097
|
-
dataType: zigbee_herdsman_1.Zcl.DataType.BOOLEAN,
|
|
1098
|
-
displayType: 'enum',
|
|
1099
|
-
values: { 'Disabled (default)': 0, Enabled: 1 },
|
|
1100
|
-
min: 0,
|
|
1101
|
-
max: 1,
|
|
1136
|
+
...COMMON_DIMMABLE_LIGHT_ATTRIBUTES.higherOutputInNonNeutral,
|
|
1102
1137
|
description: 'Increase level in non-neutral mode for light.',
|
|
1103
1138
|
},
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
description: 'Duration of full power output while lamp tranisitions from Off to On. In 60th of second. 0 = disable, 1 = 1/60s, 60 = 1s',
|
|
1110
|
-
},
|
|
1111
|
-
quickStartLevel_1: {
|
|
1112
|
-
ID: 24,
|
|
1113
|
-
dataType: zigbee_herdsman_1.Zcl.DataType.UINT8,
|
|
1114
|
-
min: 1,
|
|
1115
|
-
max: 254,
|
|
1116
|
-
description: 'Level of power output during Quick Start Light time (P23).',
|
|
1117
|
-
},
|
|
1118
|
-
leadingTrailingEdge_1: {
|
|
1119
|
-
ID: 26,
|
|
1120
|
-
dataType: zigbee_herdsman_1.Zcl.DataType.UINT8,
|
|
1121
|
-
displayType: 'enum',
|
|
1122
|
-
values: { 'Leading Edge': 0, 'Trailing Edge': 1 },
|
|
1123
|
-
min: 0,
|
|
1124
|
-
max: 1,
|
|
1125
|
-
description: 'Leading Edge has a value of 0 and is the default value, whereas Trailing Edge has a value of ' +
|
|
1126
|
-
'1. Please note that Trailing Edge is only available on neutral single-pole and neutral multi-way with an ' +
|
|
1139
|
+
dimmingMode_1: {
|
|
1140
|
+
...COMMON_DIMMABLE_LIGHT_ATTRIBUTES.dimmingMode,
|
|
1141
|
+
readOnly: false,
|
|
1142
|
+
description: 'Switches the dimming mode from leading edge (default) to trailing edge. ' +
|
|
1143
|
+
'1. Trailing Edge is only available on neutral single-pole and neutral multi-way with an ' +
|
|
1127
1144
|
'aux/add-on switch (multi-way with a dumb/existing switch and non-neutral setups are not supported and ' +
|
|
1128
1145
|
'will default back to Leading Edge).',
|
|
1129
1146
|
},
|
|
@@ -1180,11 +1197,8 @@ const VZM36_ATTRIBUTES = {
|
|
|
1180
1197
|
description: 'The state the fan should return to when power is restored after power failure. 0 = off, 1-254 = level, 255 = previous.',
|
|
1181
1198
|
},
|
|
1182
1199
|
quickStartTime_2: {
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
min: 0,
|
|
1186
|
-
max: 60,
|
|
1187
|
-
description: 'Duration of full power output while fan tranisitions from Off to On. In 60th of second. 0 = disable, 1 = 1/60s, 60 = 1s',
|
|
1200
|
+
...COMMON_DIMMABLE_LIGHT_ATTRIBUTES.quickStartTime,
|
|
1201
|
+
description: 'Duration of full power output while fan transitions from Off to On. In 60th of second. 0 = disable, 1 = 1/60s, 60 = 1s',
|
|
1188
1202
|
},
|
|
1189
1203
|
// power type readonly
|
|
1190
1204
|
// internal temp readonly
|
|
@@ -1202,7 +1216,7 @@ const VZM36_ATTRIBUTES = {
|
|
|
1202
1216
|
},
|
|
1203
1217
|
};
|
|
1204
1218
|
const tzLocal = {
|
|
1205
|
-
inovelli_parameters: (ATTRIBUTES) => ({
|
|
1219
|
+
inovelli_parameters: (ATTRIBUTES, cluster) => ({
|
|
1206
1220
|
key: Object.keys(ATTRIBUTES).filter((a) => !ATTRIBUTES[a].readOnly),
|
|
1207
1221
|
convertSet: async (entity, key, value, meta) => {
|
|
1208
1222
|
// Check key to see if there is an endpoint postfix for the VZM36
|
|
@@ -1223,7 +1237,7 @@ const tzLocal = {
|
|
|
1223
1237
|
type: ATTRIBUTES[key].dataType,
|
|
1224
1238
|
},
|
|
1225
1239
|
};
|
|
1226
|
-
await entityToUse.write(
|
|
1240
|
+
await entityToUse.write(cluster, payload, {
|
|
1227
1241
|
manufacturerCode: INOVELLI,
|
|
1228
1242
|
});
|
|
1229
1243
|
return {
|
|
@@ -1241,12 +1255,12 @@ const tzLocal = {
|
|
|
1241
1255
|
entityToUse = meta.device.getEndpoint(Number(keysplit[1]));
|
|
1242
1256
|
keyToUse = keysplit[0];
|
|
1243
1257
|
}
|
|
1244
|
-
await entityToUse.read(
|
|
1258
|
+
await entityToUse.read(cluster, [keyToUse], {
|
|
1245
1259
|
manufacturerCode: INOVELLI,
|
|
1246
1260
|
});
|
|
1247
1261
|
},
|
|
1248
1262
|
}),
|
|
1249
|
-
inovelli_parameters_readOnly: (ATTRIBUTES) => ({
|
|
1263
|
+
inovelli_parameters_readOnly: (ATTRIBUTES, cluster) => ({
|
|
1250
1264
|
key: Object.keys(ATTRIBUTES).filter((a) => ATTRIBUTES[a].readOnly),
|
|
1251
1265
|
convertGet: async (entity, key, meta) => {
|
|
1252
1266
|
// Check key to see if there is an endpoint postfix for the VZM36
|
|
@@ -1257,7 +1271,7 @@ const tzLocal = {
|
|
|
1257
1271
|
entityToUse = meta.device.getEndpoint(Number(keysplit[1]));
|
|
1258
1272
|
keyToUse = keysplit[0];
|
|
1259
1273
|
}
|
|
1260
|
-
await entityToUse.read(
|
|
1274
|
+
await entityToUse.read(cluster, [keyToUse], {
|
|
1261
1275
|
manufacturerCode: INOVELLI,
|
|
1262
1276
|
});
|
|
1263
1277
|
},
|
|
@@ -1265,7 +1279,7 @@ const tzLocal = {
|
|
|
1265
1279
|
inovelli_led_effect: {
|
|
1266
1280
|
key: ['led_effect'],
|
|
1267
1281
|
convertSet: async (entity, key, values, meta) => {
|
|
1268
|
-
await entity.command(
|
|
1282
|
+
await entity.command(INOVELLI_CLUSTER_NAME, 'ledEffect', {
|
|
1269
1283
|
// @ts-expect-error ignore
|
|
1270
1284
|
effect: ledEffects[values.effect],
|
|
1271
1285
|
// @ts-expect-error ignore
|
|
@@ -1281,7 +1295,7 @@ const tzLocal = {
|
|
|
1281
1295
|
inovelli_individual_led_effect: {
|
|
1282
1296
|
key: ['individual_led_effect'],
|
|
1283
1297
|
convertSet: async (entity, key, values, meta) => {
|
|
1284
|
-
await entity.command(
|
|
1298
|
+
await entity.command(INOVELLI_CLUSTER_NAME, 'individualLedEffect', {
|
|
1285
1299
|
// @ts-expect-error ignore
|
|
1286
1300
|
led: Math.min(Math.max(0, parseInt(values.led)), 7),
|
|
1287
1301
|
// @ts-expect-error ignore
|
|
@@ -1402,6 +1416,14 @@ const tzLocal = {
|
|
|
1402
1416
|
transtime: 0xffff,
|
|
1403
1417
|
}, utils.getOptions(meta.mapped, entity));
|
|
1404
1418
|
meta.state[key] = value;
|
|
1419
|
+
if (endpointId == 2) {
|
|
1420
|
+
return {
|
|
1421
|
+
state: {
|
|
1422
|
+
[key]: value,
|
|
1423
|
+
fan_state: 'ON',
|
|
1424
|
+
},
|
|
1425
|
+
};
|
|
1426
|
+
}
|
|
1405
1427
|
return {
|
|
1406
1428
|
state: {
|
|
1407
1429
|
[key]: value,
|
|
@@ -1472,55 +1494,7 @@ const tzLocal = {
|
|
|
1472
1494
|
await endpoint.read('genOnOff', ['onOff']);
|
|
1473
1495
|
},
|
|
1474
1496
|
},
|
|
1475
|
-
|
|
1476
|
-
key: ['breezeMode'],
|
|
1477
|
-
convertSet: async (entity, key, values, meta) => {
|
|
1478
|
-
// Calculate the value..
|
|
1479
|
-
let configValue = 0;
|
|
1480
|
-
let term = false;
|
|
1481
|
-
configValue += speedToInt(values.speed1);
|
|
1482
|
-
configValue += (Number(values.time1) / 5) * 4;
|
|
1483
|
-
let speed = speedToInt(values.speed2);
|
|
1484
|
-
if (speed !== 0) {
|
|
1485
|
-
configValue += speed * 64;
|
|
1486
|
-
configValue += (values.time2 / 5) * 256;
|
|
1487
|
-
}
|
|
1488
|
-
else {
|
|
1489
|
-
term = true;
|
|
1490
|
-
}
|
|
1491
|
-
speed = speedToInt(values.speed3);
|
|
1492
|
-
if (speed !== 0 && !term) {
|
|
1493
|
-
configValue += speed * 4096;
|
|
1494
|
-
configValue += (values.time3 / 5) * 16384;
|
|
1495
|
-
}
|
|
1496
|
-
else {
|
|
1497
|
-
term = true;
|
|
1498
|
-
}
|
|
1499
|
-
speed = speedToInt(values.speed4);
|
|
1500
|
-
if (speed !== 0 && !term) {
|
|
1501
|
-
configValue += speed * 262144;
|
|
1502
|
-
configValue += (values.time4 / 5) * 1048576;
|
|
1503
|
-
}
|
|
1504
|
-
else {
|
|
1505
|
-
term = true;
|
|
1506
|
-
}
|
|
1507
|
-
speed = speedToInt(values.speed5);
|
|
1508
|
-
if (speed !== 0 && !term) {
|
|
1509
|
-
configValue += speed * 16777216;
|
|
1510
|
-
configValue += (values.time5 / 5) * 67108864;
|
|
1511
|
-
}
|
|
1512
|
-
else {
|
|
1513
|
-
term = true;
|
|
1514
|
-
}
|
|
1515
|
-
const endpoint = meta.device.getEndpoint(2);
|
|
1516
|
-
const payload = { breezeMode: configValue.toString() };
|
|
1517
|
-
await endpoint.write('manuSpecificInovelli', payload, {
|
|
1518
|
-
manufacturerCode: INOVELLI,
|
|
1519
|
-
});
|
|
1520
|
-
return { state: { [key]: values } };
|
|
1521
|
-
},
|
|
1522
|
-
},
|
|
1523
|
-
breezeMode: {
|
|
1497
|
+
breezeMode: (endpointId) => ({
|
|
1524
1498
|
key: ['breezeMode'],
|
|
1525
1499
|
convertSet: async (entity, key, values, meta) => {
|
|
1526
1500
|
// Calculate the value..
|
|
@@ -1560,14 +1534,14 @@ const tzLocal = {
|
|
|
1560
1534
|
else {
|
|
1561
1535
|
term = true;
|
|
1562
1536
|
}
|
|
1563
|
-
const endpoint = meta.device.getEndpoint(
|
|
1537
|
+
const endpoint = meta.device.getEndpoint(endpointId);
|
|
1564
1538
|
const payload = { breezeMode: configValue.toString() };
|
|
1565
|
-
await endpoint.write(
|
|
1539
|
+
await endpoint.write(INOVELLI_CLUSTER_NAME, payload, {
|
|
1566
1540
|
manufacturerCode: INOVELLI,
|
|
1567
1541
|
});
|
|
1568
1542
|
return { state: { [key]: values } };
|
|
1569
1543
|
},
|
|
1570
|
-
},
|
|
1544
|
+
}),
|
|
1571
1545
|
};
|
|
1572
1546
|
/*
|
|
1573
1547
|
* Inovelli VZM31SN has a default transition property that the device should
|
|
@@ -1605,8 +1579,8 @@ const inovelliOnOffConvertSet = async (entity, key, value, meta) => {
|
|
|
1605
1579
|
}
|
|
1606
1580
|
};
|
|
1607
1581
|
const fzLocal = {
|
|
1608
|
-
inovelli: (ATTRIBUTES) => ({
|
|
1609
|
-
cluster:
|
|
1582
|
+
inovelli: (ATTRIBUTES, cluster, splitValuesByEndpoint = false) => ({
|
|
1583
|
+
cluster: cluster,
|
|
1610
1584
|
type: ['raw', 'readResponse', 'commandQueryNextImageRequest'],
|
|
1611
1585
|
convert: (model, msg, publish, options, meta) => {
|
|
1612
1586
|
if (msg.type === 'raw' && msg.endpoint.ID == 2 && msg.data[4] === 0x00) {
|
|
@@ -1629,13 +1603,14 @@ const fzLocal = {
|
|
|
1629
1603
|
}
|
|
1630
1604
|
else if (msg.type === 'readResponse') {
|
|
1631
1605
|
return Object.keys(msg.data).reduce((p, c) => {
|
|
1632
|
-
|
|
1606
|
+
const key = splitValuesByEndpoint ? `${c}_${msg.endpoint.ID}` : c;
|
|
1607
|
+
if (ATTRIBUTES[key] && ATTRIBUTES[key].displayType === 'enum') {
|
|
1633
1608
|
return {
|
|
1634
1609
|
...p,
|
|
1635
|
-
[
|
|
1610
|
+
[key]: Object.keys(ATTRIBUTES[key].values).find((k) => ATTRIBUTES[key].values[k] === msg.data[c]),
|
|
1636
1611
|
};
|
|
1637
1612
|
}
|
|
1638
|
-
return { ...p, [
|
|
1613
|
+
return { ...p, [key]: msg.data[c] };
|
|
1639
1614
|
}, {});
|
|
1640
1615
|
}
|
|
1641
1616
|
else {
|
|
@@ -1691,11 +1666,11 @@ const fzLocal = {
|
|
|
1691
1666
|
*
|
|
1692
1667
|
* Extract each nybble of the word, then reverse the calculation to get the settig for each.
|
|
1693
1668
|
*/
|
|
1694
|
-
breeze_mode: {
|
|
1695
|
-
cluster:
|
|
1669
|
+
breeze_mode: (endpointId) => ({
|
|
1670
|
+
cluster: INOVELLI_CLUSTER_NAME,
|
|
1696
1671
|
type: ['attributeReport', 'readResponse'],
|
|
1697
1672
|
convert: (model, msg, publish, options, meta) => {
|
|
1698
|
-
if (msg.endpoint.ID ==
|
|
1673
|
+
if (msg.endpoint.ID == endpointId) {
|
|
1699
1674
|
if (msg.data.breeze_mode !== undefined) {
|
|
1700
1675
|
const bitmasks = [3, 60, 192, 3840, 12288, 245760, 786432, 15728640, 50331648, 1006632960];
|
|
1701
1676
|
const raw = msg.data['breeze_mode'];
|
|
@@ -1726,7 +1701,7 @@ const fzLocal = {
|
|
|
1726
1701
|
}
|
|
1727
1702
|
}
|
|
1728
1703
|
},
|
|
1729
|
-
},
|
|
1704
|
+
}),
|
|
1730
1705
|
vzm36_fan_light_state: {
|
|
1731
1706
|
cluster: 'genOnOff',
|
|
1732
1707
|
type: ['attributeReport', 'readResponse'],
|
|
@@ -1837,6 +1812,16 @@ const buttonTapSequences = [
|
|
|
1837
1812
|
exposesListVZM30.push(e.action(buttonTapSequences));
|
|
1838
1813
|
exposesListVZM31.push(e.action(buttonTapSequences));
|
|
1839
1814
|
exposesListVZM35.push(e.action(buttonTapSequences));
|
|
1815
|
+
/*
|
|
1816
|
+
* Inovelli devices have a huge number of attributes. Calling endpoint.read() in a single call
|
|
1817
|
+
* for all attributes causes timeouts even with the timeout set to an absurdly high number (2 minutes)
|
|
1818
|
+
*/
|
|
1819
|
+
const chunkedRead = async (endpoint, attributes, cluster) => {
|
|
1820
|
+
const chunkSize = 10;
|
|
1821
|
+
for (let i = 0; i < attributes.length; i += chunkSize) {
|
|
1822
|
+
await endpoint.read(cluster, attributes.slice(i, i + chunkSize));
|
|
1823
|
+
}
|
|
1824
|
+
};
|
|
1840
1825
|
const definitions = [
|
|
1841
1826
|
{
|
|
1842
1827
|
zigbeeModel: ['VZM30-SN'],
|
|
@@ -1861,18 +1846,26 @@ const definitions = [
|
|
|
1861
1846
|
toZigbee_1.default.identify,
|
|
1862
1847
|
tzLocal.inovelli_led_effect,
|
|
1863
1848
|
tzLocal.inovelli_individual_led_effect,
|
|
1864
|
-
tzLocal.inovelli_parameters(VZM30_ATTRIBUTES),
|
|
1865
|
-
tzLocal.inovelli_parameters_readOnly(VZM30_ATTRIBUTES),
|
|
1849
|
+
tzLocal.inovelli_parameters(VZM30_ATTRIBUTES, INOVELLI_CLUSTER_NAME),
|
|
1850
|
+
tzLocal.inovelli_parameters_readOnly(VZM30_ATTRIBUTES, INOVELLI_CLUSTER_NAME),
|
|
1851
|
+
],
|
|
1852
|
+
fromZigbee: [
|
|
1853
|
+
fromZigbee_1.default.on_off,
|
|
1854
|
+
fromZigbee_1.default.brightness,
|
|
1855
|
+
fromZigbee_1.default.level_config,
|
|
1856
|
+
fromZigbee_1.default.power_on_behavior,
|
|
1857
|
+
fromZigbee_1.default.ignore_basic_report,
|
|
1858
|
+
fzLocal.inovelli(VZM30_ATTRIBUTES, INOVELLI_CLUSTER_NAME),
|
|
1866
1859
|
],
|
|
1867
|
-
fromZigbee: [fromZigbee_1.default.on_off, fromZigbee_1.default.brightness, fromZigbee_1.default.level_config, fromZigbee_1.default.power_on_behavior, fromZigbee_1.default.ignore_basic_report, fzLocal.inovelli(VZM30_ATTRIBUTES)],
|
|
1868
1860
|
ota: true,
|
|
1869
1861
|
configure: async (device, coordinatorEndpoint) => {
|
|
1870
1862
|
const endpoint = device.getEndpoint(1);
|
|
1871
1863
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
|
|
1872
1864
|
await reporting.onOff(endpoint);
|
|
1865
|
+
await chunkedRead(endpoint, Object.keys(VZM30_ATTRIBUTES), INOVELLI_CLUSTER_NAME);
|
|
1873
1866
|
// Bind for Button Event Reporting
|
|
1874
1867
|
const endpoint2 = device.getEndpoint(2);
|
|
1875
|
-
await reporting.bind(endpoint2, coordinatorEndpoint, [
|
|
1868
|
+
await reporting.bind(endpoint2, coordinatorEndpoint, [INOVELLI_CLUSTER_NAME]);
|
|
1876
1869
|
},
|
|
1877
1870
|
},
|
|
1878
1871
|
{
|
|
@@ -1901,18 +1894,26 @@ const definitions = [
|
|
|
1901
1894
|
toZigbee_1.default.identify,
|
|
1902
1895
|
tzLocal.inovelli_led_effect,
|
|
1903
1896
|
tzLocal.inovelli_individual_led_effect,
|
|
1904
|
-
tzLocal.inovelli_parameters(VZM31_ATTRIBUTES),
|
|
1905
|
-
tzLocal.inovelli_parameters_readOnly(VZM31_ATTRIBUTES),
|
|
1897
|
+
tzLocal.inovelli_parameters(VZM31_ATTRIBUTES, INOVELLI_CLUSTER_NAME),
|
|
1898
|
+
tzLocal.inovelli_parameters_readOnly(VZM31_ATTRIBUTES, INOVELLI_CLUSTER_NAME),
|
|
1899
|
+
],
|
|
1900
|
+
fromZigbee: [
|
|
1901
|
+
fromZigbee_1.default.on_off,
|
|
1902
|
+
fromZigbee_1.default.brightness,
|
|
1903
|
+
fromZigbee_1.default.level_config,
|
|
1904
|
+
fromZigbee_1.default.power_on_behavior,
|
|
1905
|
+
fromZigbee_1.default.ignore_basic_report,
|
|
1906
|
+
fzLocal.inovelli(VZM31_ATTRIBUTES, INOVELLI_CLUSTER_NAME),
|
|
1906
1907
|
],
|
|
1907
|
-
fromZigbee: [fromZigbee_1.default.on_off, fromZigbee_1.default.brightness, fromZigbee_1.default.level_config, fromZigbee_1.default.power_on_behavior, fromZigbee_1.default.ignore_basic_report, fzLocal.inovelli(VZM31_ATTRIBUTES)],
|
|
1908
1908
|
ota: true,
|
|
1909
1909
|
configure: async (device, coordinatorEndpoint) => {
|
|
1910
1910
|
const endpoint = device.getEndpoint(1);
|
|
1911
1911
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
|
|
1912
1912
|
await reporting.onOff(endpoint);
|
|
1913
|
+
await chunkedRead(endpoint, Object.keys(VZM31_ATTRIBUTES), INOVELLI_CLUSTER_NAME);
|
|
1913
1914
|
// Bind for Button Event Reporting
|
|
1914
1915
|
const endpoint2 = device.getEndpoint(2);
|
|
1915
|
-
await reporting.bind(endpoint2, coordinatorEndpoint, [
|
|
1916
|
+
await reporting.bind(endpoint2, coordinatorEndpoint, [INOVELLI_CLUSTER_NAME]);
|
|
1916
1917
|
},
|
|
1917
1918
|
},
|
|
1918
1919
|
{
|
|
@@ -1920,16 +1921,16 @@ const definitions = [
|
|
|
1920
1921
|
model: 'VZM35-SN',
|
|
1921
1922
|
vendor: 'Inovelli',
|
|
1922
1923
|
description: 'Fan controller',
|
|
1923
|
-
fromZigbee: [fzLocal.fan_state, fzLocal.fan_mode(1), fzLocal.breeze_mode, fzLocal.inovelli(VZM35_ATTRIBUTES)],
|
|
1924
|
+
fromZigbee: [fzLocal.fan_state, fzLocal.fan_mode(1), fzLocal.breeze_mode(1), fzLocal.inovelli(VZM35_ATTRIBUTES, INOVELLI_CLUSTER_NAME)],
|
|
1924
1925
|
toZigbee: [
|
|
1925
1926
|
toZigbee_1.default.identify,
|
|
1926
1927
|
tzLocal.fan_state,
|
|
1927
1928
|
tzLocal.fan_mode(1),
|
|
1928
1929
|
tzLocal.inovelli_led_effect,
|
|
1929
1930
|
tzLocal.inovelli_individual_led_effect,
|
|
1930
|
-
tzLocal.inovelli_parameters(VZM35_ATTRIBUTES),
|
|
1931
|
-
tzLocal.inovelli_parameters_readOnly(VZM35_ATTRIBUTES),
|
|
1932
|
-
tzLocal.breezeMode,
|
|
1931
|
+
tzLocal.inovelli_parameters(VZM35_ATTRIBUTES, INOVELLI_CLUSTER_NAME),
|
|
1932
|
+
tzLocal.inovelli_parameters_readOnly(VZM35_ATTRIBUTES, INOVELLI_CLUSTER_NAME),
|
|
1933
|
+
tzLocal.breezeMode(1),
|
|
1933
1934
|
],
|
|
1934
1935
|
exposes: exposesListVZM35.concat(m.identify().exposes),
|
|
1935
1936
|
extend: [inovelliExtend.addCustomClusterInovelli()],
|
|
@@ -1937,9 +1938,10 @@ const definitions = [
|
|
|
1937
1938
|
configure: async (device, coordinatorEndpoint) => {
|
|
1938
1939
|
const endpoint = device.getEndpoint(1);
|
|
1939
1940
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
|
|
1941
|
+
await chunkedRead(endpoint, Object.keys(VZM35_ATTRIBUTES), INOVELLI_CLUSTER_NAME);
|
|
1940
1942
|
// Bind for Button Event Reporting
|
|
1941
1943
|
const endpoint2 = device.getEndpoint(2);
|
|
1942
|
-
await reporting.bind(endpoint2, coordinatorEndpoint, [
|
|
1944
|
+
await reporting.bind(endpoint2, coordinatorEndpoint, [INOVELLI_CLUSTER_NAME]);
|
|
1943
1945
|
},
|
|
1944
1946
|
},
|
|
1945
1947
|
{
|
|
@@ -1947,15 +1949,21 @@ const definitions = [
|
|
|
1947
1949
|
model: 'VZM36',
|
|
1948
1950
|
vendor: 'Inovelli',
|
|
1949
1951
|
description: 'Fan canopy module',
|
|
1950
|
-
fromZigbee: [
|
|
1952
|
+
fromZigbee: [
|
|
1953
|
+
fzLocal.brightness,
|
|
1954
|
+
fzLocal.vzm36_fan_light_state,
|
|
1955
|
+
fzLocal.fan_mode(2),
|
|
1956
|
+
fzLocal.breeze_mode(2),
|
|
1957
|
+
fzLocal.inovelli(VZM36_ATTRIBUTES, INOVELLI_CLUSTER_NAME, true),
|
|
1958
|
+
],
|
|
1951
1959
|
toZigbee: [
|
|
1952
1960
|
toZigbee_1.default.identify,
|
|
1953
1961
|
tzLocal.vzm36_fan_on_off, // Need to use VZM36 specific converter
|
|
1954
1962
|
tzLocal.fan_mode(2),
|
|
1955
1963
|
tzLocal.light_onoff_brightness_inovelli,
|
|
1956
|
-
tzLocal.inovelli_parameters(VZM36_ATTRIBUTES),
|
|
1957
|
-
tzLocal.inovelli_parameters_readOnly(VZM36_ATTRIBUTES),
|
|
1958
|
-
tzLocal.
|
|
1964
|
+
tzLocal.inovelli_parameters(VZM36_ATTRIBUTES, INOVELLI_CLUSTER_NAME),
|
|
1965
|
+
tzLocal.inovelli_parameters_readOnly(VZM36_ATTRIBUTES, INOVELLI_CLUSTER_NAME),
|
|
1966
|
+
tzLocal.breezeMode(2),
|
|
1959
1967
|
],
|
|
1960
1968
|
exposes: exposesListVZM36.concat(m.identify().exposes),
|
|
1961
1969
|
extend: [inovelliExtend.addCustomClusterInovelli()],
|
|
@@ -1966,9 +1974,28 @@ const definitions = [
|
|
|
1966
1974
|
const endpoint = device.getEndpoint(1);
|
|
1967
1975
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
|
|
1968
1976
|
await reporting.onOff(endpoint);
|
|
1977
|
+
await chunkedRead(endpoint, Object.keys(VZM36_ATTRIBUTES).flatMap((key) => {
|
|
1978
|
+
const keysplit = key.split('_');
|
|
1979
|
+
if (keysplit.length === 2) {
|
|
1980
|
+
if (Number(keysplit[1]) == 1) {
|
|
1981
|
+
return [keysplit[0]];
|
|
1982
|
+
}
|
|
1983
|
+
return [];
|
|
1984
|
+
}
|
|
1985
|
+
return [key];
|
|
1986
|
+
}), INOVELLI_CLUSTER_NAME);
|
|
1969
1987
|
const endpoint2 = device.getEndpoint(2);
|
|
1970
1988
|
await reporting.bind(endpoint2, coordinatorEndpoint, ['genOnOff']);
|
|
1971
1989
|
await reporting.onOff(endpoint2);
|
|
1990
|
+
await chunkedRead(endpoint2, Object.keys(VZM36_ATTRIBUTES).flatMap((key) => {
|
|
1991
|
+
const keysplit = key.split('_');
|
|
1992
|
+
if (keysplit.length === 2) {
|
|
1993
|
+
if (Number(keysplit[1]) == 2) {
|
|
1994
|
+
return [keysplit[0]];
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
return [];
|
|
1998
|
+
}), INOVELLI_CLUSTER_NAME);
|
|
1972
1999
|
},
|
|
1973
2000
|
},
|
|
1974
2001
|
];
|