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/.eslintrc.json CHANGED
@@ -1,36 +1,36 @@
1
- {
2
- "env": {
3
- "es2021": true,
4
- "node": true
5
- },
6
- "extends": [
7
- "eslint:recommended",
8
- "plugin:@typescript-eslint/recommended"
9
- ],
10
- "parser": "@typescript-eslint/parser",
11
- "parserOptions": {
12
- "ecmaVersion": "latest",
13
- "sourceType": "module"
14
- },
15
- "plugins": [
16
- "@typescript-eslint"
17
- ],
18
- "rules": {
19
- "indent": [
20
- "error",
21
- "tab"
22
- ],
23
- "linebreak-style": [
24
- "error",
25
- "windows"
26
- ],
27
- "quotes": [
28
- "error",
29
- "single"
30
- ],
31
- "semi": [
32
- "error",
33
- "always"
34
- ]
35
- }
36
- }
1
+ {
2
+ "env": {
3
+ "es2021": true,
4
+ "node": true
5
+ },
6
+ "extends": [
7
+ "eslint:recommended",
8
+ "plugin:@typescript-eslint/recommended"
9
+ ],
10
+ "parser": "@typescript-eslint/parser",
11
+ "parserOptions": {
12
+ "ecmaVersion": "latest",
13
+ "sourceType": "module"
14
+ },
15
+ "plugins": [
16
+ "@typescript-eslint"
17
+ ],
18
+ "rules": {
19
+ "indent": [
20
+ "error",
21
+ "tab"
22
+ ],
23
+ "linebreak-style": [
24
+ "error",
25
+ "windows"
26
+ ],
27
+ "quotes": [
28
+ "error",
29
+ "single"
30
+ ],
31
+ "semi": [
32
+ "error",
33
+ "always"
34
+ ]
35
+ }
36
+ }
@@ -1,84 +1,84 @@
1
- name: "\U0001F41B Bug report"
2
- description: Create a report to help us improve
3
- title: '[BUG] '
4
- body:
5
- - type: markdown
6
- attributes:
7
- value: |
8
- Thank you for reporting an issue. Most issues can be more readily resolved by attaching a Packet Capture. Follow the instructions to complete a [packet capture](https://github.com/tagyoureit/nodejs-poolController/wiki/How-to-capture-all-packets-for-issue-resolution) and attach the resulting zip/log files.
9
-
10
- If you require more general support please file an start a discussion on our discussion board https://github.com/tagyoureit/nodejs-poolController/discussions
11
-
12
- Having trouble installing? Be sure to check out the wiki! https://github.com/tagyoureit/nodejs-poolController/wiki
13
-
14
- Please fill in as much of the form below as you're able.
15
- - type: input
16
- attributes:
17
- label: nodejs-poolController Version/commit
18
- description: can be viewed under dashPanel. Hamburger menu => System.
19
- validations:
20
- required: true
21
- - type: input
22
- attributes:
23
- label: nodejs-poolController-dashPanel Version/commit
24
- description: if applicable
25
- - type: input
26
- attributes:
27
- label: relayEquipmentManager Version/commit
28
- description: if applicable
29
- - type: input
30
- attributes:
31
- label: Node Version
32
- description: Output of `node -v`
33
- - type: input
34
- attributes:
35
- label: Platform
36
- description: |
37
- UNIX: output of `uname -a`
38
- Windows: output of `"$([Environment]::OSVersion | ForEach-Object VersionString) $(if ([Environment]::Is64BitOperatingSystem) { "x64" } else { "x86" })"` in PowerShell console
39
- - type: input
40
- attributes:
41
- label: RS485 Adapter
42
- description: Elfin? JBTek?
43
- - type: checkboxes
44
- attributes:
45
- label: Are you using Docker?
46
- options:
47
- - label: Yes.
48
- - type: input
49
- attributes:
50
- label: OCP
51
- description: Outdoor Control Panel. Eg EasyTouch2 8P, Intellicenter i5PS, none.
52
- placeholder: None / Nixie (standalone setup)
53
- - type: input
54
- attributes:
55
- label: Pump(s)
56
- description: Please list all pumps. EG Intelliflo 2 VST, Intelliflo VS
57
- placeholder: Intelliflo VS
58
- - type: input
59
- attributes:
60
- label: Chlorinator(s)
61
- description: Please list all chlorinators. EG Intellichlor IC-40, Aquarite, None
62
- placeholder: None
63
- - type: textarea
64
- attributes:
65
- label: What steps will reproduce the bug?
66
- description: Enter details about your bug, preferably a simple code snippet that can be run using `node` directly without installing third-party dependencies.
67
- validations:
68
- required: true
69
- - type: textarea
70
- attributes:
71
- label: What happens?
72
- description: If possible please provide textual output instead of screenshots.
73
- validations:
74
- required: true
75
- - type: textarea
76
- attributes:
77
- label: What should have happened?
78
- description: If possible please provide textual output instead of screenshots.
79
- validations:
80
- required: true
81
- - type: textarea
82
- attributes:
83
- label: Additional information
84
- description: Tell us anything else you think we should know.
1
+ name: "\U0001F41B Bug report"
2
+ description: Create a report to help us improve
3
+ title: '[BUG] '
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ Thank you for reporting an issue. Most issues can be more readily resolved by attaching a Packet Capture. Follow the instructions to complete a [packet capture](https://github.com/tagyoureit/nodejs-poolController/wiki/How-to-capture-all-packets-for-issue-resolution) and attach the resulting zip/log files.
9
+
10
+ If you require more general support please file an start a discussion on our discussion board https://github.com/tagyoureit/nodejs-poolController/discussions
11
+
12
+ Having trouble installing? Be sure to check out the wiki! https://github.com/tagyoureit/nodejs-poolController/wiki
13
+
14
+ Please fill in as much of the form below as you're able.
15
+ - type: input
16
+ attributes:
17
+ label: nodejs-poolController Version/commit
18
+ description: can be viewed under dashPanel. Hamburger menu => System.
19
+ validations:
20
+ required: true
21
+ - type: input
22
+ attributes:
23
+ label: nodejs-poolController-dashPanel Version/commit
24
+ description: if applicable
25
+ - type: input
26
+ attributes:
27
+ label: relayEquipmentManager Version/commit
28
+ description: if applicable
29
+ - type: input
30
+ attributes:
31
+ label: Node Version
32
+ description: Output of `node -v`
33
+ - type: input
34
+ attributes:
35
+ label: Platform
36
+ description: |
37
+ UNIX: output of `uname -a`
38
+ Windows: output of `"$([Environment]::OSVersion | ForEach-Object VersionString) $(if ([Environment]::Is64BitOperatingSystem) { "x64" } else { "x86" })"` in PowerShell console
39
+ - type: input
40
+ attributes:
41
+ label: RS485 Adapter
42
+ description: Elfin? JBTek?
43
+ - type: checkboxes
44
+ attributes:
45
+ label: Are you using Docker?
46
+ options:
47
+ - label: Yes.
48
+ - type: input
49
+ attributes:
50
+ label: OCP
51
+ description: Outdoor Control Panel. Eg EasyTouch2 8P, Intellicenter i5PS, none.
52
+ placeholder: None / Nixie (standalone setup)
53
+ - type: input
54
+ attributes:
55
+ label: Pump(s)
56
+ description: Please list all pumps. EG Intelliflo 2 VST, Intelliflo VS
57
+ placeholder: Intelliflo VS
58
+ - type: input
59
+ attributes:
60
+ label: Chlorinator(s)
61
+ description: Please list all chlorinators. EG Intellichlor IC-40, Aquarite, None
62
+ placeholder: None
63
+ - type: textarea
64
+ attributes:
65
+ label: What steps will reproduce the bug?
66
+ description: Enter details about your bug, preferably a simple code snippet that can be run using `node` directly without installing third-party dependencies.
67
+ validations:
68
+ required: true
69
+ - type: textarea
70
+ attributes:
71
+ label: What happens?
72
+ description: If possible please provide textual output instead of screenshots.
73
+ validations:
74
+ required: true
75
+ - type: textarea
76
+ attributes:
77
+ label: What should have happened?
78
+ description: If possible please provide textual output instead of screenshots.
79
+ validations:
80
+ required: true
81
+ - type: textarea
82
+ attributes:
83
+ label: Additional information
84
+ description: Tell us anything else you think we should know.
@@ -1,12 +1,12 @@
1
- ---
2
- name: 📚 Documentation
3
- about: Report an issue related to documentation
4
- ---
5
-
6
- ## 📚 Documentation
7
-
8
- (A clear and concise description of how the docs could be better, with links if possible)
9
-
10
- ### Have you read the [Contributing Guidelines on docs](https://github.com/serialport/node-serialport/blob/master/CONTRIBUTING.md#writing-documentation)?
11
-
12
- (Write your answer here.)
1
+ ---
2
+ name: 📚 Documentation
3
+ about: Report an issue related to documentation
4
+ ---
5
+
6
+ ## 📚 Documentation
7
+
8
+ (A clear and concise description of how the docs could be better, with links if possible)
9
+
10
+ ### Have you read the [Contributing Guidelines on docs](https://github.com/serialport/node-serialport/blob/master/CONTRIBUTING.md#writing-documentation)?
11
+
12
+ (Write your answer here.)
@@ -1,28 +1,28 @@
1
- ---
2
- name: 💥 Proposal / Feature
3
- about: Propose a non-trivial change or new feature for SerialPort
4
- ---
5
-
6
- ## 💥 Proposal
7
-
8
- ### What feature you'd like to see
9
-
10
- (A clear and concise description of what the proposal is.)
11
-
12
- ## Motivation
13
-
14
- (Please outline the motivation for the proposal. It's interesting knowing what people are working on and also could help community members make suggestions for work-arounds until the feature is built)
15
-
16
- ## Pitch
17
-
18
- (Please explain why this feature should be implemented and how it would be used.)
19
-
20
- <!--
21
- What happens if you skip this step?
22
-
23
- Someone will read your feature proposal and maybe will be able to help you,
24
- but it’s unlikely that it will get much attention from the team. Eventually,
25
- the issue will likely get closed in favor of issues that have better explanations
26
-
27
- Thanks for helping us help you!
28
- -->
1
+ ---
2
+ name: 💥 Proposal / Feature
3
+ about: Propose a non-trivial change or new feature for SerialPort
4
+ ---
5
+
6
+ ## 💥 Proposal
7
+
8
+ ### What feature you'd like to see
9
+
10
+ (A clear and concise description of what the proposal is.)
11
+
12
+ ## Motivation
13
+
14
+ (Please outline the motivation for the proposal. It's interesting knowing what people are working on and also could help community members make suggestions for work-arounds until the feature is built)
15
+
16
+ ## Pitch
17
+
18
+ (Please explain why this feature should be implemented and how it would be used.)
19
+
20
+ <!--
21
+ What happens if you skip this step?
22
+
23
+ Someone will read your feature proposal and maybe will be able to help you,
24
+ but it’s unlikely that it will get much attention from the team. Eventually,
25
+ the issue will likely get closed in favor of issues that have better explanations
26
+
27
+ Thanks for helping us help you!
28
+ -->
@@ -1,8 +1,8 @@
1
- blank_issues_enabled: false
2
- contact_links:
3
- - name: ⁉️ Need help with nodejs-poolController?
4
- url: https://github.com/tagyoureit/nodejs-poolController/discussions
5
- about: Please start a discussion before opening a bug.
6
- - name: Gitter
7
- url: https://gitter.im/nodejs-poolController/Lobby
8
- about: Legacy Gitter discussion forums
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: ⁉️ Need help with nodejs-poolController?
4
+ url: https://github.com/tagyoureit/nodejs-poolController/discussions
5
+ about: Please start a discussion before opening a bug.
6
+ - name: Gitter
7
+ url: https://gitter.im/nodejs-poolController/Lobby
8
+ about: Legacy Gitter discussion forums
@@ -1,63 +1,63 @@
1
- # Copilot Project Instructions
2
-
3
- Purpose: Help AI agents contribute effectively to nodejs-poolController (njsPC) with minimal ramp-up.
4
-
5
- ## 1. Core Domain & Architecture
6
- - Goal: Bridge Pentair / compatible pool automation equipment (RS-485 / ScreenLogic) to REST, WebSockets, MQTT, InfluxDB, Rules, and REM (Relay Equipment Manager) interfaces.
7
- - Startup sequence (see `app.ts`): config.init -> logger.init -> sys.init -> state.init -> webApp.init -> conn.initAsync (RS485 / network) -> sys.start -> webApp.initAutoBackup -> sl.openAsync (ScreenLogic).
8
- - Major layers:
9
- 1. `config/Config.ts`: Loads/merges `defaultConfig.json` + `config.json`, watches disk, applies env overrides (POOL_*). Always mutate via `config.setSection()` / `config.updateAsync()`.
10
- 2. `controller/`:
11
- - `comms/Comms.ts` (RS485 transport) + `comms/messages/*` (protocol encode/decode) feeding message objects to system/state.
12
- - `Equipment.ts` (`sys`): Aggregates boards, pumps, heaters, bodies, chemistry, schedules.
13
- - `boards/*Board.ts` selected by `BoardFactory.fromControllerType()` (ControllerType enum) to encapsulate model-specific logic.
14
- - `State.ts`: Higher-level computed/state cache (emits events to interfaces & persistence).
15
- 3. `web/Server.ts`: Orchestrates multiple server/interface types (http/https/http2, mdns, ssdp, mqtt, influx, rule, rem). Each concrete server extends a ProtoServer pattern (see file) and exposes `emitToClients` / `emitToChannel`.
16
- 4. `logger/Logger.ts`: Winston wrapper with packet & ScreenLogic capture, optional replay capture mode (`log.app.captureForReplay`).
17
- - Data Flow: Raw bytes -> `Comms` -> `Messages` decode -> equipment/state mutation -> events -> `webApp.emitToChannel()` -> clients (dashPanel, bindings, MQTT, etc.).
18
-
19
- ## 2. Key Conventions & Patterns
20
- - Prefer calling exported singletons (`config`, `logger`, `sys`, `state`, `webApp`, `conn`) — they are initialized once in `app.ts`.
21
- - Extend support for a new controller board: create `controller/boards/NewBoard.ts` implementing expected interface and add to `BoardFactory` switch.
22
- - Adding an external interface: implement a server class similar to existing ones in `web/Server.ts` and register in `initInterfaces()` via `type` value in `web.interfaces` section of config.
23
- - Configuration writes are async & debounced by a semaphore (`_isLoading`). Avoid rapid consecutive writes — batch changes before `setSection`.
24
- - Logging packets: push through `logger.packet(msg)`; only log when `log.packet.enabled` or capture mode active. Don't bypass logger for protocol-level diagnostics.
25
- - Use `utils.uuid()` for persistent IDs stored back into config (`web.servers.*` / `web.interfaces.*`).
26
-
27
- ## 3. Build & Run Workflow
28
- - Scripts (`package.json`): `npm start` = build (tsc) + run `dist/app.js`; `npm run start:cached` skips build (use only after prior successful build); `npm run build` or `watch` for development.
29
- - Always rebuild after pulling if Typescript sources changed (common; master is live development).
30
- - Minimum Node >=16 (see `engines`).
31
- - Typical dev loop: edit TS -> `npm run build` (or `watch` in one terminal) -> `npm run start:cached` in another.
32
-
33
- ## 4. Safe Change Guidelines (Project Specific)
34
- - Never directly edit `config.json` structure assumptions without updating `defaultConfig.json` and migration logic if needed.
35
- - When adding message types: place in proper `controller/comms/messages/{config|status}` folder; ensure decode populates strongly typed object consumed by equipment/state.
36
- - Emitting to clients: prefer channel scoping with `webApp.emitToChannel(channel, evt, payload)` over broad `emitToClients` to reduce noise.
37
- - Shutdown paths must await: see `stopAsync()` ordering in `app.ts`; replicate that order if introducing new long-lived resources.
38
- - Packet capture integration: if adding new traffic sources, feed capture arrays so `logger.stopCaptureForReplayAsync()` includes them in backups.
39
-
40
- ## 5. Extending / Examples
41
- - Add new board: create file, implement constructor(system), override protocol handlers, add case in `BoardFactory`.
42
- - Add new interface type: define class (e.g., `FooInterfaceServer`) patterned after `MqttInterfaceServer`; map `type: 'foo'` in config to new class in `initInterfaces` switch.
43
- - Add env override: update `Config.getEnvVariables()` with POOL_* variable mapping.
44
-
45
- ## 6. Debugging Tips
46
- - Packet issues: enable `log.packet.logToConsole` & set `log.app.level` to `debug` or `silly` in `config.json` (or via capture mode) then rebuild & restart.
47
- - Config reload: editing `config.json` on disk triggers fs watch; logger reinitializes log settings automatically.
48
- - Network discovery problems: inspect `mdns` / `ssdp` sections in `web.servers` config; ensure correct interface binding (`ip` / `0.0.0.0`).
49
-
50
- ## 7. Common Pitfalls
51
- - Forgetting to rebuild after TS edits (leads to running stale `dist`).
52
- - Mutating returned config objects directly after `getSection` (they are deep-cloned; you must re-set via `setSection`).
53
- - Adding interface without persisting UUID: ensure `utils.uuid()` assigned when undefined.
54
- - Logging floods: avoid tight loops writing directly to console; use logger buffering (`packet` flush timer) pattern.
55
-
56
- ## 8. Contribution Checklist (Agent Focused)
57
- 1. Identify layer (comms / equipment / state / interface / config / logging) impacted.
58
- 2. Update or add unit-like logic in correct module; keep cross-layer boundaries (no UI assumptions in lower layers).
59
- 3. Use existing singletons; avoid new global state without need.
60
- 4. Validate build (`npm run build`) before proposing changes.
61
- 5. Provide brief rationale in PR tying change to equipment behavior or integration capability.
62
-
63
- Feedback welcome: clarify any unclear pattern or request examples to extend this guide.
1
+ # Copilot Project Instructions
2
+
3
+ Purpose: Help AI agents contribute effectively to nodejs-poolController (njsPC) with minimal ramp-up.
4
+
5
+ ## 1. Core Domain & Architecture
6
+ - Goal: Bridge Pentair / compatible pool automation equipment (RS-485 / ScreenLogic) to REST, WebSockets, MQTT, InfluxDB, Rules, and REM (Relay Equipment Manager) interfaces.
7
+ - Startup sequence (see `app.ts`): config.init -> logger.init -> sys.init -> state.init -> webApp.init -> conn.initAsync (RS485 / network) -> sys.start -> webApp.initAutoBackup -> sl.openAsync (ScreenLogic).
8
+ - Major layers:
9
+ 1. `config/Config.ts`: Loads/merges `defaultConfig.json` + `config.json`, watches disk, applies env overrides (POOL_*). Always mutate via `config.setSection()` / `config.updateAsync()`.
10
+ 2. `controller/`:
11
+ - `comms/Comms.ts` (RS485 transport) + `comms/messages/*` (protocol encode/decode) feeding message objects to system/state.
12
+ - `Equipment.ts` (`sys`): Aggregates boards, pumps, heaters, bodies, chemistry, schedules.
13
+ - `boards/*Board.ts` selected by `BoardFactory.fromControllerType()` (ControllerType enum) to encapsulate model-specific logic.
14
+ - `State.ts`: Higher-level computed/state cache (emits events to interfaces & persistence).
15
+ 3. `web/Server.ts`: Orchestrates multiple server/interface types (http/https/http2, mdns, ssdp, mqtt, influx, rule, rem). Each concrete server extends a ProtoServer pattern (see file) and exposes `emitToClients` / `emitToChannel`.
16
+ 4. `logger/Logger.ts`: Winston wrapper with packet & ScreenLogic capture, optional replay capture mode (`log.app.captureForReplay`).
17
+ - Data Flow: Raw bytes -> `Comms` -> `Messages` decode -> equipment/state mutation -> events -> `webApp.emitToChannel()` -> clients (dashPanel, bindings, MQTT, etc.).
18
+
19
+ ## 2. Key Conventions & Patterns
20
+ - Prefer calling exported singletons (`config`, `logger`, `sys`, `state`, `webApp`, `conn`) — they are initialized once in `app.ts`.
21
+ - Extend support for a new controller board: create `controller/boards/NewBoard.ts` implementing expected interface and add to `BoardFactory` switch.
22
+ - Adding an external interface: implement a server class similar to existing ones in `web/Server.ts` and register in `initInterfaces()` via `type` value in `web.interfaces` section of config.
23
+ - Configuration writes are async & debounced by a semaphore (`_isLoading`). Avoid rapid consecutive writes — batch changes before `setSection`.
24
+ - Logging packets: push through `logger.packet(msg)`; only log when `log.packet.enabled` or capture mode active. Don't bypass logger for protocol-level diagnostics.
25
+ - Use `utils.uuid()` for persistent IDs stored back into config (`web.servers.*` / `web.interfaces.*`).
26
+
27
+ ## 3. Build & Run Workflow
28
+ - Scripts (`package.json`): `npm start` = build (tsc) + run `dist/app.js`; `npm run start:cached` skips build (use only after prior successful build); `npm run build` or `watch` for development.
29
+ - Always rebuild after pulling if Typescript sources changed (common; master is live development).
30
+ - Minimum Node >=16 (see `engines`).
31
+ - Typical dev loop: edit TS -> `npm run build` (or `watch` in one terminal) -> `npm run start:cached` in another.
32
+
33
+ ## 4. Safe Change Guidelines (Project Specific)
34
+ - Never directly edit `config.json` structure assumptions without updating `defaultConfig.json` and migration logic if needed.
35
+ - When adding message types: place in proper `controller/comms/messages/{config|status}` folder; ensure decode populates strongly typed object consumed by equipment/state.
36
+ - Emitting to clients: prefer channel scoping with `webApp.emitToChannel(channel, evt, payload)` over broad `emitToClients` to reduce noise.
37
+ - Shutdown paths must await: see `stopAsync()` ordering in `app.ts`; replicate that order if introducing new long-lived resources.
38
+ - Packet capture integration: if adding new traffic sources, feed capture arrays so `logger.stopCaptureForReplayAsync()` includes them in backups.
39
+
40
+ ## 5. Extending / Examples
41
+ - Add new board: create file, implement constructor(system), override protocol handlers, add case in `BoardFactory`.
42
+ - Add new interface type: define class (e.g., `FooInterfaceServer`) patterned after `MqttInterfaceServer`; map `type: 'foo'` in config to new class in `initInterfaces` switch.
43
+ - Add env override: update `Config.getEnvVariables()` with POOL_* variable mapping.
44
+
45
+ ## 6. Debugging Tips
46
+ - Packet issues: enable `log.packet.logToConsole` & set `log.app.level` to `debug` or `silly` in `config.json` (or via capture mode) then rebuild & restart.
47
+ - Config reload: editing `config.json` on disk triggers fs watch; logger reinitializes log settings automatically.
48
+ - Network discovery problems: inspect `mdns` / `ssdp` sections in `web.servers` config; ensure correct interface binding (`ip` / `0.0.0.0`).
49
+
50
+ ## 7. Common Pitfalls
51
+ - Forgetting to rebuild after TS edits (leads to running stale `dist`).
52
+ - Mutating returned config objects directly after `getSection` (they are deep-cloned; you must re-set via `setSection`).
53
+ - Adding interface without persisting UUID: ensure `utils.uuid()` assigned when undefined.
54
+ - Logging floods: avoid tight loops writing directly to console; use logger buffering (`packet` flush timer) pattern.
55
+
56
+ ## 8. Contribution Checklist (Agent Focused)
57
+ 1. Identify layer (comms / equipment / state / interface / config / logging) impacted.
58
+ 2. Update or add unit-like logic in correct module; keep cross-layer boundaries (no UI assumptions in lower layers).
59
+ 3. Use existing singletons; avoid new global state without need.
60
+ 4. Validate build (`npm run build`) before proposing changes.
61
+ 5. Provide brief rationale in PR tying change to equipment behavior or integration capability.
62
+
63
+ Feedback welcome: clarify any unclear pattern or request examples to extend this guide.
@@ -1,67 +1,67 @@
1
- name: Publish Docker Image - GHCR
2
-
3
- on:
4
- push:
5
- branches:
6
- - master
7
- tags:
8
- - 'v*.*.*'
9
- workflow_dispatch:
10
-
11
- jobs:
12
- build-and-push:
13
- runs-on: ubuntu-latest
14
- permissions:
15
- contents: read
16
- packages: write
17
- steps:
18
- - name: Checkout
19
- uses: actions/checkout@v4
20
-
21
- - name: Docker meta
22
- id: meta
23
- uses: docker/metadata-action@v5
24
- with:
25
- images: |
26
- ghcr.io/${{ github.repository_owner }}/njspc
27
- tags: |
28
- type=ref,event=branch
29
- type=ref,event=pr
30
- type=semver,pattern={{version}}
31
- type=semver,pattern={{major}}.{{minor}}
32
- type=semver,pattern={{major}}
33
- type=sha
34
- type=raw,value=latest,enable={{is_default_branch}}
35
- labels: |
36
- org.opencontainers.image.source=${{ github.repository }}
37
- org.opencontainers.image.revision=${{ github.sha }}
38
- org.opencontainers.image.title=njspc
39
- org.opencontainers.image.description=Pentair pool controller bridge (GHCR image)
40
-
41
- - name: Set up QEMU
42
- uses: docker/setup-qemu-action@v3
43
-
44
- - name: Set up Docker Buildx
45
- uses: docker/setup-buildx-action@v3
46
-
47
- - name: Login to GHCR
48
- uses: docker/login-action@v3
49
- with:
50
- registry: ghcr.io
51
- username: ${{ github.actor }}
52
- password: ${{ secrets.GITHUB_TOKEN }}
53
-
54
- - name: Build and push
55
- uses: docker/build-push-action@v6
56
- with:
57
- context: .
58
- push: true
59
- platforms: linux/amd64,linux/arm64,linux/arm/v7
60
- tags: ${{ steps.meta.outputs.tags }}
61
- labels: ${{ steps.meta.outputs.labels }}
62
- cache-from: type=gha
63
- cache-to: type=gha,mode=max
64
-
65
- - name: Echo published tags
66
- run: |
67
- echo "Published: ${{ steps.meta.outputs.tags }}"
1
+ name: Publish Docker Image - GHCR
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ tags:
8
+ - 'v*.*.*'
9
+ workflow_dispatch:
10
+
11
+ jobs:
12
+ build-and-push:
13
+ runs-on: ubuntu-latest
14
+ permissions:
15
+ contents: read
16
+ packages: write
17
+ steps:
18
+ - name: Checkout
19
+ uses: actions/checkout@v4
20
+
21
+ - name: Docker meta
22
+ id: meta
23
+ uses: docker/metadata-action@v5
24
+ with:
25
+ images: |
26
+ ghcr.io/${{ github.repository_owner }}/njspc
27
+ tags: |
28
+ type=ref,event=branch
29
+ type=ref,event=pr
30
+ type=semver,pattern={{version}}
31
+ type=semver,pattern={{major}}.{{minor}}
32
+ type=semver,pattern={{major}}
33
+ type=sha
34
+ type=raw,value=latest,enable={{is_default_branch}}
35
+ labels: |
36
+ org.opencontainers.image.source=https://github.com/${{ github.repository }}
37
+ org.opencontainers.image.revision=${{ github.sha }}
38
+ org.opencontainers.image.title=njspc
39
+ org.opencontainers.image.description=Pentair pool controller bridge (GHCR image)
40
+
41
+ - name: Set up QEMU
42
+ uses: docker/setup-qemu-action@v3
43
+
44
+ - name: Set up Docker Buildx
45
+ uses: docker/setup-buildx-action@v3
46
+
47
+ - name: Login to GHCR
48
+ uses: docker/login-action@v3
49
+ with:
50
+ registry: ghcr.io
51
+ username: ${{ github.actor }}
52
+ password: ${{ secrets.GITHUB_TOKEN }}
53
+
54
+ - name: Build and push
55
+ uses: docker/build-push-action@v6
56
+ with:
57
+ context: .
58
+ push: true
59
+ platforms: linux/amd64,linux/arm64,linux/arm/v7
60
+ tags: ${{ steps.meta.outputs.tags }}
61
+ labels: ${{ steps.meta.outputs.labels }}
62
+ cache-from: type=gha
63
+ cache-to: type=gha,mode=max
64
+
65
+ - name: Echo published tags
66
+ run: |
67
+ echo "Published: ${{ steps.meta.outputs.tags }}"