@hurenkam/hue-services 0.6.3 → 0.6.5

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 (112) hide show
  1. package/README.md +17 -5
  2. package/attic-bridge-v2-key.txt +2 -0
  3. package/package.json +1 -1
  4. package/src/all.html +4 -0
  5. package/src/all.js +4 -0
  6. package/src/clip/ClipApi.js +4 -35
  7. package/src/nodes/CameraMotionNode.js +39 -0
  8. package/src/nodes/ContactNode.js +52 -0
  9. package/src/ui/BaseUI.js +1 -3
  10. package/src/ui/CameraMotionUI.js +27 -0
  11. package/src/ui/ContactUI.js +27 -0
  12. package/.nyc_output/b2f41757-3a3e-4377-8622-cddcc882cf32.json +0 -1
  13. package/.nyc_output/processinfo/b2f41757-3a3e-4377-8622-cddcc882cf32.json +0 -1
  14. package/.nyc_output/processinfo/index.json +0 -1
  15. package/.vscode/settings.json +0 -15
  16. package/.vscode/sftp.json +0 -11
  17. package/Todo.txt +0 -18
  18. package/coverage/BaseNode.js.html +0 -379
  19. package/coverage/base.css +0 -224
  20. package/coverage/block-navigation.js +0 -87
  21. package/coverage/favicon.png +0 -0
  22. package/coverage/index.html +0 -146
  23. package/coverage/lcov-report/base.css +0 -224
  24. package/coverage/lcov-report/block-navigation.js +0 -87
  25. package/coverage/lcov-report/favicon.png +0 -0
  26. package/coverage/lcov-report/index.html +0 -161
  27. package/coverage/lcov-report/prettify.css +0 -1
  28. package/coverage/lcov-report/prettify.js +0 -2
  29. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  30. package/coverage/lcov-report/sorter.js +0 -196
  31. package/coverage/lcov-report/src/RestApi.js.html +0 -499
  32. package/coverage/lcov-report/src/all.js.html +0 -208
  33. package/coverage/lcov-report/src/clip/ClipApi.js.html +0 -1096
  34. package/coverage/lcov-report/src/clip/Resource.js.html +0 -481
  35. package/coverage/lcov-report/src/clip/index.html +0 -131
  36. package/coverage/lcov-report/src/debug.js.html +0 -253
  37. package/coverage/lcov-report/src/files.js.html +0 -118
  38. package/coverage/lcov-report/src/index.html +0 -161
  39. package/coverage/lcov-report/src/nodes/BaseNode.js.html +0 -381
  40. package/coverage/lcov-report/src/nodes/BridgeConfigNode.js.html +0 -817
  41. package/coverage/lcov-report/src/nodes/ButtonNode.js.html +0 -241
  42. package/coverage/lcov-report/src/nodes/DevicePowerNode.js.html +0 -199
  43. package/coverage/lcov-report/src/nodes/GroupedLightNode.js.html +0 -226
  44. package/coverage/lcov-report/src/nodes/LightLevelNode.js.html +0 -205
  45. package/coverage/lcov-report/src/nodes/LightNode.js.html +0 -226
  46. package/coverage/lcov-report/src/nodes/MotionNode.js.html +0 -205
  47. package/coverage/lcov-report/src/nodes/RelativeRotaryNode.js.html +0 -253
  48. package/coverage/lcov-report/src/nodes/ResourceNode.js.html +0 -388
  49. package/coverage/lcov-report/src/nodes/SceneNode.js.html +0 -124
  50. package/coverage/lcov-report/src/nodes/ServiceNode.js.html +0 -124
  51. package/coverage/lcov-report/src/nodes/TemperatureNode.js.html +0 -205
  52. package/coverage/lcov-report/src/nodes/ZigbeeConnectivityNode.js.html +0 -199
  53. package/coverage/lcov-report/src/nodes/index.html +0 -311
  54. package/coverage/lcov-report/src/ui/BaseUI.js.html +0 -484
  55. package/coverage/lcov-report/src/ui/BridgeConfigUI.js.html +0 -475
  56. package/coverage/lcov-report/src/ui/ButtonUI.js.html +0 -166
  57. package/coverage/lcov-report/src/ui/DevicePowerUI.js.html +0 -166
  58. package/coverage/lcov-report/src/ui/GroupedLightUI.js.html +0 -178
  59. package/coverage/lcov-report/src/ui/LightLevelUI.js.html +0 -166
  60. package/coverage/lcov-report/src/ui/LightUI.js.html +0 -178
  61. package/coverage/lcov-report/src/ui/MotionUI.js.html +0 -166
  62. package/coverage/lcov-report/src/ui/RelativeRotaryUI.js.html +0 -166
  63. package/coverage/lcov-report/src/ui/ResourceUI.js.html +0 -511
  64. package/coverage/lcov-report/src/ui/SceneUI.js.html +0 -160
  65. package/coverage/lcov-report/src/ui/ServiceUI.js.html +0 -868
  66. package/coverage/lcov-report/src/ui/TemperatureUI.js.html +0 -166
  67. package/coverage/lcov-report/src/ui/ZigbeeConnectivityUI.js.html +0 -166
  68. package/coverage/lcov-report/src/ui/index.html +0 -311
  69. package/coverage/lcov.info +0 -2217
  70. package/coverage/prettify.css +0 -1
  71. package/coverage/prettify.js +0 -2
  72. package/coverage/sort-arrow-sprite.png +0 -0
  73. package/coverage/sorter.js +0 -196
  74. package/coverage/src/RestApi.js.html +0 -499
  75. package/coverage/src/all.js.html +0 -208
  76. package/coverage/src/clip/ClipApi.js.html +0 -1183
  77. package/coverage/src/clip/Resource.js.html +0 -481
  78. package/coverage/src/clip/index.html +0 -131
  79. package/coverage/src/debug.js.html +0 -253
  80. package/coverage/src/files.js.html +0 -118
  81. package/coverage/src/index.html +0 -116
  82. package/coverage/src/nodes/BaseNode.js.html +0 -379
  83. package/coverage/src/nodes/BridgeConfigNode.js.html +0 -517
  84. package/coverage/src/nodes/ButtonNode.js.html +0 -238
  85. package/coverage/src/nodes/DevicePowerNode.js.html +0 -196
  86. package/coverage/src/nodes/GroupedLightNode.js.html +0 -223
  87. package/coverage/src/nodes/LightLevelNode.js.html +0 -202
  88. package/coverage/src/nodes/LightNode.js.html +0 -223
  89. package/coverage/src/nodes/MotionNode.js.html +0 -202
  90. package/coverage/src/nodes/RelativeRotaryNode.js.html +0 -250
  91. package/coverage/src/nodes/ResourceNode.js.html +0 -409
  92. package/coverage/src/nodes/SceneNode.js.html +0 -124
  93. package/coverage/src/nodes/ServiceNode.js.html +0 -124
  94. package/coverage/src/nodes/TemperatureNode.js.html +0 -202
  95. package/coverage/src/nodes/ZigbeeConnectivityNode.js.html +0 -199
  96. package/coverage/src/nodes/index.html +0 -311
  97. package/coverage/src/ui/BaseUI.js.html +0 -484
  98. package/coverage/src/ui/BridgeConfigUI.js.html +0 -475
  99. package/coverage/src/ui/ButtonUI.js.html +0 -166
  100. package/coverage/src/ui/DevicePowerUI.js.html +0 -166
  101. package/coverage/src/ui/GroupedLightUI.js.html +0 -178
  102. package/coverage/src/ui/LightLevelUI.js.html +0 -166
  103. package/coverage/src/ui/LightUI.js.html +0 -178
  104. package/coverage/src/ui/MotionUI.js.html +0 -166
  105. package/coverage/src/ui/RelativeRotaryUI.js.html +0 -166
  106. package/coverage/src/ui/ResourceUI.js.html +0 -511
  107. package/coverage/src/ui/SceneUI.js.html +0 -160
  108. package/coverage/src/ui/ServiceUI.js.html +0 -868
  109. package/coverage/src/ui/TemperatureUI.js.html +0 -166
  110. package/coverage/src/ui/ZigbeeConnectivityUI.js.html +0 -166
  111. package/coverage/src/ui/index.html +0 -311
  112. package/test/BaseUI_spec.js +0 -17
package/README.md CHANGED
@@ -6,15 +6,20 @@ node-red palette to access hue bridge through clip v2 api
6
6
 
7
7
  # Status
8
8
 
9
- (Last update: 2022/12/16)
9
+ (Last update: 2025/12/20)
10
10
  This is not complete, but seems to work consistent and reliable for the services I regularly use.
11
- (motion/temperature/light_level/light/grouped_light/button/relative_rotary/scene).
11
+ (motion/temperature/light_level/light/grouped_light/button/relative_rotary/scene/contact/camera_motion).
12
12
 
13
13
  Unit tests are in place for the server side nodes.
14
14
 
15
15
  Editor/UI functionality is currently not being tested apart from my own use in the editor, so your mileage may vary.
16
16
 
17
17
  # Changelog
18
+ v0.6.5: Added nodes for camera and contact sensor. Improved generic service usability.
19
+
20
+ v0.6.4: Fix checkbox to work with Safari
21
+
22
+ v0.6.3: Added option for nodes to generate a status event on startup (see issue #3)
18
23
 
19
24
  v0.6.2: Fixes issue with services pointing to wrong bridge type and thus unable to add/edit bridge references.
20
25
 
@@ -27,6 +32,8 @@ This should address issue #1.
27
32
  ## Services:
28
33
  - Generic Service, in case you need some service that is not supported below, you can use this.
29
34
  - Button
35
+ - Camera Motion
36
+ - Contact
30
37
  - Device Power
31
38
  - Grouped Light
32
39
  - Light
@@ -47,14 +54,19 @@ This should address issue #1.
47
54
  - ~~Upload package to node-red library~~
48
55
  - ~~Unit Tests for Clip~~
49
56
  - ~~Unit Tests for Nodes~~
57
+ - ~~Contact sensor~~
58
+ - ~~Camera~~
59
+ - Geofencing
60
+ - Smart Scenes
50
61
  - Unit Tests for UI
51
62
 
63
+
52
64
  ## Postponed until after 0.6.x release
53
65
  - Improve 'smart' modes for Switch and Motion devices
54
- - Improve the generic device node (which allows using as of yet unsupported devices)
66
+ - ~~Improve the generic device node (which allows using as of yet unsupported devices)~~
55
67
  - Support more devices
56
- - smart button (should be easy to do, but i don't have one to test)
57
- - tap dial switch (should be similar to a lutron aurora, but i don't have one to test)
68
+ - ~~smart button (should be easy to do, but i don't have one to test)~~
69
+ - ~~tap dial switch (should be similar to a lutron aurora, but i don't have one to test)~~
58
70
 
59
71
  # Use
60
72
  Using these nodes requires a bit of knowledge on the clip v2 api, as i designed this palette
@@ -0,0 +1,2 @@
1
+ 2ml0TLJEUc-j-byMhxIhymRSOUPUlnzRrZUiseoq
2
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hurenkam/hue-services",
3
- "version": "0.6.3",
3
+ "version": "0.6.5",
4
4
  "description": "Custom node-red nodes for interfacing with philips hue devices",
5
5
  "author": "Mark Hurenkamp",
6
6
  "license": "Apache 2.0",
package/src/all.html CHANGED
@@ -3,6 +3,8 @@
3
3
  import { BridgeConfigUI } from "/src/ui/BridgeConfigUI.js";
4
4
 
5
5
  import { ButtonUI } from "/src/ui/ButtonUI.js";
6
+ import { CameraMotionUI } from "/src/ui/CameraMotionUI.js";
7
+ import { ContactUI } from "/src/ui/ContactUI.js";
6
8
  import { DevicePowerUI } from "/src/ui/DevicePowerUI.js";
7
9
  import { GroupedLightUI } from "/src/ui/GroupedLightUI.js";
8
10
  import { LightUI } from "/src/ui/LightUI.js";
@@ -18,6 +20,8 @@
18
20
  "BridgeConfigNode": BridgeConfigUI,
19
21
 
20
22
  "ButtonNode": ButtonUI,
23
+ "CameraMotionNode": CameraMotionUI,
24
+ "ContactNode": ContactUI,
21
25
  "DevicePowerNode": DevicePowerUI,
22
26
  "GroupedLightNode": GroupedLightUI,
23
27
  "LightNode": LightUI,
package/src/all.js CHANGED
@@ -7,6 +7,8 @@ module.exports = function(RED) {
7
7
  const BridgeConfigNode = require('./nodes/BridgeConfigNode');
8
8
 
9
9
  const ButtonNode = require('./nodes/ButtonNode');
10
+ const CameraMotionNode = require('./nodes/CameraMotionNode');
11
+ const ContactNode = require('./nodes/ContactNode');
10
12
  const DevicePowerNode = require('./nodes/DevicePowerNode');
11
13
  const GroupedLightNode = require('./nodes/GroupedLightNode');
12
14
  const LightNode = require('./nodes/LightNode');
@@ -23,6 +25,8 @@ module.exports = function(RED) {
23
25
  "BridgeConfigNode": BridgeConfigNode,
24
26
 
25
27
  "ButtonNode": ButtonNode,
28
+ "CameraMotionNode": CameraMotionNode,
29
+ "ContactNode": ContactNode,
26
30
  "DevicePowerNode": DevicePowerNode,
27
31
  "GroupedLightNode": GroupedLightNode,
28
32
  "LightNode": LightNode,
@@ -24,33 +24,6 @@ class ClipApi extends events.EventEmitter {
24
24
  #info;
25
25
  #trace;
26
26
 
27
- #factory = {
28
- "behavior_script": Resource,
29
- "behavior_instance": Resource,
30
- "bridge": Resource,
31
- "bridge_home": Resource,
32
- "button": Resource,
33
- "device": Resource,
34
- "device_power": Resource,
35
- "entertainment": Resource,
36
- "entertainment_configuration": Resource,
37
- "geolocation": Resource,
38
- "grouped_light": Resource,
39
- "homekit": Resource,
40
- "light": Resource,
41
- "light_level": Resource,
42
- "matter": Resource,
43
- "motion": Resource,
44
- "relative_rotary": Resource,
45
- "room": Resource,
46
- "scene": Resource,
47
- "temperature": Resource,
48
- "zgp_connectivity": Resource,
49
- "zigbee_connectivity": Resource,
50
- "zigbee_device_discovery": Resource,
51
- "zone": Resource
52
- };
53
-
54
27
  constructor(ip,key,name) {
55
28
  super();
56
29
 
@@ -145,13 +118,9 @@ class ClipApi extends events.EventEmitter {
145
118
  response.data.forEach((item) => {
146
119
  this.#trace("constructor() found resource:", item);
147
120
 
148
- if (Object.keys(this.#factory).includes(item.type)) {
149
- if (!this._isResourceRegistered(item.id)) {
150
- var resource = new this.#factory[item.type](item,this);
151
- this._registerResource(resource);
152
- }
153
- } else {
154
- this.#warn("constructor(): Missing factory for type", item.type);
121
+ if (!this._isResourceRegistered(item.id)) {
122
+ var resource = new Resource(item,this);
123
+ this._registerResource(resource);
155
124
  }
156
125
  });
157
126
 
@@ -364,4 +333,4 @@ class ClipApi extends events.EventEmitter {
364
333
  }
365
334
  }
366
335
 
367
- module.exports = ClipApi
336
+ module.exports = ClipApi
@@ -0,0 +1,39 @@
1
+ ResourceNode = require("./ResourceNode");
2
+
3
+ class CameraMotionNode extends ResourceNode {
4
+ #info;
5
+ #trace;
6
+
7
+ constructor(config) {
8
+ super(config);
9
+ this.#info = require('debug')('info').extend('CameraMotionNode').extend("["+this.logid()+"]");
10
+ this.#trace = require('debug')('trace').extend('CameraMotionNode').extend("["+this.logid()+"]");
11
+ this.#info("constructor()");
12
+ }
13
+
14
+ onUpdate(event) {
15
+ this.#trace("onUpdate(",event,")")
16
+ this.updateStatus();
17
+ super.onUpdate(event);
18
+ }
19
+
20
+ updateStatus() {
21
+ this.#trace("updateStatus()")
22
+
23
+ var fill = "grey";
24
+ var shape = "dot";
25
+ var text = "";
26
+
27
+ var resource = this.resource();
28
+ if ((resource) && (resource.data()) && (resource.data().motion)) {
29
+ if (resource.data().motion.motion!=null) {
30
+ fill = (resource.data().motion.motion==true)? "blue" : "grey";
31
+ text = (resource.data().motion.motion==true)? "motion" : "no motion";
32
+ }
33
+ }
34
+
35
+ this.status({fill: fill, shape: shape, text: text});
36
+ }
37
+ }
38
+
39
+ module.exports = CameraMotionNode;
@@ -0,0 +1,52 @@
1
+ ResourceNode = require("./ResourceNode");
2
+
3
+ class ContactNode extends ResourceNode {
4
+ #fill;
5
+
6
+ #info;
7
+ #trace;
8
+
9
+ constructor(config) {
10
+ super(config);
11
+
12
+ this.#info = require('debug')('info').extend('ContactNode').extend("["+this.logid()+"]");
13
+ this.#trace = require('debug')('trace').extend('ContactNode').extend("["+this.logid()+"]");
14
+ this.#info("constructor()");
15
+
16
+ this.#fill = "grey";
17
+ }
18
+
19
+ onUpdate(event) {
20
+ this.#trace("onUpdate(",event,")");
21
+ this.#fill = "blue";
22
+
23
+ var instance = this;
24
+ setTimeout(()=>{
25
+ instance.#fill = "grey";
26
+ instance.updateStatus();
27
+ },1000);
28
+
29
+ this.updateStatus();
30
+ super.onUpdate(event);
31
+ }
32
+
33
+ updateStatus() {
34
+ this.#trace("updateStatus()");
35
+
36
+ var fill = this.#fill;
37
+ var shape = "dot";
38
+ var text = "";
39
+
40
+ var resource = this.resource();
41
+ if ((resource) && (resource.data()) && (resource.data().contact_report)) {
42
+ if (resource.data().contact_report.state!=null) {
43
+ fill = (resource.data().contact_report.state=="contact")? "grey" : "blue";
44
+ text = (resource.data().contact_report.state=="contact")? "closed" : "open";
45
+ }
46
+ }
47
+
48
+ this.status({fill: fill, shape: shape, text: text});
49
+ }
50
+ }
51
+
52
+ module.exports = ContactNode;
package/src/ui/BaseUI.js CHANGED
@@ -75,9 +75,7 @@ export class BaseUI {
75
75
  item.setAttribute("id","node-container-" + id);
76
76
  item.innerHTML = '\
77
77
  <div style="display: inline-flex; width: calc(100% - 105px)">\
78
- <div id="input-select-'+ id +'" style="flex-grow: 1;">\
79
- <input type="checkbox" id="' + prefix + id +'" style="flex: 15px;">\
80
- </div>\
78
+ <input type="checkbox" id="' + prefix + id +'" style="flex: 15px;">\
81
79
  <span style="width: 100%; margin-left: 10px;">\
82
80
  '+ label +'\
83
81
  </span>\
@@ -0,0 +1,27 @@
1
+ import { ServiceUI } from "./ServiceUI.js"
2
+
3
+ export class CameraMotionUI extends ServiceUI {
4
+ constructor() {
5
+ super("Camera Motion","hue services","camera_motion");
6
+ console.log("CameraMotionUI.constructor()");
7
+
8
+ this.config.color = "#FFC0FF";
9
+ this.config.icon = "font-awesome/fa-rss";
10
+ }
11
+
12
+ buildHelp() {
13
+ var help = super.buildHelp();
14
+ help["Outputs"] += "\
15
+ The CameraMotion node only has one output. It will listen to events for the specified service \
16
+ and forward them to the output as `msg.payload` which contains the motion events in a \
17
+ JSON format conform the clip v2 specification.\n\n\
18
+ Please see the Hue CLIP API documentation: \n\n\
19
+ https://developers.meethue.com/develop/hue-api-v2";
20
+ return help;
21
+ }
22
+
23
+ onEditPrepare(config) {
24
+ super.onEditPrepare(config);
25
+ $('#node-container-rtype').hide();
26
+ }
27
+ }
@@ -0,0 +1,27 @@
1
+ import { ServiceUI } from "./ServiceUI.js"
2
+
3
+ export class ContactUI extends ServiceUI {
4
+ constructor() {
5
+ super("Contact","hue services","contact");
6
+ console.log("ContactUI.constructor()");
7
+
8
+ this.config.color = "#FFD8FF";
9
+ this.config.icon = "font-awesome/fa-step-forward";
10
+ }
11
+
12
+ buildHelp() {
13
+ var help = super.buildHelp();
14
+ help["Outputs"] += "\
15
+ The Contact node only has one output. It will listen to events for the specified service \
16
+ and forward them to the output as `msg.payload` which contains the contact events in a \
17
+ JSON format conform the clip v2 specification.\n\n\
18
+ Please see the Hue CLIP API documentation: \n\n\
19
+ https://developers.meethue.com/develop/hue-api-v2";
20
+ return help;
21
+ }
22
+
23
+ onEditPrepare(config) {
24
+ super.onEditPrepare(config);
25
+ $('#node-container-rtype').hide();
26
+ }
27
+ }