iobroker.sonoff 2.4.5 → 2.5.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/.github/workflows/test-and-release.yml +3 -3
- package/.mocharc.json +5 -0
- package/.releaseconfig.json +3 -0
- package/LICENSE +1 -1
- package/README.md +22 -1
- package/admin/words.js +6 -6
- package/io-package.json +186 -318
- package/lib/datapoints.js +1 -1
- package/lib/server.js +114 -98
- package/package.json +9 -7
package/lib/server.js
CHANGED
|
@@ -103,7 +103,7 @@ function hsvToRgb(h, s, v) {
|
|
|
103
103
|
|
|
104
104
|
function componentToHex(c) {
|
|
105
105
|
const hex = c.toString(16);
|
|
106
|
-
return hex.length === 1 ?
|
|
106
|
+
return hex.length === 1 ? `0${hex}` : hex;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
function toPaddedHexString(num, len) {
|
|
@@ -113,6 +113,7 @@ function toPaddedHexString(num, len) {
|
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
115
|
const str = num.toString(16);
|
|
116
|
+
if (str.length >= len) return str;
|
|
116
117
|
return '0'.repeat(len - str.length) + str;
|
|
117
118
|
}
|
|
118
119
|
|
|
@@ -187,10 +188,10 @@ function MQTTServer(adapter) {
|
|
|
187
188
|
function setColor(channelId, val) {
|
|
188
189
|
//adapter.log.info('color write: '+ val);
|
|
189
190
|
const stateId = 'Color';
|
|
190
|
-
if (clients[channelId]._map && clients[channelId]._map[stateId]) {
|
|
191
|
+
if (clients[channelId] && clients[channelId]._map && clients[channelId]._map[stateId]) {
|
|
191
192
|
setImmediate(sendState2Client, clients[channelId], clients[channelId]._map[stateId] || 'cmnd/sonoff/Color', val, adapter.config.defaultQoS);
|
|
192
|
-
} else if (clients[channelId]._fallBackName) {
|
|
193
|
-
setImmediate(sendState2Client, clients[channelId],
|
|
193
|
+
} else if (clients[channelId] && clients[channelId]._fallBackName) {
|
|
194
|
+
setImmediate(sendState2Client, clients[channelId], `cmnd/${clients[channelId]._fallBackName}/${stateId}`, val, adapter.config.defaultQoS);
|
|
194
195
|
} else {
|
|
195
196
|
adapter.log.warn(`Unknown mapping for "${stateId}"`);
|
|
196
197
|
}
|
|
@@ -204,15 +205,15 @@ function MQTTServer(adapter) {
|
|
|
204
205
|
if (clients[channelId]._map && clients[channelId]._map[stateId]) {
|
|
205
206
|
setImmediate(sendState2Client, clients[channelId], clients[channelId]._map[stateId] || 'cmnd/sonoff/POWER', val ? 'ON' : 'OFF', adapter.config.defaultQoS);
|
|
206
207
|
} else if (clients[channelId]._fallBackName) {
|
|
207
|
-
setImmediate(sendState2Client, clients[channelId],
|
|
208
|
+
setImmediate(sendState2Client, clients[channelId], `cmnd/${clients[channelId]._fallBackName}/${stateId}`, val, adapter.config.defaultQoS);
|
|
208
209
|
} else {
|
|
209
210
|
adapter.log.warn(`Unknown mapping for "${stateId}"`);
|
|
210
211
|
}
|
|
211
212
|
}
|
|
212
213
|
|
|
213
|
-
function setStateImmediate(channelId,stateId,val) {
|
|
214
|
+
function setStateImmediate(channelId, stateId, val) {
|
|
214
215
|
if (clients[channelId] && clients[channelId]._map && clients[channelId]._map[stateId]) {
|
|
215
|
-
setImmediate(sendState2Client, clients[channelId], clients[channelId]._map[stateId] || (
|
|
216
|
+
setImmediate(sendState2Client, clients[channelId], clients[channelId]._map[stateId] || (`cmnd/sonoff/${stateId}`), val, adapter.config.defaultQoS);
|
|
216
217
|
} else if (clients[channelId] && clients[channelId]._fallBackName) {
|
|
217
218
|
setImmediate(sendState2Client, clients[channelId], `cmnd/${clients[channelId]._fallBackName}/${stateId}`, val, adapter.config.defaultQoS);
|
|
218
219
|
} else {
|
|
@@ -252,12 +253,12 @@ function MQTTServer(adapter) {
|
|
|
252
253
|
stateId = parts.pop();
|
|
253
254
|
|
|
254
255
|
if (stateId === 'level' || stateId === 'state' || stateId === 'red' || stateId === 'blue' || stateId === 'green') {
|
|
255
|
-
stateId = parts.pop()
|
|
256
|
+
stateId = `${parts.pop()}.${stateId}`;
|
|
256
257
|
}
|
|
257
258
|
|
|
258
259
|
channelId = parts.splice(2, parts.length).join('.');
|
|
259
260
|
}
|
|
260
|
-
const ledModeIdExor = adapter.namespace
|
|
261
|
+
const ledModeIdExor = `${adapter.namespace}.${channelId}.modeLedExor`;
|
|
261
262
|
if (cachedModeExor[ledModeIdExor] === undefined) {
|
|
262
263
|
return adapter.getForeignState(ledModeIdExor, (err, _state) => {
|
|
263
264
|
cachedModeExor[ledModeIdExor] = _state ? _state.val || false : true;
|
|
@@ -279,7 +280,9 @@ function MQTTServer(adapter) {
|
|
|
279
280
|
// set white to rgb or rgbww
|
|
280
281
|
adapter.getObject(id, (err, obj) => {
|
|
281
282
|
if (!obj) {
|
|
282
|
-
adapter.log.warn(
|
|
283
|
+
adapter.log.warn(`invalid rgbww obj for ${id}`);
|
|
284
|
+
} if (typeof state.val !== 'string') {
|
|
285
|
+
adapter.log.warn(`invalid rgbww state value for ${id} : ${JSON.stringify(state.val)} needs to be a string`);
|
|
283
286
|
} else {
|
|
284
287
|
const role = obj.common.role;
|
|
285
288
|
let color;
|
|
@@ -290,13 +293,13 @@ function MQTTServer(adapter) {
|
|
|
290
293
|
if (state.val.toUpperCase() === '#FFFFFF') {
|
|
291
294
|
// transform white to WW
|
|
292
295
|
//color='000000FF';
|
|
293
|
-
color = state.val.substring(1)
|
|
296
|
+
color = `${state.val.substring(1)}00`;
|
|
294
297
|
} else {
|
|
295
298
|
// strip # char and add ww
|
|
296
|
-
color = state.val.substring(1)
|
|
299
|
+
color = `${state.val.substring(1)}00`;
|
|
297
300
|
}
|
|
298
301
|
} else if (role === 'level.color.rgbcwww') {
|
|
299
|
-
color = state.val.substring(1)
|
|
302
|
+
color = `${state.val.substring(1)}0000`;
|
|
300
303
|
} else {
|
|
301
304
|
// rgb, strip # char
|
|
302
305
|
color = state.val.substring(1);
|
|
@@ -310,25 +313,25 @@ function MQTTServer(adapter) {
|
|
|
310
313
|
|
|
311
314
|
// set rgb too
|
|
312
315
|
const hidE = id.split('.');
|
|
313
|
-
const deviceDesc = hidE[0]
|
|
314
|
-
let idAlive = deviceDesc
|
|
316
|
+
const deviceDesc = `${hidE[0]}.${hidE[1]}.${hidE[2]}`;
|
|
317
|
+
let idAlive = `${deviceDesc}.Red`;
|
|
315
318
|
adapter.setState(idAlive, 100 * parseInt(color.substring(0, 2), 16) / 255, true);
|
|
316
319
|
|
|
317
|
-
idAlive = deviceDesc
|
|
320
|
+
idAlive = `${deviceDesc}.Green`;
|
|
318
321
|
adapter.setState(idAlive, 100 * parseInt(color.substring(2, 4), 16) / 255, true);
|
|
319
322
|
|
|
320
|
-
idAlive = deviceDesc
|
|
323
|
+
idAlive = `${deviceDesc}.Blue`;
|
|
321
324
|
adapter.setState(idAlive, 100 * parseInt(color.substring(4, 6), 16) / 255, true);
|
|
322
325
|
}
|
|
323
326
|
});
|
|
324
327
|
} else {
|
|
325
328
|
const hidE = id.split('.');
|
|
326
|
-
const deviceDesc = hidE[0]
|
|
329
|
+
const deviceDesc = `${hidE[0]}.${hidE[1]}.${hidE[2]}`;
|
|
327
330
|
if (stateId.match(/Red\d?/)) {
|
|
328
331
|
// set red component
|
|
329
332
|
if (state.val > 100) state.val = 100;
|
|
330
333
|
const red = toPaddedHexString(Math.floor(255 * state.val / 100), 2);
|
|
331
|
-
const idAlive = deviceDesc
|
|
334
|
+
const idAlive = `${deviceDesc}.Color`;
|
|
332
335
|
adapter.getForeignState(idAlive, (err, state) => {
|
|
333
336
|
if (!state) {
|
|
334
337
|
adapter.setState(idAlive, '#000000', false);
|
|
@@ -337,7 +340,7 @@ function MQTTServer(adapter) {
|
|
|
337
340
|
const color = state.val.substring(1);
|
|
338
341
|
// replace red component
|
|
339
342
|
const out = red + color.substring(2, 10);
|
|
340
|
-
adapter.setState(idAlive,
|
|
343
|
+
adapter.setState(idAlive, `#${out}`, false);
|
|
341
344
|
setColor(channelId, out);
|
|
342
345
|
});
|
|
343
346
|
} else
|
|
@@ -345,7 +348,7 @@ function MQTTServer(adapter) {
|
|
|
345
348
|
// set green component
|
|
346
349
|
if (state.val > 100) state.val = 100;
|
|
347
350
|
const green = toPaddedHexString(Math.floor(255 * state.val / 100), 2);
|
|
348
|
-
const idAlive = deviceDesc
|
|
351
|
+
const idAlive = `${deviceDesc}.Color`;
|
|
349
352
|
adapter.getForeignState(idAlive, (err, state) => {
|
|
350
353
|
if (!state) {
|
|
351
354
|
adapter.setState(idAlive, '#000000', false);
|
|
@@ -354,7 +357,7 @@ function MQTTServer(adapter) {
|
|
|
354
357
|
const color = state.val.substring(1);
|
|
355
358
|
// replace green component
|
|
356
359
|
const out = color.substring(0, 2) + green + color.substring(4, 10);
|
|
357
|
-
adapter.setState(idAlive,
|
|
360
|
+
adapter.setState(idAlive, `#${out}`, false);
|
|
358
361
|
setColor(channelId, out);
|
|
359
362
|
});
|
|
360
363
|
} else
|
|
@@ -362,7 +365,7 @@ function MQTTServer(adapter) {
|
|
|
362
365
|
// set blue component
|
|
363
366
|
if (state.val > 100) state.val = 100;
|
|
364
367
|
const blue = toPaddedHexString(Math.floor(255 * state.val / 100), 2);
|
|
365
|
-
const idAlive = deviceDesc
|
|
368
|
+
const idAlive = `${deviceDesc}.Color`;
|
|
366
369
|
adapter.getForeignState(idAlive, (err, state) => {
|
|
367
370
|
if (!state) {
|
|
368
371
|
adapter.setState(idAlive, '#000000', false);
|
|
@@ -371,17 +374,17 @@ function MQTTServer(adapter) {
|
|
|
371
374
|
const color = state.val.substring(1);
|
|
372
375
|
// replace blue component
|
|
373
376
|
const out = color.substring(0, 4) + blue + color.substring(6, 10);
|
|
374
|
-
adapter.setState(idAlive,
|
|
377
|
+
adapter.setState(idAlive, `#${out}`, false);
|
|
375
378
|
setColor(channelId, out);
|
|
376
379
|
});
|
|
377
380
|
} else
|
|
378
381
|
if (stateId.match(/RGB_POWER\d?/)) {
|
|
379
382
|
// set ww component
|
|
380
383
|
const rgbpow = state.val === 'true' || state.val === true || state.val === 1 || state.val === '1';
|
|
381
|
-
const idAlive = deviceDesc
|
|
384
|
+
const idAlive = `${deviceDesc}.Color`;
|
|
382
385
|
adapter.getForeignState(idAlive, (err, state) => {
|
|
383
|
-
if (!state) {
|
|
384
|
-
|
|
386
|
+
if (!state || typeof state.val !== 'string') {
|
|
387
|
+
adapter.log.info(`invalid state Color for ${idAlive}, correcting value to #000000`);
|
|
385
388
|
adapter.setState(idAlive, '#000000', false);
|
|
386
389
|
return;
|
|
387
390
|
}
|
|
@@ -395,18 +398,18 @@ function MQTTServer(adapter) {
|
|
|
395
398
|
|
|
396
399
|
if (rgbpow && exorWhiteLeds) {
|
|
397
400
|
//adapter.log.info('reset white');
|
|
398
|
-
out = rgb
|
|
399
|
-
let idAlive = deviceDesc
|
|
401
|
+
out = `${rgb}0000`;
|
|
402
|
+
let idAlive = `${deviceDesc}.WW_POWER`;
|
|
400
403
|
adapter.setState(idAlive, false, false);
|
|
401
|
-
idAlive = deviceDesc
|
|
404
|
+
idAlive = `${deviceDesc}.WW`;
|
|
402
405
|
adapter.setState(idAlive, 0, false);
|
|
403
|
-
idAlive = deviceDesc
|
|
406
|
+
idAlive = `${deviceDesc}.CW_POWER`;
|
|
404
407
|
adapter.setState(idAlive, false, false);
|
|
405
|
-
idAlive = deviceDesc
|
|
408
|
+
idAlive = `${deviceDesc}.CW`;
|
|
406
409
|
adapter.setState(idAlive, 0, false);
|
|
407
410
|
}
|
|
408
411
|
setColor(channelId, out);
|
|
409
|
-
adapter.setState(idAlive,
|
|
412
|
+
adapter.setState(idAlive, `#${out}`, false);
|
|
410
413
|
if (rgbpow) {
|
|
411
414
|
setPower(channelId, true)
|
|
412
415
|
}
|
|
@@ -419,7 +422,7 @@ function MQTTServer(adapter) {
|
|
|
419
422
|
let hue = state.val;
|
|
420
423
|
if (hue > 359) hue = 359;
|
|
421
424
|
// recalc color by hue
|
|
422
|
-
const idAlive = deviceDesc
|
|
425
|
+
const idAlive = `${deviceDesc}.Dimmer`;
|
|
423
426
|
adapter.getForeignState(idAlive, (err, state) => {
|
|
424
427
|
if (!state) {
|
|
425
428
|
const dim = 100;
|
|
@@ -427,7 +430,7 @@ function MQTTServer(adapter) {
|
|
|
427
430
|
//adapter.log.warn('ill state Dimmer');
|
|
428
431
|
} else {
|
|
429
432
|
const dim = state.val;
|
|
430
|
-
let idAlive = deviceDesc
|
|
433
|
+
let idAlive = `${deviceDesc}.Saturation`;
|
|
431
434
|
adapter.getForeignState(idAlive, (err, state) => {
|
|
432
435
|
if (!state) {
|
|
433
436
|
const sat = 100;
|
|
@@ -436,8 +439,8 @@ function MQTTServer(adapter) {
|
|
|
436
439
|
const sat = state.val;
|
|
437
440
|
const rgb = hsvToRgb(hue, sat, dim);
|
|
438
441
|
const hexVal = componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]);
|
|
439
|
-
let idAlive = deviceDesc
|
|
440
|
-
adapter.setState(idAlive,
|
|
442
|
+
let idAlive = `${deviceDesc}.Color`;
|
|
443
|
+
adapter.setState(idAlive, `#${hexVal}`, false);
|
|
441
444
|
}
|
|
442
445
|
});
|
|
443
446
|
}
|
|
@@ -447,7 +450,7 @@ function MQTTServer(adapter) {
|
|
|
447
450
|
let sat = state.val;
|
|
448
451
|
if (sat > 100) sat = 100;
|
|
449
452
|
// recalc color by saturation
|
|
450
|
-
const idAlive = deviceDesc
|
|
453
|
+
const idAlive = `${deviceDesc}.Dimmer`;
|
|
451
454
|
adapter.getForeignState(idAlive, (err, state) => {
|
|
452
455
|
if (!state) {
|
|
453
456
|
const dim = 100;
|
|
@@ -455,7 +458,7 @@ function MQTTServer(adapter) {
|
|
|
455
458
|
//adapter.log.warn('ill state Dimmer');
|
|
456
459
|
} else {
|
|
457
460
|
const dim = state.val;
|
|
458
|
-
const idAlive = deviceDesc
|
|
461
|
+
const idAlive = `${deviceDesc}.Hue`;
|
|
459
462
|
adapter.getForeignState(idAlive, (err, state) => {
|
|
460
463
|
if (!state) {
|
|
461
464
|
const hue = 100;
|
|
@@ -464,15 +467,15 @@ function MQTTServer(adapter) {
|
|
|
464
467
|
const hue = state.val;
|
|
465
468
|
const rgb = hsvToRgb(hue, sat, dim);
|
|
466
469
|
const hexVal = componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]);
|
|
467
|
-
const idAlive = deviceDesc
|
|
468
|
-
adapter.setState(idAlive,
|
|
470
|
+
const idAlive = `${deviceDesc}.Color`;
|
|
471
|
+
adapter.setState(idAlive, `#${hexVal}`, false);
|
|
469
472
|
}
|
|
470
473
|
});
|
|
471
474
|
}
|
|
472
475
|
});
|
|
473
476
|
} else {
|
|
474
477
|
// get color attributes to check other ledstripe vars
|
|
475
|
-
const idAlive = deviceDesc
|
|
478
|
+
const idAlive = `${deviceDesc}.Color`;
|
|
476
479
|
adapter.getForeignObject(idAlive, (err, obj) => {
|
|
477
480
|
if (!obj) {
|
|
478
481
|
// no color object
|
|
@@ -490,7 +493,7 @@ function MQTTServer(adapter) {
|
|
|
490
493
|
if (stateId.match(/WW_POWER\d?/)) {
|
|
491
494
|
// set ww component
|
|
492
495
|
const wwpow = state.val === 'true' || state.val === true || state.val === 1 || state.val === '1';
|
|
493
|
-
const idAlive = deviceDesc
|
|
496
|
+
const idAlive = `${deviceDesc}.Color`;
|
|
494
497
|
adapter.getForeignState(idAlive, (err, state) => {
|
|
495
498
|
if (!state) {
|
|
496
499
|
adapter.log.warn('ill state Color');
|
|
@@ -505,17 +508,17 @@ function MQTTServer(adapter) {
|
|
|
505
508
|
let out = color.substring(0, wwindex) + ww;
|
|
506
509
|
if (wwpow && exorWhiteLeds) {
|
|
507
510
|
//adapter.log.info('reset white');
|
|
508
|
-
out =
|
|
509
|
-
let idAlive = deviceDesc
|
|
511
|
+
out = `000000${ww}`;
|
|
512
|
+
let idAlive = `${deviceDesc}.RGB_POWER`;
|
|
510
513
|
adapter.setState(idAlive,false, false);
|
|
511
514
|
}
|
|
512
515
|
|
|
513
|
-
let idAlive = deviceDesc
|
|
514
|
-
adapter.setState(idAlive
|
|
516
|
+
let idAlive = `${deviceDesc}.Color`;
|
|
517
|
+
adapter.setState(idAlive,`#${out}`, false);
|
|
515
518
|
setColor(channelId, out);
|
|
516
519
|
|
|
517
520
|
// set ww channel
|
|
518
|
-
idAlive = deviceDesc
|
|
521
|
+
idAlive = `${deviceDesc}.WW`;
|
|
519
522
|
adapter.setState(idAlive, 100 * parseInt(out.substring(6, 8), 16) / 255, true);
|
|
520
523
|
|
|
521
524
|
// in case POWER is off, switch it on
|
|
@@ -525,7 +528,7 @@ function MQTTServer(adapter) {
|
|
|
525
528
|
if (stateId.match(/CW_POWER\d?/)) {
|
|
526
529
|
// set ww component
|
|
527
530
|
const cwpow = state.val === 'true' || state.val === true || state.val === 1 || state.val === '1';
|
|
528
|
-
const idAlive = deviceDesc
|
|
531
|
+
const idAlive = `${deviceDesc}.Color`;
|
|
529
532
|
adapter.getForeignState(idAlive, (err, state) => {
|
|
530
533
|
if (!state) {
|
|
531
534
|
adapter.log.warn('ill state Color');
|
|
@@ -540,22 +543,22 @@ function MQTTServer(adapter) {
|
|
|
540
543
|
let out = color.substring(0, 6) + cw + color.substring(8, 10);
|
|
541
544
|
if (cwpow && exorWhiteLeds) {
|
|
542
545
|
//adapter.log.info('reset white');
|
|
543
|
-
out =
|
|
544
|
-
let idAlive = deviceDesc
|
|
546
|
+
out = `000000${cw}${color.substring(8, 10)}`;
|
|
547
|
+
let idAlive = `${deviceDesc}.RGB_POWER`;
|
|
545
548
|
adapter.setState(idAlive, false, false);
|
|
546
549
|
}
|
|
547
550
|
|
|
548
|
-
let idAlive = deviceDesc
|
|
549
|
-
adapter.setState(idAlive,
|
|
551
|
+
let idAlive = `${deviceDesc}.Color`;
|
|
552
|
+
adapter.setState(idAlive, `#${out}`, false);
|
|
550
553
|
setColor(channelId, out);
|
|
551
554
|
|
|
552
555
|
// set cw channel
|
|
553
|
-
idAlive = deviceDesc
|
|
556
|
+
idAlive = `${deviceDesc}.CW`;
|
|
554
557
|
adapter.setState(idAlive, 100 * parseInt(out.substring(6, 8), 16) / 255, true);
|
|
555
558
|
|
|
556
559
|
// in case POWER is off, switch it on
|
|
557
560
|
if (cwpow) {
|
|
558
|
-
let idAlive = deviceDesc
|
|
561
|
+
let idAlive = `${deviceDesc}.POWER`;
|
|
559
562
|
adapter.setState(idAlive, true, false);
|
|
560
563
|
}
|
|
561
564
|
});
|
|
@@ -563,7 +566,7 @@ function MQTTServer(adapter) {
|
|
|
563
566
|
if (stateId.match(/WW\d?/)) {
|
|
564
567
|
// set ww component
|
|
565
568
|
const ww = toPaddedHexString(Math.floor(255 * state.val / 100), 2);
|
|
566
|
-
const idAlive = deviceDesc
|
|
569
|
+
const idAlive = `${deviceDesc}.Color`;
|
|
567
570
|
adapter.getForeignState(idAlive, (err, state) => {
|
|
568
571
|
if (!state) {
|
|
569
572
|
adapter.setState(idAlive, '#000000', false);
|
|
@@ -578,7 +581,7 @@ function MQTTServer(adapter) {
|
|
|
578
581
|
if (stateId.match(/CW\d?/)) {
|
|
579
582
|
// set ww component
|
|
580
583
|
const cw = toPaddedHexString(Math.floor(255 * state.val / 100), 2);
|
|
581
|
-
const idAlive = deviceDesc
|
|
584
|
+
const idAlive = `${deviceDesc}.Color`;
|
|
582
585
|
adapter.getForeignState(idAlive, (err, state) => {
|
|
583
586
|
if (!state) {
|
|
584
587
|
adapter.setState(idAlive, '#000000', false);
|
|
@@ -617,15 +620,15 @@ function MQTTServer(adapter) {
|
|
|
617
620
|
setStateImmediate(mappingClients[channelId], stateId, state.val ? 'ON' : 'OFF');
|
|
618
621
|
break;
|
|
619
622
|
case 'number':
|
|
620
|
-
setStateImmediate(mappingClients[channelId], stateId, state.val.toString());
|
|
623
|
+
setStateImmediate(mappingClients[channelId], stateId, (state.val === null) ? '' : state.val.toString());
|
|
621
624
|
break;
|
|
622
625
|
case 'string':
|
|
623
|
-
setStateImmediate(mappingClients[channelId], stateId, state.val);
|
|
626
|
+
setStateImmediate(mappingClients[channelId], stateId, (state.val === null) ? '' : state.val.toString());
|
|
624
627
|
break;
|
|
625
628
|
}
|
|
626
629
|
}
|
|
627
630
|
});
|
|
628
|
-
} else {
|
|
631
|
+
} else if (state.val !== null) {
|
|
629
632
|
onStateChangedColors(id, state, channelId, stateId);
|
|
630
633
|
}
|
|
631
634
|
} else {
|
|
@@ -670,17 +673,17 @@ function MQTTServer(adapter) {
|
|
|
670
673
|
return;
|
|
671
674
|
}
|
|
672
675
|
let task = tasks[0];
|
|
673
|
-
adapter.log.debug(
|
|
676
|
+
adapter.log.debug(`process task: ${JSON.stringify(task)}`);
|
|
674
677
|
if (task.type === 'addObject') {
|
|
675
678
|
if (!cacheAddedObjects[task.id]) {
|
|
676
679
|
cacheAddedObjects[task.id] = true;
|
|
677
680
|
adapter.getForeignObject(task.id, (err, obj) => {
|
|
678
|
-
if (!obj) {
|
|
681
|
+
if (!obj || !obj.common) {
|
|
679
682
|
adapter.setForeignObject(task.id, task.data, (err) => {
|
|
680
683
|
if (err) {
|
|
681
|
-
adapter.log.warn(
|
|
684
|
+
adapter.log.warn(`New Object creation error: ${err.message}`)
|
|
682
685
|
} else {
|
|
683
|
-
adapter.log.info(
|
|
686
|
+
adapter.log.info(`new object created: ${task.id}`);
|
|
684
687
|
}
|
|
685
688
|
if (task.cb) {
|
|
686
689
|
task.cb(task.id, task.cbArg, () => {
|
|
@@ -695,9 +698,9 @@ function MQTTServer(adapter) {
|
|
|
695
698
|
} else if (obj.common.type !== task.data.common.type) {
|
|
696
699
|
adapter.extendObject(task.id, {common: {type: task.data.common.type}}, err => {
|
|
697
700
|
if (err) {
|
|
698
|
-
adapter.log.warn(
|
|
701
|
+
adapter.log.warn(`Object update error: ${err.message}`)
|
|
699
702
|
} else {
|
|
700
|
-
adapter.log.info(
|
|
703
|
+
adapter.log.info(`Object updated: ${task.id}`);
|
|
701
704
|
}
|
|
702
705
|
if (task.cb) {
|
|
703
706
|
task.cb(task.id, task.cbArg, () => {
|
|
@@ -757,7 +760,7 @@ function MQTTServer(adapter) {
|
|
|
757
760
|
}
|
|
758
761
|
});
|
|
759
762
|
} else {
|
|
760
|
-
adapter.log.error(
|
|
763
|
+
adapter.log.error(`Unknown task name: ${JSON.stringify(task)}`);
|
|
761
764
|
if (task.cb) {
|
|
762
765
|
task.cb(task.id, task.cbArg, () => {
|
|
763
766
|
tasks.shift();
|
|
@@ -775,7 +778,7 @@ function MQTTServer(adapter) {
|
|
|
775
778
|
// mqtt.0.stat.sonoff.POWER
|
|
776
779
|
let isStart = !tasks.length;
|
|
777
780
|
|
|
778
|
-
let id = adapter.namespace
|
|
781
|
+
let id = `${adapter.namespace}.${client.iobId}`;
|
|
779
782
|
let obj = {
|
|
780
783
|
_id: id,
|
|
781
784
|
common: {
|
|
@@ -790,13 +793,13 @@ function MQTTServer(adapter) {
|
|
|
790
793
|
tasks.push({type: 'addObject', id: obj._id, data: obj});
|
|
791
794
|
|
|
792
795
|
obj = {
|
|
793
|
-
_id: id
|
|
796
|
+
_id: `${id}.alive`,
|
|
794
797
|
common: {
|
|
795
798
|
type: 'boolean',
|
|
796
799
|
role: 'indicator.reachable',
|
|
797
800
|
read: true,
|
|
798
801
|
write: false,
|
|
799
|
-
name: client.id
|
|
802
|
+
name: `${client.id} alive`
|
|
800
803
|
},
|
|
801
804
|
type: 'state'
|
|
802
805
|
};
|
|
@@ -812,7 +815,7 @@ function MQTTServer(adapter) {
|
|
|
812
815
|
let text = '';
|
|
813
816
|
if (clients) {
|
|
814
817
|
for (let id in clients) {
|
|
815
|
-
text +=
|
|
818
|
+
text += `${text ? ',' : ''}${id}`;
|
|
816
819
|
}
|
|
817
820
|
}
|
|
818
821
|
|
|
@@ -820,7 +823,7 @@ function MQTTServer(adapter) {
|
|
|
820
823
|
}
|
|
821
824
|
|
|
822
825
|
function updateAlive(client, alive) {
|
|
823
|
-
let idAlive = adapter.namespace
|
|
826
|
+
let idAlive = `${adapter.namespace}.${client.iobId}.alive`;
|
|
824
827
|
|
|
825
828
|
adapter.getForeignState(idAlive, (err, state) => {
|
|
826
829
|
if (!state || state.val !== alive) {
|
|
@@ -869,7 +872,7 @@ function MQTTServer(adapter) {
|
|
|
869
872
|
|
|
870
873
|
function addObject(attr, client, prefix, path) {
|
|
871
874
|
let replaceAttr = types[attr].replace || attr;
|
|
872
|
-
let id = `${adapter.namespace}.${client.iobId}.${prefix ? prefix
|
|
875
|
+
let id = `${adapter.namespace}.${client.iobId}.${prefix ? `${prefix}.` : ''}${path.length ? `${path.join('_')}_` : ''}${replaceAttr.replace(FORBIDDEN_CHARS, '_')}`;
|
|
873
876
|
let obj = {
|
|
874
877
|
type: 'addObject',
|
|
875
878
|
id: id,
|
|
@@ -880,7 +883,7 @@ function MQTTServer(adapter) {
|
|
|
880
883
|
type: 'state'
|
|
881
884
|
}
|
|
882
885
|
};
|
|
883
|
-
obj.data.common.name = `${client.id} ${prefix ? prefix
|
|
886
|
+
obj.data.common.name = `${client.id} ${prefix ? `${prefix} ` : ''}${path.length ? `${path.join(' ')} ` : ''} ${replaceAttr}`;
|
|
884
887
|
return obj;
|
|
885
888
|
}
|
|
886
889
|
|
|
@@ -889,7 +892,7 @@ function MQTTServer(adapter) {
|
|
|
889
892
|
return;
|
|
890
893
|
}
|
|
891
894
|
|
|
892
|
-
const ledModeReadColorsID = adapter.namespace
|
|
895
|
+
const ledModeReadColorsID = `${adapter.namespace}.${client.iobId}.modeReadColors`;
|
|
893
896
|
|
|
894
897
|
if (cachedReadColors[ledModeReadColorsID] === undefined) {
|
|
895
898
|
return adapter.getForeignState(ledModeReadColorsID, (err, state) => {
|
|
@@ -919,7 +922,7 @@ function MQTTServer(adapter) {
|
|
|
919
922
|
}
|
|
920
923
|
// define new object
|
|
921
924
|
let replaceAttr = attr.replace(FORBIDDEN_CHARS, '_') + i.toString();
|
|
922
|
-
let id = `${adapter.namespace}.${client.iobId}.${prefix ? prefix
|
|
925
|
+
let id = `${adapter.namespace}.${client.iobId}.${prefix ? `${prefix}.` : ''}${path.length ? `${path.join('_')}_` : ''}${replaceAttr}`;
|
|
923
926
|
let obj = {
|
|
924
927
|
type: 'addObject',
|
|
925
928
|
id: id,
|
|
@@ -930,7 +933,7 @@ function MQTTServer(adapter) {
|
|
|
930
933
|
type: 'state'
|
|
931
934
|
}
|
|
932
935
|
};
|
|
933
|
-
obj.data.common.name = `${client.id} ${prefix ? prefix
|
|
936
|
+
obj.data.common.name = `${client.id} ${prefix ? `${prefix} ` : ''}${path.length ? `${path.join(' ')} ` : ''} ${replaceAttr}`;
|
|
934
937
|
obj.data.common.type = typeof val;
|
|
935
938
|
if (!['number', 'string', 'boolean'].includes(obj.data.common.type)) {
|
|
936
939
|
obj.data.common.type = 'string';
|
|
@@ -947,7 +950,7 @@ function MQTTServer(adapter) {
|
|
|
947
950
|
let nPath = Object.assign([], path);
|
|
948
951
|
nPath.push(attr.replace(FORBIDDEN_CHARS, '_'));
|
|
949
952
|
if (adapter.config.OBJ_TREE) {
|
|
950
|
-
checkData(client, topic, prefix
|
|
953
|
+
checkData(client, topic, `${prefix}.${nPath}`, data[attr], unit);
|
|
951
954
|
} else {
|
|
952
955
|
checkData(client, topic, prefix, data[attr], unit, nPath);
|
|
953
956
|
}
|
|
@@ -962,7 +965,7 @@ function MQTTServer(adapter) {
|
|
|
962
965
|
|
|
963
966
|
if (obj.data.common.storeMap) {
|
|
964
967
|
delete obj.data.common.storeMap;
|
|
965
|
-
client._map[replaceAttr] = topic.replace(/$\w+\//, 'cmnd/').replace(/\/\w+$/,
|
|
968
|
+
client._map[replaceAttr] = topic.replace(/$\w+\//, 'cmnd/').replace(/\/\w+$/, `/${replaceAttr}`);
|
|
966
969
|
}
|
|
967
970
|
|
|
968
971
|
// adaptions for magichome tasmota
|
|
@@ -1052,7 +1055,7 @@ function MQTTServer(adapter) {
|
|
|
1052
1055
|
if (attr === 'Color') {
|
|
1053
1056
|
// add # char
|
|
1054
1057
|
if (allowReadColors) {
|
|
1055
|
-
val =
|
|
1058
|
+
val = `#${data[attr]}`;
|
|
1056
1059
|
}
|
|
1057
1060
|
} else {
|
|
1058
1061
|
val = data[attr];
|
|
@@ -1071,6 +1074,7 @@ function MQTTServer(adapter) {
|
|
|
1071
1074
|
// auto generate objects
|
|
1072
1075
|
if ((parts[0] === 'tele' && (
|
|
1073
1076
|
(adapter.config.TELE_SENSOR && parts[2] === 'SENSOR') ||
|
|
1077
|
+
(adapter.config.STAT_RESULT && parts[2] === 'RESULT') ||
|
|
1074
1078
|
(adapter.config.TELE_STATE && parts[2] === 'STATE'))) ||
|
|
1075
1079
|
(parts[0] === 'stat' &&
|
|
1076
1080
|
(adapter.config.STAT_RESULT && parts[2] === 'RESULT'))
|
|
@@ -1090,7 +1094,7 @@ function MQTTServer(adapter) {
|
|
|
1090
1094
|
}
|
|
1091
1095
|
|
|
1092
1096
|
let replaceAttr = attr ;
|
|
1093
|
-
let id = `${adapter.namespace}.${client.iobId}.${prefix ? prefix
|
|
1097
|
+
let id = `${adapter.namespace}.${client.iobId}.${prefix ? `${prefix}.` : ''}${path.length ? `${path.join('_')}_` : ''}${replaceAttr}`;
|
|
1094
1098
|
let obj = {
|
|
1095
1099
|
type: 'addObject',
|
|
1096
1100
|
id: id,
|
|
@@ -1101,7 +1105,7 @@ function MQTTServer(adapter) {
|
|
|
1101
1105
|
type: 'state'
|
|
1102
1106
|
}
|
|
1103
1107
|
};
|
|
1104
|
-
obj.data.common.name = `${client.id} ${prefix ? prefix
|
|
1108
|
+
obj.data.common.name = `${client.id} ${prefix ? `${prefix} ` : ''}${path.length ? `${path.join(' ')} ` : ''} ${replaceAttr}`;
|
|
1105
1109
|
updateState(obj, val);
|
|
1106
1110
|
}
|
|
1107
1111
|
}
|
|
@@ -1110,7 +1114,7 @@ function MQTTServer(adapter) {
|
|
|
1110
1114
|
|
|
1111
1115
|
function receivedTopic(packet, client) {
|
|
1112
1116
|
if (!packet) {
|
|
1113
|
-
return adapter.log.warn(
|
|
1117
|
+
return adapter.log.warn(`Empty packet received: ${JSON.stringify(packet)}`);
|
|
1114
1118
|
}
|
|
1115
1119
|
|
|
1116
1120
|
client.states = client.states || {};
|
|
@@ -1205,7 +1209,7 @@ function MQTTServer(adapter) {
|
|
|
1205
1209
|
checkData(client, packet.topic, NO_PREFIX, JSON.parse(val));
|
|
1206
1210
|
}
|
|
1207
1211
|
} catch (e) {
|
|
1208
|
-
adapter.log.warn(
|
|
1212
|
+
adapter.log.warn(`Cannot parse data "${stateId}": _${val}_ - ${e}`);
|
|
1209
1213
|
}
|
|
1210
1214
|
}
|
|
1211
1215
|
return;
|
|
@@ -1215,7 +1219,7 @@ function MQTTServer(adapter) {
|
|
|
1215
1219
|
// tele/sonoff/SENSOR = {"Time":"2017-10-05T17:43:19", "DS18x20":{"DS1":{"Type":"DS18B20", "Address":"28FF9A9876815022A", "Temperature":12.2}}, "TempUnit":"C"}
|
|
1216
1220
|
// tele/sonoff5/SENSOR = {"Time":"2017-10-03T14:02:25", "AM2301-14":{"Temperature":21.6, "Humidity":54.7}, "TempUnit":"C"}
|
|
1217
1221
|
// tele/sonoff/SENSOR = {"Time":"2018-02-23T17:36:59", "Analog0":298}
|
|
1218
|
-
if (parts[0] === 'tele' && stateId.match(/^(STATE|SENSOR|WAKEUP)\d?$/)) {
|
|
1222
|
+
if (parts[0] === 'tele' && stateId.match(/^(RESULT|STATE|SENSOR|WAKEUP)\d?$/)) {
|
|
1219
1223
|
try {
|
|
1220
1224
|
if (adapter.config.OBJ_TREE) {
|
|
1221
1225
|
if (stateId.match(/^(STATE)\d?$/)) {
|
|
@@ -1224,13 +1228,15 @@ function MQTTServer(adapter) {
|
|
|
1224
1228
|
checkData(client, packet.topic, 'SENSOR', JSON.parse(val));
|
|
1225
1229
|
} else if (stateId.match(/^(WAKEUP)\d?$/)) {
|
|
1226
1230
|
checkData(client, packet.topic, 'WAKEUP', JSON.parse(val));
|
|
1231
|
+
} else if (stateId.match(/^(RESULT)\d?$/)) {
|
|
1232
|
+
checkData(client, packet.topic, 'WAKEUP', JSON.parse(val));
|
|
1227
1233
|
}
|
|
1228
1234
|
} else {
|
|
1229
1235
|
checkData(client, packet.topic, NO_PREFIX, JSON.parse(val));
|
|
1230
1236
|
//adapter.log.warn('log sensor parse"' + stateId + '": _' + val);
|
|
1231
1237
|
}
|
|
1232
1238
|
} catch (e) {
|
|
1233
|
-
adapter.log.warn(
|
|
1239
|
+
adapter.log.warn(`Cannot parse data "${stateId}": _${val}_ - ${e}`);
|
|
1234
1240
|
}
|
|
1235
1241
|
} else if (parts[0] === 'tele' && stateId.match(/^INFO\d?$/)) {
|
|
1236
1242
|
// tele/SonoffPOW/INFO1 = {"Module":"Sonoff Pow", "Version":"5.8.0", "FallbackTopic":"SonoffPOW", "GroupTopic":"sonoffs"}
|
|
@@ -1239,14 +1245,14 @@ function MQTTServer(adapter) {
|
|
|
1239
1245
|
try {
|
|
1240
1246
|
checkData(client, packet.topic, 'INFO', JSON.parse(val));
|
|
1241
1247
|
} catch (e) {
|
|
1242
|
-
adapter.log.warn(
|
|
1248
|
+
adapter.log.warn(`Cannot parse data"${stateId}": _${val}_ - ${e}`);
|
|
1243
1249
|
}
|
|
1244
1250
|
} else if (parts[0] === 'tele' && stateId.match(/^(ENERGY)\d?$/)) {
|
|
1245
1251
|
// tele/sonoff_4ch/ENERGY = {"Time":"2017-10-02T19:24:32", "Total":1.753, "Yesterday":0.308, "Today":0.205, "Period":0, "Power":3, "Factor":0.12, "Voltage":221, "Current":0.097}
|
|
1246
1252
|
try {
|
|
1247
1253
|
checkData(client, packet.topic, 'ENERGY', JSON.parse(val));
|
|
1248
1254
|
} catch (e) {
|
|
1249
|
-
adapter.log.warn(
|
|
1255
|
+
adapter.log.warn(`Cannot parse data"${stateId}": _${val}_ - ${e}`);
|
|
1250
1256
|
}
|
|
1251
1257
|
} else if (types[stateId]) {
|
|
1252
1258
|
// /ESP_BOX/BM280/Pressure = 1010.09
|
|
@@ -1258,7 +1264,7 @@ function MQTTServer(adapter) {
|
|
|
1258
1264
|
// stat/sonoff/POWER
|
|
1259
1265
|
|
|
1260
1266
|
if (types[stateId]) {
|
|
1261
|
-
let id = adapter.namespace
|
|
1267
|
+
let id = `${adapter.namespace}.${client.iobId}.${stateId.replace(/[-.+\s]+/g, '_')}`;
|
|
1262
1268
|
let obj = {
|
|
1263
1269
|
type: 'addObject',
|
|
1264
1270
|
id: id,
|
|
@@ -1269,7 +1275,7 @@ function MQTTServer(adapter) {
|
|
|
1269
1275
|
type: 'state'
|
|
1270
1276
|
}
|
|
1271
1277
|
};
|
|
1272
|
-
obj.data.common.name = client.id
|
|
1278
|
+
obj.data.common.name = `${client.id} ${stateId}`;
|
|
1273
1279
|
|
|
1274
1280
|
// push only new objects
|
|
1275
1281
|
updateState(obj, () => {
|
|
@@ -1305,7 +1311,7 @@ function MQTTServer(adapter) {
|
|
|
1305
1311
|
}
|
|
1306
1312
|
});
|
|
1307
1313
|
} else {
|
|
1308
|
-
adapter.log.debug(
|
|
1314
|
+
adapter.log.debug(`Cannot process: ${packet.topic}`);
|
|
1309
1315
|
}
|
|
1310
1316
|
}
|
|
1311
1317
|
}
|
|
@@ -1402,7 +1408,7 @@ function MQTTServer(adapter) {
|
|
|
1402
1408
|
server.on('connection', stream => {
|
|
1403
1409
|
let client = mqtt(stream);
|
|
1404
1410
|
// Store unique connection identifier
|
|
1405
|
-
client.__secret = Date.now()
|
|
1411
|
+
client.__secret = `${Date.now()}_${Math.round(Math.random() * 10000)}`;
|
|
1406
1412
|
|
|
1407
1413
|
// client connected
|
|
1408
1414
|
client.on('connect', options => {
|
|
@@ -1415,8 +1421,11 @@ function MQTTServer(adapter) {
|
|
|
1415
1421
|
let oldClient = clients[client.id];
|
|
1416
1422
|
|
|
1417
1423
|
if (config.user) {
|
|
1424
|
+
if (options.password) {
|
|
1425
|
+
options.password = options.password.toString();
|
|
1426
|
+
}
|
|
1418
1427
|
if (config.user !== options.username ||
|
|
1419
|
-
config.pass !== options.password
|
|
1428
|
+
config.pass !== options.password) {
|
|
1420
1429
|
adapter.log.warn(`Client [${client.id}] has invalid password(${options.password}) or username(${options.username})`);
|
|
1421
1430
|
client.connack({returnCode: 4});
|
|
1422
1431
|
if (oldClient) {
|
|
@@ -1515,7 +1524,7 @@ function MQTTServer(adapter) {
|
|
|
1515
1524
|
// send PUBACK to client
|
|
1516
1525
|
client.puback({messageId: packet.messageId});
|
|
1517
1526
|
} else if (packet.qos === 2) {
|
|
1518
|
-
const pack = client._messages.find(e => e.messageId === packet.messageId);
|
|
1527
|
+
const pack = client._messages && client._messages.find(e => e.messageId === packet.messageId);
|
|
1519
1528
|
if (pack) {
|
|
1520
1529
|
// duplicate message => ignore
|
|
1521
1530
|
adapter.log.warn(`Client [${client.id}] Ignored duplicate message with ID: ${packet.messageId}`);
|
|
@@ -1554,7 +1563,7 @@ function MQTTServer(adapter) {
|
|
|
1554
1563
|
return false;
|
|
1555
1564
|
}
|
|
1556
1565
|
});
|
|
1557
|
-
if (pos !==
|
|
1566
|
+
if (pos !== null) {
|
|
1558
1567
|
client.pubrel({messageId: packet.messageId});
|
|
1559
1568
|
} else {
|
|
1560
1569
|
adapter.log.warn(`Client [${client.id}] Received pubrec on ${client.id} for unknown messageId ${packet.messageId}`);
|
|
@@ -1574,7 +1583,7 @@ function MQTTServer(adapter) {
|
|
|
1574
1583
|
|
|
1575
1584
|
let pos = null;
|
|
1576
1585
|
// remove this message from queue
|
|
1577
|
-
client._messages.forEach((e, i) => {
|
|
1586
|
+
client._messages && client._messages.forEach((e, i) => {
|
|
1578
1587
|
if (e.messageId === packet.messageId) {
|
|
1579
1588
|
pos = i;
|
|
1580
1589
|
return false;
|
|
@@ -1589,6 +1598,9 @@ function MQTTServer(adapter) {
|
|
|
1589
1598
|
|
|
1590
1599
|
// response for QoS2
|
|
1591
1600
|
client.on('pubrel', packet => {
|
|
1601
|
+
if (!client._messages) {
|
|
1602
|
+
return;
|
|
1603
|
+
}
|
|
1592
1604
|
if (clients[client.id] && client.__secret !== clients[client.id].__secret) {
|
|
1593
1605
|
!adapter.config.ignorePings && adapter.log.warn(`Old client ${client.id} with secret ${client.__secret} sends pubrel. Ignore! Actual secret is ${clients[client.id].__secret}`);
|
|
1594
1606
|
return;
|
|
@@ -1600,14 +1612,14 @@ function MQTTServer(adapter) {
|
|
|
1600
1612
|
|
|
1601
1613
|
let pos = null;
|
|
1602
1614
|
// remove this message from queue
|
|
1603
|
-
client._messages.forEach((e, i) => {
|
|
1615
|
+
client._messages && client._messages.forEach((e, i) => {
|
|
1604
1616
|
if (e.messageId === packet.messageId) {
|
|
1605
1617
|
pos = i;
|
|
1606
1618
|
return false;
|
|
1607
1619
|
}
|
|
1608
1620
|
});
|
|
1609
1621
|
|
|
1610
|
-
if (pos !==
|
|
1622
|
+
if (pos !== null) {
|
|
1611
1623
|
client.pubcomp({messageId: packet.messageId});
|
|
1612
1624
|
|
|
1613
1625
|
receivedTopic(client._messages[pos], client);
|
|
@@ -1690,6 +1702,10 @@ function MQTTServer(adapter) {
|
|
|
1690
1702
|
});
|
|
1691
1703
|
});
|
|
1692
1704
|
|
|
1705
|
+
server.on('error', err => {
|
|
1706
|
+
adapter.log.error(`Can not start Server ${err}`);
|
|
1707
|
+
});
|
|
1708
|
+
|
|
1693
1709
|
config.port = parseInt(config.port, 10) || 1883;
|
|
1694
1710
|
|
|
1695
1711
|
config.retransmitInterval = config.retransmitInterval || 2000;
|