homebridge-zwave-usb 2.3.1 → 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/dist/accessories/ZWaveAccessory.d.ts +4 -0
- package/dist/accessories/ZWaveAccessory.js +18 -0
- package/dist/features/ZWaveFeature.d.ts +5 -0
- package/dist/features/ZWaveFeature.js +19 -0
- package/dist/platform/ZWaveUsbPlatform.js +7 -8
- package/dist/zwave/ZWaveController.js +2 -1
- package/package.json +1 -1
|
@@ -11,6 +11,10 @@ export declare class ZWaveAccessory {
|
|
|
11
11
|
private initialized;
|
|
12
12
|
constructor(platform: ZWaveUsbPlatform, node: IZWaveNode, homeId: number);
|
|
13
13
|
addFeature(feature: ZWaveFeature): void;
|
|
14
|
+
/**
|
|
15
|
+
* Syncs the HomeKit name and service names when the node is renamed.
|
|
16
|
+
*/
|
|
17
|
+
rename(newName: string): void;
|
|
14
18
|
/**
|
|
15
19
|
* HOT-RECOVERY FIX: Update stale node references.
|
|
16
20
|
* When the driver restarts (hot-plug), the IZWaveNode instance changes.
|
|
@@ -82,6 +82,24 @@ class ZWaveAccessory {
|
|
|
82
82
|
addFeature(feature) {
|
|
83
83
|
this.features.push(feature);
|
|
84
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Syncs the HomeKit name and service names when the node is renamed.
|
|
87
|
+
*/
|
|
88
|
+
rename(newName) {
|
|
89
|
+
this.platform.log.info(`Syncing HomeKit name for Node ${this.node.nodeId} -> ${newName}`);
|
|
90
|
+
this.platformAccessory.displayName = newName;
|
|
91
|
+
// Update the Model and Serial if they were using the generic name
|
|
92
|
+
const model = this.node.deviceConfig?.label || newName;
|
|
93
|
+
this.platformAccessory
|
|
94
|
+
.getService(this.platform.Service.AccessoryInformation)
|
|
95
|
+
.setCharacteristic(this.platform.Characteristic.Model, model);
|
|
96
|
+
// Update all features
|
|
97
|
+
for (const feature of this.features) {
|
|
98
|
+
feature.rename(newName);
|
|
99
|
+
}
|
|
100
|
+
// Notify Homebridge of changes
|
|
101
|
+
this.platform.api.updatePlatformAccessories([this.platformAccessory]);
|
|
102
|
+
}
|
|
85
103
|
/**
|
|
86
104
|
* HOT-RECOVERY FIX: Update stale node references.
|
|
87
105
|
* When the driver restarts (hot-plug), the IZWaveNode instance changes.
|
|
@@ -9,6 +9,7 @@ export interface ZWaveFeature {
|
|
|
9
9
|
getEndpointIndex(): number;
|
|
10
10
|
stop(): void;
|
|
11
11
|
updateNode(node: IZWaveNode, endpoint: Endpoint): void;
|
|
12
|
+
rename(newName: string): void;
|
|
12
13
|
}
|
|
13
14
|
export declare abstract class BaseFeature implements ZWaveFeature {
|
|
14
15
|
protected readonly platform: ZWaveUsbPlatform;
|
|
@@ -21,6 +22,10 @@ export declare abstract class BaseFeature implements ZWaveFeature {
|
|
|
21
22
|
abstract update(args?: ZWaveValueEvent): void;
|
|
22
23
|
stop(): void;
|
|
23
24
|
updateNode(node: IZWaveNode, endpoint: Endpoint): void;
|
|
25
|
+
/**
|
|
26
|
+
* Dynamically updates the Name characteristic of all managed services.
|
|
27
|
+
*/
|
|
28
|
+
rename(newName: string): void;
|
|
24
29
|
getServices(): Service[];
|
|
25
30
|
getEndpointIndex(): number;
|
|
26
31
|
/**
|
|
@@ -21,6 +21,20 @@ class BaseFeature {
|
|
|
21
21
|
this.node = node;
|
|
22
22
|
this.endpoint = endpoint;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Dynamically updates the Name characteristic of all managed services.
|
|
26
|
+
*/
|
|
27
|
+
rename(newName) {
|
|
28
|
+
const serviceName = this.endpoint.index > 0 ? `${newName} ${this.endpoint.index}` : newName;
|
|
29
|
+
for (const service of this.managedServices) {
|
|
30
|
+
if (service.testCharacteristic(this.platform.Characteristic.Name)) {
|
|
31
|
+
service.getCharacteristic(this.platform.Characteristic.Name).updateValue(serviceName);
|
|
32
|
+
}
|
|
33
|
+
if (service.testCharacteristic(this.platform.Characteristic.ConfiguredName)) {
|
|
34
|
+
service.getCharacteristic(this.platform.Characteristic.ConfiguredName).updateValue(serviceName);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
24
38
|
getServices() {
|
|
25
39
|
return this.managedServices;
|
|
26
40
|
}
|
|
@@ -76,6 +90,11 @@ class BaseFeature {
|
|
|
76
90
|
perms: [settings_1.HAPPerm.PAIRED_READ],
|
|
77
91
|
})
|
|
78
92
|
.updateValue(serviceName);
|
|
93
|
+
// Also set ConfiguredName which HomeKit often prioritizes for display
|
|
94
|
+
if (!service.testCharacteristic(this.platform.Characteristic.ConfiguredName)) {
|
|
95
|
+
service.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName);
|
|
96
|
+
}
|
|
97
|
+
service.getCharacteristic(this.platform.Characteristic.ConfiguredName).updateValue(serviceName);
|
|
79
98
|
// Add Service Label Index for multi-endpoint devices to help with ordering/naming
|
|
80
99
|
if (this.endpoint.index > 0) {
|
|
81
100
|
if (!service.testCharacteristic(this.platform.Characteristic.ServiceLabelIndex)) {
|
|
@@ -140,9 +140,7 @@ class ZWaveUsbPlatform {
|
|
|
140
140
|
// Update Homebridge Accessory Name
|
|
141
141
|
const accessory = this.zwaveAccessories.get(nodeId);
|
|
142
142
|
if (accessory) {
|
|
143
|
-
|
|
144
|
-
accessory.platformAccessory.displayName = name;
|
|
145
|
-
this.api.updatePlatformAccessories([accessory.platformAccessory]);
|
|
143
|
+
accessory.rename(name);
|
|
146
144
|
}
|
|
147
145
|
return sendJson({ success: true });
|
|
148
146
|
}
|
|
@@ -326,7 +324,8 @@ class ZWaveUsbPlatform {
|
|
|
326
324
|
this.log.info(`Node ${node.nodeId} added to the network. Waiting for interview to complete...`);
|
|
327
325
|
}
|
|
328
326
|
handleNodeReady(node) {
|
|
329
|
-
|
|
327
|
+
const nodeName = node.name || node.deviceConfig?.label || `Node ${node.nodeId}`;
|
|
328
|
+
this.log.info(`Node ${node.nodeId} (${nodeName}) ready`);
|
|
330
329
|
// Skip Node 1 (the controller itself) as it's handled by ControllerAccessory
|
|
331
330
|
if (Number(node.nodeId) === 1) {
|
|
332
331
|
this.log.info('System: Controller node (Node 1) identified. Skipping generic accessory creation.');
|
|
@@ -345,6 +344,9 @@ class ZWaveUsbPlatform {
|
|
|
345
344
|
if (existing || this.discoveryInFlight.has(node.nodeId)) {
|
|
346
345
|
if (existing) {
|
|
347
346
|
existing.updateNode(node);
|
|
347
|
+
if (existing.platformAccessory.displayName !== nodeName) {
|
|
348
|
+
existing.rename(nodeName);
|
|
349
|
+
}
|
|
348
350
|
existing.refresh();
|
|
349
351
|
}
|
|
350
352
|
return;
|
|
@@ -353,11 +355,8 @@ class ZWaveUsbPlatform {
|
|
|
353
355
|
try {
|
|
354
356
|
const accessory = AccessoryFactory_1.AccessoryFactory.create(this, node, homeId);
|
|
355
357
|
this.zwaveAccessories.set(node.nodeId, accessory);
|
|
356
|
-
const nodeName = node.name || node.deviceConfig?.label || `Node ${node.nodeId}`;
|
|
357
358
|
if (accessory.platformAccessory.displayName !== nodeName) {
|
|
358
|
-
|
|
359
|
-
accessory.platformAccessory.displayName = nodeName;
|
|
360
|
-
this.api.updatePlatformAccessories([accessory.platformAccessory]);
|
|
359
|
+
accessory.rename(nodeName);
|
|
361
360
|
}
|
|
362
361
|
accessory.initialize();
|
|
363
362
|
}
|
|
@@ -154,7 +154,8 @@ class ZWaveController extends events_1.EventEmitter {
|
|
|
154
154
|
*/
|
|
155
155
|
const statusMap = ['Unknown', 'Asleep', 'Awake', 'Dead', 'Alive'];
|
|
156
156
|
const status = statusMap[node.status] || node.status.toString();
|
|
157
|
-
|
|
157
|
+
const nodeName = node.name || node.deviceConfig?.label || `Node ${node.nodeId}`;
|
|
158
|
+
this.log.info(`Node ${node.nodeId} (${nodeName}) added to controller (Status: ${status}, Interview Stage: ${node.interviewStage})`);
|
|
158
159
|
const onReady = () => {
|
|
159
160
|
this.log.info(`Node ${node.nodeId} is ready (Interview Stage: ${node.interviewStage})`);
|
|
160
161
|
this.emit('status updated', `Node ${node.nodeId} Ready`);
|
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.
|
|
4
|
+
"version": "2.5.0",
|
|
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": {
|