node-red-contrib-knx-ultimate 2.2.30 → 2.2.31

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
@@ -6,6 +6,11 @@
6
6
 
7
7
  # CHANGELOG
8
8
 
9
+ **Version 2.2.31** - December 2023<br/>
10
+ - NEW: HUE Scene node: added the status GA and Datapoint, for the scene to send true/false if active/not active. This currently works only for "Single mode".<br/>
11
+ - WARNING: the new HUE Scene node is to be considered **BETA (= in testing with user feedback)**.<br/>
12
+
13
+
9
14
  **Version 2.2.30** - December 2023<br/>
10
15
  - NEW: HUE Scene node: added a "Multi scene" section, more powerful.<br/>
11
16
  - HUE Scene: when selecting a group address for the scene, the scene number dropdown list doesn't show up.<br/>
@@ -43,8 +43,6 @@ module.exports = function (RED) {
43
43
  if (_event.id === config.hueDevice) {
44
44
 
45
45
  if (!_event.hasOwnProperty("motion") || _event.motion.motion === undefined) return;
46
-
47
-
48
46
  const knxMsgPayload = {};
49
47
  knxMsgPayload.topic = config.GAmotion;
50
48
  knxMsgPayload.dpt = config.dptmotion;
@@ -15,6 +15,9 @@
15
15
  GAscene: { value: "" },
16
16
  dptscene: { value: "" },
17
17
  valscene: { value: 0 }, // the scene number or true/false
18
+ namesceneStatus: { value: "" },
19
+ GAsceneStatus: { value: "" },
20
+ dptsceneStatus: { value: "" },
18
21
 
19
22
  enableNodePINS: { value: "no" },
20
23
  outputs: { value: 0 },
@@ -39,7 +42,7 @@
39
42
  if (Number(this.selectedModeTabNumber) === 0) return this.name;
40
43
  if (Number(this.selectedModeTabNumber) === 1) return this.namesceneMulti;
41
44
  },
42
- paletteLabel: "Hue Scene",
45
+ paletteLabel: "Hue Scene (Beta)",
43
46
  // button: {
44
47
  // enabled: function() {
45
48
  // // return whether or not the button is enabled, based on the current
@@ -105,8 +108,14 @@
105
108
  .attr("value", dpt.value)
106
109
  .text(dpt.text))
107
110
  }
111
+ if (dpt.value.startsWith("1.")) {
112
+ $("#node-input-dptsceneStatus").append($("<option></option>")
113
+ .attr("value", dpt.value)
114
+ .text(dpt.text))
115
+ }
108
116
  });
109
117
  $("#node-input-dptscene").val(this.dptscene)
118
+ $("#node-input-dptsceneStatus").val(this.dptsceneStatus)
110
119
  $("#node-input-dptsceneMulti").val(this.dptsceneMulti)
111
120
  ShowHideValScene();
112
121
  })
@@ -145,6 +154,39 @@
145
154
  ShowHideValScene();
146
155
  }
147
156
  });
157
+ $("#node-input-GAsceneStatus").autocomplete({
158
+ minLength: 1,
159
+ source: function (request, response) {
160
+ //$.getJSON("csv", request, function( data, status, xhr ) {
161
+ $.getJSON("knxUltimatecsv?nodeID=" + oNodeServer.id, (data) => {
162
+ response($.map(data, function (value, key) {
163
+ var sSearch = (value.ga + " (" + value.devicename + ") DPT" + value.dpt);
164
+ if (fullSearch(sSearch, request.term)) {
165
+ if (value.dpt.startsWith("1.")) {
166
+ return {
167
+ label: value.ga + " # " + value.devicename + " # " + value.dpt, // Label for Display
168
+ value: value.ga // Value
169
+ }
170
+ } else { return null; }
171
+ } else {
172
+ return null;
173
+ }
174
+ }));
175
+ });
176
+ }, select: function (event, ui) {
177
+ // Sets Datapoint and device name automatically
178
+ var sDevName = ui.item.label.split("#")[1].trim();
179
+ try {
180
+ sDevName = sDevName.substr(sDevName.indexOf(")") + 1).trim();
181
+ } catch (error) {
182
+ }
183
+ $('#node-input-namesceneStatus').val(sDevName);
184
+ var optVal = $("#node-input-dptsceneStatus option:contains('" + ui.item.label.split("#")[2].trim() + "')").attr('value');
185
+ // Select the option value
186
+ $("#node-input-dptsceneStatus").val(optVal);
187
+ ShowHideValScene();
188
+ }
189
+ });
148
190
  $("#node-input-GAsceneMulti").autocomplete({
149
191
  minLength: 1,
150
192
  source: function (request, response) {
@@ -460,12 +502,23 @@
460
502
  <label for="node-input-namescene" style="width:50px; margin-left: 0px; text-align: right;">Name</label>
461
503
  <input type="text" id="node-input-namescene" style="width:200px;margin-left: 5px; text-align: left;">
462
504
  </div>
463
-
464
505
  <div class="form-row" id="divValScene" hidden>
465
506
  <label for="node-input-valscene" style="width:100px;"></label>
466
507
  <label for="node-input-valscene" style="width:20px;">#</label>
467
508
  <select id="node-input-valscene" style="width:180px;margin-left: 5px; text-align: left;"></select>
468
509
  </div>
510
+ <div class="form-row">
511
+ <label for="node-input-namesceneStatus" style="width:100px;"><i class="fa fa-play-circle-o"></i> Status</label>
512
+
513
+ <label for="node-input-GAsceneStatus" style="width:20px;">GA</label>
514
+ <input type="text" id="node-input-GAsceneStatus" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
515
+
516
+ <label for="node-input-dptsceneStatus" style="width:40px; margin-left: 0px; text-align: right;">DPT</label>
517
+ <select id="node-input-dptsceneStatus" style="width:140px;"></select>
518
+
519
+ <label for="node-input-namesceneStatus" style="width:50px; margin-left: 0px; text-align: right;">Name</label>
520
+ <input type="text" id="node-input-namesceneStatus" style="width:200px;margin-left: 5px; text-align: left;">
521
+ </div>
469
522
  <br/>
470
523
  <br/>
471
524
  </div> <!-- // End Tab 1 -->
@@ -541,6 +594,7 @@ This works also with the HUE scene text field.
541
594
  |--|--|
542
595
  | Recall | Choose your group address to be used for recalling the HUE scene. In case of Datapoint 1.x, send *true* to that group address to recall the scene, *false* to switch off all lights belonging to the scene. |
543
596
  | # | Select the KNX scene number. Visible only with datapoint 18.001. |
597
+ | Status | It's the scene status. *True* when the scene is active, *false* when the scene is not active. |
544
598
 
545
599
 
546
600
  **Multi mode tab**
@@ -114,9 +114,39 @@ module.exports = function (RED) {
114
114
 
115
115
  node.handleSendHUE = (_event) => {
116
116
  try {
117
- if (_event.id === config.hueDevice) {
118
- // Output the msg to the flow
119
- node.send(_event);
117
+ if (Number(config.selectedModeTabNumber) === 0 && config.hueDevice !== undefined && _event.id === config.hueDevice) {
118
+ // Single mode
119
+ const knxMsgPayload = {};
120
+ knxMsgPayload.topic = config.GAsceneStatus;
121
+ knxMsgPayload.dpt = config.dptsceneStatus;
122
+ if (_event.hasOwnProperty("status") && _event.status.hasOwnProperty("active")) {
123
+ knxMsgPayload.payload = _event.status.active !== "inactive";
124
+ // Send to KNX bus
125
+ if (knxMsgPayload.topic !== "" && knxMsgPayload.topic !== undefined && node.server !== undefined) {
126
+ node.server.writeQueueAdd({
127
+ grpaddr: knxMsgPayload.topic,
128
+ payload: knxMsgPayload.payload,
129
+ dpt: knxMsgPayload.dpt,
130
+ outputtype: "write",
131
+ nodecallerid: node.id,
132
+ });
133
+ }
134
+ node.status({
135
+ fill: "blue",
136
+ shape: "dot",
137
+ text: `HUE->KNX ${JSON.stringify(knxMsgPayload.payload)} (${new Date().getDate()}, ${new Date().toLocaleTimeString()})`,
138
+ });
139
+ // Output the msg to the flow
140
+ node.send(_event);
141
+ }
142
+ } else if (Number(config.selectedModeTabNumber) === 1 && config.rules !== undefined) {
143
+ // Multi mode
144
+ config.rules.forEach(row => {
145
+ if (row.rowRuleHUESceneID !== undefined && _event.id === row.rowRuleHUESceneID) {
146
+ // Output the msg to the flow
147
+ node.send(_event);
148
+ }
149
+ });
120
150
  }
121
151
  } catch (error) {
122
152
  node.status({ fill: 'red', shape: 'dot', text: 'HUE->KNX error ' + error.message + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' });
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "engines": {
4
4
  "node": ">=16.0.0"
5
5
  },
6
- "version": "2.2.30",
6
+ "version": "2.2.31",
7
7
  "description": "Control your KNX intallation via Node-Red! A bunch of KNX nodes, with integrated Philips HUE control and ETS group address importer. Easy to use and highly configurable.",
8
8
  "dependencies": {
9
9
  "binary-parser": "2.2.1",