node-red-contrib-zwave-js 7.2.0-beta.3 → 7.2.1-beta.6

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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # node-red-contrib-zwave-js Change Log
2
2
 
3
+ - 7.2.1
4
+
5
+ **New Features**
6
+ - Implemented a Firmware Update Service, that allows to install Firmware on devices that have known updates
7
+ - 2 new event types have been added : **ALIVE**, **DEAD** - these allow you to monitor if a device has been marked dead
8
+ or alive accordingly.
9
+
10
+ **Bug Fixes**
11
+ - Modal alerts are now rendering HTML content once again
12
+ - Missing `normalizedObject.label` for Thermostat devices
13
+
14
+ **Changes**
15
+ - Association Management has been updated, and changes are now applied in batch.
16
+ - For battery operated devices, certain UI actions now ask you to wake up said device before anything is comitted.
17
+ - Bump ZWave JS
18
+ - Bump Winston
19
+ - Bump ESlint
20
+
3
21
  - 7.1.2
4
22
 
5
23
  **Changes**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-zwave-js",
3
- "version": "7.2.0-beta.3",
3
+ "version": "7.2.1-beta.6",
4
4
  "license": "MIT",
5
5
  "description": "The most powerful, high performing and highly polished Z-Wave node for Node-RED based on Z-Wave JS. If you want a fully featured Z-Wave framework in your Node-RED instance, you have found it.",
6
6
  "dependencies": {
@@ -279,6 +279,7 @@ const ZwaveJsUI = (function () {
279
279
  let LastTargetForBA; // BA TArget
280
280
  let WakeResolver; // Resolve for wake wait
281
281
  let WakeResolverTarget; // Target Wake Node
282
+ let NodesListed = false; // nodes listed
282
283
 
283
284
  function modalAlert(message, title) {
284
285
  const Buts = {
@@ -506,11 +507,43 @@ const ZwaveJsUI = (function () {
506
507
  FWRunning = false;
507
508
  }
508
509
 
509
- function PerformUpdate() {
510
+ async function PerformUpdateFromService(Node, File) {
511
+ const nodeRow = $('#zwave-js-node-list').find(`[data-nodeid='${Node}']`);
512
+ if (nodeRow.data().info.status.toUpperCase() === 'ASLEEP') {
513
+ await WaitForNodeWake(Node);
514
+ }
515
+
516
+ ControllerCMD(
517
+ DCs.beginOTAFirmwareUpdate.API,
518
+ DCs.beginOTAFirmwareUpdate.name,
519
+ undefined,
520
+ [Node, File],
521
+ DCs.beginOTAFirmwareUpdate.noWait
522
+ )
523
+ .then(() => {
524
+ FWRunning = true;
525
+ selectNode(Node);
526
+ $(":button:contains('Begin Update')")
527
+ .prop('disabled', true)
528
+ .addClass('ui-state-disabled');
529
+ $('#FWProgress').css({ display: 'block' });
530
+ })
531
+ .catch((err) => {
532
+ modalAlert(err.responseText || err.message, 'Firmware rejected');
533
+ throw new Error(err.responseText || err.message);
534
+ });
535
+ }
536
+
537
+ async function PerformUpdate() {
510
538
  const FE = $('#FILE_FW')[0].files[0];
511
539
  const NID = parseInt($('#NODE_FW option:selected').val());
512
540
  const Target = $('#TARGET_FW').val();
513
541
 
542
+ const nodeRow = $('#zwave-js-node-list').find(`[data-nodeid='${NID}']`);
543
+ if (nodeRow.data().info.status.toUpperCase() === 'ASLEEP') {
544
+ await WaitForNodeWake(NID);
545
+ }
546
+
514
547
  const FD = new FormData();
515
548
  FD.append('Binary', FE);
516
549
  FD.append('NodeID', NID);
@@ -1168,7 +1201,7 @@ const ZwaveJsUI = (function () {
1168
1201
  } else {
1169
1202
  Nodes.forEach((N) => $('#zwave-js-node-list').append(renderNode(N)));
1170
1203
  }
1171
-
1204
+ NodesListed = true;
1172
1205
  $('#zwave-js-node-properties').treeList('empty');
1173
1206
  })
1174
1207
  .catch((err) => {
@@ -2475,7 +2508,11 @@ const ZwaveJsUI = (function () {
2475
2508
  //
2476
2509
  const Container = $('<div>');
2477
2510
  Container.append(
2478
- `<strong>Version ${object[0].version}</strong><br /><br />`
2511
+ `Current Version <strong>${
2512
+ nodeRow.data().info.firmwareVersion
2513
+ }</strong> New Version <strong>${
2514
+ object[0].version
2515
+ }</strong><br /><br />`
2479
2516
  );
2480
2517
 
2481
2518
  Container.append('<strong>Change Log</strong>');
@@ -2487,37 +2524,15 @@ const ZwaveJsUI = (function () {
2487
2524
  });
2488
2525
  CLL.appendTo(Container);
2489
2526
 
2490
- const Buttons = {
2491
- Update: function () {
2492
- $(this)
2493
- .prop('disabled', true)
2494
- .addClass('ui-state-disabled')
2495
- .text('Please wait...');
2527
+ const Buttons = {};
2496
2528
 
2497
- // Yuk!
2498
- const File = object[0].files.filter((F) => F.target === 0)[0];
2529
+ for (let i = 0; i < object[0].files.length; i++) {
2530
+ const File = object[0].files[i];
2531
+ Buttons[`Update (Target ${File.target})`] = function () {
2532
+ PerformUpdateFromService(Node, File);
2533
+ };
2534
+ }
2499
2535
 
2500
- ControllerCMD(
2501
- DCs.beginOTAFirmwareUpdate.API,
2502
- DCs.beginOTAFirmwareUpdate.name,
2503
- undefined,
2504
- [Node, File],
2505
- DCs.beginOTAFirmwareUpdate.noWait
2506
- )
2507
- .then(() => {
2508
- FWRunning = true;
2509
- selectNode(Node);
2510
- $('#FWProgress').css({ display: 'block' });
2511
- })
2512
- .catch((err) => {
2513
- modalAlert(
2514
- err.responseText || err.message,
2515
- 'Could not begin update'
2516
- );
2517
- throw new Error(err.responseText || err.message);
2518
- });
2519
- }
2520
- };
2521
2536
  modalPrompt(
2522
2537
  Container,
2523
2538
  'Firmware Update Available',
@@ -2726,7 +2741,11 @@ const ZwaveJsUI = (function () {
2726
2741
  const nodeRow = $('#zwave-js-node-list').find(
2727
2742
  `[data-nodeid='${data.node}']`
2728
2743
  );
2729
- nodeRow.data().info.status = data.status;
2744
+
2745
+ if (NodesListed) {
2746
+ nodeRow.data().info.status = data.status;
2747
+ }
2748
+
2730
2749
  if (data.status == 'READY') {
2731
2750
  if (DriverReady) {
2732
2751
  GetNodesThrottled();
@@ -2740,9 +2759,11 @@ const ZwaveJsUI = (function () {
2740
2759
  ) {
2741
2760
  WakeResolver();
2742
2761
  }
2743
- nodeRow
2744
- .find('.zwave-js-node-row-status')
2745
- .html(renderStatusIcon(data.status.toUpperCase()));
2762
+ if (NodesListed) {
2763
+ nodeRow
2764
+ .find('.zwave-js-node-row-status')
2765
+ .html(renderStatusIcon(data.status.toUpperCase()));
2766
+ }
2746
2767
  }
2747
2768
  break;
2748
2769
  }
@@ -484,6 +484,10 @@ class UIServer {
484
484
  }
485
485
 
486
486
  _WireNodeEvents(node) {
487
+ if (node.isControllerNode) {
488
+ return;
489
+ }
490
+
487
491
  // Status
488
492
  node.on('sleep', (node) => {
489
493
  this._SendNodeStatus(node, 'ASLEEP');
@@ -45,6 +45,8 @@ module.exports = function (RED) {
45
45
  const event_ValueAdded = new SanitizedEventName('value added');
46
46
  const event_Wake = new SanitizedEventName('wake up');
47
47
  const event_Sleep = new SanitizedEventName('sleep');
48
+ const event_Dead = new SanitizedEventName('dead');
49
+ const event_Alive = new SanitizedEventName('alive');
48
50
  const event_InterviewStarted = new SanitizedEventName('interview started');
49
51
  const event_InterviewFailed = new SanitizedEventName('interview failed');
50
52
  const event_InterviewCompleted = new SanitizedEventName(
@@ -1674,7 +1676,9 @@ module.exports = function (RED) {
1674
1676
  } else {
1675
1677
  let Name;
1676
1678
  switch (VID.commandClass) {
1677
- case 67: // Thermo Setpoint;
1679
+ // Thermostat Setpoint
1680
+ case 'Thermostat Setpoint':
1681
+ case 67:
1678
1682
  Name = ZWaveJS.getEnumMemberName(
1679
1683
  ZWaveJS.ThermostatSetpointType,
1680
1684
  VID.propertyKey
@@ -1753,6 +1757,8 @@ module.exports = function (RED) {
1753
1757
  'VALUE_UPDATED',
1754
1758
  'SLEEP',
1755
1759
  'WAKE_UP',
1760
+ 'DEAD',
1761
+ 'ALIVE',
1756
1762
  'VALUE_ID_LIST',
1757
1763
  'GET_VALUE_RESPONSE',
1758
1764
  'GET_VALUE_METADATA_RESPONSE'
@@ -2025,11 +2031,11 @@ module.exports = function (RED) {
2025
2031
  }
2026
2032
 
2027
2033
  function WireNodeEvents(Node) {
2028
- Node.once(event_Ready.zwaveName, (N) => {
2029
- if (N.isControllerNode) {
2030
- return;
2031
- }
2034
+ if (Node.isControllerNode) {
2035
+ return;
2036
+ }
2032
2037
 
2038
+ Node.once(event_Ready.zwaveName, () => {
2033
2039
  Node.on(event_FirmwareUpdateFinished.zwaveName, (N, S) => {
2034
2040
  Send(N, event_FirmwareUpdateFinished.redName, S);
2035
2041
  });
@@ -2064,6 +2070,14 @@ module.exports = function (RED) {
2064
2070
  Node.on(event_Sleep.zwaveName, (N) => {
2065
2071
  Send(N, event_Sleep.redName);
2066
2072
  });
2073
+
2074
+ Node.on(event_Dead.zwaveName, (N) => {
2075
+ Send(N, event_Dead.redName);
2076
+ });
2077
+
2078
+ Node.on(event_Alive.zwaveName, (N) => {
2079
+ Send(N, event_Alive.redName);
2080
+ });
2067
2081
  });
2068
2082
 
2069
2083
  Node.on(event_InterviewStarted.zwaveName, (N) => {