node-red-contrib-homekit-bridged 2.0.0-dev.0 → 2.0.0-dev.10

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 (125) hide show
  1. package/build/lib/HAPHostNode.js +185 -148
  2. package/build/lib/HAPServiceNode.js +200 -177
  3. package/build/lib/HAPServiceNode2.js +208 -177
  4. package/build/lib/NRCHKBError.js +23 -2
  5. package/build/lib/PairingQRCode.js +62 -0
  6. package/build/lib/Storage.js +152 -90
  7. package/build/lib/api.js +654 -291
  8. package/build/lib/camera/CameraControl.js +125 -0
  9. package/build/lib/camera/CameraDelegate.js +507 -0
  10. package/build/lib/camera/MP4StreamingServer.js +159 -0
  11. package/build/lib/hap/HAPCharacteristic.js +25 -4
  12. package/build/lib/hap/HAPService.js +25 -4
  13. package/build/lib/hap/eve-app/EveCharacteristics.js +124 -81
  14. package/build/lib/hap/eve-app/EveServices.js +50 -17
  15. package/build/lib/hap/hap-nodejs.js +32 -0
  16. package/build/lib/migration/HomeKitService2Migration.js +34 -0
  17. package/build/lib/migration/NodeMigration.js +75 -0
  18. package/build/lib/types/AccessoryInformationType.js +15 -1
  19. package/build/lib/types/CameraConfigType.js +15 -1
  20. package/build/lib/types/CustomCharacteristicType.js +15 -1
  21. package/build/lib/types/HAPHostConfigType.js +15 -1
  22. package/build/lib/types/HAPHostNodeType.js +15 -1
  23. package/build/lib/types/HAPService2ConfigType.js +15 -1
  24. package/build/lib/types/HAPService2NodeType.js +15 -1
  25. package/build/lib/types/HAPServiceConfigType.js +15 -1
  26. package/build/lib/types/HAPServiceNodeType.js +15 -1
  27. package/build/lib/types/HAPStatusConfigType.js +15 -1
  28. package/build/lib/types/HAPStatusNodeType.js +15 -1
  29. package/build/lib/types/HostType.js +28 -7
  30. package/build/lib/types/NodeType.js +15 -1
  31. package/build/lib/types/PublishTimersType.js +15 -1
  32. package/build/lib/types/UniFiControllerConfigType.js +16 -0
  33. package/build/lib/types/hap-nodejs/HapAdaptiveLightingControllerMode.js +28 -7
  34. package/build/lib/types/hap-nodejs/HapCategories.js +64 -43
  35. package/build/lib/types/storage/SerializedHostType.js +15 -1
  36. package/build/lib/types/storage/StorageType.js +34 -10
  37. package/build/lib/unifi/ProtectDiscovery.js +80 -0
  38. package/build/lib/utils/AccessoryUtils.js +152 -110
  39. package/build/lib/utils/BridgeUtils.js +95 -39
  40. package/build/lib/utils/CharacteristicUtils.js +5 -49
  41. package/build/lib/utils/CharacteristicUtils2.js +5 -49
  42. package/build/lib/utils/CharacteristicUtilsBase.js +81 -0
  43. package/build/lib/utils/NodeStatusUtils.js +89 -40
  44. package/build/lib/utils/ServiceUtils.js +433 -371
  45. package/build/lib/utils/ServiceUtils2.js +519 -305
  46. package/build/lib/utils/index.js +11 -12
  47. package/build/nodes/bridge.html +206 -168
  48. package/build/nodes/bridge.js +27 -9
  49. package/build/nodes/locales/en-US/node-red-contrib-homekit-bridged.json +22 -0
  50. package/build/nodes/nrchkb.html +1753 -117
  51. package/build/nodes/nrchkb.js +66 -88
  52. package/build/nodes/plugin-instance.html +509 -0
  53. package/build/nodes/plugin-instance.js +46 -0
  54. package/build/nodes/service.html +557 -306
  55. package/build/nodes/service.js +5 -6
  56. package/build/nodes/service2.html +1735 -455
  57. package/build/nodes/service2.js +5 -8
  58. package/build/nodes/standalone.html +208 -176
  59. package/build/nodes/standalone.js +27 -9
  60. package/build/nodes/status.html +51 -18
  61. package/build/nodes/status.js +47 -41
  62. package/build/nodes/unifi-controller.html +92 -0
  63. package/build/nodes/unifi-controller.js +20 -0
  64. package/build/plugins/embedded/homebridge-camera-ffmpeg/index.js +479 -0
  65. package/build/plugins/embedded/homebridge-unifi-protect/index.js +521 -0
  66. package/build/plugins/embedded/index.js +58 -0
  67. package/build/plugins/nrchkb-homekit-plugins.js +17 -0
  68. package/build/plugins/registry/index.js +203 -0
  69. package/build/plugins/registry/types.js +16 -0
  70. package/build/scripts/migrate-homekit-service-flows.js +47 -0
  71. package/examples/demo/01 - ALL Demos single import.json +1885 -2139
  72. package/examples/demo/02 - Air Purifier.json +12 -61
  73. package/examples/demo/03 - Air Quality sensor with Battery.json +8 -36
  74. package/examples/demo/04 - Dimmable Bulb.json +4 -21
  75. package/examples/demo/05 - Color Bulb (HSV).json +5 -26
  76. package/examples/demo/06 - Fan (simple, 3 speeds).json +6 -31
  77. package/examples/demo/07 - Fan (with speed, oscillate, rotation direction).json +4 -21
  78. package/examples/demo/08 - CO2 detector.json +8 -39
  79. package/examples/demo/09 - CO (carbon monoxide) example.json +9 -44
  80. package/examples/demo/10 - Door window contact sensor.json +8 -39
  81. package/examples/demos (advanced)/01 - Television with inputs and speaker.json +19 -85
  82. package/examples/switch/01 - Plain Switch.json +179 -199
  83. package/package.json +48 -34
  84. package/build/lib/HAPHostNode.d.ts +0 -1
  85. package/build/lib/HAPServiceNode.d.ts +0 -1
  86. package/build/lib/HAPServiceNode2.d.ts +0 -1
  87. package/build/lib/NRCHKBError.d.ts +0 -3
  88. package/build/lib/Storage.d.ts +0 -30
  89. package/build/lib/api.d.ts +0 -1
  90. package/build/lib/hap/HAPCharacteristic.d.ts +0 -9
  91. package/build/lib/hap/HAPService.d.ts +0 -6
  92. package/build/lib/hap/eve-app/EveCharacteristics.d.ts +0 -20
  93. package/build/lib/hap/eve-app/EveServices.d.ts +0 -5
  94. package/build/lib/types/AccessoryInformationType.d.ts +0 -11
  95. package/build/lib/types/CameraConfigType.d.ts +0 -24
  96. package/build/lib/types/CustomCharacteristicType.d.ts +0 -6
  97. package/build/lib/types/HAPHostConfigType.d.ts +0 -22
  98. package/build/lib/types/HAPHostNodeType.d.ts +0 -14
  99. package/build/lib/types/HAPService2ConfigType.d.ts +0 -6
  100. package/build/lib/types/HAPService2NodeType.d.ts +0 -7
  101. package/build/lib/types/HAPServiceConfigType.d.ts +0 -26
  102. package/build/lib/types/HAPServiceNodeType.d.ts +0 -38
  103. package/build/lib/types/HAPStatusConfigType.d.ts +0 -5
  104. package/build/lib/types/HAPStatusNodeType.d.ts +0 -12
  105. package/build/lib/types/HostType.d.ts +0 -5
  106. package/build/lib/types/NodeType.d.ts +0 -3
  107. package/build/lib/types/PublishTimersType.d.ts +0 -4
  108. package/build/lib/types/hap-nodejs/HapAdaptiveLightingControllerMode.d.ts +0 -5
  109. package/build/lib/types/hap-nodejs/HapCategories.d.ts +0 -41
  110. package/build/lib/types/storage/SerializedHostType.d.ts +0 -5
  111. package/build/lib/types/storage/StorageType.d.ts +0 -8
  112. package/build/lib/utils/AccessoryUtils.d.ts +0 -1
  113. package/build/lib/utils/BridgeUtils.d.ts +0 -1
  114. package/build/lib/utils/CharacteristicUtils.d.ts +0 -1
  115. package/build/lib/utils/CharacteristicUtils2.d.ts +0 -1
  116. package/build/lib/utils/NodeStatusUtils.d.ts +0 -17
  117. package/build/lib/utils/ServiceUtils.d.ts +0 -1
  118. package/build/lib/utils/ServiceUtils2.d.ts +0 -1
  119. package/build/lib/utils/index.d.ts +0 -1
  120. package/build/nodes/bridge.d.ts +0 -1
  121. package/build/nodes/nrchkb.d.ts +0 -1
  122. package/build/nodes/service.d.ts +0 -1
  123. package/build/nodes/service2.d.ts +0 -1
  124. package/build/nodes/standalone.d.ts +0 -1
  125. package/build/nodes/status.d.ts +0 -1
@@ -1,2141 +1,1887 @@
1
1
  [
2
- {
3
- "id": "2c464315.51c50c",
4
- "type": "group",
5
- "z": "eeb8b00c.2c18c",
6
- "name": "Fan Full Example: input from device, output to device",
7
- "style": {
8
- "stroke": "#999999",
9
- "fill": "none",
10
- "label": true,
11
- "label-position": "nw",
12
- "color": "#a4a4a4"
13
- },
14
- "nodes": [
15
- "b7778e52.220a5",
16
- "fd8aff55.91d41",
17
- "c717b796.0735b8",
18
- "f56a2f96.509c1",
19
- "d945ba75.897998"
20
- ],
21
- "x": 94,
22
- "y": 1559,
23
- "w": 752,
24
- "h": 182,
25
- "info": "# Fan V2\n\nThis example shows a fan. The inputs from node red are to turn the fan on, off, or set \"No Response\".\n\nThe outputs going to \"Fan output\" will show:\n\nOn / off state <br/>\nRotation speed<br/>\nSwing mode on / off (oscillate) <br/>\nRotation direction (clockwise/counterclockwise)"
26
- },
27
- {
28
- "id": "b7778e52.220a5",
29
- "type": "debug",
30
- "z": "eeb8b00c.2c18c",
31
- "g": "2c464315.51c50c",
32
- "name": "Fan output",
33
- "active": true,
34
- "tosidebar": true,
35
- "console": false,
36
- "tostatus": false,
37
- "complete": "payload",
38
- "targetType": "msg",
39
- "x": 730,
40
- "y": 1600,
41
- "wires": []
42
- },
43
- {
44
- "id": "fd8aff55.91d41",
45
- "type": "homekit-service",
46
- "z": "eeb8b00c.2c18c",
47
- "g": "2c464315.51c50c",
48
- "isParent": true,
49
- "bridge": "409001a1.3e7a78",
50
- "parentService": "",
51
- "name": "Fan V2",
52
- "serviceName": "Fanv2",
53
- "topic": "",
54
- "filter": false,
55
- "manufacturer": "Default Manufacturer",
56
- "model": "Default Model",
57
- "serialNo": "Default Serial Number",
58
- "firmwareRev": "1.0.0",
59
- "hardwareRev": "1.0.0",
60
- "softwareRev": "1.0.0",
61
- "cameraConfigVideoProcessor": "ffmpeg",
62
- "cameraConfigSource": "",
63
- "cameraConfigStillImageSource": "",
64
- "cameraConfigMaxStreams": 2,
65
- "cameraConfigMaxWidth": 1280,
66
- "cameraConfigMaxHeight": 720,
67
- "cameraConfigMaxFPS": 10,
68
- "cameraConfigMaxBitrate": 300,
69
- "cameraConfigVideoCodec": "libx264",
70
- "cameraConfigAudioCodec": "libfdk_aac",
71
- "cameraConfigAudio": false,
72
- "cameraConfigPacketSize": 1316,
73
- "cameraConfigVerticalFlip": false,
74
- "cameraConfigHorizontalFlip": false,
75
- "cameraConfigMapVideo": "0:0",
76
- "cameraConfigMapAudio": "0:1",
77
- "cameraConfigVideoFilter": "scale=1280:720",
78
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
79
- "cameraConfigDebug": false,
80
- "cameraConfigSnapshotOutput": "disabled",
81
- "cameraConfigInterfaceName": "",
82
- "characteristicProperties": "{\n \"RotationSpeed\":true,\n \"RotationDirection\":true,\n \"SwingMode\":true\n}",
83
- "outputs": 2,
84
- "x": 500,
85
- "y": 1600,
86
- "wires": [
87
- [
88
- "b7778e52.220a5"
89
- ],
90
- []
91
- ]
92
- },
93
- {
94
- "id": "c717b796.0735b8",
95
- "type": "inject",
96
- "z": "eeb8b00c.2c18c",
97
- "g": "2c464315.51c50c",
98
- "name": "NO RESPONSE",
99
- "repeat": "",
100
- "crontab": "",
101
- "once": false,
102
- "onceDelay": 0.1,
103
- "topic": "",
104
- "payload": "{\"Active\":\"NO_RESPONSE\"}",
105
- "payloadType": "json",
106
- "x": 220,
107
- "y": 1700,
108
- "wires": [
109
- [
110
- "fd8aff55.91d41"
111
- ]
112
- ]
113
- },
114
- {
115
- "id": "f56a2f96.509c1",
116
- "type": "inject",
117
- "z": "eeb8b00c.2c18c",
118
- "g": "2c464315.51c50c",
119
- "name": "ON",
120
- "props": [
121
- {
122
- "p": "payload"
123
- },
124
- {
125
- "p": "topic",
126
- "vt": "str"
127
- }
128
- ],
129
- "repeat": "",
130
- "crontab": "",
131
- "once": false,
132
- "onceDelay": 0.1,
133
- "topic": "",
134
- "payload": "{\"Active\":true}",
135
- "payloadType": "json",
136
- "x": 200,
137
- "y": 1600,
138
- "wires": [
139
- [
140
- "fd8aff55.91d41"
141
- ]
142
- ]
143
- },
144
- {
145
- "id": "d945ba75.897998",
146
- "type": "inject",
147
- "z": "eeb8b00c.2c18c",
148
- "g": "2c464315.51c50c",
149
- "name": "OFF",
150
- "props": [
151
- {
152
- "p": "payload"
153
- },
154
- {
155
- "p": "topic",
156
- "vt": "str"
157
- }
158
- ],
159
- "repeat": "",
160
- "crontab": "",
161
- "once": false,
162
- "onceDelay": 0.1,
163
- "topic": "",
164
- "payload": "{\"Active\":false}",
165
- "payloadType": "json",
166
- "x": 200,
167
- "y": 1640,
168
- "wires": [
169
- [
170
- "fd8aff55.91d41"
171
- ]
172
- ]
173
- },
174
- {
175
- "id": "409001a1.3e7a78",
176
- "type": "homekit-bridge",
177
- "bridgeName": "Demo 1",
178
- "pinCode": "153-10-538",
179
- "port": "",
180
- "allowInsecureRequest": false,
181
- "manufacturer": "NRCHKB",
182
- "model": "Demo",
183
- "serialNo": "1.1.2",
184
- "customMdnsConfig": false,
185
- "mdnsMulticast": true,
186
- "mdnsInterface": "",
187
- "mdnsPort": "",
188
- "mdnsIp": "",
189
- "mdnsTtl": "",
190
- "mdnsLoopback": true,
191
- "mdnsReuseAddr": true,
192
- "allowMessagePassthrough": true
193
- },
194
- {
195
- "id": "384e0889.1fdae",
196
- "type": "group",
197
- "z": "eeb8b00c.2c18c",
198
- "name": "Color Bulb: input from device, output to device",
199
- "style": {
200
- "stroke": "#999999",
201
- "fill": "none",
202
- "label": true,
203
- "label-position": "nw",
204
- "color": "#a4a4a4"
205
- },
206
- "nodes": [
207
- "d838176b.dbaf7",
208
- "7bf880d4.3cd4d",
209
- "ee1452a5.08edd",
210
- "c6ed2a2a.90a01",
211
- "8cdfae2b.2f2ce8",
212
- "1758401b.6c62e8"
213
- ],
214
- "x": 94,
215
- "y": 599,
216
- "w": 752,
217
- "h": 162,
218
- "info": "# Color Bulb\n\nThis is a color bulb. It accepts and sends out Hue, Saturation, Value, and On/off state.\n\nHue is the color\n\nSaturation is how deep the color is\n\nValue is brightness\n\nOn is power state"
219
- },
220
- {
221
- "id": "d838176b.dbaf7",
222
- "type": "debug",
223
- "z": "eeb8b00c.2c18c",
224
- "g": "384e0889.1fdae",
225
- "name": "Color light output",
226
- "active": true,
227
- "tosidebar": true,
228
- "console": false,
229
- "tostatus": false,
230
- "complete": "payload",
231
- "targetType": "msg",
232
- "x": 710,
233
- "y": 720,
234
- "wires": []
235
- },
236
- {
237
- "id": "7bf880d4.3cd4d",
238
- "type": "homekit-service",
239
- "z": "eeb8b00c.2c18c",
240
- "g": "384e0889.1fdae",
241
- "isParent": true,
242
- "hostType": "0",
243
- "bridge": "409001a1.3e7a78",
244
- "accessoryId": "",
245
- "parentService": "",
246
- "name": "Color",
247
- "serviceName": "Lightbulb",
248
- "topic": "",
249
- "filter": false,
250
- "manufacturer": "Garrett",
251
- "model": "Color",
252
- "serialNo": "42",
253
- "firmwareRev": "1.2",
254
- "hardwareRev": "1.0.0",
255
- "softwareRev": "1.0.0",
256
- "cameraConfigVideoProcessor": "ffmpeg",
257
- "cameraConfigSource": "",
258
- "cameraConfigStillImageSource": "",
259
- "cameraConfigMaxStreams": 2,
260
- "cameraConfigMaxWidth": 1280,
261
- "cameraConfigMaxHeight": 720,
262
- "cameraConfigMaxFPS": 10,
263
- "cameraConfigMaxBitrate": 300,
264
- "cameraConfigVideoCodec": "libx264",
265
- "cameraConfigAudioCodec": "libfdk_aac",
266
- "cameraConfigAudio": false,
267
- "cameraConfigPacketSize": 1316,
268
- "cameraConfigVerticalFlip": false,
269
- "cameraConfigHorizontalFlip": false,
270
- "cameraConfigMapVideo": "0:0",
271
- "cameraConfigMapAudio": "0:1",
272
- "cameraConfigVideoFilter": "scale=1280:720",
273
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
274
- "cameraConfigDebug": false,
275
- "cameraConfigSnapshotOutput": "disabled",
276
- "cameraConfigInterfaceName": "",
277
- "characteristicProperties": "{ \"Brightness\":true, \"Hue\":true, \"Saturation\":true}",
278
- "waitForSetupMsg": false,
279
- "outputs": 2,
280
- "x": 490,
281
- "y": 720,
282
- "wires": [
283
- [
284
- "d838176b.dbaf7"
285
- ],
286
- []
287
- ]
288
- },
289
- {
290
- "id": "ee1452a5.08edd",
291
- "type": "inject",
292
- "z": "eeb8b00c.2c18c",
293
- "g": "384e0889.1fdae",
294
- "name": "NO RESPONSE",
295
- "props": [
296
- {
297
- "p": "payload"
298
- }
299
- ],
300
- "repeat": "",
301
- "crontab": "",
302
- "once": false,
303
- "onceDelay": 0.1,
304
- "topic": "",
305
- "payload": "{\"On\":\"NO_RESPONSE\"}",
306
- "payloadType": "json",
307
- "x": 420,
308
- "y": 640,
309
- "wires": [
310
- [
311
- "7bf880d4.3cd4d"
312
- ]
313
- ]
314
- },
315
- {
316
- "id": "c6ed2a2a.90a01",
317
- "type": "inject",
318
- "z": "eeb8b00c.2c18c",
319
- "g": "384e0889.1fdae",
320
- "name": "ON",
321
- "props": [
322
- {
323
- "p": "payload"
324
- }
325
- ],
326
- "repeat": "",
327
- "crontab": "",
328
- "once": false,
329
- "onceDelay": 0.1,
330
- "topic": "",
331
- "payload": "{\"On\":true}",
332
- "payloadType": "json",
333
- "x": 190,
334
- "y": 640,
335
- "wires": [
336
- [
337
- "7bf880d4.3cd4d"
338
- ]
339
- ]
340
- },
341
- {
342
- "id": "8cdfae2b.2f2ce8",
343
- "type": "inject",
344
- "z": "eeb8b00c.2c18c",
345
- "g": "384e0889.1fdae",
346
- "name": "Reset HSV",
347
- "props": [
348
- {
349
- "p": "payload"
350
- }
351
- ],
352
- "repeat": "",
353
- "crontab": "",
354
- "once": false,
355
- "onceDelay": 0.1,
356
- "topic": "",
357
- "payload": "{\"Brightness\":50,\"Hue\":50,\"Saturation\":50}",
358
- "payloadType": "json",
359
- "x": 200,
360
- "y": 720,
361
- "wires": [
362
- [
363
- "7bf880d4.3cd4d"
364
- ]
365
- ]
366
- },
367
- {
368
- "id": "1758401b.6c62e8",
369
- "type": "inject",
370
- "z": "eeb8b00c.2c18c",
371
- "g": "384e0889.1fdae",
372
- "name": "OFF",
373
- "props": [
374
- {
375
- "p": "payload"
376
- }
377
- ],
378
- "repeat": "",
379
- "crontab": "",
380
- "once": false,
381
- "onceDelay": 0.1,
382
- "topic": "",
383
- "payload": "{\"On\":false}",
384
- "payloadType": "json",
385
- "x": 190,
386
- "y": 680,
387
- "wires": [
388
- [
389
- "7bf880d4.3cd4d"
390
- ]
391
- ]
392
- },
393
- {
394
- "id": "3a57bebe.a3b222",
395
- "type": "group",
396
- "z": "eeb8b00c.2c18c",
397
- "name": "Dimmable Bulb: input from device, output to device",
398
- "style": {
399
- "stroke": "#999999",
400
- "fill": "none",
401
- "label": true,
402
- "label-position": "nw",
403
- "color": "#a4a4a4"
404
- },
405
- "nodes": [
406
- "459254fe.49c72c",
407
- "379657db.a99df8",
408
- "52a07047.03ce7",
409
- "253b3550.729caa",
410
- "b9bc7f3d.51acf"
411
- ],
412
- "x": 94,
413
- "y": 459,
414
- "w": 752,
415
- "h": 122,
416
- "info": "# Dimmable Bulb\n\nThis is a dimmable bulb. The Characteristic Properties enable brightness. It is a white bulb which can be adjusted from 0 to 100% brightness."
417
- },
418
- {
419
- "id": "459254fe.49c72c",
420
- "type": "homekit-service",
421
- "z": "eeb8b00c.2c18c",
422
- "g": "3a57bebe.a3b222",
423
- "isParent": true,
424
- "hostType": "0",
425
- "bridge": "409001a1.3e7a78",
426
- "accessoryId": "",
427
- "parentService": "",
428
- "name": "Dimmable",
429
- "serviceName": "Lightbulb",
430
- "topic": "",
431
- "filter": false,
432
- "manufacturer": "Garrett",
433
- "model": "Dummy",
434
- "serialNo": "Default Serial Number",
435
- "firmwareRev": "1.1.9",
436
- "hardwareRev": "1.0.0",
437
- "softwareRev": "1.0.0",
438
- "cameraConfigVideoProcessor": "ffmpeg",
439
- "cameraConfigSource": "",
440
- "cameraConfigStillImageSource": "",
441
- "cameraConfigMaxStreams": 2,
442
- "cameraConfigMaxWidth": 1280,
443
- "cameraConfigMaxHeight": 720,
444
- "cameraConfigMaxFPS": 10,
445
- "cameraConfigMaxBitrate": 300,
446
- "cameraConfigVideoCodec": "libx264",
447
- "cameraConfigAudioCodec": "libfdk_aac",
448
- "cameraConfigAudio": false,
449
- "cameraConfigPacketSize": 1316,
450
- "cameraConfigVerticalFlip": false,
451
- "cameraConfigHorizontalFlip": false,
452
- "cameraConfigMapVideo": "0:0",
453
- "cameraConfigMapAudio": "0:1",
454
- "cameraConfigVideoFilter": "scale=1280:720",
455
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
456
- "cameraConfigDebug": false,
457
- "cameraConfigSnapshotOutput": "disabled",
458
- "cameraConfigInterfaceName": "",
459
- "characteristicProperties": "{ \"Brightness\":true}",
460
- "waitForSetupMsg": false,
461
- "outputs": 2,
462
- "x": 460,
463
- "y": 540,
464
- "wires": [
465
- [
466
- "379657db.a99df8"
467
- ],
468
- []
469
- ]
470
- },
471
- {
472
- "id": "379657db.a99df8",
473
- "type": "debug",
474
- "z": "eeb8b00c.2c18c",
475
- "g": "3a57bebe.a3b222",
476
- "name": "Dimmable light output",
477
- "active": true,
478
- "tosidebar": true,
479
- "console": false,
480
- "tostatus": false,
481
- "complete": "payload",
482
- "targetType": "msg",
483
- "x": 700,
484
- "y": 540,
485
- "wires": []
486
- },
487
- {
488
- "id": "52a07047.03ce7",
489
- "type": "inject",
490
- "z": "eeb8b00c.2c18c",
491
- "g": "3a57bebe.a3b222",
492
- "name": "NO RESPONSE",
493
- "props": [
494
- {
495
- "p": "payload"
496
- }
497
- ],
498
- "repeat": "",
499
- "crontab": "",
500
- "once": false,
501
- "onceDelay": 0.1,
502
- "topic": "",
503
- "payload": "{\"On\":\"NO_RESPONSE\"}",
504
- "payloadType": "json",
505
- "x": 400,
506
- "y": 500,
507
- "wires": [
508
- [
509
- "459254fe.49c72c"
510
- ]
511
- ]
512
- },
513
- {
514
- "id": "253b3550.729caa",
515
- "type": "inject",
516
- "z": "eeb8b00c.2c18c",
517
- "g": "3a57bebe.a3b222",
518
- "name": "ON",
519
- "props": [
520
- {
521
- "p": "payload"
522
- }
523
- ],
524
- "repeat": "",
525
- "crontab": "",
526
- "once": false,
527
- "onceDelay": 0.1,
528
- "topic": "",
529
- "payload": "{\"On\":true}",
530
- "payloadType": "json",
531
- "x": 190,
532
- "y": 500,
533
- "wires": [
534
- [
535
- "459254fe.49c72c"
536
- ]
537
- ]
538
- },
539
- {
540
- "id": "b9bc7f3d.51acf",
541
- "type": "inject",
542
- "z": "eeb8b00c.2c18c",
543
- "g": "3a57bebe.a3b222",
544
- "name": "OFF",
545
- "props": [
546
- {
547
- "p": "payload"
548
- }
549
- ],
550
- "repeat": "",
551
- "crontab": "",
552
- "once": false,
553
- "onceDelay": 0.1,
554
- "topic": "",
555
- "payload": "{\"On\":false}",
556
- "payloadType": "json",
557
- "x": 190,
558
- "y": 540,
559
- "wires": [
560
- [
561
- "459254fe.49c72c"
562
- ]
563
- ]
564
- },
565
- {
566
- "id": "60e44fde.c914f8",
567
- "type": "group",
568
- "z": "eeb8b00c.2c18c",
569
- "name": "Air Purifier: input power state, output commands device",
570
- "style": {
571
- "stroke": "#999999",
572
- "fill": "none",
573
- "label": true,
574
- "label-position": "nw",
575
- "color": "#a4a4a4"
576
- },
577
- "nodes": [
578
- "8dea49.4a770db8",
579
- "5302e4aa.1b466c",
580
- "bfe1c73d.c165a8",
581
- "9739d842.a402f",
582
- "87048a6e.df64e8",
583
- "db412cea.4a62f8",
584
- "46418e19.aa6d6",
585
- "664dadf9.85d0d4",
586
- "d7cd8a56.628178",
587
- "3de34c4c.1871a4",
588
- "ee8894e4.f1855"
589
- ],
590
- "x": 94,
591
- "y": 59,
592
- "w": 822,
593
- "h": 162,
594
- "info": "Turning the device on or off will send:\n`{\"Active\":[0, 1]}`\n\nAfter changing power state, the device will be \"Turning on\" or \"Turning off\" until a current state is sent of:\n`{\"CurrentAirPurifierState\":[0, 1, 2]}`\n0: off <br/>\n1: idle <br/>\n2: on <br/>\n\nThere will be a slider in the home app for sending `RotationSpeed`\n\nThere will be a switch on Home app for \"Oscillate\" which sends:\n`{\"SwingMode\":[0,1]}`\n\nChanging mode to manual to auto will send payload:\n`{\"TargetAirPurifierState\":[0, 1]}`\n\nChild lock will send \n`{\"LockPhysicalControls\": [0, 1]}`\n\n"
595
- },
596
- {
597
- "id": "8dea49.4a770db8",
598
- "type": "inject",
599
- "z": "eeb8b00c.2c18c",
600
- "g": "60e44fde.c914f8",
601
- "name": "off",
602
- "props": [
603
- {
604
- "p": "payload"
605
- }
606
- ],
607
- "repeat": "",
608
- "crontab": "",
609
- "once": false,
610
- "onceDelay": 0.1,
611
- "topic": "",
612
- "payload": "{\"CurrentAirPurifierState\":0}",
613
- "payloadType": "json",
614
- "x": 190,
615
- "y": 100,
616
- "wires": [
617
- [
618
- "5302e4aa.1b466c"
619
- ]
620
- ]
621
- },
622
- {
623
- "id": "5302e4aa.1b466c",
624
- "type": "homekit-service",
625
- "z": "eeb8b00c.2c18c",
626
- "g": "60e44fde.c914f8",
627
- "isParent": true,
628
- "bridge": "409001a1.3e7a78",
629
- "parentService": "",
630
- "name": "Air purifier",
631
- "serviceName": "AirPurifier",
632
- "topic": "",
633
- "filter": false,
634
- "manufacturer": "Purity",
635
- "model": "Air",
636
- "serialNo": "23",
637
- "firmwareRev": "1.0.0",
638
- "hardwareRev": "1.0.0",
639
- "softwareRev": "1.0.0",
640
- "cameraConfigVideoProcessor": "ffmpeg",
641
- "cameraConfigSource": "",
642
- "cameraConfigStillImageSource": "",
643
- "cameraConfigMaxStreams": 2,
644
- "cameraConfigMaxWidth": 1280,
645
- "cameraConfigMaxHeight": 720,
646
- "cameraConfigMaxFPS": 10,
647
- "cameraConfigMaxBitrate": 300,
648
- "cameraConfigVideoCodec": "libx264",
649
- "cameraConfigAudioCodec": "libfdk_aac",
650
- "cameraConfigAudio": false,
651
- "cameraConfigPacketSize": 1316,
652
- "cameraConfigVerticalFlip": false,
653
- "cameraConfigHorizontalFlip": false,
654
- "cameraConfigMapVideo": "0:0",
655
- "cameraConfigMapAudio": "0:1",
656
- "cameraConfigVideoFilter": "scale=1280:720",
657
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
658
- "cameraConfigDebug": false,
659
- "cameraConfigSnapshotOutput": "disabled",
660
- "cameraConfigInterfaceName": "",
661
- "characteristicProperties": "{\n \"SwingMode\":true,\n \"RotationSpeed\":true,\n \"LockPhysicalControls\":true\n}",
662
- "outputs": 2,
663
- "x": 370,
664
- "y": 100,
665
- "wires": [
666
- [
667
- "bfe1c73d.c165a8",
668
- "9739d842.a402f"
669
- ],
670
- []
671
- ]
672
- },
673
- {
674
- "id": "bfe1c73d.c165a8",
675
- "type": "debug",
676
- "z": "eeb8b00c.2c18c",
677
- "g": "60e44fde.c914f8",
678
- "name": "Purifier output",
679
- "active": true,
680
- "tosidebar": true,
681
- "console": false,
682
- "tostatus": false,
683
- "complete": "true",
684
- "targetType": "full",
685
- "x": 500,
686
- "y": 180,
687
- "wires": []
688
- },
689
- {
690
- "id": "9739d842.a402f",
691
- "type": "function",
692
- "z": "eeb8b00c.2c18c",
693
- "g": "60e44fde.c914f8",
694
- "name": "on/off",
695
- "func": "if (msg.hap !== undefined && msg.hap.context !== undefined){\n if (msg.payload.Active === 1){\n return [msg,null];\n }\n if (msg.payload.Active === 0){\n return [null,msg];\n }\n}\nreturn;",
696
- "outputs": 2,
697
- "noerr": 0,
698
- "initialize": "",
699
- "finalize": "",
700
- "x": 530,
701
- "y": 100,
702
- "wires": [
703
- [
704
- "664dadf9.85d0d4",
705
- "d7cd8a56.628178"
706
- ],
707
- [
708
- "3de34c4c.1871a4"
709
- ]
710
- ],
711
- "outputLabels": [
712
- "On",
713
- "Off"
714
- ]
715
- },
716
- {
717
- "id": "87048a6e.df64e8",
718
- "type": "inject",
719
- "z": "eeb8b00c.2c18c",
720
- "g": "60e44fde.c914f8",
721
- "name": "idle",
722
- "props": [
723
- {
724
- "p": "payload"
725
- }
726
- ],
727
- "repeat": "",
728
- "crontab": "",
729
- "once": false,
730
- "onceDelay": 0.1,
731
- "topic": "",
732
- "payload": "{\"CurrentAirPurifierState\":1}",
733
- "payloadType": "json",
734
- "x": 190,
735
- "y": 140,
736
- "wires": [
737
- [
738
- "5302e4aa.1b466c"
739
- ]
740
- ]
741
- },
742
- {
743
- "id": "db412cea.4a62f8",
744
- "type": "inject",
745
- "z": "eeb8b00c.2c18c",
746
- "g": "60e44fde.c914f8",
747
- "name": "on",
748
- "props": [
749
- {
750
- "p": "payload"
751
- }
752
- ],
753
- "repeat": "",
754
- "crontab": "",
755
- "once": false,
756
- "onceDelay": 0.1,
757
- "topic": "",
758
- "payload": "{\"CurrentAirPurifierState\":2}",
759
- "payloadType": "json",
760
- "x": 190,
761
- "y": 180,
762
- "wires": [
763
- [
764
- "5302e4aa.1b466c"
765
- ]
766
- ]
767
- },
768
- {
769
- "id": "46418e19.aa6d6",
770
- "type": "link in",
771
- "z": "eeb8b00c.2c18c",
772
- "g": "60e44fde.c914f8",
773
- "name": "",
774
- "links": [
775
- "ee8894e4.f1855"
776
- ],
777
- "x": 315,
778
- "y": 180,
779
- "wires": [
780
- [
781
- "5302e4aa.1b466c"
782
- ]
783
- ]
784
- },
785
- {
786
- "id": "664dadf9.85d0d4",
787
- "type": "trigger",
788
- "z": "eeb8b00c.2c18c",
789
- "g": "60e44fde.c914f8",
790
- "name": "5 sec to idle",
791
- "op1": "",
792
- "op2": "{\"CurrentAirPurifierState\":1}",
793
- "op1type": "nul",
794
- "op2type": "json",
795
- "duration": "5",
796
- "extend": false,
797
- "units": "s",
798
- "reset": "",
799
- "bytopic": "all",
800
- "topic": "topic",
801
- "outputs": 1,
802
- "x": 730,
803
- "y": 100,
804
- "wires": [
805
- [
806
- "ee8894e4.f1855"
807
- ]
808
- ]
809
- },
810
- {
811
- "id": "d7cd8a56.628178",
812
- "type": "trigger",
813
- "z": "eeb8b00c.2c18c",
814
- "g": "60e44fde.c914f8",
815
- "name": "10 sec to on",
816
- "op1": "",
817
- "op2": "{\"CurrentAirPurifierState\":2}",
818
- "op1type": "nul",
819
- "op2type": "json",
820
- "duration": "10",
821
- "extend": false,
822
- "units": "s",
823
- "reset": "",
824
- "bytopic": "all",
825
- "topic": "topic",
826
- "outputs": 1,
827
- "x": 730,
828
- "y": 140,
829
- "wires": [
830
- [
831
- "ee8894e4.f1855"
832
- ]
833
- ]
834
- },
835
- {
836
- "id": "3de34c4c.1871a4",
837
- "type": "trigger",
838
- "z": "eeb8b00c.2c18c",
839
- "g": "60e44fde.c914f8",
840
- "name": "5 sec to off",
841
- "op1": "",
842
- "op2": "{\"CurrentAirPurifierState\":0}",
843
- "op1type": "nul",
844
- "op2type": "json",
845
- "duration": "5",
846
- "extend": false,
847
- "units": "s",
848
- "reset": "",
849
- "bytopic": "all",
850
- "topic": "topic",
851
- "outputs": 1,
852
- "x": 730,
853
- "y": 180,
854
- "wires": [
855
- [
856
- "ee8894e4.f1855"
857
- ]
858
- ]
859
- },
860
- {
861
- "id": "ee8894e4.f1855",
862
- "type": "link out",
863
- "z": "eeb8b00c.2c18c",
864
- "g": "60e44fde.c914f8",
865
- "name": "",
866
- "links": [
867
- "46418e19.aa6d6"
868
- ],
869
- "x": 875,
870
- "y": 140,
871
- "wires": []
872
- },
873
- {
874
- "id": "6eaa9b9e.282734",
875
- "type": "group",
876
- "z": "eeb8b00c.2c18c",
877
- "name": "CO plus CO2 Sensor: input only sensor",
878
- "style": {
879
- "stroke": "#999999",
880
- "fill": "none",
881
- "label": true,
882
- "label-position": "nw",
883
- "color": "#a4a4a4"
884
- },
885
- "nodes": [
886
- "2e6738a6.ef5dd8",
887
- "79889759.8219c",
888
- "7f53465b.356a68",
889
- "97aff586.786ff8",
890
- "659ff3da.236404",
891
- "e6105066.f8911",
892
- "b433a780.665a7",
893
- "d4b30334.a19e58",
894
- "b0eeeb34.2dde8"
895
- ],
896
- "x": 94,
897
- "y": 999,
898
- "w": 752,
899
- "h": 282,
900
- "info": "# Combined Sensor\nThis is a sensor which will display both Carbon Monoxide (poisonous, deadly gas) and Carbon Dioxide (what humans exhale) levels.\n\n# CO Sensor\n\nThere are three inputs to this example, one for each level of Carbon Monoxide in the air. Options are:\n\n**0 ppm:** this will assume no CO in the air <br/>\n**Low level:** this will assume a level between 1 and 35 ppm, inclusive. This level is generally assumed to not cause problems in healthy adults <br/>\n**Dangerous level:** this will assume a level between 35 and 5000, inclusive; this will also trigger an alert in Home app\n\n## IF YOU HAVE A CARBON MONOXIDE DETECTOR EVER READING ABOVE 35 PPM, PLEASE EVACUATE THE AREA AND SEEK FRESH AIR IMMEDIATELY TO AVOID RISK OF DEATH ##\n\n# CO2 Sensor\n\nThere are three inputs to this example, one for each level of Carbon Dioxide in the air. Options are:\n\n**0 ppm:** this will assume no CO2 in the air <br/>\n**CO2 Level:** this will assume a level between 1 and 100,000 ppm, inclusive <br/>\n**Dangerous level:** this will assume a level between 1,000 and 100,000, inclusive\n\n"
901
- },
902
- {
903
- "id": "2e6738a6.ef5dd8",
904
- "type": "homekit-service",
905
- "z": "eeb8b00c.2c18c",
906
- "g": "6eaa9b9e.282734",
907
- "isParent": true,
908
- "hostType": "0",
909
- "bridge": "409001a1.3e7a78",
910
- "accessoryId": "",
911
- "parentService": "",
912
- "name": "CO detector",
913
- "serviceName": "CarbonMonoxideSensor",
914
- "topic": "",
915
- "filter": false,
916
- "manufacturer": "MONOxide",
917
- "model": "1",
918
- "serialNo": "2",
919
- "firmwareRev": "2",
920
- "hardwareRev": "2",
921
- "softwareRev": "1.0.0",
922
- "cameraConfigVideoProcessor": "ffmpeg",
923
- "cameraConfigSource": "",
924
- "cameraConfigStillImageSource": "",
925
- "cameraConfigMaxStreams": 2,
926
- "cameraConfigMaxWidth": 1280,
927
- "cameraConfigMaxHeight": 720,
928
- "cameraConfigMaxFPS": 10,
929
- "cameraConfigMaxBitrate": 300,
930
- "cameraConfigVideoCodec": "libx264",
931
- "cameraConfigAudioCodec": "libfdk_aac",
932
- "cameraConfigAudio": false,
933
- "cameraConfigPacketSize": 1316,
934
- "cameraConfigVerticalFlip": false,
935
- "cameraConfigHorizontalFlip": false,
936
- "cameraConfigMapVideo": "0:0",
937
- "cameraConfigMapAudio": "0:1",
938
- "cameraConfigVideoFilter": "scale=1280:720",
939
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
940
- "cameraConfigDebug": false,
941
- "cameraConfigSnapshotOutput": "disabled",
942
- "cameraConfigInterfaceName": "",
943
- "characteristicProperties": "{ \"CarbonMonoxideLevel\":{ \"maxValue\":5000 }, \"CarbonMonoxidePeakLevel\":{ \"maxValue\":5000 }, \"CarbonDioxideLevel\":true, \"CarbonDioxidePeakLevel\":true}",
944
- "waitForSetupMsg": false,
945
- "outputs": 2,
946
- "x": 750,
947
- "y": 1040,
948
- "wires": [
949
- [],
950
- []
951
- ]
952
- },
953
- {
954
- "id": "79889759.8219c",
955
- "type": "function",
956
- "z": "eeb8b00c.2c18c",
957
- "g": "6eaa9b9e.282734",
958
- "name": "Carbon DIoxide",
959
- "func": "if(msg.payload === 0){\n context.set('lastPeak',0);\n newMsg = {\n payload: {\n \"CarbonDioxideLevel\":0\n }\n }\n return newMsg;\n}\n\n// Initialize vars\nvar CurrentLevel = 0;\nvar lastPeak = context.get('lastPeak');\n\n// Set random level\nif(msg.payload === \"CO2\"){\n CurrentLevel = Math.floor(Math.random() * (100000 - 1 + 1) + 1);\n}\n\n\n// Formulate output message\nvar newMsg = {\n payload: {\n \"CarbonDioxideLevel\" : CurrentLevel\n }\n};\n\n// Set new peak level\nif(CurrentLevel > lastPeak){\n lastPeak = CurrentLevel;\n context.set('lastPeak',CurrentLevel);\n newMsg.payload.CarbonDioxidePeakLevel = CurrentLevel;\n}\n\nreturn newMsg;",
960
- "outputs": 1,
961
- "noerr": 0,
962
- "initialize": "// Code added here will be run once\n// whenever the node is deployed.\ncontext.set('lastPeak',0);",
963
- "finalize": "",
964
- "x": 460,
965
- "y": 1200,
966
- "wires": [
967
- [
968
- "2e6738a6.ef5dd8"
969
- ]
970
- ]
971
- },
972
- {
973
- "id": "7f53465b.356a68",
974
- "type": "function",
975
- "z": "eeb8b00c.2c18c",
976
- "g": "6eaa9b9e.282734",
977
- "name": "Carbon MONoxide",
978
- "func": "// Reset all values to 0 if 0ppm input\nif(msg.payload === 0){\n context.set('lastPeak',0);\n newMsg = {\n payload: {\n \"CarbonMonoxideLevel\":0,\n \"CarbonMonoxidePeakLevel\":0,\n \"CarbonMonoxideDetected\":0\n }\n };\n return newMsg;\n}\n\n// Initialize vars\nvar CurrentLevel = 0;\nvar lastPeak = context.get('lastPeak');\n\n// Set random Low or Dangerous levels\nif(msg.payload === \"Low\"){\n CurrentLevel = Math.floor(Math.random() * (35 - 1 + 1) + 1);\n}\nif(msg.payload === \"Danger\"){\n CurrentLevel = Math.floor(Math.random() * (5000 - 35 + 1) + 35);\n}\n\n// Formulate output message\nvar newMsg = {\n payload: {\n \"CarbonMonoxideLevel\" : CurrentLevel,\n \"CarbonMonoxideDetected\" : 0\n }\n};\n\n// Set new peak level\nif(CurrentLevel > lastPeak){\n lastPeak = CurrentLevel;\n context.set('lastPeak',CurrentLevel);\n newMsg.payload.CarbonMonoxidePeakLevel = CurrentLevel;\n}\n\n// Set warning if dangerous\nif (CurrentLevel >= 35) {\n newMsg.payload.CarbonMonoxideDetected = 1;\n} \n\nreturn newMsg;",
979
- "outputs": 1,
980
- "noerr": 0,
981
- "initialize": "",
982
- "finalize": "",
983
- "x": 470,
984
- "y": 1080,
985
- "wires": [
986
- [
987
- "2e6738a6.ef5dd8"
988
- ]
989
- ]
990
- },
991
- {
992
- "id": "97aff586.786ff8",
993
- "type": "inject",
994
- "z": "eeb8b00c.2c18c",
995
- "g": "6eaa9b9e.282734",
996
- "name": "NO RESPONSE",
997
- "props": [
998
- {
999
- "p": "payload"
1000
- },
1001
- {
1002
- "p": "topic",
1003
- "vt": "str"
1004
- }
1005
- ],
1006
- "repeat": "",
1007
- "crontab": "",
1008
- "once": false,
1009
- "onceDelay": 0.1,
1010
- "topic": "",
1011
- "payload": "{\"CarbonMonoxideLevel\":\"NO_RESPONSE\"}",
1012
- "payloadType": "json",
1013
- "x": 480,
1014
- "y": 1040,
1015
- "wires": [
1016
- [
1017
- "2e6738a6.ef5dd8"
1018
- ]
1019
- ]
1020
- },
1021
- {
1022
- "id": "659ff3da.236404",
1023
- "type": "inject",
1024
- "z": "eeb8b00c.2c18c",
1025
- "g": "6eaa9b9e.282734",
1026
- "name": "Clear CO2 Peak",
1027
- "props": [
1028
- {
1029
- "p": "payload"
1030
- }
1031
- ],
1032
- "repeat": "",
1033
- "crontab": "",
1034
- "once": false,
1035
- "onceDelay": 0.1,
1036
- "topic": "",
1037
- "payload": "0",
1038
- "payloadType": "num",
1039
- "x": 220,
1040
- "y": 1200,
1041
- "wires": [
1042
- [
1043
- "79889759.8219c"
1044
- ]
1045
- ]
1046
- },
1047
- {
1048
- "id": "e6105066.f8911",
1049
- "type": "inject",
1050
- "z": "eeb8b00c.2c18c",
1051
- "g": "6eaa9b9e.282734",
1052
- "name": "0 ppm",
1053
- "repeat": "",
1054
- "crontab": "",
1055
- "once": false,
1056
- "onceDelay": 0.1,
1057
- "topic": "",
1058
- "payload": "0",
1059
- "payloadType": "num",
1060
- "x": 210,
1061
- "y": 1040,
1062
- "wires": [
1063
- [
1064
- "7f53465b.356a68"
1065
- ]
1066
- ]
1067
- },
1068
- {
1069
- "id": "b433a780.665a7",
1070
- "type": "inject",
1071
- "z": "eeb8b00c.2c18c",
1072
- "g": "6eaa9b9e.282734",
1073
- "name": "CO2 Level",
1074
- "props": [
1075
- {
1076
- "p": "payload"
1077
- }
1078
- ],
1079
- "repeat": "",
1080
- "crontab": "",
1081
- "once": false,
1082
- "onceDelay": 0.1,
1083
- "topic": "",
1084
- "payload": "CO2",
1085
- "payloadType": "str",
1086
- "x": 200,
1087
- "y": 1240,
1088
- "wires": [
1089
- [
1090
- "79889759.8219c"
1091
- ]
1092
- ]
1093
- },
1094
- {
1095
- "id": "d4b30334.a19e58",
1096
- "type": "inject",
1097
- "z": "eeb8b00c.2c18c",
1098
- "g": "6eaa9b9e.282734",
1099
- "name": "Low level",
1100
- "props": [
1101
- {
1102
- "p": "payload"
1103
- }
1104
- ],
1105
- "repeat": "",
1106
- "crontab": "",
1107
- "once": false,
1108
- "onceDelay": 0.1,
1109
- "topic": "",
1110
- "payload": "Low",
1111
- "payloadType": "str",
1112
- "x": 220,
1113
- "y": 1080,
1114
- "wires": [
1115
- [
1116
- "7f53465b.356a68"
1117
- ]
1118
- ]
1119
- },
1120
- {
1121
- "id": "b0eeeb34.2dde8",
1122
- "type": "inject",
1123
- "z": "eeb8b00c.2c18c",
1124
- "g": "6eaa9b9e.282734",
1125
- "name": "Danger level",
1126
- "props": [
1127
- {
1128
- "p": "payload"
1129
- }
1130
- ],
1131
- "repeat": "",
1132
- "crontab": "",
1133
- "once": false,
1134
- "onceDelay": 0.1,
1135
- "topic": "",
1136
- "payload": "Danger",
1137
- "payloadType": "str",
1138
- "x": 230,
1139
- "y": 1120,
1140
- "wires": [
1141
- [
1142
- "7f53465b.356a68"
1143
- ]
1144
- ]
1145
- },
1146
- {
1147
- "id": "a875cc7.a4c42b",
1148
- "type": "group",
1149
- "z": "eeb8b00c.2c18c",
1150
- "name": "Contact Sensor: input only sensor",
1151
- "style": {
1152
- "stroke": "#999999",
1153
- "fill": "none",
1154
- "label": true,
1155
- "label-position": "nw",
1156
- "color": "#a4a4a4"
1157
- },
1158
- "nodes": [
1159
- "a5194c26.18c628",
1160
- "2f9bc0d.42a73c",
1161
- "dfca0b2d.8b8e8",
1162
- "d74a610c.09a36",
1163
- "c15b6468.ae2eb8",
1164
- "6f7bc7fa.7f4f6",
1165
- "99b55eb3.e31bf8",
1166
- "508d9ccf.29e404"
1167
- ],
1168
- "x": 94,
1169
- "y": 1299,
1170
- "w": 752,
1171
- "h": 242,
1172
- "info": "# Contact Sensor\n\nThe contact sensor has one inject node to Open the sensor (door, window, etc). Once open, a ten second timer will run then set it back to closed.\n\nAdditional inputs are for \"No Response\", \"Tampered\", and \"Battery\". Note that this battery will not show a battery level but only a good/low battery status."
1173
- },
1174
- {
1175
- "id": "a5194c26.18c628",
1176
- "type": "homekit-service",
1177
- "z": "eeb8b00c.2c18c",
1178
- "g": "a875cc7.a4c42b",
1179
- "isParent": true,
1180
- "hostType": "0",
1181
- "bridge": "409001a1.3e7a78",
1182
- "accessoryId": "",
1183
- "parentService": "",
1184
- "name": "Contact Sensor",
1185
- "serviceName": "ContactSensor",
1186
- "topic": "",
1187
- "filter": false,
1188
- "manufacturer": "Full Contact",
1189
- "model": "Door",
1190
- "serialNo": "Sensor",
1191
- "firmwareRev": "1.0.0",
1192
- "hardwareRev": "1.0.0",
1193
- "softwareRev": "1.0.0",
1194
- "cameraConfigVideoProcessor": "ffmpeg",
1195
- "cameraConfigSource": "",
1196
- "cameraConfigStillImageSource": "",
1197
- "cameraConfigMaxStreams": 2,
1198
- "cameraConfigMaxWidth": 1280,
1199
- "cameraConfigMaxHeight": 720,
1200
- "cameraConfigMaxFPS": 10,
1201
- "cameraConfigMaxBitrate": 300,
1202
- "cameraConfigVideoCodec": "libx264",
1203
- "cameraConfigAudioCodec": "libfdk_aac",
1204
- "cameraConfigAudio": false,
1205
- "cameraConfigPacketSize": 1316,
1206
- "cameraConfigVerticalFlip": false,
1207
- "cameraConfigHorizontalFlip": false,
1208
- "cameraConfigMapVideo": "0:0",
1209
- "cameraConfigMapAudio": "0:1",
1210
- "cameraConfigVideoFilter": "scale=1280:720",
1211
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
1212
- "cameraConfigDebug": false,
1213
- "cameraConfigSnapshotOutput": "disabled",
1214
- "cameraConfigInterfaceName": "",
1215
- "characteristicProperties": "{ \"StatusTampered\":true, \"StatusLowBattery\":true}",
1216
- "waitForSetupMsg": false,
1217
- "outputs": 2,
1218
- "x": 740,
1219
- "y": 1340,
1220
- "wires": [
1221
- [],
1222
- []
1223
- ]
1224
- },
1225
- {
1226
- "id": "2f9bc0d.42a73c",
1227
- "type": "inject",
1228
- "z": "eeb8b00c.2c18c",
1229
- "g": "a875cc7.a4c42b",
1230
- "name": "Tampered",
1231
- "repeat": "",
1232
- "crontab": "",
1233
- "once": false,
1234
- "onceDelay": 0.1,
1235
- "topic": "",
1236
- "payload": "{\"StatusTampered\":1}",
1237
- "payloadType": "json",
1238
- "x": 200,
1239
- "y": 1460,
1240
- "wires": [
1241
- [
1242
- "a5194c26.18c628"
1243
- ]
1244
- ]
1245
- },
1246
- {
1247
- "id": "dfca0b2d.8b8e8",
1248
- "type": "inject",
1249
- "z": "eeb8b00c.2c18c",
1250
- "g": "a875cc7.a4c42b",
1251
- "name": "Clear tampered",
1252
- "repeat": "",
1253
- "crontab": "",
1254
- "once": false,
1255
- "onceDelay": 0.1,
1256
- "topic": "",
1257
- "payload": "{\"StatusTampered\":0}",
1258
- "payloadType": "json",
1259
- "x": 220,
1260
- "y": 1500,
1261
- "wires": [
1262
- [
1263
- "a5194c26.18c628"
1264
- ]
1265
- ]
1266
- },
1267
- {
1268
- "id": "d74a610c.09a36",
1269
- "type": "inject",
1270
- "z": "eeb8b00c.2c18c",
1271
- "g": "a875cc7.a4c42b",
1272
- "name": "Low batt",
1273
- "repeat": "",
1274
- "crontab": "",
1275
- "once": false,
1276
- "onceDelay": 0.1,
1277
- "topic": "",
1278
- "payload": "{\"StatusLowBattery\":1}",
1279
- "payloadType": "json",
1280
- "x": 560,
1281
- "y": 1460,
1282
- "wires": [
1283
- [
1284
- "a5194c26.18c628"
1285
- ]
1286
- ]
1287
- },
1288
- {
1289
- "id": "c15b6468.ae2eb8",
1290
- "type": "inject",
1291
- "z": "eeb8b00c.2c18c",
1292
- "g": "a875cc7.a4c42b",
1293
- "name": "Good batt",
1294
- "repeat": "",
1295
- "crontab": "",
1296
- "once": false,
1297
- "onceDelay": 0.1,
1298
- "topic": "",
1299
- "payload": "{\"StatusLowBattery\":0}",
1300
- "payloadType": "json",
1301
- "x": 560,
1302
- "y": 1500,
1303
- "wires": [
1304
- [
1305
- "a5194c26.18c628"
1306
- ]
1307
- ]
1308
- },
1309
- {
1310
- "id": "6f7bc7fa.7f4f6",
1311
- "type": "inject",
1312
- "z": "eeb8b00c.2c18c",
1313
- "g": "a875cc7.a4c42b",
1314
- "name": "NO RESPONSE",
1315
- "props": [
1316
- {
1317
- "p": "payload"
1318
- },
1319
- {
1320
- "p": "topic",
1321
- "vt": "str"
1322
- }
1323
- ],
1324
- "repeat": "",
1325
- "crontab": "",
1326
- "once": false,
1327
- "onceDelay": 0.1,
1328
- "topic": "",
1329
- "payload": "{\"ContactSensorState\":\"NO_RESPONSE\"}",
1330
- "payloadType": "json",
1331
- "x": 220,
1332
- "y": 1400,
1333
- "wires": [
1334
- [
1335
- "a5194c26.18c628"
1336
- ]
1337
- ]
1338
- },
1339
- {
1340
- "id": "99b55eb3.e31bf8",
1341
- "type": "trigger",
1342
- "z": "eeb8b00c.2c18c",
1343
- "g": "a875cc7.a4c42b",
1344
- "name": "10 Sec open",
1345
- "op1": "",
1346
- "op2": "{\"ContactSensorState\":0}",
1347
- "op1type": "pay",
1348
- "op2type": "json",
1349
- "duration": "10",
1350
- "extend": false,
1351
- "units": "s",
1352
- "reset": "",
1353
- "bytopic": "all",
1354
- "topic": "topic",
1355
- "outputs": 1,
1356
- "x": 430,
1357
- "y": 1340,
1358
- "wires": [
1359
- [
1360
- "a5194c26.18c628"
1361
- ]
1362
- ]
1363
- },
1364
- {
1365
- "id": "508d9ccf.29e404",
1366
- "type": "inject",
1367
- "z": "eeb8b00c.2c18c",
1368
- "g": "a875cc7.a4c42b",
1369
- "name": "Open",
1370
- "props": [
1371
- {
1372
- "p": "payload"
1373
- },
1374
- {
1375
- "p": "topic",
1376
- "vt": "str"
1377
- }
1378
- ],
1379
- "repeat": "",
1380
- "crontab": "",
1381
- "once": false,
1382
- "onceDelay": "1",
1383
- "topic": "",
1384
- "payload": "{\"ContactSensorState\":1}",
1385
- "payloadType": "json",
1386
- "x": 190,
1387
- "y": 1340,
1388
- "wires": [
1389
- [
1390
- "99b55eb3.e31bf8"
1391
- ]
1392
- ]
1393
- },
1394
- {
1395
- "id": "ab48426e.25466",
1396
- "type": "group",
1397
- "z": "eeb8b00c.2c18c",
1398
- "name": "CO2 Sensor: input only sensor",
1399
- "style": {
1400
- "stroke": "#999999",
1401
- "fill": "none",
1402
- "label": true,
1403
- "label-position": "nw",
1404
- "color": "#a4a4a4"
1405
- },
1406
- "nodes": [
1407
- "88892b4.8a61bd8",
1408
- "3611c654.8a42f2",
1409
- "62cafcb0.8ade9c",
1410
- "a0171cdb.f209b",
1411
- "6f7de764.a6a688",
1412
- "8758b463.afb0f",
1413
- "69e8161b.74b7a",
1414
- "40010b09.c73cdc"
1415
- ],
1416
- "x": 94,
1417
- "y": 779,
1418
- "w": 752,
1419
- "h": 202,
1420
- "info": "# CO2 Sensor\n\nThere are three inputs to this example, one for each level of Carbon Dioxide in the air. Options are:\n\n**0 ppm:** this will assume no CO2 <br/>\n**Safe level:** this will assume a level between 1 and 999 ppm, inclusive <br/>\n**Dangerous level:** this will assume a level between 1,000 and 100,000, inclusive; this will also trigger an alert"
1421
- },
1422
- {
1423
- "id": "88892b4.8a61bd8",
1424
- "type": "homekit-service",
1425
- "z": "eeb8b00c.2c18c",
1426
- "g": "ab48426e.25466",
1427
- "isParent": true,
1428
- "hostType": "0",
1429
- "bridge": "409001a1.3e7a78",
1430
- "accessoryId": "",
1431
- "parentService": "",
1432
- "name": "CO2 Sensor",
1433
- "serviceName": "CarbonDioxideSensor",
1434
- "topic": "",
1435
- "filter": false,
1436
- "manufacturer": "Default Manufacturer",
1437
- "model": "Carbon",
1438
- "serialNo": "Default Serial Number",
1439
- "firmwareRev": "22",
1440
- "hardwareRev": "11",
1441
- "softwareRev": "",
1442
- "cameraConfigVideoProcessor": "",
1443
- "cameraConfigSource": "",
1444
- "cameraConfigStillImageSource": "",
1445
- "cameraConfigMaxStreams": "",
1446
- "cameraConfigMaxWidth": "",
1447
- "cameraConfigMaxHeight": "",
1448
- "cameraConfigMaxFPS": "",
1449
- "cameraConfigMaxBitrate": "",
1450
- "cameraConfigVideoCodec": "",
1451
- "cameraConfigAudioCodec": "",
1452
- "cameraConfigAudio": false,
1453
- "cameraConfigPacketSize": "",
1454
- "cameraConfigVerticalFlip": false,
1455
- "cameraConfigHorizontalFlip": false,
1456
- "cameraConfigMapVideo": "",
1457
- "cameraConfigMapAudio": "",
1458
- "cameraConfigVideoFilter": "",
1459
- "cameraConfigAdditionalCommandLine": "",
1460
- "cameraConfigDebug": false,
1461
- "cameraConfigSnapshotOutput": "disabled",
1462
- "cameraConfigInterfaceName": "",
1463
- "characteristicProperties": "{ \"CarbonDioxideLevel\" : true, \"CarbonDioxidePeakLevel\": true, \"StatusActive\" : true}",
1464
- "waitForSetupMsg": false,
1465
- "outputs": 2,
1466
- "x": 750,
1467
- "y": 820,
1468
- "wires": [
1469
- [],
1470
- []
1471
- ]
1472
- },
1473
- {
1474
- "id": "3611c654.8a42f2",
1475
- "type": "function",
1476
- "z": "eeb8b00c.2c18c",
1477
- "g": "ab48426e.25466",
1478
- "name": "Random values, peak value",
1479
- "func": "// Reset all values to 0 if 0ppm input\nif(msg.payload === 0){\n context.set('lastPeak',0);\n newMsg = {\n payload: {\n \"CarbonDioxideLevel\":0,\n \"CarbonDioxidePeakLevel\":0,\n \"CarbonDioxideDetected\":0\n }\n };\n return newMsg;\n}\n\n// Initialize vars\nvar CurrentLevel = 0;\nvar lastPeak = context.get('lastPeak');\n\n// Set random safe or dangerous levels\nif(msg.payload === \"Safe\"){\n CurrentLevel = Math.floor(Math.random() * (999 - 1 + 1) + 1);\n}\nif(msg.payload === \"Danger\"){\n CurrentLevel = Math.floor(Math.random() * (100000 - 1000 + 1) + 1000);\n}\n\n// Formulate output message\nvar newMsg = {\n payload: {\n \"CarbonDioxideLevel\" : CurrentLevel,\n \"CarbonDioxideDetected\" : 0\n }\n};\n\n// Set new peak level\nif(CurrentLevel > lastPeak){\n lastPeak = CurrentLevel;\n context.set('lastPeak',CurrentLevel);\n newMsg.payload.CarbonDioxidePeakLevel = CurrentLevel;\n}\n\n// Set warning if dangerous\nif (CurrentLevel >= 1000) {\n newMsg.payload.CarbonDioxideDetected = 1;\n} \n\nreturn newMsg;",
1480
- "outputs": 1,
1481
- "noerr": 0,
1482
- "initialize": "// Code added here will be run once\n// whenever the node is deployed.\ncontext.set('lastPeak',0);\n",
1483
- "finalize": "",
1484
- "x": 480,
1485
- "y": 820,
1486
- "wires": [
1487
- [
1488
- "88892b4.8a61bd8"
1489
- ]
1490
- ]
1491
- },
1492
- {
1493
- "id": "62cafcb0.8ade9c",
1494
- "type": "inject",
1495
- "z": "eeb8b00c.2c18c",
1496
- "g": "ab48426e.25466",
1497
- "name": "Active",
1498
- "repeat": "",
1499
- "crontab": "",
1500
- "once": false,
1501
- "onceDelay": 0.1,
1502
- "topic": "",
1503
- "payload": "{\"StatusActive\":true}",
1504
- "payloadType": "json",
1505
- "x": 550,
1506
- "y": 860,
1507
- "wires": [
1508
- [
1509
- "88892b4.8a61bd8"
1510
- ]
1511
- ]
1512
- },
1513
- {
1514
- "id": "a0171cdb.f209b",
1515
- "type": "inject",
1516
- "z": "eeb8b00c.2c18c",
1517
- "g": "ab48426e.25466",
1518
- "name": "Inactive",
1519
- "repeat": "",
1520
- "crontab": "",
1521
- "once": false,
1522
- "onceDelay": 0.1,
1523
- "topic": "",
1524
- "payload": "{\"StatusActive\":false}",
1525
- "payloadType": "json",
1526
- "x": 550,
1527
- "y": 900,
1528
- "wires": [
1529
- [
1530
- "88892b4.8a61bd8"
1531
- ]
1532
- ]
1533
- },
1534
- {
1535
- "id": "6f7de764.a6a688",
1536
- "type": "inject",
1537
- "z": "eeb8b00c.2c18c",
1538
- "g": "ab48426e.25466",
1539
- "name": "NO RESPONSE",
1540
- "repeat": "",
1541
- "crontab": "",
1542
- "once": false,
1543
- "onceDelay": 0.1,
1544
- "topic": "",
1545
- "payload": "{\"CarbonDioxideLevel\":\"NO_RESPONSE\"}",
1546
- "payloadType": "json",
1547
- "x": 520,
1548
- "y": 940,
1549
- "wires": [
1550
- [
1551
- "88892b4.8a61bd8"
1552
- ]
1553
- ]
1554
- },
1555
- {
1556
- "id": "8758b463.afb0f",
1557
- "type": "inject",
1558
- "z": "eeb8b00c.2c18c",
1559
- "g": "ab48426e.25466",
1560
- "name": "0 ppm",
1561
- "props": [
1562
- {
1563
- "p": "payload"
1564
- }
1565
- ],
1566
- "repeat": "",
1567
- "crontab": "",
1568
- "once": false,
1569
- "onceDelay": 0.1,
1570
- "topic": "",
1571
- "payload": "0",
1572
- "payloadType": "num",
1573
- "x": 190,
1574
- "y": 820,
1575
- "wires": [
1576
- [
1577
- "3611c654.8a42f2"
1578
- ]
1579
- ]
1580
- },
1581
- {
1582
- "id": "69e8161b.74b7a",
1583
- "type": "inject",
1584
- "z": "eeb8b00c.2c18c",
1585
- "g": "ab48426e.25466",
1586
- "name": "Safe Level",
1587
- "props": [
1588
- {
1589
- "p": "payload"
1590
- }
1591
- ],
1592
- "repeat": "",
1593
- "crontab": "",
1594
- "once": false,
1595
- "onceDelay": 0.1,
1596
- "topic": "",
1597
- "payload": "Safe",
1598
- "payloadType": "str",
1599
- "x": 200,
1600
- "y": 860,
1601
- "wires": [
1602
- [
1603
- "3611c654.8a42f2"
1604
- ]
1605
- ]
1606
- },
1607
- {
1608
- "id": "40010b09.c73cdc",
1609
- "type": "inject",
1610
- "z": "eeb8b00c.2c18c",
1611
- "g": "ab48426e.25466",
1612
- "name": "Dangerous level",
1613
- "props": [
1614
- {
1615
- "p": "payload"
1616
- }
1617
- ],
1618
- "repeat": "",
1619
- "crontab": "",
1620
- "once": false,
1621
- "onceDelay": 0.1,
1622
- "topic": "",
1623
- "payload": "Danger",
1624
- "payloadType": "str",
1625
- "x": 220,
1626
- "y": 900,
1627
- "wires": [
1628
- [
1629
- "3611c654.8a42f2"
1630
- ]
1631
- ]
1632
- },
1633
- {
1634
- "id": "b3b5156e.cdf988",
1635
- "type": "group",
1636
- "z": "eeb8b00c.2c18c",
1637
- "name": "Air Quality with Battery: input only sensor",
1638
- "style": {
1639
- "stroke": "#999999",
1640
- "fill": "none",
1641
- "label": true,
1642
- "label-position": "nw",
1643
- "color": "#a4a4a4"
1644
- },
1645
- "nodes": [
1646
- "8088a797.e1a7c",
1647
- "a70b3192.dfb4f",
1648
- "d5708f5.036c87",
1649
- "90b692e4.b9f6c",
1650
- "54bfafbc.396898",
1651
- "560fc866.6de558",
1652
- "61e113b2.dbb714"
1653
- ],
1654
- "x": 94,
1655
- "y": 239,
1656
- "w": 758,
1657
- "h": 208,
1658
- "info": "# Air Quality Sensor\n\nThis sensor will inject random values for all of the air quality metrics available in the HomeKit spec. It will also inject random values for a linked battery service.\n\nWatch the input and Home app to learn how to see how things are working."
1659
- },
1660
- {
1661
- "id": "8088a797.e1a7c",
1662
- "type": "homekit-service",
1663
- "z": "eeb8b00c.2c18c",
1664
- "g": "b3b5156e.cdf988",
1665
- "isParent": true,
1666
- "hostType": "0",
1667
- "bridge": "409001a1.3e7a78",
1668
- "accessoryId": "",
1669
- "parentService": "",
1670
- "name": "Air Quality",
1671
- "serviceName": "AirQualitySensor",
1672
- "topic": "",
1673
- "filter": false,
1674
- "manufacturer": "Quality",
1675
- "model": "Battery",
1676
- "serialNo": "777",
1677
- "firmwareRev": "8.3",
1678
- "hardwareRev": "2.1",
1679
- "softwareRev": "1.0.0",
1680
- "cameraConfigVideoProcessor": "ffmpeg",
1681
- "cameraConfigSource": "",
1682
- "cameraConfigStillImageSource": "",
1683
- "cameraConfigMaxStreams": 2,
1684
- "cameraConfigMaxWidth": 1280,
1685
- "cameraConfigMaxHeight": 720,
1686
- "cameraConfigMaxFPS": 10,
1687
- "cameraConfigMaxBitrate": 300,
1688
- "cameraConfigVideoCodec": "libx264",
1689
- "cameraConfigAudioCodec": "libfdk_aac",
1690
- "cameraConfigAudio": false,
1691
- "cameraConfigPacketSize": 1316,
1692
- "cameraConfigVerticalFlip": false,
1693
- "cameraConfigHorizontalFlip": false,
1694
- "cameraConfigMapVideo": "0:0",
1695
- "cameraConfigMapAudio": "0:1",
1696
- "cameraConfigVideoFilter": "scale=1280:720",
1697
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
1698
- "cameraConfigDebug": false,
1699
- "cameraConfigSnapshotOutput": "disabled",
1700
- "cameraConfigInterfaceName": "",
1701
- "characteristicProperties": "{ \"AirQuality\":true, \"PM2_5Density\":true, \"PM10Density\":true}",
1702
- "waitForSetupMsg": false,
1703
- "outputs": 2,
1704
- "x": 750,
1705
- "y": 280,
1706
- "wires": [
1707
- [],
1708
- []
1709
- ]
1710
- },
1711
- {
1712
- "id": "a70b3192.dfb4f",
1713
- "type": "inject",
1714
- "z": "eeb8b00c.2c18c",
1715
- "g": "b3b5156e.cdf988",
1716
- "name": "Air quality random",
1717
- "props": [
1718
- {
1719
- "p": "payload"
1720
- }
1721
- ],
1722
- "repeat": "15",
1723
- "crontab": "",
1724
- "once": true,
1725
- "onceDelay": "5",
1726
- "topic": "",
1727
- "payload": "{}",
1728
- "payloadType": "json",
1729
- "x": 230,
1730
- "y": 280,
1731
- "wires": [
1732
- [
1733
- "560fc866.6de558"
1734
- ]
1735
- ]
1736
- },
1737
- {
1738
- "id": "d5708f5.036c87",
1739
- "type": "inject",
1740
- "z": "eeb8b00c.2c18c",
1741
- "g": "b3b5156e.cdf988",
1742
- "name": "Battery random",
1743
- "props": [
1744
- {
1745
- "p": "payload"
1746
- }
1747
- ],
1748
- "repeat": "30",
1749
- "crontab": "",
1750
- "once": true,
1751
- "onceDelay": "5",
1752
- "topic": "",
1753
- "payload": "",
1754
- "payloadType": "date",
1755
- "x": 220,
1756
- "y": 380,
1757
- "wires": [
1758
- [
1759
- "90b692e4.b9f6c"
1760
- ]
1761
- ]
1762
- },
1763
- {
1764
- "id": "90b692e4.b9f6c",
1765
- "type": "function",
1766
- "z": "eeb8b00c.2c18c",
1767
- "g": "b3b5156e.cdf988",
1768
- "name": "Batt",
1769
- "func": "// Define random battery level\nconst level = Math.floor(Math.random() * Math.floor(100))\nvar newMsg = {\n payload: {\n \"BatteryLevel\": level\n }\n};\n\n// Show \"Low Battery\" if less than 10%\nif (level < 10)newMsg.payload.StatusLowBattery = 1;\nelse newMsg.payload.StatusLowBattery = 0;\n\n// Show \"Charging\" if greater than 60%\nif (level > 60) newMsg.payload.ChargingState = 1;\nelse newMsg.payload.ChargingState = 0;\n\nreturn newMsg;",
1770
- "outputs": 1,
1771
- "noerr": 0,
1772
- "initialize": "",
1773
- "finalize": "",
1774
- "x": 470,
1775
- "y": 380,
1776
- "wires": [
1777
- [
1778
- "5cd5342a.cfd72c"
1779
- ]
1780
- ]
1781
- },
1782
- {
1783
- "id": "54bfafbc.396898",
1784
- "type": "inject",
1785
- "z": "eeb8b00c.2c18c",
1786
- "g": "b3b5156e.cdf988",
1787
- "name": "NO RESPONSE",
1788
- "props": [
1789
- {
1790
- "p": "payload"
1791
- }
1792
- ],
1793
- "repeat": "",
1794
- "crontab": "",
1795
- "once": false,
1796
- "onceDelay": 0.1,
1797
- "topic": "",
1798
- "payload": "{\"AirQuality\":\"NO_RESPONSE\"}",
1799
- "payloadType": "json",
1800
- "x": 500,
1801
- "y": 320,
1802
- "wires": [
1803
- [
1804
- "8088a797.e1a7c"
1805
- ]
1806
- ]
1807
- },
1808
- {
1809
- "id": "560fc866.6de558",
1810
- "type": "function",
1811
- "z": "eeb8b00c.2c18c",
1812
- "g": "b3b5156e.cdf988",
1813
- "name": "Random values",
1814
- "func": "var newMsg = {\n \"payload\":{\n \"AirQuality\":Math.floor(Math.random() * Math.floor(5)),\n \"PM2_5Density\":Math.floor(Math.random() * Math.floor(1000)),\n \"PM10Density\":Math.floor(Math.random() * Math.floor(1000)),\n \"OzoneDensity\":Math.floor(Math.random() * Math.floor(1000)),\n \"NitrogenDioxideDensity\":Math.floor(Math.random() * Math.floor(1000)),\n \"SulphurDioxideDensity\": Math.floor(Math.random() * Math.floor(1000))\n }\n}\n\n\n\nreturn newMsg;",
1815
- "outputs": 1,
1816
- "noerr": 0,
1817
- "initialize": "",
1818
- "finalize": "",
1819
- "x": 500,
1820
- "y": 280,
1821
- "wires": [
1822
- [
1823
- "8088a797.e1a7c"
1824
- ]
1825
- ]
1826
- },
1827
- {
1828
- "id": "61e113b2.dbb714",
1829
- "type": "group",
1830
- "z": "eeb8b00c.2c18c",
1831
- "g": "b3b5156e.cdf988",
1832
- "name": "LINKED",
1833
- "style": {
1834
- "stroke": "#0070c0",
1835
- "fill": "#bfdbef",
1836
- "label": true
1837
- },
1838
- "nodes": [
1839
- "5cd5342a.cfd72c"
1840
- ],
1841
- "x": 654,
1842
- "y": 339,
1843
- "w": 172,
1844
- "h": 82
1845
- },
1846
- {
1847
- "id": "5cd5342a.cfd72c",
1848
- "type": "homekit-service",
1849
- "z": "eeb8b00c.2c18c",
1850
- "g": "61e113b2.dbb714",
1851
- "isParent": false,
1852
- "bridge": "",
1853
- "accessoryId": "",
1854
- "parentService": "8088a797.e1a7c",
1855
- "name": "Battery",
1856
- "serviceName": "Battery",
1857
- "topic": "Air Quality",
1858
- "filter": false,
1859
- "manufacturer": "Default Manufacturer",
1860
- "model": "Default Model",
1861
- "serialNo": "Default Serial Number",
1862
- "firmwareRev": "1.0.0",
1863
- "hardwareRev": "1.0.0",
1864
- "softwareRev": "1.0.0",
1865
- "cameraConfigVideoProcessor": "ffmpeg",
1866
- "cameraConfigSource": "",
1867
- "cameraConfigStillImageSource": "",
1868
- "cameraConfigMaxStreams": 2,
1869
- "cameraConfigMaxWidth": 1280,
1870
- "cameraConfigMaxHeight": 720,
1871
- "cameraConfigMaxFPS": 10,
1872
- "cameraConfigMaxBitrate": 300,
1873
- "cameraConfigVideoCodec": "libx264",
1874
- "cameraConfigAudioCodec": "libfdk_aac",
1875
- "cameraConfigAudio": false,
1876
- "cameraConfigPacketSize": 1316,
1877
- "cameraConfigVerticalFlip": false,
1878
- "cameraConfigHorizontalFlip": false,
1879
- "cameraConfigMapVideo": "0:0",
1880
- "cameraConfigMapAudio": "0:1",
1881
- "cameraConfigVideoFilter": "scale=1280:720",
1882
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
1883
- "cameraConfigDebug": false,
1884
- "cameraConfigSnapshotOutput": "disabled",
1885
- "cameraConfigInterfaceName": "",
1886
- "characteristicProperties": "{}",
1887
- "waitForSetupMsg": false,
1888
- "outputs": 2,
1889
- "x": 740,
1890
- "y": 380,
1891
- "wires": [
1892
- [],
1893
- []
1894
- ]
1895
- },
1896
- {
1897
- "id": "c869b0a5.e4def8",
1898
- "type": "group",
1899
- "z": "eeb8b00c.2c18c",
1900
- "name": "Fan Simplified: input from device, output to device",
1901
- "style": {
1902
- "stroke": "#999999",
1903
- "fill": "none",
1904
- "label": true,
1905
- "label-position": "nw",
1906
- "color": "#a4a4a4"
1907
- },
1908
- "nodes": [
1909
- "dadd634c.ae2258",
1910
- "753e3777.49a1d",
1911
- "992f4930.012aa",
1912
- "2497a466.aa0e84",
1913
- "c53b76fb.7a3cc8",
1914
- "6c9646ee.1f3a18",
1915
- "1e42a8f3.cf008f"
1916
- ],
1917
- "x": 94,
1918
- "y": 1759,
1919
- "w": 752,
1920
- "h": 202,
1921
- "info": "# Fan Simple\n\nThis example is for a 3-speed fan.\n\nSpeeds are: <br/>\nLow = 33<br/>\nMedium = 66<br/>\nHigh = 99<br/>\n\nValues outside of this are restricted and will not work. The home app will \"snap\" to these values. Siri will respond to \"set fan to low/medium/high\" with the corresponding value."
1922
- },
1923
- {
1924
- "id": "dadd634c.ae2258",
1925
- "type": "debug",
1926
- "z": "eeb8b00c.2c18c",
1927
- "g": "c869b0a5.e4def8",
1928
- "name": "Fan output",
1929
- "active": true,
1930
- "tosidebar": true,
1931
- "console": false,
1932
- "tostatus": false,
1933
- "complete": "payload",
1934
- "targetType": "msg",
1935
- "statusVal": "",
1936
- "statusType": "auto",
1937
- "x": 730,
1938
- "y": 1800,
1939
- "wires": []
1940
- },
1941
- {
1942
- "id": "753e3777.49a1d",
1943
- "type": "homekit-service",
1944
- "z": "eeb8b00c.2c18c",
1945
- "g": "c869b0a5.e4def8",
1946
- "isParent": true,
1947
- "bridge": "409001a1.3e7a78",
1948
- "parentService": "",
1949
- "name": "Fan Speeds",
1950
- "serviceName": "Fan",
1951
- "topic": "",
1952
- "filter": false,
1953
- "manufacturer": "Gman",
1954
- "model": "Default Model",
1955
- "serialNo": "CRX1",
1956
- "firmwareRev": "1.0.0",
1957
- "hardwareRev": "1.0.0",
1958
- "softwareRev": "1.0.0",
1959
- "cameraConfigVideoProcessor": "ffmpeg",
1960
- "cameraConfigSource": "",
1961
- "cameraConfigStillImageSource": "",
1962
- "cameraConfigMaxStreams": 2,
1963
- "cameraConfigMaxWidth": 1280,
1964
- "cameraConfigMaxHeight": 720,
1965
- "cameraConfigMaxFPS": 10,
1966
- "cameraConfigMaxBitrate": 300,
1967
- "cameraConfigVideoCodec": "libx264",
1968
- "cameraConfigAudioCodec": "libfdk_aac",
1969
- "cameraConfigAudio": false,
1970
- "cameraConfigPacketSize": 1316,
1971
- "cameraConfigVerticalFlip": false,
1972
- "cameraConfigHorizontalFlip": false,
1973
- "cameraConfigMapVideo": "0:0",
1974
- "cameraConfigMapAudio": "0:1",
1975
- "cameraConfigVideoFilter": "scale=1280:720",
1976
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
1977
- "cameraConfigDebug": false,
1978
- "cameraConfigSnapshotOutput": "disabled",
1979
- "cameraConfigInterfaceName": "",
1980
- "characteristicProperties": "{\n \"RotationSpeed\": {\n \"minValue\":0,\n \"maxValue\":99,\n \"minStep\":33\n }\n}",
1981
- "outputs": 2,
1982
- "x": 510,
1983
- "y": 1800,
1984
- "wires": [
1985
- [
1986
- "dadd634c.ae2258"
1987
- ],
1988
- []
1989
- ]
1990
- },
1991
- {
1992
- "id": "992f4930.012aa",
1993
- "type": "inject",
1994
- "z": "eeb8b00c.2c18c",
1995
- "g": "c869b0a5.e4def8",
1996
- "name": "NO RESPONSE",
1997
- "props": [
1998
- {
1999
- "p": "payload"
2000
- },
2001
- {
2002
- "p": "topic",
2003
- "vt": "str"
2004
- }
2005
- ],
2006
- "repeat": "",
2007
- "crontab": "",
2008
- "once": false,
2009
- "onceDelay": 0.1,
2010
- "topic": "",
2011
- "payload": "{\"On\":\"NO_RESPONSE\"}",
2012
- "payloadType": "json",
2013
- "x": 460,
2014
- "y": 1880,
2015
- "wires": [
2016
- [
2017
- "753e3777.49a1d"
2018
- ]
2019
- ]
2020
- },
2021
- {
2022
- "id": "2497a466.aa0e84",
2023
- "type": "inject",
2024
- "z": "eeb8b00c.2c18c",
2025
- "g": "c869b0a5.e4def8",
2026
- "name": "OFF",
2027
- "props": [
2028
- {
2029
- "p": "payload"
2030
- },
2031
- {
2032
- "p": "topic",
2033
- "vt": "str"
2034
- }
2035
- ],
2036
- "repeat": "",
2037
- "crontab": "",
2038
- "once": false,
2039
- "onceDelay": 0.1,
2040
- "topic": "",
2041
- "payload": "{\"On\":false}",
2042
- "payloadType": "json",
2043
- "x": 190,
2044
- "y": 1800,
2045
- "wires": [
2046
- [
2047
- "753e3777.49a1d"
2048
- ]
2049
- ]
2050
- },
2051
- {
2052
- "id": "c53b76fb.7a3cc8",
2053
- "type": "inject",
2054
- "z": "eeb8b00c.2c18c",
2055
- "g": "c869b0a5.e4def8",
2056
- "name": "Low",
2057
- "props": [
2058
- {
2059
- "p": "payload"
2060
- },
2061
- {
2062
- "p": "topic",
2063
- "vt": "str"
2064
- }
2065
- ],
2066
- "repeat": "",
2067
- "crontab": "",
2068
- "once": false,
2069
- "onceDelay": 0.1,
2070
- "topic": "",
2071
- "payload": "{\"On\":true,\"RotationSpeed\":33}",
2072
- "payloadType": "json",
2073
- "x": 190,
2074
- "y": 1840,
2075
- "wires": [
2076
- [
2077
- "753e3777.49a1d"
2078
- ]
2079
- ]
2080
- },
2081
- {
2082
- "id": "6c9646ee.1f3a18",
2083
- "type": "inject",
2084
- "z": "eeb8b00c.2c18c",
2085
- "g": "c869b0a5.e4def8",
2086
- "name": "Medium",
2087
- "props": [
2088
- {
2089
- "p": "payload"
2090
- },
2091
- {
2092
- "p": "topic",
2093
- "vt": "str"
2094
- }
2095
- ],
2096
- "repeat": "",
2097
- "crontab": "",
2098
- "once": false,
2099
- "onceDelay": 0.1,
2100
- "topic": "",
2101
- "payload": "{\"On\":true,\"RotationSpeed\":66}",
2102
- "payloadType": "json",
2103
- "x": 200,
2104
- "y": 1880,
2105
- "wires": [
2106
- [
2107
- "753e3777.49a1d"
2108
- ]
2109
- ]
2110
- },
2111
- {
2112
- "id": "1e42a8f3.cf008f",
2113
- "type": "inject",
2114
- "z": "eeb8b00c.2c18c",
2115
- "g": "c869b0a5.e4def8",
2116
- "name": "High",
2117
- "props": [
2118
- {
2119
- "p": "payload"
2120
- },
2121
- {
2122
- "p": "topic",
2123
- "vt": "str"
2124
- }
2125
- ],
2126
- "repeat": "",
2127
- "crontab": "",
2128
- "once": false,
2129
- "onceDelay": 0.1,
2130
- "topic": "",
2131
- "payload": "{\"On\":true,\"RotationSpeed\":99}",
2132
- "payloadType": "json",
2133
- "x": 190,
2134
- "y": 1920,
2135
- "wires": [
2136
- [
2137
- "753e3777.49a1d"
2138
- ]
2139
- ]
2140
- }
2
+ {
3
+ "id": "2c464315.51c50c",
4
+ "type": "group",
5
+ "z": "eeb8b00c.2c18c",
6
+ "name": "Fan Full Example: input from device, output to device",
7
+ "style": {
8
+ "stroke": "#999999",
9
+ "fill": "none",
10
+ "label": true,
11
+ "label-position": "nw",
12
+ "color": "#a4a4a4"
13
+ },
14
+ "nodes": [
15
+ "b7778e52.220a5",
16
+ "fd8aff55.91d41",
17
+ "c717b796.0735b8",
18
+ "f56a2f96.509c1",
19
+ "d945ba75.897998"
20
+ ],
21
+ "x": 94,
22
+ "y": 1559,
23
+ "w": 752,
24
+ "h": 182,
25
+ "info": "# Fan V2\n\nThis example shows a fan. The inputs from node red are to turn the fan on, off, or set \"No Response\".\n\nThe outputs going to \"Fan output\" will show:\n\nOn / off state <br/>\nRotation speed<br/>\nSwing mode on / off (oscillate) <br/>\nRotation direction (clockwise/counterclockwise)"
26
+ },
27
+ {
28
+ "id": "b7778e52.220a5",
29
+ "type": "debug",
30
+ "z": "eeb8b00c.2c18c",
31
+ "g": "2c464315.51c50c",
32
+ "name": "Fan output",
33
+ "active": true,
34
+ "tosidebar": true,
35
+ "console": false,
36
+ "tostatus": false,
37
+ "complete": "payload",
38
+ "targetType": "msg",
39
+ "x": 730,
40
+ "y": 1600,
41
+ "wires": []
42
+ },
43
+ {
44
+ "id": "fd8aff55.91d41",
45
+ "type": "homekit-service",
46
+ "z": "eeb8b00c.2c18c",
47
+ "g": "2c464315.51c50c",
48
+ "isParent": true,
49
+ "bridge": "409001a1.3e7a78",
50
+ "parentService": "",
51
+ "name": "Fan V2",
52
+ "serviceName": "Fanv2",
53
+ "topic": "",
54
+ "filter": false,
55
+ "manufacturer": "Default Manufacturer",
56
+ "model": "Default Model",
57
+ "serialNo": "Default Serial Number",
58
+ "firmwareRev": "1.0.0",
59
+ "hardwareRev": "1.0.0",
60
+ "softwareRev": "1.0.0",
61
+ "cameraConfigVideoProcessor": "ffmpeg",
62
+ "cameraConfigSource": "",
63
+ "cameraConfigStillImageSource": "",
64
+ "cameraConfigMaxStreams": 2,
65
+ "cameraConfigMaxWidth": 1280,
66
+ "cameraConfigMaxHeight": 720,
67
+ "cameraConfigMaxFPS": 10,
68
+ "cameraConfigMaxBitrate": 300,
69
+ "cameraConfigVideoCodec": "libx264",
70
+ "cameraConfigAudioCodec": "libfdk_aac",
71
+ "cameraConfigAudio": false,
72
+ "cameraConfigPacketSize": 1316,
73
+ "cameraConfigVerticalFlip": false,
74
+ "cameraConfigHorizontalFlip": false,
75
+ "cameraConfigMapVideo": "0:0",
76
+ "cameraConfigMapAudio": "0:1",
77
+ "cameraConfigVideoFilter": "scale=1280:720",
78
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
79
+ "cameraConfigDebug": false,
80
+ "cameraConfigSnapshotOutput": "disabled",
81
+ "cameraConfigInterfaceName": "",
82
+ "characteristicProperties": "{\n \"RotationSpeed\":true,\n \"RotationDirection\":true,\n \"SwingMode\":true\n}",
83
+ "outputs": 2,
84
+ "x": 500,
85
+ "y": 1600,
86
+ "wires": [["b7778e52.220a5"], []]
87
+ },
88
+ {
89
+ "id": "c717b796.0735b8",
90
+ "type": "inject",
91
+ "z": "eeb8b00c.2c18c",
92
+ "g": "2c464315.51c50c",
93
+ "name": "NO RESPONSE",
94
+ "repeat": "",
95
+ "crontab": "",
96
+ "once": false,
97
+ "onceDelay": 0.1,
98
+ "topic": "",
99
+ "payload": "{\"Active\":\"NO_RESPONSE\"}",
100
+ "payloadType": "json",
101
+ "x": 220,
102
+ "y": 1700,
103
+ "wires": [["fd8aff55.91d41"]]
104
+ },
105
+ {
106
+ "id": "f56a2f96.509c1",
107
+ "type": "inject",
108
+ "z": "eeb8b00c.2c18c",
109
+ "g": "2c464315.51c50c",
110
+ "name": "ON",
111
+ "props": [
112
+ {
113
+ "p": "payload"
114
+ },
115
+ {
116
+ "p": "topic",
117
+ "vt": "str"
118
+ }
119
+ ],
120
+ "repeat": "",
121
+ "crontab": "",
122
+ "once": false,
123
+ "onceDelay": 0.1,
124
+ "topic": "",
125
+ "payload": "{\"Active\":true}",
126
+ "payloadType": "json",
127
+ "x": 200,
128
+ "y": 1600,
129
+ "wires": [["fd8aff55.91d41"]]
130
+ },
131
+ {
132
+ "id": "d945ba75.897998",
133
+ "type": "inject",
134
+ "z": "eeb8b00c.2c18c",
135
+ "g": "2c464315.51c50c",
136
+ "name": "OFF",
137
+ "props": [
138
+ {
139
+ "p": "payload"
140
+ },
141
+ {
142
+ "p": "topic",
143
+ "vt": "str"
144
+ }
145
+ ],
146
+ "repeat": "",
147
+ "crontab": "",
148
+ "once": false,
149
+ "onceDelay": 0.1,
150
+ "topic": "",
151
+ "payload": "{\"Active\":false}",
152
+ "payloadType": "json",
153
+ "x": 200,
154
+ "y": 1640,
155
+ "wires": [["fd8aff55.91d41"]]
156
+ },
157
+ {
158
+ "id": "409001a1.3e7a78",
159
+ "type": "homekit-bridge",
160
+ "bridgeName": "Demo 1",
161
+ "pinCode": "153-10-538",
162
+ "port": "",
163
+ "allowInsecureRequest": false,
164
+ "manufacturer": "NRCHKB",
165
+ "model": "Demo",
166
+ "serialNo": "1.1.2",
167
+ "customMdnsConfig": false,
168
+ "mdnsMulticast": true,
169
+ "mdnsInterface": "",
170
+ "mdnsPort": "",
171
+ "mdnsIp": "",
172
+ "mdnsTtl": "",
173
+ "mdnsLoopback": true,
174
+ "mdnsReuseAddr": true,
175
+ "allowMessagePassthrough": true
176
+ },
177
+ {
178
+ "id": "384e0889.1fdae",
179
+ "type": "group",
180
+ "z": "eeb8b00c.2c18c",
181
+ "name": "Color Bulb: input from device, output to device",
182
+ "style": {
183
+ "stroke": "#999999",
184
+ "fill": "none",
185
+ "label": true,
186
+ "label-position": "nw",
187
+ "color": "#a4a4a4"
188
+ },
189
+ "nodes": [
190
+ "d838176b.dbaf7",
191
+ "7bf880d4.3cd4d",
192
+ "ee1452a5.08edd",
193
+ "c6ed2a2a.90a01",
194
+ "8cdfae2b.2f2ce8",
195
+ "1758401b.6c62e8"
196
+ ],
197
+ "x": 94,
198
+ "y": 599,
199
+ "w": 752,
200
+ "h": 162,
201
+ "info": "# Color Bulb\n\nThis is a color bulb. It accepts and sends out Hue, Saturation, Value, and On/off state.\n\nHue is the color\n\nSaturation is how deep the color is\n\nValue is brightness\n\nOn is power state"
202
+ },
203
+ {
204
+ "id": "d838176b.dbaf7",
205
+ "type": "debug",
206
+ "z": "eeb8b00c.2c18c",
207
+ "g": "384e0889.1fdae",
208
+ "name": "Color light output",
209
+ "active": true,
210
+ "tosidebar": true,
211
+ "console": false,
212
+ "tostatus": false,
213
+ "complete": "payload",
214
+ "targetType": "msg",
215
+ "x": 710,
216
+ "y": 720,
217
+ "wires": []
218
+ },
219
+ {
220
+ "id": "7bf880d4.3cd4d",
221
+ "type": "homekit-service",
222
+ "z": "eeb8b00c.2c18c",
223
+ "g": "384e0889.1fdae",
224
+ "isParent": true,
225
+ "hostType": "0",
226
+ "bridge": "409001a1.3e7a78",
227
+ "accessoryId": "",
228
+ "parentService": "",
229
+ "name": "Color",
230
+ "serviceName": "Lightbulb",
231
+ "topic": "",
232
+ "filter": false,
233
+ "manufacturer": "Garrett",
234
+ "model": "Color",
235
+ "serialNo": "42",
236
+ "firmwareRev": "1.2",
237
+ "hardwareRev": "1.0.0",
238
+ "softwareRev": "1.0.0",
239
+ "cameraConfigVideoProcessor": "ffmpeg",
240
+ "cameraConfigSource": "",
241
+ "cameraConfigStillImageSource": "",
242
+ "cameraConfigMaxStreams": 2,
243
+ "cameraConfigMaxWidth": 1280,
244
+ "cameraConfigMaxHeight": 720,
245
+ "cameraConfigMaxFPS": 10,
246
+ "cameraConfigMaxBitrate": 300,
247
+ "cameraConfigVideoCodec": "libx264",
248
+ "cameraConfigAudioCodec": "libfdk_aac",
249
+ "cameraConfigAudio": false,
250
+ "cameraConfigPacketSize": 1316,
251
+ "cameraConfigVerticalFlip": false,
252
+ "cameraConfigHorizontalFlip": false,
253
+ "cameraConfigMapVideo": "0:0",
254
+ "cameraConfigMapAudio": "0:1",
255
+ "cameraConfigVideoFilter": "scale=1280:720",
256
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
257
+ "cameraConfigDebug": false,
258
+ "cameraConfigSnapshotOutput": "disabled",
259
+ "cameraConfigInterfaceName": "",
260
+ "characteristicProperties": "{ \"Brightness\":true, \"Hue\":true, \"Saturation\":true}",
261
+ "waitForSetupMsg": false,
262
+ "outputs": 2,
263
+ "x": 490,
264
+ "y": 720,
265
+ "wires": [["d838176b.dbaf7"], []]
266
+ },
267
+ {
268
+ "id": "ee1452a5.08edd",
269
+ "type": "inject",
270
+ "z": "eeb8b00c.2c18c",
271
+ "g": "384e0889.1fdae",
272
+ "name": "NO RESPONSE",
273
+ "props": [
274
+ {
275
+ "p": "payload"
276
+ }
277
+ ],
278
+ "repeat": "",
279
+ "crontab": "",
280
+ "once": false,
281
+ "onceDelay": 0.1,
282
+ "topic": "",
283
+ "payload": "{\"On\":\"NO_RESPONSE\"}",
284
+ "payloadType": "json",
285
+ "x": 420,
286
+ "y": 640,
287
+ "wires": [["7bf880d4.3cd4d"]]
288
+ },
289
+ {
290
+ "id": "c6ed2a2a.90a01",
291
+ "type": "inject",
292
+ "z": "eeb8b00c.2c18c",
293
+ "g": "384e0889.1fdae",
294
+ "name": "ON",
295
+ "props": [
296
+ {
297
+ "p": "payload"
298
+ }
299
+ ],
300
+ "repeat": "",
301
+ "crontab": "",
302
+ "once": false,
303
+ "onceDelay": 0.1,
304
+ "topic": "",
305
+ "payload": "{\"On\":true}",
306
+ "payloadType": "json",
307
+ "x": 190,
308
+ "y": 640,
309
+ "wires": [["7bf880d4.3cd4d"]]
310
+ },
311
+ {
312
+ "id": "8cdfae2b.2f2ce8",
313
+ "type": "inject",
314
+ "z": "eeb8b00c.2c18c",
315
+ "g": "384e0889.1fdae",
316
+ "name": "Reset HSV",
317
+ "props": [
318
+ {
319
+ "p": "payload"
320
+ }
321
+ ],
322
+ "repeat": "",
323
+ "crontab": "",
324
+ "once": false,
325
+ "onceDelay": 0.1,
326
+ "topic": "",
327
+ "payload": "{\"Brightness\":50,\"Hue\":50,\"Saturation\":50}",
328
+ "payloadType": "json",
329
+ "x": 200,
330
+ "y": 720,
331
+ "wires": [["7bf880d4.3cd4d"]]
332
+ },
333
+ {
334
+ "id": "1758401b.6c62e8",
335
+ "type": "inject",
336
+ "z": "eeb8b00c.2c18c",
337
+ "g": "384e0889.1fdae",
338
+ "name": "OFF",
339
+ "props": [
340
+ {
341
+ "p": "payload"
342
+ }
343
+ ],
344
+ "repeat": "",
345
+ "crontab": "",
346
+ "once": false,
347
+ "onceDelay": 0.1,
348
+ "topic": "",
349
+ "payload": "{\"On\":false}",
350
+ "payloadType": "json",
351
+ "x": 190,
352
+ "y": 680,
353
+ "wires": [["7bf880d4.3cd4d"]]
354
+ },
355
+ {
356
+ "id": "3a57bebe.a3b222",
357
+ "type": "group",
358
+ "z": "eeb8b00c.2c18c",
359
+ "name": "Dimmable Bulb: input from device, output to device",
360
+ "style": {
361
+ "stroke": "#999999",
362
+ "fill": "none",
363
+ "label": true,
364
+ "label-position": "nw",
365
+ "color": "#a4a4a4"
366
+ },
367
+ "nodes": [
368
+ "459254fe.49c72c",
369
+ "379657db.a99df8",
370
+ "52a07047.03ce7",
371
+ "253b3550.729caa",
372
+ "b9bc7f3d.51acf"
373
+ ],
374
+ "x": 94,
375
+ "y": 459,
376
+ "w": 752,
377
+ "h": 122,
378
+ "info": "# Dimmable Bulb\n\nThis is a dimmable bulb. The Characteristic Properties enable brightness. It is a white bulb which can be adjusted from 0 to 100% brightness."
379
+ },
380
+ {
381
+ "id": "459254fe.49c72c",
382
+ "type": "homekit-service",
383
+ "z": "eeb8b00c.2c18c",
384
+ "g": "3a57bebe.a3b222",
385
+ "isParent": true,
386
+ "hostType": "0",
387
+ "bridge": "409001a1.3e7a78",
388
+ "accessoryId": "",
389
+ "parentService": "",
390
+ "name": "Dimmable",
391
+ "serviceName": "Lightbulb",
392
+ "topic": "",
393
+ "filter": false,
394
+ "manufacturer": "Garrett",
395
+ "model": "Dummy",
396
+ "serialNo": "Default Serial Number",
397
+ "firmwareRev": "1.1.9",
398
+ "hardwareRev": "1.0.0",
399
+ "softwareRev": "1.0.0",
400
+ "cameraConfigVideoProcessor": "ffmpeg",
401
+ "cameraConfigSource": "",
402
+ "cameraConfigStillImageSource": "",
403
+ "cameraConfigMaxStreams": 2,
404
+ "cameraConfigMaxWidth": 1280,
405
+ "cameraConfigMaxHeight": 720,
406
+ "cameraConfigMaxFPS": 10,
407
+ "cameraConfigMaxBitrate": 300,
408
+ "cameraConfigVideoCodec": "libx264",
409
+ "cameraConfigAudioCodec": "libfdk_aac",
410
+ "cameraConfigAudio": false,
411
+ "cameraConfigPacketSize": 1316,
412
+ "cameraConfigVerticalFlip": false,
413
+ "cameraConfigHorizontalFlip": false,
414
+ "cameraConfigMapVideo": "0:0",
415
+ "cameraConfigMapAudio": "0:1",
416
+ "cameraConfigVideoFilter": "scale=1280:720",
417
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
418
+ "cameraConfigDebug": false,
419
+ "cameraConfigSnapshotOutput": "disabled",
420
+ "cameraConfigInterfaceName": "",
421
+ "characteristicProperties": "{ \"Brightness\":true}",
422
+ "waitForSetupMsg": false,
423
+ "outputs": 2,
424
+ "x": 460,
425
+ "y": 540,
426
+ "wires": [["379657db.a99df8"], []]
427
+ },
428
+ {
429
+ "id": "379657db.a99df8",
430
+ "type": "debug",
431
+ "z": "eeb8b00c.2c18c",
432
+ "g": "3a57bebe.a3b222",
433
+ "name": "Dimmable light output",
434
+ "active": true,
435
+ "tosidebar": true,
436
+ "console": false,
437
+ "tostatus": false,
438
+ "complete": "payload",
439
+ "targetType": "msg",
440
+ "x": 700,
441
+ "y": 540,
442
+ "wires": []
443
+ },
444
+ {
445
+ "id": "52a07047.03ce7",
446
+ "type": "inject",
447
+ "z": "eeb8b00c.2c18c",
448
+ "g": "3a57bebe.a3b222",
449
+ "name": "NO RESPONSE",
450
+ "props": [
451
+ {
452
+ "p": "payload"
453
+ }
454
+ ],
455
+ "repeat": "",
456
+ "crontab": "",
457
+ "once": false,
458
+ "onceDelay": 0.1,
459
+ "topic": "",
460
+ "payload": "{\"On\":\"NO_RESPONSE\"}",
461
+ "payloadType": "json",
462
+ "x": 400,
463
+ "y": 500,
464
+ "wires": [["459254fe.49c72c"]]
465
+ },
466
+ {
467
+ "id": "253b3550.729caa",
468
+ "type": "inject",
469
+ "z": "eeb8b00c.2c18c",
470
+ "g": "3a57bebe.a3b222",
471
+ "name": "ON",
472
+ "props": [
473
+ {
474
+ "p": "payload"
475
+ }
476
+ ],
477
+ "repeat": "",
478
+ "crontab": "",
479
+ "once": false,
480
+ "onceDelay": 0.1,
481
+ "topic": "",
482
+ "payload": "{\"On\":true}",
483
+ "payloadType": "json",
484
+ "x": 190,
485
+ "y": 500,
486
+ "wires": [["459254fe.49c72c"]]
487
+ },
488
+ {
489
+ "id": "b9bc7f3d.51acf",
490
+ "type": "inject",
491
+ "z": "eeb8b00c.2c18c",
492
+ "g": "3a57bebe.a3b222",
493
+ "name": "OFF",
494
+ "props": [
495
+ {
496
+ "p": "payload"
497
+ }
498
+ ],
499
+ "repeat": "",
500
+ "crontab": "",
501
+ "once": false,
502
+ "onceDelay": 0.1,
503
+ "topic": "",
504
+ "payload": "{\"On\":false}",
505
+ "payloadType": "json",
506
+ "x": 190,
507
+ "y": 540,
508
+ "wires": [["459254fe.49c72c"]]
509
+ },
510
+ {
511
+ "id": "60e44fde.c914f8",
512
+ "type": "group",
513
+ "z": "eeb8b00c.2c18c",
514
+ "name": "Air Purifier: input power state, output commands device",
515
+ "style": {
516
+ "stroke": "#999999",
517
+ "fill": "none",
518
+ "label": true,
519
+ "label-position": "nw",
520
+ "color": "#a4a4a4"
521
+ },
522
+ "nodes": [
523
+ "8dea49.4a770db8",
524
+ "5302e4aa.1b466c",
525
+ "bfe1c73d.c165a8",
526
+ "9739d842.a402f",
527
+ "87048a6e.df64e8",
528
+ "db412cea.4a62f8",
529
+ "46418e19.aa6d6",
530
+ "664dadf9.85d0d4",
531
+ "d7cd8a56.628178",
532
+ "3de34c4c.1871a4",
533
+ "ee8894e4.f1855"
534
+ ],
535
+ "x": 94,
536
+ "y": 59,
537
+ "w": 822,
538
+ "h": 162,
539
+ "info": "Turning the device on or off will send:\n`{\"Active\":[0, 1]}`\n\nAfter changing power state, the device will be \"Turning on\" or \"Turning off\" until a current state is sent of:\n`{\"CurrentAirPurifierState\":[0, 1, 2]}`\n0: off <br/>\n1: idle <br/>\n2: on <br/>\n\nThere will be a slider in the home app for sending `RotationSpeed`\n\nThere will be a switch on Home app for \"Oscillate\" which sends:\n`{\"SwingMode\":[0,1]}`\n\nChanging mode to manual to auto will send payload:\n`{\"TargetAirPurifierState\":[0, 1]}`\n\nChild lock will send \n`{\"LockPhysicalControls\": [0, 1]}`\n\n"
540
+ },
541
+ {
542
+ "id": "8dea49.4a770db8",
543
+ "type": "inject",
544
+ "z": "eeb8b00c.2c18c",
545
+ "g": "60e44fde.c914f8",
546
+ "name": "off",
547
+ "props": [
548
+ {
549
+ "p": "payload"
550
+ }
551
+ ],
552
+ "repeat": "",
553
+ "crontab": "",
554
+ "once": false,
555
+ "onceDelay": 0.1,
556
+ "topic": "",
557
+ "payload": "{\"CurrentAirPurifierState\":0}",
558
+ "payloadType": "json",
559
+ "x": 190,
560
+ "y": 100,
561
+ "wires": [["5302e4aa.1b466c"]]
562
+ },
563
+ {
564
+ "id": "5302e4aa.1b466c",
565
+ "type": "homekit-service",
566
+ "z": "eeb8b00c.2c18c",
567
+ "g": "60e44fde.c914f8",
568
+ "isParent": true,
569
+ "bridge": "409001a1.3e7a78",
570
+ "parentService": "",
571
+ "name": "Air purifier",
572
+ "serviceName": "AirPurifier",
573
+ "topic": "",
574
+ "filter": false,
575
+ "manufacturer": "Purity",
576
+ "model": "Air",
577
+ "serialNo": "23",
578
+ "firmwareRev": "1.0.0",
579
+ "hardwareRev": "1.0.0",
580
+ "softwareRev": "1.0.0",
581
+ "cameraConfigVideoProcessor": "ffmpeg",
582
+ "cameraConfigSource": "",
583
+ "cameraConfigStillImageSource": "",
584
+ "cameraConfigMaxStreams": 2,
585
+ "cameraConfigMaxWidth": 1280,
586
+ "cameraConfigMaxHeight": 720,
587
+ "cameraConfigMaxFPS": 10,
588
+ "cameraConfigMaxBitrate": 300,
589
+ "cameraConfigVideoCodec": "libx264",
590
+ "cameraConfigAudioCodec": "libfdk_aac",
591
+ "cameraConfigAudio": false,
592
+ "cameraConfigPacketSize": 1316,
593
+ "cameraConfigVerticalFlip": false,
594
+ "cameraConfigHorizontalFlip": false,
595
+ "cameraConfigMapVideo": "0:0",
596
+ "cameraConfigMapAudio": "0:1",
597
+ "cameraConfigVideoFilter": "scale=1280:720",
598
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
599
+ "cameraConfigDebug": false,
600
+ "cameraConfigSnapshotOutput": "disabled",
601
+ "cameraConfigInterfaceName": "",
602
+ "characteristicProperties": "{\n \"SwingMode\":true,\n \"RotationSpeed\":true,\n \"LockPhysicalControls\":true\n}",
603
+ "outputs": 2,
604
+ "x": 370,
605
+ "y": 100,
606
+ "wires": [["bfe1c73d.c165a8", "9739d842.a402f"], []]
607
+ },
608
+ {
609
+ "id": "bfe1c73d.c165a8",
610
+ "type": "debug",
611
+ "z": "eeb8b00c.2c18c",
612
+ "g": "60e44fde.c914f8",
613
+ "name": "Purifier output",
614
+ "active": true,
615
+ "tosidebar": true,
616
+ "console": false,
617
+ "tostatus": false,
618
+ "complete": "true",
619
+ "targetType": "full",
620
+ "x": 500,
621
+ "y": 180,
622
+ "wires": []
623
+ },
624
+ {
625
+ "id": "9739d842.a402f",
626
+ "type": "function",
627
+ "z": "eeb8b00c.2c18c",
628
+ "g": "60e44fde.c914f8",
629
+ "name": "on/off",
630
+ "func": "if (msg.hap !== undefined && msg.hap.context !== undefined){\n if (msg.payload.Active === 1){\n return [msg,null];\n }\n if (msg.payload.Active === 0){\n return [null,msg];\n }\n}\nreturn;",
631
+ "outputs": 2,
632
+ "noerr": 0,
633
+ "initialize": "",
634
+ "finalize": "",
635
+ "x": 530,
636
+ "y": 100,
637
+ "wires": [["664dadf9.85d0d4", "d7cd8a56.628178"], ["3de34c4c.1871a4"]],
638
+ "outputLabels": ["On", "Off"]
639
+ },
640
+ {
641
+ "id": "87048a6e.df64e8",
642
+ "type": "inject",
643
+ "z": "eeb8b00c.2c18c",
644
+ "g": "60e44fde.c914f8",
645
+ "name": "idle",
646
+ "props": [
647
+ {
648
+ "p": "payload"
649
+ }
650
+ ],
651
+ "repeat": "",
652
+ "crontab": "",
653
+ "once": false,
654
+ "onceDelay": 0.1,
655
+ "topic": "",
656
+ "payload": "{\"CurrentAirPurifierState\":1}",
657
+ "payloadType": "json",
658
+ "x": 190,
659
+ "y": 140,
660
+ "wires": [["5302e4aa.1b466c"]]
661
+ },
662
+ {
663
+ "id": "db412cea.4a62f8",
664
+ "type": "inject",
665
+ "z": "eeb8b00c.2c18c",
666
+ "g": "60e44fde.c914f8",
667
+ "name": "on",
668
+ "props": [
669
+ {
670
+ "p": "payload"
671
+ }
672
+ ],
673
+ "repeat": "",
674
+ "crontab": "",
675
+ "once": false,
676
+ "onceDelay": 0.1,
677
+ "topic": "",
678
+ "payload": "{\"CurrentAirPurifierState\":2}",
679
+ "payloadType": "json",
680
+ "x": 190,
681
+ "y": 180,
682
+ "wires": [["5302e4aa.1b466c"]]
683
+ },
684
+ {
685
+ "id": "46418e19.aa6d6",
686
+ "type": "link in",
687
+ "z": "eeb8b00c.2c18c",
688
+ "g": "60e44fde.c914f8",
689
+ "name": "",
690
+ "links": ["ee8894e4.f1855"],
691
+ "x": 315,
692
+ "y": 180,
693
+ "wires": [["5302e4aa.1b466c"]]
694
+ },
695
+ {
696
+ "id": "664dadf9.85d0d4",
697
+ "type": "trigger",
698
+ "z": "eeb8b00c.2c18c",
699
+ "g": "60e44fde.c914f8",
700
+ "name": "5 sec to idle",
701
+ "op1": "",
702
+ "op2": "{\"CurrentAirPurifierState\":1}",
703
+ "op1type": "nul",
704
+ "op2type": "json",
705
+ "duration": "5",
706
+ "extend": false,
707
+ "units": "s",
708
+ "reset": "",
709
+ "bytopic": "all",
710
+ "topic": "topic",
711
+ "outputs": 1,
712
+ "x": 730,
713
+ "y": 100,
714
+ "wires": [["ee8894e4.f1855"]]
715
+ },
716
+ {
717
+ "id": "d7cd8a56.628178",
718
+ "type": "trigger",
719
+ "z": "eeb8b00c.2c18c",
720
+ "g": "60e44fde.c914f8",
721
+ "name": "10 sec to on",
722
+ "op1": "",
723
+ "op2": "{\"CurrentAirPurifierState\":2}",
724
+ "op1type": "nul",
725
+ "op2type": "json",
726
+ "duration": "10",
727
+ "extend": false,
728
+ "units": "s",
729
+ "reset": "",
730
+ "bytopic": "all",
731
+ "topic": "topic",
732
+ "outputs": 1,
733
+ "x": 730,
734
+ "y": 140,
735
+ "wires": [["ee8894e4.f1855"]]
736
+ },
737
+ {
738
+ "id": "3de34c4c.1871a4",
739
+ "type": "trigger",
740
+ "z": "eeb8b00c.2c18c",
741
+ "g": "60e44fde.c914f8",
742
+ "name": "5 sec to off",
743
+ "op1": "",
744
+ "op2": "{\"CurrentAirPurifierState\":0}",
745
+ "op1type": "nul",
746
+ "op2type": "json",
747
+ "duration": "5",
748
+ "extend": false,
749
+ "units": "s",
750
+ "reset": "",
751
+ "bytopic": "all",
752
+ "topic": "topic",
753
+ "outputs": 1,
754
+ "x": 730,
755
+ "y": 180,
756
+ "wires": [["ee8894e4.f1855"]]
757
+ },
758
+ {
759
+ "id": "ee8894e4.f1855",
760
+ "type": "link out",
761
+ "z": "eeb8b00c.2c18c",
762
+ "g": "60e44fde.c914f8",
763
+ "name": "",
764
+ "links": ["46418e19.aa6d6"],
765
+ "x": 875,
766
+ "y": 140,
767
+ "wires": []
768
+ },
769
+ {
770
+ "id": "6eaa9b9e.282734",
771
+ "type": "group",
772
+ "z": "eeb8b00c.2c18c",
773
+ "name": "CO plus CO2 Sensor: input only sensor",
774
+ "style": {
775
+ "stroke": "#999999",
776
+ "fill": "none",
777
+ "label": true,
778
+ "label-position": "nw",
779
+ "color": "#a4a4a4"
780
+ },
781
+ "nodes": [
782
+ "2e6738a6.ef5dd8",
783
+ "79889759.8219c",
784
+ "7f53465b.356a68",
785
+ "97aff586.786ff8",
786
+ "659ff3da.236404",
787
+ "e6105066.f8911",
788
+ "b433a780.665a7",
789
+ "d4b30334.a19e58",
790
+ "b0eeeb34.2dde8"
791
+ ],
792
+ "x": 94,
793
+ "y": 999,
794
+ "w": 752,
795
+ "h": 282,
796
+ "info": "# Combined Sensor\nThis is a sensor which will display both Carbon Monoxide (poisonous, deadly gas) and Carbon Dioxide (what humans exhale) levels.\n\n# CO Sensor\n\nThere are three inputs to this example, one for each level of Carbon Monoxide in the air. Options are:\n\n**0 ppm:** this will assume no CO in the air <br/>\n**Low level:** this will assume a level between 1 and 35 ppm, inclusive. This level is generally assumed to not cause problems in healthy adults <br/>\n**Dangerous level:** this will assume a level between 35 and 5000, inclusive; this will also trigger an alert in Home app\n\n## IF YOU HAVE A CARBON MONOXIDE DETECTOR EVER READING ABOVE 35 PPM, PLEASE EVACUATE THE AREA AND SEEK FRESH AIR IMMEDIATELY TO AVOID RISK OF DEATH ##\n\n# CO2 Sensor\n\nThere are three inputs to this example, one for each level of Carbon Dioxide in the air. Options are:\n\n**0 ppm:** this will assume no CO2 in the air <br/>\n**CO2 Level:** this will assume a level between 1 and 100,000 ppm, inclusive <br/>\n**Dangerous level:** this will assume a level between 1,000 and 100,000, inclusive\n\n"
797
+ },
798
+ {
799
+ "id": "2e6738a6.ef5dd8",
800
+ "type": "homekit-service",
801
+ "z": "eeb8b00c.2c18c",
802
+ "g": "6eaa9b9e.282734",
803
+ "isParent": true,
804
+ "hostType": "0",
805
+ "bridge": "409001a1.3e7a78",
806
+ "accessoryId": "",
807
+ "parentService": "",
808
+ "name": "CO detector",
809
+ "serviceName": "CarbonMonoxideSensor",
810
+ "topic": "",
811
+ "filter": false,
812
+ "manufacturer": "MONOxide",
813
+ "model": "1",
814
+ "serialNo": "2",
815
+ "firmwareRev": "2",
816
+ "hardwareRev": "2",
817
+ "softwareRev": "1.0.0",
818
+ "cameraConfigVideoProcessor": "ffmpeg",
819
+ "cameraConfigSource": "",
820
+ "cameraConfigStillImageSource": "",
821
+ "cameraConfigMaxStreams": 2,
822
+ "cameraConfigMaxWidth": 1280,
823
+ "cameraConfigMaxHeight": 720,
824
+ "cameraConfigMaxFPS": 10,
825
+ "cameraConfigMaxBitrate": 300,
826
+ "cameraConfigVideoCodec": "libx264",
827
+ "cameraConfigAudioCodec": "libfdk_aac",
828
+ "cameraConfigAudio": false,
829
+ "cameraConfigPacketSize": 1316,
830
+ "cameraConfigVerticalFlip": false,
831
+ "cameraConfigHorizontalFlip": false,
832
+ "cameraConfigMapVideo": "0:0",
833
+ "cameraConfigMapAudio": "0:1",
834
+ "cameraConfigVideoFilter": "scale=1280:720",
835
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
836
+ "cameraConfigDebug": false,
837
+ "cameraConfigSnapshotOutput": "disabled",
838
+ "cameraConfigInterfaceName": "",
839
+ "characteristicProperties": "{ \"CarbonMonoxideLevel\":{ \"maxValue\":5000 }, \"CarbonMonoxidePeakLevel\":{ \"maxValue\":5000 }, \"CarbonDioxideLevel\":true, \"CarbonDioxidePeakLevel\":true}",
840
+ "waitForSetupMsg": false,
841
+ "outputs": 2,
842
+ "x": 750,
843
+ "y": 1040,
844
+ "wires": [[], []]
845
+ },
846
+ {
847
+ "id": "79889759.8219c",
848
+ "type": "function",
849
+ "z": "eeb8b00c.2c18c",
850
+ "g": "6eaa9b9e.282734",
851
+ "name": "Carbon DIoxide",
852
+ "func": "if(msg.payload === 0){\n context.set('lastPeak',0);\n newMsg = {\n payload: {\n \"CarbonDioxideLevel\":0\n }\n }\n return newMsg;\n}\n\n// Initialize vars\nvar CurrentLevel = 0;\nvar lastPeak = context.get('lastPeak');\n\n// Set random level\nif(msg.payload === \"CO2\"){\n CurrentLevel = Math.floor(Math.random() * (100000 - 1 + 1) + 1);\n}\n\n\n// Formulate output message\nvar newMsg = {\n payload: {\n \"CarbonDioxideLevel\" : CurrentLevel\n }\n};\n\n// Set new peak level\nif(CurrentLevel > lastPeak){\n lastPeak = CurrentLevel;\n context.set('lastPeak',CurrentLevel);\n newMsg.payload.CarbonDioxidePeakLevel = CurrentLevel;\n}\n\nreturn newMsg;",
853
+ "outputs": 1,
854
+ "noerr": 0,
855
+ "initialize": "// Code added here will be run once\n// whenever the node is deployed.\ncontext.set('lastPeak',0);",
856
+ "finalize": "",
857
+ "x": 460,
858
+ "y": 1200,
859
+ "wires": [["2e6738a6.ef5dd8"]]
860
+ },
861
+ {
862
+ "id": "7f53465b.356a68",
863
+ "type": "function",
864
+ "z": "eeb8b00c.2c18c",
865
+ "g": "6eaa9b9e.282734",
866
+ "name": "Carbon MONoxide",
867
+ "func": "// Reset all values to 0 if 0ppm input\nif(msg.payload === 0){\n context.set('lastPeak',0);\n newMsg = {\n payload: {\n \"CarbonMonoxideLevel\":0,\n \"CarbonMonoxidePeakLevel\":0,\n \"CarbonMonoxideDetected\":0\n }\n };\n return newMsg;\n}\n\n// Initialize vars\nvar CurrentLevel = 0;\nvar lastPeak = context.get('lastPeak');\n\n// Set random Low or Dangerous levels\nif(msg.payload === \"Low\"){\n CurrentLevel = Math.floor(Math.random() * (35 - 1 + 1) + 1);\n}\nif(msg.payload === \"Danger\"){\n CurrentLevel = Math.floor(Math.random() * (5000 - 35 + 1) + 35);\n}\n\n// Formulate output message\nvar newMsg = {\n payload: {\n \"CarbonMonoxideLevel\" : CurrentLevel,\n \"CarbonMonoxideDetected\" : 0\n }\n};\n\n// Set new peak level\nif(CurrentLevel > lastPeak){\n lastPeak = CurrentLevel;\n context.set('lastPeak',CurrentLevel);\n newMsg.payload.CarbonMonoxidePeakLevel = CurrentLevel;\n}\n\n// Set warning if dangerous\nif (CurrentLevel >= 35) {\n newMsg.payload.CarbonMonoxideDetected = 1;\n} \n\nreturn newMsg;",
868
+ "outputs": 1,
869
+ "noerr": 0,
870
+ "initialize": "",
871
+ "finalize": "",
872
+ "x": 470,
873
+ "y": 1080,
874
+ "wires": [["2e6738a6.ef5dd8"]]
875
+ },
876
+ {
877
+ "id": "97aff586.786ff8",
878
+ "type": "inject",
879
+ "z": "eeb8b00c.2c18c",
880
+ "g": "6eaa9b9e.282734",
881
+ "name": "NO RESPONSE",
882
+ "props": [
883
+ {
884
+ "p": "payload"
885
+ },
886
+ {
887
+ "p": "topic",
888
+ "vt": "str"
889
+ }
890
+ ],
891
+ "repeat": "",
892
+ "crontab": "",
893
+ "once": false,
894
+ "onceDelay": 0.1,
895
+ "topic": "",
896
+ "payload": "{\"CarbonMonoxideLevel\":\"NO_RESPONSE\"}",
897
+ "payloadType": "json",
898
+ "x": 480,
899
+ "y": 1040,
900
+ "wires": [["2e6738a6.ef5dd8"]]
901
+ },
902
+ {
903
+ "id": "659ff3da.236404",
904
+ "type": "inject",
905
+ "z": "eeb8b00c.2c18c",
906
+ "g": "6eaa9b9e.282734",
907
+ "name": "Clear CO2 Peak",
908
+ "props": [
909
+ {
910
+ "p": "payload"
911
+ }
912
+ ],
913
+ "repeat": "",
914
+ "crontab": "",
915
+ "once": false,
916
+ "onceDelay": 0.1,
917
+ "topic": "",
918
+ "payload": "0",
919
+ "payloadType": "num",
920
+ "x": 220,
921
+ "y": 1200,
922
+ "wires": [["79889759.8219c"]]
923
+ },
924
+ {
925
+ "id": "e6105066.f8911",
926
+ "type": "inject",
927
+ "z": "eeb8b00c.2c18c",
928
+ "g": "6eaa9b9e.282734",
929
+ "name": "0 ppm",
930
+ "repeat": "",
931
+ "crontab": "",
932
+ "once": false,
933
+ "onceDelay": 0.1,
934
+ "topic": "",
935
+ "payload": "0",
936
+ "payloadType": "num",
937
+ "x": 210,
938
+ "y": 1040,
939
+ "wires": [["7f53465b.356a68"]]
940
+ },
941
+ {
942
+ "id": "b433a780.665a7",
943
+ "type": "inject",
944
+ "z": "eeb8b00c.2c18c",
945
+ "g": "6eaa9b9e.282734",
946
+ "name": "CO2 Level",
947
+ "props": [
948
+ {
949
+ "p": "payload"
950
+ }
951
+ ],
952
+ "repeat": "",
953
+ "crontab": "",
954
+ "once": false,
955
+ "onceDelay": 0.1,
956
+ "topic": "",
957
+ "payload": "CO2",
958
+ "payloadType": "str",
959
+ "x": 200,
960
+ "y": 1240,
961
+ "wires": [["79889759.8219c"]]
962
+ },
963
+ {
964
+ "id": "d4b30334.a19e58",
965
+ "type": "inject",
966
+ "z": "eeb8b00c.2c18c",
967
+ "g": "6eaa9b9e.282734",
968
+ "name": "Low level",
969
+ "props": [
970
+ {
971
+ "p": "payload"
972
+ }
973
+ ],
974
+ "repeat": "",
975
+ "crontab": "",
976
+ "once": false,
977
+ "onceDelay": 0.1,
978
+ "topic": "",
979
+ "payload": "Low",
980
+ "payloadType": "str",
981
+ "x": 220,
982
+ "y": 1080,
983
+ "wires": [["7f53465b.356a68"]]
984
+ },
985
+ {
986
+ "id": "b0eeeb34.2dde8",
987
+ "type": "inject",
988
+ "z": "eeb8b00c.2c18c",
989
+ "g": "6eaa9b9e.282734",
990
+ "name": "Danger level",
991
+ "props": [
992
+ {
993
+ "p": "payload"
994
+ }
995
+ ],
996
+ "repeat": "",
997
+ "crontab": "",
998
+ "once": false,
999
+ "onceDelay": 0.1,
1000
+ "topic": "",
1001
+ "payload": "Danger",
1002
+ "payloadType": "str",
1003
+ "x": 230,
1004
+ "y": 1120,
1005
+ "wires": [["7f53465b.356a68"]]
1006
+ },
1007
+ {
1008
+ "id": "a875cc7.a4c42b",
1009
+ "type": "group",
1010
+ "z": "eeb8b00c.2c18c",
1011
+ "name": "Contact Sensor: input only sensor",
1012
+ "style": {
1013
+ "stroke": "#999999",
1014
+ "fill": "none",
1015
+ "label": true,
1016
+ "label-position": "nw",
1017
+ "color": "#a4a4a4"
1018
+ },
1019
+ "nodes": [
1020
+ "a5194c26.18c628",
1021
+ "2f9bc0d.42a73c",
1022
+ "dfca0b2d.8b8e8",
1023
+ "d74a610c.09a36",
1024
+ "c15b6468.ae2eb8",
1025
+ "6f7bc7fa.7f4f6",
1026
+ "99b55eb3.e31bf8",
1027
+ "508d9ccf.29e404"
1028
+ ],
1029
+ "x": 94,
1030
+ "y": 1299,
1031
+ "w": 752,
1032
+ "h": 242,
1033
+ "info": "# Contact Sensor\n\nThe contact sensor has one inject node to Open the sensor (door, window, etc). Once open, a ten second timer will run then set it back to closed.\n\nAdditional inputs are for \"No Response\", \"Tampered\", and \"Battery\". Note that this battery will not show a battery level but only a good/low battery status."
1034
+ },
1035
+ {
1036
+ "id": "a5194c26.18c628",
1037
+ "type": "homekit-service",
1038
+ "z": "eeb8b00c.2c18c",
1039
+ "g": "a875cc7.a4c42b",
1040
+ "isParent": true,
1041
+ "hostType": "0",
1042
+ "bridge": "409001a1.3e7a78",
1043
+ "accessoryId": "",
1044
+ "parentService": "",
1045
+ "name": "Contact Sensor",
1046
+ "serviceName": "ContactSensor",
1047
+ "topic": "",
1048
+ "filter": false,
1049
+ "manufacturer": "Full Contact",
1050
+ "model": "Door",
1051
+ "serialNo": "Sensor",
1052
+ "firmwareRev": "1.0.0",
1053
+ "hardwareRev": "1.0.0",
1054
+ "softwareRev": "1.0.0",
1055
+ "cameraConfigVideoProcessor": "ffmpeg",
1056
+ "cameraConfigSource": "",
1057
+ "cameraConfigStillImageSource": "",
1058
+ "cameraConfigMaxStreams": 2,
1059
+ "cameraConfigMaxWidth": 1280,
1060
+ "cameraConfigMaxHeight": 720,
1061
+ "cameraConfigMaxFPS": 10,
1062
+ "cameraConfigMaxBitrate": 300,
1063
+ "cameraConfigVideoCodec": "libx264",
1064
+ "cameraConfigAudioCodec": "libfdk_aac",
1065
+ "cameraConfigAudio": false,
1066
+ "cameraConfigPacketSize": 1316,
1067
+ "cameraConfigVerticalFlip": false,
1068
+ "cameraConfigHorizontalFlip": false,
1069
+ "cameraConfigMapVideo": "0:0",
1070
+ "cameraConfigMapAudio": "0:1",
1071
+ "cameraConfigVideoFilter": "scale=1280:720",
1072
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
1073
+ "cameraConfigDebug": false,
1074
+ "cameraConfigSnapshotOutput": "disabled",
1075
+ "cameraConfigInterfaceName": "",
1076
+ "characteristicProperties": "{ \"StatusTampered\":true, \"StatusLowBattery\":true}",
1077
+ "waitForSetupMsg": false,
1078
+ "outputs": 2,
1079
+ "x": 740,
1080
+ "y": 1340,
1081
+ "wires": [[], []]
1082
+ },
1083
+ {
1084
+ "id": "2f9bc0d.42a73c",
1085
+ "type": "inject",
1086
+ "z": "eeb8b00c.2c18c",
1087
+ "g": "a875cc7.a4c42b",
1088
+ "name": "Tampered",
1089
+ "repeat": "",
1090
+ "crontab": "",
1091
+ "once": false,
1092
+ "onceDelay": 0.1,
1093
+ "topic": "",
1094
+ "payload": "{\"StatusTampered\":1}",
1095
+ "payloadType": "json",
1096
+ "x": 200,
1097
+ "y": 1460,
1098
+ "wires": [["a5194c26.18c628"]]
1099
+ },
1100
+ {
1101
+ "id": "dfca0b2d.8b8e8",
1102
+ "type": "inject",
1103
+ "z": "eeb8b00c.2c18c",
1104
+ "g": "a875cc7.a4c42b",
1105
+ "name": "Clear tampered",
1106
+ "repeat": "",
1107
+ "crontab": "",
1108
+ "once": false,
1109
+ "onceDelay": 0.1,
1110
+ "topic": "",
1111
+ "payload": "{\"StatusTampered\":0}",
1112
+ "payloadType": "json",
1113
+ "x": 220,
1114
+ "y": 1500,
1115
+ "wires": [["a5194c26.18c628"]]
1116
+ },
1117
+ {
1118
+ "id": "d74a610c.09a36",
1119
+ "type": "inject",
1120
+ "z": "eeb8b00c.2c18c",
1121
+ "g": "a875cc7.a4c42b",
1122
+ "name": "Low batt",
1123
+ "repeat": "",
1124
+ "crontab": "",
1125
+ "once": false,
1126
+ "onceDelay": 0.1,
1127
+ "topic": "",
1128
+ "payload": "{\"StatusLowBattery\":1}",
1129
+ "payloadType": "json",
1130
+ "x": 560,
1131
+ "y": 1460,
1132
+ "wires": [["a5194c26.18c628"]]
1133
+ },
1134
+ {
1135
+ "id": "c15b6468.ae2eb8",
1136
+ "type": "inject",
1137
+ "z": "eeb8b00c.2c18c",
1138
+ "g": "a875cc7.a4c42b",
1139
+ "name": "Good batt",
1140
+ "repeat": "",
1141
+ "crontab": "",
1142
+ "once": false,
1143
+ "onceDelay": 0.1,
1144
+ "topic": "",
1145
+ "payload": "{\"StatusLowBattery\":0}",
1146
+ "payloadType": "json",
1147
+ "x": 560,
1148
+ "y": 1500,
1149
+ "wires": [["a5194c26.18c628"]]
1150
+ },
1151
+ {
1152
+ "id": "6f7bc7fa.7f4f6",
1153
+ "type": "inject",
1154
+ "z": "eeb8b00c.2c18c",
1155
+ "g": "a875cc7.a4c42b",
1156
+ "name": "NO RESPONSE",
1157
+ "props": [
1158
+ {
1159
+ "p": "payload"
1160
+ },
1161
+ {
1162
+ "p": "topic",
1163
+ "vt": "str"
1164
+ }
1165
+ ],
1166
+ "repeat": "",
1167
+ "crontab": "",
1168
+ "once": false,
1169
+ "onceDelay": 0.1,
1170
+ "topic": "",
1171
+ "payload": "{\"ContactSensorState\":\"NO_RESPONSE\"}",
1172
+ "payloadType": "json",
1173
+ "x": 220,
1174
+ "y": 1400,
1175
+ "wires": [["a5194c26.18c628"]]
1176
+ },
1177
+ {
1178
+ "id": "99b55eb3.e31bf8",
1179
+ "type": "trigger",
1180
+ "z": "eeb8b00c.2c18c",
1181
+ "g": "a875cc7.a4c42b",
1182
+ "name": "10 Sec open",
1183
+ "op1": "",
1184
+ "op2": "{\"ContactSensorState\":0}",
1185
+ "op1type": "pay",
1186
+ "op2type": "json",
1187
+ "duration": "10",
1188
+ "extend": false,
1189
+ "units": "s",
1190
+ "reset": "",
1191
+ "bytopic": "all",
1192
+ "topic": "topic",
1193
+ "outputs": 1,
1194
+ "x": 430,
1195
+ "y": 1340,
1196
+ "wires": [["a5194c26.18c628"]]
1197
+ },
1198
+ {
1199
+ "id": "508d9ccf.29e404",
1200
+ "type": "inject",
1201
+ "z": "eeb8b00c.2c18c",
1202
+ "g": "a875cc7.a4c42b",
1203
+ "name": "Open",
1204
+ "props": [
1205
+ {
1206
+ "p": "payload"
1207
+ },
1208
+ {
1209
+ "p": "topic",
1210
+ "vt": "str"
1211
+ }
1212
+ ],
1213
+ "repeat": "",
1214
+ "crontab": "",
1215
+ "once": false,
1216
+ "onceDelay": "1",
1217
+ "topic": "",
1218
+ "payload": "{\"ContactSensorState\":1}",
1219
+ "payloadType": "json",
1220
+ "x": 190,
1221
+ "y": 1340,
1222
+ "wires": [["99b55eb3.e31bf8"]]
1223
+ },
1224
+ {
1225
+ "id": "ab48426e.25466",
1226
+ "type": "group",
1227
+ "z": "eeb8b00c.2c18c",
1228
+ "name": "CO2 Sensor: input only sensor",
1229
+ "style": {
1230
+ "stroke": "#999999",
1231
+ "fill": "none",
1232
+ "label": true,
1233
+ "label-position": "nw",
1234
+ "color": "#a4a4a4"
1235
+ },
1236
+ "nodes": [
1237
+ "88892b4.8a61bd8",
1238
+ "3611c654.8a42f2",
1239
+ "62cafcb0.8ade9c",
1240
+ "a0171cdb.f209b",
1241
+ "6f7de764.a6a688",
1242
+ "8758b463.afb0f",
1243
+ "69e8161b.74b7a",
1244
+ "40010b09.c73cdc"
1245
+ ],
1246
+ "x": 94,
1247
+ "y": 779,
1248
+ "w": 752,
1249
+ "h": 202,
1250
+ "info": "# CO2 Sensor\n\nThere are three inputs to this example, one for each level of Carbon Dioxide in the air. Options are:\n\n**0 ppm:** this will assume no CO2 <br/>\n**Safe level:** this will assume a level between 1 and 999 ppm, inclusive <br/>\n**Dangerous level:** this will assume a level between 1,000 and 100,000, inclusive; this will also trigger an alert"
1251
+ },
1252
+ {
1253
+ "id": "88892b4.8a61bd8",
1254
+ "type": "homekit-service",
1255
+ "z": "eeb8b00c.2c18c",
1256
+ "g": "ab48426e.25466",
1257
+ "isParent": true,
1258
+ "hostType": "0",
1259
+ "bridge": "409001a1.3e7a78",
1260
+ "accessoryId": "",
1261
+ "parentService": "",
1262
+ "name": "CO2 Sensor",
1263
+ "serviceName": "CarbonDioxideSensor",
1264
+ "topic": "",
1265
+ "filter": false,
1266
+ "manufacturer": "Default Manufacturer",
1267
+ "model": "Carbon",
1268
+ "serialNo": "Default Serial Number",
1269
+ "firmwareRev": "22",
1270
+ "hardwareRev": "11",
1271
+ "softwareRev": "",
1272
+ "cameraConfigVideoProcessor": "",
1273
+ "cameraConfigSource": "",
1274
+ "cameraConfigStillImageSource": "",
1275
+ "cameraConfigMaxStreams": "",
1276
+ "cameraConfigMaxWidth": "",
1277
+ "cameraConfigMaxHeight": "",
1278
+ "cameraConfigMaxFPS": "",
1279
+ "cameraConfigMaxBitrate": "",
1280
+ "cameraConfigVideoCodec": "",
1281
+ "cameraConfigAudioCodec": "",
1282
+ "cameraConfigAudio": false,
1283
+ "cameraConfigPacketSize": "",
1284
+ "cameraConfigVerticalFlip": false,
1285
+ "cameraConfigHorizontalFlip": false,
1286
+ "cameraConfigMapVideo": "",
1287
+ "cameraConfigMapAudio": "",
1288
+ "cameraConfigVideoFilter": "",
1289
+ "cameraConfigAdditionalCommandLine": "",
1290
+ "cameraConfigDebug": false,
1291
+ "cameraConfigSnapshotOutput": "disabled",
1292
+ "cameraConfigInterfaceName": "",
1293
+ "characteristicProperties": "{ \"CarbonDioxideLevel\" : true, \"CarbonDioxidePeakLevel\": true, \"StatusActive\" : true}",
1294
+ "waitForSetupMsg": false,
1295
+ "outputs": 2,
1296
+ "x": 750,
1297
+ "y": 820,
1298
+ "wires": [[], []]
1299
+ },
1300
+ {
1301
+ "id": "3611c654.8a42f2",
1302
+ "type": "function",
1303
+ "z": "eeb8b00c.2c18c",
1304
+ "g": "ab48426e.25466",
1305
+ "name": "Random values, peak value",
1306
+ "func": "// Reset all values to 0 if 0ppm input\nif(msg.payload === 0){\n context.set('lastPeak',0);\n newMsg = {\n payload: {\n \"CarbonDioxideLevel\":0,\n \"CarbonDioxidePeakLevel\":0,\n \"CarbonDioxideDetected\":0\n }\n };\n return newMsg;\n}\n\n// Initialize vars\nvar CurrentLevel = 0;\nvar lastPeak = context.get('lastPeak');\n\n// Set random safe or dangerous levels\nif(msg.payload === \"Safe\"){\n CurrentLevel = Math.floor(Math.random() * (999 - 1 + 1) + 1);\n}\nif(msg.payload === \"Danger\"){\n CurrentLevel = Math.floor(Math.random() * (100000 - 1000 + 1) + 1000);\n}\n\n// Formulate output message\nvar newMsg = {\n payload: {\n \"CarbonDioxideLevel\" : CurrentLevel,\n \"CarbonDioxideDetected\" : 0\n }\n};\n\n// Set new peak level\nif(CurrentLevel > lastPeak){\n lastPeak = CurrentLevel;\n context.set('lastPeak',CurrentLevel);\n newMsg.payload.CarbonDioxidePeakLevel = CurrentLevel;\n}\n\n// Set warning if dangerous\nif (CurrentLevel >= 1000) {\n newMsg.payload.CarbonDioxideDetected = 1;\n} \n\nreturn newMsg;",
1307
+ "outputs": 1,
1308
+ "noerr": 0,
1309
+ "initialize": "// Code added here will be run once\n// whenever the node is deployed.\ncontext.set('lastPeak',0);\n",
1310
+ "finalize": "",
1311
+ "x": 480,
1312
+ "y": 820,
1313
+ "wires": [["88892b4.8a61bd8"]]
1314
+ },
1315
+ {
1316
+ "id": "62cafcb0.8ade9c",
1317
+ "type": "inject",
1318
+ "z": "eeb8b00c.2c18c",
1319
+ "g": "ab48426e.25466",
1320
+ "name": "Active",
1321
+ "repeat": "",
1322
+ "crontab": "",
1323
+ "once": false,
1324
+ "onceDelay": 0.1,
1325
+ "topic": "",
1326
+ "payload": "{\"StatusActive\":true}",
1327
+ "payloadType": "json",
1328
+ "x": 550,
1329
+ "y": 860,
1330
+ "wires": [["88892b4.8a61bd8"]]
1331
+ },
1332
+ {
1333
+ "id": "a0171cdb.f209b",
1334
+ "type": "inject",
1335
+ "z": "eeb8b00c.2c18c",
1336
+ "g": "ab48426e.25466",
1337
+ "name": "Inactive",
1338
+ "repeat": "",
1339
+ "crontab": "",
1340
+ "once": false,
1341
+ "onceDelay": 0.1,
1342
+ "topic": "",
1343
+ "payload": "{\"StatusActive\":false}",
1344
+ "payloadType": "json",
1345
+ "x": 550,
1346
+ "y": 900,
1347
+ "wires": [["88892b4.8a61bd8"]]
1348
+ },
1349
+ {
1350
+ "id": "6f7de764.a6a688",
1351
+ "type": "inject",
1352
+ "z": "eeb8b00c.2c18c",
1353
+ "g": "ab48426e.25466",
1354
+ "name": "NO RESPONSE",
1355
+ "repeat": "",
1356
+ "crontab": "",
1357
+ "once": false,
1358
+ "onceDelay": 0.1,
1359
+ "topic": "",
1360
+ "payload": "{\"CarbonDioxideLevel\":\"NO_RESPONSE\"}",
1361
+ "payloadType": "json",
1362
+ "x": 520,
1363
+ "y": 940,
1364
+ "wires": [["88892b4.8a61bd8"]]
1365
+ },
1366
+ {
1367
+ "id": "8758b463.afb0f",
1368
+ "type": "inject",
1369
+ "z": "eeb8b00c.2c18c",
1370
+ "g": "ab48426e.25466",
1371
+ "name": "0 ppm",
1372
+ "props": [
1373
+ {
1374
+ "p": "payload"
1375
+ }
1376
+ ],
1377
+ "repeat": "",
1378
+ "crontab": "",
1379
+ "once": false,
1380
+ "onceDelay": 0.1,
1381
+ "topic": "",
1382
+ "payload": "0",
1383
+ "payloadType": "num",
1384
+ "x": 190,
1385
+ "y": 820,
1386
+ "wires": [["3611c654.8a42f2"]]
1387
+ },
1388
+ {
1389
+ "id": "69e8161b.74b7a",
1390
+ "type": "inject",
1391
+ "z": "eeb8b00c.2c18c",
1392
+ "g": "ab48426e.25466",
1393
+ "name": "Safe Level",
1394
+ "props": [
1395
+ {
1396
+ "p": "payload"
1397
+ }
1398
+ ],
1399
+ "repeat": "",
1400
+ "crontab": "",
1401
+ "once": false,
1402
+ "onceDelay": 0.1,
1403
+ "topic": "",
1404
+ "payload": "Safe",
1405
+ "payloadType": "str",
1406
+ "x": 200,
1407
+ "y": 860,
1408
+ "wires": [["3611c654.8a42f2"]]
1409
+ },
1410
+ {
1411
+ "id": "40010b09.c73cdc",
1412
+ "type": "inject",
1413
+ "z": "eeb8b00c.2c18c",
1414
+ "g": "ab48426e.25466",
1415
+ "name": "Dangerous level",
1416
+ "props": [
1417
+ {
1418
+ "p": "payload"
1419
+ }
1420
+ ],
1421
+ "repeat": "",
1422
+ "crontab": "",
1423
+ "once": false,
1424
+ "onceDelay": 0.1,
1425
+ "topic": "",
1426
+ "payload": "Danger",
1427
+ "payloadType": "str",
1428
+ "x": 220,
1429
+ "y": 900,
1430
+ "wires": [["3611c654.8a42f2"]]
1431
+ },
1432
+ {
1433
+ "id": "b3b5156e.cdf988",
1434
+ "type": "group",
1435
+ "z": "eeb8b00c.2c18c",
1436
+ "name": "Air Quality with Battery: input only sensor",
1437
+ "style": {
1438
+ "stroke": "#999999",
1439
+ "fill": "none",
1440
+ "label": true,
1441
+ "label-position": "nw",
1442
+ "color": "#a4a4a4"
1443
+ },
1444
+ "nodes": [
1445
+ "8088a797.e1a7c",
1446
+ "a70b3192.dfb4f",
1447
+ "d5708f5.036c87",
1448
+ "90b692e4.b9f6c",
1449
+ "54bfafbc.396898",
1450
+ "560fc866.6de558",
1451
+ "61e113b2.dbb714"
1452
+ ],
1453
+ "x": 94,
1454
+ "y": 239,
1455
+ "w": 758,
1456
+ "h": 208,
1457
+ "info": "# Air Quality Sensor\n\nThis sensor will inject random values for all of the air quality metrics available in the HomeKit spec. It will also inject random values for a linked battery service.\n\nWatch the input and Home app to learn how to see how things are working."
1458
+ },
1459
+ {
1460
+ "id": "8088a797.e1a7c",
1461
+ "type": "homekit-service",
1462
+ "z": "eeb8b00c.2c18c",
1463
+ "g": "b3b5156e.cdf988",
1464
+ "isParent": true,
1465
+ "hostType": "0",
1466
+ "bridge": "409001a1.3e7a78",
1467
+ "accessoryId": "",
1468
+ "parentService": "",
1469
+ "name": "Air Quality",
1470
+ "serviceName": "AirQualitySensor",
1471
+ "topic": "",
1472
+ "filter": false,
1473
+ "manufacturer": "Quality",
1474
+ "model": "Battery",
1475
+ "serialNo": "777",
1476
+ "firmwareRev": "8.3",
1477
+ "hardwareRev": "2.1",
1478
+ "softwareRev": "1.0.0",
1479
+ "cameraConfigVideoProcessor": "ffmpeg",
1480
+ "cameraConfigSource": "",
1481
+ "cameraConfigStillImageSource": "",
1482
+ "cameraConfigMaxStreams": 2,
1483
+ "cameraConfigMaxWidth": 1280,
1484
+ "cameraConfigMaxHeight": 720,
1485
+ "cameraConfigMaxFPS": 10,
1486
+ "cameraConfigMaxBitrate": 300,
1487
+ "cameraConfigVideoCodec": "libx264",
1488
+ "cameraConfigAudioCodec": "libfdk_aac",
1489
+ "cameraConfigAudio": false,
1490
+ "cameraConfigPacketSize": 1316,
1491
+ "cameraConfigVerticalFlip": false,
1492
+ "cameraConfigHorizontalFlip": false,
1493
+ "cameraConfigMapVideo": "0:0",
1494
+ "cameraConfigMapAudio": "0:1",
1495
+ "cameraConfigVideoFilter": "scale=1280:720",
1496
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
1497
+ "cameraConfigDebug": false,
1498
+ "cameraConfigSnapshotOutput": "disabled",
1499
+ "cameraConfigInterfaceName": "",
1500
+ "characteristicProperties": "{ \"AirQuality\":true, \"PM2_5Density\":true, \"PM10Density\":true}",
1501
+ "waitForSetupMsg": false,
1502
+ "outputs": 2,
1503
+ "x": 750,
1504
+ "y": 280,
1505
+ "wires": [[], []]
1506
+ },
1507
+ {
1508
+ "id": "a70b3192.dfb4f",
1509
+ "type": "inject",
1510
+ "z": "eeb8b00c.2c18c",
1511
+ "g": "b3b5156e.cdf988",
1512
+ "name": "Air quality random",
1513
+ "props": [
1514
+ {
1515
+ "p": "payload"
1516
+ }
1517
+ ],
1518
+ "repeat": "15",
1519
+ "crontab": "",
1520
+ "once": true,
1521
+ "onceDelay": "5",
1522
+ "topic": "",
1523
+ "payload": "{}",
1524
+ "payloadType": "json",
1525
+ "x": 230,
1526
+ "y": 280,
1527
+ "wires": [["560fc866.6de558"]]
1528
+ },
1529
+ {
1530
+ "id": "d5708f5.036c87",
1531
+ "type": "inject",
1532
+ "z": "eeb8b00c.2c18c",
1533
+ "g": "b3b5156e.cdf988",
1534
+ "name": "Battery random",
1535
+ "props": [
1536
+ {
1537
+ "p": "payload"
1538
+ }
1539
+ ],
1540
+ "repeat": "30",
1541
+ "crontab": "",
1542
+ "once": true,
1543
+ "onceDelay": "5",
1544
+ "topic": "",
1545
+ "payload": "",
1546
+ "payloadType": "date",
1547
+ "x": 220,
1548
+ "y": 380,
1549
+ "wires": [["90b692e4.b9f6c"]]
1550
+ },
1551
+ {
1552
+ "id": "90b692e4.b9f6c",
1553
+ "type": "function",
1554
+ "z": "eeb8b00c.2c18c",
1555
+ "g": "b3b5156e.cdf988",
1556
+ "name": "Batt",
1557
+ "func": "// Define random battery level\nconst level = Math.floor(Math.random() * Math.floor(100))\nvar newMsg = {\n payload: {\n \"BatteryLevel\": level\n }\n};\n\n// Show \"Low Battery\" if less than 10%\nif (level < 10)newMsg.payload.StatusLowBattery = 1;\nelse newMsg.payload.StatusLowBattery = 0;\n\n// Show \"Charging\" if greater than 60%\nif (level > 60) newMsg.payload.ChargingState = 1;\nelse newMsg.payload.ChargingState = 0;\n\nreturn newMsg;",
1558
+ "outputs": 1,
1559
+ "noerr": 0,
1560
+ "initialize": "",
1561
+ "finalize": "",
1562
+ "x": 470,
1563
+ "y": 380,
1564
+ "wires": [["5cd5342a.cfd72c"]]
1565
+ },
1566
+ {
1567
+ "id": "54bfafbc.396898",
1568
+ "type": "inject",
1569
+ "z": "eeb8b00c.2c18c",
1570
+ "g": "b3b5156e.cdf988",
1571
+ "name": "NO RESPONSE",
1572
+ "props": [
1573
+ {
1574
+ "p": "payload"
1575
+ }
1576
+ ],
1577
+ "repeat": "",
1578
+ "crontab": "",
1579
+ "once": false,
1580
+ "onceDelay": 0.1,
1581
+ "topic": "",
1582
+ "payload": "{\"AirQuality\":\"NO_RESPONSE\"}",
1583
+ "payloadType": "json",
1584
+ "x": 500,
1585
+ "y": 320,
1586
+ "wires": [["8088a797.e1a7c"]]
1587
+ },
1588
+ {
1589
+ "id": "560fc866.6de558",
1590
+ "type": "function",
1591
+ "z": "eeb8b00c.2c18c",
1592
+ "g": "b3b5156e.cdf988",
1593
+ "name": "Random values",
1594
+ "func": "var newMsg = {\n \"payload\":{\n \"AirQuality\":Math.floor(Math.random() * Math.floor(5)),\n \"PM2_5Density\":Math.floor(Math.random() * Math.floor(1000)),\n \"PM10Density\":Math.floor(Math.random() * Math.floor(1000)),\n \"OzoneDensity\":Math.floor(Math.random() * Math.floor(1000)),\n \"NitrogenDioxideDensity\":Math.floor(Math.random() * Math.floor(1000)),\n \"SulphurDioxideDensity\": Math.floor(Math.random() * Math.floor(1000))\n }\n}\n\n\n\nreturn newMsg;",
1595
+ "outputs": 1,
1596
+ "noerr": 0,
1597
+ "initialize": "",
1598
+ "finalize": "",
1599
+ "x": 500,
1600
+ "y": 280,
1601
+ "wires": [["8088a797.e1a7c"]]
1602
+ },
1603
+ {
1604
+ "id": "61e113b2.dbb714",
1605
+ "type": "group",
1606
+ "z": "eeb8b00c.2c18c",
1607
+ "g": "b3b5156e.cdf988",
1608
+ "name": "LINKED",
1609
+ "style": {
1610
+ "stroke": "#0070c0",
1611
+ "fill": "#bfdbef",
1612
+ "label": true
1613
+ },
1614
+ "nodes": ["5cd5342a.cfd72c"],
1615
+ "x": 654,
1616
+ "y": 339,
1617
+ "w": 172,
1618
+ "h": 82
1619
+ },
1620
+ {
1621
+ "id": "5cd5342a.cfd72c",
1622
+ "type": "homekit-service",
1623
+ "z": "eeb8b00c.2c18c",
1624
+ "g": "61e113b2.dbb714",
1625
+ "isParent": false,
1626
+ "bridge": "",
1627
+ "accessoryId": "",
1628
+ "parentService": "8088a797.e1a7c",
1629
+ "name": "Battery",
1630
+ "serviceName": "Battery",
1631
+ "topic": "Air Quality",
1632
+ "filter": false,
1633
+ "manufacturer": "Default Manufacturer",
1634
+ "model": "Default Model",
1635
+ "serialNo": "Default Serial Number",
1636
+ "firmwareRev": "1.0.0",
1637
+ "hardwareRev": "1.0.0",
1638
+ "softwareRev": "1.0.0",
1639
+ "cameraConfigVideoProcessor": "ffmpeg",
1640
+ "cameraConfigSource": "",
1641
+ "cameraConfigStillImageSource": "",
1642
+ "cameraConfigMaxStreams": 2,
1643
+ "cameraConfigMaxWidth": 1280,
1644
+ "cameraConfigMaxHeight": 720,
1645
+ "cameraConfigMaxFPS": 10,
1646
+ "cameraConfigMaxBitrate": 300,
1647
+ "cameraConfigVideoCodec": "libx264",
1648
+ "cameraConfigAudioCodec": "libfdk_aac",
1649
+ "cameraConfigAudio": false,
1650
+ "cameraConfigPacketSize": 1316,
1651
+ "cameraConfigVerticalFlip": false,
1652
+ "cameraConfigHorizontalFlip": false,
1653
+ "cameraConfigMapVideo": "0:0",
1654
+ "cameraConfigMapAudio": "0:1",
1655
+ "cameraConfigVideoFilter": "scale=1280:720",
1656
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
1657
+ "cameraConfigDebug": false,
1658
+ "cameraConfigSnapshotOutput": "disabled",
1659
+ "cameraConfigInterfaceName": "",
1660
+ "characteristicProperties": "{}",
1661
+ "waitForSetupMsg": false,
1662
+ "outputs": 2,
1663
+ "x": 740,
1664
+ "y": 380,
1665
+ "wires": [[], []]
1666
+ },
1667
+ {
1668
+ "id": "c869b0a5.e4def8",
1669
+ "type": "group",
1670
+ "z": "eeb8b00c.2c18c",
1671
+ "name": "Fan Simplified: input from device, output to device",
1672
+ "style": {
1673
+ "stroke": "#999999",
1674
+ "fill": "none",
1675
+ "label": true,
1676
+ "label-position": "nw",
1677
+ "color": "#a4a4a4"
1678
+ },
1679
+ "nodes": [
1680
+ "dadd634c.ae2258",
1681
+ "753e3777.49a1d",
1682
+ "992f4930.012aa",
1683
+ "2497a466.aa0e84",
1684
+ "c53b76fb.7a3cc8",
1685
+ "6c9646ee.1f3a18",
1686
+ "1e42a8f3.cf008f"
1687
+ ],
1688
+ "x": 94,
1689
+ "y": 1759,
1690
+ "w": 752,
1691
+ "h": 202,
1692
+ "info": "# Fan Simple\n\nThis example is for a 3-speed fan.\n\nSpeeds are: <br/>\nLow = 33<br/>\nMedium = 66<br/>\nHigh = 99<br/>\n\nValues outside of this are restricted and will not work. The home app will \"snap\" to these values. Siri will respond to \"set fan to low/medium/high\" with the corresponding value."
1693
+ },
1694
+ {
1695
+ "id": "dadd634c.ae2258",
1696
+ "type": "debug",
1697
+ "z": "eeb8b00c.2c18c",
1698
+ "g": "c869b0a5.e4def8",
1699
+ "name": "Fan output",
1700
+ "active": true,
1701
+ "tosidebar": true,
1702
+ "console": false,
1703
+ "tostatus": false,
1704
+ "complete": "payload",
1705
+ "targetType": "msg",
1706
+ "statusVal": "",
1707
+ "statusType": "auto",
1708
+ "x": 730,
1709
+ "y": 1800,
1710
+ "wires": []
1711
+ },
1712
+ {
1713
+ "id": "753e3777.49a1d",
1714
+ "type": "homekit-service",
1715
+ "z": "eeb8b00c.2c18c",
1716
+ "g": "c869b0a5.e4def8",
1717
+ "isParent": true,
1718
+ "bridge": "409001a1.3e7a78",
1719
+ "parentService": "",
1720
+ "name": "Fan Speeds",
1721
+ "serviceName": "Fan",
1722
+ "topic": "",
1723
+ "filter": false,
1724
+ "manufacturer": "Gman",
1725
+ "model": "Default Model",
1726
+ "serialNo": "CRX1",
1727
+ "firmwareRev": "1.0.0",
1728
+ "hardwareRev": "1.0.0",
1729
+ "softwareRev": "1.0.0",
1730
+ "cameraConfigVideoProcessor": "ffmpeg",
1731
+ "cameraConfigSource": "",
1732
+ "cameraConfigStillImageSource": "",
1733
+ "cameraConfigMaxStreams": 2,
1734
+ "cameraConfigMaxWidth": 1280,
1735
+ "cameraConfigMaxHeight": 720,
1736
+ "cameraConfigMaxFPS": 10,
1737
+ "cameraConfigMaxBitrate": 300,
1738
+ "cameraConfigVideoCodec": "libx264",
1739
+ "cameraConfigAudioCodec": "libfdk_aac",
1740
+ "cameraConfigAudio": false,
1741
+ "cameraConfigPacketSize": 1316,
1742
+ "cameraConfigVerticalFlip": false,
1743
+ "cameraConfigHorizontalFlip": false,
1744
+ "cameraConfigMapVideo": "0:0",
1745
+ "cameraConfigMapAudio": "0:1",
1746
+ "cameraConfigVideoFilter": "scale=1280:720",
1747
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
1748
+ "cameraConfigDebug": false,
1749
+ "cameraConfigSnapshotOutput": "disabled",
1750
+ "cameraConfigInterfaceName": "",
1751
+ "characteristicProperties": "{\n \"RotationSpeed\": {\n \"minValue\":0,\n \"maxValue\":99,\n \"minStep\":33\n }\n}",
1752
+ "outputs": 2,
1753
+ "x": 510,
1754
+ "y": 1800,
1755
+ "wires": [["dadd634c.ae2258"], []]
1756
+ },
1757
+ {
1758
+ "id": "992f4930.012aa",
1759
+ "type": "inject",
1760
+ "z": "eeb8b00c.2c18c",
1761
+ "g": "c869b0a5.e4def8",
1762
+ "name": "NO RESPONSE",
1763
+ "props": [
1764
+ {
1765
+ "p": "payload"
1766
+ },
1767
+ {
1768
+ "p": "topic",
1769
+ "vt": "str"
1770
+ }
1771
+ ],
1772
+ "repeat": "",
1773
+ "crontab": "",
1774
+ "once": false,
1775
+ "onceDelay": 0.1,
1776
+ "topic": "",
1777
+ "payload": "{\"On\":\"NO_RESPONSE\"}",
1778
+ "payloadType": "json",
1779
+ "x": 460,
1780
+ "y": 1880,
1781
+ "wires": [["753e3777.49a1d"]]
1782
+ },
1783
+ {
1784
+ "id": "2497a466.aa0e84",
1785
+ "type": "inject",
1786
+ "z": "eeb8b00c.2c18c",
1787
+ "g": "c869b0a5.e4def8",
1788
+ "name": "OFF",
1789
+ "props": [
1790
+ {
1791
+ "p": "payload"
1792
+ },
1793
+ {
1794
+ "p": "topic",
1795
+ "vt": "str"
1796
+ }
1797
+ ],
1798
+ "repeat": "",
1799
+ "crontab": "",
1800
+ "once": false,
1801
+ "onceDelay": 0.1,
1802
+ "topic": "",
1803
+ "payload": "{\"On\":false}",
1804
+ "payloadType": "json",
1805
+ "x": 190,
1806
+ "y": 1800,
1807
+ "wires": [["753e3777.49a1d"]]
1808
+ },
1809
+ {
1810
+ "id": "c53b76fb.7a3cc8",
1811
+ "type": "inject",
1812
+ "z": "eeb8b00c.2c18c",
1813
+ "g": "c869b0a5.e4def8",
1814
+ "name": "Low",
1815
+ "props": [
1816
+ {
1817
+ "p": "payload"
1818
+ },
1819
+ {
1820
+ "p": "topic",
1821
+ "vt": "str"
1822
+ }
1823
+ ],
1824
+ "repeat": "",
1825
+ "crontab": "",
1826
+ "once": false,
1827
+ "onceDelay": 0.1,
1828
+ "topic": "",
1829
+ "payload": "{\"On\":true,\"RotationSpeed\":33}",
1830
+ "payloadType": "json",
1831
+ "x": 190,
1832
+ "y": 1840,
1833
+ "wires": [["753e3777.49a1d"]]
1834
+ },
1835
+ {
1836
+ "id": "6c9646ee.1f3a18",
1837
+ "type": "inject",
1838
+ "z": "eeb8b00c.2c18c",
1839
+ "g": "c869b0a5.e4def8",
1840
+ "name": "Medium",
1841
+ "props": [
1842
+ {
1843
+ "p": "payload"
1844
+ },
1845
+ {
1846
+ "p": "topic",
1847
+ "vt": "str"
1848
+ }
1849
+ ],
1850
+ "repeat": "",
1851
+ "crontab": "",
1852
+ "once": false,
1853
+ "onceDelay": 0.1,
1854
+ "topic": "",
1855
+ "payload": "{\"On\":true,\"RotationSpeed\":66}",
1856
+ "payloadType": "json",
1857
+ "x": 200,
1858
+ "y": 1880,
1859
+ "wires": [["753e3777.49a1d"]]
1860
+ },
1861
+ {
1862
+ "id": "1e42a8f3.cf008f",
1863
+ "type": "inject",
1864
+ "z": "eeb8b00c.2c18c",
1865
+ "g": "c869b0a5.e4def8",
1866
+ "name": "High",
1867
+ "props": [
1868
+ {
1869
+ "p": "payload"
1870
+ },
1871
+ {
1872
+ "p": "topic",
1873
+ "vt": "str"
1874
+ }
1875
+ ],
1876
+ "repeat": "",
1877
+ "crontab": "",
1878
+ "once": false,
1879
+ "onceDelay": 0.1,
1880
+ "topic": "",
1881
+ "payload": "{\"On\":true,\"RotationSpeed\":99}",
1882
+ "payloadType": "json",
1883
+ "x": 190,
1884
+ "y": 1920,
1885
+ "wires": [["753e3777.49a1d"]]
1886
+ }
2141
1887
  ]