nodejs-poolcontroller 8.3.0 → 8.4.1

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