@evilbunny/node-red-contrib-zigbee2mqtt 3.2.6 → 3.2.9

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/README.md CHANGED
@@ -5,15 +5,15 @@ I've made other improvements, such as more state options to support ZigBee devic
5
5
 
6
6
  # @evilbunny/node-red-contrib-zigbee2mqtt
7
7
  [![platform](https://img.shields.io/badge/platform-Node--RED-red?logo=nodered)](https://nodered.org)
8
- [![Min Node Version](https://img.shields.io/node/v/node-red-contrib-zigbee2mqtt.svg)](https://nodejs.org/en/)
8
+ [![Min Node Version](https://img.shields.io/node/v/@evilbunny/node-red-contrib-zigbee2mqtt.svg)](https://nodejs.org/en/)
9
9
  [![GitHub version](https://img.shields.io/github/package-json/v/evilbunny2008/node-red-contrib-zigbee2mqtt?logo=npm)](https://www.npmjs.com/package/node-red-contrib-zigbee2mqtt)
10
10
  [![GitHub stars](https://img.shields.io/github/stars/evilbunny2008/node-red-contrib-zigbee2mqtt)](https://github.com/evilbunny2008/node-red-contrib-zigbee2mqtt/stargazers)
11
- [![Package Quality](https://packagequality.com/shield/node-red-contrib-zigbee2mqtt.svg)](https://packagequality.com/#?package=node-red-contrib-zigbee2mqtt)
11
+ [![Package Quality](https://packagequality.com/shield/@evilbunny/node-red-contrib-zigbee2mqtt.svg)](https://packagequality.com/#?package=node-red-contrib-zigbee2mqtt)
12
12
 
13
13
  [![issues](https://img.shields.io/github/issues/evilbunny2008/node-red-contrib-zigbee2mqtt?logo=github)](https://github.com/evilbunny2008/node-red-contrib-zigbee2mqtt/issues)
14
14
  ![GitHub last commit](https://img.shields.io/github/last-commit/evilbunny2008/node-red-contrib-zigbee2mqtt)
15
- ![NPM Total Downloads](https://img.shields.io/npm/dt/node-red-contrib-zigbee2mqtt.svg)
16
- ![NPM Downloads per month](https://img.shields.io/npm/dm/node-red-contrib-zigbee2mqtt)
15
+ ![NPM Total Downloads](https://img.shields.io/npm/dt/@evilbunny/node-red-contrib-zigbee2mqtt.svg)
16
+ ![NPM Downloads per month](https://img.shields.io/npm/dm/@evilbunny/node-red-contrib-zigbee2mqtt)
17
17
  ![Repo size](https://img.shields.io/github/repo-size/evilbunny2008/node-red-contrib-zigbee2mqtt)
18
18
 
19
19
  Node-Red Nodes for Zigbee2mqtt connectivity.
package/nodes/server.js CHANGED
@@ -464,19 +464,49 @@ module.exports = function(RED) {
464
464
  }
465
465
 
466
466
  let useProperty = null;
467
- if (node.config.state && node.config.state !== '0') {
468
- if (item.homekit && node.config.state.split("homekit_").join('') in item.homekit) {
469
- payload = item.homekit[node.config.state.split("homekit_").join('')];
470
- useProperty = node.config.state.split("homekit_").join('');
471
- } else if (payload_all && node.config.state in payload_all) {
472
- payload = text = payload_all[node.config.state];
473
- useProperty = node.config.state;
474
- } else {
475
- //state was not found in payload (button case)
467
+ // normalize config.state: supports the new array format, and legacy single-string configs
468
+ let stateList = node.config.state;
469
+ if (typeof stateList === 'string') {
470
+ stateList = (stateList && stateList !== '0') ? [stateList] : [];
471
+ }
472
+ if (!Array.isArray(stateList)) {
473
+ stateList = [];
474
+ }
475
+
476
+ if (stateList.length) {
477
+ let collected = {};
478
+ let foundAny = false;
479
+
480
+ for (let prop of stateList) {
481
+ let homekitKey = prop.split("homekit_").join('');
482
+ if (item.homekit && homekitKey in item.homekit) {
483
+ collected[prop] = item.homekit[homekitKey];
484
+ useProperty = homekitKey;
485
+ foundAny = true;
486
+ } else if (payload_all && prop in payload_all) {
487
+ collected[prop] = payload_all[prop];
488
+ useProperty = prop;
489
+ foundAny = true;
490
+ }
491
+ // if a requested property isn't present on this message, it's just skipped
492
+ // (e.g. a button event won't carry every sensor property)
493
+ }
494
+
495
+ if (!foundAny) {
496
+ //none of the requested properties were found in payload (button case)
476
497
  //payload: { last_seen: '2022-07-27T15:25:22+03:00', linkquality: 36 }
477
498
  //payload: { action: 'single', last_seen: '2022-07-27T15:25:22+03:00', linkquality: 36 }
478
499
  return;
479
500
  }
501
+
502
+ if (stateList.length === 1) {
503
+ // preserve existing behaviour: a single selected property outputs its raw value
504
+ payload = text = collected[stateList[0]];
505
+ } else {
506
+ // multiple selected properties: output an object containing just those keys
507
+ payload = collected;
508
+ useProperty = null; // unit-suffix below only makes sense for a single property
509
+ }
480
510
  } else {
481
511
  payload = payload_all;
482
512
  }
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  },
6
6
  "name": "@evilbunny/node-red-contrib-zigbee2mqtt",
7
7
  "description": "Fork of Zigbee2mqtt connectivity nodes for node-red",
8
- "version": "3.2.6",
8
+ "version": "3.2.9",
9
9
  "publishConfig": {
10
10
  "access": "public"
11
11
  },
@@ -74,10 +74,10 @@ class Zigbee2MqttEditor {
74
74
  dropWidth: 320,
75
75
  width: 320,
76
76
  filter: true,
77
- formatAllSelected:function(){return RED._("@evilbunny/zigbee2mqtt/server:editor.select_device")}
77
+ formatAllSelected:function(){return RED._("@evilbunny/node-red-contrib-zigbee2mqtt/server:editor.select_device")}
78
78
  };
79
79
  if (that.config.allow_empty && !that.isMultiple()) {
80
- params.formatAllSelected = function(){return RED._("@evilbunny/zigbee2mqtt/server:editor.msg_topic")};
80
+ params.formatAllSelected = function(){return RED._("@evilbunny/node-red-contrib-zigbee2mqtt/server:editor.msg_topic")};
81
81
  }
82
82
 
83
83
  that.getDeviceIdInput().children().remove();
@@ -97,7 +97,7 @@ class Zigbee2MqttEditor {
97
97
  return (a.friendly_name || '').localeCompare(b.friendly_name || '', undefined, {sensitivity: 'base'});
98
98
  });
99
99
  if (groups.length) {
100
- html = $('<optgroup/>', {label: RED._("@evilbunny/zigbee2mqtt/server:editor.groups")});
100
+ html = $('<optgroup/>', {label: RED._("@evilbunny/node-red-contrib-zigbee2mqtt/server:editor.groups")});
101
101
  html.appendTo(that.getDeviceIdInput());
102
102
  $.each(groups, function(index, value) {
103
103
  let text = '';
@@ -115,7 +115,7 @@ class Zigbee2MqttEditor {
115
115
  return (a.friendly_name || '').localeCompare(b.friendly_name || '', undefined, {sensitivity: 'base'});
116
116
  });
117
117
  if (devices.length) {
118
- html = $('<optgroup/>', {label: RED._("@evilbunny/zigbee2mqtt/server:editor.devices")});
118
+ html = $('<optgroup/>', {label: RED._("@evilbunny/node-red-contrib-zigbee2mqtt/server:editor.devices")});
119
119
  html.appendTo(that.getDeviceIdInput());
120
120
  $.each(devices, function(index, value) {
121
121
  var model = '';
@@ -148,16 +148,15 @@ class Zigbee2MqttEditor {
148
148
  numberDisplayed: 1,
149
149
  dropWidth: 320,
150
150
  width: 320,
151
- single: !(typeof $(this).attr('multiple') !== typeof undefined && $(this).attr('multiple') !== false)
151
+ single: false, // always allow selecting multiple attributes; no selection = complete payload
152
+ placeholder: RED._("@evilbunny/node-red-contrib-zigbee2mqtt/server:editor.complete_payload")
152
153
  }).multipleSelect('disable');
153
154
 
154
- that.getDevicePropertyInput().html('<option value="0">'+ RED._("@evilbunny/zigbee2mqtt/server:editor.complete_payload")+'</option>');
155
-
156
155
  let html = '';
157
156
  let device = that.getDevice();
158
157
 
159
158
  if (device && 'definition' in device && device.definition && 'exposes' in device.definition) {
160
- html = $('<optgroup/>', {label: RED._("@evilbunny/zigbee2mqtt/server:editor.zigbee2mqtt")});
159
+ html = $('<optgroup/>', {label: RED._("@evilbunny/node-red-contrib-zigbee2mqtt/server:editor.zigbee2mqtt")});
161
160
  html.appendTo(that.getDevicePropertyInput());
162
161
 
163
162
  $.each(device.definition.exposes, function(index, value) {
@@ -179,7 +178,7 @@ class Zigbee2MqttEditor {
179
178
  }
180
179
 
181
180
  if (device && 'homekit' in device && device.homekit && Object.keys(device.homekit).length) {
182
- html = $('<optgroup/>', {label: RED._("@evilbunny/zigbee2mqtt/server:editor.homekit")});
181
+ html = $('<optgroup/>', {label: RED._("@evilbunny/node-red-contrib-zigbee2mqtt/server:editor.homekit")});
183
182
  html.appendTo(that.getDevicePropertyInput());
184
183
 
185
184
  $.each(device.homekit, function (index, value) {
@@ -187,11 +186,22 @@ class Zigbee2MqttEditor {
187
186
  });
188
187
  }
189
188
  that.getDevicePropertyInput().multipleSelect('enable');
190
- if (that.getDevicePropertyInput().find('option[value='+that.property+']').length) {
191
- that.getDevicePropertyInput().val(that.property);
192
- } else {
193
- that.getDevicePropertyInput().val(that.getDevicePropertyInput().find('option').eq(0).attr('value'));
189
+
190
+ // restore previously-selected properties (supports legacy single-string values too)
191
+ let selected = that.property;
192
+ if (typeof selected === 'string') {
193
+ selected = selected && selected !== '0' ? [selected] : [];
194
194
  }
195
+ if (!Array.isArray(selected)) {
196
+ selected = [];
197
+ }
198
+ // drop any selections that no longer exist as options for this device
199
+ selected = selected.filter(function(value) {
200
+ return that.getDevicePropertyInput().find('option[value="' + value + '"]').length > 0;
201
+ });
202
+ that.property = selected;
203
+ that.getDevicePropertyInput().multipleSelect('setSelects', selected);
204
+
195
205
  that.getDevicePropertyInput().multipleSelect('refresh');
196
206
  }
197
207
 
@@ -218,7 +228,7 @@ class Zigbee2MqttEditor {
218
228
  // console.log('BUILD buildDeviceOptionsInput');
219
229
  let device = that.getDevice();
220
230
  let options = [];
221
- options.push({'value': 'nothing', 'label': RED._("@evilbunny/zigbee2mqtt/server:editor.nothing"), options:['']});
231
+ options.push({'value': 'nothing', 'label': RED._("@evilbunny/node-red-contrib-zigbee2mqtt/server:editor.nothing"), options:['']});
222
232
  options.push('msg');
223
233
  options.push('json');
224
234
  if (device && 'definition' in device && device.definition && 'options' in device.definition) {
@@ -401,7 +411,7 @@ class Zigbee2MqttEditor {
401
411
  if (!that.device_id) {
402
412
  that.device_id = [];
403
413
  }
404
- that.getDeviceFriendlyNameInput().val(that.device_id.length + ' ' + RED._("@evilbunny/zigbee2mqtt/server:editor.selected"));
414
+ that.getDeviceFriendlyNameInput().val(that.device_id.length + ' ' + RED._("@evilbunny/node-red-contrib-zigbee2mqtt/server:editor.selected"));
405
415
  } else if (that.device_id && that.device_id.length) {
406
416
  if (typeof(that.device_id) == 'object') {
407
417
  that.device_id = that.device_id[0]; //get the first device