node-red-contrib-knx-ultimate 4.3.23 → 4.3.24
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 4.3.24** - June 2026<br/>
|
|
10
|
+
|
|
11
|
+
- Hue **Contact Sensor** and **Motion** nodes: fixed the state on the KNX bus getting stuck on a wrong value (e.g. a contact sensor showing **closed** while the door stayed open) after the Hue event-stream reconnected. The nodes now re-publish the authoritative state at startup and after every (re)connection, and ignore stale/out-of-order reports by checking the `contact_report.changed` / `motion_report.changed` timestamp. Closes [#514](https://github.com/Supergiovane/node-red-contrib-knx-ultimate/issues/514).<br/>
|
|
12
|
+
|
|
9
13
|
**Version 4.3.23** - June 2026<br/>
|
|
10
14
|
|
|
11
15
|
- Hue nodes: fixed the **help text** not appearing in the editor sidebar when selecting a node. The help is now declared inline in each node's main HTML file (sidebar reads help from there; the `locales/` files keep providing translations). Affected nodes: Light/Outlet, Area Motion, Battery, Button, Contact Sensor, Light Sensor, Motion, Scene, Tap Dial, Temperature Sensor, Zigbee Connectivity and Device Software Update. Also closed an unterminated template `<script>` tag in the Hue Light node.<br/>
|
|
@@ -23,7 +23,13 @@ module.exports = function (RED) {
|
|
|
23
23
|
node.formatnegativevalue = 'leave'
|
|
24
24
|
node.formatdecimalsvalue = 2
|
|
25
25
|
node.hueDevice = config.hueDevice
|
|
26
|
-
|
|
26
|
+
// Re-publish the authoritative contact state at startup and after every event-stream
|
|
27
|
+
// (re)connection. Without this, any contact_report event missed during an SSE reconnect
|
|
28
|
+
// gap leaves KNX stuck on the last value seen (see issue #514).
|
|
29
|
+
node.initializingAtStart = (config.readStatusAtStartup === undefined || config.readStatusAtStartup === 'yes')
|
|
30
|
+
// Timestamp (ms) of the last contact_report.changed we already applied to KNX. Used to
|
|
31
|
+
// ignore stale/out-of-order reports (e.g. replays after a reconnect).
|
|
32
|
+
node.lastContactChangedTs = undefined
|
|
27
33
|
|
|
28
34
|
const pushStatus = (status) => {
|
|
29
35
|
if (!status) return
|
|
@@ -94,6 +100,18 @@ module.exports = function (RED) {
|
|
|
94
100
|
return
|
|
95
101
|
}
|
|
96
102
|
|
|
103
|
+
// contact_report.state is always the real current state (per Hue API v2), and
|
|
104
|
+
// contact_report.changed is when it last changed. Ignore reports that are not newer
|
|
105
|
+
// than the last one applied, so stale/replayed events after an SSE reconnect can't
|
|
106
|
+
// flip KNX to a wrong state (issue #514).
|
|
107
|
+
const changedTs = _event.contact_report.changed !== undefined ? new Date(_event.contact_report.changed).getTime() : NaN
|
|
108
|
+
if (!Number.isNaN(changedTs)) {
|
|
109
|
+
if (node.lastContactChangedTs !== undefined && changedTs <= node.lastContactChangedTs) {
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
node.lastContactChangedTs = changedTs
|
|
113
|
+
}
|
|
114
|
+
|
|
97
115
|
const knxMsgPayload = {}
|
|
98
116
|
knxMsgPayload.topic = config.GAcontact
|
|
99
117
|
knxMsgPayload.dpt = config.dptcontact
|
|
@@ -23,7 +23,13 @@ module.exports = function (RED) {
|
|
|
23
23
|
node.formatnegativevalue = 'leave'
|
|
24
24
|
node.formatdecimalsvalue = 2
|
|
25
25
|
node.hueDevice = config.hueDevice
|
|
26
|
-
|
|
26
|
+
// Re-publish the authoritative motion state at startup and after every event-stream
|
|
27
|
+
// (re)connection, so events missed during an SSE reconnect gap don't leave KNX stuck
|
|
28
|
+
// on a wrong value (same root cause as the contact sensor, issue #514).
|
|
29
|
+
node.initializingAtStart = (config.readStatusAtStartup === undefined || config.readStatusAtStartup === 'yes')
|
|
30
|
+
// Timestamp (ms) of the last motion_report.changed we already applied to KNX. Used to
|
|
31
|
+
// ignore stale/out-of-order reports (e.g. replays after a reconnect).
|
|
32
|
+
node.lastMotionChangedTs = undefined
|
|
27
33
|
const pinsSetting = (config.enableNodePINS === undefined || config.enableNodePINS === 'yes' || config.enableNodePINS === true)
|
|
28
34
|
node.enableNodePINS = pinsSetting ? 'yes' : 'no'
|
|
29
35
|
node.outputs = pinsSetting ? 1 : 0
|
|
@@ -97,6 +103,18 @@ module.exports = function (RED) {
|
|
|
97
103
|
try {
|
|
98
104
|
if (_event.id === config.hueDevice) {
|
|
99
105
|
if (!_event.hasOwnProperty('motion') || _event.motion.motion === undefined) return
|
|
106
|
+
|
|
107
|
+
// Ignore reports that are not newer than the last one applied, so stale/replayed
|
|
108
|
+
// events after an SSE reconnect can't push a wrong state to KNX (issue #514).
|
|
109
|
+
const motionChanged = _event.motion.motion_report !== undefined ? _event.motion.motion_report.changed : undefined
|
|
110
|
+
const changedTs = motionChanged !== undefined ? new Date(motionChanged).getTime() : NaN
|
|
111
|
+
if (!Number.isNaN(changedTs)) {
|
|
112
|
+
if (node.lastMotionChangedTs !== undefined && changedTs <= node.lastMotionChangedTs) {
|
|
113
|
+
return
|
|
114
|
+
}
|
|
115
|
+
node.lastMotionChangedTs = changedTs
|
|
116
|
+
}
|
|
117
|
+
|
|
100
118
|
const knxMsgPayload = {}
|
|
101
119
|
knxMsgPayload.topic = config.GAmotion
|
|
102
120
|
knxMsgPayload.dpt = config.dptmotion
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"engines": {
|
|
4
4
|
"node": ">=20.18.1"
|
|
5
5
|
},
|
|
6
|
-
"version": "4.3.
|
|
6
|
+
"version": "4.3.24",
|
|
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/",
|