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
package/README.md CHANGED
@@ -1,309 +1,329 @@
1
- ```diff
2
- - INTELLICENTER USERS: Do not upgrade Intellicenter to 2.006. Rollback to 1.064 to use this application.
3
- ```
4
- # nodejs-poolController - Version 8.3.0
5
-
6
- ## What is nodejs-poolController
7
-
8
- nodejs-poolController is an application to communicate and control your Pentair compatible pool equipment.
9
-
10
- * Want to include a low cost controller for your pool?
11
- * Want a web interface for your system?
12
- * Want to turn your pumps on remotely?
13
- * Want to have your home automation system talk to your pool?
14
- * Want to control your pumps or chlorinator without a pool controller?
15
-
16
- Equipment supported
17
- 1. Controllers: IntelliCenter, Intellitouch, EasyTouch, Nixie (standalone equimpent), Aqualink
18
- 1. Pumps: Intelliflow VS/VSF/VF, older models, relay controlled pumps, Whisperflo
19
- 1. Chlorinators: Intellichlor, Aqua-Rite and OEM brands
20
- 1. Heaters: Gas, solar, heatpump
21
- 1. Intellichem and Relay Equipment Manager (REM) chemical controllers
22
- 1. Intellivalve (coming soon)
23
- 1. Home Automation: SmartThings, Hubitat, ISY, Vera, Siri, Echo
24
- 1. Chemical probes (pH, ORP, flow sensors, EC, etc.)
25
-
26
- ## Latest Changes
27
- See [Changelog](https://github.com/tagyoureit/nodejs-poolController/blob/master/Changelog)
28
-
29
- ## What's new in 8.3.0?
30
-
31
- 1. Configurable RS‑485 transmit pacing via new `controller.txDelays` for finer collision avoidance and throughput tuning.
32
- 2. Startup & config resilience: empty or invalid `config.json` now auto‑recreated from defaults, corrupt originals backed up.
33
- 3. Latitude / longitude environment overrides to eliminate early heliotrope warnings prior to UI configuration.
34
- 4. Version check enhancements: git detection, safer redirects, throttled polling, warning suppression.
35
- 5. Docker improvements: fixed Dockerfile and added docker‑compose example with named volumes & environment variable guidance.
36
- 6. Add workflow to build and publish docker images to GitHub Container registry.
37
- 7. Runtime requirements: elevated minimum Node.js version to 20+, safe dependency and security/patch updates.
38
-
39
- ## What's new in 8.1?
40
-
41
- Support for dual chlorinators with REM chem controllers. It is now possible to have two separate chlorinators controlled in 'dynamic' mode by two separate REM chems. Note: In order for REM chem to control each chlorinator, each needs to be on a dedicated RS-485 port (not shared with an OCP or any other chlorinator).
42
-
43
- ## What's new in 8.0?
44
-
45
- Screenlogic can now be used as a direct connection point. If you feel that integrating an RS-485 adapter is a bit too much, then this is an option for you. The preferred method is still RS-485 as it is more fully featured.
46
-
47
- ## What's new in 7.0?
48
-
49
- The current version includes very tight intergation with [relayEquipmentManager](https://github.com/rstrouse/relayEquipmentManager) which allows for hardware control over your ancillary pool equipment (chemical probes, pumps, tanks, heaters, pumps, etc).
50
-
51
- Starting with this version, all code will immediately be pushed to `master` branch. The version of a `next` branch for feature development will disappear.
52
-
53
-
54
- <a name="module_nodejs-poolController--install"></a>
55
-
56
- Dashpanel Client Screenshot
57
-
58
- <img src="https://tagyoureit.github.io/nodejs-poolController/images/v6/clients/dashPanel.png?raw=true" height="300">
59
-
60
- ## Installation Instructions
61
-
62
- This code requires a physical [RS485](https://github.com/tagyoureit/nodejs-poolController/wiki/RS-485-Adapter-Details) adapter to work.
63
-
64
- This is only the server code. See [clients](#module_nodejs-poolController--clients) below for web or other ways to read/control the pool equipment.
65
-
66
- ### Prerequisites
67
- If you don't know anything about NodeJS, these directions might be helpful.
68
-
69
- 1. Install Nodejs (v20+ required). (https://nodejs.org/en/download/)
70
- 1. Update NPM (https://docs.npmjs.com/getting-started/installing-node).
71
- 1. It is recommended to clone the source code as updates are frequently pushed while releases are infrequent
72
- clone with `git clone https://github.com/tagyoureit/nodejs-poolController.git`
73
- (Alternate - not recommended - Download the latest [code release](https://github.com/tagyoureit/nodejs-poolController/releases)
74
- 1. Change directory into nodejs-poolController.
75
- 1. Run `npm install` in the new folder (where package.json exists). This will automatically install all the dependencies (serial-port, express, sockets.io, etc).
76
- 1. Run the app with `npm start`.
77
- * `npm start` will compile the Typescript code. You should use this every time you download/clone/pull the latest code.
78
- * `npm run start:cached` will run the app without compiling the code which can be much faster.
79
- 1. Install a [webclient](module_nodejs-poolController--clients) for a browser experience and/or a [binding](module_nodejs-poolController--bindings) to have two way control with Home Automation systems.
80
-
81
- For a very thorough walk-through, see [this](https://www.troublefreepool.com/threads/pentair-intellicenter-pool-control-dashboard-instructional-guide.218514/) great thread on Trouble Free Pool. Thanks @MyAZPool.
82
-
83
- #### Upgrade Instructions
84
- Assuming you cloned the repo, the following are easy steps to get the latest version:
85
- 1. Change directory to the njsPC app
86
- 2. **Important**: Ensure you have Node.js v20 or higher installed (`node --version`). If not, upgrade Node.js first.
87
- 3. `git pull`
88
- 4. **Important**: Run `npm i` to update dependencies. This is especially important when upgrading to version 8.3.0+ as it requires Node 20+ and has updated dependencies.
89
- 5. Start application as normal, or if using `npm run start:cached` then run `npm run build` to compile the code.
90
-
91
- ### Docker instructions
92
-
93
- See the [wiki](https://github.com/tagyoureit/nodejs-poolController/wiki/Docker). Thanks @wurmr @andylippitt @emes.
94
-
95
- ### Docker Compose (Controller + Optional dashPanel UI)
96
-
97
- Below is an example `docker-compose.yml` snippet showing this controller (`njspc`) and an OPTIONAL dashPanel UI service (`njspc-dash`). The dashPanel image is published separately; uncomment if you want a built-in web dashboard on port 5150.
98
-
99
- ```yaml
100
- services:
101
- njspc:
102
- image: ghcr.io/sam2kb/njspc
103
- container_name: njspc
104
- restart: unless-stopped
105
- environment:
106
- - TZ=${TZ:-UTC}
107
- - NODE_ENV=production
108
- # Serial vs network connection options
109
- # - POOL_NET_CONNECT=true
110
- # - POOL_NET_HOST=raspberrypi
111
- # - POOL_NET_PORT=9801
112
- # Provide coordinates so sunrise/sunset (heliotrope) works immediately - change as needed
113
- - POOL_LATITUDE=28.5383
114
- - POOL_LONGITUDE=-81.3792
115
- ports:
116
- - "4200:4200"
117
- devices:
118
- - /dev/ttyACM0:/dev/ttyUSB0
119
- # Persistence (create host directories/files first)
120
- volumes:
121
- - ./server-config.json:/app/config.json # Persisted config file on host
122
- - njspc-data:/app/data # State & equipment snapshots
123
- - njspc-backups:/app/backups # Backup archives
124
- - njspc-logs:/app/logs # Logs
125
- - njspc-bindings:/app/web/bindings/custom # Custom bindings
126
- # OPTIONAL: If you get permission errors accessing /dev/tty*, prefer adding the container user to the host dialout/uucp group;
127
- # only as a last resort temporarily uncomment the two lines below to run privileged/root (less secure).
128
- # privileged: true
129
- # user: "0:0"
130
-
131
- njspc-dash:
132
- image: ghcr.io/sam2kb/njspc-dash
133
- container_name: njspc-dash
134
- restart: unless-stopped
135
- depends_on:
136
- - njspc
137
- environment:
138
- - TZ=${TZ:-UTC}
139
- - NODE_ENV=production
140
- - POOL_WEB_SERVICES_IP=njspc # Link to backend service name
141
- ports:
142
- - "5150:5150"
143
- volumes:
144
- - ./dash-config.json:/app/config.json
145
- - njspc-dash-data:/app/data
146
- - njspc-dash-logs:/app/logs
147
- - njspc-dash-uploads:/app/uploads
148
-
149
- volumes:
150
- njspc-data:
151
- njspc-backups:
152
- njspc-logs:
153
- njspc-bindings:
154
- njspc-dash-data:
155
- njspc-dash-logs:
156
- njspc-dash-uploads:
157
- ```
158
-
159
- Quick start:
160
- 1. Save compose file.
161
- 2. (Optional) create an empty config file: `touch dash-config.json`.
162
- 3. `docker compose up -d`
163
- 4. Visit Dash UI at: `http://localhost:5150`.
164
-
165
- Notes:
166
- * Provide either RS-485 device OR enable network (ScreenLogic) connection.
167
- * Coordinates env vars prevent heliotrope warnings before the panel reports location.
168
- * Persistence (controller):
169
- * `./server-config.json:/app/config.json` main runtime config. You can either:
170
- * Seed it with a copy of `defaultConfig.json` (`cp defaultConfig.json server-config.json`), OR
171
- * Start with an empty file and the app will auto-populate it from defaults on first launch. If the file exists but contains invalid JSON it will be backed up to `config.corrupt-<timestamp>.json` and regenerated.
172
- * Remaining state (data, backups, logs, custom bindings) is typically stored in named volumes in the provided compose for cleaner host directories. If you prefer bind mounts instead, replace the named volumes with host paths similar to the example below.
173
- * Data artifacts: `poolConfig.json`, `poolState.json` etc. live under `/app/data` (volume `njspc-data`).
174
- * Backups: `/app/backups` (volume `njspc-backups`).
175
- * Logs: `/app/logs` (volume `njspc-logs`).
176
- * Custom bindings: `/app/web/bindings/custom` (volume `njspc-bindings`).
177
- * To migrate from bind mounts to named volumes, stop the stack, `docker run --rm -v oldPath:/from -v newVolume:/to alpine sh -c 'cp -a /from/. /to/'` for each path, then update compose.
178
-
179
- ### Automate startup of app
180
- See the [wiki](https://github.com/tagyoureit/nodejs-poolController/wiki/Automatically-start-at-boot---PM2-&-Systemd).
181
-
182
- # Clients & Bindings
183
- To do anything with this app, you need a client to connect to it. A client can be a web application or Home Automation system.
184
-
185
- <a name="module_nodejs-poolController--clients"></a>
186
-
187
- ## REM (Relay Equipment Manager)
188
- [Relay Equipment Manager](https://github.com/rstrouse/relayEquipmentManager) is a companion app developed by @rstrouse that integrates standalone hardware control. Controls GPIO, i2c, and SPI devices including:
189
- * Atlas Scientific pH, orp, ec, hum, prs, pmp, rtd
190
- * ADS1x15 a/d converters
191
- * Pressure Tranducers
192
- * Flow sensors
193
- * Temperature sensors (10k, NTC)
194
-
195
- ## Web Clients
196
- 1. [nodejs-poolController-dashPanel](https://github.com/rstrouse/nodejs-poolController-dashPanel). Full compatibility with IntelliCenter, *Touch, REM (RelayEquipmentManager).
197
-
198
-
199
- <a name="module_nodejs-poolController--bindings"></a>
200
-
201
- ## Home Automation Bindings (previously Integrations)
202
-
203
- Available automations:
204
- * [Vera Home Automation Hub](https://github.com/rstrouse/nodejs-poolController-veraPlugin) - A plugin that integrates with nodejs-poolController. [Bindings Directions](https://github.com/tagyoureit/nodejs-poolController/wiki/Bindings-Integrations#vera)
205
- * [Hubitat](https://github.com/bsileo/hubitat_poolcontroller) by @bsileo (prev help from @johnny2678, @donkarnag, @arrmo). [Bindings Directions](https://github.com/tagyoureit/nodejs-poolController/wiki/Bindings-Integrations#smartthingshubitat)
206
- * [Homebridge/Siri/EVE](https://github.com/gadget-monk/homebridge-poolcontroller) by @gadget-monk, adopted from @leftyflip
207
- * InfluxDB - [Bindings Directions](https://github.com/tagyoureit/nodejs-poolController/wiki/Bindings-Integrations#influx)
208
- * [MQTT](https://github.com/crsherman/nodejs-poolController-mqtt) original release by @crsherman, re-write by @kkzonie, testing by @baudfather and others. [Bindings Directions](https://github.com/tagyoureit/nodejs-poolController/wiki/Bindings-Integrations#mqtt)
209
- * [Homeseer](https://github.com/tagyoureit/nodejs-poolController/wiki/Homeseer-Setup-Instructions) - Integration directions by @miamijerry to integrate Homeseer through MQTT
210
-
211
- Outdated:
212
- * [Another SmartThings Controller](https://github.com/dhop90/pentair-pool-controller/blob/master/README.md) by @dhop90
213
- * [ISY](src/integrations/socketISY.js). Original credit to @blueman2, enhancements by @mayermd
214
- * [ISY Polyglot NodeServer](https://github.com/brianmtreese/nodejs-pool-controller-polyglotv2) created by @brianmtreese
215
-
216
- # Support
217
- 1. For discussions, recommendations, designs, and clarifications, we recommend you join the [Github discussions](https://github.com/tagyoureit/nodejs-poolController/discussions.
218
- 1. Check the [wiki](https://github.com/tagyoureit/nodejs-poolController/wiki) for tips, tricks and additional documentation.
219
- 1. For bug reports you can open a [github issue](https://github.com/tagyoureit/nodejs-poolController/issues/new),
220
-
221
-
222
- # Changes
223
- See [Changelog](https://github.com/tagyoureit/nodejs-poolController/blob/master/Changelog)
224
-
225
- <a name="module_nodejs-poolController--config.json"></a>
226
- # Config.json changes
227
-
228
- ## Controller section - changes to the communications for the app
229
- Most of these can be configured directly from the UI in dashPanel.
230
- * `rs485Port` - set to the name of you rs485 controller. See [wiki](https://github.com/tagyoureit/nodejs-poolController/wiki/RS-485-Adapter-Details) for details and testing.
231
- * `portSettings` - should not need to be changed for RS485
232
- * `mockPort` - opens a "fake" port for this app to communicate on. Can be used with [packet captures/replays](https://github.com/tagyoureit/nodejs-poolController/wiki/How-to-capture-all-packets-for-issue-resolution).
233
- * `netConnect` - used to connect via [Socat](https://github.com/tagyoureit/nodejs-poolController/wiki/Socat)
234
- * `netHost` and `netPort` - host and port for Socat connection.
235
- * `inactivityRetry` - # of seconds the app should wait before trying to reopen the port after no communications. If your equipment isn't on all the time or you are running a virtual controller you may want to dramatically increase the timeout so you don't get console warnings.
236
- * `txDelays` - (optional) fine‑grained transmit pacing controls added in 8.1+ to better coexist with busy or bridged (socat / multiple panel / dual chlorinator) RS‑485 buses. These values are all in milliseconds. If the block is omitted, internal defaults are used (see `defaultConfig.json`). All values can be hot‑reloaded from config.
237
- * `idleBeforeTxMs` – Minimum quiet time on the bus (no RX or TX seen) before a new outbound frame may start. Helps avoid collisions just after another device finishes talking. Typical: 40‑80. Set to 0 to disable.
238
- * `interFrameDelayMs` Delay inserted between completed outbound attempts (success, retry scheduling, or queue drain) and evaluation of the next outbound message. Replaces the previous fixed 100ms. Typical: 30‑75. Lower values increase throughput but may raise collision / rewind counts.
239
- * `interByteDelayMs` – Optional per‑byte pacing inside a single frame. Normally 0 (disabled). Set to 1‑2ms only if you observe hardware or USB adapter overruns, or are experimenting with very marginal wiring / long cable runs.
240
-
241
- Example tuning block - more conservative pacing for SunTouch that works way better than defaults:
242
-
243
- ```json
244
- "txDelays": {
245
- "idleBeforeTxMs": 60,
246
- "interFrameDelayMs": 50,
247
- "interByteDelayMs": 1
248
- }
249
- ```
250
-
251
- Tuning guidance:
252
- - Start with the defaults. Only change one value at a time and observe stats (collisions, retries, rewinds) via rs485PortStats.
253
- - If you see frequent outbound retries or receive rewinds, first raise `idleBeforeTxMs` in small steps (e.g. +10ms) before touching `interFrameDelayMs`.
254
- - If overall throughput feels sluggish but collisions are low, you may lower `interFrameDelayMs` gradually.
255
- - Use `interByteDelayMs` only as a last resort; it elongates every frame and reduces total bus capacity.
256
- - Setting any value too high will simply slow configuration bursts (e.g. on startup); setting them too low can cause more retries and ultimately lower effective throughput.
257
-
258
- All three parameters are safe to adjust without restarting; edits to `config.json` are picked up by the existing config watcher.
259
-
260
- ## Web section - controls various aspects of external communications
261
- * `servers` - setting for different servers/services
262
- * `http2` - not used currently
263
- * `http` - primary server used for api connections without secure communications
264
- * `enabled` - self-explanatory
265
- * `ip` - The ip of the network address to listen on. Default of `127.0.0.1` will only listen on the local loopback (localhost) adapter. `0.0.0.0` will listen on all network interfaces. Any other address will listen exclusively on that interface.
266
- * `port` - Port to listen on. Default is `4200`.
267
- * `httpsRedirect` - Redirect http traffic to https
268
- * `authentication` - Enable basic username/password authentication. (Not implemented yet.)
269
- * `authFile` - Location of the encrypted password file. By default, `/users.htpasswd`. If you have `authentication=1` then create the file users.htpasswd in the root of the application. Use a tool such as http://www.htaccesstools.com/htpasswd-generator/ and paste your user(s) into this file. You will now be prompted for authentication.
270
- * `https` - See http options above.
271
- * `sslKeyFile` - Location of key file
272
- * `sslCertFile` - Location of certificate file
273
- * `mdns` - Not currently used.
274
- * `ssdp` - Enable for automatic configuration by the webClient and other platforms.
275
-
276
-
277
- ## Log - Different aspects of logging to the application
278
- * `app` - Application wide settings
279
- * `enabled` - Enable/disable logging for the entire application
280
- * `level` - Different levels of logging from least to most: 'error', 'warn', 'info', 'verbose', 'debug', 'silly'
281
- * `packet` - Configuration for the
282
-
283
-
284
- # Credit
285
-
286
- 1. @Rstrouse for helping make the 6.0 rewrite and Intellicenter possible, continuing to make monumental changes, and driving this project forward in numerous ways. My knowledge of coding in general has benefitted greatly from working with him.
287
- 1. [Jason Young](http://www.sdyoung.com/home/decoding-the-pentair-easytouch-rs-485-protocol) (Read both posts, they are a great baseline for knowledge)
288
- 1. Michael Russe [ceesco](https://github.com/ceesco53/pentair_examples) [CocoonTech](http://cocoontech.com/forums/topic/13548-intelliflow-pump-rs485-protocol/?p=159671) - Registration required for CocoonTech. Jason Young used this material for his understanding in the protocol as well. There is a very detailed .txt file with great information ~~that I won't post unless I get permission~~. Looks like it was publicly posted to [Pastebin](http://pastebin.com/uiAmvNjG).
289
- 1. [Michael Usner](https://github.com/michaelusner/Home-Device-Controller) for taking the work of both of the above and turning it into Javascript code.
290
- 1. [rflemming](https://github.com/rflemming) for being the first to contribute some changes to the code.
291
- 1. Awesome help from @arrmo and @blueman2 on Gitter
292
-
293
- # License
294
-
295
- nodejs-poolController. An application to control pool equipment.
296
- Copyright (C) 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025. Russell Goldin, tagyoureit. russ.goldin@gmail.com
297
-
298
- This program is free software: you can redistribute it and/or modify
299
- it under the terms of the GNU Affero General Public License as
300
- published by the Free Software Foundation, either version 3 of the
301
- License, or (at your option) any later version.
302
-
303
- This program is distributed in the hope that it will be useful,
304
- but WITHOUT ANY WARRANTY; without even the implied warranty of
305
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
306
- GNU Affero General Public License for more details.
307
-
308
- You should have received a copy of the GNU Affero General Public License
309
- along with this program. If not, see <http://www.gnu.org/licenses/>
1
+ # nodejs-poolController - Version 8.4.0
2
+
3
+ ```diff
4
+ + INTELLICENTER USERS: Firmware v3.004+ is supported, but still being refined. If you run into issues, please open a discussion and include a replay capture.
5
+ ```
6
+
7
+ ## What is nodejs-poolController
8
+
9
+ nodejs-poolController is an application to communicate and control your Pentair compatible pool equipment.
10
+
11
+ * Want to include a low cost controller for your pool?
12
+ * Want a web interface for your system?
13
+ * Want to turn your pumps on remotely?
14
+ * Want to have your home automation system talk to your pool?
15
+ * Want to control your pumps or chlorinator without a pool controller?
16
+
17
+ Equipment supported
18
+ 1. Controllers: IntelliCenter, Intellitouch, EasyTouch, Nixie (standalone equimpent), Aqualink
19
+ 1. Pumps: Intelliflow VS/VSF/VF, older models, relay controlled pumps, Whisperflo
20
+ 1. Chlorinators: Intellichlor, Aqua-Rite and OEM brands
21
+ 1. Heaters: Gas, solar, heatpump
22
+ 1. Intellichem and Relay Equipment Manager (REM) chemical controllers
23
+ 1. Intellivalve (coming soon)
24
+ 1. Home Automation: SmartThings, Hubitat, ISY, Vera, Siri, Echo
25
+ 1. Chemical probes (pH, ORP, flow sensors, EC, etc.)
26
+
27
+ ## Latest Changes
28
+ See [Changelog](https://github.com/tagyoureit/nodejs-poolController/blob/master/Changelog)
29
+
30
+ ## What's new in 8.4.0?
31
+
32
+ 1. IntelliCenter v3.004+ support updates (still being refined): registration/config refresh handling, better source-of-truth gating, and improved stability.
33
+ 2. IntelliCenter v3.004+ circuit control: Action 184 support with learned Target IDs for more reliable circuit on/off behavior.
34
+ 3. v3.004+ parsing fixes: Wireless byte offsets, big-endian schedule times, and options/setpoint processing improvements.
35
+ 4. Reduced noise: longer device announce interval and better-scoped logging.
36
+
37
+ ## What's new in 8.3.0?
38
+
39
+ 1. Configurable RS‑485 transmit pacing via new `controller.txDelays` for finer collision avoidance and throughput tuning.
40
+ 2. Startup & config resilience: empty or invalid `config.json` now auto‑recreated from defaults, corrupt originals backed up.
41
+ 3. Latitude / longitude environment overrides to eliminate early heliotrope warnings prior to UI configuration.
42
+ 4. Version check enhancements: git detection, safer redirects, throttled polling, warning suppression.
43
+ 5. Docker improvements: fixed Dockerfile and added docker‑compose example with named volumes & environment variable guidance.
44
+ 6. Add workflow to build and publish docker images to GitHub Container registry.
45
+ 7. Runtime requirements: elevated minimum Node.js version to 20+, safe dependency and security/patch updates.
46
+
47
+ ## What's new in 8.1?
48
+
49
+ Support for dual chlorinators with REM chem controllers. It is now possible to have two separate chlorinators controlled in 'dynamic' mode by two separate REM chems. Note: In order for REM chem to control each chlorinator, each needs to be on a dedicated RS-485 port (not shared with an OCP or any other chlorinator).
50
+
51
+ ## What's new in 8.0?
52
+
53
+ Screenlogic can now be used as a direct connection point. If you feel that integrating an RS-485 adapter is a bit too much, then this is an option for you. The preferred method is still RS-485 as it is more fully featured.
54
+
55
+ ## What's new in 7.0?
56
+
57
+ The current version includes very tight intergation with [relayEquipmentManager](https://github.com/rstrouse/relayEquipmentManager) which allows for hardware control over your ancillary pool equipment (chemical probes, pumps, tanks, heaters, pumps, etc).
58
+
59
+ Starting with this version, all code will immediately be pushed to `master` branch. The version of a `next` branch for feature development will disappear.
60
+
61
+
62
+ <a name="module_nodejs-poolController--install"></a>
63
+
64
+ Dashpanel Client Screenshot
65
+
66
+ <img src="https://tagyoureit.github.io/nodejs-poolController/images/v6/clients/dashPanel.png?raw=true" height="300">
67
+
68
+ ## Installation Instructions
69
+
70
+ This code requires a physical [RS485](https://github.com/tagyoureit/nodejs-poolController/wiki/RS-485-Adapter-Details) adapter to work.
71
+
72
+ This is only the server code. See [clients](#module_nodejs-poolController--clients) below for web or other ways to read/control the pool equipment.
73
+
74
+ ### Prerequisites
75
+ If you don't know anything about NodeJS, these directions might be helpful.
76
+
77
+ 1. Install Nodejs (v20+ required). (https://nodejs.org/en/download/)
78
+ 1. Update NPM (https://docs.npmjs.com/getting-started/installing-node).
79
+ 1. It is recommended to clone the source code as updates are frequently pushed while releases are infrequent
80
+ clone with `git clone https://github.com/tagyoureit/nodejs-poolController.git`
81
+ (Alternate - not recommended - Download the latest [code release](https://github.com/tagyoureit/nodejs-poolController/releases)
82
+ 1. Change directory into nodejs-poolController.
83
+ 1. Run `npm install` in the new folder (where package.json exists). This will automatically install all the dependencies (serial-port, express, sockets.io, etc).
84
+ 1. Run the app with `npm start`.
85
+ * `npm start` will compile the Typescript code. You should use this every time you download/clone/pull the latest code.
86
+ * `npm run start:cached` will run the app without compiling the code which can be much faster.
87
+ 1. Install a [webclient](module_nodejs-poolController--clients) for a browser experience and/or a [binding](module_nodejs-poolController--bindings) to have two way control with Home Automation systems.
88
+
89
+ For a very thorough walk-through, see [this](https://www.troublefreepool.com/threads/pentair-intellicenter-pool-control-dashboard-instructional-guide.218514/) great thread on Trouble Free Pool. Thanks @MyAZPool.
90
+
91
+ #### Upgrade Instructions
92
+ Assuming you cloned the repo, the following are easy steps to get the latest version:
93
+ 1. Change directory to the njsPC app
94
+ 2. **Important**: Ensure you have Node.js v20 or higher installed (`node --version`). If not, upgrade Node.js first.
95
+ 3. `git pull`
96
+ 4. **Important**: Run `npm i` to update dependencies. This is especially important when upgrading to version 8.3.0+ (including 8.4.0+) as it requires Node 20+ and has updated dependencies.
97
+ 5. Start application as normal, or if using `npm run start:cached` then run `npm run build` to compile the code.
98
+
99
+ ### Docker instructions
100
+
101
+ See the [wiki](https://github.com/tagyoureit/nodejs-poolController/wiki/Docker). Thanks @wurmr @andylippitt @emes.
102
+
103
+ #### Image channels (important)
104
+
105
+ The project has multiple image channels. `latest` only means latest within that specific channel.
106
+
107
+ * `ghcr.io/tagyoureit/njspc` - official controller image published from this repository's GitHub Actions (tracks upstream `master`).
108
+ * `msmi/nodejs-poolcontroller` - legacy Docker Hub controller image (can lag upstream).
109
+ * `ghcr.io/rstrouse/njspc-dash` - dashPanel image currently published separately.
110
+
111
+ ### Docker Compose (Controller + Optional dashPanel UI)
112
+
113
+ Below is an example `docker-compose.yml` snippet showing this controller (`njspc`) and an OPTIONAL dashPanel UI service (`njspc-dash`). The dashPanel image is published separately; uncomment if you want a built-in web dashboard on port 5150.
114
+
115
+ ```yaml
116
+ services:
117
+ njspc:
118
+ image: ${NJSPC_IMAGE:-ghcr.io/tagyoureit/njspc}
119
+ container_name: njspc
120
+ restart: unless-stopped
121
+ environment:
122
+ - TZ=${TZ:-UTC}
123
+ - NODE_ENV=production
124
+ # Serial vs network connection options
125
+ # - POOL_NET_CONNECT=true
126
+ # - POOL_NET_HOST=raspberrypi
127
+ # - POOL_NET_PORT=9801
128
+ # Provide coordinates so sunrise/sunset (heliotrope) works immediately - change as needed
129
+ - POOL_LATITUDE=28.5383
130
+ - POOL_LONGITUDE=-81.3792
131
+ ports:
132
+ - "4200:4200"
133
+ devices:
134
+ - /dev/ttyACM0:/dev/ttyUSB0
135
+ # Persistence (create host directories/files first)
136
+ volumes:
137
+ - ./server-config.json:/app/config.json # Persisted config file on host
138
+ - njspc-data:/app/data # State & equipment snapshots
139
+ - njspc-backups:/app/backups # Backup archives
140
+ - njspc-logs:/app/logs # Logs
141
+ - njspc-bindings:/app/web/bindings/custom # Custom bindings
142
+ # OPTIONAL: If you get permission errors accessing /dev/tty*, prefer adding the container user to the host dialout/uucp group;
143
+ # only as a last resort temporarily uncomment the two lines below to run privileged/root (less secure).
144
+ # privileged: true
145
+ # user: "0:0"
146
+
147
+ njspc-dash:
148
+ image: ${NJSPC_DASH_IMAGE:-ghcr.io/rstrouse/njspc-dash}
149
+ container_name: njspc-dash
150
+ restart: unless-stopped
151
+ depends_on:
152
+ - njspc
153
+ environment:
154
+ - TZ=${TZ:-UTC}
155
+ - NODE_ENV=production
156
+ - POOL_WEB_SERVICES_IP=njspc # Link to backend service name
157
+ ports:
158
+ - "5150:5150"
159
+ volumes:
160
+ - ./dash-config.json:/app/config.json
161
+ - njspc-dash-data:/app/data
162
+ - njspc-dash-logs:/app/logs
163
+ - njspc-dash-uploads:/app/uploads
164
+
165
+ volumes:
166
+ njspc-data:
167
+ njspc-backups:
168
+ njspc-logs:
169
+ njspc-bindings:
170
+ njspc-dash-data:
171
+ njspc-dash-logs:
172
+ njspc-dash-uploads:
173
+ ```
174
+
175
+ Quick start:
176
+ 1. Save compose file.
177
+ 2. (Optional) create an empty config file: `touch dash-config.json`.
178
+ 3. `docker compose up -d`
179
+ 4. Visit Dash UI at: `http://localhost:5150`.
180
+
181
+ Notes:
182
+ * Provide either RS-485 device OR enable network (ScreenLogic) connection.
183
+ * `latest` is channel-specific; use image labels to verify exact code revision:
184
+ * `docker image inspect ghcr.io/tagyoureit/njspc:latest --format '{{ index .Config.Labels "org.opencontainers.image.revision" }}'`
185
+ * `docker image inspect msmi/nodejs-poolcontroller:latest --format '{{ index .Config.Labels "git-commit" }}'`
186
+ * Coordinates env vars prevent heliotrope warnings before the panel reports location.
187
+ * Persistence (controller):
188
+ * `./server-config.json:/app/config.json` main runtime config. You can either:
189
+ * Seed it with a copy of `defaultConfig.json` (`cp defaultConfig.json server-config.json`), OR
190
+ * Start with an empty file and the app will auto-populate it from defaults on first launch. If the file exists but contains invalid JSON it will be backed up to `config.corrupt-<timestamp>.json` and regenerated.
191
+ * Remaining state (data, backups, logs, custom bindings) is typically stored in named volumes in the provided compose for cleaner host directories. If you prefer bind mounts instead, replace the named volumes with host paths similar to the example below.
192
+ * Data artifacts: `poolConfig.json`, `poolState.json` etc. live under `/app/data` (volume `njspc-data`).
193
+ * Backups: `/app/backups` (volume `njspc-backups`).
194
+ * Logs: `/app/logs` (volume `njspc-logs`).
195
+ * Custom bindings: `/app/web/bindings/custom` (volume `njspc-bindings`).
196
+ * To migrate from bind mounts to named volumes, stop the stack, `docker run --rm -v oldPath:/from -v newVolume:/to alpine sh -c 'cp -a /from/. /to/'` for each path, then update compose.
197
+
198
+ ### Automate startup of app
199
+ See the [wiki](https://github.com/tagyoureit/nodejs-poolController/wiki/Automatically-start-at-boot---PM2-&-Systemd).
200
+
201
+ # Clients & Bindings
202
+ To do anything with this app, you need a client to connect to it. A client can be a web application or Home Automation system.
203
+
204
+ <a name="module_nodejs-poolController--clients"></a>
205
+
206
+ ## REM (Relay Equipment Manager)
207
+ [Relay Equipment Manager](https://github.com/rstrouse/relayEquipmentManager) is a companion app developed by @rstrouse that integrates standalone hardware control. Controls GPIO, i2c, and SPI devices including:
208
+ * Atlas Scientific pH, orp, ec, hum, prs, pmp, rtd
209
+ * ADS1x15 a/d converters
210
+ * Pressure Tranducers
211
+ * Flow sensors
212
+ * Temperature sensors (10k, NTC)
213
+
214
+ ## Web Clients
215
+ 1. [nodejs-poolController-dashPanel](https://github.com/rstrouse/nodejs-poolController-dashPanel). Full compatibility with IntelliCenter, *Touch, REM (RelayEquipmentManager).
216
+
217
+
218
+ <a name="module_nodejs-poolController--bindings"></a>
219
+
220
+ ## Home Automation Bindings (previously Integrations)
221
+
222
+ Available automations:
223
+ * [Vera Home Automation Hub](https://github.com/rstrouse/nodejs-poolController-veraPlugin) - A plugin that integrates with nodejs-poolController. [Bindings Directions](https://github.com/tagyoureit/nodejs-poolController/wiki/Bindings-Integrations#vera)
224
+ * [Hubitat](https://github.com/bsileo/hubitat_poolcontroller) by @bsileo (prev help from @johnny2678, @donkarnag, @arrmo). [Bindings Directions](https://github.com/tagyoureit/nodejs-poolController/wiki/Bindings-Integrations#smartthingshubitat)
225
+ * [Homebridge/Siri/EVE](https://github.com/gadget-monk/homebridge-poolcontroller) by @gadget-monk, adopted from @leftyflip
226
+ * InfluxDB - [Bindings Directions](https://github.com/tagyoureit/nodejs-poolController/wiki/Bindings-Integrations#influx)
227
+ * [MQTT](https://github.com/crsherman/nodejs-poolController-mqtt) original release by @crsherman, re-write by @kkzonie, testing by @baudfather and others. [Bindings Directions](https://github.com/tagyoureit/nodejs-poolController/wiki/Bindings-Integrations#mqtt)
228
+ * [Homeseer](https://github.com/tagyoureit/nodejs-poolController/wiki/Homeseer-Setup-Instructions) - Integration directions by @miamijerry to integrate Homeseer through MQTT
229
+
230
+ Outdated:
231
+ * [Another SmartThings Controller](https://github.com/dhop90/pentair-pool-controller/blob/master/README.md) by @dhop90
232
+ * [ISY](src/integrations/socketISY.js). Original credit to @blueman2, enhancements by @mayermd
233
+ * [ISY Polyglot NodeServer](https://github.com/brianmtreese/nodejs-pool-controller-polyglotv2) created by @brianmtreese
234
+
235
+ # Support
236
+ 1. For discussions, recommendations, designs, and clarifications, we recommend you join the [Github discussions](https://github.com/tagyoureit/nodejs-poolController/discussions.
237
+ 1. Check the [wiki](https://github.com/tagyoureit/nodejs-poolController/wiki) for tips, tricks and additional documentation.
238
+ 1. For bug reports you can open a [github issue](https://github.com/tagyoureit/nodejs-poolController/issues/new),
239
+
240
+
241
+ # Changes
242
+ See [Changelog](https://github.com/tagyoureit/nodejs-poolController/blob/master/Changelog)
243
+
244
+ <a name="module_nodejs-poolController--config.json"></a>
245
+ # Config.json changes
246
+
247
+ ## Controller section - changes to the communications for the app
248
+ Most of these can be configured directly from the UI in dashPanel.
249
+ * `rs485Port` - set to the name of you rs485 controller. See [wiki](https://github.com/tagyoureit/nodejs-poolController/wiki/RS-485-Adapter-Details) for details and testing.
250
+ * `portSettings` - should not need to be changed for RS485
251
+ * `mockPort` - opens a "fake" port for this app to communicate on. Can be used with [packet captures/replays](https://github.com/tagyoureit/nodejs-poolController/wiki/How-to-capture-all-packets-for-issue-resolution).
252
+ * `netConnect` - used to connect via [Socat](https://github.com/tagyoureit/nodejs-poolController/wiki/Socat)
253
+ * `netHost` and `netPort` - host and port for Socat connection.
254
+ * `inactivityRetry` - # of seconds the app should wait before trying to reopen the port after no communications. If your equipment isn't on all the time or you are running a virtual controller you may want to dramatically increase the timeout so you don't get console warnings.
255
+ * `txDelays` - (optional) fine‑grained transmit pacing controls added in 8.1+ to better coexist with busy or bridged (socat / multiple panel / dual chlorinator) RS‑485 buses. These values are all in milliseconds. If the block is omitted, internal defaults are used (see `defaultConfig.json`). All values can be hot‑reloaded from config.
256
+ * `idleBeforeTxMs` Minimum quiet time on the bus (no RX or TX seen) before a new outbound frame may start. Helps avoid collisions just after another device finishes talking. Typical: 40‑80. Set to 0 to disable.
257
+ * `interFrameDelayMs` – Delay inserted between completed outbound attempts (success, retry scheduling, or queue drain) and evaluation of the next outbound message. Replaces the previous fixed 100ms. Typical: 30‑75. Lower values increase throughput but may raise collision / rewind counts.
258
+ * `interByteDelayMs` Optional per‑byte pacing inside a single frame. Normally 0 (disabled). Set to 1‑2ms only if you observe hardware or USB adapter overruns, or are experimenting with very marginal wiring / long cable runs.
259
+
260
+ Example tuning block - more conservative pacing for SunTouch that works way better than defaults:
261
+
262
+ ```json
263
+ "txDelays": {
264
+ "idleBeforeTxMs": 60,
265
+ "interFrameDelayMs": 50,
266
+ "interByteDelayMs": 1
267
+ }
268
+ ```
269
+
270
+ Tuning guidance:
271
+ - Start with the defaults. Only change one value at a time and observe stats (collisions, retries, rewinds) via rs485PortStats.
272
+ - If you see frequent outbound retries or receive rewinds, first raise `idleBeforeTxMs` in small steps (e.g. +10ms) before touching `interFrameDelayMs`.
273
+ - If overall throughput feels sluggish but collisions are low, you may lower `interFrameDelayMs` gradually.
274
+ - Use `interByteDelayMs` only as a last resort; it elongates every frame and reduces total bus capacity.
275
+ - Setting any value too high will simply slow configuration bursts (e.g. on startup); setting them too low can cause more retries and ultimately lower effective throughput.
276
+
277
+ All three parameters are safe to adjust without restarting; edits to `config.json` are picked up by the existing config watcher.
278
+
279
+ ## Web section - controls various aspects of external communications
280
+ * `servers` - setting for different servers/services
281
+ * `http2` - not used currently
282
+ * `http` - primary server used for api connections without secure communications
283
+ * `enabled` - self-explanatory
284
+ * `ip` - The ip of the network address to listen on. Default of `127.0.0.1` will only listen on the local loopback (localhost) adapter. `0.0.0.0` will listen on all network interfaces. Any other address will listen exclusively on that interface.
285
+ * `port` - Port to listen on. Default is `4200`.
286
+ * `httpsRedirect` - Redirect http traffic to https
287
+ * `authentication` - Enable basic username/password authentication. (Not implemented yet.)
288
+ * `authFile` - Location of the encrypted password file. By default, `/users.htpasswd`. If you have `authentication=1` then create the file users.htpasswd in the root of the application. Use a tool such as http://www.htaccesstools.com/htpasswd-generator/ and paste your user(s) into this file. You will now be prompted for authentication.
289
+ * `https` - See http options above.
290
+ * `sslKeyFile` - Location of key file
291
+ * `sslCertFile` - Location of certificate file
292
+ * `mdns` - Not currently used.
293
+ * `ssdp` - Enable for automatic configuration by the webClient and other platforms.
294
+
295
+
296
+ ## Log - Different aspects of logging to the application
297
+ * `app` - Application wide settings
298
+ * `enabled` - Enable/disable logging for the entire application
299
+ * `level` - Different levels of logging from least to most: 'error', 'warn', 'info', 'verbose', 'debug', 'silly'
300
+ * `packet` - Configuration for the
301
+
302
+
303
+ # Credit
304
+
305
+ 1. @Rstrouse for helping make the 6.0 rewrite and Intellicenter possible, continuing to make monumental changes, and driving this project forward in numerous ways. My knowledge of coding in general has benefitted greatly from working with him.
306
+ 1. @jwtaylor310 for providing a ton of IntelliCenter v3.004+ replay captures that helped track down and fix bugs.
307
+ 1. [Jason Young](http://www.sdyoung.com/home/decoding-the-pentair-easytouch-rs-485-protocol) (Read both posts, they are a great baseline for knowledge)
308
+ 1. Michael Russe [ceesco](https://github.com/ceesco53/pentair_examples) [CocoonTech](http://cocoontech.com/forums/topic/13548-intelliflow-pump-rs485-protocol/?p=159671) - Registration required for CocoonTech. Jason Young used this material for his understanding in the protocol as well. There is a very detailed .txt file with great information ~~that I won't post unless I get permission~~. Looks like it was publicly posted to [Pastebin](http://pastebin.com/uiAmvNjG).
309
+ 1. [Michael Usner](https://github.com/michaelusner/Home-Device-Controller) for taking the work of both of the above and turning it into Javascript code.
310
+ 1. [rflemming](https://github.com/rflemming) for being the first to contribute some changes to the code.
311
+ 1. Awesome help from @arrmo and @blueman2 on Gitter
312
+
313
+ # License
314
+
315
+ nodejs-poolController. An application to control pool equipment.
316
+ Copyright (C) 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025. Russell Goldin, tagyoureit. russ.goldin@gmail.com
317
+
318
+ This program is free software: you can redistribute it and/or modify
319
+ it under the terms of the GNU Affero General Public License as
320
+ published by the Free Software Foundation, either version 3 of the
321
+ License, or (at your option) any later version.
322
+
323
+ This program is distributed in the hope that it will be useful,
324
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
325
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
326
+ GNU Affero General Public License for more details.
327
+
328
+ You should have received a copy of the GNU Affero General Public License
329
+ along with this program. If not, see <http://www.gnu.org/licenses/>