nodejs-poolcontroller 8.0.1 → 8.0.2
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.
- package/.docker/Dockerfile.armv6 +29 -0
- package/.docker/Dockerfile.armv7 +29 -0
- package/.docker/Dockerfile.linux +62 -0
- package/.docker/Dockerfile.windows +43 -0
- package/.docker/docker-compose.yml +47 -0
- package/.docker/ecosystem.config.js +35 -0
- package/.github/workflows/docker-publish-njsPC-linux.yml +81 -0
- package/.github/workflows/docker-publish-njsPC-windows.yml +41 -0
- package/Dockerfile +4 -3
- package/README.md +4 -1
- package/config/Config.ts +1 -1
- package/controller/Constants.ts +164 -67
- package/controller/Equipment.ts +78 -18
- package/controller/Lockouts.ts +15 -0
- package/controller/State.ts +280 -7
- package/controller/boards/EasyTouchBoard.ts +225 -101
- package/controller/boards/IntelliCenterBoard.ts +67 -18
- package/controller/boards/IntelliTouchBoard.ts +2 -4
- package/controller/boards/NixieBoard.ts +84 -27
- package/controller/boards/SunTouchBoard.ts +8 -2
- package/controller/boards/SystemBoard.ts +3259 -3242
- package/controller/comms/ScreenLogic.ts +47 -44
- package/controller/comms/messages/Messages.ts +4 -4
- package/controller/comms/messages/config/ChlorinatorMessage.ts +10 -3
- package/controller/comms/messages/config/ExternalMessage.ts +4 -1
- package/controller/comms/messages/config/PumpMessage.ts +8 -7
- package/controller/comms/messages/config/RemoteMessage.ts +48 -43
- package/controller/comms/messages/status/ChlorinatorStateMessage.ts +8 -2
- package/controller/comms/messages/status/EquipmentStateMessage.ts +9 -4
- package/controller/nixie/NixieEquipment.ts +1 -1
- package/controller/nixie/bodies/Body.ts +1 -1
- package/controller/nixie/chemistry/ChemController.ts +37 -28
- package/controller/nixie/circuits/Circuit.ts +36 -0
- package/controller/nixie/heaters/Heater.ts +24 -5
- package/controller/nixie/pumps/Pump.ts +155 -97
- package/controller/nixie/schedules/Schedule.ts +207 -126
- package/defaultConfig.json +3 -3
- package/logger/DataLogger.ts +7 -7
- package/package.json +2 -2
- package/sendSocket.js +32 -0
- package/web/Server.ts +17 -11
- package/web/bindings/homeassistant.json +2 -2
- package/web/interfaces/mqttInterface.ts +18 -18
- package/web/services/config/Config.ts +34 -1
- package/web/services/state/State.ts +10 -3
- package/web/services/state/StateSocket.ts +7 -3
- package/web/services/utilities/Utilities.ts +3 -3
|
@@ -912,21 +912,21 @@ class Controller {
|
|
|
912
912
|
}
|
|
913
913
|
], */
|
|
914
914
|
}
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
915
|
+
public static decodeHighSpeed(highSpeed: number[]) {
|
|
916
|
+
let maxCircuits = sys.controllerType === ControllerType.IntelliTouch ? 8 : 4;
|
|
917
|
+
let arrCircuits = [];
|
|
918
|
+
let pump = sys.pumps.find(x => { return x.master !== 1 && x.type === 65 });
|
|
919
|
+
for (let i = 0; i < maxCircuits && i < highSpeed.length; i++) {
|
|
920
|
+
let val = highSpeed[i];
|
|
921
|
+
if (val > 0) arrCircuits.push(val);
|
|
922
|
+
else if (typeof pump !== 'undefined') pump.circuits.removeItemById(i);
|
|
923
|
+
}
|
|
924
|
+
if (arrCircuits.length > 0) {
|
|
925
|
+
let pump = sys.pumps.getDualSpeed(true);
|
|
926
|
+
for (let j = 1; j <= arrCircuits.length; j++) pump.circuits.getItemById(j, true).circuit = arrCircuits[j - 1];
|
|
927
|
+
}
|
|
928
|
+
else if (typeof pump !== 'undefined') sys.pumps.removeItemById(pump.id);
|
|
929
|
+
}
|
|
930
930
|
public static decodeRemote(remoteDataArray) {
|
|
931
931
|
if (sys.controllerType === ControllerType.EasyTouch) {
|
|
932
932
|
|
|
@@ -1071,35 +1071,38 @@ class Controller {
|
|
|
1071
1071
|
await sys.board.pumps.setPumpAsync(pData, false);
|
|
1072
1072
|
})
|
|
1073
1073
|
}
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1074
|
+
public static async decodePumpStatusAsync(id: number, slpump: SLPumpStatusData) {
|
|
1075
|
+
/* {
|
|
1076
|
+
pumpCircuits: [
|
|
1077
|
+
{ circuitId: 6,speed: 2000,isRPMs: true, },
|
|
1078
|
+
{ circuitId: 8, speed:2700,isRPMs: true, },
|
|
1079
|
+
{ circuitId: 2,speed: 2710,isRPMs: true, },
|
|
1080
|
+
{ circuitId: 2,speed:1000, isRPMs: true,},
|
|
1081
|
+
{ circuitId: 5,speed:2830, isRPMs: true,},
|
|
1082
|
+
{ circuitId: 0,speed: 30,isRPMs: false,},
|
|
1083
|
+
{ circuitId: 0,speed: 30,isRPMs: false,},
|
|
1084
|
+
{ circuitId: 0,speed: 30,isRPMs: false,},
|
|
1085
|
+
],
|
|
1086
|
+
pumpType: 4,
|
|
1087
|
+
isRunning: false,
|
|
1088
|
+
pumpWatts: 0,
|
|
1089
|
+
pumpRPMs: 0,
|
|
1090
|
+
pumpUnknown1: 0,
|
|
1091
|
+
pumpGPMs: 0,
|
|
1092
|
+
pumpUnknown2: 255,
|
|
1093
|
+
}
|
|
1094
|
+
*/
|
|
1095
|
+
// RKS: 05-07-23 - This process of getting the pump by its id is flawed. We need to pull this information by its address.
|
|
1096
|
+
//let pstate = state.pumps.getItemById(id);
|
|
1097
|
+
let pstate = state.pumps.find(x => x.address === 95 + id);
|
|
1098
|
+
if (typeof pstate !== 'undefined') {
|
|
1099
|
+
pstate.watts = slpump.pumpWatts;
|
|
1100
|
+
pstate.rpm = slpump.pumpRPMs;
|
|
1101
|
+
pstate.flow = slpump.pumpGPMs === 255 ? 0 : slpump.pumpGPMs;
|
|
1102
|
+
pstate.command = (pstate.rpm > 0 || pstate.watts > 0) ? 10 : 0;
|
|
1103
|
+
state.emitEquipmentChanges();
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1103
1106
|
public static async decodeSchedules(slrecurring: SLScheduleData, slrunonce: SLScheduleData) {
|
|
1104
1107
|
/* reccuring schedules: [{"scheduleId":1,"circuitId":6,"startTime":"1800","stopTime":"0700","dayMask":127,"flags":0,"heatCmd":4,"heatSetPoint":70,"days":["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]},
|
|
1105
1108
|
|
|
@@ -75,7 +75,7 @@ export class Message {
|
|
|
75
75
|
private static _messageId: number = 0;
|
|
76
76
|
public static get nextMessageId(): number {
|
|
77
77
|
let i = this._messageId < 80000 ? ++this._messageId : this._messageId = 0;
|
|
78
|
-
logger.debug(`Assigning message id ${i}`)
|
|
78
|
+
//logger.debug(`Assigning message id ${i}`)
|
|
79
79
|
return i; }
|
|
80
80
|
public portId = 0; // This will be the target or source port for the message. If this is from or to an Aux RS485 port the value will be > 0.
|
|
81
81
|
public timestamp: Date = new Date();
|
|
@@ -507,7 +507,7 @@ export class Inbound extends Message {
|
|
|
507
507
|
ndx = bytes.length - 5;
|
|
508
508
|
let arr = bytes.slice(0, ndx);
|
|
509
509
|
// Remove all but the last 4 bytes. This will result in nothing anyway.
|
|
510
|
-
logger.verbose(`Tossed Inbound Bytes ${arr} due to an unrecoverable collision.`);
|
|
510
|
+
logger.verbose(`[Port ${this.portId}] Tossed Inbound Bytes ${arr} due to an unrecoverable collision.`);
|
|
511
511
|
}
|
|
512
512
|
this.padding = [];
|
|
513
513
|
break;
|
|
@@ -1169,12 +1169,12 @@ export class Response extends OutboundCommon {
|
|
|
1169
1169
|
// Scenario 1. Request for pump status.
|
|
1170
1170
|
// Msg In: [165,0,16, 96, 7,15], [4,0,0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0,17,31], [1,95]
|
|
1171
1171
|
// Msg Out: [165,0,96, 16, 7, 0],[1,28]
|
|
1172
|
-
if (msgIn.source !== msgOut.dest || msgIn.dest !== msgOut.source) { return false; }
|
|
1172
|
+
if (msgIn.source !== msgOut.dest || (msgIn.dest !== msgOut.source && msgIn.dest != 16)) { return false; }
|
|
1173
1173
|
if (msgIn.action === 7 && msgOut.action === 7) { return true; }
|
|
1174
1174
|
return false;
|
|
1175
1175
|
default:
|
|
1176
1176
|
//Scenario 2, pump messages are mimics of each other but the dest/src are swapped
|
|
1177
|
-
if (msgIn.source !== msgOut.dest || msgIn.dest !== msgOut.source) { return false; }
|
|
1177
|
+
if (msgIn.source !== msgOut.dest || (msgIn.dest !== msgOut.source && msgIn.dest != 16)) { return false; }
|
|
1178
1178
|
// sub-case
|
|
1179
1179
|
// Msg In: [165,0,16, 96, 1, 2], [3,32],[1,59]
|
|
1180
1180
|
// Msg Out: [165,0,96,16, 1,4],[3,39, 3,32], [1,103]
|
|
@@ -80,6 +80,7 @@ export class ChlorinatorMessage {
|
|
|
80
80
|
if (isActive) {
|
|
81
81
|
let chlor = sys.chlorinators.getItemById(1, true);
|
|
82
82
|
let schlor = state.chlorinators.getItemById(1, true);
|
|
83
|
+
chlor.master = 0;
|
|
83
84
|
chlor.isActive = schlor.isActive = isActive;
|
|
84
85
|
if (!chlor.disabled) {
|
|
85
86
|
// RKS: We don't want these setpoints if our chem controller disabled the
|
|
@@ -87,10 +88,16 @@ export class ChlorinatorMessage {
|
|
|
87
88
|
schlor.spaSetpoint = chlor.spaSetpoint = msg.extractPayloadByte(0) >> 1;
|
|
88
89
|
schlor.poolSetpoint = chlor.poolSetpoint = msg.extractPayloadByte(1);
|
|
89
90
|
chlor.address = msg.dest;
|
|
90
|
-
schlor.body = chlor.body = sys.equipment.
|
|
91
|
+
schlor.body = chlor.body = sys.equipment.shared === true ? 32 : 0;
|
|
92
|
+
}
|
|
93
|
+
let name = msg.extractPayloadString(6, 16).trimEnd();
|
|
94
|
+
if (typeof chlor.name === 'undefined') schlor.name = chlor.name = name;
|
|
95
|
+
if (typeof chlor.model === 'undefined') {
|
|
96
|
+
chlor.model = sys.board.valueMaps.chlorinatorModel.getValue(schlor.name.toLowerCase());
|
|
97
|
+
if (typeof chlor.model === 'undefined') {
|
|
98
|
+
if (name.startsWith('iChlor')) chlor.model = sys.board.valueMaps.chlorinatorModel.getValue('ichlor-ic30');
|
|
99
|
+
}
|
|
91
100
|
}
|
|
92
|
-
if (typeof chlor.name === 'undefined') schlor.name = chlor.name = msg.extractPayloadString(6, 16);
|
|
93
|
-
if (typeof chlor.model === 'undefined') chlor.model = sys.board.valueMaps.chlorinatorModel.getValue(schlor.name.toLowerCase());
|
|
94
101
|
if (typeof chlor.type === 'undefined') chlor.type = schlor.type = 0;
|
|
95
102
|
schlor.saltLevel = msg.extractPayloadByte(3) * 50 || schlor.saltLevel;
|
|
96
103
|
schlor.status = msg.extractPayloadByte(4) & 0x007F; // Strip off the high bit. The chlorinator does not actually report this.;
|
|
@@ -329,6 +329,7 @@ export class ExternalMessage {
|
|
|
329
329
|
case 8: // Intellibrite
|
|
330
330
|
case 10: // Colorcascade
|
|
331
331
|
cstate.lightingTheme = circuit.lightingTheme;
|
|
332
|
+
if (!isOn) cstate.action = 0;
|
|
332
333
|
break;
|
|
333
334
|
case 9: // Dimmer
|
|
334
335
|
cstate.level = circuit.level;
|
|
@@ -354,7 +355,8 @@ export class ExternalMessage {
|
|
|
354
355
|
if (schedule.isActive) {
|
|
355
356
|
if (schedule.circuit > 0) { // Don't get the schedule state if we haven't determined the entire config for it yet.
|
|
356
357
|
let sstate = state.schedules.getItemById(scheduleId, schedule.isActive);
|
|
357
|
-
|
|
358
|
+
let isOn = ((byte & (1 << (j))) >> j) > 0;
|
|
359
|
+
sstate.isOn = isOn;
|
|
358
360
|
sstate.circuit = schedule.circuit;
|
|
359
361
|
sstate.endTime = schedule.endTime;
|
|
360
362
|
sstate.startDate = schedule.startDate;
|
|
@@ -365,6 +367,7 @@ export class ExternalMessage {
|
|
|
365
367
|
sstate.heatSource = schedule.heatSource;
|
|
366
368
|
sstate.startTimeType = schedule.startTimeType;
|
|
367
369
|
sstate.endTimeType = schedule.endTimeType;
|
|
370
|
+
sstate.startDate = schedule.startDate;
|
|
368
371
|
}
|
|
369
372
|
}
|
|
370
373
|
else
|
|
@@ -35,13 +35,14 @@ export class PumpMessage {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
public static processPumpConfig_IT(msg: Inbound) {
|
|
38
|
-
// packet 24/27/152/155 - Pump Config: IntelliTouch
|
|
38
|
+
// packet 24/27/152/155 - Pump Config: IntelliTouch. These will always be addressable pumps ds & ss are not included.
|
|
39
39
|
const pumpId = msg.extractPayloadByte(0);
|
|
40
40
|
let type = msg.extractPayloadByte(1); // Avoid setting this then setting it back if we are mapping to a different value.
|
|
41
41
|
let isActive = type !== 0 && pumpId <= sys.equipment.maxPumps;
|
|
42
42
|
// RKS: 04-14-21 - Only create the pump if it is available. If the pump was previously defined as another type
|
|
43
43
|
// then it will be removed and recreated.
|
|
44
|
-
|
|
44
|
+
// RKS: 05-06-23 - The original code did not search for the pump by its address. This is not correct.
|
|
45
|
+
let pump: Pump = sys.pumps.getPumpByAddress(95 + pumpId, isActive);
|
|
45
46
|
if(isActive) {
|
|
46
47
|
// Remap the combination pump types.
|
|
47
48
|
switch (type) {
|
|
@@ -59,8 +60,8 @@ export class PumpMessage {
|
|
|
59
60
|
break;
|
|
60
61
|
}
|
|
61
62
|
if (pump.type !== type) {
|
|
62
|
-
sys.pumps.
|
|
63
|
-
pump = sys.pumps.
|
|
63
|
+
sys.pumps.removePumpByAddress(95 + pumpId);
|
|
64
|
+
if (isActive) pump = sys.pumps.getPumpByAddress(95 + pumpId, isActive);
|
|
64
65
|
}
|
|
65
66
|
pump.address = pumpId + 95;
|
|
66
67
|
pump.master = 0;
|
|
@@ -308,7 +309,7 @@ export class PumpMessage {
|
|
|
308
309
|
// Sample Packet
|
|
309
310
|
// [255, 0, 255], [165, 33, 15, 16, 27, 46], [1, 128, 1, 2, 0, 1, 6, 2, 12, 4, 9, 11, 7, 6, 7, 128, 8, 132, 3, 15, 5, 3, 234, 128, 46, 108, 58, 2, 232, 220, 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [8, 5]
|
|
310
311
|
const pumpId = msg.extractPayloadByte(0);
|
|
311
|
-
const pump = sys.pumps.
|
|
312
|
+
const pump = sys.pumps.getPumpByAddress(95 + pumpId);
|
|
312
313
|
// [1, 128, 0, 2, 0, 6, 5, 1, 5, 158, 9, 2, 10, 0, 3, 0, 3, 0, 3, 0, 3, 3, 120, 20, 146, 240, 232, 232, 232, 232, 232]
|
|
313
314
|
// byte | val |
|
|
314
315
|
// 0 | 1 | PumpId = 1
|
|
@@ -359,7 +360,7 @@ export class PumpMessage {
|
|
|
359
360
|
// Sample Packet
|
|
360
361
|
// [255, 0, 255], [165, 33, 15, 16, 27, 46], [2, 6, 15, 2, 0, 1, 29, 11, 35, 0, 30, 0, 30, 0, 30, 0, 30, 0, 30, 0, 30, 30, 55, 5, 10, 60, 5, 1, 50, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [3, 41]
|
|
361
362
|
const pumpId = msg.extractPayloadByte(0);
|
|
362
|
-
const pump = sys.pumps.
|
|
363
|
+
const pump = sys.pumps.getPumpByAddress(95 + pumpId);
|
|
363
364
|
if (typeof pump.model === 'undefined') pump.model = 0;
|
|
364
365
|
for (let circuitId = 1; circuitId <= sys.board.valueMaps.pumpTypes.get(pump.type).maxCircuits; circuitId++) {
|
|
365
366
|
let _circuit = msg.extractPayloadByte(circuitId * 2 + 3);
|
|
@@ -395,7 +396,7 @@ export class PumpMessage {
|
|
|
395
396
|
//[255, 0, 255][165, 33, 15, 16, 27, 46][2, 64, 0, 0, 2, 1, 33, 2, 4, 0, 30, 0, 30, 0, 30, 0, 30, 0, 30, 0, 30, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [2, 94]
|
|
396
397
|
//[255, 0, 255][165, 1, 15, 16, 24, 31][1, 64, 0, 0, 0, 6, 5, 2, 8, 1, 11, 7, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 152, 184, 122, 0, 0, 0, 0, 0][4, 24]
|
|
397
398
|
const pumpId = msg.extractPayloadByte(0);
|
|
398
|
-
const pump = sys.pumps.
|
|
399
|
+
const pump = sys.pumps.getPumpByAddress(95 + pumpId);
|
|
399
400
|
if (typeof pump.model === 'undefined') pump.model = 0;
|
|
400
401
|
for (let circuitId = 1; circuitId <= sys.board.valueMaps.pumpTypes.get(pump.type).maxCircuits; circuitId++) {
|
|
401
402
|
let _circuit = msg.extractPayloadByte(circuitId * 2 + 3);
|
|
@@ -158,52 +158,57 @@ export class RemoteMessage {
|
|
|
158
158
|
// RKS: 12-1-22 This message is a message that has been mis-interpreted for quite some time
|
|
159
159
|
// it appears that early versions of EasyTouch did not include the ability to add more than one pump and only 4 potential
|
|
160
160
|
// circuits could be set. This comes as 3 bytes per pump setting. If there are no circuits assigned then the pump is not installed.
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
{
|
|
176
|
-
id: sys.pumps.getNextEquipmentId(),
|
|
177
|
-
master: 0,
|
|
178
|
-
address: 96,
|
|
179
|
-
type: 128,
|
|
180
|
-
name: `Pump${sys.pumps.length + 1}`,
|
|
181
|
-
flowStepSize: 1,
|
|
182
|
-
primingTime: 0,
|
|
183
|
-
primingSpeed: 450,
|
|
184
|
-
minSpeed: 450,
|
|
185
|
-
maxSpeed: 3450
|
|
161
|
+
// RKS: 05-13-23 - As it turns out ScreenLogic always asks for this bullshit and all panels return it. However, if the firmware version is
|
|
162
|
+
// greater than 1.6 it should be ignored.
|
|
163
|
+
let fwVersion = parseFloat(sys.equipment.controllerFirmware);
|
|
164
|
+
if (!isNaN(fwVersion) && fwVersion <= 1.6) {
|
|
165
|
+
let isActive = (msg.extractPayloadByte(1, 0) + msg.extractPayloadByte(4, 0) + msg.extractPayloadByte(7, 0) + msg.extractPayloadByte(10, 0)) > 0;
|
|
166
|
+
let pump = sys.pumps.find(x => x.address === 96 && (x.master || 0) === 0);
|
|
167
|
+
if (!isActive) {
|
|
168
|
+
if (typeof pump !== 'undefined') {
|
|
169
|
+
let spump = state.pumps.getItemById(pump.id, false);
|
|
170
|
+
spump.address = 96;
|
|
171
|
+
spump.isActive = false;
|
|
172
|
+
sys.pumps.removeItemById(pump.id);
|
|
173
|
+
state.pumps.removeItemById(pump.id);
|
|
174
|
+
spump.emitEquipmentChange();
|
|
186
175
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
if (typeof pump === 'undefined') pump = sys.pumps.getPumpByAddress(96, true,
|
|
179
|
+
{
|
|
180
|
+
id: sys.pumps.getNextEquipmentId(),
|
|
181
|
+
master: 0,
|
|
182
|
+
address: 96,
|
|
183
|
+
type: 128,
|
|
184
|
+
name: `Pump${sys.pumps.length + 1}`,
|
|
185
|
+
flowStepSize: 1,
|
|
186
|
+
primingTime: 0,
|
|
187
|
+
primingSpeed: 450,
|
|
188
|
+
minSpeed: 450,
|
|
189
|
+
maxSpeed: 3450
|
|
190
|
+
}
|
|
191
|
+
);
|
|
192
|
+
let spump = state.pumps.getItemById(pump.id, true);
|
|
193
|
+
spump.name = pump.name;
|
|
194
|
+
spump.address = pump.address = 96;
|
|
195
|
+
spump.type = pump.type = 128;
|
|
196
|
+
pump.isActive = spump.isActive = true;
|
|
197
|
+
// Set the circuits on the pump.
|
|
198
|
+
let cid = 0;
|
|
199
|
+
for (let i = 1; i <= 10; i += 3) {
|
|
200
|
+
let circuitId = msg.extractPayloadByte(i, 0);
|
|
201
|
+
if (circuitId > 0) {
|
|
202
|
+
cid++;
|
|
203
|
+
let circ = pump.circuits.getItemById(cid, true);
|
|
204
|
+
circ.circuit = circuitId;
|
|
205
|
+
circ.speed = (msg.extractPayloadByte(i + 1, 0) * 256) + msg.extractPayloadByte(i + 2, 0);
|
|
206
|
+
circ.units = 0;
|
|
207
|
+
}
|
|
203
208
|
}
|
|
209
|
+
if (cid < 4) for (let i = 4; i > cid && i > 0; i--) pump.circuits.removeItemById(i);
|
|
210
|
+
spump.emitEquipmentChange();
|
|
204
211
|
}
|
|
205
|
-
if (cid < 4) for (let i = 4; i > cid && i > 0; i--) pump.circuits.removeItemById(i);
|
|
206
|
-
spump.emitEquipmentChange();
|
|
207
212
|
}
|
|
208
213
|
}
|
|
209
214
|
private static processRemoteType(msg: Inbound) {
|
|
@@ -67,9 +67,15 @@ export class ChlorinatorStateMessage {
|
|
|
67
67
|
// I n t e l l i c h l o r - - 4 0
|
|
68
68
|
//[16, 2, 0, 3][0, 73, 110, 116, 101, 108, 108, 105, 99, 104, 108, 111, 114, 45, 45, 52, 48][188, 16, 3]
|
|
69
69
|
// This is the model number of the chlorinator and the address is actually the second byte.
|
|
70
|
-
let name = msg.extractPayloadString(1, 16);
|
|
70
|
+
let name = msg.extractPayloadString(1, 16).trimEnd();
|
|
71
71
|
if (typeof chlor.name === 'undefined' || chlor.name === '') chlor.name = cstate.name = name;
|
|
72
|
-
if (typeof chlor.model === 'undefined' || chlor.model === 0)
|
|
72
|
+
if (typeof chlor.model === 'undefined' || chlor.model === 0) {
|
|
73
|
+
chlor.model = sys.board.valueMaps.chlorinatorModel.getValue(name.toLowerCase());
|
|
74
|
+
// With iChlor it does not report the model.
|
|
75
|
+
if (typeof chlor.model === 'undefined') {
|
|
76
|
+
if (name.startsWith('iChlor')) chlor.model = sys.board.valueMaps.chlorinatorModel.getValue('ichlor-ic30');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
73
79
|
cstate.isActive = chlor.isActive;
|
|
74
80
|
state.emitEquipmentChanges();
|
|
75
81
|
break;
|
|
@@ -121,8 +121,12 @@ export class EquipmentStateMessage {
|
|
|
121
121
|
// Start over because we didn't have communication before but we now do. This will fall into the if
|
|
122
122
|
// below so that it goes through the intialization process. In this case we didn't see an OCP when we started
|
|
123
123
|
// but there clearly is one now.
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
(async () => {
|
|
125
|
+
await sys.board.closeAsync();
|
|
126
|
+
logger.info(`Closed ${sys.controllerType} board`);
|
|
127
|
+
sys.controllerType = ControllerType.Unknown;
|
|
128
|
+
state.status = 0;
|
|
129
|
+
})();
|
|
126
130
|
}
|
|
127
131
|
if (!state.isInitialized) {
|
|
128
132
|
msg.isProcessed = true;
|
|
@@ -592,9 +596,9 @@ export class EquipmentStateMessage {
|
|
|
592
596
|
case 204: // IntelliCenter only.
|
|
593
597
|
state.batteryVoltage = msg.extractPayloadByte(2) / 50;
|
|
594
598
|
state.comms.keepAlives = msg.extractPayloadInt(4);
|
|
595
|
-
state.time.date = msg.extractPayloadByte(6);
|
|
596
|
-
state.time.month = msg.extractPayloadByte(7);
|
|
597
599
|
state.time.year = msg.extractPayloadByte(8);
|
|
600
|
+
state.time.month = msg.extractPayloadByte(7);
|
|
601
|
+
state.time.date = msg.extractPayloadByte(6);
|
|
598
602
|
sys.equipment.controllerFirmware = (msg.extractPayloadByte(42) + (msg.extractPayloadByte(43) / 1000)).toString();
|
|
599
603
|
if (sys.chlorinators.length > 0) {
|
|
600
604
|
if (msg.extractPayloadByte(37, 255) !== 255) {
|
|
@@ -637,6 +641,7 @@ export class EquipmentStateMessage {
|
|
|
637
641
|
scover2.name = cover2.name;
|
|
638
642
|
state.temps.bodies.getItemById(cover2.body + 1).isCovered = scover2.isClosed = (msg.extractPayloadByte(30) & 0x0002) > 0;
|
|
639
643
|
}
|
|
644
|
+
sys.board.schedules.syncScheduleStates();
|
|
640
645
|
msg.isProcessed = true;
|
|
641
646
|
state.emitEquipmentChanges();
|
|
642
647
|
break;
|
|
@@ -62,7 +62,7 @@ export class NixieEquipment {
|
|
|
62
62
|
public async closeAsync() {
|
|
63
63
|
try {
|
|
64
64
|
}
|
|
65
|
-
catch (err) { logger.error(err); }
|
|
65
|
+
catch (err) { logger.error(`Error closing Nixie Equipment: ${err.message}`); }
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
export class NixieChildEquipment extends NixieEquipment {
|
|
@@ -79,7 +79,7 @@ export class NixieBody extends NixieEquipment {
|
|
|
79
79
|
try {
|
|
80
80
|
// Here we go we need to set the valve state.
|
|
81
81
|
if (bstate.isOn !== isOn) {
|
|
82
|
-
logger.info(`Nixie: Set Body ${bstate.id}-${bstate.name} to ${isOn}`);
|
|
82
|
+
logger.info(`Nixie: Set Body ${bstate.id}-${bstate.name} to ${isOn}`);
|
|
83
83
|
}
|
|
84
84
|
bstate.isOn = isOn;
|
|
85
85
|
} catch (err) { logger.error(`Nixie Error setting body state ${bstate.id}-${bstate.name}: ${err.message}`); }
|