node-red-contrib-ccu 4.1.0 → 4.3.0

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.
Files changed (51) hide show
  1. package/CHANGELOG.md +125 -0
  2. package/HANDOFF.md +67 -16
  3. package/README.md +42 -0
  4. package/ROADMAP.md +129 -47
  5. package/examples/home-assistant.json +127 -0
  6. package/nodes/ccu-alexa.html +3 -1
  7. package/nodes/ccu-connection.html +26 -0
  8. package/nodes/ccu-connection.js +124 -13
  9. package/nodes/ccu-display.js +29 -13
  10. package/nodes/ccu-get-value.html +3 -1
  11. package/nodes/ccu-homeassistant.html +334 -0
  12. package/nodes/ccu-homeassistant.js +272 -0
  13. package/nodes/ccu-mqtt.html +21 -4
  14. package/nodes/ccu-mqtt.js +188 -105
  15. package/nodes/ccu-rpc-event.html +6 -0
  16. package/nodes/ccu-rpc-event.js +31 -12
  17. package/nodes/ccu-set-value.html +38 -0
  18. package/nodes/ccu-set-value.js +59 -235
  19. package/nodes/ccu-signal.html +55 -1
  20. package/nodes/ccu-signal.js +52 -9
  21. package/nodes/ccu-switch.html +17 -4
  22. package/nodes/ccu-switch.js +28 -4
  23. package/nodes/ccu-sysvar.html +40 -1
  24. package/nodes/ccu-sysvar.js +78 -8
  25. package/nodes/ccu-value.html +27 -1
  26. package/nodes/ccu-value.js +69 -19
  27. package/nodes/lib/cast.js +59 -14
  28. package/nodes/lib/channelfilter.js +136 -0
  29. package/nodes/lib/dynconfig.js +81 -0
  30. package/nodes/lib/hadiscovery.js +846 -0
  31. package/nodes/lib/haroles.js +193 -0
  32. package/nodes/lib/localccu.js +81 -0
  33. package/nodes/lib/message.js +6 -2
  34. package/nodes/lib/valuestatus.js +145 -0
  35. package/nodes/locales/de/ccu-display.html +17 -0
  36. package/nodes/locales/de/ccu-rpc-event.json +1 -0
  37. package/nodes/locales/de/ccu-sysvar.json +3 -2
  38. package/nodes/locales/de/ccu-value.json +2 -1
  39. package/nodes/locales/en-US/ccu-display.html +17 -0
  40. package/nodes/locales/en-US/ccu-rpc-event.json +3 -2
  41. package/nodes/locales/en-US/ccu-switch.html +12 -0
  42. package/nodes/locales/en-US/ccu-sysvar.json +3 -2
  43. package/nodes/locales/en-US/ccu-value.json +2 -1
  44. package/package.json +2 -1
  45. package/patch-certainonly.py +51 -0
  46. package/roadmap-archive/B-16.md +31 -0
  47. package/roadmap-archive/B-2.md +69 -0
  48. package/roadmap-archive/B-3.md +57 -0
  49. package/roadmap-archive/B-4.md +44 -0
  50. package/roadmap-archive/B-5.md +57 -0
  51. package/roadmap-archive/README.md +11 -0
@@ -0,0 +1,81 @@
1
+ /* Per-message dynamic node configuration (B-2, issues #172 #71 #103 #80
2
+ #56 #148 #133).
3
+
4
+ Two mechanisms, in increasing precedence:
5
+
6
+ 1. Flat properties (`msg.channel`, `msg.rooms`, ...). Long-standing
7
+ behaviour of ccu-set-value/ccu-value/ccu-get-value: they fill in
8
+ configuration the node itself leaves empty. Kept as-is because
9
+ messages coming straight from an event node carry exactly these
10
+ names, which is what makes it convenient - and, for the same
11
+ reason, only ever used for the nodes that already did it.
12
+ 2. `msg.config`, an object of overrides. Always wins, works for every
13
+ configurable field including lists, and cannot collide with the
14
+ properties an event message carries (`msg.ccu` is the CCU host, so
15
+ it is not available as a namespace). This is what makes the
16
+ settings of the signal/display/switch/sysvar nodes reachable from
17
+ a flow.
18
+
19
+ The old inline implementation in ccu-set-value wrote message
20
+ properties into the node's own `config` object, so only the *first*
21
+ message ever configured the node: every later message hit the
22
+ `if (!config[key])` guard and was ignored (#133). Nothing here mutates
23
+ the stored configuration. */
24
+
25
+ /**
26
+ * Build the effective configuration for one message.
27
+ *
28
+ * @param {object} config the node's stored configuration (never mutated)
29
+ * @param {object} message the incoming message
30
+ * @param {string[]} keys the keys that may be overridden; anything else
31
+ * in `msg.config` is ignored, so a stray property cannot reach
32
+ * node internals
33
+ * @param {object} [options]
34
+ * @param {boolean} [options.flat=false] also fill empty keys from
35
+ * top-level message properties (mechanism 1)
36
+ * @returns {{config: object, dynamic: boolean}} effective config plus
37
+ * whether anything actually came from the message
38
+ */
39
+ function effectiveConfig(config, message, keys, options) {
40
+ const effective = {...config};
41
+ let dynamic = false;
42
+
43
+ if (!message || typeof message !== 'object') {
44
+ return {config: effective, dynamic};
45
+ }
46
+
47
+ if (options && options.flat) {
48
+ keys.forEach((key) => {
49
+ if (!effective[key] && key in message) {
50
+ effective[key] = message[key];
51
+ dynamic = true;
52
+ }
53
+ });
54
+ }
55
+
56
+ const overrides = message.config;
57
+ if (overrides && typeof overrides === 'object' && !Array.isArray(overrides)) {
58
+ keys.forEach((key) => {
59
+ if (key in overrides) {
60
+ effective[key] = overrides[key];
61
+ dynamic = true;
62
+ }
63
+ });
64
+ }
65
+
66
+ return {config: effective, dynamic};
67
+ }
68
+
69
+ /**
70
+ * A stable identity for a set of configuration keys, used to decide
71
+ * whether a cache derived from them is still valid. Two effective configs
72
+ * that produce the same key select the same devices/datapoints.
73
+ * @param {object} config
74
+ * @param {string[]} keys
75
+ * @returns {string}
76
+ */
77
+ function configCacheKey(config, keys) {
78
+ return keys.map((key) => JSON.stringify(config[key] === undefined ? null : config[key])).join(' ');
79
+ }
80
+
81
+ module.exports = {effectiveConfig, configCacheKey};