node-red-contrib-zwave-js 7.0.0-alpha.21 → 7.0.0-alpha.24
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/CHANGELOG.md +8 -2
- package/package.json +1 -1
- package/zwave-js/zwave-device.js +13 -4
- package/zwave-js/zwave-js.js +35 -98
package/CHANGELOG.md
CHANGED
|
@@ -6,16 +6,22 @@
|
|
|
6
6
|
- The **GET_VALUE_RESPONSE** object is no longer partitioned with **response** and **valueId** properties.
|
|
7
7
|
Instead, the returned object now represents a shape simular to **VALUE_UPDATED** events.
|
|
8
8
|
The value will now be attached to the **currentValue** property, along with the Value ID on the same level.
|
|
9
|
-
-
|
|
9
|
+
- The **VALUE_DB** objects are no longer partitioned with **currentValue** and **valueId** properties.
|
|
10
|
+
Instead, the returned objects now include the Value ID on the same level as **currentValue**
|
|
11
|
+
- Much like above, **GET_VALUE_METADATA_RESPONSE** has also been simplified, where the result is attached to **metadata**, with the Value ID on the same level.
|
|
12
|
+
- The module no longer attempts a restart on a fatal error (i.e the stick is pulled from the socket as an example)
|
|
13
|
+
This caused more problems than what they resolved, so the descision is made to not attempt recovery.
|
|
14
|
+
Restarting the node is just as good as a recovery attempt.
|
|
10
15
|
|
|
11
16
|
**New Features**
|
|
12
|
-
- **VALUE_UPDATED**, **VALUE_NOTIFICATION**, and **
|
|
17
|
+
- **VALUE_UPDATED**, **VALUE_NOTIFICATION**, **GET_VALUE_RESPONSE** and **VALUE_DB** now contain a **normalizedObject** property.
|
|
13
18
|
This property aims to make it easy to utilise the value change, in that it summarises the event with easy to understand property names.
|
|
14
19
|
- New UI Layout - We have overhauled the UI, and focused on making it fit more into the node red style guide.
|
|
15
20
|
- An entierly new User Interface to render a Network Mesh Map.
|
|
16
21
|
- Network statistics now include route information that is obtained during communication, and is used
|
|
17
22
|
as the basis of the new map.
|
|
18
23
|
- Multiple ZWave sticks/Networks are now supported (finally)
|
|
24
|
+
- all message will contain a property of **networkId** to indentify the source network.
|
|
19
25
|
|
|
20
26
|
**Fixes**
|
|
21
27
|
- Nodes that are not marked as ready can now be removed correctly.
|
package/package.json
CHANGED
package/zwave-js/zwave-device.js
CHANGED
|
@@ -6,7 +6,7 @@ module.exports = function (RED) {
|
|
|
6
6
|
RED.nodes.createNode(this, config);
|
|
7
7
|
const RedNode = this;
|
|
8
8
|
|
|
9
|
-
const NetworkIdentifier =
|
|
9
|
+
const NetworkIdentifier = config.networkIdentifier || 1;
|
|
10
10
|
|
|
11
11
|
function UpdateStatus(Color, Shape, Text) {
|
|
12
12
|
if (config.showStatus === undefined || config.showStatus) {
|
|
@@ -75,14 +75,20 @@ module.exports = function (RED) {
|
|
|
75
75
|
}
|
|
76
76
|
VarNode = VarValue;
|
|
77
77
|
if (Out) {
|
|
78
|
-
NodeEventEmitter.on(
|
|
78
|
+
NodeEventEmitter.on(
|
|
79
|
+
`zwjs:${NetworkIdentifier}:node:event:${VarNode}`,
|
|
80
|
+
processEventMessage
|
|
81
|
+
);
|
|
79
82
|
}
|
|
80
83
|
}
|
|
81
84
|
|
|
82
85
|
if (Array.isArray(config.filteredNodeId)) {
|
|
83
86
|
if (Out) {
|
|
84
87
|
config.filteredNodeId.forEach((N) => {
|
|
85
|
-
NodeEventEmitter.on(
|
|
88
|
+
NodeEventEmitter.on(
|
|
89
|
+
`zwjs:${NetworkIdentifier}:node:event:${N}`,
|
|
90
|
+
processEventMessage
|
|
91
|
+
);
|
|
86
92
|
});
|
|
87
93
|
}
|
|
88
94
|
if (config.multicast) {
|
|
@@ -108,7 +114,10 @@ module.exports = function (RED) {
|
|
|
108
114
|
} else if (config.filteredNodeId === 'All') {
|
|
109
115
|
DeviceMode = 'All';
|
|
110
116
|
if (Out) {
|
|
111
|
-
NodeEventEmitter.on(
|
|
117
|
+
NodeEventEmitter.on(
|
|
118
|
+
`zwjs:${NetworkIdentifier}:node:event:all`,
|
|
119
|
+
processEventMessage
|
|
120
|
+
);
|
|
112
121
|
}
|
|
113
122
|
UpdateStatus('green', 'dot', 'Mode: All Nodes');
|
|
114
123
|
} else if (config.filteredNodeId === 'AS') {
|
package/zwave-js/zwave-js.js
CHANGED
|
@@ -72,9 +72,6 @@ module.exports = function (RED) {
|
|
|
72
72
|
let _DSKResolve = undefined;
|
|
73
73
|
let _ClientSideAuth = undefined;
|
|
74
74
|
|
|
75
|
-
const MaxDriverAttempts = 3;
|
|
76
|
-
let DriverAttempts = 0;
|
|
77
|
-
const RetryTime = 5000;
|
|
78
75
|
let DriverOptions = {};
|
|
79
76
|
|
|
80
77
|
// Log function
|
|
@@ -1009,6 +1006,11 @@ module.exports = function (RED) {
|
|
|
1009
1006
|
...Params[0],
|
|
1010
1007
|
currentValue: V
|
|
1011
1008
|
};
|
|
1009
|
+
ReturnObject.normalizedObject = buildNormalized(
|
|
1010
|
+
ReturnObject,
|
|
1011
|
+
ReturnNode.id
|
|
1012
|
+
);
|
|
1013
|
+
|
|
1012
1014
|
if (msg.isolatedNodeId !== undefined) {
|
|
1013
1015
|
ReturnNode.targetFlowNode = msg.isolatedNodeId;
|
|
1014
1016
|
delete msg['isolatedNodeId'];
|
|
@@ -1192,9 +1194,10 @@ module.exports = function (RED) {
|
|
|
1192
1194
|
VIDs.forEach((VID) => {
|
|
1193
1195
|
const V = Driver.controller.nodes.get(NID).getValue(VID);
|
|
1194
1196
|
const VI = {
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
+
...VID,
|
|
1198
|
+
currentValue: V
|
|
1197
1199
|
};
|
|
1200
|
+
VI.normalizedObject = buildNormalized(VI, NID);
|
|
1198
1201
|
G.values.push(VI);
|
|
1199
1202
|
});
|
|
1200
1203
|
Result.push(G);
|
|
@@ -1408,20 +1411,18 @@ module.exports = function (RED) {
|
|
|
1408
1411
|
}
|
|
1409
1412
|
}
|
|
1410
1413
|
|
|
1411
|
-
function buildNormalized(Payload) {
|
|
1414
|
+
function buildNormalized(Payload, Node) {
|
|
1412
1415
|
try {
|
|
1413
1416
|
const VID = {
|
|
1414
|
-
commandClass: Payload.
|
|
1415
|
-
endpoint: Payload.
|
|
1416
|
-
property: Payload.
|
|
1417
|
-
propertyKey: Payload.
|
|
1417
|
+
commandClass: Payload.commandClass,
|
|
1418
|
+
endpoint: Payload.endpoint,
|
|
1419
|
+
property: Payload.property,
|
|
1420
|
+
propertyKey: Payload.propertyKey
|
|
1418
1421
|
};
|
|
1419
1422
|
|
|
1420
|
-
const CCName = getCCName(Payload.
|
|
1423
|
+
const CCName = getCCName(Payload.commandClass);
|
|
1421
1424
|
|
|
1422
|
-
const Meta = Driver.controller.nodes
|
|
1423
|
-
.get(Payload.node)
|
|
1424
|
-
.getValueMetadata(VID);
|
|
1425
|
+
const Meta = Driver.controller.nodes.get(Node).getValueMetadata(VID);
|
|
1425
1426
|
|
|
1426
1427
|
if (Meta === undefined) {
|
|
1427
1428
|
return undefined;
|
|
@@ -1429,31 +1430,28 @@ module.exports = function (RED) {
|
|
|
1429
1430
|
|
|
1430
1431
|
const NO = {};
|
|
1431
1432
|
|
|
1432
|
-
NO.commandClass =
|
|
1433
|
-
.toString(16)
|
|
1434
|
-
.padStart(2, '0')} - ${CCName}`;
|
|
1433
|
+
NO.commandClass = `${VID.commandClass} - ${CCName}`;
|
|
1435
1434
|
|
|
1436
1435
|
let Key = 'newValue';
|
|
1437
1436
|
|
|
1438
|
-
if (Payload.
|
|
1437
|
+
if (Payload.hasOwnProperty('currentValue')) {
|
|
1439
1438
|
Key = 'currentValue';
|
|
1440
1439
|
}
|
|
1441
1440
|
|
|
1442
1441
|
if (
|
|
1443
1442
|
Meta.states !== undefined &&
|
|
1444
|
-
Meta.states[Payload
|
|
1443
|
+
Meta.states[Payload[Key]] !== undefined
|
|
1445
1444
|
) {
|
|
1446
|
-
NO.type = typeof Meta.states[Payload
|
|
1447
|
-
NO[Key] = Meta.states[Payload
|
|
1445
|
+
NO.type = typeof Meta.states[Payload[Key]];
|
|
1446
|
+
NO[Key] = Meta.states[Payload[Key]];
|
|
1448
1447
|
if (Key === 'newValue') {
|
|
1449
|
-
NO.prevValue =
|
|
1450
|
-
Meta.states[Payload.object.prevValue] || Payload.object.prevValue;
|
|
1448
|
+
NO.prevValue = Meta.states[Payload.prevValue] || Payload.prevValue;
|
|
1451
1449
|
}
|
|
1452
1450
|
} else {
|
|
1453
|
-
NO.type = typeof Payload
|
|
1454
|
-
NO[Key] = Payload
|
|
1451
|
+
NO.type = typeof Payload[Key];
|
|
1452
|
+
NO[Key] = Payload[Key];
|
|
1455
1453
|
if (Key === 'newValue') {
|
|
1456
|
-
NO.prevValue = Payload.
|
|
1454
|
+
NO.prevValue = Payload.prevValue;
|
|
1457
1455
|
}
|
|
1458
1456
|
}
|
|
1459
1457
|
|
|
@@ -1469,6 +1467,7 @@ module.exports = function (RED) {
|
|
|
1469
1467
|
|
|
1470
1468
|
function Send(Node, Subject, Value, send) {
|
|
1471
1469
|
const PL = {};
|
|
1470
|
+
PL.networkId = NetworkIdentifier;
|
|
1472
1471
|
|
|
1473
1472
|
let IsolatedNodeId;
|
|
1474
1473
|
|
|
@@ -1500,13 +1499,6 @@ module.exports = function (RED) {
|
|
|
1500
1499
|
_Subject = '[' + Subject + ']';
|
|
1501
1500
|
}
|
|
1502
1501
|
|
|
1503
|
-
switch (PL.event) {
|
|
1504
|
-
case 'VALUE_UPDATED':
|
|
1505
|
-
case 'VALUE_NOTIFICATION':
|
|
1506
|
-
case 'GET_VALUE_RESPONSE':
|
|
1507
|
-
PL.normalizedObject = buildNormalized(PL);
|
|
1508
|
-
break;
|
|
1509
|
-
}
|
|
1510
1502
|
Log('debug', 'NDERED', 'OUT', _Subject, '[DIRECT] Forwarding payload...');
|
|
1511
1503
|
if (send) {
|
|
1512
1504
|
send({ payload: PL });
|
|
@@ -1563,7 +1555,6 @@ module.exports = function (RED) {
|
|
|
1563
1555
|
StartDriver();
|
|
1564
1556
|
|
|
1565
1557
|
function InitDriver() {
|
|
1566
|
-
DriverAttempts++;
|
|
1567
1558
|
try {
|
|
1568
1559
|
Log('info', 'NDERED', undefined, undefined, 'Initializing driver...');
|
|
1569
1560
|
Driver = new ZWaveJS.Driver(config.serialPort, DriverOptions);
|
|
@@ -1588,43 +1579,15 @@ module.exports = function (RED) {
|
|
|
1588
1579
|
}
|
|
1589
1580
|
|
|
1590
1581
|
WireDriverEvents();
|
|
1591
|
-
//UI.Unregister();
|
|
1592
1582
|
UI.Register(Driver, Input);
|
|
1593
1583
|
}
|
|
1594
1584
|
|
|
1595
1585
|
function WireDriverEvents() {
|
|
1596
1586
|
Driver.on('error', (e) => {
|
|
1597
1587
|
if (e.code === ZWaveErrorCodes.Driver_Failed) {
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
} else {
|
|
1602
|
-
Log('error', 'NDERED', undefined, '[ERROR] [DRIVER]', e.message);
|
|
1603
|
-
Log(
|
|
1604
|
-
'debug',
|
|
1605
|
-
'NDERED',
|
|
1606
|
-
undefined,
|
|
1607
|
-
undefined,
|
|
1608
|
-
'Will retry in ' +
|
|
1609
|
-
RetryTime +
|
|
1610
|
-
'ms. Attempted: ' +
|
|
1611
|
-
DriverAttempts +
|
|
1612
|
-
', Max: ' +
|
|
1613
|
-
MaxDriverAttempts
|
|
1614
|
-
);
|
|
1615
|
-
RedNode.error(
|
|
1616
|
-
new Error(
|
|
1617
|
-
'Driver Failed: Will retry in ' +
|
|
1618
|
-
RetryTime +
|
|
1619
|
-
'ms. Attempted: ' +
|
|
1620
|
-
DriverAttempts +
|
|
1621
|
-
', Max: ' +
|
|
1622
|
-
MaxDriverAttempts
|
|
1623
|
-
)
|
|
1624
|
-
);
|
|
1625
|
-
InitDriver();
|
|
1626
|
-
setTimeout(StartDriver, RetryTime);
|
|
1627
|
-
}
|
|
1588
|
+
Log('error', 'NDERED', undefined, '[ERROR] [DRIVER]', e.message);
|
|
1589
|
+
UI.Unregister();
|
|
1590
|
+
RedNode.error(e);
|
|
1628
1591
|
} else {
|
|
1629
1592
|
Log('error', 'NDERED', undefined, '[ERROR] [DRIVER]', e.message);
|
|
1630
1593
|
RedNode.error(e);
|
|
@@ -1644,8 +1607,6 @@ module.exports = function (RED) {
|
|
|
1644
1607
|
|
|
1645
1608
|
// driver ready
|
|
1646
1609
|
Driver.once(event_DriverReady.zwaveName, () => {
|
|
1647
|
-
DriverAttempts = 0;
|
|
1648
|
-
|
|
1649
1610
|
RedNode.status({
|
|
1650
1611
|
fill: 'yellow',
|
|
1651
1612
|
shape: 'dot',
|
|
@@ -1828,6 +1789,7 @@ module.exports = function (RED) {
|
|
|
1828
1789
|
});
|
|
1829
1790
|
|
|
1830
1791
|
Node.on(event_ValueNotification.zwaveName, (N, VL) => {
|
|
1792
|
+
VL.normalizedObject = buildNormalized(VL, N.id);
|
|
1831
1793
|
Send(N, event_ValueNotification.redName, VL);
|
|
1832
1794
|
});
|
|
1833
1795
|
|
|
@@ -1840,10 +1802,12 @@ module.exports = function (RED) {
|
|
|
1840
1802
|
});
|
|
1841
1803
|
|
|
1842
1804
|
Node.on(event_ValueUpdated.zwaveName, (N, VL) => {
|
|
1805
|
+
VL.normalizedObject = buildNormalized(VL, N.id);
|
|
1843
1806
|
Send(N, event_ValueUpdated.redName, VL);
|
|
1844
1807
|
});
|
|
1845
1808
|
|
|
1846
1809
|
Node.on(event_ValueAdded.zwaveName, (N, VL) => {
|
|
1810
|
+
VL.normalizedObject = buildNormalized(VL, N.id);
|
|
1847
1811
|
Send(N, 'VALUE_UPDATED', VL); // we dont differentiate between added, update - cant see the need.
|
|
1848
1812
|
});
|
|
1849
1813
|
|
|
@@ -1896,43 +1860,16 @@ module.exports = function (RED) {
|
|
|
1896
1860
|
Driver.start()
|
|
1897
1861
|
.catch((e) => {
|
|
1898
1862
|
if (e.code === ZWaveErrorCodes.Driver_Failed) {
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
} else {
|
|
1903
|
-
Log('error', 'NDERED', undefined, '[ERROR] [DRIVER]', e.message);
|
|
1904
|
-
Log(
|
|
1905
|
-
'debug',
|
|
1906
|
-
'NDERED',
|
|
1907
|
-
undefined,
|
|
1908
|
-
undefined,
|
|
1909
|
-
'Will retry in ' +
|
|
1910
|
-
RetryTime +
|
|
1911
|
-
'ms. Attempted: ' +
|
|
1912
|
-
DriverAttempts +
|
|
1913
|
-
', Max: ' +
|
|
1914
|
-
MaxDriverAttempts
|
|
1915
|
-
);
|
|
1916
|
-
RedNode.error(
|
|
1917
|
-
new Error(
|
|
1918
|
-
'Driver failed: Will retry in ' +
|
|
1919
|
-
RetryTime +
|
|
1920
|
-
'ms. Attempted: ' +
|
|
1921
|
-
DriverAttempts +
|
|
1922
|
-
', Max: ' +
|
|
1923
|
-
MaxDriverAttempts
|
|
1924
|
-
)
|
|
1925
|
-
);
|
|
1926
|
-
InitDriver();
|
|
1927
|
-
setTimeout(StartDriver, RetryTime);
|
|
1928
|
-
}
|
|
1863
|
+
Log('error', 'NDERED', undefined, '[ERROR] [DRIVER]', e.message);
|
|
1864
|
+
UI.Unregister();
|
|
1865
|
+
RedNode.error(e);
|
|
1929
1866
|
} else {
|
|
1930
1867
|
Log('error', 'NDERED', undefined, '[ERROR] [DRIVER]', e.message);
|
|
1931
1868
|
RedNode.error(e);
|
|
1932
1869
|
}
|
|
1933
1870
|
})
|
|
1934
1871
|
.then(() => {
|
|
1935
|
-
//
|
|
1872
|
+
// we are live!
|
|
1936
1873
|
});
|
|
1937
1874
|
}
|
|
1938
1875
|
}
|