nodejs-poolcontroller 8.3.0 → 8.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/.eslintrc.json +36 -36
  2. package/.github/ISSUE_TEMPLATE/1-bug-report.yml +84 -84
  3. package/.github/ISSUE_TEMPLATE/2-docs.md +12 -12
  4. package/.github/ISSUE_TEMPLATE/3-proposal.md +28 -28
  5. package/.github/ISSUE_TEMPLATE/config.yml +8 -8
  6. package/.github/copilot-instructions.md +63 -63
  7. package/.github/workflows/ghcr-publish.yml +67 -67
  8. package/AGENTS.md +597 -0
  9. package/CONTRIBUTING.md +74 -74
  10. package/Changelog +292 -284
  11. package/Dockerfile +62 -62
  12. package/Gruntfile.js +40 -40
  13. package/LICENSE +661 -661
  14. package/README.md +318 -309
  15. package/anslq25/MessagesMock.ts +221 -221
  16. package/anslq25/boards/MockBoardFactory.ts +49 -49
  17. package/anslq25/boards/MockEasyTouchBoard.ts +696 -696
  18. package/anslq25/boards/MockSystemBoard.ts +216 -216
  19. package/anslq25/chemistry/MockChlorinator.ts +98 -98
  20. package/anslq25/pumps/MockPump.ts +83 -83
  21. package/app.ts +115 -115
  22. package/config/Config.ts +0 -0
  23. package/config/VersionCheck.ts +0 -0
  24. package/controller/Constants.ts +809 -805
  25. package/controller/Equipment.ts +2688 -2664
  26. package/controller/Errors.ts +181 -181
  27. package/controller/Lockouts.ts +549 -549
  28. package/controller/State.ts +3738 -3701
  29. package/controller/boards/AquaLinkBoard.ts +1003 -1003
  30. package/controller/boards/BoardFactory.ts +53 -53
  31. package/controller/boards/EasyTouchBoard.ts +3202 -3202
  32. package/controller/boards/IntelliCenterBoard.ts +4393 -3899
  33. package/controller/boards/IntelliComBoard.ts +69 -69
  34. package/controller/boards/IntelliTouchBoard.ts +382 -382
  35. package/controller/boards/NixieBoard.ts +1944 -1944
  36. package/controller/boards/SunTouchBoard.ts +400 -400
  37. package/controller/boards/SystemBoard.ts +5268 -5268
  38. package/controller/comms/Comms.ts +1272 -1255
  39. package/controller/comms/ScreenLogic.ts +1665 -1665
  40. package/controller/comms/messages/Messages.ts +1433 -1406
  41. package/controller/comms/messages/config/ChlorinatorMessage.ts +5 -0
  42. package/controller/comms/messages/config/CircuitGroupMessage.ts +0 -0
  43. package/controller/comms/messages/config/CircuitMessage.ts +0 -0
  44. package/controller/comms/messages/config/ConfigMessage.ts +6 -0
  45. package/controller/comms/messages/config/CoverMessage.ts +0 -0
  46. package/controller/comms/messages/config/CustomNameMessage.ts +31 -31
  47. package/controller/comms/messages/config/EquipmentMessage.ts +216 -210
  48. package/controller/comms/messages/config/ExternalMessage.ts +96 -10
  49. package/controller/comms/messages/config/FeatureMessage.ts +0 -0
  50. package/controller/comms/messages/config/GeneralMessage.ts +0 -0
  51. package/controller/comms/messages/config/HeaterMessage.ts +0 -0
  52. package/controller/comms/messages/config/IntellichemMessage.ts +0 -0
  53. package/controller/comms/messages/config/OptionsMessage.ts +194 -174
  54. package/controller/comms/messages/config/PumpMessage.ts +0 -0
  55. package/controller/comms/messages/config/RemoteMessage.ts +0 -0
  56. package/controller/comms/messages/config/ScheduleMessage.ts +401 -390
  57. package/controller/comms/messages/config/SecurityMessage.ts +0 -0
  58. package/controller/comms/messages/config/ValveMessage.ts +0 -0
  59. package/controller/comms/messages/status/ChlorinatorStateMessage.ts +0 -0
  60. package/controller/comms/messages/status/EquipmentStateMessage.ts +1158 -822
  61. package/controller/comms/messages/status/HeaterStateMessage.ts +135 -135
  62. package/controller/comms/messages/status/IntelliChemStateMessage.ts +448 -448
  63. package/controller/comms/messages/status/IntelliValveStateMessage.ts +36 -36
  64. package/controller/comms/messages/status/PumpStateMessage.ts +0 -0
  65. package/controller/comms/messages/status/RegalModbusStateMessage.ts +410 -410
  66. package/controller/comms/messages/status/VersionMessage.ts +103 -41
  67. package/controller/nixie/Nixie.ts +173 -173
  68. package/controller/nixie/NixieEquipment.ts +104 -104
  69. package/controller/nixie/bodies/Body.ts +120 -120
  70. package/controller/nixie/bodies/Filter.ts +135 -135
  71. package/controller/nixie/chemistry/ChemController.ts +2724 -2724
  72. package/controller/nixie/chemistry/ChemDoser.ts +806 -806
  73. package/controller/nixie/chemistry/Chlorinator.ts +367 -367
  74. package/controller/nixie/circuits/Circuit.ts +478 -478
  75. package/controller/nixie/heaters/Heater.ts +834 -834
  76. package/controller/nixie/pumps/Pump.ts +1193 -1193
  77. package/controller/nixie/schedules/Schedule.ts +401 -401
  78. package/controller/nixie/valves/Valve.ts +170 -170
  79. package/defaultConfig.json +352 -352
  80. package/docker-compose.yml +31 -31
  81. package/logger/DataLogger.ts +448 -448
  82. package/logger/Logger.ts +448 -436
  83. package/package.json +58 -58
  84. package/sendSocket.js +32 -32
  85. package/tsconfig.json +25 -25
  86. package/types/express-multer.d.ts +32 -32
  87. package/web/Server.ts +1937 -1927
  88. package/web/bindings/aqualinkD.json +559 -559
  89. package/web/bindings/influxDB.json +1066 -1066
  90. package/web/bindings/mqtt.json +721 -721
  91. package/web/bindings/mqttAlt.json +746 -746
  92. package/web/bindings/rulesManager.json +54 -54
  93. package/web/bindings/smartThings-Hubitat.json +31 -31
  94. package/web/bindings/valveRelays.json +20 -20
  95. package/web/bindings/vera.json +25 -25
  96. package/web/interfaces/baseInterface.ts +188 -188
  97. package/web/interfaces/httpInterface.ts +148 -148
  98. package/web/interfaces/influxInterface.ts +283 -283
  99. package/web/interfaces/mqttInterface.ts +695 -695
  100. package/web/interfaces/ruleInterface.ts +101 -87
  101. package/web/services/config/Config.ts +1063 -1053
  102. package/web/services/config/ConfigSocket.ts +0 -0
  103. package/web/services/state/State.ts +0 -0
  104. package/web/services/state/StateSocket.ts +0 -0
  105. package/web/services/utilities/Utilities.ts +233 -233
@@ -1,722 +1,722 @@
1
- {
2
- "context": {
3
- "name": "MQTT",
4
- "options": {
5
- "formatter": [
6
- {
7
- "transform": ".toLowerCase()"
8
- },
9
- {
10
- "regexkey": "\\s",
11
- "replace": "",
12
- "description": "Remove whitespace"
13
- },
14
- {
15
- "regexkey": "\\/",
16
- "replace": "",
17
- "description": "Remove /"
18
- },
19
- {
20
- "regexkey": "\\+",
21
- "replace": "",
22
- "description": "Remove +"
23
- },
24
- {
25
- "regexkey": "\\$",
26
- "replace": "",
27
- "description": "Remove $"
28
- },
29
- {
30
- "regexkey": "\\#",
31
- "replace": "",
32
- "description": "Remove #"
33
- }
34
- ],
35
- "rootTopic-DIRECTIONS": "You can override the root topic by renaming _rootTopic to rootTopic",
36
- "_rootTopic": "@bind=(state.equipment.alias).replace(' ','-').replace('/','').toLowerCase();",
37
- "clientId": "@bind='mqttjs_njsPC_'+Math.random().toString(16).substr(2, 8);",
38
- "willTopic": "state/status",
39
- "willPayload": "{\"val\":3,\"name\":\"lost\",\"desc\":\"Connection Lost\",\"percent\":0}"
40
- }
41
- },
42
- "events": [
43
- {
44
- "name": "config",
45
- "description": "Don't flood the MQTT bus.",
46
- "enabled": false
47
- },
48
- {
49
- "name": "controller",
50
- "description": "Emit time every minute",
51
- "enabled": true,
52
- "topics": [
53
- {
54
- "topic": "state/time",
55
- "message": "@bind=data.time;",
56
- "filter": "@bind=data.status.percent === 100;"
57
- },
58
- {
59
- "topic": "alias",
60
- "message": "@bind=data.alias;"
61
- },
62
- {
63
- "topic": "state/status",
64
- "message": "@bind=data.status;"
65
- },
66
- {
67
- "topic": "state/mode",
68
- "message": "@bind=data.mode;"
69
- },
70
- {
71
- "topic": "state/startTime",
72
- "message": "@bind=data.startTime;"
73
- }
74
- ]
75
- },
76
- {
77
- "name": "circuit",
78
- "description": "Populate the circuits topics",
79
- "topics": [
80
- {
81
- "topic": "state/circuits/@bind=data.id;/@bind=data.name;",
82
- "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';,\"endTime\":\"@bind=data.endTime;\"}",
83
- "description": "Bind 'on'/'off' as a message to the state topic."
84
- },
85
- {
86
- "topic": "state/circuits/@bind=data.id;/@bind=data.name;/isOn/string",
87
- "message": "@bind=data.isOn?'on':'off';",
88
- "description": "Bind 'on'/'off' as a message to the topic.",
89
- "enabled": false
90
- },
91
- {
92
- "topic": "state/circuits/@bind=data.id;/@bind=data.name;/isOn/boolean",
93
- "message": "@bind=data.isOn;",
94
- "description": "SAMPLE: Bind the isOn as a message to the topic.",
95
- "enabled": false
96
- },
97
- {
98
- "topic": "state/circuits/@bind=data.id;/@bind=data.name;/lightingTheme",
99
- "message": "{\"lightingTheme\":@bind=data.lightingTheme;}",
100
- "description": "SAMPLE: Bind the lighting theme to the topic.",
101
- "filter": "@bind=data.type.isLight === true;"
102
- },
103
- {
104
- "topic": "state/circuits/@bind=data.id;/customTopicFormatter/@bind=data.name;/isOn",
105
- "message": "@bind=data.isOn;",
106
- "description": "SAMPLE: Bind the isOn as a message to the topic with a custom replacer, qos and retain setting.",
107
- "formatter": [
108
- {
109
- "transform": ".toLowerCase()"
110
- },
111
- {
112
- "regexkey": "\\s",
113
- "replace": "__",
114
- "description": "Remove whitespace and replace with __"
115
- },
116
- {
117
- "regexkey": "\\/",
118
- "replace": "__",
119
- "description": "Remove / and replace with __"
120
- }
121
- ],
122
- "options": { "qos": 2 },
123
- "enabled": false
124
- },
125
- {
126
- "topic": "state/circuits/@bind=data.id;/@bind=data.name;/endTime",
127
- "message": "{\"id\":@bind=data.id;,\"endTime\":@bind=data.endTime;}",
128
- "description": "Bind endTime as a message to the state topic."
129
- },
130
- {
131
- "topic": "state/circuits/@bind=data.id;/@bind=data.name;/object",
132
- "message": "@bind=data;",
133
- "description": "SAMPLE: Bind a JSON object as a message to the topic.",
134
- "enabled": false
135
- }
136
- ]
137
- },
138
- {
139
- "name": "virtualCircuit",
140
- "description": "Populate the virtual circuits topics",
141
- "topics": [
142
- {
143
- "topic": "state/virtualcircuits/@bind=data.id;/@bind=data.name;",
144
- "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';}",
145
- "description": "Bind 'on'/'off' as a message to the state topic."
146
- }
147
- ]
148
- },
149
- {
150
- "name": "valve",
151
- "description": "Populate the valve topics",
152
- "topics": [
153
- {
154
- "topic": "state/valve/@bind=data.id;/@bind=data.name;",
155
- "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isDiverted?'\"on\"':'\"off\"';,\"isVirtual\":@bind=data.isVirtual? true: false;,\"pinId\": @bind=data.pinId;}",
156
- "description": "Bind 'on'/'off' as a message to the valve state topic."
157
- }
158
- ]
159
- },
160
- {
161
- "name": "feature",
162
- "description": "Populate the features topics",
163
- "topics": [
164
- {
165
- "topic": "state/features/@bind=data.id;/@bind=data.name;",
166
- "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';,\"endTime\":\"@bind=data.endTime;\"}",
167
- "description": "Bind 'on'/'off' as a message to the state topic."
168
- },
169
- {
170
- "topic": "state/features/@bind=data.id;/@bind=data.name;/endTime",
171
- "message": "{\"id\":@bind=data.id;,\"endTime\":@bind=data.endTime;}",
172
- "description": "Bind endTime as a message to the state topic."
173
- }
174
- ]
175
- },
176
- {
177
- "name": "temps",
178
- "description": "Populate the temps topics",
179
- "topics": [
180
- {
181
- "topic": "state/temps/air",
182
- "message": "{\"temp\":@bind=data.air;}",
183
- "description": "Send air temp."
184
- },
185
- {
186
- "topic": "state/temps/solar",
187
- "message": "{\"temp\":@bind=data.solar;}",
188
- "description": "Send solar temp.",
189
- "filter": "@bind=typeof data.solar !== 'undefined';"
190
- },
191
- {
192
- "topic": "state/temps/solarSensor2",
193
- "message": "{\"temp\":@bind=data.solarSensor2;}",
194
- "description": "Solar temp",
195
- "filter": "@bind=typeof data.solarSensor2 !== 'undefined';"
196
- },
197
- {
198
- "topic": "state/temps/solarSensor3",
199
- "message": "{\"temp\":@bind=data.solarSensor3;}",
200
- "description": "Solar temp",
201
- "filter": "@bind=typeof data.solarSensor3 !== 'undefined';"
202
- },
203
- {
204
- "topic": "state/temps/solarSensor4",
205
- "message": "{\"temp\":@bind=data.solarSensor4;}",
206
- "description": "Solar temp",
207
- "filter": "@bind=typeof data.solarSensor4 !== 'undefined';"
208
- },
209
-
210
- {
211
- "topic": "state/temps/waterSensor1",
212
- "message": "{\"temp\":@bind=data.waterSensor1;}",
213
- "description": "Water temp sensor 1",
214
- "filter": "@bind=typeof data.waterSensor1 !== 'undefined';"
215
- },
216
- {
217
- "topic": "state/temps/waterSensor2",
218
- "message": "{\"temp\":@bind=data.waterSensor2;}",
219
- "description": "Water temp sensor 2",
220
- "filter": "@bind=typeof data.waterSensor2 !== 'undefined';"
221
- },
222
- {
223
- "topic": "state/temps/waterSensor3",
224
- "message": "{\"temp\":@bind=data.waterSensor3;}",
225
- "description": "Water temp sensor 3",
226
- "filter": "@bind=typeof data.waterSensor3 !== 'undefined';"
227
- },
228
- {
229
- "topic": "state/temps/waterSensor4",
230
- "message": "{\"temp\":@bind=data.waterSensor4;}",
231
- "description": "Water temp sensor 4",
232
- "filter": "@bind=typeof data.waterSensor4 !== 'undefined';"
233
- },
234
- {
235
- "topic": "state/temps/units",
236
- "message": "{\"units\":@bind=data.units;}"
237
- }
238
- ]
239
- },
240
- {
241
- "name": "circuitGroup",
242
- "description": "Populate the circuitGroup topic",
243
- "topics": [
244
- {
245
- "topic": "state/circuitGroups/@bind=data.id;/@bind=data.name;",
246
- "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';,\"endTime\":\"@bind=data.endTime;\"}",
247
- "description": "Bind name to the state topic."
248
- },
249
- {
250
- "topic": "state/circuitGroups/@bind=data.id;/@bind=data.name;/isOn",
251
- "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';}",
252
- "description": "Bind the on/off status to the topic.",
253
- "enabled": false
254
- },
255
- {
256
- "topic": "state/circuitGroups/@bind=data.id;/@bind=data.name;/type",
257
- "message": "{\"type\":@bind=data.type;}",
258
- "enabled": false
259
- },
260
- {
261
- "topic": "state/circuitGroups/@bind=data.id;/@bind=data.name;/showInFeatures",
262
- "message": "{\"showInFeatures\":@bind=data.showInFeatures;}",
263
- "description": "Indicates wether the item should show in features."
264
- }
265
-
266
- ]
267
- },
268
- {
269
- "name": "body",
270
- "description": "Populate the body topic",
271
- "topics": [
272
- {
273
- "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;",
274
- "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';}",
275
- "description": "Bind 'on'/'off' as a message to the state topic."
276
- },
277
- {
278
- "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;/heatMode",
279
- "message": "{\"heatMode\":@bind=data.heatMode;}",
280
- "description": "Send heat mode."
281
- },
282
- {
283
- "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;/heatStatus",
284
- "message": "{\"heatStatus\":@bind=data.heatStatus;}",
285
- "description": "Send heat status."
286
- },
287
- {
288
- "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;/setPoint",
289
- "message": "{\"setPoint\":@bind=data.setPoint;}",
290
- "description": "Send set point."
291
- },
292
- {
293
- "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;/heatSetpoint",
294
- "message": "{\"heatSetpoint\":@bind=data.setPoint;}",
295
- "description": "Send heat set point."
296
- },
297
- {
298
- "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;/coolSetpoint",
299
- "message": "{\"coolSetpoint\":@bind=data.coolSetpoint;}",
300
- "description": "Send cool set point."
301
- },
302
- {
303
- "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;/temp",
304
- "message": "{\"temp\":@bind=data.temp;}",
305
- "description": "Send temp."
306
- }
307
- ]
308
- },
309
- {
310
- "name": "chlorinator",
311
- "description": "Populate the chlorinator topic",
312
- "topics": [
313
- {
314
- "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;",
315
- "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.currentOutput > 0 ?'\"on\"':'\"off\"';}",
316
- "description": "Bind 'on'/'off' as a message to the state topic."
317
- },
318
- {
319
- "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/currentOutput",
320
- "message": "{\"currentOutput\":@bind=data.currentOutput;}",
321
- "description": "Send current output."
322
- },
323
- {
324
- "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/poolSetpoint",
325
- "message": "{\"poolSetpoint\":@bind=data.poolSetpoint;}",
326
- "description": "Send pool setpoint."
327
- },
328
- {
329
- "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/spaSetpoint",
330
- "message": "{\"spaSetpoint\":@bind=data.spaSetpoint;}",
331
- "description": "Send set point."
332
- },
333
- {
334
- "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/status",
335
- "message": "{\"status\":@bind=data.status;}",
336
- "description": "Send status."
337
- },
338
- {
339
- "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/superChlor",
340
- "message": "{\"superChlor\":@bind=data.superChlor?'\"on\"':'\"off\"';}",
341
- "description": "Send superChlor."
342
- },
343
- {
344
- "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/superChlorHours",
345
- "message": "{\"superChlorHours\":@bind=data.superChlorHours;}",
346
- "description": "Send superChlorHours."
347
- },
348
- {
349
- "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/saltLevel",
350
- "message": "{\"saltLevel\":@bind=data.saltLevel;}",
351
- "description": "Send salt level."
352
- },
353
- {
354
- "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/saltRequired",
355
- "message": "{\"saltRequired\":@bind=data.saltRequired;}",
356
- "description": "Send the calculated salt requirement."
357
- },
358
- {
359
- "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/saltTarget",
360
- "message": "{\"saltTarget\":@bind=data.saltTarget;}",
361
- "description": "Send the target salt level."
362
- },
363
- {
364
- "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/type",
365
- "message": "{\"type\":@bind=data.type;}",
366
- "description": "Send type."
367
- },
368
- {
369
- "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/model",
370
- "message": "{\"type\":@bind=data.model;}",
371
- "description": "Send Model."
372
- },
373
- {
374
- "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/targetOutput",
375
- "message": "{\"targetOutput\":@bind=data.targetOutput;}",
376
- "description": "Send targetOutput."
377
- }
378
- ]
379
- },
380
- {
381
- "name": "lightGroup",
382
- "description": "Populate the lightGroup topic",
383
- "topics": [
384
- {
385
- "topic": "state/lightgroups/@bind=data.id;/@bind=data.name;",
386
- "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';}",
387
- "description": "Bind 'on'/'off' as a message to the state topic."
388
- },
389
- {
390
- "topic": "state/lightgroups/@bind=data.id;/@bind=data.name;/action",
391
- "message": "{\"action\":@bind=data.action;}"
392
- },
393
- {
394
- "topic": "state/lightgroups/@bind=data.id;/@bind=data.name;/lightingTheme",
395
- "message": "{\"lightingTheme\":@bind=data.lightingTheme;}"
396
- },
397
- {
398
- "topic": "state/lightgroups/@bind=data.id;/@bind=data.name;/type",
399
- "message": "{\"type\":@bind=data.type;}"
400
- },
401
- {
402
- "topic": "state/lightgroups/@bind=data.id;/@bind=data.name;/endTime",
403
- "message": "{\"endTime\":@bind=data.endTime;}"
404
- }
405
- ]
406
- },
407
- {
408
- "name": "pump",
409
- "description": "Populate the pumps topic",
410
- "topics": [
411
- {
412
- "topic": "state/pumps/@bind=data.id;/@bind=data.name;",
413
- "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.flow > 0 || data.rpm > 0?'\"on\"':'\"off\"';}",
414
- "description": "Bind 'on'/'off' as a message to the state topic."
415
- },
416
- {
417
- "topic": "state/pumps/@bind=data.id;/@bind=data.name;/rpm",
418
- "message": "{\"rpm\":@bind=data.rpm;}"
419
- },
420
- {
421
- "topic": "state/pumps/@bind=data.id;/@bind=data.name;/flow",
422
- "message": "{\"flow\":@bind=data.flow;}"
423
- },
424
- {
425
- "topic": "state/pumps/@bind=data.id;/@bind=data.name;/watts",
426
- "message": "{\"watts\":@bind=data.watts;}"
427
- },
428
- {
429
- "topic": "state/pumps/@bind=data.id;/@bind=data.name;/status",
430
- "message": "{\"status\":@bind=data.status;}"
431
- }
432
- ]
433
- },
434
- {
435
- "name": "chemController",
436
- "description": "Populate the chemControllers topic",
437
- "vars": {
438
- "cfg": "@bind=sys.chemControllers.getItemById(data.id).get();"
439
- },
440
- "topics": [
441
- {
442
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/ph/tankLevel",
443
- "message": "@bind=data.ph.tank.level;",
444
- "enabled": true
445
- },
446
- {
447
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/ph/setpoint",
448
- "message": "@bind=data.ph.setpoint;",
449
- "enabled": true
450
- },
451
- {
452
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/ph/level",
453
- "message": "@bind=data.ph.level;",
454
- "enabled": true
455
- },
456
- {
457
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/ph/doseTime",
458
- "message": "@bind=data.ph.doseTime;",
459
- "enabled": true
460
- },
461
- {
462
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/ph/doseVolume",
463
- "message": "@bind=data.ph.doseVolume;",
464
- "enabled": true
465
- },
466
- {
467
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/tankLevel",
468
- "message": "@bind=data.orp.tank.level;",
469
- "enabled": true
470
- },
471
- {
472
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/setpoint",
473
- "message": "@bind=data.orp.setpoint;",
474
- "enabled": true
475
- },
476
- {
477
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/level",
478
- "message": "@bind=data.orp.level;",
479
- "enabled": true
480
- },
481
- {
482
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/demand",
483
- "message": "@bind=data.orp.demand;",
484
- "enabled": true
485
- },
486
- {
487
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/doseTime",
488
- "message": "@bind=data.orp.doseTime;",
489
- "enabled": true
490
- },
491
- {
492
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/doseVolume",
493
- "message": "@bind=data.orp.doseVolume;",
494
- "enabled": true
495
- },
496
- {
497
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/saltLevel",
498
- "message": "@bind=data.orp.saltLevel;",
499
- "enabled": true
500
- },
501
- {
502
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/acidTankLevel",
503
- "message": "{\"acidTankLevel\":@bind=data.ph.tank.level;}"
504
- },
505
- {
506
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orpTankLevel",
507
- "message": "{\"orpTankLevel\":@bind=data.orp.tank.level;}"
508
- },
509
- {
510
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orpDosingTime",
511
- "message": "{\"orpDosingTime\":@bind=data.orp.doseTime;}"
512
- },
513
- {
514
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/pHDosingTime",
515
- "message": "{\"pHDosingTime\":@bind=data.ph.doseTime;}"
516
- },
517
- {
518
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/pHDosingVolume",
519
- "message": "{\"pHDosingVolume\":@bind=data.ph.doseVolume;}"
520
- },
521
- {
522
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orpDosingVolume",
523
- "message": "{\"orpDosingVolume\":@bind=data.orp.doseVolume;}"
524
- },
525
- {
526
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orpSetpoint",
527
- "message": "{\"orpSetpoint\":@bind=data.orp.setpoint;}"
528
- },
529
- {
530
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/pHSetpoint",
531
- "message": "{\"pHSetpoint\":@bind=data.ph.setpoint;}"
532
- },
533
- {
534
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orpLevel",
535
- "message": "{\"orpLevel\":@bind=data.orp.level;}"
536
- },
537
- {
538
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/pHLevel",
539
- "message": "{\"pHLevel\":@bind=data.ph.level;}"
540
- },
541
- {
542
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/saltLevel",
543
- "message": "{\"saltLevel\":@bind=data.orp.probe.saltLevel;}"
544
- },
545
- {
546
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/saturationIndex",
547
- "message": "{\"saturationIndex\":@bind=data.saturationIndex;}"
548
- },
549
- {
550
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/status",
551
- "message": "@bind=data.status;"
552
- },
553
- {
554
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/type",
555
- "message": "@bind=data.type;"
556
- },
557
- {
558
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alkalinity",
559
- "message": "@bind=vars.cfg.alkalinity;"
560
- },
561
- {
562
- "topic": "config/chemControllers/@bind=data.id;/@bind=data.name;/alkalinity",
563
- "message": "{\"alkalinity\":@bind=vars.cfg.alkalinity;}"
564
- },
565
- {
566
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/calciumHardness",
567
- "message": "@bind=vars.cfg.calciumHardness;"
568
- },
569
- {
570
- "topic": "config/chemControllers/@bind=data.id;/@bind=data.name;/calciumHardness",
571
- "message": "@bind=vars.cfg.calciumHardness;"
572
- },
573
- {
574
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/cyanuricAcid",
575
- "message": "@bind=vars.cfg.cyanuricAcid;"
576
- },
577
- {
578
- "topic": "config/chemControllers/@bind=data.id;/@bind=data.name;/cyanuricAcid",
579
- "message": "@bind=vars.cfg.cyanuricAcid;"
580
- },
581
- {
582
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/borates",
583
- "message": "@bind=vars.cfg.borates;"
584
- },
585
- {
586
- "topic": "config/chemControllers/@bind=data.id;/@bind=data.name;/borates",
587
- "message": "@bind=vars.cfg.borates;"
588
- },
589
- {
590
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/acidDemand",
591
- "message": "@bind=data.ph.demand;"
592
- },
593
- {
594
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orpDemand",
595
- "message": "@bind=data.orp.demand;"
596
- },
597
- {
598
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/flow",
599
- "message": "@bind=data.alarms.flow;"
600
- },
601
- {
602
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/ph",
603
- "message": "@bind=data.alarms.pH;"
604
- },
605
- {
606
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/orp",
607
- "message": "@bind=data.alarms.orp;"
608
- },
609
- {
610
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/phTank",
611
- "message": "@bind=data.alarms.pHTank;"
612
- },
613
- {
614
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/orpTank",
615
- "message": "@bind=data.alarms.orpTank;"
616
- },
617
- {
618
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/orpProbeFault",
619
- "message": "@bind=data.alarms.orpProbeFault;"
620
- },
621
- {
622
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/pHProbeFault",
623
- "message": "@bind=data.alarms.pHProbeFault;"
624
- },
625
-
626
- {
627
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/warnings/waterChemistry",
628
- "message": "@bind=data.warnings.waterChemistry;"
629
- },
630
- {
631
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/warnings/pHLockout",
632
- "message": "@bind=data.warnings.pHLockout;"
633
- },
634
- {
635
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/warnings/pHDailyLimitReached",
636
- "message": "@bind=data.warnings.pHDailyLimitReached;"
637
- },
638
- {
639
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/warnings/orpDailyLimitReached",
640
- "message": "@bind=data.warnings.orpDailyLimitReached;"
641
- },
642
- {
643
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/warnings/invalidSetup",
644
- "message": "@bind=data.warnings.invalidSetup;"
645
- },
646
- {
647
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/warnings/chlorinatorCommError",
648
- "message": "@bind=data.warnings.chlorinatorCommError;"
649
- }
650
- ]
651
- },
652
- {
653
- "name": "chemicalDose",
654
- "description": "Event when a chemical is being dosed",
655
- "topics": [
656
- {
657
- "topic": "state/chemControllers/@bind=data.id;/@bind=data.chem;",
658
- "message": "@bind=data;",
659
- "enabled": true
660
- }
661
- ]
662
- },
663
- {
664
- "name": "filter",
665
- "description": "Populate the filter topic",
666
- "topics": [
667
- {
668
- "topic": "state/filters/@bind=data.id;/@bind=data.name;",
669
- "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';}",
670
- "description": "Bind 'on'/'off' as a message to the state topic."
671
- },
672
- {
673
- "topic": "state/filters/@bind=data.id;/@bind=data.name;/pressure",
674
- "message": "{\"pressure\":@bind=data.pressure;}",
675
- "description": "Send current pressure."
676
- },
677
- {
678
- "topic": "state/filters/@bind=data.id;/@bind=data.name;/refPressure",
679
- "message": "{\"refPressure\":@bind=data.refPressure;}",
680
- "description": "Send reference pressure (when circuits are on)."
681
- },
682
- {
683
- "topic": "state/filters/@bind=data.id;/@bind=data.name;/body",
684
- "message": "{\"body\":@bind=data.body.desc;}",
685
- "description": "Send associated body."
686
- },
687
- {
688
- "topic": "state/filters/@bind=data.id;/@bind=data.name;/filterType",
689
- "message": "{\"filterType\":@bind=data.filterType.desc;}",
690
- "description": "Send filter type."
691
- },
692
- {
693
- "topic": "state/filters/@bind=data.id;/@bind=data.name;/pressureUnits",
694
- "message": "{\"pressureUnits\":@bind=data.pressureUnits.desc;}",
695
- "description": "Send pressureUnits."
696
- },
697
- {
698
- "topic": "state/filters/@bind=data.id;/@bind=data.name;/cleanPercentage",
699
- "message": "{\"cleanPercentage\":@bind=data.cleanPercentage;}",
700
- "description": "Send cleanPercentage."
701
- }
702
- ]
703
- },
704
- {
705
- "name": "cover",
706
- "description": "Populate the cover topic",
707
- "topics": [
708
- {
709
- "topic": "state/covers/@bind=data.id;/@bind=data.name;",
710
- "message": "{\"id\":@bind=data.id;,\"isClosed\":@bind=data.isClosed?'\"true\"':'\"false\"';}",
711
- "description": "Bind isClosed as a message to the state topic."
712
- }
713
- ]
714
- },
715
- {
716
- "name": "*",
717
- "description": "DEFAULT: Sends the entire emitted response.",
718
- "body": "@bind=data;",
719
- "enabled": false
720
- }
721
- ]
1
+ {
2
+ "context": {
3
+ "name": "MQTT",
4
+ "options": {
5
+ "formatter": [
6
+ {
7
+ "transform": ".toLowerCase()"
8
+ },
9
+ {
10
+ "regexkey": "\\s",
11
+ "replace": "",
12
+ "description": "Remove whitespace"
13
+ },
14
+ {
15
+ "regexkey": "\\/",
16
+ "replace": "",
17
+ "description": "Remove /"
18
+ },
19
+ {
20
+ "regexkey": "\\+",
21
+ "replace": "",
22
+ "description": "Remove +"
23
+ },
24
+ {
25
+ "regexkey": "\\$",
26
+ "replace": "",
27
+ "description": "Remove $"
28
+ },
29
+ {
30
+ "regexkey": "\\#",
31
+ "replace": "",
32
+ "description": "Remove #"
33
+ }
34
+ ],
35
+ "rootTopic-DIRECTIONS": "You can override the root topic by renaming _rootTopic to rootTopic",
36
+ "_rootTopic": "@bind=(state.equipment.alias).replace(' ','-').replace('/','').toLowerCase();",
37
+ "clientId": "@bind='mqttjs_njsPC_'+Math.random().toString(16).substr(2, 8);",
38
+ "willTopic": "state/status",
39
+ "willPayload": "{\"val\":3,\"name\":\"lost\",\"desc\":\"Connection Lost\",\"percent\":0}"
40
+ }
41
+ },
42
+ "events": [
43
+ {
44
+ "name": "config",
45
+ "description": "Don't flood the MQTT bus.",
46
+ "enabled": false
47
+ },
48
+ {
49
+ "name": "controller",
50
+ "description": "Emit time every minute",
51
+ "enabled": true,
52
+ "topics": [
53
+ {
54
+ "topic": "state/time",
55
+ "message": "@bind=data.time;",
56
+ "filter": "@bind=data.status.percent === 100;"
57
+ },
58
+ {
59
+ "topic": "alias",
60
+ "message": "@bind=data.alias;"
61
+ },
62
+ {
63
+ "topic": "state/status",
64
+ "message": "@bind=data.status;"
65
+ },
66
+ {
67
+ "topic": "state/mode",
68
+ "message": "@bind=data.mode;"
69
+ },
70
+ {
71
+ "topic": "state/startTime",
72
+ "message": "@bind=data.startTime;"
73
+ }
74
+ ]
75
+ },
76
+ {
77
+ "name": "circuit",
78
+ "description": "Populate the circuits topics",
79
+ "topics": [
80
+ {
81
+ "topic": "state/circuits/@bind=data.id;/@bind=data.name;",
82
+ "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';,\"endTime\":\"@bind=data.endTime;\"}",
83
+ "description": "Bind 'on'/'off' as a message to the state topic."
84
+ },
85
+ {
86
+ "topic": "state/circuits/@bind=data.id;/@bind=data.name;/isOn/string",
87
+ "message": "@bind=data.isOn?'on':'off';",
88
+ "description": "Bind 'on'/'off' as a message to the topic.",
89
+ "enabled": false
90
+ },
91
+ {
92
+ "topic": "state/circuits/@bind=data.id;/@bind=data.name;/isOn/boolean",
93
+ "message": "@bind=data.isOn;",
94
+ "description": "SAMPLE: Bind the isOn as a message to the topic.",
95
+ "enabled": false
96
+ },
97
+ {
98
+ "topic": "state/circuits/@bind=data.id;/@bind=data.name;/lightingTheme",
99
+ "message": "{\"lightingTheme\":@bind=data.lightingTheme;}",
100
+ "description": "SAMPLE: Bind the lighting theme to the topic.",
101
+ "filter": "@bind=data.type.isLight === true;"
102
+ },
103
+ {
104
+ "topic": "state/circuits/@bind=data.id;/customTopicFormatter/@bind=data.name;/isOn",
105
+ "message": "@bind=data.isOn;",
106
+ "description": "SAMPLE: Bind the isOn as a message to the topic with a custom replacer, qos and retain setting.",
107
+ "formatter": [
108
+ {
109
+ "transform": ".toLowerCase()"
110
+ },
111
+ {
112
+ "regexkey": "\\s",
113
+ "replace": "__",
114
+ "description": "Remove whitespace and replace with __"
115
+ },
116
+ {
117
+ "regexkey": "\\/",
118
+ "replace": "__",
119
+ "description": "Remove / and replace with __"
120
+ }
121
+ ],
122
+ "options": { "qos": 2 },
123
+ "enabled": false
124
+ },
125
+ {
126
+ "topic": "state/circuits/@bind=data.id;/@bind=data.name;/endTime",
127
+ "message": "{\"id\":@bind=data.id;,\"endTime\":@bind=data.endTime;}",
128
+ "description": "Bind endTime as a message to the state topic."
129
+ },
130
+ {
131
+ "topic": "state/circuits/@bind=data.id;/@bind=data.name;/object",
132
+ "message": "@bind=data;",
133
+ "description": "SAMPLE: Bind a JSON object as a message to the topic.",
134
+ "enabled": false
135
+ }
136
+ ]
137
+ },
138
+ {
139
+ "name": "virtualCircuit",
140
+ "description": "Populate the virtual circuits topics",
141
+ "topics": [
142
+ {
143
+ "topic": "state/virtualcircuits/@bind=data.id;/@bind=data.name;",
144
+ "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';}",
145
+ "description": "Bind 'on'/'off' as a message to the state topic."
146
+ }
147
+ ]
148
+ },
149
+ {
150
+ "name": "valve",
151
+ "description": "Populate the valve topics",
152
+ "topics": [
153
+ {
154
+ "topic": "state/valve/@bind=data.id;/@bind=data.name;",
155
+ "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isDiverted?'\"on\"':'\"off\"';,\"isVirtual\":@bind=data.isVirtual? true: false;,\"pinId\": @bind=data.pinId;}",
156
+ "description": "Bind 'on'/'off' as a message to the valve state topic."
157
+ }
158
+ ]
159
+ },
160
+ {
161
+ "name": "feature",
162
+ "description": "Populate the features topics",
163
+ "topics": [
164
+ {
165
+ "topic": "state/features/@bind=data.id;/@bind=data.name;",
166
+ "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';,\"endTime\":\"@bind=data.endTime;\"}",
167
+ "description": "Bind 'on'/'off' as a message to the state topic."
168
+ },
169
+ {
170
+ "topic": "state/features/@bind=data.id;/@bind=data.name;/endTime",
171
+ "message": "{\"id\":@bind=data.id;,\"endTime\":@bind=data.endTime;}",
172
+ "description": "Bind endTime as a message to the state topic."
173
+ }
174
+ ]
175
+ },
176
+ {
177
+ "name": "temps",
178
+ "description": "Populate the temps topics",
179
+ "topics": [
180
+ {
181
+ "topic": "state/temps/air",
182
+ "message": "{\"temp\":@bind=data.air;}",
183
+ "description": "Send air temp."
184
+ },
185
+ {
186
+ "topic": "state/temps/solar",
187
+ "message": "{\"temp\":@bind=data.solar;}",
188
+ "description": "Send solar temp.",
189
+ "filter": "@bind=typeof data.solar !== 'undefined';"
190
+ },
191
+ {
192
+ "topic": "state/temps/solarSensor2",
193
+ "message": "{\"temp\":@bind=data.solarSensor2;}",
194
+ "description": "Solar temp",
195
+ "filter": "@bind=typeof data.solarSensor2 !== 'undefined';"
196
+ },
197
+ {
198
+ "topic": "state/temps/solarSensor3",
199
+ "message": "{\"temp\":@bind=data.solarSensor3;}",
200
+ "description": "Solar temp",
201
+ "filter": "@bind=typeof data.solarSensor3 !== 'undefined';"
202
+ },
203
+ {
204
+ "topic": "state/temps/solarSensor4",
205
+ "message": "{\"temp\":@bind=data.solarSensor4;}",
206
+ "description": "Solar temp",
207
+ "filter": "@bind=typeof data.solarSensor4 !== 'undefined';"
208
+ },
209
+
210
+ {
211
+ "topic": "state/temps/waterSensor1",
212
+ "message": "{\"temp\":@bind=data.waterSensor1;}",
213
+ "description": "Water temp sensor 1",
214
+ "filter": "@bind=typeof data.waterSensor1 !== 'undefined';"
215
+ },
216
+ {
217
+ "topic": "state/temps/waterSensor2",
218
+ "message": "{\"temp\":@bind=data.waterSensor2;}",
219
+ "description": "Water temp sensor 2",
220
+ "filter": "@bind=typeof data.waterSensor2 !== 'undefined';"
221
+ },
222
+ {
223
+ "topic": "state/temps/waterSensor3",
224
+ "message": "{\"temp\":@bind=data.waterSensor3;}",
225
+ "description": "Water temp sensor 3",
226
+ "filter": "@bind=typeof data.waterSensor3 !== 'undefined';"
227
+ },
228
+ {
229
+ "topic": "state/temps/waterSensor4",
230
+ "message": "{\"temp\":@bind=data.waterSensor4;}",
231
+ "description": "Water temp sensor 4",
232
+ "filter": "@bind=typeof data.waterSensor4 !== 'undefined';"
233
+ },
234
+ {
235
+ "topic": "state/temps/units",
236
+ "message": "{\"units\":@bind=data.units;}"
237
+ }
238
+ ]
239
+ },
240
+ {
241
+ "name": "circuitGroup",
242
+ "description": "Populate the circuitGroup topic",
243
+ "topics": [
244
+ {
245
+ "topic": "state/circuitGroups/@bind=data.id;/@bind=data.name;",
246
+ "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';,\"endTime\":\"@bind=data.endTime;\"}",
247
+ "description": "Bind name to the state topic."
248
+ },
249
+ {
250
+ "topic": "state/circuitGroups/@bind=data.id;/@bind=data.name;/isOn",
251
+ "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';}",
252
+ "description": "Bind the on/off status to the topic.",
253
+ "enabled": false
254
+ },
255
+ {
256
+ "topic": "state/circuitGroups/@bind=data.id;/@bind=data.name;/type",
257
+ "message": "{\"type\":@bind=data.type;}",
258
+ "enabled": false
259
+ },
260
+ {
261
+ "topic": "state/circuitGroups/@bind=data.id;/@bind=data.name;/showInFeatures",
262
+ "message": "{\"showInFeatures\":@bind=data.showInFeatures;}",
263
+ "description": "Indicates wether the item should show in features."
264
+ }
265
+
266
+ ]
267
+ },
268
+ {
269
+ "name": "body",
270
+ "description": "Populate the body topic",
271
+ "topics": [
272
+ {
273
+ "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;",
274
+ "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';}",
275
+ "description": "Bind 'on'/'off' as a message to the state topic."
276
+ },
277
+ {
278
+ "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;/heatMode",
279
+ "message": "{\"heatMode\":@bind=data.heatMode;}",
280
+ "description": "Send heat mode."
281
+ },
282
+ {
283
+ "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;/heatStatus",
284
+ "message": "{\"heatStatus\":@bind=data.heatStatus;}",
285
+ "description": "Send heat status."
286
+ },
287
+ {
288
+ "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;/setPoint",
289
+ "message": "{\"setPoint\":@bind=data.setPoint;}",
290
+ "description": "Send set point."
291
+ },
292
+ {
293
+ "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;/heatSetpoint",
294
+ "message": "{\"heatSetpoint\":@bind=data.setPoint;}",
295
+ "description": "Send heat set point."
296
+ },
297
+ {
298
+ "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;/coolSetpoint",
299
+ "message": "{\"coolSetpoint\":@bind=data.coolSetpoint;}",
300
+ "description": "Send cool set point."
301
+ },
302
+ {
303
+ "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;/temp",
304
+ "message": "{\"temp\":@bind=data.temp;}",
305
+ "description": "Send temp."
306
+ }
307
+ ]
308
+ },
309
+ {
310
+ "name": "chlorinator",
311
+ "description": "Populate the chlorinator topic",
312
+ "topics": [
313
+ {
314
+ "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;",
315
+ "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.currentOutput > 0 ?'\"on\"':'\"off\"';}",
316
+ "description": "Bind 'on'/'off' as a message to the state topic."
317
+ },
318
+ {
319
+ "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/currentOutput",
320
+ "message": "{\"currentOutput\":@bind=data.currentOutput;}",
321
+ "description": "Send current output."
322
+ },
323
+ {
324
+ "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/poolSetpoint",
325
+ "message": "{\"poolSetpoint\":@bind=data.poolSetpoint;}",
326
+ "description": "Send pool setpoint."
327
+ },
328
+ {
329
+ "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/spaSetpoint",
330
+ "message": "{\"spaSetpoint\":@bind=data.spaSetpoint;}",
331
+ "description": "Send set point."
332
+ },
333
+ {
334
+ "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/status",
335
+ "message": "{\"status\":@bind=data.status;}",
336
+ "description": "Send status."
337
+ },
338
+ {
339
+ "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/superChlor",
340
+ "message": "{\"superChlor\":@bind=data.superChlor?'\"on\"':'\"off\"';}",
341
+ "description": "Send superChlor."
342
+ },
343
+ {
344
+ "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/superChlorHours",
345
+ "message": "{\"superChlorHours\":@bind=data.superChlorHours;}",
346
+ "description": "Send superChlorHours."
347
+ },
348
+ {
349
+ "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/saltLevel",
350
+ "message": "{\"saltLevel\":@bind=data.saltLevel;}",
351
+ "description": "Send salt level."
352
+ },
353
+ {
354
+ "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/saltRequired",
355
+ "message": "{\"saltRequired\":@bind=data.saltRequired;}",
356
+ "description": "Send the calculated salt requirement."
357
+ },
358
+ {
359
+ "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/saltTarget",
360
+ "message": "{\"saltTarget\":@bind=data.saltTarget;}",
361
+ "description": "Send the target salt level."
362
+ },
363
+ {
364
+ "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/type",
365
+ "message": "{\"type\":@bind=data.type;}",
366
+ "description": "Send type."
367
+ },
368
+ {
369
+ "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/model",
370
+ "message": "{\"type\":@bind=data.model;}",
371
+ "description": "Send Model."
372
+ },
373
+ {
374
+ "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/targetOutput",
375
+ "message": "{\"targetOutput\":@bind=data.targetOutput;}",
376
+ "description": "Send targetOutput."
377
+ }
378
+ ]
379
+ },
380
+ {
381
+ "name": "lightGroup",
382
+ "description": "Populate the lightGroup topic",
383
+ "topics": [
384
+ {
385
+ "topic": "state/lightgroups/@bind=data.id;/@bind=data.name;",
386
+ "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';}",
387
+ "description": "Bind 'on'/'off' as a message to the state topic."
388
+ },
389
+ {
390
+ "topic": "state/lightgroups/@bind=data.id;/@bind=data.name;/action",
391
+ "message": "{\"action\":@bind=data.action;}"
392
+ },
393
+ {
394
+ "topic": "state/lightgroups/@bind=data.id;/@bind=data.name;/lightingTheme",
395
+ "message": "{\"lightingTheme\":@bind=data.lightingTheme;}"
396
+ },
397
+ {
398
+ "topic": "state/lightgroups/@bind=data.id;/@bind=data.name;/type",
399
+ "message": "{\"type\":@bind=data.type;}"
400
+ },
401
+ {
402
+ "topic": "state/lightgroups/@bind=data.id;/@bind=data.name;/endTime",
403
+ "message": "{\"endTime\":@bind=data.endTime;}"
404
+ }
405
+ ]
406
+ },
407
+ {
408
+ "name": "pump",
409
+ "description": "Populate the pumps topic",
410
+ "topics": [
411
+ {
412
+ "topic": "state/pumps/@bind=data.id;/@bind=data.name;",
413
+ "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.flow > 0 || data.rpm > 0?'\"on\"':'\"off\"';}",
414
+ "description": "Bind 'on'/'off' as a message to the state topic."
415
+ },
416
+ {
417
+ "topic": "state/pumps/@bind=data.id;/@bind=data.name;/rpm",
418
+ "message": "{\"rpm\":@bind=data.rpm;}"
419
+ },
420
+ {
421
+ "topic": "state/pumps/@bind=data.id;/@bind=data.name;/flow",
422
+ "message": "{\"flow\":@bind=data.flow;}"
423
+ },
424
+ {
425
+ "topic": "state/pumps/@bind=data.id;/@bind=data.name;/watts",
426
+ "message": "{\"watts\":@bind=data.watts;}"
427
+ },
428
+ {
429
+ "topic": "state/pumps/@bind=data.id;/@bind=data.name;/status",
430
+ "message": "{\"status\":@bind=data.status;}"
431
+ }
432
+ ]
433
+ },
434
+ {
435
+ "name": "chemController",
436
+ "description": "Populate the chemControllers topic",
437
+ "vars": {
438
+ "cfg": "@bind=sys.chemControllers.getItemById(data.id).get();"
439
+ },
440
+ "topics": [
441
+ {
442
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/ph/tankLevel",
443
+ "message": "@bind=data.ph.tank.level;",
444
+ "enabled": true
445
+ },
446
+ {
447
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/ph/setpoint",
448
+ "message": "@bind=data.ph.setpoint;",
449
+ "enabled": true
450
+ },
451
+ {
452
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/ph/level",
453
+ "message": "@bind=data.ph.level;",
454
+ "enabled": true
455
+ },
456
+ {
457
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/ph/doseTime",
458
+ "message": "@bind=data.ph.doseTime;",
459
+ "enabled": true
460
+ },
461
+ {
462
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/ph/doseVolume",
463
+ "message": "@bind=data.ph.doseVolume;",
464
+ "enabled": true
465
+ },
466
+ {
467
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/tankLevel",
468
+ "message": "@bind=data.orp.tank.level;",
469
+ "enabled": true
470
+ },
471
+ {
472
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/setpoint",
473
+ "message": "@bind=data.orp.setpoint;",
474
+ "enabled": true
475
+ },
476
+ {
477
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/level",
478
+ "message": "@bind=data.orp.level;",
479
+ "enabled": true
480
+ },
481
+ {
482
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/demand",
483
+ "message": "@bind=data.orp.demand;",
484
+ "enabled": true
485
+ },
486
+ {
487
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/doseTime",
488
+ "message": "@bind=data.orp.doseTime;",
489
+ "enabled": true
490
+ },
491
+ {
492
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/doseVolume",
493
+ "message": "@bind=data.orp.doseVolume;",
494
+ "enabled": true
495
+ },
496
+ {
497
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/saltLevel",
498
+ "message": "@bind=data.orp.saltLevel;",
499
+ "enabled": true
500
+ },
501
+ {
502
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/acidTankLevel",
503
+ "message": "{\"acidTankLevel\":@bind=data.ph.tank.level;}"
504
+ },
505
+ {
506
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orpTankLevel",
507
+ "message": "{\"orpTankLevel\":@bind=data.orp.tank.level;}"
508
+ },
509
+ {
510
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orpDosingTime",
511
+ "message": "{\"orpDosingTime\":@bind=data.orp.doseTime;}"
512
+ },
513
+ {
514
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/pHDosingTime",
515
+ "message": "{\"pHDosingTime\":@bind=data.ph.doseTime;}"
516
+ },
517
+ {
518
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/pHDosingVolume",
519
+ "message": "{\"pHDosingVolume\":@bind=data.ph.doseVolume;}"
520
+ },
521
+ {
522
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orpDosingVolume",
523
+ "message": "{\"orpDosingVolume\":@bind=data.orp.doseVolume;}"
524
+ },
525
+ {
526
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orpSetpoint",
527
+ "message": "{\"orpSetpoint\":@bind=data.orp.setpoint;}"
528
+ },
529
+ {
530
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/pHSetpoint",
531
+ "message": "{\"pHSetpoint\":@bind=data.ph.setpoint;}"
532
+ },
533
+ {
534
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orpLevel",
535
+ "message": "{\"orpLevel\":@bind=data.orp.level;}"
536
+ },
537
+ {
538
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/pHLevel",
539
+ "message": "{\"pHLevel\":@bind=data.ph.level;}"
540
+ },
541
+ {
542
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/saltLevel",
543
+ "message": "{\"saltLevel\":@bind=data.orp.probe.saltLevel;}"
544
+ },
545
+ {
546
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/saturationIndex",
547
+ "message": "{\"saturationIndex\":@bind=data.saturationIndex;}"
548
+ },
549
+ {
550
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/status",
551
+ "message": "@bind=data.status;"
552
+ },
553
+ {
554
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/type",
555
+ "message": "@bind=data.type;"
556
+ },
557
+ {
558
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alkalinity",
559
+ "message": "@bind=vars.cfg.alkalinity;"
560
+ },
561
+ {
562
+ "topic": "config/chemControllers/@bind=data.id;/@bind=data.name;/alkalinity",
563
+ "message": "{\"alkalinity\":@bind=vars.cfg.alkalinity;}"
564
+ },
565
+ {
566
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/calciumHardness",
567
+ "message": "@bind=vars.cfg.calciumHardness;"
568
+ },
569
+ {
570
+ "topic": "config/chemControllers/@bind=data.id;/@bind=data.name;/calciumHardness",
571
+ "message": "@bind=vars.cfg.calciumHardness;"
572
+ },
573
+ {
574
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/cyanuricAcid",
575
+ "message": "@bind=vars.cfg.cyanuricAcid;"
576
+ },
577
+ {
578
+ "topic": "config/chemControllers/@bind=data.id;/@bind=data.name;/cyanuricAcid",
579
+ "message": "@bind=vars.cfg.cyanuricAcid;"
580
+ },
581
+ {
582
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/borates",
583
+ "message": "@bind=vars.cfg.borates;"
584
+ },
585
+ {
586
+ "topic": "config/chemControllers/@bind=data.id;/@bind=data.name;/borates",
587
+ "message": "@bind=vars.cfg.borates;"
588
+ },
589
+ {
590
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/acidDemand",
591
+ "message": "@bind=data.ph.demand;"
592
+ },
593
+ {
594
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orpDemand",
595
+ "message": "@bind=data.orp.demand;"
596
+ },
597
+ {
598
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/flow",
599
+ "message": "@bind=data.alarms.flow;"
600
+ },
601
+ {
602
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/ph",
603
+ "message": "@bind=data.alarms.pH;"
604
+ },
605
+ {
606
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/orp",
607
+ "message": "@bind=data.alarms.orp;"
608
+ },
609
+ {
610
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/phTank",
611
+ "message": "@bind=data.alarms.pHTank;"
612
+ },
613
+ {
614
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/orpTank",
615
+ "message": "@bind=data.alarms.orpTank;"
616
+ },
617
+ {
618
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/orpProbeFault",
619
+ "message": "@bind=data.alarms.orpProbeFault;"
620
+ },
621
+ {
622
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/pHProbeFault",
623
+ "message": "@bind=data.alarms.pHProbeFault;"
624
+ },
625
+
626
+ {
627
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/warnings/waterChemistry",
628
+ "message": "@bind=data.warnings.waterChemistry;"
629
+ },
630
+ {
631
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/warnings/pHLockout",
632
+ "message": "@bind=data.warnings.pHLockout;"
633
+ },
634
+ {
635
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/warnings/pHDailyLimitReached",
636
+ "message": "@bind=data.warnings.pHDailyLimitReached;"
637
+ },
638
+ {
639
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/warnings/orpDailyLimitReached",
640
+ "message": "@bind=data.warnings.orpDailyLimitReached;"
641
+ },
642
+ {
643
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/warnings/invalidSetup",
644
+ "message": "@bind=data.warnings.invalidSetup;"
645
+ },
646
+ {
647
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/warnings/chlorinatorCommError",
648
+ "message": "@bind=data.warnings.chlorinatorCommError;"
649
+ }
650
+ ]
651
+ },
652
+ {
653
+ "name": "chemicalDose",
654
+ "description": "Event when a chemical is being dosed",
655
+ "topics": [
656
+ {
657
+ "topic": "state/chemControllers/@bind=data.id;/@bind=data.chem;",
658
+ "message": "@bind=data;",
659
+ "enabled": true
660
+ }
661
+ ]
662
+ },
663
+ {
664
+ "name": "filter",
665
+ "description": "Populate the filter topic",
666
+ "topics": [
667
+ {
668
+ "topic": "state/filters/@bind=data.id;/@bind=data.name;",
669
+ "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';}",
670
+ "description": "Bind 'on'/'off' as a message to the state topic."
671
+ },
672
+ {
673
+ "topic": "state/filters/@bind=data.id;/@bind=data.name;/pressure",
674
+ "message": "{\"pressure\":@bind=data.pressure;}",
675
+ "description": "Send current pressure."
676
+ },
677
+ {
678
+ "topic": "state/filters/@bind=data.id;/@bind=data.name;/refPressure",
679
+ "message": "{\"refPressure\":@bind=data.refPressure;}",
680
+ "description": "Send reference pressure (when circuits are on)."
681
+ },
682
+ {
683
+ "topic": "state/filters/@bind=data.id;/@bind=data.name;/body",
684
+ "message": "{\"body\":@bind=data.body.desc;}",
685
+ "description": "Send associated body."
686
+ },
687
+ {
688
+ "topic": "state/filters/@bind=data.id;/@bind=data.name;/filterType",
689
+ "message": "{\"filterType\":@bind=data.filterType.desc;}",
690
+ "description": "Send filter type."
691
+ },
692
+ {
693
+ "topic": "state/filters/@bind=data.id;/@bind=data.name;/pressureUnits",
694
+ "message": "{\"pressureUnits\":@bind=data.pressureUnits.desc;}",
695
+ "description": "Send pressureUnits."
696
+ },
697
+ {
698
+ "topic": "state/filters/@bind=data.id;/@bind=data.name;/cleanPercentage",
699
+ "message": "{\"cleanPercentage\":@bind=data.cleanPercentage;}",
700
+ "description": "Send cleanPercentage."
701
+ }
702
+ ]
703
+ },
704
+ {
705
+ "name": "cover",
706
+ "description": "Populate the cover topic",
707
+ "topics": [
708
+ {
709
+ "topic": "state/covers/@bind=data.id;/@bind=data.name;",
710
+ "message": "{\"id\":@bind=data.id;,\"isClosed\":@bind=data.isClosed?'\"true\"':'\"false\"';}",
711
+ "description": "Bind isClosed as a message to the state topic."
712
+ }
713
+ ]
714
+ },
715
+ {
716
+ "name": "*",
717
+ "description": "DEFAULT: Sends the entire emitted response.",
718
+ "body": "@bind=data;",
719
+ "enabled": false
720
+ }
721
+ ]
722
722
  }