node-red-contrib-knx-ultimate 6.0.0 → 6.0.1

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 6.0.1** - July 2026<br/>
10
+
11
+ - **Expose KNX to Matter (BETA) — flow-only covers/shutters**: fixed intermediate position commands reaching the Node-RED output but not being optimistically confirmed to Matter when no KNX command group address was configured. Voice assistants such as Alexa no longer report that the device is not responding after a percentage-position command.<br/>
12
+
9
13
  **Version 6.0.0** - July 2026<br/>
10
14
 
11
15
  - **BREAKING CHANGE**: this release intentionally bumps the package to `6.0.0` because the Matter node model changed. The unpublished dedicated Matter controller nodes and the old generic Matter Device node have been replaced by the new single **Control Matter from KNX (BETA)** node, and the KNX-to-Matter bridge/editor behaviour has been reworked. Existing experimental Matter flows created with the previous beta nodes may need to be rebuilt or adjusted.<br/>
@@ -179,6 +179,22 @@ module.exports = function (RED) {
179
179
  }
180
180
  return false
181
181
  }
182
+
183
+ const applyOptimisticCoverPosition = (command) => {
184
+ if (node.deviceType !== 'windowcovering' || node.coverUpdateMode !== 'optimistic' || !node.serverMatterBridge) return
185
+ let optimisticPosition
186
+ if (command.fn === 'position') optimisticPosition = command.value
187
+ if (command.fn === 'updown') optimisticPosition = command.value === true ? 100 : 0
188
+ if (optimisticPosition === undefined) return
189
+ node.serverMatterBridge.setDeviceState(node.matterDeviceId, 'position', optimisticPosition)
190
+ clearCoverStatusTimer()
191
+ if (node.coverStatusTimeoutMs > 0 && hasStatusRouteFor('position')) {
192
+ coverStatusTimer = setTimeout(() => {
193
+ coverStatusTimer = null
194
+ node.setNodeStatus({ fill: 'yellow', shape: 'ring', text: 'Waiting for KNX cover status', payload: optimisticPosition })
195
+ }, node.coverStatusTimeoutMs)
196
+ }
197
+ }
182
198
  node.knxUltimateAcceptedGAs = Array.from(statusRoutes.keys())
183
199
 
184
200
  // The device definition consumed by the bridge engine (via the config node).
@@ -221,6 +237,9 @@ module.exports = function (RED) {
221
237
  })
222
238
  } catch (error) { /* empty */ }
223
239
  }
240
+ // Confirm the requested position to Matter even when this is a flow-only
241
+ // device and no KNX command GA is configured.
242
+ applyOptimisticCoverPosition(command)
224
243
  const route = commandRoutes.get(command.fn)
225
244
  if (route === undefined) {
226
245
  if (node.enableNodePINS) return // Flow-only device: the flow already got the command
@@ -240,21 +259,6 @@ module.exports = function (RED) {
240
259
  return
241
260
  }
242
261
  safeSendToKNX({ grpaddr: route.ga, payload: command.value, dpt: route.dpt, outputtype: 'write' }, 'write')
243
- if (node.deviceType === 'windowcovering' && node.coverUpdateMode === 'optimistic' && node.serverMatterBridge) {
244
- let optimisticPosition
245
- if (command.fn === 'position') optimisticPosition = command.value
246
- if (command.fn === 'updown') optimisticPosition = command.value === true ? 100 : 0
247
- if (optimisticPosition !== undefined) {
248
- node.serverMatterBridge.setDeviceState(node.matterDeviceId, 'position', optimisticPosition)
249
- clearCoverStatusTimer()
250
- if (node.coverStatusTimeoutMs > 0 && hasStatusRouteFor('position')) {
251
- coverStatusTimer = setTimeout(() => {
252
- coverStatusTimer = null
253
- node.setNodeStatus({ fill: 'yellow', shape: 'ring', text: 'Waiting for KNX cover status', payload: optimisticPosition })
254
- }, node.coverStatusTimeoutMs)
255
- }
256
- }
257
- }
258
262
  node.setNodeStatus({ fill: 'green', shape: 'dot', text: `Matter->KNX ${command.fn}`, payload: command.value })
259
263
  } catch (error) {
260
264
  node.setNodeStatus({ fill: 'red', shape: 'dot', text: `Matter->KNX error ${error.message}` })
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "engines": {
4
4
  "node": ">=20.18.1"
5
5
  },
6
- "version": "6.0.0",
6
+ "version": "6.0.1",
7
7
  "description": "Control your KNX and KNX Secure intallation via Node-Red! A bunch of KNX nodes, with integrated Philips HUE control, ETS group address importer, KNX AI for diagnosticsand KNX routing between interfaces. Easy to use and highly configurable.",
8
8
  "files": [
9
9
  "nodes/",