Add messages, cleanup

This adds a bunch of messages to retrieve and set various things on the controller. It also groups the messages under one export to simplify the process of using and discovering many of them from one location.

Some of these are WIP/probably not portable to other systems.

This also adds the ability to set multiple circuits at once.
This commit is contained in:
2025-01-03 20:27:30 -06:00
parent 7daf47ac18
commit e306a62e24
31 changed files with 425 additions and 57 deletions

27
dist/index.js vendored
View File

@ -1,9 +1,6 @@
"use strict";
import { FindUnits } from "./finder.js";
import { GetBodyStatus } from "./messages/body-status.js";
import { GetSystemConfiguration } from "./messages/configuration.js";
// import { SetItemStatus } from "./messages/set-status.js";
import { GetSystemInfoRequest } from "./messages/system-info.js";
import { messages } from "./messages/messages.js";
import { Unit } from "./unit.js";
console.log("searching...");
const f = new FindUnits();
@ -25,19 +22,31 @@ const unit = new Unit(endpoint, port);
await unit.connect();
console.log("connected");
console.log("sending Get System Info request...");
let resp = await unit.send(GetSystemInfoRequest());
let resp = await unit.send(messages.GetSystemInformation());
console.log("got response:", JSON.stringify(resp, null, 2));
console.log("sending Get System Config request...");
resp = await unit.send(GetSystemConfiguration());
resp = await unit.send(messages.GetSystemConfiguration());
console.log("got response:", JSON.stringify(resp, null, 2));
console.log("sending Get Body Status request...");
resp = await unit.send(GetBodyStatus());
resp = await unit.send(messages.GetBodyStatus());
console.log("got response:", JSON.stringify(resp, null, 2));
console.log("sending Get Chemical Status request...");
resp = await unit.send(messages.GetChemicalStatus());
console.log("got response:", JSON.stringify(resp, null, 2));
console.log("sending Get Heaters request...");
resp = await unit.send(messages.GetHeaters());
console.log("got response:", JSON.stringify(resp, null, 2));
// console.log("sending Set Setpoint request...");
// resp = await unit.send(messages.SetSetpoint("B1202", 97));
// console.log("got response:", JSON.stringify(resp, null, 2));
// console.log("turning off pool...");
// resp = await unit.send(SetItemStatus("B1101", false));
// resp = await unit.send(messages.SetItemStatus("B1101", false));
// console.log("got response:", JSON.stringify(resp, null, 2));
// console.log("turning off water feature...");
// resp = await unit.send(SetItemStatus("C0003", false));
// resp = await unit.send(messages.SetItemStatus("C0003", false));
// console.log("got response:", JSON.stringify(resp, null, 2));
console.log("sending Set Heatmode request...");
resp = await unit.send(messages.SetHeatMode("B1202", true));
console.log("got response:", JSON.stringify(resp, null, 2));
unit.close();
//# sourceMappingURL=index.js.map

2
dist/index.js.map vendored
View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,4DAA4D;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AAC5B,MAAM,CAAC,GAAG,IAAI,SAAS,EAAE,CAAC;AAC1B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC,CAAC,KAAK,EAAE,CAAC;AACV,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;AAExC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IACvB,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;AAC5D,CAAC;AAED,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;IACrB,MAAM,IAAI,KAAK,CACb,oEAAoE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAC5F,CAAC;AACJ,CAAC;AAED,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;AACrC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAE3B,gCAAgC;AAChC,qBAAqB;AAErB,OAAO,CAAC,GAAG,CAAC,uCAAuC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;AAC7E,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACtC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;AACrB,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AAEzB,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;AAClD,IAAI,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC;AACnD,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAE5D,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;AACpD,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE,CAAC,CAAC;AACjD,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAE5D,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;AAClD,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;AACxC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAE5D,sCAAsC;AACtC,yDAAyD;AACzD,+DAA+D;AAE/D,+CAA+C;AAC/C,yDAAyD;AACzD,+DAA+D;AAE/D,IAAI,CAAC,KAAK,EAAE,CAAC"}
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AAC5B,MAAM,CAAC,GAAG,IAAI,SAAS,EAAE,CAAC;AAC1B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC,CAAC,KAAK,EAAE,CAAC;AACV,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;AAExC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IACvB,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;AAC5D,CAAC;AAED,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;IACrB,MAAM,IAAI,KAAK,CACb,oEAAoE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAC5F,CAAC;AACJ,CAAC;AAED,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;AACrC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAE3B,gCAAgC;AAChC,qBAAqB;AAErB,OAAO,CAAC,GAAG,CAAC,uCAAuC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;AAC7E,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACtC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;AACrB,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AAEzB,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;AAClD,IAAI,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,oBAAoB,EAAE,CAAC,CAAC;AAC5D,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAE5D,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;AACpD,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,sBAAsB,EAAE,CAAC,CAAC;AAC1D,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAE5D,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;AAClD,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;AACjD,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAE5D,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;AACtD,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACrD,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAE5D,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;AAC9C,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;AAC9C,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAE5D,kDAAkD;AAClD,6DAA6D;AAC7D,+DAA+D;AAE/D,sCAAsC;AACtC,kEAAkE;AAClE,+DAA+D;AAE/D,+CAA+C;AAC/C,kEAAkE;AAClE,+DAA+D;AAE/D,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;AAC/C,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;AAC5D,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAE5D,IAAI,CAAC,KAAK,EAAE,CAAC"}

17
dist/messages/chem-status.d.ts vendored Normal file
View File

@ -0,0 +1,17 @@
import { ICRequest } from "./request.js";
/**
* Requests the status of chemical controllers known to this controller.
*
* The response contains the list of chemical controllers available in the `objectList` array.
* For example, an IntelliChem may be one of the entries with `objnam` = `"CHM01"`, `params`.`OBJTYP`
* = `"CHEM"`, `params`.`SUBTYP` = `"ICHEM"` while an IntelliChlor salt cell may be `objnam` = `"CHR01"`,
* `params`.`OBJTYP` = `"CHEM"`, `params`.`SUBTYP` = `"ICHLOR"`. IntelliChlor knows the `"SALT"` level
* while IntelliChem knows the `"PH"` values (PHTNK, PHSET, PHVAL), `"ORP"` values (ORPTNK, ORPSET, ORPVAL),
* `"ALK"` (alkalinity), `"CALC"` (calcium hardness), and `"CYACID"` (cyanuric acid).
*
* pH and ORP Set and Val are in their respective units and orders of magnitude (e.g. 7.6, 750) while the TNK
* levels seem to be on a scale of 1-7 (so "7" would be 100% full).
*
* @returns the object used to issue this request
*/
export declare function GetChemicalStatus(): ICRequest;

30
dist/messages/chem-status.js vendored Normal file
View File

@ -0,0 +1,30 @@
import { GetRequest, ICRequestObj } from "./request.js";
/**
* Requests the status of chemical controllers known to this controller.
*
* The response contains the list of chemical controllers available in the `objectList` array.
* For example, an IntelliChem may be one of the entries with `objnam` = `"CHM01"`, `params`.`OBJTYP`
* = `"CHEM"`, `params`.`SUBTYP` = `"ICHEM"` while an IntelliChlor salt cell may be `objnam` = `"CHR01"`,
* `params`.`OBJTYP` = `"CHEM"`, `params`.`SUBTYP` = `"ICHLOR"`. IntelliChlor knows the `"SALT"` level
* while IntelliChem knows the `"PH"` values (PHTNK, PHSET, PHVAL), `"ORP"` values (ORPTNK, ORPSET, ORPVAL),
* `"ALK"` (alkalinity), `"CALC"` (calcium hardness), and `"CYACID"` (cyanuric acid).
*
* pH and ORP Set and Val are in their respective units and orders of magnitude (e.g. 7.6, 750) while the TNK
* levels seem to be on a scale of 1-7 (so "7" would be 100% full).
*
* @returns the object used to issue this request
*/
export function GetChemicalStatus() {
const req = GetRequest();
req.command = "GetParamList";
req.condition = "OBJTYP = CHEM";
req.objectList = [];
const reqObj = new ICRequestObj();
reqObj.objnam = "ALL";
reqObj.keys = [
"OBJTYP: SUBTYP: SNAME: LISTORD : BODY: PHVAL: ORPVAL: SINDEX : PRIM: SEC : PHTNK : ORPTNK : ALK : CALC : CYACID : SUPER : SALT: COMUART: PHSET: ORPSET: TIMOUT : QUALTY ",
];
req.objectList.push(reqObj);
return req;
}
//# sourceMappingURL=chem-status.js.map

1
dist/messages/chem-status.js.map vendored Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"chem-status.js","sourceRoot":"","sources":["../../messages/chem-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,YAAY,EAAE,MAAM,cAAc,CAAC;AAEnE;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,GAAG,CAAC,OAAO,GAAG,cAAc,CAAC;IAC7B,GAAG,CAAC,SAAS,GAAG,eAAe,CAAC;IAChC,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC;IAEpB,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;IAClC,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,MAAM,CAAC,IAAI,GAAG;QACZ,0KAA0K;KAC3K,CAAC;IACF,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE5B,OAAO,GAAG,CAAC;AACb,CAAC"}

9
dist/messages/get-heater.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
import { ICRequest } from "./request.js";
/**
* Requests the list of heaters known to this controller.
*
* The response contains an `objectList` populated with heater information.
*
* @returns the object used to issue this request
*/
export declare function GetHeaters(): ICRequest;

22
dist/messages/get-heater.js vendored Normal file
View File

@ -0,0 +1,22 @@
import { GetRequest, ICRequestObj } from "./request.js";
/**
* Requests the list of heaters known to this controller.
*
* The response contains an `objectList` populated with heater information.
*
* @returns the object used to issue this request
*/
export function GetHeaters() {
const req = GetRequest();
req.command = "GetParamList";
req.condition = "OBJTYP = HEATER";
req.objectList = [];
const reqObj = new ICRequestObj();
reqObj.objnam = "ALL";
reqObj.keys = [
"OBJTYP: SUBTYP: SNAME: LISTORD: STATUS: PERMIT: TIMOUT: READY: HTMODE : SHOMNU : COOL : COMUART : BODY : HNAME : START : STOP : HEATING : BOOST : TIME : DLY : MODE",
];
req.objectList.push(reqObj);
return req;
}
//# sourceMappingURL=get-heater.js.map

1
dist/messages/get-heater.js.map vendored Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"get-heater.js","sourceRoot":"","sources":["../../messages/get-heater.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,YAAY,EAAE,MAAM,cAAc,CAAC;AAEnE;;;;;;GAMG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,GAAG,CAAC,OAAO,GAAG,cAAc,CAAC;IAC7B,GAAG,CAAC,SAAS,GAAG,iBAAiB,CAAC;IAClC,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC;IAEpB,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;IAClC,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,MAAM,CAAC,IAAI,GAAG;QACZ,qKAAqK;KACtK,CAAC;IACF,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE5B,OAAO,GAAG,CAAC;AACb,CAAC"}

18
dist/messages/messages.d.ts vendored Normal file
View File

@ -0,0 +1,18 @@
import { GetBodyStatus } from "./body-status.js";
import { GetChemicalStatus } from "./chem-status.js";
import { GetSystemConfiguration } from "./configuration.js";
import { GetHeaters } from "./get-heater.js";
import { SetHeatMode } from "./set-heater.js";
import { SetItemStatus } from "./set-status.js";
import { SetSetpoint } from "./setpoint.js";
import { GetSystemInformation } from "./system-info.js";
export declare const messages: {
GetBodyStatus: typeof GetBodyStatus;
GetChemicalStatus: typeof GetChemicalStatus;
GetHeaters: typeof GetHeaters;
GetSystemConfiguration: typeof GetSystemConfiguration;
GetSystemInformation: typeof GetSystemInformation;
SetHeatMode: typeof SetHeatMode;
SetItemStatus: typeof SetItemStatus;
SetSetpoint: typeof SetSetpoint;
};

19
dist/messages/messages.js vendored Normal file
View File

@ -0,0 +1,19 @@
import { GetBodyStatus } from "./body-status.js";
import { GetChemicalStatus } from "./chem-status.js";
import { GetSystemConfiguration } from "./configuration.js";
import { GetHeaters } from "./get-heater.js";
import { SetHeatMode } from "./set-heater.js";
import { SetItemStatus } from "./set-status.js";
import { SetSetpoint } from "./setpoint.js";
import { GetSystemInformation } from "./system-info.js";
export const messages = {
GetBodyStatus,
GetChemicalStatus,
GetHeaters,
GetSystemConfiguration,
GetSystemInformation,
SetHeatMode,
SetItemStatus,
SetSetpoint,
};
//# sourceMappingURL=messages.js.map

1
dist/messages/messages.js.map vendored Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../messages/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,aAAa;IACb,iBAAiB;IACjB,UAAU;IACV,sBAAsB;IACtB,oBAAoB;IACpB,WAAW;IACX,aAAa;IACb,WAAW;CACZ,CAAC"}

15
dist/messages/set-heater.d.ts vendored Normal file
View File

@ -0,0 +1,15 @@
import { ICRequest } from "./request.js";
/**
* Requests to turn a body's heater on or off.
*
* This is very WIP. For my pool and my heater configuration, the MODE needs to be 11 to enable my
* heater and 1 to disable all heaters. I have a feeling 11 is unique to my system's configuration,
* but I can't yet determine how to know what 11 maps to in order to make this more generic.
*
* Note that this doesn't necessarily start heating the body by itself - if the body's pump is
* currently off, enabling the heater will not turn it on. If the pump/body is on, then this will
* enable the heater and no further action is required.
*
* @returns the object used to issue this request
*/
export declare function SetHeatMode(bodyObjnam: string, enabled: boolean): ICRequest;

27
dist/messages/set-heater.js vendored Normal file
View File

@ -0,0 +1,27 @@
import { ICParam } from "./param.js";
import { GetRequest, ICRequestObj } from "./request.js";
/**
* Requests to turn a body's heater on or off.
*
* This is very WIP. For my pool and my heater configuration, the MODE needs to be 11 to enable my
* heater and 1 to disable all heaters. I have a feeling 11 is unique to my system's configuration,
* but I can't yet determine how to know what 11 maps to in order to make this more generic.
*
* Note that this doesn't necessarily start heating the body by itself - if the body's pump is
* currently off, enabling the heater will not turn it on. If the pump/body is on, then this will
* enable the heater and no further action is required.
*
* @returns the object used to issue this request
*/
export function SetHeatMode(bodyObjnam, enabled) {
const req = GetRequest();
req.command = "SetParamList";
req.objectList = [];
const reqObj = new ICRequestObj();
reqObj.objnam = bodyObjnam;
reqObj.params = new ICParam();
reqObj.params.MODE = enabled ? "11" : "1";
req.objectList.push(reqObj);
return req;
}
//# sourceMappingURL=set-heater.js.map

1
dist/messages/set-heater.js.map vendored Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"set-heater.js","sourceRoot":"","sources":["../../messages/set-heater.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,UAAU,EAAa,YAAY,EAAE,MAAM,cAAc,CAAC;AAEnE;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,WAAW,CAAC,UAAkB,EAAE,OAAgB;IAC9D,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,GAAG,CAAC,OAAO,GAAG,cAAc,CAAC;IAC7B,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC;IAEpB,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;IAClC,MAAM,CAAC,MAAM,GAAG,UAAU,CAAC;IAC3B,MAAM,CAAC,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;IAC9B,MAAM,CAAC,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;IAC1C,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE5B,OAAO,GAAG,CAAC;AACb,CAAC"}

View File

@ -1,14 +1,9 @@
import { ICRequest } from "./request.js";
/**
* Requests the status of bodies known to this controller.
* Requests to change the status of items known to this controller.
*
* The response contains the list of bodies in the `params` field. Each body has
* an `objnam` that should be used to reference that body for future requests.
* When `params`.`STATUS` is `"OFF"`, use `params`.`LSTTMP` to get the temperature
* of the body the last time it was on, or `params`.`TEMP` to get the temperature
* if the `STATUS` is `"ON"`. `LSTTMP` seems to always be accurate, however, whether
* the body is currently on or off.
* Turns one or more items on or off. Use the `objnam` of the circuit to be set.
*
* @returns the object used to issue this request
*/
export declare function SetItemStatus(item: string, status: boolean): ICRequest;
export declare function SetItemStatus(item: string | string[], status: boolean): ICRequest;

View File

@ -1,14 +1,9 @@
import { ICParam } from "./param.js";
import { GetRequest, ICRequestObj } from "./request.js";
/**
* Requests the status of bodies known to this controller.
* Requests to change the status of items known to this controller.
*
* The response contains the list of bodies in the `params` field. Each body has
* an `objnam` that should be used to reference that body for future requests.
* When `params`.`STATUS` is `"OFF"`, use `params`.`LSTTMP` to get the temperature
* of the body the last time it was on, or `params`.`TEMP` to get the temperature
* if the `STATUS` is `"ON"`. `LSTTMP` seems to always be accurate, however, whether
* the body is currently on or off.
* Turns one or more items on or off. Use the `objnam` of the circuit to be set.
*
* @returns the object used to issue this request
*/
@ -16,11 +11,20 @@ export function SetItemStatus(item, status) {
const req = GetRequest();
req.command = "SetParamList";
req.objectList = [];
const reqObj = new ICRequestObj();
reqObj.objnam = item;
reqObj.params = new ICParam();
reqObj.params.STATUS = status ? "ON" : "OFF";
req.objectList.push(reqObj);
let items;
if (Array.isArray(item)) {
items = item;
}
else {
items = [item];
}
for (const i of items) {
const reqObj = new ICRequestObj();
reqObj.objnam = i;
reqObj.params = new ICParam();
reqObj.params.STATUS = status ? "ON" : "OFF";
req.objectList.push(reqObj);
}
return req;
}
//# sourceMappingURL=set-status.js.map

View File

@ -1 +1 @@
{"version":3,"file":"set-status.js","sourceRoot":"","sources":["../../messages/set-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,UAAU,EAAa,YAAY,EAAE,MAAM,cAAc,CAAC;AAEnE;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,MAAe;IACzD,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,GAAG,CAAC,OAAO,GAAG,cAAc,CAAC;IAC7B,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC;IAEpB,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;IAClC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,CAAC,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;IAC9B,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IAC7C,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE5B,OAAO,GAAG,CAAC;AACb,CAAC"}
{"version":3,"file":"set-status.js","sourceRoot":"","sources":["../../messages/set-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,UAAU,EAAa,YAAY,EAAE,MAAM,cAAc,CAAC;AAEnE;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAuB,EACvB,MAAe;IAEf,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,GAAG,CAAC,OAAO,GAAG,cAAc,CAAC;IAC7B,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC;IAEpB,IAAI,KAAe,CAAC;IACpB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,KAAK,GAAG,IAAI,CAAC;IACf,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;QAClC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAClB,MAAM,CAAC,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QAC7C,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}

11
dist/messages/setpoint.d.ts vendored Normal file
View File

@ -0,0 +1,11 @@
import { ICRequest } from "./request.js";
/**
* Requests to change the setpoint of a temperature circuit.
*
* Use the `objnam` of the circuit to be set and give the temperature in the same units that the
* controller is set to (so, give a number in Celsius if the system is in Celsius or Fahrenheit
* if the system is in Fahrenheit).
*
* @returns the object used to issue this request
*/
export declare function SetSetpoint(objnam: string, setpoint: number): ICRequest;

23
dist/messages/setpoint.js vendored Normal file
View File

@ -0,0 +1,23 @@
import { ICParam } from "./param.js";
import { GetRequest, ICRequestObj } from "./request.js";
/**
* Requests to change the setpoint of a temperature circuit.
*
* Use the `objnam` of the circuit to be set and give the temperature in the same units that the
* controller is set to (so, give a number in Celsius if the system is in Celsius or Fahrenheit
* if the system is in Fahrenheit).
*
* @returns the object used to issue this request
*/
export function SetSetpoint(objnam, setpoint) {
const req = GetRequest();
req.command = "SetParamList";
req.objectList = [];
const reqObj = new ICRequestObj();
reqObj.objnam = objnam;
reqObj.params = new ICParam();
reqObj.params.LOTMP = setpoint.toString();
req.objectList.push(reqObj);
return req;
}
//# sourceMappingURL=setpoint.js.map

1
dist/messages/setpoint.js.map vendored Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"setpoint.js","sourceRoot":"","sources":["../../messages/setpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,UAAU,EAAa,YAAY,EAAE,MAAM,cAAc,CAAC;AAEnE;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc,EAAE,QAAgB;IAC1D,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,GAAG,CAAC,OAAO,GAAG,cAAc,CAAC;IAC7B,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC;IAEpB,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;IAClC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,MAAM,CAAC,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;IAC9B,MAAM,CAAC,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAC1C,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE5B,OAAO,GAAG,CAAC;AACb,CAAC"}

View File

@ -1,2 +1,7 @@
import { ICRequest } from "./request.js";
export declare function GetSystemInfoRequest(): ICRequest;
/**
* Requests information about this controller such as owner, address, etc.
*
* @returns the object used to issue this request
*/
export declare function GetSystemInformation(): ICRequest;

View File

@ -1,5 +1,10 @@
import { GetRequest, ICRequestObj } from "./request.js";
export function GetSystemInfoRequest() {
/**
* Requests information about this controller such as owner, address, etc.
*
* @returns the object used to issue this request
*/
export function GetSystemInformation() {
const req = GetRequest();
req.command = "GETPARAMLIST";
req.condition = "";

View File

@ -1 +1 @@
{"version":3,"file":"system-info.js","sourceRoot":"","sources":["../../messages/system-info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,YAAY,EAAE,MAAM,cAAc,CAAC;AAEnE,MAAM,UAAU,oBAAoB;IAClC,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,GAAG,CAAC,OAAO,GAAG,cAAc,CAAC;IAC7B,GAAG,CAAC,SAAS,GAAG,EAAE,CAAC;IACnB,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC;IAEpB,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;IAClC,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC;IACxB,MAAM,CAAC,IAAI,GAAG;QACZ,KAAK;QACL,MAAM;QACN,KAAK;QACL,QAAQ;QACR,UAAU;QACV,MAAM;QACN,SAAS;QACT,MAAM;QACN,OAAO;QACP,OAAO;QACP,QAAQ;QACR,OAAO;QACP,QAAQ;QACR,SAAS;QACT,OAAO;QACP,MAAM;QACN,MAAM;QACN,OAAO;QACP,SAAS;QACT,QAAQ;QACR,UAAU;QACV,IAAI;QACJ,OAAO;QACP,SAAS;KACV,CAAC;IACF,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE5B,OAAO,GAAG,CAAC;AACb,CAAC"}
{"version":3,"file":"system-info.js","sourceRoot":"","sources":["../../messages/system-info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,YAAY,EAAE,MAAM,cAAc,CAAC;AAEnE;;;;GAIG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,GAAG,CAAC,OAAO,GAAG,cAAc,CAAC;IAC7B,GAAG,CAAC,SAAS,GAAG,EAAE,CAAC;IACnB,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC;IAEpB,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;IAClC,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC;IACxB,MAAM,CAAC,IAAI,GAAG;QACZ,KAAK;QACL,MAAM;QACN,KAAK;QACL,QAAQ;QACR,UAAU;QACV,MAAM;QACN,SAAS;QACT,MAAM;QACN,OAAO;QACP,OAAO;QACP,QAAQ;QACR,OAAO;QACP,QAAQ;QACR,SAAS;QACT,OAAO;QACP,MAAM;QACN,MAAM;QACN,OAAO;QACP,SAAS;QACT,QAAQ;QACR,UAAU;QACV,IAAI;QACJ,OAAO;QACP,SAAS;KACV,CAAC;IACF,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE5B,OAAO,GAAG,CAAC;AACb,CAAC"}

View File

@ -1,10 +1,7 @@
"use strict";
import { FindUnits } from "./finder.js";
import { GetBodyStatus } from "./messages/body-status.js";
import { GetSystemConfiguration } from "./messages/configuration.js";
// import { SetItemStatus } from "./messages/set-status.js";
import { GetSystemInfoRequest } from "./messages/system-info.js";
import { messages } from "./messages/messages.js";
import { Unit } from "./unit.js";
console.log("searching...");
@ -35,23 +32,39 @@ await unit.connect();
console.log("connected");
console.log("sending Get System Info request...");
let resp = await unit.send(GetSystemInfoRequest());
let resp = await unit.send(messages.GetSystemInformation());
console.log("got response:", JSON.stringify(resp, null, 2));
console.log("sending Get System Config request...");
resp = await unit.send(GetSystemConfiguration());
resp = await unit.send(messages.GetSystemConfiguration());
console.log("got response:", JSON.stringify(resp, null, 2));
console.log("sending Get Body Status request...");
resp = await unit.send(GetBodyStatus());
resp = await unit.send(messages.GetBodyStatus());
console.log("got response:", JSON.stringify(resp, null, 2));
console.log("sending Get Chemical Status request...");
resp = await unit.send(messages.GetChemicalStatus());
console.log("got response:", JSON.stringify(resp, null, 2));
console.log("sending Get Heaters request...");
resp = await unit.send(messages.GetHeaters());
console.log("got response:", JSON.stringify(resp, null, 2));
// console.log("sending Set Setpoint request...");
// resp = await unit.send(messages.SetSetpoint("B1202", 97));
// console.log("got response:", JSON.stringify(resp, null, 2));
// console.log("turning off pool...");
// resp = await unit.send(SetItemStatus("B1101", false));
// resp = await unit.send(messages.SetItemStatus("B1101", false));
// console.log("got response:", JSON.stringify(resp, null, 2));
// console.log("turning off water feature...");
// resp = await unit.send(SetItemStatus("C0003", false));
// resp = await unit.send(messages.SetItemStatus("C0003", false));
// console.log("got response:", JSON.stringify(resp, null, 2));
console.log("sending Set Heatmode request...");
resp = await unit.send(messages.SetHeatMode("B1202", true));
console.log("got response:", JSON.stringify(resp, null, 2));
unit.close();

32
messages/chem-status.ts Normal file
View File

@ -0,0 +1,32 @@
import { GetRequest, ICRequest, ICRequestObj } from "./request.js";
/**
* Requests the status of chemical controllers known to this controller.
*
* The response contains the list of chemical controllers available in the `objectList` array.
* For example, an IntelliChem may be one of the entries with `objnam` = `"CHM01"`, `params`.`OBJTYP`
* = `"CHEM"`, `params`.`SUBTYP` = `"ICHEM"` while an IntelliChlor salt cell may be `objnam` = `"CHR01"`,
* `params`.`OBJTYP` = `"CHEM"`, `params`.`SUBTYP` = `"ICHLOR"`. IntelliChlor knows the `"SALT"` level
* while IntelliChem knows the `"PH"` values (PHTNK, PHSET, PHVAL), `"ORP"` values (ORPTNK, ORPSET, ORPVAL),
* `"ALK"` (alkalinity), `"CALC"` (calcium hardness), and `"CYACID"` (cyanuric acid).
*
* pH and ORP Set and Val are in their respective units and orders of magnitude (e.g. 7.6, 750) while the TNK
* levels seem to be on a scale of 1-7 (so "7" would be 100% full).
*
* @returns the object used to issue this request
*/
export function GetChemicalStatus(): ICRequest {
const req = GetRequest();
req.command = "GetParamList";
req.condition = "OBJTYP = CHEM";
req.objectList = [];
const reqObj = new ICRequestObj();
reqObj.objnam = "ALL";
reqObj.keys = [
"OBJTYP: SUBTYP: SNAME: LISTORD : BODY: PHVAL: ORPVAL: SINDEX : PRIM: SEC : PHTNK : ORPTNK : ALK : CALC : CYACID : SUPER : SALT: COMUART: PHSET: ORPSET: TIMOUT : QUALTY ",
];
req.objectList.push(reqObj);
return req;
}

24
messages/get-heater.ts Normal file
View File

@ -0,0 +1,24 @@
import { GetRequest, ICRequest, ICRequestObj } from "./request.js";
/**
* Requests the list of heaters known to this controller.
*
* The response contains an `objectList` populated with heater information.
*
* @returns the object used to issue this request
*/
export function GetHeaters(): ICRequest {
const req = GetRequest();
req.command = "GetParamList";
req.condition = "OBJTYP = HEATER";
req.objectList = [];
const reqObj = new ICRequestObj();
reqObj.objnam = "ALL";
reqObj.keys = [
"OBJTYP: SUBTYP: SNAME: LISTORD: STATUS: PERMIT: TIMOUT: READY: HTMODE : SHOMNU : COOL : COMUART : BODY : HNAME : START : STOP : HEATING : BOOST : TIME : DLY : MODE",
];
req.objectList.push(reqObj);
return req;
}

19
messages/messages.ts Normal file
View File

@ -0,0 +1,19 @@
import { GetBodyStatus } from "./body-status.js";
import { GetChemicalStatus } from "./chem-status.js";
import { GetSystemConfiguration } from "./configuration.js";
import { GetHeaters } from "./get-heater.js";
import { SetHeatMode } from "./set-heater.js";
import { SetItemStatus } from "./set-status.js";
import { SetSetpoint } from "./setpoint.js";
import { GetSystemInformation } from "./system-info.js";
export const messages = {
GetBodyStatus,
GetChemicalStatus,
GetHeaters,
GetSystemConfiguration,
GetSystemInformation,
SetHeatMode,
SetItemStatus,
SetSetpoint,
};

29
messages/set-heater.ts Normal file
View File

@ -0,0 +1,29 @@
import { ICParam } from "./param.js";
import { GetRequest, ICRequest, ICRequestObj } from "./request.js";
/**
* Requests to turn a body's heater on or off.
*
* This is very WIP. For my pool and my heater configuration, the MODE needs to be 11 to enable my
* heater and 1 to disable all heaters. I have a feeling 11 is unique to my system's configuration,
* but I can't yet determine how to know what 11 maps to in order to make this more generic.
*
* Note that this doesn't necessarily start heating the body by itself - if the body's pump is
* currently off, enabling the heater will not turn it on. If the pump/body is on, then this will
* enable the heater and no further action is required.
*
* @returns the object used to issue this request
*/
export function SetHeatMode(bodyObjnam: string, enabled: boolean): ICRequest {
const req = GetRequest();
req.command = "SetParamList";
req.objectList = [];
const reqObj = new ICRequestObj();
reqObj.objnam = bodyObjnam;
reqObj.params = new ICParam();
reqObj.params.MODE = enabled ? "11" : "1";
req.objectList.push(reqObj);
return req;
}

View File

@ -2,27 +2,34 @@ import { ICParam } from "./param.js";
import { GetRequest, ICRequest, ICRequestObj } from "./request.js";
/**
* Requests the status of bodies known to this controller.
* Requests to change the status of items known to this controller.
*
* The response contains the list of bodies in the `params` field. Each body has
* an `objnam` that should be used to reference that body for future requests.
* When `params`.`STATUS` is `"OFF"`, use `params`.`LSTTMP` to get the temperature
* of the body the last time it was on, or `params`.`TEMP` to get the temperature
* if the `STATUS` is `"ON"`. `LSTTMP` seems to always be accurate, however, whether
* the body is currently on or off.
* Turns one or more items on or off. Use the `objnam` of the circuit to be set.
*
* @returns the object used to issue this request
*/
export function SetItemStatus(item: string, status: boolean): ICRequest {
export function SetItemStatus(
item: string | string[],
status: boolean,
): ICRequest {
const req = GetRequest();
req.command = "SetParamList";
req.objectList = [];
const reqObj = new ICRequestObj();
reqObj.objnam = item;
reqObj.params = new ICParam();
reqObj.params.STATUS = status ? "ON" : "OFF";
req.objectList.push(reqObj);
let items: string[];
if (Array.isArray(item)) {
items = item;
} else {
items = [item];
}
for (const i of items) {
const reqObj = new ICRequestObj();
reqObj.objnam = i;
reqObj.params = new ICParam();
reqObj.params.STATUS = status ? "ON" : "OFF";
req.objectList.push(reqObj);
}
return req;
}

25
messages/setpoint.ts Normal file
View File

@ -0,0 +1,25 @@
import { ICParam } from "./param.js";
import { GetRequest, ICRequest, ICRequestObj } from "./request.js";
/**
* Requests to change the setpoint of a temperature circuit.
*
* Use the `objnam` of the circuit to be set and give the temperature in the same units that the
* controller is set to (so, give a number in Celsius if the system is in Celsius or Fahrenheit
* if the system is in Fahrenheit).
*
* @returns the object used to issue this request
*/
export function SetSetpoint(objnam: string, setpoint: number): ICRequest {
const req = GetRequest();
req.command = "SetParamList";
req.objectList = [];
const reqObj = new ICRequestObj();
reqObj.objnam = objnam;
reqObj.params = new ICParam();
reqObj.params.LOTMP = setpoint.toString();
req.objectList.push(reqObj);
return req;
}

View File

@ -1,6 +1,11 @@
import { GetRequest, ICRequest, ICRequestObj } from "./request.js";
export function GetSystemInfoRequest(): ICRequest {
/**
* Requests information about this controller such as owner, address, etc.
*
* @returns the object used to issue this request
*/
export function GetSystemInformation(): ICRequest {
const req = GetRequest();
req.command = "GETPARAMLIST";
req.condition = "";