mirror of
https://github.com/parnic/node-intellicenter.git
synced 2025-06-17 02:21:53 -05:00
Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
861fec9565
|
|||
69c2c67336
|
|||
50d71a2858
|
|||
abe9ba7d95
|
|||
21d62549d3
|
|||
9455ae224c
|
|||
e8ebfe8e02
|
|||
3031bc2079
|
|||
9e332038c6
|
|||
033627d698
|
|||
f59cc3438c
|
3
.markdownlint-cli2.jsonc
Normal file
3
.markdownlint-cli2.jsonc
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"gitignore": true,
|
||||
}
|
7
.markdownlint.json
Normal file
7
.markdownlint.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"default": true,
|
||||
"MD024": {
|
||||
"siblings_only": true
|
||||
},
|
||||
"line-length": false
|
||||
}
|
7
.vscode/launch.json
vendored
7
.vscode/launch.json
vendored
@ -9,9 +9,12 @@
|
||||
"request": "launch",
|
||||
"name": "Launch Program",
|
||||
"skipFiles": ["<node_internals>/**"],
|
||||
"program": "${workspaceFolder}/index.ts",
|
||||
"program": "${workspaceFolder}/example.ts",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": ["${workspaceFolder}/**/*.js"]
|
||||
"outFiles": ["${workspaceFolder}/**/*.js"],
|
||||
"env": {
|
||||
"DEBUG": "ic:*"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
32
CHANGELOG.md
32
CHANGELOG.md
@ -2,5 +2,35 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [v0.1.0] - 2025-01-05
|
||||
|
||||
### Added
|
||||
|
||||
- Added GetCircuitStatus message for getting current status of all connected circuits.
|
||||
|
||||
### Changed
|
||||
|
||||
- [Breaking change] Renamed Item to Object in, e.g., messages.SetObjectStatus()
|
||||
|
||||
## [v0.0.2] - 2025-01-04
|
||||
|
||||
### Added
|
||||
|
||||
- Added "close", "open", "error", "timeout" events to Unit.
|
||||
- Added more documentation and error checking to Unit methods.
|
||||
- Added ability to specify which interface to broadcast the unit search on. Specify your adapter's address to pick which one to use, e.g. "10.0.0.3", "172.16.0.25". Leaving this argument out will use the previous behavior, which allows the system to choose the adapter it wants to use.
|
||||
- Added FindUnits and Unit as exports from the base package to make importing and using the library easier in non-module consumers.
|
||||
- Added "connected" event to Unit which runs once a connection is established and requests may be sent.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed the default import being the example code which was finding and running commands against controllers.
|
||||
|
||||
## [v0.0.1] - 2025-01-04
|
||||
|
||||
### Added
|
||||
|
||||
- Initial release. Includes basic ability to find and connect to an IntelliCenter unit and query and make changes to it.
|
||||
|
1
dist/example.d.ts
vendored
Normal file
1
dist/example.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export {};
|
63
dist/example.js
vendored
Normal file
63
dist/example.js
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
"use strict";
|
||||
import { FindUnits, Unit } from "./index.js";
|
||||
import { messages } from "./messages/messages.js";
|
||||
console.log("searching...");
|
||||
const f = new FindUnits();
|
||||
const units = await f.searchAsync(1000);
|
||||
f.close();
|
||||
console.log("Discovered units:", units);
|
||||
if (units.length === 0) {
|
||||
throw new Error("no IntelliCenter units found, exiting.");
|
||||
}
|
||||
if (units.length > 1) {
|
||||
throw new Error(`found more than one IntelliCenter unit, unsure which one to use. ${JSON.stringify(units)}`);
|
||||
}
|
||||
const endpoint = units[0].addressStr;
|
||||
const port = units[0].port;
|
||||
// const endpoint = "10.0.0.41";
|
||||
// const port = 6680;
|
||||
console.log("connecting to intellicenter device at", endpoint, "port", port);
|
||||
const unit = new Unit(endpoint, port);
|
||||
await unit.connect();
|
||||
console.log("connected");
|
||||
unit.on("notify", (msg) => {
|
||||
console.log("received notify:", msg);
|
||||
});
|
||||
console.log("subscribing for updates...");
|
||||
let resp = await unit.send(messages.SubscribeToUpdates("B1202", "LOTMP"));
|
||||
console.log("got response:", JSON.stringify(resp, null, 2));
|
||||
console.log("sending Get System Info request...");
|
||||
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(messages.GetSystemConfiguration());
|
||||
console.log("got response:", JSON.stringify(resp, null, 2));
|
||||
console.log("sending Get Body Status request...");
|
||||
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 Get Schedule request...");
|
||||
resp = await unit.send(messages.GetSchedule());
|
||||
console.log("got response:", JSON.stringify(resp, null, 2));
|
||||
console.log("sending Get Circuit Status request...");
|
||||
resp = await unit.send(messages.GetCircuitStatus());
|
||||
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(messages.SetObjectStatus("B1101", false));
|
||||
// console.log("got response:", JSON.stringify(resp, null, 2));
|
||||
// console.log("turning off water feature...");
|
||||
// resp = await unit.send(messages.SetObjectStatus("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=example.js.map
|
1
dist/example.js.map
vendored
Normal file
1
dist/example.js.map
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"example.js","sourceRoot":"","sources":["../example.ts"],"names":[],"mappings":"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"}
|
8
dist/finder.d.ts
vendored
8
dist/finder.d.ts
vendored
@ -20,7 +20,13 @@ export declare class UnitInfo {
|
||||
* * `"serverFound"` - fired immediately when an IntelliCenter unit has been located; receives a {@linkcode UnitInfo} argument
|
||||
*/
|
||||
export declare class FindUnits extends EventEmitter {
|
||||
constructor();
|
||||
broadcastInterface?: string | undefined;
|
||||
/**
|
||||
* Creates a new finder.
|
||||
*
|
||||
* @param broadcastInterface the address of the interface to send the broadcast to. If not specified, will use system selection. Only necessary if you have more than one network adapter/interface and want to search on a specific one.
|
||||
*/
|
||||
constructor(broadcastInterface?: string | undefined);
|
||||
private finder;
|
||||
private bound;
|
||||
private message;
|
||||
|
12
dist/finder.js
vendored
12
dist/finder.js
vendored
@ -31,8 +31,15 @@ export class UnitInfo {
|
||||
* * `"serverFound"` - fired immediately when an IntelliCenter unit has been located; receives a {@linkcode UnitInfo} argument
|
||||
*/
|
||||
export class FindUnits extends EventEmitter {
|
||||
constructor() {
|
||||
broadcastInterface;
|
||||
/**
|
||||
* Creates a new finder.
|
||||
*
|
||||
* @param broadcastInterface the address of the interface to send the broadcast to. If not specified, will use system selection. Only necessary if you have more than one network adapter/interface and want to search on a specific one.
|
||||
*/
|
||||
constructor(broadcastInterface) {
|
||||
super();
|
||||
this.broadcastInterface = broadcastInterface;
|
||||
// construct mDNS packet to ping for intellicenter controllers
|
||||
this.message = Buffer.alloc(34);
|
||||
let offset = 0;
|
||||
@ -54,6 +61,9 @@ export class FindUnits extends EventEmitter {
|
||||
this.finder = createSocket("udp4");
|
||||
this.finder
|
||||
.on("listening", () => {
|
||||
if (this.broadcastInterface) {
|
||||
this.finder.setMulticastInterface(this.broadcastInterface);
|
||||
}
|
||||
this.finder.setBroadcast(true);
|
||||
this.finder.setMulticastTTL(128);
|
||||
if (!this.bound) {
|
||||
|
2
dist/finder.js.map
vendored
2
dist/finder.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/index.d.ts
vendored
4
dist/index.d.ts
vendored
@ -1 +1,3 @@
|
||||
export {};
|
||||
import { FindUnits } from "./finder.js";
|
||||
import { Unit } from "./unit.js";
|
||||
export { FindUnits, Unit };
|
||||
|
59
dist/index.js
vendored
59
dist/index.js
vendored
@ -1,61 +1,4 @@
|
||||
"use strict";
|
||||
import { FindUnits } from "./finder.js";
|
||||
import { messages } from "./messages/messages.js";
|
||||
import { Unit } from "./unit.js";
|
||||
console.log("searching...");
|
||||
const f = new FindUnits();
|
||||
const units = await f.searchAsync(1000);
|
||||
f.close();
|
||||
console.log("Discovered units:", units);
|
||||
if (units.length === 0) {
|
||||
throw new Error("no IntelliCenter units found, exiting.");
|
||||
}
|
||||
if (units.length > 1) {
|
||||
throw new Error(`found more than one IntelliCenter unit, unsure which one to use. ${JSON.stringify(units)}`);
|
||||
}
|
||||
const endpoint = units[0].addressStr;
|
||||
const port = units[0].port;
|
||||
// const endpoint = "10.0.0.41";
|
||||
// const port = 6680;
|
||||
console.log("connecting to intellicenter device at", endpoint, "port", port);
|
||||
const unit = new Unit(endpoint, port);
|
||||
await unit.connect();
|
||||
console.log("connected");
|
||||
unit.on("notify", (msg) => {
|
||||
console.log("received notify:", msg);
|
||||
});
|
||||
console.log("subscribing for updates...");
|
||||
let resp = await unit.send(messages.SubscribeToUpdates("B1202", "LOTMP"));
|
||||
console.log("got response:", JSON.stringify(resp, null, 2));
|
||||
console.log("sending Get System Info request...");
|
||||
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(messages.GetSystemConfiguration());
|
||||
console.log("got response:", JSON.stringify(resp, null, 2));
|
||||
console.log("sending Get Body Status request...");
|
||||
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 Get Schedule request...");
|
||||
resp = await unit.send(messages.GetSchedule());
|
||||
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(messages.SetItemStatus("B1101", false));
|
||||
// console.log("got response:", JSON.stringify(resp, null, 2));
|
||||
// console.log("turning off water feature...");
|
||||
// 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();
|
||||
export { FindUnits, Unit };
|
||||
//# sourceMappingURL=index.js.map
|
2
dist/index.js.map
vendored
2
dist/index.js.map
vendored
@ -1 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC"}
|
9
dist/messages/circuit-status.d.ts
vendored
Normal file
9
dist/messages/circuit-status.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
import { ICRequest } from "./request.js";
|
||||
/**
|
||||
* Requests the list of circuits known to this controller.
|
||||
*
|
||||
* The response contains an `objectList` populated with circuit information.
|
||||
*
|
||||
* @returns the object used to issue this request
|
||||
*/
|
||||
export declare function GetCircuitStatus(): ICRequest;
|
37
dist/messages/circuit-status.js
vendored
Normal file
37
dist/messages/circuit-status.js
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
import { GetRequest, ICRequestObj } from "./request.js";
|
||||
/**
|
||||
* Requests the list of circuits known to this controller.
|
||||
*
|
||||
* The response contains an `objectList` populated with circuit information.
|
||||
*
|
||||
* @returns the object used to issue this request
|
||||
*/
|
||||
export function GetCircuitStatus() {
|
||||
const req = GetRequest();
|
||||
req.command = "GetParamList";
|
||||
req.condition = "OBJTYP = CIRCUIT";
|
||||
req.objectList = [];
|
||||
const reqObj = new ICRequestObj();
|
||||
reqObj.objnam = "ALL";
|
||||
reqObj.keys = [
|
||||
"OBJNAM",
|
||||
"OBJTYP",
|
||||
"SUBTYP",
|
||||
"STATUS",
|
||||
"BODY",
|
||||
"SNAME",
|
||||
"HNAME",
|
||||
"FREEZE",
|
||||
"DNTSTP",
|
||||
"HNAME",
|
||||
"TIME",
|
||||
"FEATR",
|
||||
"USAGE",
|
||||
"LIMIT",
|
||||
"USE",
|
||||
"SHOMNU",
|
||||
];
|
||||
req.objectList.push(reqObj);
|
||||
return req;
|
||||
}
|
||||
//# sourceMappingURL=circuit-status.js.map
|
1
dist/messages/circuit-status.js.map
vendored
Normal file
1
dist/messages/circuit-status.js.map
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"circuit-status.js","sourceRoot":"","sources":["../../messages/circuit-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,YAAY,EAAE,MAAM,cAAc,CAAC;AAEnE;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,GAAG,CAAC,OAAO,GAAG,cAAc,CAAC;IAC7B,GAAG,CAAC,SAAS,GAAG,kBAAkB,CAAC;IACnC,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,QAAQ;QACR,QAAQ;QACR,QAAQ;QACR,QAAQ;QACR,MAAM;QACN,OAAO;QACP,OAAO;QACP,QAAQ;QACR,QAAQ;QACR,OAAO;QACP,MAAM;QACN,OAAO;QACP,OAAO;QACP,OAAO;QACP,KAAK;QACL,QAAQ;KACT,CAAC;IACF,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE5B,OAAO,GAAG,CAAC;AACb,CAAC"}
|
10
dist/messages/configuration.d.ts
vendored
10
dist/messages/configuration.d.ts
vendored
@ -3,12 +3,12 @@ import { ICRequest } from "./request.js";
|
||||
* Requests the configuration of bodies and circuits available to this controller.
|
||||
*
|
||||
* The response contains the list of bodies and circuits under the `answer` field.
|
||||
* Each item has an `objnam` that should be used to reference that item for future requests,
|
||||
* and `params`.`SNAME` is the user-entered friendly name that can be displayed for the item.
|
||||
* `params`.`OBJTYP` will be either BODY or CIRCUIT depending on the item it's describing.
|
||||
* Each object has an `objnam` that should be used to reference that object for future requests,
|
||||
* and `params`.`SNAME` is the user-entered friendly name that can be displayed for the object.
|
||||
* `params`.`OBJTYP` will be either BODY or CIRCUIT depending on the object it's describing.
|
||||
*
|
||||
* Some items, such as the Pool body, will have the `params`.`OBJLIST` array populated with
|
||||
* a series of attached items such as a chlorinator device.
|
||||
* Some objects, such as the Pool body, will have the `params`.`OBJLIST` array populated with
|
||||
* a series of attached objects such as a chlorinator device.
|
||||
*
|
||||
* @returns the object used to issue this request
|
||||
*/
|
||||
|
10
dist/messages/configuration.js
vendored
10
dist/messages/configuration.js
vendored
@ -3,12 +3,12 @@ import { GetRequest } from "./request.js";
|
||||
* Requests the configuration of bodies and circuits available to this controller.
|
||||
*
|
||||
* The response contains the list of bodies and circuits under the `answer` field.
|
||||
* Each item has an `objnam` that should be used to reference that item for future requests,
|
||||
* and `params`.`SNAME` is the user-entered friendly name that can be displayed for the item.
|
||||
* `params`.`OBJTYP` will be either BODY or CIRCUIT depending on the item it's describing.
|
||||
* Each object has an `objnam` that should be used to reference that object for future requests,
|
||||
* and `params`.`SNAME` is the user-entered friendly name that can be displayed for the object.
|
||||
* `params`.`OBJTYP` will be either BODY or CIRCUIT depending on the object it's describing.
|
||||
*
|
||||
* Some items, such as the Pool body, will have the `params`.`OBJLIST` array populated with
|
||||
* a series of attached items such as a chlorinator device.
|
||||
* Some objects, such as the Pool body, will have the `params`.`OBJLIST` array populated with
|
||||
* a series of attached objects such as a chlorinator device.
|
||||
*
|
||||
* @returns the object used to issue this request
|
||||
*/
|
||||
|
6
dist/messages/messages.d.ts
vendored
6
dist/messages/messages.d.ts
vendored
@ -1,22 +1,24 @@
|
||||
import { GetBodyStatus } from "./body-status.js";
|
||||
import { GetChemicalStatus } from "./chem-status.js";
|
||||
import { GetCircuitStatus } from "./circuit-status.js";
|
||||
import { GetSystemConfiguration } from "./configuration.js";
|
||||
import { GetHeaters } from "./get-heater.js";
|
||||
import { SubscribeToUpdates } from "./notify.js";
|
||||
import { GetSchedule } from "./schedule.js";
|
||||
import { SetHeatMode } from "./set-heater.js";
|
||||
import { SetItemStatus } from "./set-status.js";
|
||||
import { SetObjectStatus } from "./set-object-status.js";
|
||||
import { SetSetpoint } from "./setpoint.js";
|
||||
import { GetSystemInformation } from "./system-info.js";
|
||||
export declare const messages: {
|
||||
GetBodyStatus: typeof GetBodyStatus;
|
||||
GetChemicalStatus: typeof GetChemicalStatus;
|
||||
GetCircuitStatus: typeof GetCircuitStatus;
|
||||
GetHeaters: typeof GetHeaters;
|
||||
GetSchedule: typeof GetSchedule;
|
||||
GetSystemConfiguration: typeof GetSystemConfiguration;
|
||||
GetSystemInformation: typeof GetSystemInformation;
|
||||
SetHeatMode: typeof SetHeatMode;
|
||||
SetItemStatus: typeof SetItemStatus;
|
||||
SetObjectStatus: typeof SetObjectStatus;
|
||||
SetSetpoint: typeof SetSetpoint;
|
||||
SubscribeToUpdates: typeof SubscribeToUpdates;
|
||||
};
|
||||
|
6
dist/messages/messages.js
vendored
6
dist/messages/messages.js
vendored
@ -1,22 +1,24 @@
|
||||
import { GetBodyStatus } from "./body-status.js";
|
||||
import { GetChemicalStatus } from "./chem-status.js";
|
||||
import { GetCircuitStatus } from "./circuit-status.js";
|
||||
import { GetSystemConfiguration } from "./configuration.js";
|
||||
import { GetHeaters } from "./get-heater.js";
|
||||
import { SubscribeToUpdates } from "./notify.js";
|
||||
import { GetSchedule } from "./schedule.js";
|
||||
import { SetHeatMode } from "./set-heater.js";
|
||||
import { SetItemStatus } from "./set-status.js";
|
||||
import { SetObjectStatus } from "./set-object-status.js";
|
||||
import { SetSetpoint } from "./setpoint.js";
|
||||
import { GetSystemInformation } from "./system-info.js";
|
||||
export const messages = {
|
||||
GetBodyStatus,
|
||||
GetChemicalStatus,
|
||||
GetCircuitStatus,
|
||||
GetHeaters,
|
||||
GetSchedule,
|
||||
GetSystemConfiguration,
|
||||
GetSystemInformation,
|
||||
SetHeatMode,
|
||||
SetItemStatus,
|
||||
SetObjectStatus,
|
||||
SetSetpoint,
|
||||
SubscribeToUpdates,
|
||||
};
|
||||
|
2
dist/messages/messages.js.map
vendored
2
dist/messages/messages.js.map
vendored
@ -1 +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,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,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,WAAW;IACX,sBAAsB;IACtB,oBAAoB;IACpB,WAAW;IACX,aAAa;IACb,WAAW;IACX,kBAAkB;CACnB,CAAC"}
|
||||
{"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,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,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,gBAAgB;IAChB,UAAU;IACV,WAAW;IACX,sBAAsB;IACtB,oBAAoB;IACpB,WAAW;IACX,eAAe;IACf,WAAW;IACX,kBAAkB;CACnB,CAAC"}
|
9
dist/messages/set-object-status.d.ts
vendored
Normal file
9
dist/messages/set-object-status.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
import { ICRequest } from "./request.js";
|
||||
/**
|
||||
* Requests to change the status of objects known to this controller.
|
||||
*
|
||||
* Turns one or more objects on or off. Use the `objnam` of the circuit to be set.
|
||||
*
|
||||
* @returns the object used to issue this request
|
||||
*/
|
||||
export declare function SetObjectStatus(object: string | string[], status: boolean): ICRequest;
|
@ -1,24 +1,24 @@
|
||||
import { ICParam } from "./param.js";
|
||||
import { GetRequest, ICRequestObj } from "./request.js";
|
||||
/**
|
||||
* Requests to change the status of items known to this controller.
|
||||
* Requests to change the status of objects known to this controller.
|
||||
*
|
||||
* Turns one or more items on or off. Use the `objnam` of the circuit to be set.
|
||||
* Turns one or more objects on or off. Use the `objnam` of the circuit to be set.
|
||||
*
|
||||
* @returns the object used to issue this request
|
||||
*/
|
||||
export function SetItemStatus(item, status) {
|
||||
export function SetObjectStatus(object, status) {
|
||||
const req = GetRequest();
|
||||
req.command = "SetParamList";
|
||||
req.objectList = [];
|
||||
let items;
|
||||
if (Array.isArray(item)) {
|
||||
items = item;
|
||||
let objects;
|
||||
if (Array.isArray(object)) {
|
||||
objects = object;
|
||||
}
|
||||
else {
|
||||
items = [item];
|
||||
objects = [object];
|
||||
}
|
||||
for (const i of items) {
|
||||
for (const i of objects) {
|
||||
const reqObj = new ICRequestObj();
|
||||
reqObj.objnam = i;
|
||||
reqObj.params = new ICParam();
|
||||
@ -27,4 +27,4 @@ export function SetItemStatus(item, status) {
|
||||
}
|
||||
return req;
|
||||
}
|
||||
//# sourceMappingURL=set-status.js.map
|
||||
//# sourceMappingURL=set-object-status.js.map
|
1
dist/messages/set-object-status.js.map
vendored
Normal file
1
dist/messages/set-object-status.js.map
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"set-object-status.js","sourceRoot":"","sources":["../../messages/set-object-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,eAAe,CAC7B,MAAyB,EACzB,MAAe;IAEf,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,GAAG,CAAC,OAAO,GAAG,cAAc,CAAC;IAC7B,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC;IAEpB,IAAI,OAAiB,CAAC;IACtB,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,OAAO,GAAG,MAAM,CAAC;IACnB,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC;IACrB,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,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"}
|
9
dist/messages/set-status.d.ts
vendored
9
dist/messages/set-status.d.ts
vendored
@ -1,9 +0,0 @@
|
||||
import { ICRequest } from "./request.js";
|
||||
/**
|
||||
* Requests to change the status of items known to this controller.
|
||||
*
|
||||
* 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 | string[], status: boolean): ICRequest;
|
1
dist/messages/set-status.js.map
vendored
1
dist/messages/set-status.js.map
vendored
@ -1 +0,0 @@
|
||||
{"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"}
|
7
dist/unit.d.ts
vendored
7
dist/unit.d.ts
vendored
@ -5,11 +5,18 @@ import { ICResponse } from "./messages/response.js";
|
||||
* Contains methods to connect to and communicate with an IntelliCenter controller.
|
||||
*
|
||||
* Call `connect` to connect to the unit.
|
||||
* Use `send` to send a message.
|
||||
* Subscribe to events to process socket conditions, notify updates, and message responses (if not `await`ing the response)
|
||||
*
|
||||
* Available events:
|
||||
*
|
||||
* * `"response-{messageID}"` - fired once per message sent with `send()` where {messageID} is the ID specified in the {@linkcode ICRequest} given to `send()`
|
||||
* * `"notify"` - fired when an update is available to a property previously subscribed to via a {@linkcode SubscribeToUpdates} request
|
||||
* * `"close"` - fired any time the client is closed by any means (timeout, by request, error, etc.)
|
||||
* * `"open"` - fired when the socket connects to the unit successfully
|
||||
* * `"error"` - fired when the socket encounters an unrecoverable error and will close
|
||||
* * `"timeout"` - fired when the socket has not received a ping response within the allowed threshold and will close
|
||||
* * `"connected"` - fired when a connection has completed successfully
|
||||
*/
|
||||
export declare class Unit extends EventEmitter {
|
||||
endpoint: string;
|
||||
|
28
dist/unit.js
vendored
28
dist/unit.js
vendored
@ -6,11 +6,18 @@ const debugUnit = debug("ic:unit");
|
||||
* Contains methods to connect to and communicate with an IntelliCenter controller.
|
||||
*
|
||||
* Call `connect` to connect to the unit.
|
||||
* Use `send` to send a message.
|
||||
* Subscribe to events to process socket conditions, notify updates, and message responses (if not `await`ing the response)
|
||||
*
|
||||
* Available events:
|
||||
*
|
||||
* * `"response-{messageID}"` - fired once per message sent with `send()` where {messageID} is the ID specified in the {@linkcode ICRequest} given to `send()`
|
||||
* * `"notify"` - fired when an update is available to a property previously subscribed to via a {@linkcode SubscribeToUpdates} request
|
||||
* * `"close"` - fired any time the client is closed by any means (timeout, by request, error, etc.)
|
||||
* * `"open"` - fired when the socket connects to the unit successfully
|
||||
* * `"error"` - fired when the socket encounters an unrecoverable error and will close
|
||||
* * `"timeout"` - fired when the socket has not received a ping response within the allowed threshold and will close
|
||||
* * `"connected"` - fired when a connection has completed successfully
|
||||
*/
|
||||
export class Unit extends EventEmitter {
|
||||
endpoint;
|
||||
@ -39,9 +46,13 @@ export class Unit extends EventEmitter {
|
||||
this.client.on("error", (evt) => {
|
||||
// todo: emit event so we can reconnect? auto reconnect?
|
||||
debugUnit("error in websocket: $o", evt);
|
||||
this.emit("error");
|
||||
socketCleanup();
|
||||
});
|
||||
this.client.on("open", heartbeat);
|
||||
this.client.on("open", () => {
|
||||
this.emit("open");
|
||||
heartbeat();
|
||||
});
|
||||
this.client.on("ping", heartbeat);
|
||||
this.client.on("pong", heartbeat);
|
||||
this.client.on("close", socketCleanup);
|
||||
@ -55,13 +66,18 @@ export class Unit extends EventEmitter {
|
||||
this.client?.once("open", resolve);
|
||||
});
|
||||
debugUnit("connected");
|
||||
this.emit("connected");
|
||||
}
|
||||
/**
|
||||
* Closes the connection to the unit.
|
||||
*/
|
||||
close() {
|
||||
if (!this.client) {
|
||||
return;
|
||||
}
|
||||
debugUnit("closing connection by request");
|
||||
this.client?.close();
|
||||
this.emit("close");
|
||||
this.client.close();
|
||||
}
|
||||
socketCleanup = () => {
|
||||
debugUnit("socket cleanup");
|
||||
@ -81,6 +97,7 @@ export class Unit extends EventEmitter {
|
||||
clearTimeout(this.pingTimeout);
|
||||
this.pingTimeout = setTimeout(() => {
|
||||
debugUnit("terminating connection due to heartbeat timeout");
|
||||
this.emit("timeout");
|
||||
this.client?.terminate();
|
||||
this.socketCleanup();
|
||||
}, this.pingInterval + 5000);
|
||||
@ -101,9 +118,14 @@ export class Unit extends EventEmitter {
|
||||
* @returns a promise that resolves into the {@linkcode ICResponse} with information about the request.
|
||||
*/
|
||||
async send(request) {
|
||||
if (!this.client) {
|
||||
return await new Promise(() => {
|
||||
throw new Error("client not connected");
|
||||
});
|
||||
}
|
||||
const payload = JSON.stringify(request);
|
||||
debugUnit("sending message of length %d with id %s", payload.length, request.messageID);
|
||||
this.client?.send(payload);
|
||||
this.client.send(payload);
|
||||
return await new Promise((resolve) => {
|
||||
this.once(`response-${request.messageID}`, (resp) => {
|
||||
debugUnit(" returning response to message %s", request.messageID);
|
||||
|
2
dist/unit.js.map
vendored
2
dist/unit.js.map
vendored
@ -1 +1 @@
|
||||
{"version":3,"file":"unit.js","sourceRoot":"","sources":["../unit.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"unit.js","sourceRoot":"","sources":["../unit.ts"],"names":[],"mappings":"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"}
|
85
example.ts
Normal file
85
example.ts
Normal file
@ -0,0 +1,85 @@
|
||||
"use strict";
|
||||
|
||||
import { FindUnits, Unit } from "./index.js";
|
||||
import { messages } from "./messages/messages.js";
|
||||
|
||||
console.log("searching...");
|
||||
const f = new FindUnits();
|
||||
const units = await f.searchAsync(1000);
|
||||
f.close();
|
||||
console.log("Discovered units:", units);
|
||||
|
||||
if (units.length === 0) {
|
||||
throw new Error("no IntelliCenter units found, exiting.");
|
||||
}
|
||||
|
||||
if (units.length > 1) {
|
||||
throw new Error(
|
||||
`found more than one IntelliCenter unit, unsure which one to use. ${JSON.stringify(units)}`,
|
||||
);
|
||||
}
|
||||
|
||||
const endpoint = units[0].addressStr;
|
||||
const port = units[0].port;
|
||||
|
||||
// const endpoint = "10.0.0.41";
|
||||
// const port = 6680;
|
||||
|
||||
console.log("connecting to intellicenter device at", endpoint, "port", port);
|
||||
const unit = new Unit(endpoint, port);
|
||||
await unit.connect();
|
||||
console.log("connected");
|
||||
|
||||
unit.on("notify", (msg) => {
|
||||
console.log("received notify:", msg);
|
||||
});
|
||||
|
||||
console.log("subscribing for updates...");
|
||||
let resp = await unit.send(messages.SubscribeToUpdates("B1202", "LOTMP"));
|
||||
console.log("got response:", JSON.stringify(resp, null, 2));
|
||||
|
||||
console.log("sending Get System Info request...");
|
||||
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(messages.GetSystemConfiguration());
|
||||
console.log("got response:", JSON.stringify(resp, null, 2));
|
||||
|
||||
console.log("sending Get Body Status request...");
|
||||
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 Get Schedule request...");
|
||||
resp = await unit.send(messages.GetSchedule());
|
||||
console.log("got response:", JSON.stringify(resp, null, 2));
|
||||
|
||||
console.log("sending Get Circuit Status request...");
|
||||
resp = await unit.send(messages.GetCircuitStatus());
|
||||
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(messages.SetObjectStatus("B1101", false));
|
||||
// console.log("got response:", JSON.stringify(resp, null, 2));
|
||||
|
||||
// console.log("turning off water feature...");
|
||||
// resp = await unit.send(messages.SetObjectStatus("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();
|
10
finder.ts
10
finder.ts
@ -51,7 +51,12 @@ export class UnitInfo {
|
||||
* * `"serverFound"` - fired immediately when an IntelliCenter unit has been located; receives a {@linkcode UnitInfo} argument
|
||||
*/
|
||||
export class FindUnits extends EventEmitter {
|
||||
constructor() {
|
||||
/**
|
||||
* Creates a new finder.
|
||||
*
|
||||
* @param broadcastInterface the address of the interface to send the broadcast to. If not specified, will use system selection. Only necessary if you have more than one network adapter/interface and want to search on a specific one.
|
||||
*/
|
||||
constructor(public broadcastInterface?: string) {
|
||||
super();
|
||||
|
||||
// construct mDNS packet to ping for intellicenter controllers
|
||||
@ -76,6 +81,9 @@ export class FindUnits extends EventEmitter {
|
||||
this.finder = createSocket("udp4");
|
||||
this.finder
|
||||
.on("listening", () => {
|
||||
if (this.broadcastInterface) {
|
||||
this.finder.setMulticastInterface(this.broadcastInterface);
|
||||
}
|
||||
this.finder.setBroadcast(true);
|
||||
this.finder.setMulticastTTL(128);
|
||||
|
||||
|
80
index.ts
80
index.ts
@ -1,82 +1,4 @@
|
||||
"use strict";
|
||||
|
||||
import { FindUnits } from "./finder.js";
|
||||
import { messages } from "./messages/messages.js";
|
||||
import { Unit } from "./unit.js";
|
||||
|
||||
console.log("searching...");
|
||||
const f = new FindUnits();
|
||||
const units = await f.searchAsync(1000);
|
||||
f.close();
|
||||
console.log("Discovered units:", units);
|
||||
|
||||
if (units.length === 0) {
|
||||
throw new Error("no IntelliCenter units found, exiting.");
|
||||
}
|
||||
|
||||
if (units.length > 1) {
|
||||
throw new Error(
|
||||
`found more than one IntelliCenter unit, unsure which one to use. ${JSON.stringify(units)}`,
|
||||
);
|
||||
}
|
||||
|
||||
const endpoint = units[0].addressStr;
|
||||
const port = units[0].port;
|
||||
|
||||
// const endpoint = "10.0.0.41";
|
||||
// const port = 6680;
|
||||
|
||||
console.log("connecting to intellicenter device at", endpoint, "port", port);
|
||||
const unit = new Unit(endpoint, port);
|
||||
await unit.connect();
|
||||
console.log("connected");
|
||||
|
||||
unit.on("notify", (msg) => {
|
||||
console.log("received notify:", msg);
|
||||
});
|
||||
|
||||
console.log("subscribing for updates...");
|
||||
let resp = await unit.send(messages.SubscribeToUpdates("B1202", "LOTMP"));
|
||||
console.log("got response:", JSON.stringify(resp, null, 2));
|
||||
|
||||
console.log("sending Get System Info request...");
|
||||
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(messages.GetSystemConfiguration());
|
||||
console.log("got response:", JSON.stringify(resp, null, 2));
|
||||
|
||||
console.log("sending Get Body Status request...");
|
||||
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 Get Schedule request...");
|
||||
resp = await unit.send(messages.GetSchedule());
|
||||
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(messages.SetItemStatus("B1101", false));
|
||||
// console.log("got response:", JSON.stringify(resp, null, 2));
|
||||
|
||||
// console.log("turning off water feature...");
|
||||
// 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();
|
||||
export { FindUnits, Unit };
|
||||
|
39
messages/circuit-status.ts
Normal file
39
messages/circuit-status.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { GetRequest, ICRequest, ICRequestObj } from "./request.js";
|
||||
|
||||
/**
|
||||
* Requests the list of circuits known to this controller.
|
||||
*
|
||||
* The response contains an `objectList` populated with circuit information.
|
||||
*
|
||||
* @returns the object used to issue this request
|
||||
*/
|
||||
export function GetCircuitStatus(): ICRequest {
|
||||
const req = GetRequest();
|
||||
req.command = "GetParamList";
|
||||
req.condition = "OBJTYP = CIRCUIT";
|
||||
req.objectList = [];
|
||||
|
||||
const reqObj = new ICRequestObj();
|
||||
reqObj.objnam = "ALL";
|
||||
reqObj.keys = [
|
||||
"OBJNAM",
|
||||
"OBJTYP",
|
||||
"SUBTYP",
|
||||
"STATUS",
|
||||
"BODY",
|
||||
"SNAME",
|
||||
"HNAME",
|
||||
"FREEZE",
|
||||
"DNTSTP",
|
||||
"HNAME",
|
||||
"TIME",
|
||||
"FEATR",
|
||||
"USAGE",
|
||||
"LIMIT",
|
||||
"USE",
|
||||
"SHOMNU",
|
||||
];
|
||||
req.objectList.push(reqObj);
|
||||
|
||||
return req;
|
||||
}
|
@ -4,12 +4,12 @@ import { GetRequest, ICRequest } from "./request.js";
|
||||
* Requests the configuration of bodies and circuits available to this controller.
|
||||
*
|
||||
* The response contains the list of bodies and circuits under the `answer` field.
|
||||
* Each item has an `objnam` that should be used to reference that item for future requests,
|
||||
* and `params`.`SNAME` is the user-entered friendly name that can be displayed for the item.
|
||||
* `params`.`OBJTYP` will be either BODY or CIRCUIT depending on the item it's describing.
|
||||
* Each object has an `objnam` that should be used to reference that object for future requests,
|
||||
* and `params`.`SNAME` is the user-entered friendly name that can be displayed for the object.
|
||||
* `params`.`OBJTYP` will be either BODY or CIRCUIT depending on the object it's describing.
|
||||
*
|
||||
* Some items, such as the Pool body, will have the `params`.`OBJLIST` array populated with
|
||||
* a series of attached items such as a chlorinator device.
|
||||
* Some objects, such as the Pool body, will have the `params`.`OBJLIST` array populated with
|
||||
* a series of attached objects such as a chlorinator device.
|
||||
*
|
||||
* @returns the object used to issue this request
|
||||
*/
|
||||
|
@ -1,23 +1,25 @@
|
||||
import { GetBodyStatus } from "./body-status.js";
|
||||
import { GetChemicalStatus } from "./chem-status.js";
|
||||
import { GetCircuitStatus } from "./circuit-status.js";
|
||||
import { GetSystemConfiguration } from "./configuration.js";
|
||||
import { GetHeaters } from "./get-heater.js";
|
||||
import { SubscribeToUpdates } from "./notify.js";
|
||||
import { GetSchedule } from "./schedule.js";
|
||||
import { SetHeatMode } from "./set-heater.js";
|
||||
import { SetItemStatus } from "./set-status.js";
|
||||
import { SetObjectStatus } from "./set-object-status.js";
|
||||
import { SetSetpoint } from "./setpoint.js";
|
||||
import { GetSystemInformation } from "./system-info.js";
|
||||
|
||||
export const messages = {
|
||||
GetBodyStatus,
|
||||
GetChemicalStatus,
|
||||
GetCircuitStatus,
|
||||
GetHeaters,
|
||||
GetSchedule,
|
||||
GetSystemConfiguration,
|
||||
GetSystemInformation,
|
||||
SetHeatMode,
|
||||
SetItemStatus,
|
||||
SetObjectStatus,
|
||||
SetSetpoint,
|
||||
SubscribeToUpdates,
|
||||
};
|
||||
|
@ -2,28 +2,28 @@ import { ICParam } from "./param.js";
|
||||
import { GetRequest, ICRequest, ICRequestObj } from "./request.js";
|
||||
|
||||
/**
|
||||
* Requests to change the status of items known to this controller.
|
||||
* Requests to change the status of objects known to this controller.
|
||||
*
|
||||
* Turns one or more items on or off. Use the `objnam` of the circuit to be set.
|
||||
* Turns one or more objects 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 | string[],
|
||||
export function SetObjectStatus(
|
||||
object: string | string[],
|
||||
status: boolean,
|
||||
): ICRequest {
|
||||
const req = GetRequest();
|
||||
req.command = "SetParamList";
|
||||
req.objectList = [];
|
||||
|
||||
let items: string[];
|
||||
if (Array.isArray(item)) {
|
||||
items = item;
|
||||
let objects: string[];
|
||||
if (Array.isArray(object)) {
|
||||
objects = object;
|
||||
} else {
|
||||
items = [item];
|
||||
objects = [object];
|
||||
}
|
||||
|
||||
for (const i of items) {
|
||||
for (const i of objects) {
|
||||
const reqObj = new ICRequestObj();
|
||||
reqObj.objnam = i;
|
||||
reqObj.params = new ICParam();
|
927
package-lock.json
generated
927
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
16
package.json
16
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "node-intellicenter",
|
||||
"version": "0.0.1",
|
||||
"version": "0.1.0",
|
||||
"description": "NodeJS library for communicating with a Pentair IntelliCenter controller",
|
||||
"keywords": [
|
||||
"pentair",
|
||||
@ -21,13 +21,18 @@
|
||||
"license": "MIT",
|
||||
"author": "Parnic",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"exports": {
|
||||
".": "./dist/index.js",
|
||||
"./unit": "./dist/unit.js",
|
||||
"./finder": "./dist/finder.js",
|
||||
"./messages": "./dist/messages/messages.js"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build": "tsc",
|
||||
"index": "tsc && node dist/index.js",
|
||||
"lint": "eslint . && prettier . --check"
|
||||
"example": "tsc && node dist/example.js",
|
||||
"lint": "eslint . && prettier . --check && markdownlint-cli2 **/*.md",
|
||||
"lint:fix": "eslint . --fix && prettier . --write && markdownlint-cli2 --fix **/*.md"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": "^4.4.0",
|
||||
@ -39,6 +44,7 @@
|
||||
"@types/debug": "^4.1.12",
|
||||
"@types/ws": "^8.5.13",
|
||||
"eslint": "^9.17.0",
|
||||
"markdownlint-cli2": "^0.17.1",
|
||||
"prettier": "3.4.2",
|
||||
"supports-color": "^10.0.0",
|
||||
"typescript": "^5.7.2",
|
||||
|
30
unit.ts
30
unit.ts
@ -16,11 +16,18 @@ const debugUnit = debug("ic:unit");
|
||||
* Contains methods to connect to and communicate with an IntelliCenter controller.
|
||||
*
|
||||
* Call `connect` to connect to the unit.
|
||||
* Use `send` to send a message.
|
||||
* Subscribe to events to process socket conditions, notify updates, and message responses (if not `await`ing the response)
|
||||
*
|
||||
* Available events:
|
||||
*
|
||||
* * `"response-{messageID}"` - fired once per message sent with `send()` where {messageID} is the ID specified in the {@linkcode ICRequest} given to `send()`
|
||||
* * `"notify"` - fired when an update is available to a property previously subscribed to via a {@linkcode SubscribeToUpdates} request
|
||||
* * `"close"` - fired any time the client is closed by any means (timeout, by request, error, etc.)
|
||||
* * `"open"` - fired when the socket connects to the unit successfully
|
||||
* * `"error"` - fired when the socket encounters an unrecoverable error and will close
|
||||
* * `"timeout"` - fired when the socket has not received a ping response within the allowed threshold and will close
|
||||
* * `"connected"` - fired when a connection has completed successfully
|
||||
*/
|
||||
export class Unit extends EventEmitter {
|
||||
private client?: WebSocket;
|
||||
@ -56,9 +63,13 @@ export class Unit extends EventEmitter {
|
||||
this.client.on("error", (evt) => {
|
||||
// todo: emit event so we can reconnect? auto reconnect?
|
||||
debugUnit("error in websocket: $o", evt);
|
||||
this.emit("error");
|
||||
socketCleanup();
|
||||
});
|
||||
this.client.on("open", heartbeat);
|
||||
this.client.on("open", () => {
|
||||
this.emit("open");
|
||||
heartbeat();
|
||||
});
|
||||
this.client.on("ping", heartbeat);
|
||||
this.client.on("pong", heartbeat);
|
||||
this.client.on("close", socketCleanup);
|
||||
@ -75,14 +86,20 @@ export class Unit extends EventEmitter {
|
||||
});
|
||||
|
||||
debugUnit("connected");
|
||||
this.emit("connected");
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the connection to the unit.
|
||||
*/
|
||||
public close() {
|
||||
if (!this.client) {
|
||||
return;
|
||||
}
|
||||
|
||||
debugUnit("closing connection by request");
|
||||
this.client?.close();
|
||||
this.emit("close");
|
||||
this.client.close();
|
||||
}
|
||||
|
||||
private socketCleanup = () => {
|
||||
@ -108,6 +125,7 @@ export class Unit extends EventEmitter {
|
||||
|
||||
this.pingTimeout = setTimeout(() => {
|
||||
debugUnit("terminating connection due to heartbeat timeout");
|
||||
this.emit("timeout");
|
||||
this.client?.terminate();
|
||||
this.socketCleanup();
|
||||
}, this.pingInterval + 5000);
|
||||
@ -132,6 +150,12 @@ export class Unit extends EventEmitter {
|
||||
* @returns a promise that resolves into the {@linkcode ICResponse} with information about the request.
|
||||
*/
|
||||
public async send(request: ICRequest): Promise<ICResponse> {
|
||||
if (!this.client) {
|
||||
return await new Promise(() => {
|
||||
throw new Error("client not connected");
|
||||
});
|
||||
}
|
||||
|
||||
const payload = JSON.stringify(request);
|
||||
debugUnit(
|
||||
"sending message of length %d with id %s",
|
||||
@ -139,7 +163,7 @@ export class Unit extends EventEmitter {
|
||||
request.messageID,
|
||||
);
|
||||
|
||||
this.client?.send(payload);
|
||||
this.client.send(payload);
|
||||
return await new Promise((resolve) => {
|
||||
this.once(`response-${request.messageID}`, (resp: ICResponse) => {
|
||||
debugUnit(" returning response to message %s", request.messageID);
|
||||
|
Reference in New Issue
Block a user