node-red-contrib-knx-ultimate 3.0.5 → 3.0.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
@@ -6,6 +6,10 @@
6
6
 
7
7
  # CHANGELOG
8
8
 
9
+ **Version 3.0.6** - August 2024<br/>
10
+ - Warning: Node-Red version **equals or major than 3.1.1** is needed to run this node.<br/>
11
+ - KNX Auto Responder node (BETA): fixed some issues when the ETS file has not been imported. Please be aware that until the node exits beta, there can be breaking changes.<br/>
12
+
9
13
  **Version 3.0.5** - August 2024<br/>
10
14
  - Warning: Node-Red version **equals or major than 3.1.1** is needed to run this node.<br/>
11
15
  - KNX Auto Responder node (BETA): changed to JSON array instead of plain text and updated the help. Please be aware that until the node exits beta, there can be breaking changes.<br/>
package/README.md CHANGED
@@ -43,7 +43,7 @@ msg.payload = {red:255, green:200, blue:30} // Put some colors in our life
43
43
  * **VIEWER node** [here](https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/knxUltimateViewer). View all Group Addresses and values of your KNX BUS, in the Node-Red Dashboard.
44
44
  * **PHILIPS HUE nodeset** [here](https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/en-hue-configuration). Link HUE devices to KNX in a simple way.
45
45
  * **HOME ASSISTANT translator node** translates the HA input msg, to a KNX value. Comes with a built-in translation table, that's user editable.
46
-
46
+ * **AUTO RESPONDER node** responds to read requests coming from the bus. Used mainly for virtual group addresses.
47
47
  <br>
48
48
 
49
49
  ## CHANGELOG
@@ -55,8 +55,11 @@
55
55
 
56
56
 
57
57
  <div class="form-row">
58
- <b>Auto Responder</b>
59
- <br />
58
+ <b>Auto Responder</b>&nbsp&nbsp<span style="color:red" &nbsp &nbsp<i class="fa fa-youtube"></i></span>&nbsp<a
59
+ target="_blank" href=""><u>Youtube sample coming soon...</u></a>
60
+ <br />
61
+ <br />
62
+
60
63
  <label for="node-input-server">
61
64
  <img
62
65
  src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAKnRFWHRDcmVhdGlvbiBUaW1lAEZyIDYgQXVnIDIwMTAgMjE6NTI6MTkgKzAxMDD84aS8AAAAB3RJTUUH3gYYCicNV+4WIQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAARnQU1BAACxjwv8YQUAAACUSURBVHjaY2CgFZg5c+Z/ZEyWAZ8+f/6/ZsWs/xoamqMGkGrA6Wla/1+fVARjEBuGsSoGmY4eZSCNL59d/g8DIDbIAHR14OgFGQByKjIGKX5+6/T///8gGMQGiV1+/B0Fg70GIkD+RMYgxf/O5/7//2MSmAZhkBi6OrgB6Bg5DGB4ajr3f2xqsYYLSDE2THJUDg0AAAqyDVd4tp4YAAAAAElFTkSuQmCC"></img>
@@ -45,7 +45,6 @@ module.exports = function (RED) {
45
45
  node.inputRBE = 'false' // Apply or not RBE to the input (Messages coming from BUS)
46
46
  node.exposedGAs = [];
47
47
  node.commandText = []; // Raw list Respond To
48
- node.decodedRespondToList = [];
49
48
  node.sysLogger = require('./utils/sysLogger.js').get({ loglevel: node.server.loglevel || 'error' }); // 08/04/2021 new logger to adhere to the loglevel selected in the config-window
50
49
 
51
50
  // Used to call the status update from the config node.
@@ -66,7 +65,7 @@ module.exports = function (RED) {
66
65
  //return;
67
66
  } else {
68
67
  node.server.csv.forEach(element => {
69
- node.exposedGAs.push({ address: element.ga, dpt: element.dpt, devicename: element.devicename, payload: undefined })
68
+ node.exposedGAs.push({ address: element.ga, dpt: element.dpt, default: undefined, payload: undefined })
70
69
  })
71
70
  node.status({ fill: 'green', shape: 'ring', text: 'ETS file loaded', payload: '', dpt: '', devicename: '' });
72
71
  }
@@ -84,18 +83,30 @@ module.exports = function (RED) {
84
83
  node.commandText.forEach(element => {
85
84
  if (element.ga !== undefined && element.default !== undefined) {
86
85
  let defaultVal = element.default;
86
+ let dpt = element.dpt;
87
87
  if (element.ga.includes('..')) {
88
88
  const start = Number(element.ga.substring(element.ga.lastIndexOf("/") + 1, element.ga.indexOf("..")));
89
89
  const end = Number(element.ga.substring(element.ga.indexOf("..") + 2));
90
90
  const twoLevel = element.ga.substring(0, element.ga.lastIndexOf("/") + 1);
91
91
  for (let index = start; index < end; index++) {
92
92
  const decAdd = twoLevel + index;
93
- node.decodedRespondToList.push({ address: decAdd, default: defaultVal });
93
+ // Add also to the exposedGAs list, if not already present
94
+ let curGa = node.exposedGAs.find(a => a.address === decAdd);
95
+ if (curGa === undefined) {
96
+ node.exposedGAs.push({ address: decAdd, dpt: dpt, default: defaultVal, payload: undefined });
97
+ } else {
98
+ if (dpt !== undefined) curGa.dpt = dpt; // Take the Datapoint from the commandText directive, replacing from ETS CSV file, if exists.
99
+ }
94
100
  }
95
101
  } else {
96
- node.decodedRespondToList.push({ address: element.ga, default: defaultVal })
102
+ let curGa = node.exposedGAs.find(a => a.address === element.ga);
103
+ if (curGa === undefined) {
104
+ node.exposedGAs.push({ address: element.ga, dpt: dpt, default: defaultVal, payload: undefined });
105
+ } else {
106
+ if (dpt !== undefined) curGa.dpt = dpt; // Take the Datapoint from the commandText directive, replacing from ETS CSV file, if exists.
107
+ }
97
108
  }
98
- node.status({ fill: 'green', shape: 'ring', text: 'JSON parsed: ' + node.decodedRespondToList.length + " directive(s).", payload: '', dpt: '', devicename: '' });
109
+ node.status({ fill: 'green', shape: 'ring', text: 'JSON parsed: ' + node.commandText.length + " directive(s).", payload: '', dpt: '', devicename: '' });
99
110
  } else {
100
111
  // Error
101
112
  node.status({ fill: 'red', shape: 'dot', text: 'JSON error: ga or default keys not set. Abort.', payload: '', dpt: '', devicename: '' });
@@ -111,69 +122,36 @@ module.exports = function (RED) {
111
122
 
112
123
  // Save the value
113
124
  try {
114
- var oGa = node.exposedGAs.find(ga => ga.address === msg.knx.destination)
125
+ var oGa = node.exposedGAs.find(ga => ga.address === msg.knx.destination);
115
126
  } catch (error) {
116
127
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimateAutoResponder: var oGa = node.exposedGAs.find(ga => ga.address === msg.knx.destination) ${error.stack}`);
117
128
  }
118
- if (oGa === undefined) {
119
- let datapoint;
120
- let decodedPayload;
121
- if (msg.knx !== undefined && msg.knx.dpt !== undefined) {
122
- // There is the CSV file imported
123
- datapoint = msg.knx.dpt;
124
- decodedPayload = msg.payload;
125
- } else {
126
- // Must get the dpt from the decodedRespondToList list, then decode the payload
127
- try {
128
- datapoint = node.decodedRespondToList.find(x => x.address === msg.knx.destination).dpt;
129
- const dpt = dptlib.resolve(datapoint);
130
- const decodedPayload = dptlib.fromBuffer(msg.knx.rawValue, dpt);
131
- } catch (error) {
132
- node.status({ fill: 'red', shape: 'dot', text: 'datapoint = node.decodedRespondToList ' + error.message, payload: '', dpt: '', devicename: '' });
133
- if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimateAutoResponder: datapoint = node.decodedRespondToList.find(x => x.address === msg.knx.destination).dpt ${error.stack}`);
134
- }
129
+ if (oGa !== undefined) {
130
+ try {
131
+ // Don't care about the decoded payload, because knxUltimate-config could pass a TryToFindDatapoint from raw data
132
+ // Take only RAW data and decode it with the dpt specified by the commandText directive
133
+ const decodedPayload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(oGa.dpt));
134
+ } catch (error) {
135
+ node.status({ fill: 'red', shape: 'dot', text: 'datapoint = node.decodedRespondToList ' + error.message, payload: '', dpt: '', devicename: '' });
136
+ if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimateAutoResponder: datapoint = node.decodedRespondToList.find(x => x.address === msg.knx.destination).dpt ${error.stack}`);
135
137
  }
136
- if (decodedPayload !== undefined && datapoint !== undefined) node.exposedGAs.push({ address: msg.knx.destination, devicename: undefined, dpt: datapoint, payload: decodedPayload })
137
-
138
- } else {
139
- oGa.dpt = msg.knx.dpt
140
- oGa.payload = msg.payload
138
+ oGa.payload = decodedPayload
141
139
  }
142
140
  } else {
143
141
 
144
- // Send the response to the bus
145
- var defaultValue; // Default value if no payload in the exposedGA list
146
- var bFound = false;
147
- // Can i handle the incoming message?
148
- try {
149
- for (let index = 0; index < node.decodedRespondToList.length; index++) {
150
- const element = node.decodedRespondToList[index];
151
- if (msg.knx.destination === element.address) {
152
- defaultValue = element.default;
153
- bFound = true;
154
- break;
155
- }
156
- }
157
- } catch (error) {
158
- if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimateAutoResponder: before bFound ${error.stack}`);
159
- }
160
- if (!bFound) return;
161
-
162
142
  try {
163
143
  let retVal;
164
144
  let oFoundGA = node.exposedGAs.find(ga => ga.address === msg.knx.destination);
165
145
  if (oFoundGA === undefined) return;
166
146
  if (oFoundGA.payload === undefined) {
167
- if (defaultValue === 'true') defaultValue = true;
168
- if (defaultValue === 'false') defaultValue = false;
169
- retVal = defaultValue;
147
+ retVal = oFoundGA.default;
170
148
  } else {
171
149
  retVal = oFoundGA.payload;
172
150
  }
173
151
  if (retVal !== undefined) {
174
152
  const dDate = new Date()
175
153
  node.status({ fill: 'blue', shape: 'dot', text: 'Respond ' + oFoundGA.address + ' => ' + retVal + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
176
- node.server.writeQueueAdd({ grpaddr: oFoundGA.address, payload: retVal, dpt: oFoundGA.dpt || '', outputtype: 'response', nodecallerid: node.id });
154
+ node.server.writeQueueAdd({ grpaddr: oFoundGA.address, payload: retVal, dpt: oFoundGA.dpt, outputtype: 'response', nodecallerid: node.id });
177
155
  }
178
156
  } catch (error) {
179
157
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimateAutoResponder: after bFound ${error.stack}`);
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "engines": {
4
4
  "node": ">=16.0.0"
5
5
  },
6
- "version": "3.0.5",
6
+ "version": "3.0.6",
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",