iobroker.zigbee 1.10.3 → 1.10.12
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/README.md +271 -17
- package/admin/adapter-settings.js +105 -18
- package/admin/admin.js +76 -44
- package/admin/i18n/de/translations.json +1 -1
- package/admin/i18n/en/translations.json +1 -1
- package/admin/i18n/fr/translations.json +1 -1
- package/admin/i18n/nl/translations.json +1 -1
- package/admin/i18n/pl/translations.json +1 -1
- package/admin/i18n/pt/translations.json +1 -1
- package/admin/img/E2204.png +0 -0
- package/admin/img/group_1.png +0 -0
- package/admin/img/group_2.png +0 -0
- package/admin/img/group_3.png +0 -0
- package/admin/img/group_4.png +0 -0
- package/admin/img/group_5.png +0 -0
- package/admin/img/group_6.png +0 -0
- package/admin/img/group_7.png +0 -0
- package/admin/index_m.html +286 -32
- package/admin/tab_m.html +312 -7
- package/admin/vis-network.min.css +1 -1
- package/admin/words.js +2 -2
- package/docs/de/readme.md +15 -16
- package/docs/en/readme.md +19 -19
- package/io-package.json +104 -99
- package/lib/backup.js +1 -2
- package/lib/commands.js +6 -5
- package/lib/developer.js +6 -2
- package/lib/devices.js +6 -2
- package/lib/groups.js +1 -25
- package/lib/ota.js +2 -2
- package/lib/statescontroller.js +48 -39
- package/lib/utils.js +4 -1
- package/lib/zigbeecontroller.js +31 -26
- package/main.js +57 -8
- package/package.json +17 -16
- package/support/docgen.js +3 -1
package/lib/developer.js
CHANGED
|
@@ -31,6 +31,10 @@ class Developer {
|
|
|
31
31
|
this.adapter.log.debug(msg);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
warn(msg) {
|
|
35
|
+
this.adapter.log.warn(msg);
|
|
36
|
+
}
|
|
37
|
+
|
|
34
38
|
/**
|
|
35
39
|
* @param {ioBroker.Message} obj
|
|
36
40
|
*/
|
|
@@ -57,7 +61,7 @@ class Developer {
|
|
|
57
61
|
const zcl = ZigbeeHerdsman.Zcl;
|
|
58
62
|
const result = {};
|
|
59
63
|
if (key === 'cidList') {
|
|
60
|
-
result.list = zcl.
|
|
64
|
+
result.list = zcl.Clusters;
|
|
61
65
|
} else if (key === 'attrIdList') {
|
|
62
66
|
const cid = obj.message.cid;
|
|
63
67
|
result.list = zcl.Utils.getCluster(cid).attributes;
|
|
@@ -133,7 +137,7 @@ class Developer {
|
|
|
133
137
|
// report exceptions
|
|
134
138
|
// happens for example if user tries to send write command but did not provide value/type
|
|
135
139
|
// or unsupported attribute was addressed.
|
|
136
|
-
const ZclStatusError = require('zigbee-herdsman/dist/zcl/zclStatusError').
|
|
140
|
+
const ZclStatusError = require('zigbee-herdsman/dist/zspec/zcl/zclStatusError').ZclStatusError;
|
|
137
141
|
if (exception instanceof ZclStatusError) {
|
|
138
142
|
const result = {};
|
|
139
143
|
result.msg = `Zigbee error ${exception.code} received!`;
|
package/lib/devices.js
CHANGED
|
@@ -37,7 +37,7 @@ const comb = {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
},
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
effectJson: (state, value, options, disableQueue) => {
|
|
42
42
|
if (state.id === states.effect_json.id) {
|
|
43
43
|
const effectjson = {};
|
|
@@ -1401,7 +1401,7 @@ const devices = [
|
|
|
1401
1401
|
linkedStates: [comb.brightnessAndState],
|
|
1402
1402
|
},
|
|
1403
1403
|
{
|
|
1404
|
-
models: ['LED1536G5', 'LED1903C5/LED1835C6'],
|
|
1404
|
+
models: ['LED1536G5', 'LED1835C6', 'LED1903C5/LED1835C6'],
|
|
1405
1405
|
icon: 'img/ikea_e14_bulb.png',
|
|
1406
1406
|
states: lightStatesWithColortemp,
|
|
1407
1407
|
linkedStates: [comb.brightnessAndState],
|
|
@@ -3090,6 +3090,10 @@ const devices = [
|
|
|
3090
3090
|
models: ['E1603/E1702/E1708'],
|
|
3091
3091
|
icon: 'img/ikea_control_outlet.png',
|
|
3092
3092
|
},
|
|
3093
|
+
{
|
|
3094
|
+
models: ['E2204'],
|
|
3095
|
+
icon: 'img/E2204.png',
|
|
3096
|
+
},
|
|
3093
3097
|
];
|
|
3094
3098
|
|
|
3095
3099
|
const commonStates = [
|
package/lib/groups.js
CHANGED
|
@@ -206,32 +206,8 @@ class Groups {
|
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
async deleteGroup(from, command, message) {
|
|
209
|
-
/*
|
|
210
|
-
const members = await this.getGroupMembersFromController(parseInt(message));
|
|
211
|
-
if (members && members.length) {
|
|
212
|
-
for (const member of members) {
|
|
213
|
-
const devName = member.device.substring(2);
|
|
214
|
-
const groupEntry = this.adapter.getStateAsync(`${devName}.groups`);
|
|
215
|
-
const memberarray = (groupEntry && groupEntry.val) ? JSON.parse(groupEntry.val) : [];
|
|
216
|
-
const index = memberarray.indexOf(message.toString());
|
|
217
|
-
if (index > -1) {
|
|
218
|
-
memberarray.splice(index, 1);
|
|
219
|
-
}
|
|
220
|
-
if (memberarray.length > 0) {
|
|
221
|
-
await this.adapter.setStateAsync(`${devName}.groups`, JSON.stringify(memberarray), true);
|
|
222
|
-
}
|
|
223
|
-
else {
|
|
224
|
-
await this.adapter.setStateAsync(`${devName}.groups`, '', true);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
const groupsEntry = await this.adapter.getStateAsync('info.groups');
|
|
229
|
-
const objGroups = (groupsEntry && groupsEntry.val ? JSON.parse(groupsEntry.val) : {});
|
|
230
|
-
delete objGroups[message.toString()];
|
|
231
|
-
await this.adapter.setStateAsync('info.groups', JSON.stringify(objGroups), true);
|
|
232
|
-
*/
|
|
233
209
|
await this.zbController.removeGroupById(message);
|
|
234
|
-
await this.stController.
|
|
210
|
+
await this.stController.deleteGroupById(`group_${parseInt(message)}`);
|
|
235
211
|
}
|
|
236
212
|
|
|
237
213
|
async renameGroup(from, command, message) {
|
package/lib/ota.js
CHANGED
|
@@ -94,7 +94,7 @@ class Ota {
|
|
|
94
94
|
this.debug(`Checking if firmware update is available for ${device.name}`);
|
|
95
95
|
|
|
96
96
|
if (device && device.mapped.ota) {
|
|
97
|
-
const available = await device.mapped.ota.isUpdateAvailable(device.device,
|
|
97
|
+
const available = await device.mapped.ota.isUpdateAvailable(device.device, null);
|
|
98
98
|
result.status = available.available ? 'available' : 'not_available';
|
|
99
99
|
if (available.currentFileVersion !== available.otaFileVersion) {
|
|
100
100
|
this.warn(`current Firmware for ${device.name} is ${available.currentFileVersion} new is ${available.otaFileVersion}`);
|
|
@@ -155,7 +155,7 @@ class Ota {
|
|
|
155
155
|
};
|
|
156
156
|
|
|
157
157
|
const from_ = await this.readSoftwareBuildIDAndDateCode(device.device, false);
|
|
158
|
-
await device.mapped.ota.updateToLatest(device.device,
|
|
158
|
+
const fileVersion = await device.mapped.ota.updateToLatest(device.device, onProgress);
|
|
159
159
|
const to = await this.readSoftwareBuildIDAndDateCode(device.device, true);
|
|
160
160
|
const [fromS, toS] = [JSON.stringify(from_), JSON.stringify(to)];
|
|
161
161
|
result.status = 'success';
|
package/lib/statescontroller.js
CHANGED
|
@@ -5,7 +5,7 @@ const statesMapping = require('./devices');
|
|
|
5
5
|
const getAdId = require('./utils').getAdId;
|
|
6
6
|
const getZbId = require('./utils').getZbId;
|
|
7
7
|
const fs = require('fs');
|
|
8
|
-
const
|
|
8
|
+
const axios = require('axios');
|
|
9
9
|
|
|
10
10
|
let savedDeviceNamesDB = {};
|
|
11
11
|
const knownUndefinedDevices = {};
|
|
@@ -78,6 +78,19 @@ class StatesController extends EventEmitter {
|
|
|
78
78
|
this.adapter.setStateAsync(`info.undefinedDevices`, JSON.stringify(knownUndefinedDevices), true);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
checkDebugDevice(dev) {
|
|
82
|
+
if (typeof dev != 'string' || dev == '') return false;
|
|
83
|
+
if (this.debugDevices === undefined) {
|
|
84
|
+
this.getDebugDevices();
|
|
85
|
+
}
|
|
86
|
+
for (const addressPart of this.debugDevices) {
|
|
87
|
+
if (typeof dev === 'string' && dev.includes(addressPart)) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
|
|
81
94
|
onStateChange(id, state) {
|
|
82
95
|
if (!this.adapter.zbController || !this.adapter.zbController.connected()) {
|
|
83
96
|
return;
|
|
@@ -98,12 +111,9 @@ class StatesController extends EventEmitter {
|
|
|
98
111
|
}
|
|
99
112
|
return;
|
|
100
113
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
114
|
+
|
|
115
|
+
if (this.checkDebugDevice(id)) this.warn(`ELEVATED: User stateChange ${id} ${JSON.stringify(state)}`);
|
|
116
|
+
|
|
107
117
|
this.debug(`User stateChange ${id} ${JSON.stringify(state)}`);
|
|
108
118
|
const devId = getAdId(this.adapter, id); // iobroker device id
|
|
109
119
|
let deviceId = getZbId(id); // zigbee device id
|
|
@@ -185,7 +195,7 @@ class StatesController extends EventEmitter {
|
|
|
185
195
|
knownUndefinedDevices[deviceId]++;
|
|
186
196
|
} else {
|
|
187
197
|
knownUndefinedDevices[deviceId] = 1;
|
|
188
|
-
this.
|
|
198
|
+
this.info(`Device ${deviceId} "${model}" not present in statesMapping - relying on exposes for device definition.`);
|
|
189
199
|
}
|
|
190
200
|
this.adapter.setStateAsync(`info.undefinedDevices`, JSON.stringify(knownUndefinedDevices), true);
|
|
191
201
|
states = statesMapping.commonStates;
|
|
@@ -209,14 +219,13 @@ class StatesController extends EventEmitter {
|
|
|
209
219
|
async publishFromState(deviceId, model, stateKey, state, options) {
|
|
210
220
|
if (this.debugDevices === undefined) this.getDebugDevices();
|
|
211
221
|
this.debug(`Change state '${stateKey}' at device ${deviceId} type '${model}'`);
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
}
|
|
217
|
-
}
|
|
222
|
+
const elevated = this.checkDebugDevice(deviceId);
|
|
223
|
+
|
|
224
|
+
if (elevated) this.warn(`ELEVATED Change state '${stateKey}' at device ${deviceId} type '${model}'`);
|
|
225
|
+
|
|
218
226
|
const devStates = await this.getDevStates(deviceId, model);
|
|
219
227
|
if (!devStates) {
|
|
228
|
+
if (elevated) this.error(`ELEVATED no device states for device ${deviceId} type '${model}'`);
|
|
220
229
|
return;
|
|
221
230
|
}
|
|
222
231
|
const commonStates = statesMapping.commonStates.find(statedesc => stateKey === statedesc.id);
|
|
@@ -229,6 +238,7 @@ class StatesController extends EventEmitter {
|
|
|
229
238
|
|
|
230
239
|
const value = state.val;
|
|
231
240
|
if (value === undefined || value === '') {
|
|
241
|
+
if (elevated) this.error(`ELEVATED no value for device ${deviceId} type '${model}'`);
|
|
232
242
|
return;
|
|
233
243
|
}
|
|
234
244
|
let stateList = [{stateDesc: stateDesc, value: value, index: 0, timeout: 0}];
|
|
@@ -304,22 +314,22 @@ class StatesController extends EventEmitter {
|
|
|
304
314
|
states.forEach(state =>
|
|
305
315
|
this.adapter.deleteState(devId, null, state._id));
|
|
306
316
|
}
|
|
307
|
-
this.adapter.
|
|
317
|
+
this.adapter.delObject(devId, () =>
|
|
308
318
|
callback && callback());
|
|
309
319
|
});
|
|
310
320
|
}
|
|
311
321
|
|
|
312
|
-
async
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
322
|
+
async deleteGroupById(devId) {
|
|
323
|
+
const options = { recursive:true };
|
|
324
|
+
try {
|
|
325
|
+
this.adapter.delObject(devId,options), (err) => { }
|
|
326
|
+
|
|
327
|
+
} catch (err) {
|
|
328
|
+
this.adapter.log.info(`Cannot delete Group ${devId}: ${err}`);
|
|
318
329
|
}
|
|
319
|
-
await this.adapter.deleteDevice(devId);
|
|
320
330
|
}
|
|
321
331
|
|
|
322
|
-
|
|
332
|
+
|
|
323
333
|
async deleteOrphanedDeviceStates(ieeeAddr, model, force, callback) {
|
|
324
334
|
const devStates = await this.getDevStates(ieeeAddr, model);
|
|
325
335
|
const commonStates = statesMapping.commonStates;
|
|
@@ -540,15 +550,17 @@ class StatesController extends EventEmitter {
|
|
|
540
550
|
async downloadIcon(url, image_path) {
|
|
541
551
|
if (!fs.existsSync(image_path)) {
|
|
542
552
|
return new Promise((resolve, reject) => {
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
553
|
+
axios({
|
|
554
|
+
method: 'get',
|
|
555
|
+
url: url,
|
|
556
|
+
responseType: 'stream' // Dies ist wichtig, um den Stream direkt zu erhalten
|
|
557
|
+
}).then(response => {
|
|
558
|
+
const writer = fs.createWriteStream(image_path);
|
|
559
|
+
response.data.pipe(writer);
|
|
560
|
+
writer.on('finish', resolve);
|
|
561
|
+
writer.on('error', reject);
|
|
562
|
+
}).catch(err => {
|
|
563
|
+
reject(err);
|
|
552
564
|
});
|
|
553
565
|
});
|
|
554
566
|
}
|
|
@@ -608,18 +620,15 @@ class StatesController extends EventEmitter {
|
|
|
608
620
|
const devStates = await this.getDevStates(`0x${devId}`, model);
|
|
609
621
|
let has_debug = false;
|
|
610
622
|
if (this.debugDevices === undefined) this.getDebugDevices();
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
break;
|
|
615
|
-
}
|
|
616
|
-
|
|
623
|
+
if (this.checkDebugDevice(devId))
|
|
624
|
+
{
|
|
625
|
+
if (!payload.hasOwnProperty('msg_from_zigbee')) {
|
|
617
626
|
this.warn(`ELEVATED publishToState: message received '${JSON.stringify(payload)}' from device ${devId} type '${model}'`);
|
|
618
627
|
has_debug = true;
|
|
619
|
-
break;
|
|
620
628
|
}
|
|
621
629
|
}
|
|
622
630
|
if (!devStates) {
|
|
631
|
+
if (has_debug) this.error(`ELEVATED publishToState: no device states for device ${devId} type '${model}'`)
|
|
623
632
|
return;
|
|
624
633
|
}
|
|
625
634
|
// find states for payload
|
package/lib/utils.js
CHANGED
|
@@ -127,8 +127,11 @@ function getDeviceIcon(definition) {
|
|
|
127
127
|
if (icon) {
|
|
128
128
|
icon = icon.replace('${model}', sanitizeImageParameter(definition.model));
|
|
129
129
|
}
|
|
130
|
+
// if (!icon) {
|
|
131
|
+
// icon = `https://www.zigbee2mqtt.io/images/devices/${sanitizeImageParameter(definition.model)}.jpg`;
|
|
132
|
+
// }
|
|
130
133
|
if (!icon) {
|
|
131
|
-
icon = `https://www.zigbee2mqtt.io/images/devices/${sanitizeImageParameter(definition.model)}.
|
|
134
|
+
icon = `https://www.zigbee2mqtt.io/images/devices/${sanitizeImageParameter(definition.model)}.png`;
|
|
132
135
|
}
|
|
133
136
|
return icon;
|
|
134
137
|
}
|
package/lib/zigbeecontroller.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const pathLib = require('path');
|
|
4
4
|
const ZigbeeHerdsman = require('zigbee-herdsman');
|
|
5
5
|
const zigbeeHerdsmanConverters = require('zigbee-herdsman-converters');
|
|
6
|
+
const ZDO = require('zigbee-herdsman/dist/zspec/zdo');
|
|
6
7
|
const zigbeeHerdsmanConvertersPhilips = require('zigbee-herdsman-converters/lib/philips');
|
|
7
8
|
const EventEmitter = require('events').EventEmitter;
|
|
8
9
|
const safeJsonStringify = require('./json');
|
|
@@ -11,6 +12,7 @@ const DeviceConfigureExt = require('./zbDeviceConfigure');
|
|
|
11
12
|
const DeviceEventExt = require('./zbDeviceEvent');
|
|
12
13
|
const DelayedActionExt = require('./zbDelayedAction');
|
|
13
14
|
const utils = require('./utils');
|
|
15
|
+
const { waitForDebugger } = require('inspector');
|
|
14
16
|
const groupConverters = [
|
|
15
17
|
zigbeeHerdsmanConverters.toZigbee.light_onoff_brightness,
|
|
16
18
|
zigbeeHerdsmanConverters.toZigbee.light_color_colortemp,
|
|
@@ -301,9 +303,9 @@ class ZigbeeController extends EventEmitter {
|
|
|
301
303
|
}
|
|
302
304
|
|
|
303
305
|
async removeGroupById(id) {
|
|
304
|
-
const group = await this.getGroupByID(id);
|
|
306
|
+
const group = await this.getGroupByID(Number(id));
|
|
305
307
|
try {
|
|
306
|
-
group && group.
|
|
308
|
+
group && group.removeFromNetwork();
|
|
307
309
|
} catch (error) {
|
|
308
310
|
this.sendError(error);
|
|
309
311
|
this.error(`error in removeGroupById: ${error}`);
|
|
@@ -552,7 +554,8 @@ class ZigbeeController extends EventEmitter {
|
|
|
552
554
|
const device = await this.herdsman.getDeviceByIeeeAddr(deviceID);
|
|
553
555
|
if (device) {
|
|
554
556
|
try {
|
|
555
|
-
await
|
|
557
|
+
await device.removeFromNetwork();
|
|
558
|
+
//this.herdsman.adapter.removeDevice(device.networkAddress, device.ieeeAddr);
|
|
556
559
|
} catch (error) {
|
|
557
560
|
this.sendError(error);
|
|
558
561
|
if (error)
|
|
@@ -814,20 +817,25 @@ class ZigbeeController extends EventEmitter {
|
|
|
814
817
|
|
|
815
818
|
if (type === 'foundation') {
|
|
816
819
|
cfg.disableDefaultResponse = true;
|
|
820
|
+
|
|
817
821
|
if (cmd === 'read' && !Array.isArray(zclData)) {
|
|
818
|
-
// needs to be iterable (string[] | number [])
|
|
822
|
+
/* // needs to be iterable (string[] | number [])
|
|
819
823
|
zclData[Symbol.iterator] = function* () {
|
|
820
824
|
let k;
|
|
821
825
|
for (k in this) {
|
|
822
826
|
yield k;
|
|
823
827
|
}
|
|
824
828
|
};
|
|
829
|
+
*/
|
|
825
830
|
}
|
|
826
831
|
let result;
|
|
827
832
|
if (cmd === 'configReport') {
|
|
828
833
|
result = await endpoint.configureReporting(cid, zclData, cfg);
|
|
829
834
|
} else {
|
|
830
|
-
|
|
835
|
+
if (cmd === 'read' && !Array.isArray(zclData))
|
|
836
|
+
result = await endpoint[cmd](cid, Object.keys(zclData), cfg);
|
|
837
|
+
else
|
|
838
|
+
result = await endpoint[cmd](cid, zclData, cfg);
|
|
831
839
|
}
|
|
832
840
|
callback && callback(undefined, result);
|
|
833
841
|
} else if (type === 'functionalResp') {
|
|
@@ -999,27 +1007,24 @@ class ZigbeeController extends EventEmitter {
|
|
|
999
1007
|
}
|
|
1000
1008
|
|
|
1001
1009
|
async getChannelsEnergy() {
|
|
1002
|
-
const
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
);
|
|
1021
|
-
const result = await energyScan.start().promise;
|
|
1022
|
-
return result.payload;
|
|
1010
|
+
const clusterId = ZDO.ClusterId.NWK_UPDATE_REQUEST;
|
|
1011
|
+
const result = {};
|
|
1012
|
+
try
|
|
1013
|
+
{
|
|
1014
|
+
const payload = ZDO.Buffalo.buildRequest(false, clusterId, [11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26], 0x05, 1, 0, undefined);
|
|
1015
|
+
const scanresult = await this.herdsman.adapter.sendZdo(0x0, 0x0, clusterId , payload, false);
|
|
1016
|
+
this.debug(`scanresult is ${JSON.stringify(scanresult)}`)
|
|
1017
|
+
result.energyvalues = scanresult[1].entryList;
|
|
1018
|
+
this.debug(`result is ${JSON.stringify(result)}`)
|
|
1019
|
+
}
|
|
1020
|
+
catch (error) {
|
|
1021
|
+
this.sendError(error);
|
|
1022
|
+
this.error(`Failed to scan channels ${error.stack}`);
|
|
1023
|
+
result.error = error;
|
|
1024
|
+
|
|
1025
|
+
}
|
|
1026
|
+
return result;
|
|
1027
|
+
|
|
1023
1028
|
}
|
|
1024
1029
|
}
|
|
1025
1030
|
|
package/main.js
CHANGED
|
@@ -467,6 +467,16 @@ class Zigbee extends utils.Adapter {
|
|
|
467
467
|
const devId = device.ieeeAddr.substr(2);
|
|
468
468
|
const meta = {device};
|
|
469
469
|
|
|
470
|
+
if (this.stController.checkDebugDevice(devId)) {
|
|
471
|
+
const shortMessage = {};
|
|
472
|
+
for(const propertyName in message) {
|
|
473
|
+
shortMessage[propertyName] = message[propertyName];
|
|
474
|
+
}
|
|
475
|
+
shortMessage.device = device.ieeeAddr;
|
|
476
|
+
shortMessage.meta = undefined;
|
|
477
|
+
shortMessage.endpoint = (message.endpoint.ID ? message.endpoint.ID: -1);
|
|
478
|
+
this.log.warn(`ELEVATED: Zigbee Event of Type ${type} from device ${safeJsonStringify(device.ieeeAddr)}, incoming event: ${safeJsonStringify(shortMessage)}`);
|
|
479
|
+
}
|
|
470
480
|
// this assigment give possibility to use iobroker logger in code of the converters, via meta.logger
|
|
471
481
|
meta.logger = this.log;
|
|
472
482
|
|
|
@@ -613,6 +623,7 @@ class Zigbee extends utils.Adapter {
|
|
|
613
623
|
|
|
614
624
|
async publishFromState(deviceId, model, stateModel, stateList, options) {
|
|
615
625
|
let isGroup = false;
|
|
626
|
+
const has_elevated_debug = this.stController.checkDebugDevice(deviceId)
|
|
616
627
|
|
|
617
628
|
this.log.debug(`publishFromState : ${deviceId} ${model} ${safeJsonStringify(stateList)}`);
|
|
618
629
|
if (model === 'group') {
|
|
@@ -628,6 +639,13 @@ class Zigbee extends utils.Adapter {
|
|
|
628
639
|
|
|
629
640
|
if (!mappedModel) {
|
|
630
641
|
this.log.debug(`No mapped model for ${model}`);
|
|
642
|
+
if (has_elevated_debug) this.log.warn(`ELEVATED: No mapped model for ${model}`)
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
if (!mappedModel.toZigbee)
|
|
647
|
+
{
|
|
648
|
+
this.log.error(`No toZigbee in mapped model for ${model}`);
|
|
631
649
|
return;
|
|
632
650
|
}
|
|
633
651
|
|
|
@@ -691,8 +709,33 @@ class Zigbee extends utils.Adapter {
|
|
|
691
709
|
}
|
|
692
710
|
return;
|
|
693
711
|
}
|
|
694
|
-
|
|
695
|
-
|
|
712
|
+
|
|
713
|
+
let converter = undefined;
|
|
714
|
+
for (const c of mappedModel.toZigbee) {
|
|
715
|
+
|
|
716
|
+
if (!c.hasOwnProperty('convertSet')) continue;
|
|
717
|
+
this.log.debug(`Type of toZigbee is '${typeof c}', Contains key ${(c.hasOwnProperty('key')?JSON.stringify(c.key):'false ')}`)
|
|
718
|
+
if (!c.hasOwnProperty('key') && c.hasOwnProperty('convertSet') && converter === undefined)
|
|
719
|
+
{
|
|
720
|
+
converter = c;
|
|
721
|
+
|
|
722
|
+
if (has_elevated_debug) this.log.warn(`ELEVATED: setting converter to keyless converter for ${deviceId} of type ${model}`)
|
|
723
|
+
this.log.debug('setting converter to keyless converter')
|
|
724
|
+
continue;
|
|
725
|
+
}
|
|
726
|
+
if (c.key.includes(stateDesc.prop) || c.key.includes(stateDesc.setattr) || c.key.includes(stateDesc.id))
|
|
727
|
+
{
|
|
728
|
+
this.log.debug(`${(converter===undefined?'Setting':'Overriding')}' converter to converter with key(s)'${JSON.stringify(c.key)}}`)
|
|
729
|
+
if (has_elevated_debug) this.log.warn(`ELEVATED: ${(converter===undefined?'Setting':'Overriding')}' converter to converter with key(s)'${JSON.stringify(c.key)}}`)
|
|
730
|
+
converter = c;
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
}
|
|
734
|
+
/*
|
|
735
|
+
if (!mappedModel.toZigbee[0].hasOwnProperty('key') && mappedModel.toZigbee[0].hasOwnProperty('convertSet')) converter = mappedModel.toZigbee[0];
|
|
736
|
+
converter = mappedModel.toZigbee.find(c => c && c.hasOwnProperty('key') && (c.key.includes(stateDesc.prop) || c.key.includes(stateDesc.setattr) || c.key.includes(stateDesc.id)));
|
|
737
|
+
*/
|
|
738
|
+
if (converter === undefined) {
|
|
696
739
|
this.log.error(`No converter available for '${model}' with key '${stateDesc.id}' `);
|
|
697
740
|
this.sendError(`No converter available for '${model}' with key '${stateDesc.id}' `);
|
|
698
741
|
return;
|
|
@@ -714,6 +757,7 @@ class Zigbee extends utils.Adapter {
|
|
|
714
757
|
const epName = stateDesc.epname !== undefined ? stateDesc.epname : (stateDesc.prop || stateDesc.id);
|
|
715
758
|
const key = stateDesc.prop || stateDesc.id || stateDesc.setattr;
|
|
716
759
|
this.log.debug(`convert ${key}, ${safeJsonStringify(preparedValue)}, ${safeJsonStringify(preparedOptions)}`);
|
|
760
|
+
if (has_elevated_debug) this.log.warn(`ELEVATED: convert ${key}, ${safeJsonStringify(preparedValue)}, ${safeJsonStringify(preparedOptions)} for device ${deviceId}`);
|
|
717
761
|
|
|
718
762
|
let target;
|
|
719
763
|
if (model === 'group') {
|
|
@@ -753,6 +797,7 @@ class Zigbee extends utils.Adapter {
|
|
|
753
797
|
try {
|
|
754
798
|
const result = await converter.convertSet(target, key, preparedValue, meta);
|
|
755
799
|
this.log.debug(`convert result ${safeJsonStringify(result)}`);
|
|
800
|
+
if (has_elevated_debug) this.log.warn(`ELEVATED: convert result ${safeJsonStringify(result)} for device ${deviceId}`);
|
|
756
801
|
if (result !== undefined) {
|
|
757
802
|
if (stateModel && !isGroup) {
|
|
758
803
|
this.acknowledgeState(deviceId, model, stateDesc, value);
|
|
@@ -760,13 +805,16 @@ class Zigbee extends utils.Adapter {
|
|
|
760
805
|
// process sync state list
|
|
761
806
|
this.processSyncStatesList(deviceId, model, syncStateList);
|
|
762
807
|
|
|
763
|
-
if (isGroup) {
|
|
764
|
-
await this.callPluginMethod('queryGroupMemberState', [deviceId, stateDesc]);
|
|
765
|
-
this.acknowledgeState(deviceId, model, stateDesc, value);
|
|
766
|
-
}
|
|
808
|
+
// if (isGroup) {
|
|
809
|
+
// await this.callPluginMethod('queryGroupMemberState', [deviceId, stateDesc]);
|
|
810
|
+
// this.acknowledgeState(deviceId, model, stateDesc, value);
|
|
811
|
+
// }
|
|
767
812
|
}
|
|
813
|
+
else
|
|
814
|
+
if (has_elevated_debug) this.log.warn(`Error convert result for ${key} with ${safeJsonStringify(preparedValue)} is undefined on device ${deviceId}.`);
|
|
768
815
|
|
|
769
816
|
} catch (error) {
|
|
817
|
+
if (has_elevated_debug) this.log.warn(`caught error ${safeJsonStringify(error)} is undefined on device ${deviceId}.`);
|
|
770
818
|
this.filterError(`Error ${error.code} on send command to ${deviceId}.` +
|
|
771
819
|
` Error: ${error.stack}`, `Send command to ${deviceId} failed with`, error);
|
|
772
820
|
}
|
|
@@ -961,9 +1009,10 @@ class Zigbee extends utils.Adapter {
|
|
|
961
1009
|
const adapterType = this.config.adapterType || 'zstack';
|
|
962
1010
|
// https://github.com/ioBroker/ioBroker.zigbee/issues/668
|
|
963
1011
|
const extPanIdFix = this.config.extPanIdFix ? this.config.extPanIdFix : false;
|
|
964
|
-
|
|
965
1012
|
const baudRate = parseInt(this.config.baudRate ? this.config.baudRate : 115200);
|
|
966
1013
|
|
|
1014
|
+
const setRtscts = this.config.flowCTRL ? this.config.flowCTRL : false;
|
|
1015
|
+
|
|
967
1016
|
return {
|
|
968
1017
|
net: {
|
|
969
1018
|
panId: panID,
|
|
@@ -974,7 +1023,7 @@ class Zigbee extends utils.Adapter {
|
|
|
974
1023
|
sp: {
|
|
975
1024
|
port: port,
|
|
976
1025
|
baudRate: baudRate,
|
|
977
|
-
rtscts:
|
|
1026
|
+
rtscts: setRtscts,
|
|
978
1027
|
adapter: adapterType,
|
|
979
1028
|
},
|
|
980
1029
|
dbDir: dbDir,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.zigbee",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.12",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "Kirov Ilya",
|
|
6
6
|
"email": "kirovilya@gmail.com"
|
|
@@ -21,32 +21,33 @@
|
|
|
21
21
|
"serialport": "^12.0.0"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@iobroker/adapter-core": "^3.
|
|
25
|
-
"@iobroker/dm-utils": "^0.
|
|
26
|
-
"humanize-duration": "^3.
|
|
27
|
-
"tar": "^
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
24
|
+
"@iobroker/adapter-core": "^3.2.2",
|
|
25
|
+
"@iobroker/dm-utils": "^0.5.0",
|
|
26
|
+
"humanize-duration": "^3.32.1",
|
|
27
|
+
"tar": "^7.4.3",
|
|
28
|
+
"ajv": "^8.17.1",
|
|
29
|
+
"uri-js": "^4.4.1",
|
|
30
|
+
"typescript": "^5.6.3",
|
|
31
|
+
"zigbee-herdsman": "2.1.4",
|
|
32
|
+
"zigbee-herdsman-converters": "20.28.0"
|
|
31
33
|
},
|
|
32
34
|
"description": "Zigbee devices",
|
|
33
35
|
"devDependencies": {
|
|
34
|
-
"@alcalzone/release-script": "^3.
|
|
35
|
-
"@alcalzone/release-script-plugin-iobroker": "^3.7.
|
|
36
|
+
"@alcalzone/release-script": "^3.8.0",
|
|
37
|
+
"@alcalzone/release-script-plugin-iobroker": "^3.7.2",
|
|
36
38
|
"@alcalzone/release-script-plugin-license": "^3.7.0",
|
|
37
39
|
"@alcalzone/release-script-plugin-manual-review": "^3.7.0",
|
|
38
|
-
"@iobroker/testing": "^
|
|
39
|
-
"
|
|
40
|
-
"chai": "^4.4.1",
|
|
40
|
+
"@iobroker/testing": "^5.0.0",
|
|
41
|
+
"chai": "^5.1.2",
|
|
41
42
|
"chai-as-promised": "^7.1.1",
|
|
42
|
-
"eslint": "^
|
|
43
|
+
"eslint": "^9.13.0",
|
|
43
44
|
"eslint-config-prettier": "^9.1.0",
|
|
44
|
-
"eslint-plugin-prettier": "^5.
|
|
45
|
+
"eslint-plugin-prettier": "^5.2.1",
|
|
45
46
|
"gulp": "^4.0.2",
|
|
46
47
|
"gulp-jsdoc3": "^3.0.0",
|
|
47
48
|
"gulp-replace": "^1.1.4",
|
|
48
49
|
"mixin-deep": "^2.0.1",
|
|
49
|
-
"mocha": "^10.
|
|
50
|
+
"mocha": "^10.8.2"
|
|
50
51
|
},
|
|
51
52
|
"homepage": "https://github.com/ioBroker/ioBroker.zigbee",
|
|
52
53
|
"keywords": [
|
package/support/docgen.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* This script generates the supported devices page.
|
|
3
3
|
*
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
|
|
6
6
|
let devices = [...require('zigbee-herdsman-converters').devices];
|
|
7
7
|
|
|
@@ -91,3 +91,5 @@ vendors.forEach((vendor) => {
|
|
|
91
91
|
});
|
|
92
92
|
|
|
93
93
|
fs.writeFileSync(outputdir + '/' + file, text);
|
|
94
|
+
|
|
95
|
+
*/
|