homebridge-zwave-usb 2.0.2 → 2.0.4
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.
|
@@ -304,14 +304,20 @@ class ControllerAccessory {
|
|
|
304
304
|
this.exclusionService.updateCharacteristic(this.platform.Characteristic.On, false);
|
|
305
305
|
},
|
|
306
306
|
'heal network progress': (progress) => {
|
|
307
|
-
const
|
|
307
|
+
const doneCount = Array.from(progress.values()).filter((v) => v !== 0).length;
|
|
308
308
|
const total = progress.size;
|
|
309
|
-
this.statusChar.updateValue(`Heal: ${
|
|
309
|
+
this.statusChar.updateValue(`Heal: ${doneCount}/${total}`);
|
|
310
|
+
// Safety: If we hit 100%, and the 'done' event hasn't fired yet, we'll wait for it.
|
|
311
|
+
// But if it stays at 100% and we are still 'active', the 'heal network done' handler will take care of it.
|
|
310
312
|
},
|
|
311
313
|
'heal network done': () => {
|
|
312
|
-
this.platform.log.info('Controller event: Heal Network Done');
|
|
314
|
+
this.platform.log.info('Controller event: Heal Network Done. Resetting UI switch.');
|
|
313
315
|
this.isHealActive = false;
|
|
314
|
-
|
|
316
|
+
// Use a slight delay to ensure HomeKit UI catches the state change correctly
|
|
317
|
+
setTimeout(() => {
|
|
318
|
+
this.healService.updateCharacteristic(this.platform.Characteristic.On, false);
|
|
319
|
+
this.platform.log.debug('Heal Network switch set to OFF');
|
|
320
|
+
}, 500);
|
|
315
321
|
},
|
|
316
322
|
};
|
|
317
323
|
for (const [event, handler] of Object.entries(this.handlers)) {
|
|
@@ -393,7 +399,6 @@ class ControllerAccessory {
|
|
|
393
399
|
*/
|
|
394
400
|
this.platform.log.warn('Inclusion start request returned false (possibly already active). Keeping UI state ON.');
|
|
395
401
|
}
|
|
396
|
-
this.isInclusionActive = true;
|
|
397
402
|
this.inclusionTimer = setTimeout(async () => {
|
|
398
403
|
this.platform.log.info('Inclusion Mode timed out');
|
|
399
404
|
await this.controller.stopInclusion();
|
|
@@ -444,7 +449,6 @@ class ControllerAccessory {
|
|
|
444
449
|
if (!started) {
|
|
445
450
|
this.platform.log.warn('Exclusion start request returned false (possibly already active). Keeping UI state ON.');
|
|
446
451
|
}
|
|
447
|
-
this.isExclusionActive = true;
|
|
448
452
|
this.exclusionTimer = setTimeout(async () => {
|
|
449
453
|
this.platform.log.info('Exclusion Mode timed out');
|
|
450
454
|
await this.controller.stopExclusion();
|
|
@@ -490,7 +494,6 @@ class ControllerAccessory {
|
|
|
490
494
|
if (!started) {
|
|
491
495
|
this.platform.log.warn('Heal start request returned false (possibly already active). Keeping UI state ON.');
|
|
492
496
|
}
|
|
493
|
-
this.isHealActive = true;
|
|
494
497
|
}
|
|
495
498
|
else {
|
|
496
499
|
this.platform.log.info('Requesting Heal Network OFF');
|
|
@@ -25,6 +25,7 @@ export declare class ZWaveController extends EventEmitter implements IZWaveContr
|
|
|
25
25
|
private driver;
|
|
26
26
|
readonly nodes: Map<number, ZWaveNode>;
|
|
27
27
|
private pendingS2Pin;
|
|
28
|
+
private healSafetyTimer;
|
|
28
29
|
private nodeListeners;
|
|
29
30
|
private controllerListeners;
|
|
30
31
|
constructor(log: Logger, serialPort: string, options?: ZWaveControllerOptions);
|
|
@@ -19,6 +19,7 @@ class ZWaveController extends events_1.EventEmitter {
|
|
|
19
19
|
driver;
|
|
20
20
|
nodes = new Map();
|
|
21
21
|
pendingS2Pin;
|
|
22
|
+
healSafetyTimer;
|
|
22
23
|
nodeListeners = new Map();
|
|
23
24
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
24
25
|
controllerListeners = {};
|
|
@@ -75,9 +76,24 @@ class ZWaveController extends events_1.EventEmitter {
|
|
|
75
76
|
this.log.info(`Heal Network Progress: ${done}/${total} nodes completed`);
|
|
76
77
|
this.emit('status updated', `Heal: ${done}/${total}`);
|
|
77
78
|
this.emit('heal network progress', progress);
|
|
79
|
+
// Safety: if we are at 100%, but no 'done' event arrives within 5s, auto-complete
|
|
80
|
+
if (done === total && total > 0) {
|
|
81
|
+
if (this.healSafetyTimer) {
|
|
82
|
+
clearTimeout(this.healSafetyTimer);
|
|
83
|
+
}
|
|
84
|
+
this.healSafetyTimer = setTimeout(() => {
|
|
85
|
+
this.log.info('Heal Network Safety Timeout: Triggering completion.');
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
87
|
+
(this.driver?.controller).emit('rebuild routes done', new Map());
|
|
88
|
+
}, 5000);
|
|
89
|
+
}
|
|
78
90
|
},
|
|
79
91
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
80
92
|
'rebuild routes done': (result) => {
|
|
93
|
+
if (this.healSafetyTimer) {
|
|
94
|
+
clearTimeout(this.healSafetyTimer);
|
|
95
|
+
this.healSafetyTimer = undefined;
|
|
96
|
+
}
|
|
81
97
|
this.log.info('Heal Network Complete');
|
|
82
98
|
this.emit('status updated', 'Heal Network Done');
|
|
83
99
|
setTimeout(() => this.emit('status updated', 'Driver Ready'), 5000);
|
|
@@ -465,6 +481,10 @@ class ZWaveController extends events_1.EventEmitter {
|
|
|
465
481
|
}
|
|
466
482
|
async stop() {
|
|
467
483
|
this.log.debug('Stopping Z-Wave controller and cleaning up listeners...');
|
|
484
|
+
if (this.healSafetyTimer) {
|
|
485
|
+
clearTimeout(this.healSafetyTimer);
|
|
486
|
+
this.healSafetyTimer = undefined;
|
|
487
|
+
}
|
|
468
488
|
for (const [nodeId, node] of this.nodes) {
|
|
469
489
|
const listeners = this.nodeListeners.get(nodeId);
|
|
470
490
|
if (listeners) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-zwave-usb",
|
|
3
3
|
"displayName": "Homebridge Z-Wave USB",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.4",
|
|
5
5
|
"description": "A Homebridge dynamic platform plugin for Z-Wave USB controllers using zwave-js.",
|
|
6
6
|
"license": "Polyform-Noncommercial-1.0.0",
|
|
7
7
|
"funding": {
|