iobroker.zigbee 2.0.4 → 3.0.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/README.md +90 -57
- package/admin/admin.js +497 -120
- package/admin/img/philips_hue_lom001.png +0 -0
- package/admin/index_m.html +168 -124
- package/admin/tab_m.html +20 -11
- package/docs/de/img/Bild30.png +0 -0
- package/docs/de/img/Bild38.png +0 -0
- package/docs/de/img/Info.png +0 -0
- package/docs/de/img/Zigbee_config_de.jpg +0 -0
- package/docs/de/img/battery.png +0 -0
- package/docs/de/img/debug.png +0 -0
- package/docs/de/img/delete.png +0 -0
- package/docs/de/img/disconnected.png +0 -0
- package/docs/de/img/edit_grp.png +0 -0
- package/docs/de/img/edit_image.png +0 -0
- package/docs/de/img/grp_nok.png +0 -0
- package/docs/de/img/grp_ok.png +0 -0
- package/docs/de/img/on_off.png +0 -0
- package/docs/de/img/reconfigure.png +0 -0
- package/docs/de/readme.md +52 -43
- package/docs/en/img/Zigbee_config_en.png +0 -0
- package/docs/en/img/Zigbee_pairing_en.png +0 -0
- package/docs/en/readme.md +71 -66
- package/docs/tutorial/groups-1.png +0 -0
- package/docs/tutorial/groups-2.png +0 -0
- package/docs/tutorial/tab-dev-1.png +0 -0
- package/io-package.json +31 -65
- package/lib/DeviceDebug.js +5 -2
- package/lib/commands.js +182 -31
- package/lib/developer.js +0 -0
- package/lib/devices.js +2 -2
- package/lib/exposes.js +10 -27
- package/lib/groups.js +6 -8
- package/lib/localConfig.js +4 -5
- package/lib/ota.js +6 -6
- package/lib/seriallist.js +9 -2
- package/lib/statescontroller.js +397 -128
- package/lib/utils.js +41 -11
- package/lib/zbDeviceAvailability.js +2 -2
- package/lib/zbDeviceConfigure.js +99 -58
- package/lib/zigbeecontroller.js +152 -128
- package/main.js +251 -264
- package/package.json +10 -10
- package/docs/en/img/Bild23.png +0 -0
- package/docs/en/img/Bild25.png +0 -0
- package/docs/en/img/Bild26.png +0 -0
- package/docs/en/img/Bild4.png +0 -0
- package/docs/en/img/Bild9.png +0 -0
package/lib/zigbeecontroller.js
CHANGED
|
@@ -12,11 +12,10 @@ const DeviceConfigureExt = require('./zbDeviceConfigure');
|
|
|
12
12
|
const DeviceEventExt = require('./zbDeviceEvent');
|
|
13
13
|
const DelayedActionExt = require('./zbDelayedAction');
|
|
14
14
|
const Groups = require('./groups');
|
|
15
|
-
|
|
16
15
|
const utils = require('./utils');
|
|
17
|
-
|
|
18
|
-
const {
|
|
19
|
-
|
|
16
|
+
|
|
17
|
+
const { access, constants } =require('node:fs/promises');
|
|
18
|
+
|
|
20
19
|
const groupConverters = [
|
|
21
20
|
zigbeeHerdsmanConverters.toZigbee.light_onoff_brightness,
|
|
22
21
|
zigbeeHerdsmanConverters.toZigbee.light_color_colortemp,
|
|
@@ -65,6 +64,7 @@ class ZigbeeController extends EventEmitter {
|
|
|
65
64
|
super();
|
|
66
65
|
this.adapter = adapter;
|
|
67
66
|
this._permitJoinTime = 0;
|
|
67
|
+
this.transmitPower = 0;
|
|
68
68
|
this.herdsmanStarted = false;
|
|
69
69
|
this.extensions = [
|
|
70
70
|
new DeviceAvailabilityExt(this, {}),
|
|
@@ -73,20 +73,53 @@ class ZigbeeController extends EventEmitter {
|
|
|
73
73
|
new DelayedActionExt(this, {}),
|
|
74
74
|
];
|
|
75
75
|
this.herdsmanTimeoutRegexp = new RegExp(/(\d+)ms/);
|
|
76
|
-
this.herdsmanLogSettings = {}
|
|
76
|
+
this.herdsmanLogSettings = {};
|
|
77
|
+
this.debugActive = true;
|
|
78
|
+
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
82
|
+
|
|
83
|
+
reverseIEEE(source) {
|
|
84
|
+
const rv = [];
|
|
85
|
+
for (let i=0;i<source.length;i+=2)
|
|
86
|
+
rv.push(source.slice(i,i+2))
|
|
87
|
+
return rv.reverse().join('');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async testConnectable(port) {
|
|
91
|
+
const netAddress = utils.getNetAddress(port);
|
|
92
|
+
if (netAddress && netAddress.strAddress) return netAddress.strAddress;
|
|
93
|
+
try {
|
|
94
|
+
const _port = port.trim();
|
|
95
|
+
await access(_port, constants.R_OK | constants.W_OK);
|
|
96
|
+
return _port;
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
console.warn(`unable to access ${port}`)
|
|
100
|
+
return '';
|
|
101
|
+
}
|
|
87
102
|
}
|
|
88
103
|
|
|
89
104
|
configure(options) {
|
|
105
|
+
|
|
106
|
+
if (options.transmitPower != undefined) {
|
|
107
|
+
this.transmitPower = options.transmitPower;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
this.powerText = '';
|
|
111
|
+
if (this.transmitPower !== '0') {
|
|
112
|
+
const powerLevels = {
|
|
113
|
+
'-22': 'low',
|
|
114
|
+
'19': 'high',
|
|
115
|
+
'20': 'high+'
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
this.powerText = powerLevels[this.transmitPower] || 'normal';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
this.info(` --> transmitPower : ${this.powerText}`);
|
|
122
|
+
|
|
90
123
|
const herdsmanSettings = {
|
|
91
124
|
network: {
|
|
92
125
|
panID: options.net.panId,
|
|
@@ -99,31 +132,34 @@ class ZigbeeController extends EventEmitter {
|
|
|
99
132
|
serialPort: {
|
|
100
133
|
baudRate: options.sp.baudRate,
|
|
101
134
|
rtscts: options.sp.rtscts,
|
|
102
|
-
path: options.sp.port,
|
|
135
|
+
path: (typeof options.sp.port == 'string' ? options.sp.port.trim() : options.sp.port),
|
|
103
136
|
adapter: options.sp.adapter,
|
|
104
137
|
},
|
|
138
|
+
transmitpower: this.transmitPower,
|
|
105
139
|
adapter: {
|
|
106
140
|
forceStartWithInconsistentAdapterConfiguration: options.startWithInconsistent
|
|
107
141
|
},
|
|
108
142
|
legacy : false,
|
|
109
143
|
|
|
110
144
|
};
|
|
145
|
+
// detect net port and rebuild
|
|
146
|
+
const tcpPort = utils.getNetAddress(herdsmanSettings.serialPort.path);
|
|
147
|
+
if (tcpPort && tcpPort.host)
|
|
148
|
+
herdsmanSettings.serialPort.path = `tcp://${tcpPort.host}:${tcpPort.port ? tcpPort.port : 80}`;
|
|
111
149
|
// https://github.com/ioBroker/ioBroker.zigbee/issues/668
|
|
112
150
|
if (!options.extPanIdFix) {
|
|
113
151
|
delete herdsmanSettings.network.extendedPanID;
|
|
114
152
|
herdsmanSettings.network.extenedPanID = options.net.extPanId;
|
|
115
153
|
}
|
|
116
154
|
|
|
117
|
-
if (options.transmitPower
|
|
118
|
-
|
|
119
|
-
} else {
|
|
120
|
-
this.transmitPower = options.transmitPower;
|
|
155
|
+
if (options.transmitPower != undefined) {
|
|
156
|
+
herdsmanSettings.transmitPower = options.transmitPower;
|
|
121
157
|
}
|
|
122
158
|
this.disableLed = options.disableLed;
|
|
123
159
|
this.warnOnDeviceAnnouncement = options.warnOnDeviceAnnouncement;
|
|
124
160
|
this.herdsmanLogSettings.panID = herdsmanSettings.network.panID;
|
|
125
161
|
this.herdsmanLogSettings.channel = herdsmanSettings.network.channelList[0];
|
|
126
|
-
this.herdsmanLogSettings.extendedPanID =
|
|
162
|
+
this.herdsmanLogSettings.extendedPanID = utils.byteArrayToString(herdsmanSettings.network.extendedPanID);
|
|
127
163
|
this.herdsman = new ZigbeeHerdsman.Controller(herdsmanSettings, this.adapter.log);
|
|
128
164
|
this.callExtensionMethod('setOptions', [{
|
|
129
165
|
disableActivePing: options.disablePing,
|
|
@@ -133,11 +169,23 @@ class ZigbeeController extends EventEmitter {
|
|
|
133
169
|
}]);
|
|
134
170
|
}
|
|
135
171
|
|
|
172
|
+
async stopHerdsman() {
|
|
173
|
+
try {
|
|
174
|
+
this.emit('pairing', 'stopping zigbee-herdsman');
|
|
175
|
+
await this.herdsman.stop();
|
|
176
|
+
this.emit('pairing', 'herdsman stopped !');
|
|
177
|
+
this.herdsmanStarted = false;
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
this.emit('pairing', `error stopping zigbee-herdsman: ${error && error.message ? error.message : 'no reason given'}`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
136
184
|
// Start controller
|
|
137
185
|
async start() {
|
|
138
186
|
try {
|
|
139
|
-
|
|
140
|
-
this.debug(`Starting zigbee-herdsman...`);
|
|
187
|
+
this.emit('pairing',`Starting zigbee-herdsman...`);
|
|
188
|
+
if (this.debugActive) this.debug(`Starting zigbee-herdsman...`);
|
|
141
189
|
|
|
142
190
|
// install event handlers before start
|
|
143
191
|
this.herdsman.on('adapterDisconnected', this.handleDisconnected.bind(this));
|
|
@@ -151,44 +199,45 @@ class ZigbeeController extends EventEmitter {
|
|
|
151
199
|
this.info('Starting Zigbee-Herdsman');
|
|
152
200
|
await this.herdsman.start();
|
|
153
201
|
this.herdsmanStarted = true;
|
|
154
|
-
|
|
202
|
+
const cv = await this.herdsman.getCoordinatorVersion();
|
|
203
|
+
const MetaSt = `${cv.meta.transportrev ? cv.meta.transportrev : 'X'}-${cv.meta.product ? cv.meta.product : 'X'}.${cv.meta.majorrel ? cv.meta.majorrel : 'X'}.${cv.meta.minorrel ? cv.meta.minorrel : 'X'}.${cv.meta.maintrel ? cv.meta.maintrel : 'X'}`;
|
|
204
|
+
const msg = `Zigbee-Herdsman started successfully with Coordinator firmware version: ${cv.type} : ${cv.meta.revision ? cv.meta.revision : ''} (${MetaSt})`;
|
|
205
|
+
this.emit('pairing',msg)
|
|
206
|
+
this.info(msg);
|
|
155
207
|
|
|
156
208
|
// debug info from herdsman getNetworkParameters
|
|
157
209
|
const debNetworkParam = JSON.parse(JSON.stringify(await this.herdsman.getNetworkParameters()));
|
|
158
210
|
const extendedPanIDDebug = typeof debNetworkParam.extendedPanID === 'string' ? debNetworkParam.extendedPanID.replace('0x', '') : debNetworkParam.extendedPanID;
|
|
159
211
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
extPanIDDebug += extendedPanIDDebug[i - 1];
|
|
163
|
-
extPanIDDebug += extendedPanIDDebug[i];
|
|
164
|
-
i--;
|
|
165
|
-
}
|
|
166
|
-
this.debug(`Network parameters: panID=${debNetworkParam.panID} channel=${debNetworkParam.channel} extendedPanID=${extPanIDDebug}`);
|
|
212
|
+
this.emit('pairing',`Network parameters: panID=${debNetworkParam.panID} channel=${debNetworkParam.channel} extendedPanID=${this.reverseIEEE(extendedPanIDDebug)}`);
|
|
213
|
+
if (this.debugActive) this.debug(`Network parameters: panID=${debNetworkParam.panID} channel=${debNetworkParam.channel} extendedPanID=${this.reverseIEEE(extendedPanIDDebug)}`);
|
|
167
214
|
} catch (e) {
|
|
168
215
|
try {
|
|
169
216
|
const debNetworkParam = JSON.parse(JSON.stringify(await this.herdsman.getNetworkParameters()));
|
|
170
217
|
const extendedPanIDDebug = typeof debNetworkParam.extendedPanID === 'string' ? debNetworkParam.extendedPanID.replace('0x', '') : debNetworkParam.extendedPanID;
|
|
171
218
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
this.warn(`Network parameters in Config : panID=${this.herdsmanLogSettings.panID} channel=${this.herdsmanLogSettings.channel} extendedPanID=${this.herdsmanLogSettings.extendedPanID}`)
|
|
179
|
-
this.warn(`Network parameters on Coordinator: panID=${debNetworkParam.panID} channel=${debNetworkParam.channel} extendedPanID=${extPanIDDebug}`);
|
|
219
|
+
const configParameters = `Network parameters in Config : panID=${this.herdsmanLogSettings.panID} channel=${this.herdsmanLogSettings.channel} extendedPanID=${this.reverseIEEE(this.herdsmanLogSettings.extendedPanID)}`;
|
|
220
|
+
const networkParameters = `Network parameters on Coordinator: panID=${debNetworkParam.panID} channel=${debNetworkParam.channel} extendedPanID=${this.reverseIEEE(extendedPanIDDebug)}`;
|
|
221
|
+
this.emit('pairing',configParameters)
|
|
222
|
+
this.emit('pairing',networkParameters);
|
|
223
|
+
this.warn(configParameters)
|
|
224
|
+
this.warn(networkParameters);
|
|
180
225
|
}
|
|
181
226
|
catch (error) {
|
|
182
|
-
this.
|
|
227
|
+
this.emit('pairing',`Unable to obtain herdsman settings`);
|
|
228
|
+
this.info(`Unable to obtain herdsman settings`)
|
|
183
229
|
}
|
|
184
230
|
try {
|
|
185
231
|
await this.herdsman.stop();
|
|
186
232
|
}
|
|
187
233
|
catch (error) {
|
|
234
|
+
this.emit('pairing','unable to stop zigbee-herdsman after failed startup');
|
|
188
235
|
this.warn('unable to stop zigbee-herdsman after failed startup');
|
|
189
236
|
}
|
|
190
237
|
this.sendError(e);
|
|
191
|
-
|
|
238
|
+
const msg = `Starting zigbee-herdsman problem : ${(e && e.message ? e.message : 'no error message')}`
|
|
239
|
+
this.error(msg);
|
|
240
|
+
this.emit('pairing', msg);
|
|
192
241
|
throw 'Error herdsman start';
|
|
193
242
|
}
|
|
194
243
|
// Check if we have to turn off the LED
|
|
@@ -201,48 +250,20 @@ class ZigbeeController extends EventEmitter {
|
|
|
201
250
|
}
|
|
202
251
|
} catch (e) {
|
|
203
252
|
this.info('Unable to disable LED, unsupported function.');
|
|
204
|
-
this.
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// only for CC1352P and CC26X2R1 transmit power
|
|
208
|
-
let powerText = 'normal';
|
|
209
|
-
|
|
210
|
-
if (this.transmitPower != '0') {
|
|
211
|
-
switch (this.transmitPower) {
|
|
212
|
-
case '-22':
|
|
213
|
-
powerText = 'low';
|
|
214
|
-
break;
|
|
215
|
-
case '19':
|
|
216
|
-
powerText = 'high';
|
|
217
|
-
break;
|
|
218
|
-
case '20':
|
|
219
|
-
powerText = 'high+';
|
|
220
|
-
break;
|
|
221
|
-
default:
|
|
222
|
-
powerText = 'normal';
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
this.info(` --> transmitPower : ${powerText}`);
|
|
228
|
-
try {
|
|
229
|
-
await this.herdsman.setTransmitPower(this.transmitPower);
|
|
230
|
-
} catch (e) {
|
|
231
|
-
this.sendError(e);
|
|
232
|
-
this.info('Unable to set transmit power, unsupported function.');
|
|
253
|
+
this.emit('pairing','Unable to disable LED, unsupported function.');
|
|
233
254
|
}
|
|
234
255
|
|
|
235
|
-
// Call extensions
|
|
236
|
-
|
|
237
256
|
const deviceIterator = this.getClientIterator();
|
|
238
257
|
let deviceCount = 0;
|
|
239
258
|
try {
|
|
259
|
+
//this.emit('pairing','identifying connected devices')
|
|
240
260
|
for (const device of deviceIterator) {
|
|
241
261
|
deviceCount++;
|
|
242
262
|
// get the model description for the known devices
|
|
243
263
|
const entity = await this.resolveEntity(device);
|
|
244
264
|
if (!entity) {
|
|
245
265
|
this.warn('failed to resolve Entity for ' + device.ieeeAddr);
|
|
266
|
+
//this.emit('pairing','failed to resolve Entity for ' + device.ieeeAddr)
|
|
246
267
|
continue;
|
|
247
268
|
}
|
|
248
269
|
//await this.adapter.stController.AddModelFromHerdsman(device, entity.mapped.model);
|
|
@@ -259,33 +280,37 @@ class ZigbeeController extends EventEmitter {
|
|
|
259
280
|
if (entity.mapped) {
|
|
260
281
|
this.emit('new', entity);
|
|
261
282
|
}
|
|
262
|
-
|
|
263
|
-
(entity.device.ieeeAddr) +
|
|
283
|
+
const msg = (entity.device.ieeeAddr +
|
|
264
284
|
` (addr ${entity.device.networkAddress}): ` +
|
|
265
|
-
(entity.mapped ?
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
);
|
|
285
|
+
(entity.mapped ? `${entity.mapped.model} - ${entity.mapped.vendor} ${entity.mapped.description} ` : `Unsupported (model ${entity.device.modelID})`) +
|
|
286
|
+
`(${entity.device.type})`);
|
|
287
|
+
//this.emit('pairing',msg);
|
|
288
|
+
this.info(msg);
|
|
270
289
|
}
|
|
271
290
|
|
|
272
291
|
// Log zigbee clients on startup
|
|
273
292
|
// const devices = await this.getClients();
|
|
274
293
|
if (deviceCount > 0) {
|
|
275
294
|
this.info(`Currently ${deviceCount} devices are joined:`);
|
|
295
|
+
this.emit('pairing',`Currently ${deviceCount} devices are joined:`)
|
|
276
296
|
} else {
|
|
277
|
-
this.info(`
|
|
297
|
+
this.info(`No devices are currently joined.`);
|
|
298
|
+
this.emit('pairing',`No devices are currently joined.`);
|
|
278
299
|
}
|
|
279
300
|
this.callExtensionMethod('onZigbeeStarted', []);
|
|
280
301
|
}
|
|
281
302
|
catch (error) {
|
|
282
|
-
|
|
303
|
+
const msg = 'error iterating devices : '+ (error && error.message ? error.message: 'no reason given');
|
|
304
|
+
this.error(msg);
|
|
305
|
+
this.emit('pairing',msg);
|
|
283
306
|
}
|
|
284
307
|
try {
|
|
285
308
|
this.getGroups();
|
|
286
309
|
}
|
|
287
310
|
catch (error) {
|
|
288
|
-
|
|
311
|
+
const msg = 'error iterating groups : '+ (error && error.message ? error.message: 'no reason given');
|
|
312
|
+
this.error(msg);
|
|
313
|
+
this.emit('pairing',msg);
|
|
289
314
|
}
|
|
290
315
|
this.emit('ready');
|
|
291
316
|
}
|
|
@@ -409,9 +434,9 @@ class ZigbeeController extends EventEmitter {
|
|
|
409
434
|
group = await this.herdsman.createGroup(nid);
|
|
410
435
|
group.toZigbee = groupConverters;
|
|
411
436
|
group.model = 'group';
|
|
412
|
-
this.debug(`verifyGroupExists: created group ${nid}`);
|
|
437
|
+
if (this.debugActive) this.debug(`verifyGroupExists: created group ${nid}`);
|
|
413
438
|
} else {
|
|
414
|
-
this.debug(`verifyGroupExists: group ${nid} exists`);
|
|
439
|
+
if (this.debugActive) this.debug(`verifyGroupExists: group ${nid} exists`);
|
|
415
440
|
}
|
|
416
441
|
return group
|
|
417
442
|
}
|
|
@@ -431,7 +456,7 @@ class ZigbeeController extends EventEmitter {
|
|
|
431
456
|
}
|
|
432
457
|
|
|
433
458
|
async addPairingCode(code) {
|
|
434
|
-
this.debug(`calling addPairingCode with ${code}`);
|
|
459
|
+
if (this.debugActive) this.debug(`calling addPairingCode with ${code}`);
|
|
435
460
|
if (code) {
|
|
436
461
|
try {
|
|
437
462
|
await this.herdsman.addInstallCode(code);
|
|
@@ -575,6 +600,7 @@ class ZigbeeController extends EventEmitter {
|
|
|
575
600
|
if (_key.kind === 'ieee') _key.key = await this.herdsman.getDeviceByIeeeAddr(_key.key);
|
|
576
601
|
const device = _key.key;
|
|
577
602
|
if (device) {
|
|
603
|
+
const t = Date.now();
|
|
578
604
|
const mapped = await zigbeeHerdsmanConverters.findByDevice(device);
|
|
579
605
|
const endpoints = mapped && mapped.endpoint ? mapped.endpoint(device) : null;
|
|
580
606
|
let endpoint;
|
|
@@ -609,15 +635,15 @@ class ZigbeeController extends EventEmitter {
|
|
|
609
635
|
|
|
610
636
|
async incMsgHandler(message) {
|
|
611
637
|
try {
|
|
612
|
-
this.debug('incoming msg', message);
|
|
638
|
+
if (this.debugActive) this.debug('incoming msg', message);
|
|
613
639
|
const device = await this.herdsman.getDeviceByIeeeAddr(message.srcaddr);
|
|
614
640
|
if (!device) {
|
|
615
|
-
this.debug('Message without device!');
|
|
641
|
+
if (this.debugActive) this.debug('Message without device!');
|
|
616
642
|
return;
|
|
617
643
|
}
|
|
618
644
|
// We can't handle devices without modelId.
|
|
619
645
|
if (!device.modelId) {
|
|
620
|
-
this.debug('Message without modelId!');
|
|
646
|
+
if (this.debugActive) this.debug('Message without modelId!');
|
|
621
647
|
return;
|
|
622
648
|
}
|
|
623
649
|
this.event('msg', device.ieeeAddr, message, {
|
|
@@ -640,8 +666,9 @@ class ZigbeeController extends EventEmitter {
|
|
|
640
666
|
}
|
|
641
667
|
|
|
642
668
|
try {
|
|
643
|
-
await this.permitJoin(0);
|
|
669
|
+
if (this.HerdsmanStarted) await this.permitJoin(0);
|
|
644
670
|
await this.herdsman.stop();
|
|
671
|
+
this.HerdsmanStarted = false;
|
|
645
672
|
} catch (error) {
|
|
646
673
|
this.sendError(error);
|
|
647
674
|
if (this.herdsmanStarted) {
|
|
@@ -675,7 +702,7 @@ class ZigbeeController extends EventEmitter {
|
|
|
675
702
|
async handlePermitJoinChanged(data)
|
|
676
703
|
{
|
|
677
704
|
try {
|
|
678
|
-
this.debug(`Event handlePermitJoinChanged received with ${JSON.stringify(data)}`);
|
|
705
|
+
if (this.debugActive) this.debug(`Event handlePermitJoinChanged received with ${JSON.stringify(data)}`);
|
|
679
706
|
if (data.permitted) {
|
|
680
707
|
if (!this._permitJoinInterval) {
|
|
681
708
|
this.emit('pairing',`Pairing possible for ${this._permitJoinTime} seconds`)
|
|
@@ -710,12 +737,12 @@ class ZigbeeController extends EventEmitter {
|
|
|
710
737
|
} catch (error) {
|
|
711
738
|
this.sendError(error);
|
|
712
739
|
if (error)
|
|
713
|
-
this.debug(`Failed to remove device. If device is remove is all fine, when not use Force remove`);
|
|
740
|
+
if (this.debugActive) this.debug(`Failed to remove device. If device is remove is all fine, when not use Force remove`);
|
|
714
741
|
// skip error if force
|
|
715
742
|
if (!force) {
|
|
716
743
|
throw error;
|
|
717
744
|
} else {
|
|
718
|
-
this.debug(`Force remove`);
|
|
745
|
+
if (this.debugActive) this.debug(`Force remove`);
|
|
719
746
|
}
|
|
720
747
|
}
|
|
721
748
|
|
|
@@ -725,9 +752,9 @@ class ZigbeeController extends EventEmitter {
|
|
|
725
752
|
this.sendError(error);
|
|
726
753
|
// skip error
|
|
727
754
|
if (error)
|
|
728
|
-
this.debug(`Failed to remove from DB ${error.stack}`);
|
|
755
|
+
if (this.debugActive) this.debug(`Failed to remove from DB ${error.stack}`);
|
|
729
756
|
}
|
|
730
|
-
this.debug('Remove successful.');
|
|
757
|
+
if (this.debugActive) this.debug('Remove successful.');
|
|
731
758
|
callback && callback();
|
|
732
759
|
this.callExtensionMethod(
|
|
733
760
|
'onDeviceRemove',
|
|
@@ -744,10 +771,14 @@ class ZigbeeController extends EventEmitter {
|
|
|
744
771
|
// Zigbee events
|
|
745
772
|
async handleDeviceLeave(message) {
|
|
746
773
|
try {
|
|
747
|
-
this.debug('handleDeviceLeave', message);
|
|
774
|
+
if (this.debugActive) this.debug('handleDeviceLeave', message);
|
|
748
775
|
const entity = await this.resolveEntity(message.device || message.ieeeAddr);
|
|
749
776
|
const friendlyName = entity ? entity.name : message.ieeeAddr;
|
|
750
|
-
this.
|
|
777
|
+
if (this.adapter.stController.checkDebugDevice(friendlyName)) {
|
|
778
|
+
this.emit('device_debug', {ID: Date.now(), data: {flag:'dl', states:[{id: '--', value:'--', payload:message}], IO:true},message:`Device '${friendlyName}' has left the network`});
|
|
779
|
+
}
|
|
780
|
+
else
|
|
781
|
+
this.info(`Device '${friendlyName}' left the network`);
|
|
751
782
|
this.emit('leave', message.ieeeAddr);
|
|
752
783
|
// Call extensions
|
|
753
784
|
this.callExtensionMethod(
|
|
@@ -761,10 +792,13 @@ class ZigbeeController extends EventEmitter {
|
|
|
761
792
|
}
|
|
762
793
|
|
|
763
794
|
async handleDeviceAnnounce(message) {
|
|
764
|
-
this.debug('handleDeviceAnnounce', message);
|
|
795
|
+
if (this.debugActive) this.debug('handleDeviceAnnounce', message);
|
|
765
796
|
const entity = await this.resolveEntity(message.device || message.ieeeAddr);
|
|
766
797
|
const friendlyName = entity.name;
|
|
767
|
-
if (this.
|
|
798
|
+
if (this.adapter.stController.checkDebugDevice(friendlyName)) {
|
|
799
|
+
this.emit('device_debug', {ID: Date.now(), data: {flag:'da', states:[{id: '--', value:'--', payload:message}] , IO:true} ,message:`Device '${friendlyName}' announced itself`});
|
|
800
|
+
}
|
|
801
|
+
else if (this.warnOnDeviceAnnouncement) {
|
|
768
802
|
this.warn(`Device '${friendlyName}' announced itself`);
|
|
769
803
|
} else {
|
|
770
804
|
this.info(`Device '${friendlyName}' announced itself`);
|
|
@@ -793,13 +827,13 @@ class ZigbeeController extends EventEmitter {
|
|
|
793
827
|
}
|
|
794
828
|
|
|
795
829
|
async handleDeviceJoined(message) {
|
|
796
|
-
this.debug('handleDeviceJoined', message);
|
|
830
|
+
if (this.debugActive) this.debug('handleDeviceJoined', message);
|
|
797
831
|
//const entity = await this.resolveEntity(message.device || message.ieeeAddr);
|
|
798
832
|
//this.emit('new', entity);
|
|
799
833
|
}
|
|
800
834
|
|
|
801
835
|
async handleDeviceInterview(message) {
|
|
802
|
-
this.debug('handleDeviceInterview', message);
|
|
836
|
+
if (this.debugActive) this.debug('handleDeviceInterview', message);
|
|
803
837
|
// safeguard: We do not allow to start an interview if the network is not opened
|
|
804
838
|
if (message.status === 'started' && !this.herdsman.getPermitJoin()) {
|
|
805
839
|
this.warn(`Blocked interview for '${message.ieeeAddr}' because the network is closed`);
|
|
@@ -827,7 +861,7 @@ class ZigbeeController extends EventEmitter {
|
|
|
827
861
|
[message, entity ? entity.mapped : null],
|
|
828
862
|
);
|
|
829
863
|
} else {
|
|
830
|
-
this.debug(
|
|
864
|
+
if (this.debugActive) this.debug(
|
|
831
865
|
`Device '${friendlyName}' with Zigbee model '${message.device.modelID}' is NOT supported, ` +
|
|
832
866
|
`please follow https://www.zigbee2mqtt.io/how_tos/how_to_support_new_devices.html`
|
|
833
867
|
);
|
|
@@ -853,10 +887,10 @@ class ZigbeeController extends EventEmitter {
|
|
|
853
887
|
}
|
|
854
888
|
|
|
855
889
|
async handleMessage(data) {
|
|
856
|
-
this.debug(`handleMessage`, data);
|
|
890
|
+
if (this.debugActive) this.debug(`handleMessage`, data);
|
|
857
891
|
const entity = await this.resolveEntity(data.device || data.ieeeAddr);
|
|
858
892
|
const name = (entity && entity._modelID) ? entity._modelID : data.device.ieeeAddr;
|
|
859
|
-
this.debug(
|
|
893
|
+
if (this.debugActive) this.debug(
|
|
860
894
|
`Received Zigbee message from '${name}', type '${data.type}', cluster '${data.cluster}'` +
|
|
861
895
|
`, data '${JSON.stringify(data.data)}' from endpoint ${data.endpoint.ID}` +
|
|
862
896
|
(data.hasOwnProperty('groupID') ? ` with groupID ${data.groupID}` : ``)
|
|
@@ -883,7 +917,7 @@ class ZigbeeController extends EventEmitter {
|
|
|
883
917
|
let resolved = await this.resolveEntity(device, 0);
|
|
884
918
|
if (!resolved) {
|
|
885
919
|
resolved = { name:'unresolved device', device:device }
|
|
886
|
-
this.
|
|
920
|
+
if (this.debugActive) this.debug('resolve Entity failed for ' + device.ieeeAddr)
|
|
887
921
|
}
|
|
888
922
|
let result;
|
|
889
923
|
|
|
@@ -943,9 +977,9 @@ class ZigbeeController extends EventEmitter {
|
|
|
943
977
|
|
|
944
978
|
callback && callback({lqis, routing, errors});
|
|
945
979
|
if (errors.length) {
|
|
946
|
-
this.
|
|
980
|
+
if (this.debugActive) this.debug(`Map Data collection complete with ${errors.length} issues:`);
|
|
947
981
|
for (const msg of errors)
|
|
948
|
-
this.
|
|
982
|
+
if (this.debugActive) this.debug(msg);
|
|
949
983
|
}
|
|
950
984
|
else
|
|
951
985
|
this.info('Map data collection complete');
|
|
@@ -973,7 +1007,7 @@ class ZigbeeController extends EventEmitter {
|
|
|
973
1007
|
return;
|
|
974
1008
|
}
|
|
975
1009
|
|
|
976
|
-
this.debug(`Zigbee publish to '${deviceID}', ${cid} - cmd ${cmd} - payload ${JSON.stringify(zclData)} - cfg ${JSON.stringify(cfg)} - endpoint ${ep}`);
|
|
1010
|
+
if (this.debugActive) this.debug(`Zigbee publish to '${deviceID}', ${cid} - cmd ${cmd} - payload ${JSON.stringify(zclData)} - cfg ${JSON.stringify(cfg)} - endpoint ${ep}`);
|
|
977
1011
|
|
|
978
1012
|
if (cfg == null) {
|
|
979
1013
|
cfg = {};
|
|
@@ -1012,23 +1046,23 @@ class ZigbeeController extends EventEmitter {
|
|
|
1012
1046
|
|
|
1013
1047
|
async addDevToGroup(devId, groupId, epid) {
|
|
1014
1048
|
try {
|
|
1015
|
-
this.debug(`called addDevToGroup with ${devId}, ${groupId}, ${epid}`);
|
|
1049
|
+
if (this.debugActive) this.debug(`called addDevToGroup with ${devId}, ${groupId}, ${epid}`);
|
|
1016
1050
|
const entity = await this.resolveEntity(devId);
|
|
1017
1051
|
const group = await this.resolveEntity(groupId);
|
|
1018
|
-
this.debug(`addDevFromGroup - entity: ${utils.getEntityInfo(entity)}`);
|
|
1052
|
+
if (this.debugActive) this.debug(`addDevFromGroup - entity: ${utils.getEntityInfo(entity)}`);
|
|
1019
1053
|
// generate group debug info and display it
|
|
1020
1054
|
const members = await this.getGroupMembersFromController(groupId);
|
|
1021
1055
|
const memberIDs = [];
|
|
1022
1056
|
for (const member of members) {
|
|
1023
1057
|
memberIDs.push(member.ieee);
|
|
1024
1058
|
}
|
|
1025
|
-
this.debug(`addDevToGroup ${groupId} with ${memberIDs.length} members ${safeJsonStringify(memberIDs)}`);
|
|
1059
|
+
if (this.debugActive) this.debug(`addDevToGroup ${groupId} with ${memberIDs.length} members ${safeJsonStringify(memberIDs)}`);
|
|
1026
1060
|
if (epid != undefined) {
|
|
1027
1061
|
for (const ep of entity.endpoints) {
|
|
1028
|
-
this.debug(`checking ep ${ep.ID} of ${devId} (${epid})`);
|
|
1062
|
+
if (this.debugActive) this.debug(`checking ep ${ep.ID} of ${devId} (${epid})`);
|
|
1029
1063
|
if (ep.ID == epid) {
|
|
1030
1064
|
if (ep.inputClusters.includes(4) || ep.outputClusters.includes(4)) {
|
|
1031
|
-
this.debug(`adding endpoint ${ep.ID} (${epid}) to group ${groupId}`);
|
|
1065
|
+
if (this.debugActive) this.debug(`adding endpoint ${ep.ID} (${epid}) to group ${groupId}`);
|
|
1032
1066
|
await (ep.addToGroup(group.mapped));
|
|
1033
1067
|
}
|
|
1034
1068
|
else this.error(`cluster genGroups not supported for endpoint ${epid} of ${devId}`);
|
|
@@ -1061,25 +1095,15 @@ class ZigbeeController extends EventEmitter {
|
|
|
1061
1095
|
}
|
|
1062
1096
|
|
|
1063
1097
|
async removeDevFromGroup(devId, groupId, epid) {
|
|
1064
|
-
this.debug(`removeDevFromGroup with ${devId}, ${groupId}, ${epid}`);
|
|
1098
|
+
if (this.debugActive) this.debug(`removeDevFromGroup with ${devId}, ${groupId}, ${epid}`);
|
|
1065
1099
|
let entity;
|
|
1066
1100
|
try {
|
|
1067
1101
|
entity = await this.resolveEntity(devId);
|
|
1068
1102
|
const group = await this.resolveEntity(groupId);
|
|
1069
1103
|
|
|
1070
|
-
/*
|
|
1071
|
-
const members = await this.getGroupMembersFromController(groupId);
|
|
1072
|
-
const memberIDs = [];
|
|
1073
|
-
for (const member of members) {
|
|
1074
|
-
memberIDs.push(member.ieee);
|
|
1075
|
-
}
|
|
1076
|
-
|
|
1077
|
-
this.debug(`removeDevFromGroup - entity: ${utils.getEntityInfo(entity)}`);
|
|
1078
|
-
this.debug(`removeDevFromGroup ${groupId} with ${memberIDs.length} members ${safeJsonStringify(memberIDs)}`);
|
|
1079
|
-
*/
|
|
1080
1104
|
if (epid != undefined) {
|
|
1081
1105
|
for (const ep of entity.endpoints) {
|
|
1082
|
-
this.debug(`checking ep ${ep.ID} of ${devId} (${epid})`);
|
|
1106
|
+
if (this.debugActive) this.debug(`checking ep ${ep.ID} of ${devId} (${epid})`);
|
|
1083
1107
|
if (ep.ID == epid && (ep.inputClusters.includes(4) || ep.outputClusters.includes(4))) {
|
|
1084
1108
|
await ep.removeFromGroup(group.mapped);
|
|
1085
1109
|
this.info(`removing endpoint ${ep.ID} of ${devId} from group ${groupId}`);
|
|
@@ -1101,7 +1125,7 @@ class ZigbeeController extends EventEmitter {
|
|
|
1101
1125
|
async removeDevFromAllGroups(devId) {
|
|
1102
1126
|
try {
|
|
1103
1127
|
const entity = await this.resolveEntity(devId);
|
|
1104
|
-
this.debug(`entity: ${safeJsonStringify(entity)}`);
|
|
1128
|
+
if (this.debugActive) this.debug(`entity: ${safeJsonStringify(entity)}`);
|
|
1105
1129
|
for (const ep of entity.endpoints) {
|
|
1106
1130
|
if (ep.inputClusters.includes(4) || ep.outputClusters.includes(4)) {
|
|
1107
1131
|
await ep.removefromAllGroups();
|
|
@@ -1119,14 +1143,14 @@ class ZigbeeController extends EventEmitter {
|
|
|
1119
1143
|
const log = ` ${ep.device.ieeeAddr} - ${cluster}`;
|
|
1120
1144
|
target = !target ? this.getCoordinator() : target;
|
|
1121
1145
|
|
|
1122
|
-
this.debug(`Binding ${log}`);
|
|
1146
|
+
if (this.debugActive) this.debug(`Binding ${log}`);
|
|
1123
1147
|
try {
|
|
1124
1148
|
ep.bind(cluster, target, error => {
|
|
1125
1149
|
if (error) {
|
|
1126
1150
|
this.sendError(error);
|
|
1127
1151
|
this.error(`Failed to bind ${log} - (${error})`);
|
|
1128
1152
|
} else {
|
|
1129
|
-
this.debug(`Successfully bound ${log}`);
|
|
1153
|
+
if (this.debugActive) this.debug(`Successfully bound ${log}`);
|
|
1130
1154
|
}
|
|
1131
1155
|
|
|
1132
1156
|
callback(error);
|
|
@@ -1141,13 +1165,13 @@ class ZigbeeController extends EventEmitter {
|
|
|
1141
1165
|
const log = ` ${ep.device.ieeeAddr} - ${cluster}`;
|
|
1142
1166
|
target = !target ? this.getCoordinator() : target;
|
|
1143
1167
|
|
|
1144
|
-
this.debug(`Unbinding ${log}`);
|
|
1168
|
+
if (this.debugActive) this.debug(`Unbinding ${log}`);
|
|
1145
1169
|
try {
|
|
1146
1170
|
ep.unbind(cluster, target, (error) => {
|
|
1147
1171
|
if (error) {
|
|
1148
1172
|
this.error(`Failed to unbind ${log} - (${error})`);
|
|
1149
1173
|
} else {
|
|
1150
|
-
this.debug(`Successfully unbound ${log}`);
|
|
1174
|
+
if (this.debugActive) this.debug(`Successfully unbound ${log}`);
|
|
1151
1175
|
}
|
|
1152
1176
|
|
|
1153
1177
|
callback(error);
|
|
@@ -1186,9 +1210,9 @@ class ZigbeeController extends EventEmitter {
|
|
|
1186
1210
|
{
|
|
1187
1211
|
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);
|
|
1188
1212
|
const scanresult = await this.herdsman.adapter.sendZdo(0x0, 0x0, clusterId , payload, false);
|
|
1189
|
-
this.debug(`scanresult is ${JSON.stringify(scanresult)}`)
|
|
1213
|
+
if (this.debugActive) this.debug(`scanresult is ${JSON.stringify(scanresult)}`)
|
|
1190
1214
|
result.energyvalues = scanresult[1].entryList;
|
|
1191
|
-
this.debug(`result is ${JSON.stringify(result)}`)
|
|
1215
|
+
if (this.debugActive) this.debug(`result is ${JSON.stringify(result)}`)
|
|
1192
1216
|
}
|
|
1193
1217
|
catch (error) {
|
|
1194
1218
|
this.sendError(error);
|