nodejs-poolcontroller 7.3.1 → 7.6.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 (85) hide show
  1. package/.eslintrc.json +44 -44
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +52 -52
  3. package/CONTRIBUTING.md +74 -74
  4. package/Changelog +215 -195
  5. package/Dockerfile +17 -17
  6. package/Gruntfile.js +40 -40
  7. package/LICENSE +661 -661
  8. package/README.md +191 -186
  9. package/app.ts +2 -0
  10. package/config/Config.ts +27 -2
  11. package/config/VersionCheck.ts +33 -14
  12. package/config copy.json +299 -299
  13. package/controller/Constants.ts +88 -0
  14. package/controller/Equipment.ts +2459 -2225
  15. package/controller/Errors.ts +180 -157
  16. package/controller/Lockouts.ts +437 -0
  17. package/controller/State.ts +364 -79
  18. package/controller/boards/BoardFactory.ts +45 -45
  19. package/controller/boards/EasyTouchBoard.ts +2653 -2489
  20. package/controller/boards/IntelliCenterBoard.ts +4230 -3973
  21. package/controller/boards/IntelliComBoard.ts +63 -63
  22. package/controller/boards/IntelliTouchBoard.ts +241 -167
  23. package/controller/boards/NixieBoard.ts +1675 -1105
  24. package/controller/boards/SystemBoard.ts +4697 -3201
  25. package/controller/comms/Comms.ts +222 -10
  26. package/controller/comms/messages/Messages.ts +13 -9
  27. package/controller/comms/messages/config/ChlorinatorMessage.ts +13 -4
  28. package/controller/comms/messages/config/CircuitGroupMessage.ts +6 -0
  29. package/controller/comms/messages/config/CircuitMessage.ts +0 -0
  30. package/controller/comms/messages/config/ConfigMessage.ts +0 -0
  31. package/controller/comms/messages/config/CoverMessage.ts +1 -0
  32. package/controller/comms/messages/config/CustomNameMessage.ts +30 -30
  33. package/controller/comms/messages/config/EquipmentMessage.ts +4 -0
  34. package/controller/comms/messages/config/ExternalMessage.ts +53 -33
  35. package/controller/comms/messages/config/FeatureMessage.ts +8 -1
  36. package/controller/comms/messages/config/GeneralMessage.ts +8 -0
  37. package/controller/comms/messages/config/HeaterMessage.ts +14 -28
  38. package/controller/comms/messages/config/IntellichemMessage.ts +4 -1
  39. package/controller/comms/messages/config/OptionsMessage.ts +38 -2
  40. package/controller/comms/messages/config/PumpMessage.ts +4 -20
  41. package/controller/comms/messages/config/RemoteMessage.ts +4 -0
  42. package/controller/comms/messages/config/ScheduleMessage.ts +347 -331
  43. package/controller/comms/messages/config/SecurityMessage.ts +1 -0
  44. package/controller/comms/messages/config/ValveMessage.ts +13 -3
  45. package/controller/comms/messages/status/ChlorinatorStateMessage.ts +2 -3
  46. package/controller/comms/messages/status/EquipmentStateMessage.ts +79 -25
  47. package/controller/comms/messages/status/HeaterStateMessage.ts +86 -53
  48. package/controller/comms/messages/status/IntelliChemStateMessage.ts +445 -386
  49. package/controller/comms/messages/status/IntelliValveStateMessage.ts +35 -35
  50. package/controller/comms/messages/status/PumpStateMessage.ts +0 -0
  51. package/controller/comms/messages/status/VersionMessage.ts +0 -0
  52. package/controller/nixie/Nixie.ts +162 -160
  53. package/controller/nixie/NixieEquipment.ts +103 -103
  54. package/controller/nixie/bodies/Body.ts +120 -117
  55. package/controller/nixie/bodies/Filter.ts +135 -135
  56. package/controller/nixie/chemistry/ChemController.ts +2498 -2395
  57. package/controller/nixie/chemistry/Chlorinator.ts +314 -313
  58. package/controller/nixie/circuits/Circuit.ts +248 -210
  59. package/controller/nixie/heaters/Heater.ts +649 -441
  60. package/controller/nixie/pumps/Pump.ts +661 -599
  61. package/controller/nixie/schedules/Schedule.ts +257 -256
  62. package/controller/nixie/valves/Valve.ts +170 -170
  63. package/defaultConfig.json +286 -271
  64. package/issue_template.md +51 -51
  65. package/logger/DataLogger.ts +448 -433
  66. package/logger/Logger.ts +0 -0
  67. package/package.json +56 -54
  68. package/tsconfig.json +25 -25
  69. package/web/Server.ts +522 -31
  70. package/web/bindings/influxDB.json +1022 -894
  71. package/web/bindings/mqtt.json +654 -543
  72. package/web/bindings/mqttAlt.json +684 -574
  73. package/web/bindings/rulesManager.json +54 -54
  74. package/web/bindings/smartThings-Hubitat.json +31 -31
  75. package/web/bindings/valveRelays.json +20 -20
  76. package/web/bindings/vera.json +25 -25
  77. package/web/interfaces/baseInterface.ts +136 -136
  78. package/web/interfaces/httpInterface.ts +124 -122
  79. package/web/interfaces/influxInterface.ts +245 -240
  80. package/web/interfaces/mqttInterface.ts +475 -464
  81. package/web/services/config/Config.ts +181 -152
  82. package/web/services/config/ConfigSocket.ts +0 -0
  83. package/web/services/state/State.ts +118 -7
  84. package/web/services/state/StateSocket.ts +18 -1
  85. package/web/services/utilities/Utilities.ts +42 -42
@@ -1,210 +1,248 @@
1
- import { EquipmentNotFoundError, InvalidEquipmentDataError, InvalidEquipmentIdError, ParameterOutOfRangeError } from '../../Errors';
2
- import { utils, Timestamp } from '../../Constants';
3
- import { logger } from '../../../logger/Logger';
4
-
5
- import { NixieEquipment, NixieChildEquipment, NixieEquipmentCollection, INixieControlPanel } from "../NixieEquipment";
6
- import { Circuit, CircuitCollection, sys } from "../../../controller/Equipment";
7
- import { CircuitState, state, ICircuitState, } from "../../State";
8
- import { setTimeout, clearTimeout } from 'timers';
9
- import { NixieControlPanel } from '../Nixie';
10
- import { webApp, InterfaceServerResponse } from "../../../web/Server";
11
-
12
- export class NixieCircuitCollection extends NixieEquipmentCollection<NixieCircuit> {
13
- public pollingInterval: number = 2000;
14
- private _pollTimer: NodeJS.Timeout = null;
15
- public async deleteCircuitAsync(id: number) {
16
- try {
17
- for (let i = this.length - 1; i >= 0; i--) {
18
- let circ = this[i];
19
- if (circ.id === id) {
20
- await circ.closeAsync();
21
- this.splice(i, 1);
22
- }
23
- }
24
- } catch (err) { return Promise.reject(`Nixie Control Panel deleteCircuitAsync ${err.message}`); }
25
- }
26
- public async sendOnOffSequenceAsync(id: number, count: number) {
27
- try {
28
- let c: NixieCircuit = this.find(elem => elem.id === id) as NixieCircuit;
29
- if (typeof c === 'undefined') return Promise.reject(new Error(`NCP: Circuit ${id} could not be found to send sequence ${count}.`));
30
- await c.sendOnOffSequenceAsync(count);
31
-
32
- } catch (err) { return logger.error(`NCP: sendOnOffSequence: ${err.message}`); }
33
- }
34
- public async setCircuitStateAsync(cstate: ICircuitState, val: boolean) {
35
- try {
36
- let c: NixieCircuit = this.find(elem => elem.id === cstate.id) as NixieCircuit;
37
- if (typeof c === 'undefined') return Promise.reject(new Error(`NCP: Circuit ${cstate.id}-${cstate.name} could not be found to set the state to ${val}.`));
38
- await c.setCircuitStateAsync(cstate, val);
39
- }
40
- catch (err) { return logger.error(`NCP: setCircuitStateAsync ${cstate.id}-${cstate.name}: ${err.message}`); }
41
- }
42
- public async setCircuitAsync(circuit: Circuit, data: any) {
43
- // By the time we get here we know that we are in control and this is a REMChem.
44
- try {
45
- let c: NixieCircuit = this.find(elem => elem.id === circuit.id) as NixieCircuit;
46
- if (typeof c === 'undefined') {
47
- circuit.master = 1;
48
- c = new NixieCircuit(this.controlPanel, circuit);
49
- this.push(c);
50
- await c.setCircuitAsync(data);
51
- logger.debug(`NixieController: A circuit was not found for id #${circuit.id} creating circuit`);
52
- }
53
- else {
54
- await c.setCircuitAsync(data);
55
- }
56
- }
57
- catch (err) { logger.error(`setCircuitAsync: ${err.message}`); return Promise.reject(err); }
58
- }
59
- public async initAsync(circuits: CircuitCollection) {
60
- try {
61
- for (let i = 0; i < circuits.length; i++) {
62
- let circuit = circuits.getItemByIndex(i);
63
- if (circuit.master === 1) {
64
- if (typeof this.find(elem => elem.id === circuit.id) === 'undefined') {
65
- logger.info(`Initializing Nixie circuit ${circuit.name}`);
66
- let ncircuit = new NixieCircuit(this.controlPanel, circuit);
67
- this.push(ncircuit);
68
- }
69
- }
70
- }
71
- }
72
- catch (err) { return Promise.reject(logger.error(`NixieController: Circuit initAsync: ${err.message}`)); }
73
- }
74
- public async closeAsync() {
75
- try {
76
- for (let i = this.length - 1; i >= 0; i--) {
77
- try {
78
- await this[i].closeAsync();
79
- this.splice(i, 1);
80
- } catch (err) { logger.error(`Error stopping Nixie Circuit ${err}`); }
81
- }
82
-
83
- } catch (err) { } // Don't bail if we have an errror.
84
- }
85
-
86
- public async initCircuitAsync(circuit: Circuit): Promise<NixieCircuit> {
87
- try {
88
- let c: NixieCircuit = this.find(elem => elem.id === circuit.id) as NixieCircuit;
89
- if (typeof c === 'undefined') {
90
- c = new NixieCircuit(this.controlPanel, circuit);
91
- this.push(c);
92
- }
93
- return c;
94
- } catch (err) { logger.error(`initCircuitAsync: ${err.message}`); return Promise.reject(err); }
95
- }
96
- public async pollCircuitsAsync() {
97
- let self = this;
98
- try {
99
- if (typeof this._pollTimer !== 'undefined' || this._pollTimer) clearTimeout(this._pollTimer);
100
- this._pollTimer = null;
101
- let success = false;
102
-
103
- } catch (err) { logger.error(`Error polling circuits: ${err.message}`); return Promise.reject(err); }
104
- finally { this._pollTimer = setTimeout(async () => await self.pollCircuitsAsync(), this.pollingInterval || 10000); }
105
- }
106
- }
107
- export class NixieCircuit extends NixieEquipment {
108
- public circuit: Circuit;
109
- private _sequencing = false;
110
- private scheduled = false;
111
- private timeOn: Timestamp;
112
- constructor(ncp: INixieControlPanel, circuit: Circuit) {
113
- super(ncp);
114
- this.circuit = circuit;
115
- }
116
- public get id(): number { return typeof this.circuit !== 'undefined' ? this.circuit.id : -1; }
117
- public get eggTimerOff(): Timestamp { return typeof this.timeOn !== 'undefined' && !this.circuit.dontStop ? this.timeOn.clone().addMinutes(this.circuit.eggTimer) : undefined; }
118
- public async setCircuitAsync(data: any) {
119
- try {
120
- let circuit = this.circuit;
121
- }
122
- catch (err) { logger.error(`Nixie setCircuitAsync: ${err.message}`); return Promise.reject(err); }
123
- }
124
- public async sendOnOffSequenceAsync(count: number, timeout?:number): Promise<InterfaceServerResponse> {
125
- try {
126
- this._sequencing = true;
127
- let arr = [];
128
- let t = typeof timeout === 'undefined' ? 100 : timeout;
129
- arr.push({ isOn: false, timeout: t }); // This may not be needed but we always need to start from off.
130
- //[{ isOn: true, timeout: 1000 }, { isOn: false, timeout: 1000 }]
131
- for (let i = 0; i < count; i++) {
132
- arr.push({ isOn: true, timeout: t });
133
- if(i < count - 1) arr.push({ isOn: false, timeout: t });
134
- }
135
- // The documentation for IntelliBrite is incorrect. The sequence below will give us Party mode.
136
- // Party mode:2
137
- // Start: Off
138
- // On
139
- // Off
140
- // On
141
- // According to the docs this is the sequence they lay out.
142
- // Party mode:2
143
- // Start: On
144
- // Off
145
- // On
146
- // Off
147
- // On
148
-
149
- let res = await NixieEquipment.putDeviceService(this.circuit.connectionId, `/state/device/${this.circuit.deviceBinding}`, arr, 60000);
150
- return res;
151
- } catch (err) { logger.error(`Nixie: Error sending circuit sequence ${this.id}: ${count}`); }
152
- finally { this._sequencing = false; }
153
- }
154
- public async setCircuitStateAsync(cstate: ICircuitState, val: boolean, scheduled: boolean = false) : Promise<InterfaceServerResponse> {
155
- try {
156
- if (val !== cstate.isOn) {
157
- logger.info(`NCP: Setting Circuit ${cstate.name} to ${val}`);
158
- if (cstate.isOn && val) {
159
- // We are already on so lets check the egg timer and shut it off if it has expired.
160
- let eggOff = this.eggTimerOff;
161
- if (typeof eggOff !== 'undefined' && eggOff.getTime() <= new Date().getTime()) val = false;
162
- }
163
- // Check to see if we should be on by poking the schedules.
164
- }
165
- if (utils.isNullOrEmpty(this.circuit.connectionId) || utils.isNullOrEmpty(this.circuit.deviceBinding)) {
166
- cstate.isOn = val;
167
- return new InterfaceServerResponse(200, 'Success');
168
- }
169
- if (this._sequencing) return new InterfaceServerResponse(200, 'Success');
170
- let res = await NixieEquipment.putDeviceService(this.circuit.connectionId, `/state/device/${this.circuit.deviceBinding}`, { isOn: val, latch: val ? 10000 : undefined });
171
- if (res.status.code === 200) {
172
- cstate.isOn = val;
173
- // Set this up so we can process our egg timer.
174
- if (!cstate.isOn && val) { this.timeOn = new Timestamp(); }
175
- else if (!val) this.timeOn = undefined;
176
- }
177
- return res;
178
- } catch (err) { logger.error(`Nixie: Error setting circuit state ${cstate.id}-${cstate.name} to ${val}`); }
179
- }
180
- private async checkHardwareStatusAsync(connectionId: string, deviceBinding: string) {
181
- try {
182
- let dev = await NixieEquipment.getDeviceService(connectionId, `/status/device/${deviceBinding}`);
183
- return dev;
184
- } catch (err) { logger.error(`Nixie Circuit checkHardwareStatusAsync: ${err.message}`); return { hasFault: true } }
185
- }
186
- public async validateSetupAsync(circuit: Circuit, cstate: CircuitState) {
187
- try {
188
- if (typeof circuit.connectionId !== 'undefined' && circuit.connectionId !== ''
189
- && typeof circuit.deviceBinding !== 'undefined' && circuit.deviceBinding !== '') {
190
- try {
191
- let stat = await this.checkHardwareStatusAsync(circuit.connectionId, circuit.deviceBinding);
192
- // If we have a status check the return.
193
- cstate.commStatus = stat.hasFault ? 1 : 0;
194
- } catch (err) { cstate.commStatus = 1; }
195
- }
196
- else
197
- cstate.commStatus = 0;
198
- // The validation will be different if the circuit is on or not. So lets get that information.
199
- } catch (err) { logger.error(`Nixie Error checking Circuit Hardware ${this.circuit.name}: ${err.message}`); cstate.commStatus = 1; return Promise.reject(err); }
200
- }
201
- public async closeAsync() {
202
- try {
203
- let cstate = state.circuits.getItemById(this.circuit.id);
204
- await this.setCircuitStateAsync(cstate, false);
205
- cstate.emitEquipmentChange();
206
- }
207
- catch (err) { logger.error(`Nixie Circuit closeAsync: ${err.message}`); return Promise.reject(err); }
208
- }
209
- public logData(filename: string, data: any) { this.controlPanel.logData(filename, data); }
210
- }
1
+ import { EquipmentNotFoundError, InvalidEquipmentDataError, InvalidEquipmentIdError, ParameterOutOfRangeError } from '../../Errors';
2
+ import { utils, Timestamp } from '../../Constants';
3
+ import { logger } from '../../../logger/Logger';
4
+
5
+ import { NixieEquipment, NixieChildEquipment, NixieEquipmentCollection, INixieControlPanel } from "../NixieEquipment";
6
+ import { Circuit, CircuitCollection, sys } from "../../../controller/Equipment";
7
+ import { CircuitState, state, ICircuitState, } from "../../State";
8
+ import { setTimeout, clearTimeout } from 'timers';
9
+ import { NixieControlPanel } from '../Nixie';
10
+ import { webApp, InterfaceServerResponse } from "../../../web/Server";
11
+
12
+ export class NixieCircuitCollection extends NixieEquipmentCollection<NixieCircuit> {
13
+ public pollingInterval: number = 2000;
14
+ private _pollTimer: NodeJS.Timeout = null;
15
+ public async deleteCircuitAsync(id: number) {
16
+ try {
17
+ for (let i = this.length - 1; i >= 0; i--) {
18
+ let circ = this[i];
19
+ if (circ.id === id) {
20
+ await circ.closeAsync();
21
+ this.splice(i, 1);
22
+ }
23
+ }
24
+ } catch (err) { return Promise.reject(`Nixie Control Panel deleteCircuitAsync ${err.message}`); }
25
+ }
26
+ public async sendOnOffSequenceAsync(id: number, count: number | { isOn: boolean, timeout: number }[]) {
27
+ try {
28
+ let c: NixieCircuit = this.find(elem => elem.id === id) as NixieCircuit;
29
+ if (typeof c === 'undefined') return Promise.reject(new Error(`NCP: Circuit ${id} could not be found to send sequence ${count}.`));
30
+ await c.sendOnOffSequenceAsync(count);
31
+
32
+ } catch (err) { return logger.error(`NCP: sendOnOffSequence: ${err.message}`); }
33
+ }
34
+ public async setCircuitStateAsync(cstate: ICircuitState, val: boolean) {
35
+ try {
36
+ let c: NixieCircuit = this.find(elem => elem.id === cstate.id) as NixieCircuit;
37
+ if (typeof c === 'undefined') return Promise.reject(new Error(`NCP: Circuit ${cstate.id}-${cstate.name} could not be found to set the state to ${val}.`));
38
+ await c.setCircuitStateAsync(cstate, val);
39
+ }
40
+ catch (err) { return logger.error(`NCP: setCircuitStateAsync ${cstate.id}-${cstate.name}: ${err.message}`); }
41
+ }
42
+ public async setCircuitAsync(circuit: Circuit, data: any) {
43
+ // By the time we get here we know that we are in control and this is a REMChem.
44
+ try {
45
+ let c: NixieCircuit = this.find(elem => elem.id === circuit.id) as NixieCircuit;
46
+ if (typeof c === 'undefined') {
47
+ circuit.master = 1;
48
+ c = new NixieCircuit(this.controlPanel, circuit);
49
+ this.push(c);
50
+ await c.setCircuitAsync(data);
51
+ logger.debug(`NixieController: A circuit was not found for id #${circuit.id} creating circuit`);
52
+ }
53
+ else {
54
+ await c.setCircuitAsync(data);
55
+ }
56
+ }
57
+ catch (err) { logger.error(`setCircuitAsync: ${err.message}`); return Promise.reject(err); }
58
+ }
59
+ public async checkCircuitEggTimerExpirationAsync(cstate: ICircuitState) {
60
+ try {
61
+ let c: NixieCircuit = this.find(elem => elem.id === cstate.id) as NixieCircuit;
62
+ await c.checkCircuitEggTimerExpirationAsync(cstate);
63
+ } catch (err) { logger.error(`NCP: Error synching circuit states: ${err}`); }
64
+ }
65
+ public async initAsync(circuits: CircuitCollection) {
66
+ try {
67
+ for (let i = 0; i < circuits.length; i++) {
68
+ let circuit = circuits.getItemByIndex(i);
69
+ if (circuit.master === 1) {
70
+ if (typeof this.find(elem => elem.id === circuit.id) === 'undefined') {
71
+ logger.info(`Initializing Nixie circuit ${circuit.name}`);
72
+ let ncircuit = new NixieCircuit(this.controlPanel, circuit);
73
+ this.push(ncircuit);
74
+ }
75
+ }
76
+ }
77
+ }
78
+ catch (err) { return Promise.reject(logger.error(`NixieController: Circuit initAsync: ${err.message}`)); }
79
+ }
80
+ public async closeAsync() {
81
+ try {
82
+ for (let i = this.length - 1; i >= 0; i--) {
83
+ try {
84
+ await this[i].closeAsync();
85
+ this.splice(i, 1);
86
+ } catch (err) { logger.error(`Error stopping Nixie Circuit ${err}`); }
87
+ }
88
+
89
+ } catch (err) { } // Don't bail if we have an errror.
90
+ }
91
+
92
+ public async initCircuitAsync(circuit: Circuit): Promise<NixieCircuit> {
93
+ try {
94
+ let c: NixieCircuit = this.find(elem => elem.id === circuit.id) as NixieCircuit;
95
+ if (typeof c === 'undefined') {
96
+ c = new NixieCircuit(this.controlPanel, circuit);
97
+ this.push(c);
98
+ }
99
+ return c;
100
+ } catch (err) { logger.error(`initCircuitAsync: ${err.message}`); return Promise.reject(err); }
101
+ }
102
+ public async pollCircuitsAsync() {
103
+ let self = this;
104
+ try {
105
+ if (typeof this._pollTimer !== 'undefined' || this._pollTimer) clearTimeout(this._pollTimer);
106
+ this._pollTimer = null;
107
+ let success = false;
108
+
109
+ } catch (err) { logger.error(`Error polling circuits: ${err.message}`); return Promise.reject(err); }
110
+ finally { this._pollTimer = setTimeout(async () => await self.pollCircuitsAsync(), this.pollingInterval || 10000); }
111
+ }
112
+ }
113
+ export class NixieCircuit extends NixieEquipment {
114
+ public circuit: Circuit;
115
+ private _sequencing = false;
116
+ private scheduled = false;
117
+ private timeOn: Timestamp;
118
+ constructor(ncp: INixieControlPanel, circuit: Circuit) {
119
+ super(ncp);
120
+ this.circuit = circuit;
121
+ // Clear out the delays.
122
+ let cstate = state.circuits.getItemById(circuit.id);
123
+ cstate.startDelay = false;
124
+ cstate.stopDelay = false;
125
+ }
126
+ public get id(): number { return typeof this.circuit !== 'undefined' ? this.circuit.id : -1; }
127
+ public get eggTimerOff(): Timestamp { return typeof this.timeOn !== 'undefined' && !this.circuit.dontStop ? this.timeOn.clone().addMinutes(this.circuit.eggTimer) : undefined; }
128
+ public async setCircuitAsync(data: any) {
129
+ try {
130
+ let circuit = this.circuit;
131
+ }
132
+ catch (err) { logger.error(`Nixie setCircuitAsync: ${err.message}`); return Promise.reject(err); }
133
+ }
134
+ public async sendOnOffSequenceAsync(count: number | { isOn: boolean, timeout: number }[], timeout?:number): Promise<InterfaceServerResponse> {
135
+ try {
136
+ this._sequencing = true;
137
+ let arr = [];
138
+ if (typeof count === 'number') {
139
+ let t = typeof timeout === 'undefined' ? 100 : timeout;
140
+ arr.push({ isOn: false, timeout: t }); // This may not be needed but we always need to start from off.
141
+ //[{ isOn: true, timeout: 1000 }, { isOn: false, timeout: 1000 }]
142
+ for (let i = 0; i < count; i++) {
143
+ arr.push({ isOn: true, timeout: t });
144
+ if (i < count - 1) arr.push({ isOn: false, timeout: t });
145
+ }
146
+ }
147
+ else arr = count;
148
+ // The documentation for IntelliBrite is incorrect. The sequence below will give us Party mode.
149
+ // Party mode:2
150
+ // Start: Off
151
+ // On
152
+ // Off
153
+ // On
154
+ // According to the docs this is the sequence they lay out.
155
+ // Party mode:2
156
+ // Start: On
157
+ // Off
158
+ // On
159
+ // Off
160
+ // On
161
+
162
+ let res = await NixieEquipment.putDeviceService(this.circuit.connectionId, `/state/device/${this.circuit.deviceBinding}`, arr, 60000);
163
+ return res;
164
+ } catch (err) { logger.error(`Nixie: Error sending circuit sequence ${this.id}: ${count}`); }
165
+ finally { this._sequencing = false; }
166
+ }
167
+ public async setThemeAsync(cstate: ICircuitState, theme: number): Promise<InterfaceServerResponse> {
168
+ try {
169
+
170
+
171
+
172
+ return new InterfaceServerResponse(200, 'Sucess');
173
+ } catch (err) { logger.error(`Nixie: Error setting light theme ${cstate.id}-${cstate.name} to ${theme}`); }
174
+ }
175
+ public async setCircuitStateAsync(cstate: ICircuitState, val: boolean, scheduled: boolean = false): Promise<InterfaceServerResponse> {
176
+ try {
177
+ if (val !== cstate.isOn) {
178
+ logger.info(`NCP: Setting Circuit ${cstate.name} to ${val}`);
179
+ if (cstate.isOn && val) {
180
+ // We are already on so lets check the egg timer and shut it off if it has expired.
181
+ let eggOff = this.eggTimerOff;
182
+ if (typeof eggOff !== 'undefined' && eggOff.getTime() <= new Date().getTime()) val = false;
183
+ }
184
+ // Check to see if we should be on by poking the schedules.
185
+ }
186
+ if (utils.isNullOrEmpty(this.circuit.connectionId) || utils.isNullOrEmpty(this.circuit.deviceBinding)) {
187
+ sys.board.circuits.setEndTime(sys.circuits.getInterfaceById(cstate.id), cstate, val);
188
+ cstate.isOn = val;
189
+ return new InterfaceServerResponse(200, 'Success');
190
+ }
191
+ if (this._sequencing) return new InterfaceServerResponse(200, 'Success');
192
+ let res = await NixieEquipment.putDeviceService(this.circuit.connectionId, `/state/device/${this.circuit.deviceBinding}`, { isOn: val, latch: val ? 10000 : undefined });
193
+ if (res.status.code === 200) {
194
+ sys.board.circuits.setEndTime(sys.circuits.getInterfaceById(cstate.id), cstate, val);
195
+ // Set this up so we can process our egg timer.
196
+ //if (!cstate.isOn && val) { cstate.startTime = this.timeOn = new Timestamp(); }
197
+ //else if (!val) cstate.startTime = this.timeOn = undefined;
198
+ cstate.isOn = val;
199
+ }
200
+ return res;
201
+ } catch (err) { logger.error(`Nixie: Error setting circuit state ${cstate.id}-${cstate.name} to ${val}`); }
202
+ }
203
+ public async checkCircuitEggTimerExpirationAsync(cstate: ICircuitState) {
204
+ // if circuit end time is past current time, either the schedule is finished
205
+ // (this should already be turned off) or the egg timer has expired
206
+ try {
207
+ if (!cstate.isActive || !cstate.isOn) return;
208
+ if (typeof cstate.endTime !== 'undefined') {
209
+ if (cstate.endTime.toDate() < new Timestamp().toDate()) {
210
+ await sys.board.circuits.setCircuitStateAsync(cstate.id, false);
211
+ cstate.emitEquipmentChange();
212
+ }
213
+ }
214
+ } catch (err) { logger.error(`Error syncing circuit: ${err}`); }
215
+ }
216
+ private async checkHardwareStatusAsync(connectionId: string, deviceBinding: string) {
217
+ try {
218
+ let dev = await NixieEquipment.getDeviceService(connectionId, `/status/device/${deviceBinding}`);
219
+ return dev;
220
+ } catch (err) { logger.error(`Nixie Circuit checkHardwareStatusAsync: ${err.message}`); return { hasFault: true } }
221
+ }
222
+ public async validateSetupAsync(circuit: Circuit, cstate: CircuitState) {
223
+ try {
224
+ if (typeof circuit.connectionId !== 'undefined' && circuit.connectionId !== ''
225
+ && typeof circuit.deviceBinding !== 'undefined' && circuit.deviceBinding !== '') {
226
+ try {
227
+ let stat = await this.checkHardwareStatusAsync(circuit.connectionId, circuit.deviceBinding);
228
+ // If we have a status check the return.
229
+ cstate.commStatus = stat.hasFault ? 1 : 0;
230
+ } catch (err) { cstate.commStatus = 1; }
231
+ }
232
+ else
233
+ cstate.commStatus = 0;
234
+ // The validation will be different if the circuit is on or not. So lets get that information.
235
+ } catch (err) { logger.error(`Nixie Error checking Circuit Hardware ${this.circuit.name}: ${err.message}`); cstate.commStatus = 1; return Promise.reject(err); }
236
+ }
237
+ public async closeAsync() {
238
+ try {
239
+ let cstate = state.circuits.getItemById(this.circuit.id);
240
+ cstate.stopDelay = false;
241
+ cstate.startDelay = false;
242
+ await this.setCircuitStateAsync(cstate, false);
243
+ cstate.emitEquipmentChange();
244
+ }
245
+ catch (err) { logger.error(`Nixie Circuit closeAsync: ${err.message}`); return Promise.reject(err); }
246
+ }
247
+ public logData(filename: string, data: any) { this.controlPanel.logData(filename, data); }
248
+ }