├── dist
├── example.d.ts
├── messages
│ ├── SLGatewayDataMessage.d.ts
│ ├── config
│ │ ├── HeaterMessage.d.ts
│ │ ├── CircuitMessage.d.ts
│ │ ├── HeaterMessage.js.map
│ │ ├── CircuitMessage.js.map
│ │ ├── ScheduleMessage.d.ts
│ │ ├── HeaterMessage.js
│ │ ├── CircuitMessage.js
│ │ ├── ScheduleMessage.js.map
│ │ ├── ScheduleMessage.js
│ │ └── EquipmentConfig.d.ts
│ ├── state
│ │ ├── ChlorMessage.d.ts
│ │ ├── PumpMessage.d.ts
│ │ ├── ChlorMessage.js.map
│ │ ├── ChemMessage.d.ts
│ │ ├── PumpMessage.js.map
│ │ ├── ChlorMessage.js
│ │ ├── PumpMessage.js
│ │ ├── EquipmentState.d.ts
│ │ ├── ChemMessage.js.map
│ │ ├── ChemMessage.js
│ │ └── EquipmentState.js.map
│ ├── SLGatewayDataMessage.js.map
│ ├── ConnectionMessage.d.ts
│ ├── SLGatewayDataMessage.js
│ ├── ConnectionMessage.js.map
│ ├── SLMessage.d.ts
│ ├── ConnectionMessage.js
│ ├── OutgoingMessages.d.ts
│ ├── SLMessage.js.map
│ ├── SLMessage.js
│ ├── OutgoingMessages.js.map
│ └── OutgoingMessages.js
├── utils
│ └── PasswordEncoder.d.ts
├── example.js.map
├── example.js
└── index.d.ts
├── .eslintignore
├── .markdownlint.json
├── test
├── find.spec.js
├── password.spec.js
├── unit.spec.js
└── slmessage.spec.js
├── tsconfig.json
├── .eslintrc.json
├── .github
└── workflows
│ ├── nodejs.yml
│ └── codeql-analysis.yml
├── messages
├── config
│ ├── HeaterMessage.ts
│ ├── CircuitMessage.ts
│ └── ScheduleMessage.ts
├── state
│ ├── ChlorMessage.ts
│ ├── PumpMessage.ts
│ └── ChemMessage.ts
├── ConnectionMessage.ts
├── SLGatewayDataMessage.ts
├── SLMessage.ts
└── OutgoingMessages.ts
├── LICENSE
├── .gitignore
├── package.json
├── example.ts
├── .vscode
└── launch.json
└── CHANGELOG.md
/dist/example.d.ts:
--------------------------------------------------------------------------------
1 | export {};
2 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | **/test/*.js
2 | **/dist/*.js
3 | **/*.d.ts
4 | test/
5 | dist/
6 | **/*.js
--------------------------------------------------------------------------------
/.markdownlint.json:
--------------------------------------------------------------------------------
1 | {
2 | "default": true,
3 | "no-duplicate-header": {
4 | "siblings_only": true
5 | },
6 | "line-length": false
7 | }
8 |
--------------------------------------------------------------------------------
/test/find.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const ScreenLogic = require('../dist/index');
4 |
5 | // you'll need a ScreenLogic-enabled device on your network for this to succeed
6 | describe('Finder', function() {
7 | it('finds a server', function(done) {
8 | let finder = new ScreenLogic.FindUnits();
9 | finder.on('serverFound', server => {
10 | finder.close();
11 | done();
12 | });
13 | finder.search();
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowJs": false,
4 | "noImplicitAny": true,
5 | "module": "commonjs",
6 | "noEmitOnError": true,
7 | "removeComments": false,
8 | "sourceMap": true,
9 | "target": "ES2018",
10 | "preserveConstEnums": true,
11 | "outDir": "dist",
12 | "declaration": true
13 | },
14 | "include": ["messages/**/*.ts", "*.ts", "index.ts", "utils/**/*.ts"],
15 | "exclude": [
16 | "node_modules"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/dist/messages/SLGatewayDataMessage.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | import { Inbound } from './SLMessage';
3 | export declare class SLReceiveGatewayDataMessage extends Inbound {
4 | private data;
5 | constructor(buf: Buffer);
6 | decode(): void;
7 | get(): SLGateWayData;
8 | }
9 | export interface SLGateWayData {
10 | gatewayFound: boolean;
11 | licenseOK: boolean;
12 | ipAddr: string;
13 | port: number;
14 | portOpen: boolean;
15 | relayOn: boolean;
16 | }
17 |
--------------------------------------------------------------------------------
/dist/messages/config/HeaterMessage.d.ts:
--------------------------------------------------------------------------------
1 | import { Inbound, SLSimpleBoolData } from '../SLMessage';
2 | export declare class HeaterMessage {
3 | static decodeSetHeatSetPoint(msg: Inbound): SLSimpleBoolData;
4 | static decodeCoolSetHeatSetPoint(msg: Inbound): SLSimpleBoolData;
5 | static decodeSetHeatModePoint(msg: Inbound): SLSimpleBoolData;
6 | }
7 | export declare namespace HeaterMessage {
8 | enum ResponseIDs {
9 | SetHeatSetPoint = 12529,
10 | SetHeatMode = 12539,
11 | SetCoolSetPoint = 12591
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/test/password.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const assert = require('assert');
4 | const HLEncoder = require('../dist/utils/PasswordEncoder').HLEncoder;
5 |
6 | describe('Password encoder', function() {
7 | it('encodes correctly', function() {
8 | let pw = new HLEncoder('1234').getEncryptedPassword('00-00-00-00-00-00');
9 | assert.equal(true, pw.equals(Buffer.from([0x4e, 0x71, 0x7f, 0x2e, 0xff, 0xda, 0xfd, 0x5d, 0xdf, 0x34, 0x26, 0x32, 0x23, 0xd7, 0x11, 0x06, 0x72, 0xbc, 0x40, 0x0f, 0x61, 0x81, 0x9f, 0xc8, 0x84, 0xcc, 0x6b, 0xaa, 0x0b, 0x16, 0x77, 0xab])));
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/dist/utils/PasswordEncoder.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | export declare class HLEncoder {
3 | constructor(password: string);
4 | private kd;
5 | private ke;
6 | private tk;
7 | private bKeyInit;
8 | private iROUNDS;
9 | createArray(length: number, max_length: number): any[];
10 | getEncryptedPassword(cls: string): Buffer;
11 | makeKey(sChallengeStr: string[]): void;
12 | makeBlock(str: string[], byFill: number): any[];
13 | makeKeyFromBlock(block: number[]): void;
14 | encryptBlock(block: number[]): number[];
15 | encrypt(source: string[]): Buffer;
16 | encryptData(data: number[]): Buffer;
17 | }
18 |
--------------------------------------------------------------------------------
/dist/messages/config/CircuitMessage.d.ts:
--------------------------------------------------------------------------------
1 | import { Inbound, SLSimpleBoolData } from '../SLMessage';
2 | export declare class CircuitMessage {
3 | static decodeSetCircuit(msg: Inbound): SLSimpleBoolData;
4 | static decodeSetCircuitState(msg: Inbound): SLSimpleBoolData;
5 | static decodeSetLight(msg: Inbound): SLSimpleBoolData;
6 | static decodeSetCircuitRunTime(msg: Inbound): SLSimpleBoolData;
7 | }
8 | export declare namespace CircuitMessage {
9 | enum ResponseIDs {
10 | LightSequence = 12504,
11 | SetCircuitInfo = 12521,
12 | SetCircuitState = 12531,
13 | SetCircuitRunTime = 12551,
14 | SetLightState = 12557
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/dist/messages/state/ChlorMessage.d.ts:
--------------------------------------------------------------------------------
1 | import { Inbound, SLData, SLSimpleBoolData } from '../SLMessage';
2 | export declare class ChlorMessage {
3 | static decodeIntellichlorConfig(msg: Inbound): SLIntellichlorData;
4 | static decodeSetIntellichlorConfig(msg: Inbound): SLSimpleBoolData;
5 | static decodeSetEnableIntellichlorConfig(msg: Inbound): SLSimpleBoolData;
6 | }
7 | export declare namespace ChlorMessage {
8 | enum ResponseIDs {
9 | GetIntellichlorConfig = 12573,
10 | SetIntellichlorEnabled = 12575,
11 | SetIntellichlorConfig = 12577
12 | }
13 | }
14 | export interface SLIntellichlorData extends SLData {
15 | installed: boolean;
16 | status: number;
17 | poolSetPoint: number;
18 | spaSetPoint: number;
19 | salt: number;
20 | flags: number;
21 | superChlorTimer: number;
22 | }
23 |
--------------------------------------------------------------------------------
/dist/messages/config/HeaterMessage.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"HeaterMessage.js","sourceRoot":"","sources":["../../../messages/config/HeaterMessage.ts"],"names":[],"mappings":";;;AAEA,MAAa,aAAa;IACjB,MAAM,CAAC,qBAAqB,CAAC,GAAY;QAC9C,MAAM;QACN,MAAM,QAAQ,GAAqB;YACjC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,GAAG,EAAE,IAAI;SACV,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;IACM,MAAM,CAAC,yBAAyB,CAAC,GAAY;QAClD,MAAM;QACN,MAAM,QAAQ,GAAqB;YACjC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,GAAG,EAAE,IAAI;SACV,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;IACM,MAAM,CAAC,sBAAsB,CAAC,GAAY;QAC/C,MAAM;QACN,MAAM,QAAQ,GAAqB;YACjC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,GAAG,EAAE,IAAI;SACV,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF;AAzBD,sCAyBC;AAED,WAAiB,aAAa;IAC5B,IAAY,WAIX;IAJD,WAAY,WAAW;QACrB,uEAAuB,CAAA;QACvB,+DAAmB,CAAA;QACnB,uEAAuB,CAAA;IACzB,CAAC,EAJW,WAAW,GAAX,yBAAW,KAAX,yBAAW,QAItB;AACH,CAAC,EANgB,aAAa,GAAb,qBAAa,KAAb,qBAAa,QAM7B"}
--------------------------------------------------------------------------------
/dist/messages/state/PumpMessage.d.ts:
--------------------------------------------------------------------------------
1 | import { PumpTypes } from '../../index';
2 | import { Inbound, SLData, SLSimpleBoolData } from '../SLMessage';
3 | export declare class PumpMessage {
4 | static decodePumpStatus(msg: Inbound): SLPumpStatusData;
5 | static decodeSetPumpSpeed(msg: Inbound): SLSimpleBoolData;
6 | }
7 | export declare namespace PumpMessage {
8 | enum ResponseIDs {
9 | PumpStatus = 12585,
10 | SetPumpSpeed = 12587
11 | }
12 | }
13 | export interface SLPumpStatusData extends SLData {
14 | pumpCircuits: SLPumpCircuitData[];
15 | pumpType: PumpTypes;
16 | isRunning: boolean;
17 | pumpWatts: number;
18 | pumpRPMs: number;
19 | pumpUnknown1: number;
20 | pumpGPMs: number;
21 | pumpUnknown2: number;
22 | }
23 | export interface SLPumpCircuitData {
24 | circuitId: number;
25 | speed: number;
26 | isRPMs: boolean;
27 | }
28 |
--------------------------------------------------------------------------------
/dist/messages/SLGatewayDataMessage.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"SLGatewayDataMessage.js","sourceRoot":"","sources":["../../messages/SLGatewayDataMessage.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AAEb,2CAAsC;AAEtC,MAAa,2BAA4B,SAAQ,mBAAO;IAGtD,YAAY,GAAW;QACrB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACZ,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAGD,MAAM;QACJ,KAAK,CAAC,MAAM,EAAE,CAAC;QAEf,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACzD,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACpD,IAAI,CAAC,IAAI,GAAG;YACV,YAAY;YACZ,SAAS;YACT,MAAM;YACN,IAAI;YACJ,QAAQ;YACR,OAAO;SACR,CAAC;IAEJ,CAAC;IACD,GAAG;QACD,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;CACF;AAhCD,kEAgCC"}
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "es2021": true,
4 | "node": true,
5 | "mocha": true
6 | },
7 | "extends": [
8 | "eslint:recommended",
9 | "plugin:@typescript-eslint/recommended"
10 | ],
11 | "parser": "@typescript-eslint/parser",
12 | "parserOptions": {
13 | "ecmaVersion": "latest",
14 | "sourceType": "module"
15 | },
16 | "plugins": [
17 | "@typescript-eslint"
18 | ],
19 | "rules": {
20 | "indent": [
21 | "error",
22 | 2,
23 | {
24 | "SwitchCase": 1
25 | }
26 | ],
27 | "linebreak-style": "off",
28 | "quotes": [
29 | "error",
30 | "single"
31 | ],
32 | "semi": [
33 | "error",
34 | "always"
35 | ],
36 | "@typescript-eslint/no-explicit-any": "error"
37 | }
38 | }
--------------------------------------------------------------------------------
/dist/messages/ConnectionMessage.d.ts:
--------------------------------------------------------------------------------
1 | import { Inbound, SLData, SLSimpleBoolData } from './SLMessage';
2 | export declare class ConnectionMessage {
3 | static decodeChallengeResponse(msg: Inbound): string;
4 | static decodeVersionResponse(msg: Inbound): SLVersionData;
5 | static decodeAddClient(msg: Inbound): SLSimpleBoolData;
6 | static decodeRemoveClient(msg: Inbound): SLSimpleBoolData;
7 | static decodePingClient(msg: Inbound): SLSimpleBoolData;
8 | }
9 | export declare namespace ConnectionMessage {
10 | enum ResponseIDs {
11 | LoginFailure = 13,
12 | Challenge = 15,
13 | Ping = 17,
14 | Login = 28,
15 | UnknownCommand = 30,
16 | BadParameter = 31,
17 | Version = 8121,
18 | AddClient = 12523,
19 | RemoveClient = 12525,
20 | GatewayResponse = 18004
21 | }
22 | }
23 | export interface SLVersionData extends SLData {
24 | version: string;
25 | }
26 |
--------------------------------------------------------------------------------
/.github/workflows/nodejs.yml:
--------------------------------------------------------------------------------
1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3 |
4 | name: Node.js CI
5 |
6 | on:
7 | push:
8 | branches: [ main ]
9 | pull_request:
10 | branches: [ main ]
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | strategy:
18 | matrix:
19 | node-version: [18.x, 20.x, 22.x]
20 |
21 | steps:
22 | - uses: actions/checkout@v4
23 | - name: Use Node.js ${{ matrix.node-version }}
24 | uses: actions/setup-node@v4
25 | with:
26 | node-version: ${{ matrix.node-version }}
27 | - run: npm ci
28 | - run: npm run build --if-present
29 | - run: npm run pretest
30 | - run: npm run test-slmessage
31 | - run: npm run test-passwordencoder
32 |
--------------------------------------------------------------------------------
/dist/messages/config/CircuitMessage.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"CircuitMessage.js","sourceRoot":"","sources":["../../../messages/config/CircuitMessage.ts"],"names":[],"mappings":";;;AAGA,MAAa,cAAc;IAClB,MAAM,CAAC,gBAAgB,CAAC,GAAY;QACzC,MAAM,QAAQ,GAAqB;YACjC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,GAAG,EAAE,IAAI;SACV,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEM,MAAM,CAAC,qBAAqB,CAAC,GAAY;QAC9C,MAAM;QACN,MAAM,QAAQ,GAAqB;YACjC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,GAAG,EAAE,IAAI;SACV,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;IACM,MAAM,CAAC,cAAc,CAAC,GAAY;QACvC,MAAM;QACN,MAAM,QAAQ,GAAqB;YACjC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,GAAG,EAAE,IAAI;SACV,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;IACM,MAAM,CAAC,uBAAuB,CAAC,GAAY;QAChD,MAAM;QACN,MAAM,QAAQ,GAAqB;YACjC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,GAAG,EAAE,IAAI;SACV,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF;AAjCD,wCAiCC;AAED,WAAiB,cAAc;IAC7B,IAAY,WAMX;IAND,WAAY,WAAW;QACrB,mEAAqB,CAAA;QACrB,qEAAsB,CAAA;QACtB,uEAAuB,CAAA;QACvB,2EAAyB,CAAA;QACzB,mEAAqB,CAAA;IACvB,CAAC,EANW,WAAW,GAAX,0BAAW,KAAX,0BAAW,QAMtB;AACH,CAAC,EARgB,cAAc,GAAd,sBAAc,KAAd,sBAAc,QAQ9B"}
--------------------------------------------------------------------------------
/dist/messages/config/ScheduleMessage.d.ts:
--------------------------------------------------------------------------------
1 | import { Inbound, SLData, SLSimpleBoolData, SLSimpleNumberData } from '../SLMessage';
2 | export declare class ScheduleMessage {
3 | static decodeGetScheduleMessage(msg: Inbound): SLScheduleData;
4 | static decodeAddSchedule(msg: Inbound): SLSimpleNumberData;
5 | static decodeDeleteSchedule(msg: Inbound): SLSimpleBoolData;
6 | static decodeSetSchedule(msg: Inbound): SLSimpleBoolData;
7 | }
8 | export declare namespace ScheduleMessage {
9 | enum ResponseIDs {
10 | ScheduleChanged = 12501,
11 | GetSchedule = 12543,
12 | AddSchedule = 12545,
13 | DeleteSchedule = 12547,
14 | SetSchedule = 12549
15 | }
16 | }
17 | export interface SLScheduleDatum {
18 | scheduleId: number;
19 | circuitId: number;
20 | startTime: string;
21 | stopTime: string;
22 | dayMask: number;
23 | flags: number;
24 | heatCmd: number;
25 | heatSetPoint: number;
26 | days: string[];
27 | }
28 | export interface SLScheduleData extends SLData {
29 | data: SLScheduleDatum[];
30 | }
31 |
--------------------------------------------------------------------------------
/dist/messages/state/ChlorMessage.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"ChlorMessage.js","sourceRoot":"","sources":["../../../messages/state/ChlorMessage.ts"],"names":[],"mappings":";;;AAGA,MAAa,YAAY;IAChB,MAAM,CAAC,wBAAwB,CAAC,GAAY;QACjD,MAAM,IAAI,GAAuB;YAC/B,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC;YAClC,MAAM,EAAE,GAAG,CAAC,WAAW,EAAE;YACzB,YAAY,EAAE,GAAG,CAAC,WAAW,EAAE;YAC/B,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE;YAC9B,IAAI,EAAE,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE;YAC5B,KAAK,EAAE,GAAG,CAAC,WAAW,EAAE;YACxB,eAAe,EAAE,GAAG,CAAC,WAAW,EAAE;SACnC,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IACM,MAAM,CAAC,2BAA2B,CAAC,GAAY;QACpD,MAAM;QACN,MAAM,QAAQ,GAAqB;YACjC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,GAAG,EAAE,IAAI;SACV,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;IACM,MAAM,CAAC,iCAAiC,CAAC,GAAY;QAC1D,MAAM;QACN,MAAM,QAAQ,GAAqB;YACjC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,GAAG,EAAE,IAAI;SACV,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF;AA9BD,oCA8BC;AAED,WAAiB,YAAY;IAC3B,IAAY,WAIX;IAJD,WAAY,WAAW;QACrB,mFAA6B,CAAA;QAC7B,qFAA8B,CAAA;QAC9B,mFAA6B,CAAA;IAC/B,CAAC,EAJW,WAAW,GAAX,wBAAW,KAAX,wBAAW,QAItB;AACH,CAAC,EANgB,YAAY,GAAZ,oBAAY,KAAZ,oBAAY,QAM5B"}
--------------------------------------------------------------------------------
/messages/config/HeaterMessage.ts:
--------------------------------------------------------------------------------
1 | import { Inbound, SLSimpleBoolData } from '../SLMessage';
2 |
3 | export class HeaterMessage {
4 | public static decodeSetHeatSetPoint(msg: Inbound): SLSimpleBoolData {
5 | // ack
6 | const response: SLSimpleBoolData = {
7 | senderId: msg.senderId,
8 | val: true
9 | };
10 | return response;
11 | }
12 | public static decodeCoolSetHeatSetPoint(msg: Inbound): SLSimpleBoolData {
13 | // ack
14 | const response: SLSimpleBoolData = {
15 | senderId: msg.senderId,
16 | val: true
17 | };
18 | return response;
19 | }
20 | public static decodeSetHeatModePoint(msg: Inbound): SLSimpleBoolData {
21 | // ack
22 | const response: SLSimpleBoolData = {
23 | senderId: msg.senderId,
24 | val: true
25 | };
26 | return response;
27 | }
28 | }
29 |
30 | export namespace HeaterMessage { // eslint-disable-line @typescript-eslint/no-namespace
31 | export enum ResponseIDs {
32 | SetHeatSetPoint = 12529,
33 | SetHeatMode = 12539,
34 | SetCoolSetPoint = 12591,
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (http://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # Typescript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | .DS_Store
61 |
--------------------------------------------------------------------------------
/dist/messages/SLGatewayDataMessage.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | exports.SLReceiveGatewayDataMessage = void 0;
4 | const SLMessage_1 = require("./SLMessage");
5 | class SLReceiveGatewayDataMessage extends SLMessage_1.Inbound {
6 | constructor(buf) {
7 | super(0, 0);
8 | this.readFromBuffer(buf);
9 | this.decode();
10 | }
11 | decode() {
12 | super.decode();
13 | const gatewayFound = this._smartBuffer.readUInt8() !== 0;
14 | const licenseOK = this._smartBuffer.readUInt8() !== 0;
15 | const ipAddr = this.readSLString();
16 | const port = this._smartBuffer.readUInt16LE();
17 | const portOpen = this._smartBuffer.readUInt8() !== 0;
18 | const relayOn = this._smartBuffer.readUInt8() !== 0;
19 | this.data = {
20 | gatewayFound,
21 | licenseOK,
22 | ipAddr,
23 | port,
24 | portOpen,
25 | relayOn
26 | };
27 | }
28 | get() {
29 | return this.data;
30 | }
31 | }
32 | exports.SLReceiveGatewayDataMessage = SLReceiveGatewayDataMessage;
33 | //# sourceMappingURL=SLGatewayDataMessage.js.map
--------------------------------------------------------------------------------
/dist/messages/ConnectionMessage.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"ConnectionMessage.js","sourceRoot":"","sources":["../../messages/ConnectionMessage.ts"],"names":[],"mappings":";;;AAIA,MAAa,iBAAiB;IACrB,MAAM,CAAC,uBAAuB,CAAC,GAAY;QAChD,MAAM,eAAe,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;QAC3C,OAAO,eAAe,CAAC;IACzB,CAAC;IACM,MAAM,CAAC,qBAAqB,CAAC,GAAY;QAC9C,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;QACnC,MAAM,WAAW,GAAkB;YACjC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,OAAO;SACR,CAAC;QACF,OAAO,WAAW,CAAC;IACrB,CAAC;IACM,MAAM,CAAC,eAAe,CAAC,GAAY;QACxC,MAAM;QACN,MAAM,QAAQ,GAAqB;YACjC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,GAAG,EAAE,IAAI;SACV,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;IACM,MAAM,CAAC,kBAAkB,CAAC,GAAY;QAC3C,MAAM;QACN,MAAM,QAAQ,GAAqB;YACjC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,GAAG,EAAE,IAAI;SACV,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;IACM,MAAM,CAAC,gBAAgB,CAAC,GAAY;QACzC,MAAM;QACN,MAAM,QAAQ,GAAqB;YACjC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,GAAG,EAAE,IAAI;SACV,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF;AArCD,8CAqCC;AAED,WAAiB,iBAAiB;IAChC,IAAY,WAWX;IAXD,WAAY,WAAW;QACrB,8DAAiB,CAAA;QACjB,wDAAc,CAAA;QACd,8CAAS,CAAA;QACT,gDAAU,CAAA;QACV,kEAAmB,CAAA;QACnB,8DAAiB,CAAA;QACjB,sDAAc,CAAA;QACd,2DAAiB,CAAA;QACjB,iEAAoB,CAAA;QACpB,uEAAuB,CAAA;IACzB,CAAC,EAXW,WAAW,GAAX,6BAAW,KAAX,6BAAW,QAWtB;AACH,CAAC,EAbgB,iBAAiB,GAAjB,yBAAiB,KAAjB,yBAAiB,QAajC"}
--------------------------------------------------------------------------------
/messages/config/CircuitMessage.ts:
--------------------------------------------------------------------------------
1 | import { Inbound, SLSimpleBoolData } from '../SLMessage';
2 |
3 |
4 | export class CircuitMessage {
5 | public static decodeSetCircuit(msg: Inbound): SLSimpleBoolData {
6 | const response: SLSimpleBoolData = {
7 | senderId: msg.senderId,
8 | val: true
9 | };
10 | return response;
11 | }
12 |
13 | public static decodeSetCircuitState(msg: Inbound): SLSimpleBoolData {
14 | // ack
15 | const response: SLSimpleBoolData = {
16 | senderId: msg.senderId,
17 | val: true
18 | };
19 | return response;
20 | }
21 | public static decodeSetLight(msg: Inbound): SLSimpleBoolData {
22 | // ack
23 | const response: SLSimpleBoolData = {
24 | senderId: msg.senderId,
25 | val: true
26 | };
27 | return response;
28 | }
29 | public static decodeSetCircuitRunTime(msg: Inbound): SLSimpleBoolData {
30 | // ack
31 | const response: SLSimpleBoolData = {
32 | senderId: msg.senderId,
33 | val: true
34 | };
35 | return response;
36 | }
37 | }
38 |
39 | export namespace CircuitMessage { // eslint-disable-line @typescript-eslint/no-namespace
40 | export enum ResponseIDs {
41 | LightSequence = 12504,
42 | SetCircuitInfo = 12521,
43 | SetCircuitState = 12531,
44 | SetCircuitRunTime = 12551,
45 | SetLightState = 12557,
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/dist/messages/config/HeaterMessage.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | exports.HeaterMessage = void 0;
4 | class HeaterMessage {
5 | static decodeSetHeatSetPoint(msg) {
6 | // ack
7 | const response = {
8 | senderId: msg.senderId,
9 | val: true
10 | };
11 | return response;
12 | }
13 | static decodeCoolSetHeatSetPoint(msg) {
14 | // ack
15 | const response = {
16 | senderId: msg.senderId,
17 | val: true
18 | };
19 | return response;
20 | }
21 | static decodeSetHeatModePoint(msg) {
22 | // ack
23 | const response = {
24 | senderId: msg.senderId,
25 | val: true
26 | };
27 | return response;
28 | }
29 | }
30 | exports.HeaterMessage = HeaterMessage;
31 | (function (HeaterMessage) {
32 | let ResponseIDs;
33 | (function (ResponseIDs) {
34 | ResponseIDs[ResponseIDs["SetHeatSetPoint"] = 12529] = "SetHeatSetPoint";
35 | ResponseIDs[ResponseIDs["SetHeatMode"] = 12539] = "SetHeatMode";
36 | ResponseIDs[ResponseIDs["SetCoolSetPoint"] = 12591] = "SetCoolSetPoint";
37 | })(ResponseIDs = HeaterMessage.ResponseIDs || (HeaterMessage.ResponseIDs = {}));
38 | })(HeaterMessage = exports.HeaterMessage || (exports.HeaterMessage = {}));
39 | //# sourceMappingURL=HeaterMessage.js.map
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "node-screenlogic",
3 | "description": "Tool for connecting to Pentair ScreenLogic systems on the local network",
4 | "version": "2.1.1",
5 | "main": "./dist/index.js",
6 | "types": "./dist/index.d.ts",
7 | "license": "MIT",
8 | "repository": "https://github.com/parnic/node-screenlogic.git",
9 | "keywords": [
10 | "pentair",
11 | "pool",
12 | "screenlogic",
13 | "swimmingpool"
14 | ],
15 | "dependencies": {
16 | "debug": "^4.3.2",
17 | "smart-buffer": "^4.2.0",
18 | "source-map-support": "^0.5.21"
19 | },
20 | "devDependencies": {
21 | "@types/debug": "^4.1.7",
22 | "@types/node": "^16.18.0",
23 | "@typescript-eslint/eslint-plugin": "^5.53.0",
24 | "@typescript-eslint/parser": "^5.53.0",
25 | "eslint": "^8.34.0",
26 | "eslint-config-strongloop": "^2.1.0",
27 | "mocha": "^11.1.0",
28 | "typescript": "^4.9.5"
29 | },
30 | "scripts": {
31 | "test": "mocha test/*.spec.js",
32 | "pretest": "eslint . ",
33 | "test-slmessage": "mocha test/slmessage.spec.js",
34 | "test-passwordencoder": "mocha test/password.spec.js",
35 | "build": "tsc",
36 | "lint": "eslint --fix --ext .js,.jsx,.ts ."
37 | },
38 | "engines": {
39 | "npm": ">=6.0.0",
40 | "node": ">=14.0.0"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/dist/messages/state/ChemMessage.d.ts:
--------------------------------------------------------------------------------
1 | import { Inbound, SLData } from '../SLMessage';
2 | export declare class ChemMessage {
3 | static decodeChemDataMessage(msg: Inbound): SLChemData;
4 | static decodecChemHistoryMessage(msg: Inbound): SLChemHistory;
5 | }
6 | export declare namespace ChemMessage {
7 | enum ResponseIDs {
8 | AsyncChemicalData = 12505,
9 | ChemicalHistoryData = 12506,
10 | HistoryDataPending = 12597,
11 | GetChemicalData = 12593
12 | }
13 | }
14 | export interface SLChemData extends SLData {
15 | isValid: boolean;
16 | pH: number;
17 | orp: number;
18 | pHSetPoint: number;
19 | orpSetPoint: number;
20 | pHTankLevel: number;
21 | orpTankLevel: number;
22 | saturation: number;
23 | calcium: number;
24 | cyanuricAcid: number;
25 | alkalinity: number;
26 | saltPPM: number;
27 | temperature: number;
28 | balance: number;
29 | corrosive: boolean;
30 | scaling: boolean;
31 | error: boolean;
32 | }
33 | export interface TimePHPointsPairs {
34 | time: Date;
35 | pH: number;
36 | }
37 | export interface TimeORPPointsPairs {
38 | time: Date;
39 | orp: number;
40 | }
41 | export interface TimeTimePointsPairs {
42 | on: Date;
43 | off: Date;
44 | }
45 | export interface SLChemHistory {
46 | phPoints: TimePHPointsPairs[];
47 | orpPoints: TimeORPPointsPairs[];
48 | phRuns: TimeTimePointsPairs[];
49 | orpRuns: TimeTimePointsPairs[];
50 | }
51 |
--------------------------------------------------------------------------------
/dist/example.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"example.js","sourceRoot":"","sources":["../example.ts"],"names":[],"mappings":";;AAAA,mCAAgE;AAChE,mCAAyC;AACzC,mEAAmE;AAEnE,oEAAoE;AACpE,MAAM,MAAM,GAAG,IAAI,iBAAS,EAAE,CAAC;AAC/B,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,EAAE,IAAe,EAAE,EAAE;IACnD,MAAM,CAAC,KAAK,EAAE,CAAC;IACf,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnD,MAAM,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3D,CAAC,CAAC,CAAC;AACH,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,qHAAqH;AACrH,sCAAsC;AAEtC,2EAA2E;AAC3E,gCAAgC;AAChC,gEAAgE;AAChE,4BAA4B;AAC5B,8DAA8D;AAC9D,4EAA4E;AAC5E,MAAM;AAEN,qBAAqB;AACrB,MAAM;AAEN,wFAAwF;AACxF,wCAAwC;AACxC,yBAAyB;AACzB,6CAA6C;AAC7C,sEAAsE;AACtE,kFAAkF;AAClF,wEAAwE;AACxE,uBAAuB;AACvB,MAAM;AAEN,+EAA+E;AAE/E,qBAAqB;AACrB,MAAM;AAEN,KAAK,UAAU,OAAO,CAAC,WAAmB,EAAE,MAAc,EAAE,IAAY,EAAE,QAAiB;IACzF,MAAM,MAAM,GAAG,IAAI,sBAAc,EAAE,CAAC;IACpC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IACjD,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC;IAE5B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,eAAe,EAAE,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAE1C,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/B,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;IAE/C,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;AAC5B,CAAC"}
--------------------------------------------------------------------------------
/messages/state/ChlorMessage.ts:
--------------------------------------------------------------------------------
1 | import { Inbound, SLData, SLSimpleBoolData } from '../SLMessage';
2 |
3 |
4 | export class ChlorMessage {
5 | public static decodeIntellichlorConfig(msg: Inbound){
6 | const data: SLIntellichlorData = {
7 | senderId: msg.senderId,
8 | installed: msg.readInt32LE() === 1,
9 | status: msg.readInt32LE(),
10 | poolSetPoint: msg.readInt32LE(),
11 | spaSetPoint: msg.readInt32LE(),
12 | salt: msg.readInt32LE() * 50,
13 | flags: msg.readInt32LE(),
14 | superChlorTimer: msg.readInt32LE()
15 | };
16 | return data;
17 | }
18 | public static decodeSetIntellichlorConfig(msg: Inbound): SLSimpleBoolData {
19 | // ack
20 | const response: SLSimpleBoolData = {
21 | senderId: msg.senderId,
22 | val: true
23 | };
24 | return response;
25 | }
26 | public static decodeSetEnableIntellichlorConfig(msg: Inbound): SLSimpleBoolData {
27 | // ack
28 | const response: SLSimpleBoolData = {
29 | senderId: msg.senderId,
30 | val: true
31 | };
32 | return response;
33 | }
34 | }
35 |
36 | export namespace ChlorMessage { // eslint-disable-line @typescript-eslint/no-namespace
37 | export enum ResponseIDs {
38 | GetIntellichlorConfig = 12573,
39 | SetIntellichlorEnabled = 12575,
40 | SetIntellichlorConfig = 12577,
41 | }
42 | }
43 |
44 | export interface SLIntellichlorData extends SLData {
45 | installed: boolean;
46 | status: number;
47 | poolSetPoint: number;
48 | spaSetPoint: number;
49 | salt: number;
50 | flags: number;
51 | superChlorTimer: number;
52 | }
--------------------------------------------------------------------------------
/dist/messages/state/PumpMessage.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"PumpMessage.js","sourceRoot":"","sources":["../../../messages/state/PumpMessage.ts"],"names":[],"mappings":";;;AAAA,uCAAwC;AAIxC,MAAa,WAAW;IACf,MAAM,CAAC,gBAAgB,CAAC,GAAY;QACzC,wCAAwC;QACxC,SAAS;QACT,SAAS;QACT,UAAU;QACV,oEAAoE;QACpE,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,iBAAS,CAAC,sBAAsB,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,iBAAS,CAAC,sBAAsB,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,iBAAS,CAAC,uBAAuB,CAAC,CAAC,CAAC,SAAS,CAAC;QAC3L,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC,oCAAoC;QAChF,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;QACpC,MAAM,YAAY,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,WAAW;QACpD,MAAM,QAAQ,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;QACpC,MAAM,YAAY,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,aAAa;QAEtD,MAAM,YAAY,GAAG,EAAE,CAAC;QACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1B,MAAM,SAAS,GAAsB;gBACnC,SAAS,EAAE,GAAG,CAAC,YAAY,EAAE;gBAC7B,KAAK,EAAE,GAAG,CAAC,YAAY,EAAE;gBACzB,MAAM,EAAE,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,yBAAyB;aAC3D,CAAC;YACF,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;SAC9B;QACD,MAAM,IAAI,GAAqB;YAC7B,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,YAAY;YACZ,QAAQ;YACR,SAAS;YACT,SAAS;YACT,QAAQ;YACR,YAAY;YACZ,QAAQ;YACR,YAAY;SACb,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IACM,MAAM,CAAC,kBAAkB,CAAC,GAAW;QAC1C,MAAM;QACN,MAAM,QAAQ,GAAqB;YACjC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,GAAG,EAAE,IAAI;SACV,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF;AA9CD,kCA8CC;AAED,WAAiB,WAAW;IAC1B,IAAY,WAGX;IAHD,WAAY,WAAW;QACrB,6DAAkB,CAAA;QAClB,iEAAoB,CAAA;IACtB,CAAC,EAHW,WAAW,GAAX,uBAAW,KAAX,uBAAW,QAGtB;AACH,CAAC,EALgB,WAAW,GAAX,mBAAW,KAAX,mBAAW,QAK3B"}
--------------------------------------------------------------------------------
/dist/messages/state/ChlorMessage.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | exports.ChlorMessage = void 0;
4 | class ChlorMessage {
5 | static decodeIntellichlorConfig(msg) {
6 | const data = {
7 | senderId: msg.senderId,
8 | installed: msg.readInt32LE() === 1,
9 | status: msg.readInt32LE(),
10 | poolSetPoint: msg.readInt32LE(),
11 | spaSetPoint: msg.readInt32LE(),
12 | salt: msg.readInt32LE() * 50,
13 | flags: msg.readInt32LE(),
14 | superChlorTimer: msg.readInt32LE()
15 | };
16 | return data;
17 | }
18 | static decodeSetIntellichlorConfig(msg) {
19 | // ack
20 | const response = {
21 | senderId: msg.senderId,
22 | val: true
23 | };
24 | return response;
25 | }
26 | static decodeSetEnableIntellichlorConfig(msg) {
27 | // ack
28 | const response = {
29 | senderId: msg.senderId,
30 | val: true
31 | };
32 | return response;
33 | }
34 | }
35 | exports.ChlorMessage = ChlorMessage;
36 | (function (ChlorMessage) {
37 | let ResponseIDs;
38 | (function (ResponseIDs) {
39 | ResponseIDs[ResponseIDs["GetIntellichlorConfig"] = 12573] = "GetIntellichlorConfig";
40 | ResponseIDs[ResponseIDs["SetIntellichlorEnabled"] = 12575] = "SetIntellichlorEnabled";
41 | ResponseIDs[ResponseIDs["SetIntellichlorConfig"] = 12577] = "SetIntellichlorConfig";
42 | })(ResponseIDs = ChlorMessage.ResponseIDs || (ChlorMessage.ResponseIDs = {}));
43 | })(ChlorMessage = exports.ChlorMessage || (exports.ChlorMessage = {}));
44 | //# sourceMappingURL=ChlorMessage.js.map
--------------------------------------------------------------------------------
/messages/ConnectionMessage.ts:
--------------------------------------------------------------------------------
1 |
2 | import { Inbound, SLData, SLSimpleBoolData } from './SLMessage';
3 |
4 |
5 | export class ConnectionMessage{
6 | public static decodeChallengeResponse(msg: Inbound): string {
7 | const challengeString = msg.readSLString();
8 | return challengeString;
9 | }
10 | public static decodeVersionResponse(msg: Inbound): SLVersionData {
11 | const version = msg.readSLString();
12 | const versionData: SLVersionData = {
13 | senderId: msg.senderId,
14 | version
15 | };
16 | return versionData;
17 | }
18 | public static decodeAddClient(msg: Inbound): SLSimpleBoolData {
19 | // ack
20 | const response: SLSimpleBoolData = {
21 | senderId: msg.senderId,
22 | val: true
23 | };
24 | return response;
25 | }
26 | public static decodeRemoveClient(msg: Inbound): SLSimpleBoolData {
27 | // ack
28 | const response: SLSimpleBoolData = {
29 | senderId: msg.senderId,
30 | val: true
31 | };
32 | return response;
33 | }
34 | public static decodePingClient(msg: Inbound): SLSimpleBoolData {
35 | // ack
36 | const response: SLSimpleBoolData = {
37 | senderId: msg.senderId,
38 | val: true
39 | };
40 | return response;
41 | }
42 | }
43 |
44 | export namespace ConnectionMessage { // eslint-disable-line @typescript-eslint/no-namespace
45 | export enum ResponseIDs {
46 | LoginFailure = 13,
47 | Challenge = 15,
48 | Ping = 17,
49 | Login = 28,
50 | UnknownCommand = 30,
51 | BadParameter = 31,
52 | Version = 8121,
53 | AddClient = 12523,
54 | RemoveClient = 12525,
55 | GatewayResponse = 18004,
56 | }
57 | }
58 |
59 | export interface SLVersionData extends SLData {
60 | version: string
61 | }
62 |
--------------------------------------------------------------------------------
/messages/SLGatewayDataMessage.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { Inbound } from './SLMessage';
4 |
5 | export class SLReceiveGatewayDataMessage extends Inbound {
6 | // static MSG_ID = _MSG_ID;
7 | private data: SLGateWayData;
8 | constructor(buf: Buffer) {
9 | super(0, 0);
10 | this.readFromBuffer(buf);
11 | this.decode();
12 | }
13 |
14 |
15 | decode() {
16 | super.decode();
17 |
18 | const gatewayFound = this._smartBuffer.readUInt8() !== 0;
19 | const licenseOK = this._smartBuffer.readUInt8() !== 0;
20 | const ipAddr = this.readSLString();
21 | const port = this._smartBuffer.readUInt16LE();
22 | const portOpen = this._smartBuffer.readUInt8() !== 0;
23 | const relayOn = this._smartBuffer.readUInt8() !== 0;
24 | this.data = {
25 | gatewayFound,
26 | licenseOK,
27 | ipAddr,
28 | port,
29 | portOpen,
30 | relayOn
31 | };
32 |
33 | }
34 | get(): SLGateWayData {
35 | return this.data;
36 | }
37 | }
38 |
39 |
40 | // export class SLSendGatewayDataMessage extends Outbound {
41 | // // static MSG_ID = _MSG_ID;
42 | // constructor(systemName: string) {
43 | // super(0, 0);
44 | // this.systemName = systemName;
45 | // this.writeMessage();
46 | // }
47 | // private systemName: string;
48 |
49 | // public writeMessage(): void {
50 |
51 | // this.messageId = 18003; // SLSendGatewayDataMessage.MSG_ID;
52 | // this.createBaseMessage();
53 | // this.writeSLString(this.systemName);
54 | // this.writeSLString(this.systemName);
55 | // }
56 | // };
57 |
58 | export interface SLGateWayData {
59 | gatewayFound: boolean,
60 | licenseOK: boolean,
61 | ipAddr: string,
62 | port: number,
63 | portOpen: boolean,
64 | relayOn: boolean
65 | }
--------------------------------------------------------------------------------
/dist/messages/config/CircuitMessage.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | exports.CircuitMessage = void 0;
4 | class CircuitMessage {
5 | static decodeSetCircuit(msg) {
6 | const response = {
7 | senderId: msg.senderId,
8 | val: true
9 | };
10 | return response;
11 | }
12 | static decodeSetCircuitState(msg) {
13 | // ack
14 | const response = {
15 | senderId: msg.senderId,
16 | val: true
17 | };
18 | return response;
19 | }
20 | static decodeSetLight(msg) {
21 | // ack
22 | const response = {
23 | senderId: msg.senderId,
24 | val: true
25 | };
26 | return response;
27 | }
28 | static decodeSetCircuitRunTime(msg) {
29 | // ack
30 | const response = {
31 | senderId: msg.senderId,
32 | val: true
33 | };
34 | return response;
35 | }
36 | }
37 | exports.CircuitMessage = CircuitMessage;
38 | (function (CircuitMessage) {
39 | let ResponseIDs;
40 | (function (ResponseIDs) {
41 | ResponseIDs[ResponseIDs["LightSequence"] = 12504] = "LightSequence";
42 | ResponseIDs[ResponseIDs["SetCircuitInfo"] = 12521] = "SetCircuitInfo";
43 | ResponseIDs[ResponseIDs["SetCircuitState"] = 12531] = "SetCircuitState";
44 | ResponseIDs[ResponseIDs["SetCircuitRunTime"] = 12551] = "SetCircuitRunTime";
45 | ResponseIDs[ResponseIDs["SetLightState"] = 12557] = "SetLightState";
46 | })(ResponseIDs = CircuitMessage.ResponseIDs || (CircuitMessage.ResponseIDs = {}));
47 | })(CircuitMessage = exports.CircuitMessage || (exports.CircuitMessage = {}));
48 | //# sourceMappingURL=CircuitMessage.js.map
--------------------------------------------------------------------------------
/dist/messages/config/ScheduleMessage.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"ScheduleMessage.js","sourceRoot":"","sources":["../../../messages/config/ScheduleMessage.ts"],"names":[],"mappings":";;;AAGA,MAAa,eAAe;IACnB,MAAM,CAAC,wBAAwB,CAAC,GAAY;QACjD,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;QACtC,MAAM,IAAI,GAAsB,EAAE,CAAC;QACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE;YACnC,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,EAAE,GAAG,GAAG,CAAC;YAC5C,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,EAAE,GAAG,GAAG,CAAC;YAC3C,MAAM,SAAS,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;YACrD,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;YACpD,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;YACnC,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;YACjC,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;YACnC,MAAM,YAAY,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;YACxC,MAAM,IAAI,GAAG,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YACxC,MAAM,KAAK,GAAoB;gBAC7B,UAAU;gBACV,SAAS;gBACT,SAAS;gBACT,QAAQ;gBACR,OAAO;gBACP,KAAK;gBACL,OAAO;gBACP,YAAY;gBACZ,IAAI;aACL,CAAC;YACF,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SAClB;QACD,MAAM,MAAM,GAAmB;YAC7B,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,IAAI;SACL,CAAC;QACF,OAAO,MAAM,CAAC;IAChB,CAAC;IACM,MAAM,CAAC,iBAAiB,CAAC,GAAY;QAC1C,MAAM,QAAQ,GAAuB;YACnC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,GAAG,EAAE,GAAG,CAAC,YAAY,EAAE,GAAG,GAAG;SAC9B,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;IACM,MAAM,CAAC,oBAAoB,CAAC,GAAY;QAC7C,MAAM;QACN,MAAM,QAAQ,GAAqB;YACjC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,GAAG,EAAE,IAAI;SACV,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;IACM,MAAM,CAAC,iBAAiB,CAAC,GAAY;QAC1C,MAAM;QACN,MAAM,QAAQ,GAAqB;YACjC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,GAAG,EAAE,IAAI;SACV,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF;AAxDD,0CAwDC;AAED,WAAiB,eAAe;IAC9B,IAAY,WAMX;IAND,WAAY,WAAW;QACrB,uEAAuB,CAAA;QACvB,+DAAmB,CAAA;QACnB,+DAAmB,CAAA;QACnB,qEAAsB,CAAA;QACtB,+DAAmB,CAAA;IACrB,CAAC,EANW,WAAW,GAAX,2BAAW,KAAX,2BAAW,QAMtB;AACH,CAAC,EARgB,eAAe,GAAf,uBAAe,KAAf,uBAAe,QAQ/B"}
--------------------------------------------------------------------------------
/dist/messages/SLMessage.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | import { SmartBuffer } from 'smart-buffer';
3 | export interface SLData {
4 | senderId: number;
5 | }
6 | export interface SLSimpleBoolData extends SLData {
7 | val: boolean;
8 | }
9 | export interface SLSimpleNumberData extends SLData {
10 | val: number;
11 | }
12 | export declare class SLMessage {
13 | static MSG_ID: number;
14 | constructor(controllerId?: number, senderId?: number);
15 | protected _wroteSize: boolean;
16 | action: number;
17 | senderId: number;
18 | controllerId: number;
19 | protected dataLength: number;
20 | protected _smartBuffer: SmartBuffer;
21 | get readOffset(): number;
22 | get length(): number;
23 | static slackForAlignment(val: number): number;
24 | getDayValue(dayName: string): number;
25 | toBuffer(): Buffer;
26 | }
27 | export declare class Inbound extends SLMessage {
28 | readFromBuffer(buf: Buffer): void;
29 | readMessage(buf: Buffer): void;
30 | readSLString(): string;
31 | readSLArray(): Array;
32 | decode(): void;
33 | isBitSet(value: number, bit: number): boolean;
34 | decodeTime(rawTime: number): string;
35 | decodeDayMask(dayMask: number): string[];
36 | readSLDateTime(): Date;
37 | readUInt8(): number;
38 | readUInt16BE(): number;
39 | readUInt16LE(): number;
40 | readInt32LE(): number;
41 | readUInt32LE(): number;
42 | incrementReadOffset(val: number): void;
43 | toString(): string;
44 | toHexStream(): string;
45 | }
46 | export declare class Outbound extends SLMessage {
47 | constructor(controllerId?: number, senderId?: number, messageId?: number);
48 | createBaseMessage(senderId?: number): void;
49 | addHeader(senderId?: number): void;
50 | encodeDayMask(daysArray: string[]): number;
51 | writeSLDateTime(date: Date): void;
52 | writeInt32LE(val: number): void;
53 | encode(): void;
54 | static getResponseId(): number;
55 | toBuffer(): Buffer;
56 | writeSLString(str: string): void;
57 | writeSLBuffer(buf: Buffer): void;
58 | writeSLArray(arr: Buffer): void;
59 | skipWrite(num: number): void;
60 | encodeTime(stringTime: string): number;
61 | }
62 |
--------------------------------------------------------------------------------
/dist/messages/ConnectionMessage.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | exports.ConnectionMessage = void 0;
4 | class ConnectionMessage {
5 | static decodeChallengeResponse(msg) {
6 | const challengeString = msg.readSLString();
7 | return challengeString;
8 | }
9 | static decodeVersionResponse(msg) {
10 | const version = msg.readSLString();
11 | const versionData = {
12 | senderId: msg.senderId,
13 | version
14 | };
15 | return versionData;
16 | }
17 | static decodeAddClient(msg) {
18 | // ack
19 | const response = {
20 | senderId: msg.senderId,
21 | val: true
22 | };
23 | return response;
24 | }
25 | static decodeRemoveClient(msg) {
26 | // ack
27 | const response = {
28 | senderId: msg.senderId,
29 | val: true
30 | };
31 | return response;
32 | }
33 | static decodePingClient(msg) {
34 | // ack
35 | const response = {
36 | senderId: msg.senderId,
37 | val: true
38 | };
39 | return response;
40 | }
41 | }
42 | exports.ConnectionMessage = ConnectionMessage;
43 | (function (ConnectionMessage) {
44 | let ResponseIDs;
45 | (function (ResponseIDs) {
46 | ResponseIDs[ResponseIDs["LoginFailure"] = 13] = "LoginFailure";
47 | ResponseIDs[ResponseIDs["Challenge"] = 15] = "Challenge";
48 | ResponseIDs[ResponseIDs["Ping"] = 17] = "Ping";
49 | ResponseIDs[ResponseIDs["Login"] = 28] = "Login";
50 | ResponseIDs[ResponseIDs["UnknownCommand"] = 30] = "UnknownCommand";
51 | ResponseIDs[ResponseIDs["BadParameter"] = 31] = "BadParameter";
52 | ResponseIDs[ResponseIDs["Version"] = 8121] = "Version";
53 | ResponseIDs[ResponseIDs["AddClient"] = 12523] = "AddClient";
54 | ResponseIDs[ResponseIDs["RemoveClient"] = 12525] = "RemoveClient";
55 | ResponseIDs[ResponseIDs["GatewayResponse"] = 18004] = "GatewayResponse";
56 | })(ResponseIDs = ConnectionMessage.ResponseIDs || (ConnectionMessage.ResponseIDs = {}));
57 | })(ConnectionMessage = exports.ConnectionMessage || (exports.ConnectionMessage = {}));
58 | //# sourceMappingURL=ConnectionMessage.js.map
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | name: "CodeQL"
7 |
8 | on:
9 | push:
10 | branches: [main]
11 | pull_request:
12 | # The branches below must be a subset of the branches above
13 | branches: [main]
14 |
15 | jobs:
16 | analyze:
17 | name: Analyze
18 | runs-on: ubuntu-latest
19 |
20 | strategy:
21 | fail-fast: false
22 | matrix:
23 | # Override automatic language detection by changing the below list
24 | # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
25 | language: ['javascript']
26 | # Learn more...
27 | # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
28 |
29 | steps:
30 | - name: Checkout repository
31 | uses: actions/checkout@v3
32 |
33 | # Initializes the CodeQL tools for scanning.
34 | - name: Initialize CodeQL
35 | uses: github/codeql-action/init@v2
36 | with:
37 | languages: ${{ matrix.language }}
38 | # If you wish to specify custom queries, you can do so here or in a config file.
39 | # By default, queries listed here will override any specified in a config file.
40 | # Prefix the list here with "+" to use these queries and those in the config file.
41 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
42 |
43 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
44 | # If this step fails, then you should remove it and run the build manually (see below)
45 | - name: Autobuild
46 | uses: github/codeql-action/autobuild@v2
47 |
48 | # ℹ️ Command-line programs to run using the OS shell.
49 | # 📚 https://git.io/JvXDl
50 |
51 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
52 | # and modify them (or add more) to build your code if your project
53 | # uses a compiled language
54 |
55 | #- run: |
56 | # make bootstrap
57 | # make release
58 |
59 | - name: Perform CodeQL Analysis
60 | uses: github/codeql-action/analyze@v2
61 |
--------------------------------------------------------------------------------
/example.ts:
--------------------------------------------------------------------------------
1 | import { FindUnits, LocalUnit/*, RemoteLogin*/ } from './index';
2 | import { UnitConnection } from './index';
3 | // import { SLGateWayData } from "./messages/SLGatewayDataMessage";
4 |
5 | // to find units on the local network with the event-based approach:
6 | const finder = new FindUnits();
7 | finder.once('serverFound', async (unit: LocalUnit) => {
8 | finder.close();
9 | console.log(`Found unit: ${JSON.stringify(unit)}`);
10 | await connect(unit.gatewayName, unit.address, unit.port);
11 | });
12 | finder.search();
13 |
14 | // or to connect directly to an already-known unit using async/await (assuming an appropriate environment for await):
15 | // await connect('', '10.0.0.85', 80);
16 |
17 | // or to gather all the units that can be found in 1 second using Promises:
18 | // let finder = new FindUnits();
19 | // finder.searchAsync(1000).then(async (units: LocalUnit[]) => {
20 | // if (units.length > 0) {
21 | // console.log(`Found unit: ${JSON.stringify(units[0])}`);
22 | // await connect(units[0].gatewayName, units[0].address, units[0].port);
23 | // }
24 |
25 | // process.exit(0);
26 | // });
27 |
28 | // or to connect to a system remotely with Promises (set your system name and password):
29 | // let systemName = 'Pentair: XX-XX-XX';
30 | // let password = '1234';
31 | // let gateway = new RemoteLogin(systemName);
32 | // gateway.connectAsync().then(async (gatewayData: SLGateWayData) => {
33 | // if (!gatewayData || !gatewayData.gatewayFound || gatewayData.ipAddr === '') {
34 | // console.error(`Screenlogic: No unit found called ${systemName}`);
35 | // process.exit(1);
36 | // }
37 |
38 | // await connect(systemName, gatewayData.ipAddr, gatewayData.port, password);
39 |
40 | // process.exit(0);
41 | // });
42 |
43 | async function connect(gatewayName: string, ipAddr: string, port: number, password?: string) {
44 | const client = new UnitConnection();
45 | client.init(gatewayName, ipAddr, port, password);
46 | await client.connectAsync();
47 |
48 | const result = await client.getVersionAsync();
49 | console.log(` version=${result.version}`);
50 |
51 | const state = await client.equipment.getEquipmentStateAsync(42);
52 | console.log(` pool temp=${state.bodies[0].currentTemp}`);
53 | console.log(` air temp=${state.airTemp}`);
54 | console.log(` salt ppm=${state.saltPPM}`);
55 | console.log(` pH=${state.pH}`);
56 | console.log(` saturation=${state.saturation}`);
57 |
58 | await client.closeAsync();
59 | }
60 |
--------------------------------------------------------------------------------
/messages/state/PumpMessage.ts:
--------------------------------------------------------------------------------
1 | import { PumpTypes } from '../../index';
2 | import { Inbound, SLData, SLSimpleBoolData } from '../SLMessage';
3 |
4 |
5 | export class PumpMessage {
6 | public static decodePumpStatus(msg: Inbound){
7 | // This pump type seems to be different:
8 | // 1 = VF
9 | // 2 = VS
10 | // 3 = VSF
11 | // The equipmentConfig message gives more specifics on the pump type
12 | const _pumpType = msg.readUInt32LE();
13 | const pumpType = _pumpType === 1 ? PumpTypes.PUMP_TYPE_INTELLIFLOVF : _pumpType === 2 ? PumpTypes.PUMP_TYPE_INTELLIFLOVS : _pumpType === 3 ? PumpTypes.PUMP_TYPE_INTELLIFLOVSF : _pumpType;
14 | const isRunning = msg.readUInt32LE() !== 0; // 0, 1, or 4294967295 (FF FF FF FF)
15 | const pumpWatts = msg.readUInt32LE();
16 | const pumpRPMs = msg.readUInt32LE();
17 | const pumpUnknown1 = msg.readUInt32LE(); // Always 0
18 | const pumpGPMs = msg.readUInt32LE();
19 | const pumpUnknown2 = msg.readUInt32LE(); // Always 255
20 |
21 | const pumpCircuits = [];
22 | for (let i = 0; i < 8; i++) {
23 | const _pumpCirc: SLPumpCircuitData = {
24 | circuitId: msg.readUInt32LE(),
25 | speed: msg.readUInt32LE(),
26 | isRPMs: msg.readUInt32LE() !== 0 // 1 for RPMs; 0 for GPMs
27 | };
28 | pumpCircuits.push(_pumpCirc);
29 | }
30 | const data: SLPumpStatusData = {
31 | senderId: msg.senderId,
32 | pumpCircuits,
33 | pumpType,
34 | isRunning,
35 | pumpWatts,
36 | pumpRPMs,
37 | pumpUnknown1,
38 | pumpGPMs,
39 | pumpUnknown2
40 | };
41 | return data;
42 | }
43 | public static decodeSetPumpSpeed(msg:Inbound): SLSimpleBoolData {
44 | // ack
45 | const response: SLSimpleBoolData = {
46 | senderId: msg.senderId,
47 | val: true
48 | };
49 | return response;
50 | }
51 | }
52 |
53 | export namespace PumpMessage { // eslint-disable-line @typescript-eslint/no-namespace
54 | export enum ResponseIDs {
55 | PumpStatus = 12585,
56 | SetPumpSpeed = 12587,
57 | }
58 | }
59 |
60 | export interface SLPumpStatusData extends SLData {
61 | pumpCircuits: SLPumpCircuitData[];
62 | pumpType: PumpTypes;
63 | isRunning: boolean;
64 | pumpWatts: number;
65 | pumpRPMs: number;
66 | pumpUnknown1: number;
67 | pumpGPMs: number;
68 | pumpUnknown2: number;
69 | }
70 |
71 | export interface SLPumpCircuitData {
72 | circuitId: number;
73 | speed: number;
74 | isRPMs: boolean;
75 | }
--------------------------------------------------------------------------------
/dist/messages/state/PumpMessage.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | exports.PumpMessage = void 0;
4 | const index_1 = require("../../index");
5 | class PumpMessage {
6 | static decodePumpStatus(msg) {
7 | // This pump type seems to be different:
8 | // 1 = VF
9 | // 2 = VS
10 | // 3 = VSF
11 | // The equipmentConfig message gives more specifics on the pump type
12 | const _pumpType = msg.readUInt32LE();
13 | const pumpType = _pumpType === 1 ? index_1.PumpTypes.PUMP_TYPE_INTELLIFLOVF : _pumpType === 2 ? index_1.PumpTypes.PUMP_TYPE_INTELLIFLOVS : _pumpType === 3 ? index_1.PumpTypes.PUMP_TYPE_INTELLIFLOVSF : _pumpType;
14 | const isRunning = msg.readUInt32LE() !== 0; // 0, 1, or 4294967295 (FF FF FF FF)
15 | const pumpWatts = msg.readUInt32LE();
16 | const pumpRPMs = msg.readUInt32LE();
17 | const pumpUnknown1 = msg.readUInt32LE(); // Always 0
18 | const pumpGPMs = msg.readUInt32LE();
19 | const pumpUnknown2 = msg.readUInt32LE(); // Always 255
20 | const pumpCircuits = [];
21 | for (let i = 0; i < 8; i++) {
22 | const _pumpCirc = {
23 | circuitId: msg.readUInt32LE(),
24 | speed: msg.readUInt32LE(),
25 | isRPMs: msg.readUInt32LE() !== 0 // 1 for RPMs; 0 for GPMs
26 | };
27 | pumpCircuits.push(_pumpCirc);
28 | }
29 | const data = {
30 | senderId: msg.senderId,
31 | pumpCircuits,
32 | pumpType,
33 | isRunning,
34 | pumpWatts,
35 | pumpRPMs,
36 | pumpUnknown1,
37 | pumpGPMs,
38 | pumpUnknown2
39 | };
40 | return data;
41 | }
42 | static decodeSetPumpSpeed(msg) {
43 | // ack
44 | const response = {
45 | senderId: msg.senderId,
46 | val: true
47 | };
48 | return response;
49 | }
50 | }
51 | exports.PumpMessage = PumpMessage;
52 | (function (PumpMessage) {
53 | let ResponseIDs;
54 | (function (ResponseIDs) {
55 | ResponseIDs[ResponseIDs["PumpStatus"] = 12585] = "PumpStatus";
56 | ResponseIDs[ResponseIDs["SetPumpSpeed"] = 12587] = "SetPumpSpeed";
57 | })(ResponseIDs = PumpMessage.ResponseIDs || (PumpMessage.ResponseIDs = {}));
58 | })(PumpMessage = exports.PumpMessage || (exports.PumpMessage = {}));
59 | //# sourceMappingURL=PumpMessage.js.map
--------------------------------------------------------------------------------
/dist/example.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | const index_1 = require("./index");
4 | const index_2 = require("./index");
5 | // import { SLGateWayData } from "./messages/SLGatewayDataMessage";
6 | // to find units on the local network with the event-based approach:
7 | const finder = new index_1.FindUnits();
8 | finder.once('serverFound', async (unit) => {
9 | finder.close();
10 | console.log(`Found unit: ${JSON.stringify(unit)}`);
11 | await connect(unit.gatewayName, unit.address, unit.port);
12 | });
13 | finder.search();
14 | // or to connect directly to an already-known unit using async/await (assuming an appropriate environment for await):
15 | // await connect('', '10.0.0.85', 80);
16 | // or to gather all the units that can be found in 1 second using Promises:
17 | // let finder = new FindUnits();
18 | // finder.searchAsync(1000).then(async (units: LocalUnit[]) => {
19 | // if (units.length > 0) {
20 | // console.log(`Found unit: ${JSON.stringify(units[0])}`);
21 | // await connect(units[0].gatewayName, units[0].address, units[0].port);
22 | // }
23 | // process.exit(0);
24 | // });
25 | // or to connect to a system remotely with Promises (set your system name and password):
26 | // let systemName = 'Pentair: XX-XX-XX';
27 | // let password = '1234';
28 | // let gateway = new RemoteLogin(systemName);
29 | // gateway.connectAsync().then(async (gatewayData: SLGateWayData) => {
30 | // if (!gatewayData || !gatewayData.gatewayFound || gatewayData.ipAddr === '') {
31 | // console.error(`Screenlogic: No unit found called ${systemName}`);
32 | // process.exit(1);
33 | // }
34 | // await connect(systemName, gatewayData.ipAddr, gatewayData.port, password);
35 | // process.exit(0);
36 | // });
37 | async function connect(gatewayName, ipAddr, port, password) {
38 | const client = new index_2.UnitConnection();
39 | client.init(gatewayName, ipAddr, port, password);
40 | await client.connectAsync();
41 | const result = await client.getVersionAsync();
42 | console.log(` version=${result.version}`);
43 | const state = await client.equipment.getEquipmentStateAsync(42);
44 | console.log(` pool temp=${state.bodies[0].currentTemp}`);
45 | console.log(` air temp=${state.airTemp}`);
46 | console.log(` salt ppm=${state.saltPPM}`);
47 | console.log(` pH=${state.pH}`);
48 | console.log(` saturation=${state.saturation}`);
49 | await client.closeAsync();
50 | }
51 | //# sourceMappingURL=example.js.map
--------------------------------------------------------------------------------
/messages/config/ScheduleMessage.ts:
--------------------------------------------------------------------------------
1 | import { Inbound, SLData, SLSimpleBoolData, SLSimpleNumberData } from '../SLMessage';
2 |
3 |
4 | export class ScheduleMessage {
5 | public static decodeGetScheduleMessage(msg: Inbound): SLScheduleData {
6 | const eventCount = msg.readUInt32LE();
7 | const data: SLScheduleDatum[] = [];
8 | for (let i = 0; i < eventCount; i++) {
9 | const scheduleId = msg.readUInt32LE() - 699;
10 | const circuitId = msg.readUInt32LE() - 499;
11 | const startTime = msg.decodeTime(msg.readUInt32LE());
12 | const stopTime = msg.decodeTime(msg.readUInt32LE());
13 | const dayMask = msg.readUInt32LE();
14 | const flags = msg.readUInt32LE();
15 | const heatCmd = msg.readUInt32LE();
16 | const heatSetPoint = msg.readUInt32LE();
17 | const days = msg.decodeDayMask(dayMask);
18 | const event: SLScheduleDatum = {
19 | scheduleId,
20 | circuitId,
21 | startTime,
22 | stopTime,
23 | dayMask,
24 | flags,
25 | heatCmd,
26 | heatSetPoint,
27 | days
28 | };
29 | data.push(event);
30 | }
31 | const result: SLScheduleData = {
32 | senderId: msg.senderId,
33 | data
34 | };
35 | return result;
36 | }
37 | public static decodeAddSchedule(msg: Inbound): SLSimpleNumberData {
38 | const response: SLSimpleNumberData = {
39 | senderId: msg.senderId,
40 | val: msg.readUInt32LE() - 699
41 | };
42 | return response;
43 | }
44 | public static decodeDeleteSchedule(msg: Inbound): SLSimpleBoolData {
45 | // ack
46 | const response: SLSimpleBoolData = {
47 | senderId: msg.senderId,
48 | val: true
49 | };
50 | return response;
51 | }
52 | public static decodeSetSchedule(msg: Inbound): SLSimpleBoolData {
53 | // ack
54 | const response: SLSimpleBoolData = {
55 | senderId: msg.senderId,
56 | val: true
57 | };
58 | return response;
59 | }
60 | }
61 |
62 | export namespace ScheduleMessage { // eslint-disable-line @typescript-eslint/no-namespace
63 | export enum ResponseIDs {
64 | ScheduleChanged = 12501,
65 | GetSchedule = 12543,
66 | AddSchedule = 12545,
67 | DeleteSchedule = 12547,
68 | SetSchedule = 12549,
69 | }
70 | }
71 |
72 | export interface SLScheduleDatum {
73 | scheduleId: number;
74 | circuitId: number;
75 | startTime: string;
76 | stopTime: string;
77 | dayMask: number;
78 | flags: number;
79 | heatCmd: number;
80 | heatSetPoint: number;
81 | days: string[];
82 | }
83 |
84 | export interface SLScheduleData extends SLData {
85 | data: SLScheduleDatum[]
86 | }
87 |
--------------------------------------------------------------------------------
/dist/messages/config/ScheduleMessage.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | exports.ScheduleMessage = void 0;
4 | class ScheduleMessage {
5 | static decodeGetScheduleMessage(msg) {
6 | const eventCount = msg.readUInt32LE();
7 | const data = [];
8 | for (let i = 0; i < eventCount; i++) {
9 | const scheduleId = msg.readUInt32LE() - 699;
10 | const circuitId = msg.readUInt32LE() - 499;
11 | const startTime = msg.decodeTime(msg.readUInt32LE());
12 | const stopTime = msg.decodeTime(msg.readUInt32LE());
13 | const dayMask = msg.readUInt32LE();
14 | const flags = msg.readUInt32LE();
15 | const heatCmd = msg.readUInt32LE();
16 | const heatSetPoint = msg.readUInt32LE();
17 | const days = msg.decodeDayMask(dayMask);
18 | const event = {
19 | scheduleId,
20 | circuitId,
21 | startTime,
22 | stopTime,
23 | dayMask,
24 | flags,
25 | heatCmd,
26 | heatSetPoint,
27 | days
28 | };
29 | data.push(event);
30 | }
31 | const result = {
32 | senderId: msg.senderId,
33 | data
34 | };
35 | return result;
36 | }
37 | static decodeAddSchedule(msg) {
38 | const response = {
39 | senderId: msg.senderId,
40 | val: msg.readUInt32LE() - 699
41 | };
42 | return response;
43 | }
44 | static decodeDeleteSchedule(msg) {
45 | // ack
46 | const response = {
47 | senderId: msg.senderId,
48 | val: true
49 | };
50 | return response;
51 | }
52 | static decodeSetSchedule(msg) {
53 | // ack
54 | const response = {
55 | senderId: msg.senderId,
56 | val: true
57 | };
58 | return response;
59 | }
60 | }
61 | exports.ScheduleMessage = ScheduleMessage;
62 | (function (ScheduleMessage) {
63 | let ResponseIDs;
64 | (function (ResponseIDs) {
65 | ResponseIDs[ResponseIDs["ScheduleChanged"] = 12501] = "ScheduleChanged";
66 | ResponseIDs[ResponseIDs["GetSchedule"] = 12543] = "GetSchedule";
67 | ResponseIDs[ResponseIDs["AddSchedule"] = 12545] = "AddSchedule";
68 | ResponseIDs[ResponseIDs["DeleteSchedule"] = 12547] = "DeleteSchedule";
69 | ResponseIDs[ResponseIDs["SetSchedule"] = 12549] = "SetSchedule";
70 | })(ResponseIDs = ScheduleMessage.ResponseIDs || (ScheduleMessage.ResponseIDs = {}));
71 | })(ScheduleMessage = exports.ScheduleMessage || (exports.ScheduleMessage = {}));
72 | //# sourceMappingURL=ScheduleMessage.js.map
--------------------------------------------------------------------------------
/dist/messages/state/EquipmentState.d.ts:
--------------------------------------------------------------------------------
1 | import { Inbound, SLData, SLSimpleBoolData } from '../SLMessage';
2 | import { Delays, Misc, SLCircuitIdName, SLHistoryData, SLWeatherForecastData, Valves } from '../config/EquipmentConfig';
3 | export declare class EquipmentStateMessage {
4 | static decodeEquipmentStateResponse(msg: Inbound): SLEquipmentStateData;
5 | static decodeSystemTime(msg: Inbound): SLSystemTimeData;
6 | static decodeCancelDelay(msg: Inbound): SLSimpleBoolData;
7 | static decodeSetSystemTime(msg: Inbound): SLSimpleBoolData;
8 | static decodeEquipmentConfiguration(msg: Inbound): {
9 | controllerType: number;
10 | hardwareType: number;
11 | expansionsCount: number;
12 | version: number;
13 | heaterConfig: {
14 | body1SolarPresent: boolean;
15 | body1HeatPumpPresent: boolean;
16 | body2SolarPresent: boolean;
17 | thermaFloPresent: boolean;
18 | thermaFloCoolPresent: boolean;
19 | };
20 | valves: Valves[];
21 | delays: Delays;
22 | misc: Misc;
23 | speed: SLCircuitIdName[];
24 | };
25 | static decodeWeatherMessage(msg: Inbound): SLWeatherForecastData;
26 | static decodeGetHistory(msg: Inbound): SLHistoryData;
27 | static decodeGeneric(msg: Inbound): void;
28 | }
29 | export declare namespace EquipmentStateMessage {
30 | enum ResponseIDs {
31 | SystemTime = 8111,
32 | SetSystemTime = 8113,
33 | AsyncEquipmentState = 12500,
34 | EquipmentState = 12527,
35 | CancelDelay = 12581
36 | }
37 | }
38 | export interface SLEquipmentStateData extends SLData {
39 | panelMode: number;
40 | freezeMode: number;
41 | remotes: number;
42 | poolDelay: number;
43 | spaDelay: number;
44 | cleanerDelay: number;
45 | airTemp: number;
46 | bodiesCount: number;
47 | bodies: SLEquipmentBodyState[];
48 | circuitArray: SLEquipmentCircuitArrayState[];
49 | pH: number;
50 | orp: number;
51 | saturation: number;
52 | saltPPM: number;
53 | pHTank: number;
54 | orpTank: number;
55 | alarms: number;
56 | }
57 | export interface SLEquipmentBodyState {
58 | id: number;
59 | currentTemp: number;
60 | heatStatus: number;
61 | setPoint: number;
62 | coolSetPoint: number;
63 | heatMode: number;
64 | }
65 | export interface SLEquipmentCircuitArrayState {
66 | id: number;
67 | state: number;
68 | colorSet: number;
69 | colorPos: number;
70 | colorStagger: number;
71 | delay: number;
72 | }
73 | export interface SLSystemTimeData {
74 | date: Date;
75 | year: number;
76 | month: number;
77 | dayOfWeek: number;
78 | day: number;
79 | hour: number;
80 | minute: number;
81 | second: number;
82 | millisecond: number;
83 | adjustForDST: boolean;
84 | }
85 |
--------------------------------------------------------------------------------
/test/unit.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const ScreenLogic = require('../dist/index');
4 | var assert = require('assert');
5 |
6 | // you'll need a ScreenLogic-enabled device on your network for this to succeed
7 | describe('Unit', function() {
8 | let unit;
9 | before(function(done) {
10 | let finder = new ScreenLogic.FindUnits();
11 | finder.on('serverFound', async server => {
12 | finder.close();
13 |
14 | unit = new ScreenLogic.UnitConnection();
15 | unit.initUnit(server);
16 | unit.once('loggedIn', () => {
17 | done();
18 | });
19 |
20 | try {
21 | if (!await unit.connectAsync()) {
22 | console.error('failed connection');
23 | }
24 | } catch(err) {
25 | console.error(`caught error trying to connect: ${err}`);
26 | done(err);
27 | }
28 | });
29 |
30 | finder.search();
31 | });
32 |
33 | after(async function() {
34 | await unit.closeAsync();
35 | });
36 |
37 | it('gets pool status', function(done) {
38 | unit.once('equipmentState', status => {
39 | assert.equal(status.senderId, 0);
40 | done();
41 | });
42 |
43 | unit.equipment.getEquipmentStateAsync();
44 | });
45 |
46 | it('gets controller config', function(done) {
47 | unit.once('controllerConfig', config => {
48 | assert.equal(config.senderId, 42);
49 | done();
50 | });
51 |
52 | unit.equipment.getControllerConfigAsync(42);
53 | });
54 |
55 | it('gets chemical data', function(done) {
56 | unit.once('chemicalData', chemData => {
57 | assert.equal(chemData.senderId, 123);
58 | done();
59 | });
60 |
61 | unit.chem.getChemicalDataAsync(123);
62 | });
63 |
64 | it('gets salt cell config', function(done) {
65 | unit.once('intellichlorConfig', saltConfig => {
66 | assert.equal(saltConfig.senderId, 0);
67 | done();
68 | });
69 |
70 | unit.chlor.getIntellichlorConfigAsync();
71 | });
72 |
73 | it('gets version', function(done) {
74 | unit.once('version', version => {
75 | assert.equal(version.senderId, 41239);
76 | done();
77 | });
78 |
79 | unit.getVersionAsync(41239);
80 | });
81 |
82 | it('can add and remove a client', function(done) {
83 | unit.once('addClient', response => {
84 | assert.equal(response.senderId, 4321);
85 | unit.removeClientAsync(1234, 5432);
86 | }).once('removeClient', response => {
87 | assert.equal(response.senderId, 5432);
88 | done();
89 | });
90 |
91 | unit.addClientAsync(1234, 4321);
92 | });
93 |
94 | it('can add and remove a client with async/await', async function() {
95 | const addClientResponse = await unit.addClientAsync(1234, 4321);
96 | assert.equal(addClientResponse.senderId, 4321);
97 | const removeClientResponse = await unit.removeClientAsync(1234, 5432);
98 | assert.equal(removeClientResponse.senderId, 5432);
99 | });
100 |
101 | it('can ping the server', async () => {
102 | const pong = await unit.pingServerAsync(1122);
103 | assert.equal(pong.senderId, 1122);
104 | });
105 |
106 | /* uncomment this to test setting state */
107 | // it('sets circuit state', function(done) {
108 | // let circuit;
109 | // unit.once('equipmentState', (status) => {
110 | // circuit = status.circuitArray[0];
111 | // unit.circuits.setCircuitStateAsync(circuit.id, circuit.state === 0 ? 1 : 0);
112 | // }).on('circuitStateChanged', (data) => {
113 | // done();
114 | // });
115 |
116 | // unit.equipment.getEquipmentStateAsync();
117 | // });
118 | });
119 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "type": "node",
9 | "request": "launch",
10 | "name": "Example",
11 | "program": "${workspaceFolder}/example.ts",
12 | "skipFiles": [
13 | "/**"
14 | ],
15 | "env": {
16 | "DEBUG": "sl:*"
17 | },
18 | "preLaunchTask": "tsc: build - tsconfig.json",
19 | "outFiles": [
20 | "${workspaceFolder}/**/*.js",
21 | "!**/node_modules/**"
22 | ]
23 | },
24 | {
25 | "type": "node",
26 | "request": "launch",
27 | "name": "SLMessage tests",
28 | "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
29 | "args": [
30 | "test/slmessage.spec.js"
31 | ],
32 | "skipFiles": [
33 | "/**"
34 | ],
35 | "env": {
36 | "DEBUG": "sl:*"
37 | },
38 | "preLaunchTask": "tsc: build - tsconfig.json",
39 | "outFiles": [
40 | "${workspaceFolder}/**/*.js",
41 | "!**/node_modules/**"
42 | ]
43 | },
44 | {
45 | "type": "node",
46 | "request": "launch",
47 | "name": "Password tests",
48 | "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
49 | "args": [
50 | "test/password.spec.js"
51 | ],
52 | "skipFiles": [
53 | "/**"
54 | ],
55 | "env": {
56 | "DEBUG": "sl:*"
57 | },
58 | "preLaunchTask": "tsc: build - tsconfig.json",
59 | "outFiles": [
60 | "${workspaceFolder}/**/*.js",
61 | "!**/node_modules/**"
62 | ]
63 | },
64 | {
65 | "type": "node",
66 | "request": "launch",
67 | "name": "Finder tests",
68 | "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
69 | "args": [
70 | "test/find.spec.js"
71 | ],
72 | "skipFiles": [
73 | "/**"
74 | ],
75 | "env": {
76 | "DEBUG": "sl:*"
77 | },
78 | "preLaunchTask": "tsc: build - tsconfig.json",
79 | "outFiles": [
80 | "${workspaceFolder}/**/*.js",
81 | "!**/node_modules/**"
82 | ]
83 | },
84 | {
85 | "type": "node",
86 | "request": "launch",
87 | "name": "SLUnit tests",
88 | "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
89 | "args": [
90 | "test/unit.spec.js"
91 | ],
92 | "skipFiles": [
93 | "/**"
94 | ],
95 | "env": {
96 | "DEBUG": "sl:*"
97 | },
98 | "preLaunchTask": "tsc: build - tsconfig.json",
99 | "outFiles": [
100 | "${workspaceFolder}/**/*.js",
101 | "!**/node_modules/**"
102 | ]
103 | }
104 | ]
105 | }
--------------------------------------------------------------------------------
/dist/messages/state/ChemMessage.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"ChemMessage.js","sourceRoot":"","sources":["../../../messages/state/ChemMessage.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/dist/messages/OutgoingMessages.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | import { Outbound } from './SLMessage';
3 | import { LightCommands, UnitConnection } from '../index';
4 | import { rawData } from './config/EquipmentConfig';
5 | export declare class Commands extends Outbound {
6 | protected unit: UnitConnection;
7 | constructor(unit: UnitConnection, senderId?: number);
8 | }
9 | export declare class ConnectionCommands extends Commands {
10 | sendLoginMessage(password?: Buffer, senderId?: number): ConnectionCommands;
11 | sendChallengeMessage(senderId?: number): ConnectionCommands;
12 | sendVersionMessage(senderId?: number): ConnectionCommands;
13 | sendAddClientMessage(clientId?: number, senderId?: number): ConnectionCommands;
14 | sendRemoveClientMessage(clientId?: number, senderId?: number): ConnectionCommands;
15 | sendPingMessage(senderId?: number): ConnectionCommands;
16 | }
17 | export declare class EquipmentCommands extends Commands {
18 | sendGetEquipmentStateMessage(senderId?: number): EquipmentCommands;
19 | sendGetControllerConfigMessage(senderId?: number): EquipmentCommands;
20 | sendGetNumCircuitNamesMessage(senderId?: number): EquipmentCommands;
21 | sendGetCircuitNamesMessage(idx: number, cnt: number, senderId?: number): EquipmentCommands;
22 | sendGetCircuitDefinitionsMessage(senderId?: number): EquipmentCommands;
23 | sendGetEquipmentConfigurationMessage(senderId?: number): EquipmentCommands;
24 | sendSetEquipmentConfigurationMessageAsync(data: rawData, senderId?: number): EquipmentCommands;
25 | sendGetSystemTimeMessage(senderId?: number): EquipmentCommands;
26 | sendCancelDelayMessage(senderId?: number): EquipmentCommands;
27 | sendGetCustomNamesMessage(senderId?: number): EquipmentCommands;
28 | sendSetCustomNameMessage(idx: number, name: string, senderId?: number): EquipmentCommands;
29 | sendGetWeatherMessage(senderId?: number): EquipmentCommands;
30 | sendSetSystemTimeMessage(date: Date, shouldAdjustForDST: boolean, senderId?: number): EquipmentCommands;
31 | sendGetHistoryMessage(fromTime: Date, toTime: Date, senderId?: number): EquipmentCommands;
32 | }
33 | export declare class CircuitCommands extends Commands {
34 | sendSetCircuitMessage(circuitId: number, nameIndex: number, circuitFunction: number, circuitInterface: number, freeze: boolean, colorPos: number, senderId?: number): CircuitCommands;
35 | sendSetCircuitStateMessage(circuitId: number, circuitState: boolean, senderId?: number): CircuitCommands;
36 | sendIntellibriteMessage(command: LightCommands, senderId?: number): CircuitCommands;
37 | sendSetCircuitRuntimeMessage(circuitId: number, runTime: number, senderId?: number): CircuitCommands;
38 | }
39 | export declare class ChlorCommands extends Commands {
40 | sendSetChlorOutputMessage(poolOutput: number, spaOutput: number, senderId?: number): ChlorCommands;
41 | sendGetSaltCellConfigMessage(senderId?: number): ChlorCommands;
42 | sendSetSaltCellEnableMessage(isActive?: boolean, senderId?: number): ChlorCommands;
43 | }
44 | export declare class ChemCommands extends Commands {
45 | sendGetChemStatusMessage(senderId?: number): ChemCommands;
46 | sendGetChemHistoryMessage(fromTime: Date, toTime: Date, senderId?: number): ChemCommands;
47 | }
48 | export declare class BodyCommands extends Commands {
49 | sendSetPointMessage(bodyType: number, temperature: number, senderId?: number): BodyCommands;
50 | sendCoolSetPointMessage(bodyType: number, temperature: number, senderId?: number): BodyCommands;
51 | sendHeatModeMessage(bodyType: number, heatMode: number, senderId?: number): BodyCommands;
52 | }
53 | export declare class ScheduleCommands extends Commands {
54 | sendGetSchedulesMessage(schedType: number, senderId?: number): ScheduleCommands;
55 | sendAddScheduleEventMessage(schedType: number, senderId?: number): ScheduleCommands;
56 | sendDeleteScheduleEventMessage(schedId: number, senderId?: number): ScheduleCommands;
57 | sendSetScheduleEventMessage(scheduleId: number, circuitId: number, startTime: number, stopTime: number, dayMask: number, flags: number, heatCmd: number, heatSetPoint: number, senderId?: number): ScheduleCommands;
58 | }
59 | export declare class PumpCommands extends Commands {
60 | sendGetPumpStatusMessage(pumpId: number, senderId?: number): PumpCommands;
61 | sendSetPumpSpeed(pumpId: number, circuitId: number, speed: number, isRPMs?: boolean, senderId?: number): PumpCommands;
62 | }
63 | export declare class OutboundGateway extends Outbound {
64 | createSendGatewayMessage(systemName: string, senderId?: number): Buffer;
65 | }
66 |
--------------------------------------------------------------------------------
/messages/state/ChemMessage.ts:
--------------------------------------------------------------------------------
1 | import { Inbound, SLData } from '../SLMessage';
2 |
3 |
4 | export class ChemMessage {
5 | public static decodeChemDataMessage(msg: Inbound) {
6 | let isValid = false;
7 |
8 | const sentinel = msg.readInt32LE();
9 | if (sentinel === 42) {
10 | isValid = true;
11 | // msg._smartBuffer.readOffset++;
12 | msg.incrementReadOffset(1);
13 | const pH = msg.readUInt16BE() / 100;
14 | const orp = msg.readUInt16BE();
15 | const pHSetPoint = msg.readUInt16BE() / 100;
16 | const orpSetPoint = msg.readUInt16BE();
17 | // msg._smartBuffer.readOffset += 12;
18 | msg.incrementReadOffset(12);
19 | const pHTankLevel = msg.readUInt8();
20 | const orpTankLevel = msg.readUInt8();
21 | let saturation = msg.readUInt8();
22 | if ((saturation & 128) !== 0) {
23 | saturation = -(256 - saturation);
24 | }
25 | saturation /= 100;
26 | const calcium = msg.readUInt16BE();
27 | const cyanuricAcid = msg.readUInt16BE();
28 | const alkalinity = msg.readUInt16BE();
29 | const salt = msg.readUInt16LE();
30 | const saltPPM = salt * 50;
31 | const temperature = msg.readUInt8();
32 | msg.incrementReadOffset(2);
33 | const balance = msg.readUInt8();
34 | const corrosive = (balance & 1) !== 0;
35 | const scaling = (balance & 2) !== 0;
36 | const error = (salt & 128) !== 0;
37 | const data: SLChemData = {
38 | senderId: msg.senderId,
39 | isValid,
40 | pH,
41 | orp,
42 | pHSetPoint,
43 | orpSetPoint,
44 | pHTankLevel,
45 | orpTankLevel,
46 | saturation,
47 | calcium,
48 | cyanuricAcid,
49 | alkalinity,
50 | saltPPM,
51 | temperature,
52 | balance,
53 | corrosive,
54 | scaling,
55 | error
56 | };
57 | return data;
58 | }
59 | }
60 | public static decodecChemHistoryMessage(msg: Inbound) {
61 | const readTimePHPointsPairs = () => {
62 | const retval:TimePHPointsPairs[] = [];
63 | // 4 bytes for the length
64 | if (msg.length >= msg.readOffset + 4) {
65 | const points = msg.readInt32LE();
66 | // 16 bytes per time, 4 bytes per pH reading
67 | if (msg.length >= msg.readOffset + (points * (16 + 4))) {
68 | for (let i = 0; i < points; i++) {
69 | const time = msg.readSLDateTime();
70 | const pH = msg.readInt32LE() / 100;
71 | retval.push({
72 | time: time,
73 | pH: pH,
74 | });
75 | }
76 | }
77 | }
78 |
79 | return retval;
80 | };
81 |
82 | const readTimeORPPointsPairs = () => {
83 | const retval: TimeORPPointsPairs[] = [];
84 | // 4 bytes for the length
85 | if (msg.length >= msg.readOffset + 4) {
86 | const points = msg.readInt32LE();
87 | // 16 bytes per time, 4 bytes per ORP reading
88 | if (msg.length >= msg.readOffset + (points * (16 + 4))) {
89 | for (let i = 0; i < points; i++) {
90 | const time = msg.readSLDateTime();
91 | const orp = msg.readInt32LE();
92 | retval.push({
93 | time: time,
94 | orp: orp,
95 | });
96 | }
97 | }
98 | }
99 |
100 | return retval;
101 | };
102 |
103 | const readTimeTimePointsPairs = () => {
104 | const retval:TimeTimePointsPairs[] = [];
105 | // 4 bytes for the length
106 | if (msg.length >= msg.readOffset + 4) {
107 | const points = msg.readInt32LE();
108 | // 16 bytes per on time, 16 bytes per off time
109 | if (msg.length >= msg.readOffset + (points * (16 + 16))) {
110 | for (let i = 0; i < points; i++) {
111 | const onTime = msg.readSLDateTime();
112 | const offTime = msg.readSLDateTime();
113 | retval.push({
114 | on: onTime,
115 | off: offTime,
116 | });
117 | }
118 | }
119 | }
120 |
121 | return retval;
122 | };
123 | const data: SLChemHistory = {
124 | phPoints: readTimePHPointsPairs(),
125 | orpPoints: readTimeORPPointsPairs(),
126 | phRuns: readTimeTimePointsPairs(),
127 | orpRuns: readTimeTimePointsPairs()
128 | };
129 | return data;
130 | }
131 | }
132 |
133 | export namespace ChemMessage { // eslint-disable-line @typescript-eslint/no-namespace
134 | export enum ResponseIDs {
135 | AsyncChemicalData = 12505,
136 | ChemicalHistoryData = 12506,
137 | HistoryDataPending = 12597,
138 | GetChemicalData = 12593,
139 | }
140 | }
141 |
142 | export interface SLChemData extends SLData {
143 | isValid: boolean;
144 | pH: number;
145 | orp: number;
146 | pHSetPoint: number;
147 | orpSetPoint: number;
148 | pHTankLevel: number;
149 | orpTankLevel: number;
150 | saturation: number;
151 | calcium: number;
152 | cyanuricAcid: number;
153 | alkalinity: number;
154 | saltPPM: number;
155 | temperature: number;
156 | balance: number;
157 | corrosive: boolean;
158 | scaling: boolean;
159 | error: boolean;
160 | }
161 |
162 | export interface TimePHPointsPairs {
163 | time: Date;
164 | pH: number;
165 | }
166 | export interface TimeORPPointsPairs {
167 | time: Date;
168 | orp: number;
169 | }
170 | export interface TimeTimePointsPairs {
171 | on: Date;
172 | off: Date;
173 | }
174 | export interface SLChemHistory {
175 | phPoints: TimePHPointsPairs[];
176 | orpPoints: TimeORPPointsPairs[];
177 | phRuns: TimeTimePointsPairs[];
178 | orpRuns: TimeTimePointsPairs[];
179 | }
180 |
--------------------------------------------------------------------------------
/dist/messages/state/ChemMessage.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | exports.ChemMessage = void 0;
4 | class ChemMessage {
5 | static decodeChemDataMessage(msg) {
6 | let isValid = false;
7 | const sentinel = msg.readInt32LE();
8 | if (sentinel === 42) {
9 | isValid = true;
10 | // msg._smartBuffer.readOffset++;
11 | msg.incrementReadOffset(1);
12 | const pH = msg.readUInt16BE() / 100;
13 | const orp = msg.readUInt16BE();
14 | const pHSetPoint = msg.readUInt16BE() / 100;
15 | const orpSetPoint = msg.readUInt16BE();
16 | // msg._smartBuffer.readOffset += 12;
17 | msg.incrementReadOffset(12);
18 | const pHTankLevel = msg.readUInt8();
19 | const orpTankLevel = msg.readUInt8();
20 | let saturation = msg.readUInt8();
21 | if ((saturation & 128) !== 0) {
22 | saturation = -(256 - saturation);
23 | }
24 | saturation /= 100;
25 | const calcium = msg.readUInt16BE();
26 | const cyanuricAcid = msg.readUInt16BE();
27 | const alkalinity = msg.readUInt16BE();
28 | const salt = msg.readUInt16LE();
29 | const saltPPM = salt * 50;
30 | const temperature = msg.readUInt8();
31 | msg.incrementReadOffset(2);
32 | const balance = msg.readUInt8();
33 | const corrosive = (balance & 1) !== 0;
34 | const scaling = (balance & 2) !== 0;
35 | const error = (salt & 128) !== 0;
36 | const data = {
37 | senderId: msg.senderId,
38 | isValid,
39 | pH,
40 | orp,
41 | pHSetPoint,
42 | orpSetPoint,
43 | pHTankLevel,
44 | orpTankLevel,
45 | saturation,
46 | calcium,
47 | cyanuricAcid,
48 | alkalinity,
49 | saltPPM,
50 | temperature,
51 | balance,
52 | corrosive,
53 | scaling,
54 | error
55 | };
56 | return data;
57 | }
58 | }
59 | static decodecChemHistoryMessage(msg) {
60 | const readTimePHPointsPairs = () => {
61 | const retval = [];
62 | // 4 bytes for the length
63 | if (msg.length >= msg.readOffset + 4) {
64 | const points = msg.readInt32LE();
65 | // 16 bytes per time, 4 bytes per pH reading
66 | if (msg.length >= msg.readOffset + (points * (16 + 4))) {
67 | for (let i = 0; i < points; i++) {
68 | const time = msg.readSLDateTime();
69 | const pH = msg.readInt32LE() / 100;
70 | retval.push({
71 | time: time,
72 | pH: pH,
73 | });
74 | }
75 | }
76 | }
77 | return retval;
78 | };
79 | const readTimeORPPointsPairs = () => {
80 | const retval = [];
81 | // 4 bytes for the length
82 | if (msg.length >= msg.readOffset + 4) {
83 | const points = msg.readInt32LE();
84 | // 16 bytes per time, 4 bytes per ORP reading
85 | if (msg.length >= msg.readOffset + (points * (16 + 4))) {
86 | for (let i = 0; i < points; i++) {
87 | const time = msg.readSLDateTime();
88 | const orp = msg.readInt32LE();
89 | retval.push({
90 | time: time,
91 | orp: orp,
92 | });
93 | }
94 | }
95 | }
96 | return retval;
97 | };
98 | const readTimeTimePointsPairs = () => {
99 | const retval = [];
100 | // 4 bytes for the length
101 | if (msg.length >= msg.readOffset + 4) {
102 | const points = msg.readInt32LE();
103 | // 16 bytes per on time, 16 bytes per off time
104 | if (msg.length >= msg.readOffset + (points * (16 + 16))) {
105 | for (let i = 0; i < points; i++) {
106 | const onTime = msg.readSLDateTime();
107 | const offTime = msg.readSLDateTime();
108 | retval.push({
109 | on: onTime,
110 | off: offTime,
111 | });
112 | }
113 | }
114 | }
115 | return retval;
116 | };
117 | const data = {
118 | phPoints: readTimePHPointsPairs(),
119 | orpPoints: readTimeORPPointsPairs(),
120 | phRuns: readTimeTimePointsPairs(),
121 | orpRuns: readTimeTimePointsPairs()
122 | };
123 | return data;
124 | }
125 | }
126 | exports.ChemMessage = ChemMessage;
127 | (function (ChemMessage) {
128 | let ResponseIDs;
129 | (function (ResponseIDs) {
130 | ResponseIDs[ResponseIDs["AsyncChemicalData"] = 12505] = "AsyncChemicalData";
131 | ResponseIDs[ResponseIDs["ChemicalHistoryData"] = 12506] = "ChemicalHistoryData";
132 | ResponseIDs[ResponseIDs["HistoryDataPending"] = 12597] = "HistoryDataPending";
133 | ResponseIDs[ResponseIDs["GetChemicalData"] = 12593] = "GetChemicalData";
134 | })(ResponseIDs = ChemMessage.ResponseIDs || (ChemMessage.ResponseIDs = {}));
135 | })(ChemMessage = exports.ChemMessage || (exports.ChemMessage = {}));
136 | //# sourceMappingURL=ChemMessage.js.map
--------------------------------------------------------------------------------
/dist/messages/SLMessage.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"SLMessage.js","sourceRoot":"","sources":["../../messages/SLMessage.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/dist/messages/SLMessage.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | exports.Outbound = exports.Inbound = exports.SLMessage = void 0;
4 | const smart_buffer_1 = require("smart-buffer");
5 | const DAY_VALUES = {
6 | Mon: 0x1,
7 | Tue: 0x2,
8 | Wed: 0x4,
9 | Thu: 0x8,
10 | Fri: 0x10,
11 | Sat: 0x20,
12 | Sun: 0x40,
13 | };
14 | class SLMessage {
15 | constructor(controllerId, senderId) {
16 | this.senderId = 0;
17 | this.controllerId = 0;
18 | this.controllerId = controllerId !== null && controllerId !== void 0 ? controllerId : 0;
19 | this.senderId = senderId !== null && senderId !== void 0 ? senderId : 0;
20 | }
21 | get readOffset() { return this._smartBuffer.readOffset; }
22 | get length() { return this._smartBuffer.length; }
23 | static slackForAlignment(val) {
24 | return (4 - val % 4) % 4;
25 | }
26 | getDayValue(dayName) {
27 | if (!(dayName in DAY_VALUES)) {
28 | return 0;
29 | }
30 | return DAY_VALUES[dayName];
31 | }
32 | toBuffer() {
33 | return this._smartBuffer.toBuffer();
34 | }
35 | }
36 | exports.SLMessage = SLMessage;
37 | class Inbound extends SLMessage {
38 | readFromBuffer(buf) {
39 | this._smartBuffer = smart_buffer_1.SmartBuffer.fromBuffer(buf);
40 | this.decode();
41 | }
42 | readMessage(buf) {
43 | this._wroteSize = true;
44 | this._smartBuffer.writeBuffer(buf, 0);
45 | this.decode();
46 | }
47 | readSLString() {
48 | const len = this._smartBuffer.readInt32LE();
49 | const str = this._smartBuffer.readString(len);
50 | this._smartBuffer.readOffset += SLMessage.slackForAlignment(len);
51 | return str;
52 | }
53 | readSLArray() {
54 | const len = this._smartBuffer.readInt32LE();
55 | const retval = new Array(len);
56 | for (let i = 0; i < len; i++) {
57 | retval[i] = this._smartBuffer.readUInt8();
58 | }
59 | this._smartBuffer.readOffset += SLMessage.slackForAlignment(len);
60 | return retval;
61 | }
62 | decode() {
63 | this._smartBuffer.readOffset = 0;
64 | this.senderId = this._smartBuffer.readUInt16LE();
65 | this.action = this._smartBuffer.readUInt16LE();
66 | this.dataLength = this._smartBuffer.readInt32LE();
67 | }
68 | isBitSet(value, bit) {
69 | return ((value >> bit) & 0x1) === 1;
70 | }
71 | decodeTime(rawTime) {
72 | let retVal;
73 | retVal = Math.floor(rawTime / 60) * 100 + rawTime % 60;
74 | retVal = String(retVal).padStart(4, '0');
75 | return retVal;
76 | }
77 | decodeDayMask(dayMask) {
78 | const days = [];
79 | for (let i = 0; i < 7; i++) {
80 | if (this.isBitSet(dayMask, i)) {
81 | days.push(Object.keys(DAY_VALUES)[i]);
82 | }
83 | }
84 | return days;
85 | }
86 | readSLDateTime() {
87 | const year = this._smartBuffer.readInt16LE();
88 | const month = this._smartBuffer.readInt16LE() - 1;
89 | this._smartBuffer.readInt16LE(); // day of week
90 | const day = this._smartBuffer.readInt16LE();
91 | const hour = this._smartBuffer.readInt16LE();
92 | const minute = this._smartBuffer.readInt16LE();
93 | const second = this._smartBuffer.readInt16LE();
94 | const millisecond = this._smartBuffer.readInt16LE();
95 | const date = new Date(year, month, day, hour, minute, second, millisecond);
96 | return date;
97 | }
98 | readUInt8() {
99 | return this._smartBuffer.readUInt8();
100 | }
101 | readUInt16BE() {
102 | return this._smartBuffer.readUInt16BE();
103 | }
104 | readUInt16LE() {
105 | return this._smartBuffer.readUInt16LE();
106 | }
107 | readInt32LE() {
108 | return this._smartBuffer.readInt32LE();
109 | }
110 | readUInt32LE() {
111 | return this._smartBuffer.readUInt32LE();
112 | }
113 | incrementReadOffset(val) {
114 | this._smartBuffer.readOffset = this._smartBuffer.readOffset + val;
115 | }
116 | toString() {
117 | return this._smartBuffer.toString();
118 | }
119 | toHexStream() {
120 | return this._smartBuffer.toString('hex');
121 | }
122 | }
123 | exports.Inbound = Inbound;
124 | class Outbound extends SLMessage {
125 | constructor(controllerId, senderId, messageId) {
126 | super(controllerId, senderId);
127 | this.action = messageId;
128 | }
129 | createBaseMessage(senderId) {
130 | this._smartBuffer = new smart_buffer_1.SmartBuffer();
131 | this.addHeader(senderId);
132 | }
133 | addHeader(senderId) {
134 | this._smartBuffer.writeUInt16LE(senderId !== null && senderId !== void 0 ? senderId : this.senderId);
135 | this._smartBuffer.writeUInt16LE(this.action);
136 | this._wroteSize = false;
137 | }
138 | encodeDayMask(daysArray) {
139 | let dayMask = 0;
140 | for (let i = 0; i < daysArray.length; i++) {
141 | dayMask += this.getDayValue(daysArray[i]);
142 | }
143 | return dayMask;
144 | }
145 | writeSLDateTime(date) {
146 | this._smartBuffer.writeInt16LE(date.getFullYear());
147 | this._smartBuffer.writeInt16LE(date.getMonth() + 1);
148 | this._smartBuffer.writeInt16LE(date.getDay() + 1);
149 | this._smartBuffer.writeInt16LE(date.getDate());
150 | this._smartBuffer.writeInt16LE(date.getHours());
151 | this._smartBuffer.writeInt16LE(date.getMinutes());
152 | this._smartBuffer.writeInt16LE(date.getSeconds());
153 | this._smartBuffer.writeInt16LE(date.getMilliseconds());
154 | }
155 | writeInt32LE(val) {
156 | this._smartBuffer.writeInt32LE(val);
157 | }
158 | encode() { null; }
159 | static getResponseId() {
160 | return this.MSG_ID + 1;
161 | }
162 | toBuffer() {
163 | this.encode();
164 | if (this._wroteSize === false) {
165 | this._smartBuffer.insertInt32LE(this._smartBuffer.length - 4, 4);
166 | this._wroteSize = true;
167 | }
168 | else {
169 | this._smartBuffer.writeInt32LE(this._smartBuffer.length - 8, 4);
170 | }
171 | return this._smartBuffer.toBuffer();
172 | }
173 | writeSLString(str) {
174 | this._smartBuffer.writeInt32LE(str.length);
175 | this._smartBuffer.writeString(str);
176 | this.skipWrite(SLMessage.slackForAlignment(str.length));
177 | }
178 | writeSLBuffer(buf) {
179 | this._smartBuffer.writeInt32LE(buf.length);
180 | this._smartBuffer.writeBuffer(buf);
181 | }
182 | writeSLArray(arr) {
183 | this._smartBuffer.writeInt32LE(arr.length);
184 | for (let i = 0; i < arr.length; i++) {
185 | this._smartBuffer.writeUInt8(arr[i]);
186 | }
187 | this.skipWrite(SLMessage.slackForAlignment(arr.length));
188 | }
189 | skipWrite(num) {
190 | if (num > 0) {
191 | this._smartBuffer.writeBuffer(Buffer.alloc(num));
192 | }
193 | }
194 | encodeTime(stringTime) {
195 | return (Number(stringTime.substring(0, 2)) * 60) + Number(stringTime.substring(2, 4));
196 | }
197 | }
198 | exports.Outbound = Outbound;
199 | //# sourceMappingURL=SLMessage.js.map
--------------------------------------------------------------------------------
/messages/SLMessage.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { SmartBuffer } from 'smart-buffer';
4 |
5 | interface Map {
6 | [key: string]: number
7 | }
8 |
9 | const DAY_VALUES: Map = {
10 | Mon: 0x1,
11 | Tue: 0x2,
12 | Wed: 0x4,
13 | Thu: 0x8,
14 | Fri: 0x10,
15 | Sat: 0x20,
16 | Sun: 0x40,
17 | };
18 |
19 |
20 | export interface SLData {
21 | senderId: number;
22 | }
23 |
24 |
25 | export interface SLSimpleBoolData extends SLData {
26 | val: boolean
27 | }
28 |
29 |
30 | export interface SLSimpleNumberData extends SLData {
31 | val: number
32 | }
33 |
34 |
35 | export class SLMessage {
36 | static MSG_ID: number;
37 | constructor(controllerId?: number, senderId?: number) {
38 | this.controllerId = controllerId ?? 0;
39 | this.senderId = senderId ?? 0;
40 | }
41 | protected _wroteSize: boolean;
42 | public action: number;
43 | public senderId = 0;
44 | public controllerId = 0;
45 | protected dataLength: number;
46 | protected _smartBuffer: SmartBuffer;
47 | public get readOffset() { return this._smartBuffer.readOffset; }
48 | public get length() { return this._smartBuffer.length; }
49 | public static slackForAlignment(val: number) {
50 | return (4 - val % 4) % 4;
51 | }
52 | public getDayValue(dayName: string): number {
53 | if (!(dayName in DAY_VALUES)) {
54 | return 0;
55 | }
56 | return DAY_VALUES[dayName];
57 | }
58 | public toBuffer() {
59 | return this._smartBuffer.toBuffer();
60 | }
61 | }
62 |
63 | export class Inbound extends SLMessage {
64 | public readFromBuffer(buf: Buffer) {
65 | this._smartBuffer = SmartBuffer.fromBuffer(buf);
66 | this.decode();
67 | }
68 | public readMessage(buf: Buffer) {
69 | this._wroteSize = true;
70 | this._smartBuffer.writeBuffer(buf, 0);
71 |
72 | this.decode();
73 | }
74 | public readSLString() {
75 | const len = this._smartBuffer.readInt32LE();
76 | const str = this._smartBuffer.readString(len);
77 | this._smartBuffer.readOffset += SLMessage.slackForAlignment(len);
78 | return str;
79 | }
80 | readSLArray(): Array {
81 | const len = this._smartBuffer.readInt32LE();
82 |
83 | const retval = new Array(len);
84 | for (let i = 0; i < len; i++) {
85 | retval[i] = this._smartBuffer.readUInt8();
86 | }
87 |
88 | this._smartBuffer.readOffset += SLMessage.slackForAlignment(len);
89 |
90 | return retval;
91 | }
92 | decode() {
93 | this._smartBuffer.readOffset = 0;
94 | this.senderId = this._smartBuffer.readUInt16LE();
95 | this.action = this._smartBuffer.readUInt16LE();
96 | this.dataLength = this._smartBuffer.readInt32LE();
97 | }
98 | isBitSet(value: number, bit: number): boolean {
99 | return ((value >> bit) & 0x1) === 1;
100 | }
101 | decodeTime(rawTime: number) { // Takes 'rawTime' in mins past midnight and returns military time as a string
102 | let retVal;
103 |
104 | retVal = Math.floor(rawTime / 60) * 100 + rawTime % 60;
105 |
106 | retVal = String(retVal).padStart(4, '0');
107 |
108 | return retVal;
109 | }
110 | decodeDayMask(dayMask: number): string[] {
111 | const days = [];
112 |
113 | for (let i = 0; i < 7; i++) {
114 | if (this.isBitSet(dayMask, i)) {
115 | days.push(Object.keys(DAY_VALUES)[i]);
116 | }
117 | }
118 | return days;
119 | }
120 |
121 | readSLDateTime() {
122 | const year = this._smartBuffer.readInt16LE();
123 | const month = this._smartBuffer.readInt16LE() - 1;
124 | this._smartBuffer.readInt16LE(); // day of week
125 | const day = this._smartBuffer.readInt16LE();
126 | const hour = this._smartBuffer.readInt16LE();
127 | const minute = this._smartBuffer.readInt16LE();
128 | const second = this._smartBuffer.readInt16LE();
129 | const millisecond = this._smartBuffer.readInt16LE();
130 |
131 | const date = new Date(year, month, day, hour, minute, second, millisecond);
132 | return date;
133 | }
134 | readUInt8() {
135 | return this._smartBuffer.readUInt8();
136 | }
137 | readUInt16BE() {
138 | return this._smartBuffer.readUInt16BE();
139 | }
140 | readUInt16LE() {
141 | return this._smartBuffer.readUInt16LE();
142 | }
143 | readInt32LE() {
144 | return this._smartBuffer.readInt32LE();
145 | }
146 | readUInt32LE() {
147 | return this._smartBuffer.readUInt32LE();
148 | }
149 | incrementReadOffset(val: number) {
150 | this._smartBuffer.readOffset = this._smartBuffer.readOffset + val;
151 | }
152 | toString() {
153 | return this._smartBuffer.toString();
154 | }
155 | toHexStream() {
156 | return this._smartBuffer.toString('hex');
157 | }
158 | }
159 |
160 |
161 | export class Outbound extends SLMessage {
162 | constructor(controllerId?: number, senderId?: number, messageId?: number) {
163 | super(controllerId, senderId);
164 |
165 | this.action = messageId;
166 | }
167 | public createBaseMessage(senderId?: number) {
168 | this._smartBuffer = new SmartBuffer();
169 | this.addHeader(senderId);
170 | }
171 | public addHeader(senderId?: number) {
172 |
173 | this._smartBuffer.writeUInt16LE(senderId ?? this.senderId);
174 | this._smartBuffer.writeUInt16LE(this.action);
175 |
176 | this._wroteSize = false;
177 | }
178 |
179 | encodeDayMask(daysArray: string[]) {
180 | let dayMask = 0;
181 |
182 | for (let i = 0; i < daysArray.length; i++) {
183 | dayMask += this.getDayValue(daysArray[i]);
184 | }
185 | return dayMask;
186 | }
187 | writeSLDateTime(date: Date) {
188 | this._smartBuffer.writeInt16LE(date.getFullYear());
189 | this._smartBuffer.writeInt16LE(date.getMonth() + 1);
190 | this._smartBuffer.writeInt16LE(date.getDay() + 1);
191 | this._smartBuffer.writeInt16LE(date.getDate());
192 | this._smartBuffer.writeInt16LE(date.getHours());
193 | this._smartBuffer.writeInt16LE(date.getMinutes());
194 | this._smartBuffer.writeInt16LE(date.getSeconds());
195 | this._smartBuffer.writeInt16LE(date.getMilliseconds());
196 | }
197 | writeInt32LE(val: number) {
198 | this._smartBuffer.writeInt32LE(val);
199 | }
200 | encode() { null; }
201 | static getResponseId() {
202 | return this.MSG_ID + 1;
203 | }
204 | public toBuffer() {
205 | this.encode();
206 |
207 | if (this._wroteSize === false) {
208 | this._smartBuffer.insertInt32LE(this._smartBuffer.length - 4, 4);
209 | this._wroteSize = true;
210 | } else {
211 | this._smartBuffer.writeInt32LE(this._smartBuffer.length - 8, 4);
212 | }
213 |
214 | return this._smartBuffer.toBuffer();
215 | }
216 | writeSLString(str: string) {
217 | this._smartBuffer.writeInt32LE(str.length);
218 | this._smartBuffer.writeString(str);
219 | this.skipWrite(SLMessage.slackForAlignment(str.length));
220 | }
221 | writeSLBuffer(buf: Buffer) {
222 | this._smartBuffer.writeInt32LE(buf.length);
223 | this._smartBuffer.writeBuffer(buf);
224 | }
225 | writeSLArray(arr: Buffer) {
226 | this._smartBuffer.writeInt32LE(arr.length);
227 |
228 | for (let i = 0; i < arr.length; i++) {
229 | this._smartBuffer.writeUInt8(arr[i]);
230 | }
231 |
232 | this.skipWrite(SLMessage.slackForAlignment(arr.length));
233 | }
234 | skipWrite(num: number) {
235 | if (num > 0) {
236 | this._smartBuffer.writeBuffer(Buffer.alloc(num));
237 | }
238 | }
239 | encodeTime(stringTime: string) { // Takes 'stringTime' as military time and returns mins past midnight
240 | return (Number(stringTime.substring(0, 2)) * 60) + Number(stringTime.substring(2, 4));
241 | }
242 | }
243 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## v2.1.1 - 2024-10-07
9 |
10 | ### Fixed
11 |
12 | * Fixed equipment.getCircuitNamesAsync timing out due to not listening to the correct event internally.
13 |
14 | ## v2.1.0 - 2024-06-19
15 |
16 | ### Fixed
17 |
18 | * Fixed bodies.setHeatModeAsync incorrectly subtracting one from the given body index. This is a breaking change if you were correcting for the offset already.
19 |
20 | ## v2.0.0 - 2023-03-10
21 |
22 | This major version number increase comes with many changes under the hood, including a rename of most every method in the library. This adds Promises and Typescript support. See the [Migration guide](https://github.com/parnic/node-screenlogic/wiki/Migration-guide) and [Breaking changes](https://github.com/parnic/node-screenlogic/wiki/Breaking-changes) wiki pages for detailed information.
23 |
24 | ## v1.10.1 - 2022-05-31
25 |
26 | ### Added
27 |
28 | * Added simple "ping" message as a lightweight way to keep the connection alive for a user using the addClient() api.
29 |
30 | ### Fixed
31 |
32 | * Fixed Date parsing from ScreenLogic packets returning the wrong date under specific conditions (such as the last day of the month or during specific hours when javascript month/day assignment order can change other parts of the date).
33 |
34 | ### Changed
35 |
36 | * Improved FindUnits.search() to support being called multiple times. This function issues one UDP broadcast per call, so consumer applications may need to run it in a delayed loop if no units are found on the first request (e.g. when the device running the search or the pool equipment is temporarily disconnected from the network). This is a stateless UDP query, so client applications cannot rely on the error or close events to issue retries.
37 |
38 | ## v1.10.0 - 2022-05-23
39 |
40 | ### Added
41 |
42 | * Added capturing of weather forecast events so that we're not treating it as an unknown message. This also includes full handling for getting weather forecasts from the equipment, but in my experience it's either outdated or not as thorough/reliable as we could get from pretty much any other source, so it remains undocumented for now.
43 | * Added handling of asynchronous chemicalData messages. These are received periodically through the addClient() data push feature.
44 |
45 | ### Fixed
46 |
47 | * Fixed an ugly problem where the library could hang and fail to hand off any more messages if multiple messages were received at the same time (which I've seen happen on lower powered hardware like a Raspberry Pi). This would also cause the internal data buffer to grow unbounded as long as the UnitConnection stayed alive.
48 |
49 | ## v1.9.1 - 2022-05-20
50 |
51 | ### Added
52 |
53 | * Added `close` event to FindUnits, RemoteLogin, and UnitConnection for when the connection to the endpoint has closed.
54 |
55 | ## v1.9.0 - 2022-05-20
56 |
57 | ### Added
58 |
59 | * Added support for getting system chemical history data. This includes pH and ORP readings over time as well as pH and ORP feed on/off times.
60 |
61 | ## v1.8.0 - 2022-04-17
62 |
63 | ### Added
64 |
65 | * Added support for reading ScreenLogic time packets.
66 | * Added support for getting system history data. This includes temperature readings over time as well as circuit on/off changes over time.
67 |
68 | ### Fixed
69 |
70 | * Updated dependencies to safer versions of some packages.
71 | * Fixed day-of-week conversion from Javascript Date objects to ScreenLogic times (SLTimes are 1-based starting on Sunday).
72 |
73 | ### Changed
74 |
75 | * Alphabetized the readme.
76 |
77 | ## v1.7.0 - 2021-10-13
78 |
79 | ### Added
80 |
81 | * Added handling/documentation for the scheduleChanged event (#44).
82 | * Added support for getting and setting the system date/time.
83 |
84 | ### Fixed
85 |
86 | * Documentation updates for `SLGetScheduleData`, more linkage for easy navigation, `addClient`/`removeClient` methods, clarified `coolSetPoint` for spas.
87 |
88 | ## v1.6.1 - 2020-11-23
89 |
90 | ### Added
91 |
92 | * Every call now can optionally specify an ID that will be returned with the result, allowing tracking of simultaneous commands.
93 |
94 | ## v1.6.0 - 2020-07-14
95 |
96 | ### Added
97 |
98 | * Fleshed out the still-undocumented `SLEquipmentConfigurationMessage` with a few more helper methods for interpreting the data inside.
99 | * Helper method for getting a circuit from its device ID on an `SLControllerConfigMessage`.
100 | * Support for getting the status of pumps and setting flow speeds per-pump-per-circuit.
101 | * Constants for interpreting heat command/mode properties on various messages:
102 | * ScreenLogic.HEAT_MODE_OFF
103 | * ScreenLogic.HEAT_MODE_SOLAR
104 | * ScreenLogic.HEAT_MODE_SOLARPREFERRED
105 | * ScreenLogic.HEAT_MODE_HEATPUMP
106 | * ScreenLogic.HEAT_MODE_DONTCHANGE
107 | * Debug logs using the "debug" NPM package. You'll need to run an `npm install` after updating to this version.
108 | * Ability to cancel delays in pool equipment. #20 - thanks @bshep
109 | * Ability to register for push messages from the equipment so the connection can be kept open instead of repeatedly reconnecting and polling for changes. See the `addClient()` and `removeClient()` functions on the `UnitConnection` docs. Thanks @bshep
110 |
111 | ## v1.5.0 - 2020-06-06
112 |
113 | ### Added
114 |
115 | * Added support for adding, deleting, listing, and updating scheduled events - thanks @bshep
116 | * Added egg timer support - thanks @bshep
117 |
118 | ## v1.4.0 - 2020-05-25
119 |
120 | ### Added
121 |
122 | * Support for controlling the salt cell generator's output levels.
123 | * Helper methods for interpreting `controllerType`.
124 | * Experimental support for an Equipment Configuration message (not documented as of yet - `SLEquipmentConfigurationMessage` / `getEquipmentConfiguration()`). This message returns arrays of various information about the equipment, but I don't know how to interpret the information in those arrays yet. Any assistance with decoding this information would be hugely helpful.
125 | * `error` handler on all objects for reacting to unhandled node errors - thanks @schemers
126 |
127 | ### Fixed
128 |
129 | * VSCode "Example" configuration can now be launched on non-Windows platforms.
130 |
131 | ### Changed
132 |
133 | * Minor memory/performance optimizations.
134 | * Running tests no longer changes any state of any pool equipment.
135 |
136 | ## v1.3.1 - 2019-12-27
137 |
138 | ### Added
139 |
140 | * Several methods added to SLControllerConfigMessage for interpreting the equipFlags value.
141 |
142 | ### Fixed
143 |
144 | * server.gatewayName no longer cuts off the last character of the name. #14 - thanks @mikemucc
145 |
146 | ## v1.3.0 - 2019-11-26
147 |
148 | ### Added
149 |
150 | * Ability to set heat setpoint.
151 | * Ability to set heat mode.
152 | * Event for supplying incorrect parameters to `set` functions.
153 | * Ability to send limited selection of light commands.
154 |
155 | ## v1.2.1 - 2019-03-26
156 |
157 | ### Fixed
158 |
159 | * Messages larger than 1024 bytes are now handled properly.
160 |
161 | ## v1.2.0 - 2019-02-22
162 |
163 | ### Added
164 |
165 | * Remote connection through Pentair servers
166 | * Connecting to password-protected systems (this is only enforced by the ScreenLogic system on remote connections)
167 |
168 | ## v1.1.0 - 2018-04-23
169 |
170 | ### Added
171 |
172 | * Ability to set circuit state.
173 |
174 | ### Fixed
175 |
176 | * FindUnits.sendServerBroadcast() was failing in certain environments.
177 |
178 | ## v1.0.1 - 2018-03-31
179 |
180 | ### Added
181 |
182 | * Direct connection support.
183 |
184 | ## v1.0.0 - 2018-03-31
185 |
186 | * Initial release
187 |
--------------------------------------------------------------------------------
/dist/messages/config/EquipmentConfig.d.ts:
--------------------------------------------------------------------------------
1 | import { PumpTypes } from '../../index';
2 | import { Inbound, SLData, SLSimpleBoolData } from '../SLMessage';
3 | export declare class EquipmentConfigurationMessage {
4 | static decodeCircuitDefinitions(msg: Inbound): SLCircuitNamesData;
5 | static decodeNCircuitNames(msg: Inbound): number;
6 | static decodeCircuitNames(msg: Inbound): SLCircuitNamesData;
7 | static decodeControllerConfig(msg: Inbound): SLControllerConfigData;
8 | static isEasyTouch(controllerType: number): boolean;
9 | static isIntelliTouch(controllerType: number): boolean;
10 | static isEasyTouchLite(controllerType: number, hwType: number): boolean;
11 | static isDualBody(controllerType: number): boolean;
12 | static isChem2(controllerType: number, hwType: number): boolean;
13 | static decodeSetEquipmentConfigurationAck(msg: Inbound): SLSimpleBoolData;
14 | static decodeSetEquipmentConfiguration(msg: Inbound): SLSetEquipmentConfigurationData;
15 | private static _getNumPumps;
16 | private static _getPumpData;
17 | private static _isValvePresent;
18 | private static _loadHeaterData;
19 | private static _loadValveData;
20 | private static _loadDelayData;
21 | private static _loadMiscData;
22 | private static _loadSpeedData;
23 | private static _loadLightData;
24 | private static _loadRemoteData;
25 | private static _loadSpaFlowData;
26 | static decodeGetEquipmentConfiguration(msg: Inbound): SLEquipmentConfigurationData;
27 | static decodeWeatherMessage(msg: Inbound): SLWeatherForecastData;
28 | static decodeGetHistory(msg: Inbound): SLHistoryData;
29 | getCircuitName(poolConfig: SLEquipmentConfigurationData, circuitIndex: number): string;
30 | static decodeCustomNames(msg: Inbound): SLGetCustomNamesData;
31 | static decodeSetCustomNameAck(msg: Inbound): SLSimpleBoolData;
32 | }
33 | export declare namespace EquipmentConfigurationMessage {
34 | enum ResponseIDs {
35 | WeatherForecastChanged = 9806,
36 | WeatherForecastAck = 9808,
37 | GetHistoryData = 12502,
38 | GetCircuitDefinitions = 12511,
39 | GetControllerConfig = 12533,
40 | HistoryDataPending = 12535,
41 | NumCircuitNames = 12559,
42 | AsyncCircuitNames = 12560,
43 | GetCircuitNames = 12562,
44 | GetCustomNamesAck = 12563,
45 | SetCustomNameAck = 12565,
46 | GetEquipmentConfiguration = 12567,
47 | SetEquipmentConfiguration = 12568,
48 | SetEquipmentConfigurationAck = 12569
49 | }
50 | }
51 | export interface SLControllerConfigData extends SLData {
52 | controllerId: number;
53 | minSetPoint: number[];
54 | maxSetPoint: number[];
55 | degC: boolean;
56 | controllerType: number;
57 | circuitCount: number;
58 | hwType: number;
59 | controllerData: number;
60 | equipment: Equipment;
61 | genCircuitName: string;
62 | interfaceTabFlags: number;
63 | circuitArray: Circuit[];
64 | colorCount: number;
65 | colorArray: SLNameColor[];
66 | pumpCircCount: number;
67 | pumpCircArray: number[];
68 | showAlarms: number;
69 | }
70 | export interface Equipment {
71 | POOL_SOLARPRESENT: boolean;
72 | POOL_SOLARHEATPUMP: boolean;
73 | POOL_CHLORPRESENT: boolean;
74 | POOL_IBRITEPRESENT: boolean;
75 | POOL_IFLOWPRESENT0: boolean;
76 | POOL_IFLOWPRESENT1: boolean;
77 | POOL_IFLOWPRESENT2: boolean;
78 | POOL_IFLOWPRESENT3: boolean;
79 | POOL_IFLOWPRESENT4: boolean;
80 | POOL_IFLOWPRESENT5: boolean;
81 | POOL_IFLOWPRESENT6: boolean;
82 | POOL_IFLOWPRESENT7: boolean;
83 | POOL_NO_SPECIAL_LIGHTS: boolean;
84 | POOL_HEATPUMPHASCOOL: boolean;
85 | POOL_MAGICSTREAMPRESENT: boolean;
86 | POOL_ICHEMPRESENT: boolean;
87 | }
88 | export interface Circuit {
89 | circuitId: number;
90 | name: string;
91 | nameIndex: number;
92 | function: number;
93 | interface: number;
94 | freeze: number;
95 | colorSet?: number;
96 | colorPos?: number;
97 | colorStagger?: number;
98 | eggTimer: number;
99 | deviceId: number;
100 | }
101 | export interface SLColor {
102 | r: number;
103 | g: number;
104 | b: number;
105 | }
106 | export interface SLNameColor {
107 | name: string;
108 | color: SLColor;
109 | }
110 | export interface SLSetEquipmentConfigurationData extends SLData {
111 | pumps: Pump[];
112 | heaterConfig: HeaterConfig;
113 | valves: Valves[];
114 | delays: Delays;
115 | misc: Misc;
116 | lights: Lights;
117 | highSpeedCircuits: number[];
118 | remotes: SLRemoteData;
119 | numPumps: number;
120 | }
121 | export interface SLEquipmentConfigurationData extends SLData {
122 | controllerType: number;
123 | hardwareType: number;
124 | expansionsCount: number;
125 | version: number;
126 | pumps: Pump[];
127 | heaterConfig: HeaterConfig;
128 | valves: Valves[];
129 | delays: Delays;
130 | misc: Misc;
131 | remotes: SLRemoteData;
132 | highSpeedCircuits: number[];
133 | lights: Lights;
134 | spaFlow: SpaFlow;
135 | numPumps: number;
136 | rawData: rawData;
137 | }
138 | export interface SLRemoteData {
139 | fourButton: number[];
140 | tenButton: number[][];
141 | quickTouch: number[];
142 | }
143 | export interface rawData {
144 | versionData: number[];
145 | highSpeedCircuitData: number[];
146 | valveData: number[];
147 | remoteData: number[];
148 | heaterConfigData: number[];
149 | delayData: number[];
150 | macroData: number[];
151 | miscData: number[];
152 | lightData: number[];
153 | pumpData: number[];
154 | sgData: number[];
155 | spaFlowData: number[];
156 | }
157 | export interface PumpCircuit {
158 | id: number;
159 | circuit: number;
160 | speed?: number;
161 | flow?: number;
162 | units: number;
163 | }
164 | export interface Pump {
165 | id: number;
166 | type: number;
167 | pentairType: PumpTypes;
168 | name: string;
169 | address: number;
170 | circuits: PumpCircuit[];
171 | primingSpeed: number;
172 | primingTime: number;
173 | minSpeed: number;
174 | maxSpeed: number;
175 | speedStepSize: number;
176 | backgroundCircuit: number;
177 | filterSize: number;
178 | turnovers: number;
179 | manualFilterGPM: number;
180 | minFlow: number;
181 | maxFlow: number;
182 | flowStepSize: number;
183 | maxSystemTime: number;
184 | maxPressureIncrease: number;
185 | backwashFlow: number;
186 | backwashTime: number;
187 | rinseTime: number;
188 | vacuumFlow: number;
189 | vacuumTime: number;
190 | }
191 | export interface Lights {
192 | allOnAllOff: number[];
193 | }
194 | export interface SpaFlow {
195 | isActive: boolean;
196 | pumpId: number;
197 | stepSize: number;
198 | }
199 | export interface HeaterConfig {
200 | body1SolarPresent: boolean;
201 | body2SolarPresent: boolean;
202 | thermaFloCoolPresent: boolean;
203 | solarHeatPumpPresent: boolean;
204 | thermaFloPresent: boolean;
205 | units: number;
206 | }
207 | export interface Delays {
208 | poolPumpOnDuringHeaterCooldown: boolean;
209 | spaPumpOnDuringHeaterCooldown: boolean;
210 | pumpOffDuringValveAction: boolean;
211 | }
212 | export interface Misc {
213 | intelliChem: boolean;
214 | manualHeat: boolean;
215 | }
216 | export interface Valves {
217 | loadCenterIndex: number;
218 | valveIndex: number;
219 | valveName: string;
220 | loadCenterName: string;
221 | deviceId: number;
222 | sCircuit?: string;
223 | }
224 | export interface SLWeatherForecastData extends SLData {
225 | version: number;
226 | zip: string;
227 | lastUpdate: Date;
228 | lastRequest: Date;
229 | dateText: string;
230 | text: string;
231 | currentTemperature: number;
232 | humidity: number;
233 | wind: string;
234 | pressure: number;
235 | dewPoint: number;
236 | windChill: number;
237 | visibility: number;
238 | dayData: SLWeatherForecastDayData[];
239 | sunrise: number;
240 | sunset: number;
241 | }
242 | export interface SLWeatherForecastDayData {
243 | dayTime: Date;
244 | highTemp: number;
245 | lowTemp: number;
246 | text: string;
247 | }
248 | export interface TimeTimePointPairs {
249 | on: Date;
250 | off: Date;
251 | }
252 | export interface TimeTempPointPairs {
253 | time: Date;
254 | temp: number;
255 | }
256 | export interface SLHistoryData extends SLData {
257 | airTemps: TimeTempPointPairs[];
258 | poolTemps: TimeTempPointPairs[];
259 | poolSetPointTemps: TimeTempPointPairs[];
260 | spaTemps: TimeTempPointPairs[];
261 | spaSetPointTemps: TimeTempPointPairs[];
262 | poolRuns: TimeTimePointPairs[];
263 | spaRuns: TimeTimePointPairs[];
264 | solarRuns: TimeTimePointPairs[];
265 | heaterRuns: TimeTimePointPairs[];
266 | lightRuns: TimeTimePointPairs[];
267 | }
268 | export interface SLCircuitIdName {
269 | id: number;
270 | circuitName: string;
271 | }
272 | export interface SLCircuitNamesData extends SLData {
273 | circuits: SLCircuitIdName[];
274 | }
275 | export interface SLGetCustomNamesData extends SLData {
276 | names: string[];
277 | }
278 |
--------------------------------------------------------------------------------
/dist/index.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 | ///
4 | ///
5 | import 'source-map-support/register';
6 | import * as dgram from 'dgram';
7 | import { EventEmitter } from 'events';
8 | import * as net from 'net';
9 | import * as SLGateway from './messages/SLGatewayDataMessage';
10 | import { BodyCommands, ChemCommands, ChlorCommands, CircuitCommands, ConnectionCommands, EquipmentCommands, PumpCommands, ScheduleCommands } from './messages/OutgoingMessages';
11 | import { SLVersionData } from './messages/ConnectionMessage';
12 | import { SLCircuitNamesData, SLControllerConfigData, SLEquipmentConfigurationData, SLGetCustomNamesData, SLHistoryData, SLWeatherForecastData } from './messages/config/EquipmentConfig';
13 | import { SLIntellichlorData } from './messages/state/ChlorMessage';
14 | import { SLChemData, SLChemHistory } from './messages/state/ChemMessage';
15 | import { SLScheduleData } from './messages/config/ScheduleMessage';
16 | import { SLPumpStatusData } from './messages/state/PumpMessage';
17 | import { Inbound, SLMessage, SLSimpleBoolData, SLSimpleNumberData } from './messages/SLMessage';
18 | import { SLEquipmentStateData, SLSystemTimeData } from './messages/state/EquipmentState';
19 | export * from './messages/config/ScheduleMessage';
20 | export * from './messages/config/EquipmentConfig';
21 | export * from './messages/config/CircuitMessage';
22 | export * from './messages/config/HeaterMessage';
23 | export * from './messages/state/ChemMessage';
24 | export * from './messages/state/ChlorMessage';
25 | export * from './messages/state/PumpMessage';
26 | export * from './messages/state/EquipmentState';
27 | export * from './messages/ConnectionMessage';
28 | export * from './messages/OutgoingMessages';
29 | export * from './messages/SLGatewayDataMessage';
30 | export * from './messages/SLMessage';
31 | export declare class FindUnits extends EventEmitter {
32 | constructor();
33 | private finder;
34 | private bound;
35 | private message;
36 | search(): void;
37 | searchAsync(searchTimeMs?: number): Promise;
38 | foundServer(msg: Buffer, remote: dgram.RemoteInfo): void;
39 | sendServerBroadcast(): void;
40 | close(): void;
41 | }
42 | export declare class RemoteLogin extends EventEmitter {
43 | constructor(systemName: string);
44 | systemName: string;
45 | private _client;
46 | private _gateway;
47 | connectAsync(): Promise;
48 | closeAsync(): Promise;
49 | }
50 | export declare class UnitConnection extends EventEmitter {
51 | constructor();
52 | systemName: string;
53 | private serverPort;
54 | private serverAddress;
55 | private password;
56 | protected client: net.Socket;
57 | private isConnected;
58 | private _clientId;
59 | get clientId(): number;
60 | set clientId(val: number);
61 | private _controllerId;
62 | get controllerId(): number;
63 | set controllerId(val: number);
64 | static controllerType: number;
65 | static expansionsCount: number;
66 | protected _isMock: boolean;
67 | protected _hasAddedClient: boolean;
68 | private _buffer;
69 | private _bufferIdx;
70 | private _senderId;
71 | get senderId(): number;
72 | set senderId(val: number);
73 | controller: Controller;
74 | netTimeout: number;
75 | private _keepAliveDuration;
76 | private _keepAliveTimer;
77 | private _expectedMsgLen;
78 | circuits: Circuit;
79 | equipment: Equipment;
80 | bodies: Body;
81 | chem: Chem;
82 | chlor: Chlor;
83 | schedule: Schedule;
84 | pump: Pump;
85 | reconnectAsync: () => Promise;
86 | initMock(systemName: string, address: string, port: number, password: string, senderId?: number): void;
87 | init(systemName: string, address: string, port: number, password?: string, senderId?: number): void;
88 | initUnit(server: LocalUnit): void;
89 | private _initCommands;
90 | write(bytes: Buffer | string): void;
91 | readMockBytesAsString(hexStr: string): void;
92 | keepAliveAsync(): void;
93 | processData(msg: Buffer): void;
94 | toLogEmit(message: SLMessage, direction: string): void;
95 | closeAsync(): Promise;
96 | connectAsync(): Promise;
97 | loginAsync(challengeString: string, senderId?: number): Promise;
98 | bytesRead(): number;
99 | bytesWritten(): number;
100 | status(): {
101 | destroyed: boolean;
102 | connecting: boolean;
103 | readyState: string;
104 | timeout?: undefined;
105 | } | {
106 | destroyed: boolean;
107 | connecting: boolean;
108 | timeout: number;
109 | readyState: net.SocketReadyState;
110 | };
111 | getVersionAsync(senderId?: number): Promise;
112 | addClientAsync(clientId?: number, senderId?: number): Promise;
113 | removeClientAsync(clientId?: number, senderId?: number): Promise;
114 | pingServerAsync(senderId?: number): Promise;
115 | onClientMessage(msg: Inbound): void;
116 | }
117 | export declare const screenlogic: UnitConnection;
118 | export declare class Equipment {
119 | protected unit: UnitConnection;
120 | constructor(parent: UnitConnection);
121 | setSystemTimeAsync(date: Date, shouldAdjustForDST: boolean, senderId?: number): Promise;
122 | getWeatherForecastAsync(senderId?: number): Promise;
123 | getHistoryDataAsync(fromTime?: Date, toTime?: Date, senderId?: number): Promise;
124 | getAllCircuitNamesAsync(senderId?: number): Promise;
125 | getNCircuitNamesAsync(senderId?: number): Promise;
126 | getCircuitNamesAsync(size: number, senderId?: number): Promise;
127 | getCircuitDefinitionsAsync(senderId?: number): Promise;
128 | getEquipmentConfigurationAsync(senderId?: number): Promise;
129 | cancelDelayAsync(senderId?: number): Promise;
130 | getSystemTimeAsync(senderId?: number): Promise;
131 | getControllerConfigAsync(senderId?: number): Promise;
132 | getEquipmentStateAsync(senderId?: number): Promise;
133 | getCustomNamesAsync(senderId?: number): Promise;
134 | setCustomNameAsync(idx: number, name: string, senderId?: number): Promise;
135 | }
136 | export declare class Circuit {
137 | protected unit: UnitConnection;
138 | constructor(parent: UnitConnection);
139 | sendLightCommandAsync(command: LightCommands, senderId?: number): Promise;
140 | setCircuitRuntimebyIdAsync(circuitId: number, runTime?: number, senderId?: number): Promise;
141 | setCircuitAsync(circuitId: number, nameIndex: number, circuitFunction: number, circuitInterface: number, freeze: boolean, colorPos: number, senderId?: number): Promise;
142 | setCircuitStateAsync(circuitId: number, circuitState: boolean, senderId?: number): Promise;
143 | }
144 | export declare class Body {
145 | protected unit: UnitConnection;
146 | constructor(parent: UnitConnection);
147 | setSetPointAsync(bodyIndex: BodyIndex, temperature: number, senderId?: number): Promise;
148 | setCoolSetPointAsync(bodyIndex: BodyIndex, temperature: number, senderId?: number): Promise;
149 | setHeatModeAsync(bodyIndex: BodyIndex, heatMode: HeatModes, senderId?: number): Promise;
150 | }
151 | export declare class Pump {
152 | protected unit: UnitConnection;
153 | constructor(parent: UnitConnection);
154 | setPumpSpeedAsync(pumpId: number, circuitId: number, speed: number, isRPMs?: boolean, senderId?: number): Promise;
155 | getPumpStatusAsync(pumpId: number, senderId?: number): Promise;
156 | }
157 | export declare class Schedule {
158 | protected unit: UnitConnection;
159 | constructor(parent: UnitConnection);
160 | setScheduleEventByIdAsync(scheduleId: number, circuitId: number, startTime: number, stopTime: number, dayMask: number, flags: number, heatCmd: number, heatSetPoint: number, senderId?: number): Promise;
161 | addNewScheduleEventAsync(scheduleType: SchedTypes, senderId?: number): Promise;
162 | deleteScheduleEventByIdAsync(scheduleId: number, senderId?: number): Promise;
163 | getScheduleDataAsync(scheduleType: SchedTypes, senderId?: number): Promise;
164 | }
165 | export declare class Chem {
166 | protected unit: UnitConnection;
167 | constructor(parent: UnitConnection);
168 | getChemHistoryDataAsync(fromTime?: Date, toTime?: Date, senderId?: number): Promise;
169 | getChemicalDataAsync(senderId?: number): Promise;
170 | }
171 | export declare class Chlor {
172 | protected unit: UnitConnection;
173 | constructor(parent: UnitConnection);
174 | setIntellichlorOutputAsync(poolOutput: number, spaOutput: number, senderId?: number): Promise;
175 | getIntellichlorConfigAsync(senderId?: number): Promise;
176 | setIntellichlorIsActiveAsync(isActive: boolean, senderId?: number): Promise;
177 | }
178 | export declare enum LightCommands {
179 | LIGHT_CMD_LIGHTS_OFF = 0,
180 | LIGHT_CMD_LIGHTS_ON = 1,
181 | LIGHT_CMD_COLOR_SET = 2,
182 | LIGHT_CMD_COLOR_SYNC = 3,
183 | LIGHT_CMD_COLOR_SWIM = 4,
184 | LIGHT_CMD_COLOR_MODE_PARTY = 5,
185 | LIGHT_CMD_COLOR_MODE_ROMANCE = 6,
186 | LIGHT_CMD_COLOR_MODE_CARIBBEAN = 7,
187 | LIGHT_CMD_COLOR_MODE_AMERICAN = 8,
188 | LIGHT_CMD_COLOR_MODE_SUNSET = 9,
189 | LIGHT_CMD_COLOR_MODE_ROYAL = 10,
190 | LIGHT_CMD_COLOR_SET_SAVE = 11,
191 | LIGHT_CMD_COLOR_SET_RECALL = 12,
192 | LIGHT_CMD_COLOR_BLUE = 13,
193 | LIGHT_CMD_COLOR_GREEN = 14,
194 | LIGHT_CMD_COLOR_RED = 15,
195 | LIGHT_CMD_COLOR_WHITE = 16,
196 | LIGHT_CMD_COLOR_PURPLE = 17
197 | }
198 | export declare enum HeatModes {
199 | HEAT_MODE_OFF = 0,
200 | HEAT_MODE_SOLAR = 1,
201 | HEAT_MODE_SOLARPREFERRED = 2,
202 | HEAT_MODE_HEATPUMP = 3,
203 | HEAT_MODE_HEATER = 3,
204 | HEAT_MODE_DONTCHANGE = 4
205 | }
206 | export declare enum PumpTypes {
207 | Invalid = 0,
208 | PUMP_TYPE_INTELLIFLOVF = 5,
209 | PUMP_TYPE_INTELLIFLOVS = 3,
210 | PUMP_TYPE_INTELLIFLOVSF = 4
211 | }
212 | export declare enum BodyIndex {
213 | POOL = 0,
214 | SPA = 1
215 | }
216 | export interface Controller {
217 | circuits: CircuitCommands;
218 | connection: ConnectionCommands;
219 | equipment: EquipmentCommands;
220 | chlor: ChlorCommands;
221 | chem: ChemCommands;
222 | schedules: ScheduleCommands;
223 | pumps: PumpCommands;
224 | bodies: BodyCommands;
225 | }
226 | export declare enum SchedTypes {
227 | RECURRING = 0,
228 | RUNONCE = 1
229 | }
230 | export interface LocalUnit {
231 | address: string;
232 | type: number;
233 | port: number;
234 | gatewayType: number;
235 | gatewaySubtype: number;
236 | gatewayName: string;
237 | }
238 |
--------------------------------------------------------------------------------
/test/slmessage.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const SLMessage = require('../dist/messages/SLMessage.js');
4 | const assert = require('assert');
5 |
6 | function slMessageLen(str) {
7 | // strings have length prefixed on them as an int32 for an additional 4b.
8 | // strings are dword aligned, so if str.length is 21, dword alignment pushes it up to 24
9 | return 4 + str.length + SLMessage.SLMessage.slackForAlignment(str.length);
10 | }
11 |
12 | describe('SLMessage utilities', function() {
13 | // message header = senderId, messageId, bodyLen.
14 | // senderId and messageId are int16's, so 2b each. bodyLen is an int32, so 4b. total 8b.
15 | let msgHeaderLen = 8;
16 |
17 | it('sets senderId and messageId properly', function() {
18 | {
19 | let msg = new SLMessage.Outbound(0, 123, 456);
20 | msg.createBaseMessage();
21 | let decodedMsg = new SLMessage.Inbound();
22 | decodedMsg.readFromBuffer(msg.toBuffer());
23 | assert.strictEqual(decodedMsg.senderId, 123);
24 | assert.strictEqual(decodedMsg.action, 456);
25 | assert.strictEqual(decodedMsg.dataLength, 0);
26 | }
27 |
28 | {
29 | let msg = new SLMessage.Outbound(0, 0, 65534);
30 | msg.createBaseMessage();
31 | let decodedMsg = new SLMessage.Inbound();
32 | decodedMsg.readFromBuffer(msg.toBuffer());
33 | assert.strictEqual(decodedMsg.senderId, 0);
34 | assert.strictEqual(decodedMsg.action, 65534);
35 | assert.strictEqual(decodedMsg.dataLength, 0);
36 | }
37 |
38 | {
39 | let msg = new SLMessage.Outbound();
40 | msg.createBaseMessage();
41 | let decodedMsg = new SLMessage.Inbound();
42 | decodedMsg.readFromBuffer(msg.toBuffer());
43 | assert.strictEqual(decodedMsg.senderId, 0);
44 | assert.strictEqual(decodedMsg.action, 0);
45 | assert.strictEqual(decodedMsg.dataLength, 0);
46 | }
47 |
48 | {
49 | let msg = new SLMessage.Outbound(0, 123);
50 | msg.createBaseMessage();
51 | let decodedMsg = new SLMessage.Inbound();
52 | decodedMsg.readFromBuffer(msg.toBuffer());
53 | assert.strictEqual(decodedMsg.senderId, 123);
54 | assert.strictEqual(decodedMsg.action, 0);
55 | assert.strictEqual(decodedMsg.dataLength, 0);
56 | }
57 | });
58 |
59 | it('encodes and decodes SLStrings', function() {
60 | {
61 | let msg = new SLMessage.Outbound();
62 | msg.createBaseMessage();
63 | let testStr = 'this is a test string';
64 | msg.writeSLString(testStr);
65 | let decodedMsg = new SLMessage.Inbound();
66 | decodedMsg.readFromBuffer(msg.toBuffer());
67 | assert.strictEqual(decodedMsg.readSLString(), testStr, 'did not receive serialized message properly');
68 | assert.strictEqual(SLMessage.SLMessage.slackForAlignment(testStr.length), 3);
69 | // SLString byte length = 4 + 21 + 3 = 28b
70 | assert.strictEqual(slMessageLen(testStr),
71 | 4 + testStr.length + SLMessage.SLMessage.slackForAlignment(testStr.length));
72 | assert.strictEqual(decodedMsg.readOffset, msgHeaderLen + slMessageLen(testStr), 'read offset was invalid');
73 | assert.strictEqual(decodedMsg.dataLength, decodedMsg.readOffset - 8);
74 | }
75 |
76 | {
77 | let msg = new SLMessage.Outbound();
78 | msg.createBaseMessage();
79 | let testStr = '1';
80 | msg.writeSLString(testStr);
81 | let decodedMsg = new SLMessage.Inbound();
82 | decodedMsg.readFromBuffer(msg.toBuffer());
83 | assert.strictEqual(decodedMsg.readSLString(), testStr, 'did not receive serialized message properly');
84 | assert.strictEqual(SLMessage.SLMessage.slackForAlignment(testStr.length), 3);
85 | assert.strictEqual(decodedMsg.readOffset, msgHeaderLen + slMessageLen(testStr), 'read offset was invalid');
86 | assert.strictEqual(decodedMsg.dataLength, decodedMsg.readOffset - 8);
87 | }
88 |
89 | {
90 | let msg = new SLMessage.Outbound();
91 | msg.createBaseMessage();
92 | let testStr = '12';
93 | msg.writeSLString(testStr);
94 | let decodedMsg = new SLMessage.Inbound();
95 | decodedMsg.readFromBuffer(msg.toBuffer());
96 | assert.strictEqual(decodedMsg.readSLString(), testStr, 'did not receive serialized message properly');
97 | assert.strictEqual(SLMessage.SLMessage.slackForAlignment(testStr.length), 2);
98 | assert.strictEqual(decodedMsg.readOffset, msgHeaderLen + slMessageLen(testStr), 'read offset was invalid');
99 | assert.strictEqual(decodedMsg.dataLength, decodedMsg.readOffset - 8);
100 | }
101 |
102 | {
103 | let msg = new SLMessage.Outbound();
104 | msg.createBaseMessage();
105 | let testStr = '123';
106 | msg.writeSLString(testStr);
107 | let decodedMsg = new SLMessage.Inbound();
108 | decodedMsg.readFromBuffer(msg.toBuffer());
109 | assert.strictEqual(decodedMsg.readSLString(), testStr, 'did not receive serialized message properly');
110 | assert.strictEqual(SLMessage.SLMessage.slackForAlignment(testStr.length), 1);
111 | assert.strictEqual(decodedMsg.readOffset, msgHeaderLen + slMessageLen(testStr), 'read offset was invalid');
112 | assert.strictEqual(decodedMsg.dataLength, decodedMsg.readOffset - 8);
113 | }
114 |
115 | {
116 | let msg = new SLMessage.Outbound();
117 | msg.createBaseMessage();
118 | let testStr = '1234';
119 | msg.writeSLString(testStr);
120 | let decodedMsg = new SLMessage.Inbound();
121 | decodedMsg.readFromBuffer(msg.toBuffer());
122 | assert.strictEqual(decodedMsg.readSLString(), testStr, 'did not receive serialized message properly');
123 | assert.strictEqual(SLMessage.SLMessage.slackForAlignment(testStr.length), 0);
124 | assert.strictEqual(decodedMsg.readOffset, msgHeaderLen + slMessageLen(testStr), 'read offset was invalid');
125 | assert.strictEqual(decodedMsg.dataLength, decodedMsg.readOffset - 8);
126 | }
127 | });
128 |
129 | it('encodes and decodes SLArrays', function() {
130 | {
131 | let msg = new SLMessage.Outbound();
132 | msg.createBaseMessage();
133 | let list = [];
134 | msg.writeSLArray(list);
135 | let decodedMsg = new SLMessage.Inbound();
136 | decodedMsg.readFromBuffer(msg.toBuffer());
137 | assert.deepStrictEqual(decodedMsg.readSLArray(), list);
138 | assert.strictEqual(SLMessage.SLMessage.slackForAlignment(list.length), 0);
139 | assert.strictEqual(decodedMsg.readOffset, msgHeaderLen + slMessageLen(list), 'read offset was invalid');
140 | assert.strictEqual(decodedMsg.dataLength, decodedMsg.readOffset - 8);
141 | }
142 |
143 | {
144 | let msg = new SLMessage.Outbound();
145 | msg.createBaseMessage();
146 | let list = [1];
147 | msg.writeSLArray(list);
148 | let decodedMsg = new SLMessage.Inbound();
149 | decodedMsg.readFromBuffer(msg.toBuffer());
150 | assert.deepStrictEqual(decodedMsg.readSLArray(), list);
151 | assert.strictEqual(SLMessage.SLMessage.slackForAlignment(list.length), 3);
152 | assert.strictEqual(decodedMsg.readOffset, msgHeaderLen + slMessageLen(list), 'read offset was invalid');
153 | assert.strictEqual(decodedMsg.dataLength, decodedMsg.readOffset - 8);
154 | }
155 |
156 | {
157 | let msg = new SLMessage.Outbound();
158 | msg.createBaseMessage();
159 | let list = [1, 2];
160 | msg.writeSLArray(list);
161 | let decodedMsg = new SLMessage.Inbound();
162 | decodedMsg.readFromBuffer(msg.toBuffer());
163 | assert.deepStrictEqual(decodedMsg.readSLArray(), list);
164 | assert.strictEqual(SLMessage.SLMessage.slackForAlignment(list.length), 2);
165 | assert.strictEqual(decodedMsg.readOffset, msgHeaderLen + slMessageLen(list), 'read offset was invalid');
166 | assert.strictEqual(decodedMsg.dataLength, decodedMsg.readOffset - 8);
167 | }
168 |
169 | {
170 | let msg = new SLMessage.Outbound();
171 | msg.createBaseMessage();
172 | let list = [1, 2, 3];
173 | msg.writeSLArray(list);
174 | let decodedMsg = new SLMessage.Inbound();
175 | decodedMsg.readFromBuffer(msg.toBuffer());
176 | assert.deepStrictEqual(decodedMsg.readSLArray(), list);
177 | assert.strictEqual(SLMessage.SLMessage.slackForAlignment(list.length), 1);
178 | assert.strictEqual(decodedMsg.readOffset, msgHeaderLen + slMessageLen(list), 'read offset was invalid');
179 | assert.strictEqual(decodedMsg.dataLength, decodedMsg.readOffset - 8);
180 | }
181 |
182 | {
183 | let msg = new SLMessage.Outbound();
184 | msg.createBaseMessage();
185 | let list = [1, 2, 3, 4];
186 | msg.writeSLArray(list);
187 | let decodedMsg = new SLMessage.Inbound();
188 | decodedMsg.readFromBuffer(msg.toBuffer());
189 | assert.deepStrictEqual(decodedMsg.readSLArray(), list);
190 | assert.strictEqual(SLMessage.SLMessage.slackForAlignment(list.length), 0);
191 | assert.strictEqual(decodedMsg.readOffset, msgHeaderLen + slMessageLen(list), 'read offset was invalid');
192 | assert.strictEqual(decodedMsg.dataLength, decodedMsg.readOffset - 8);
193 | }
194 | });
195 |
196 | it('encodes Date as SLTime', function() {
197 | let msg = new SLMessage.Outbound();
198 | msg.createBaseMessage();
199 | let date = new Date(2021, 8, 6, 22, 8, 5);
200 | msg.writeSLDateTime(date);
201 | let decodedMsg = new SLMessage.Inbound();
202 | decodedMsg.readFromBuffer(msg.toBuffer());
203 | assert.equal(decodedMsg.readUInt16LE(), 2021);
204 | // javascript Date() month is 0-based, ScreenLogic month matches the calendar
205 | assert.equal(decodedMsg.readUInt16LE(), 9);
206 | // ScreenLogic day-of-week starts with Sunday as 1
207 | assert.equal(decodedMsg.readUInt16LE(), 2);
208 | assert.equal(decodedMsg.readUInt16LE(), 6);
209 | assert.equal(decodedMsg.readUInt16LE(), 22);
210 | assert.equal(decodedMsg.readUInt16LE(), 8);
211 | assert.equal(decodedMsg.readUInt16LE(), 5);
212 | assert.equal(decodedMsg.readUInt16LE(), 0);
213 | });
214 |
215 | it('decodes SLTime as Date', function() {
216 | let msg = new SLMessage.Outbound();
217 | msg.createBaseMessage();
218 | let date = new Date(2021, 8, 6, 22, 8, 5);
219 | msg.writeSLDateTime(date);
220 | let decodedMsg = new SLMessage.Inbound();
221 | decodedMsg.readFromBuffer(msg.toBuffer());
222 | let decodedDate = decodedMsg.readSLDateTime();
223 | assert.equal(date.getFullYear(), decodedDate.getFullYear());
224 | assert.equal(date.getMonth(), decodedDate.getMonth());
225 | assert.equal(date.getDate(), decodedDate.getDate());
226 | assert.equal(date.getHours(), decodedDate.getHours());
227 | assert.equal(date.getMinutes(), decodedDate.getMinutes());
228 | assert.equal(date.getSeconds(), decodedDate.getSeconds());
229 | assert.equal(date.getMilliseconds(), decodedDate.getMilliseconds());
230 | });
231 |
232 | it('writes the appropriate day of week', function() {
233 | let handler = function(inDate) {
234 | let msg = new SLMessage.Outbound();
235 | msg.createBaseMessage();
236 | msg.writeSLDateTime(inDate);
237 | let decodedMsg = new SLMessage.Inbound();
238 | decodedMsg.readFromBuffer(msg.toBuffer());
239 | decodedMsg.readUInt16LE();
240 | decodedMsg.readUInt16LE();
241 | return decodedMsg.readUInt16LE();
242 | };
243 |
244 | let dow = handler(new Date(2022, 3, 17, 10, 3, 0));
245 | assert.equal(dow, 1);
246 | dow = handler(new Date(2022, 3, 18, 10, 3, 0));
247 | assert.equal(dow, 2);
248 | dow = handler(new Date(2022, 3, 19, 10, 3, 0));
249 | assert.equal(dow, 3);
250 | dow = handler(new Date(2022, 3, 20, 10, 3, 0));
251 | assert.equal(dow, 4);
252 | dow = handler(new Date(2022, 3, 21, 10, 3, 0));
253 | assert.equal(dow, 5);
254 | dow = handler(new Date(2022, 3, 22, 10, 3, 0));
255 | assert.equal(dow, 6);
256 | dow = handler(new Date(2022, 3, 23, 10, 3, 0));
257 | assert.equal(dow, 7);
258 | });
259 | });
260 |
--------------------------------------------------------------------------------
/dist/messages/state/EquipmentState.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"EquipmentState.js","sourceRoot":"","sources":["../../../messages/state/EquipmentState.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/dist/messages/OutgoingMessages.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"OutgoingMessages.js","sourceRoot":"","sources":["../../messages/OutgoingMessages.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/messages/OutgoingMessages.ts:
--------------------------------------------------------------------------------
1 | import { Outbound } from './SLMessage';
2 | import { ChemMessage, ChlorMessage, CircuitMessage, ConnectionMessage, EquipmentStateMessage, HeaterMessage, LightCommands, PumpMessage, ScheduleMessage, UnitConnection } from '../index';
3 | import { EquipmentConfigurationMessage, rawData } from './config/EquipmentConfig';
4 |
5 | export class Commands extends Outbound {
6 | protected unit: UnitConnection;
7 | constructor(unit: UnitConnection, senderId?: number) {
8 | super(unit.controllerId, senderId ?? unit.senderId);
9 | this.unit = unit;
10 | }
11 | }
12 |
13 | export class ConnectionCommands extends Commands {
14 | public sendLoginMessage(password?: Buffer, senderId?: number): ConnectionCommands {
15 | this.action = ConnectionMessage.ResponseIDs.Login - 1;
16 | this.createBaseMessage(senderId);
17 | // this.addHeader(this.senderId, this.messageId)
18 | this.writeInt32LE(348); // schema
19 | this.writeInt32LE(0); // connection type
20 | this.writeSLString('node-screenlogic'); // version
21 |
22 | if (!password) {
23 | password = Buffer.alloc(16);
24 | }
25 | if (password.length > 16) {
26 | password = password.slice(0, 16);
27 | }
28 | this.writeSLArray(password); // encoded password. empty/unused for local connections
29 |
30 | this.writeInt32LE(2); // procID
31 | this.unit.write(this.toBuffer());
32 | return this;
33 | }
34 |
35 | public sendChallengeMessage(senderId?: number): ConnectionCommands {
36 | this.action = ConnectionMessage.ResponseIDs.Challenge - 1;
37 | this.createBaseMessage(senderId);
38 | this.unit.write(this.toBuffer());
39 | return this;
40 | }
41 | public sendVersionMessage(senderId?: number): ConnectionCommands {
42 | this.action = ConnectionMessage.ResponseIDs.Version - 1;
43 | this.createBaseMessage(senderId);
44 | this.unit.write(this.toBuffer());
45 | return this;
46 | }
47 | public sendAddClientMessage(clientId?: number, senderId?: number): ConnectionCommands {
48 | this.action = ConnectionMessage.ResponseIDs.AddClient - 1;
49 | this.createBaseMessage(senderId);
50 | this.writeInt32LE(this.unit.controllerId);
51 | this.writeInt32LE(clientId ?? this.unit.clientId);
52 | this.unit.write(this.toBuffer());
53 | return this;
54 | }
55 | public sendRemoveClientMessage(clientId?: number, senderId?: number): ConnectionCommands {
56 | this.action = ConnectionMessage.ResponseIDs.RemoveClient - 1;
57 | this.createBaseMessage(senderId);
58 | this.writeInt32LE(this.unit.controllerId);
59 | this.writeInt32LE(clientId ?? this.unit.clientId);
60 | this.unit.write(this.toBuffer());
61 | return this;
62 | }
63 | public sendPingMessage(senderId?: number): ConnectionCommands {
64 | this.action = ConnectionMessage.ResponseIDs.Ping - 1;
65 | this.createBaseMessage(senderId);
66 | this.unit.write(this.toBuffer());
67 | return this;
68 | }
69 | }
70 |
71 |
72 | export class EquipmentCommands extends Commands {
73 | public sendGetEquipmentStateMessage(senderId?: number): EquipmentCommands {
74 | this.action = EquipmentStateMessage.ResponseIDs.EquipmentState - 1;
75 | this.createBaseMessage(senderId);
76 | this.writeInt32LE(0);
77 | this.unit.write(this.toBuffer());
78 | return this;
79 | }
80 | public sendGetControllerConfigMessage(senderId?: number): EquipmentCommands {
81 | this.action = EquipmentConfigurationMessage.ResponseIDs.GetControllerConfig - 1;
82 | this.createBaseMessage(senderId);
83 | this.writeInt32LE(0);
84 | this.writeInt32LE(0);
85 | this.unit.write(this.toBuffer());
86 | return this;
87 | }
88 | public sendGetNumCircuitNamesMessage(senderId?: number): EquipmentCommands {
89 | this.action = EquipmentConfigurationMessage.ResponseIDs.NumCircuitNames - 1;
90 | this.createBaseMessage(senderId);
91 | this.writeInt32LE(0);
92 | this.writeInt32LE(0);
93 | this.unit.write(this.toBuffer());
94 | return this;
95 | }
96 | public sendGetCircuitNamesMessage(idx: number, cnt: number, senderId?: number): EquipmentCommands {
97 | this.action = EquipmentConfigurationMessage.ResponseIDs.GetCircuitNames;
98 | this.createBaseMessage(senderId);
99 | this.writeInt32LE(0);
100 | this.writeInt32LE(idx);
101 | this.writeInt32LE(cnt);
102 | this.unit.write(this.toBuffer());
103 | return this;
104 | }
105 | public sendGetCircuitDefinitionsMessage(senderId?: number): EquipmentCommands {
106 | this.action = EquipmentConfigurationMessage.ResponseIDs.GetCircuitDefinitions - 1;
107 | this.createBaseMessage(senderId);
108 | this.writeInt32LE(0);
109 | this.writeInt32LE(0);
110 | this.unit.write(this.toBuffer());
111 | return this;
112 | }
113 | public sendGetEquipmentConfigurationMessage(senderId?: number): EquipmentCommands {
114 | this.action = EquipmentConfigurationMessage.ResponseIDs.GetEquipmentConfiguration - 1;
115 | this.createBaseMessage(senderId);
116 | this.writeInt32LE(0);
117 | this.writeInt32LE(0);
118 | this.unit.write(this.toBuffer());
119 | return this;
120 | }
121 | public sendSetEquipmentConfigurationMessageAsync(data: rawData, senderId?: number): EquipmentCommands {
122 | this.action = EquipmentConfigurationMessage.ResponseIDs.SetEquipmentConfiguration; //setequipconfg
123 | this.createBaseMessage(senderId);
124 | this.writeInt32LE(0);
125 | this.writeInt32LE(0);
126 | this.unit.write(this.toBuffer());
127 | return this;
128 | }
129 | public sendGetSystemTimeMessage(senderId?: number): EquipmentCommands {
130 | this.action = EquipmentStateMessage.ResponseIDs.SystemTime - 1;
131 | this.createBaseMessage(senderId);
132 | this.unit.write(this.toBuffer());
133 | return this;
134 | }
135 | public sendCancelDelayMessage(senderId?: number): EquipmentCommands {
136 | this.action = EquipmentStateMessage.ResponseIDs.CancelDelay - 1;
137 | this.createBaseMessage(senderId);
138 | this.writeInt32LE(0);
139 | this.unit.write(this.toBuffer());
140 | return this;
141 | }
142 | public sendGetCustomNamesMessage(senderId?: number): EquipmentCommands {
143 | this.action = EquipmentConfigurationMessage.ResponseIDs.GetCustomNamesAck - 1;
144 | this.createBaseMessage(senderId);
145 | this.writeInt32LE(0);
146 | this.unit.write(this.toBuffer());
147 | return this;
148 | }
149 | public sendSetCustomNameMessage(idx: number, name: string, senderId?: number): EquipmentCommands {
150 | this.action = EquipmentConfigurationMessage.ResponseIDs.SetCustomNameAck - 1;
151 | this.createBaseMessage(senderId);
152 | this.writeInt32LE(this.controllerId);
153 | this.writeInt32LE(idx);
154 | this.writeSLString(name);
155 | this.unit.write(this.toBuffer());
156 | return this;
157 | }
158 | public sendGetWeatherMessage(senderId?: number): EquipmentCommands {
159 | this.action = EquipmentConfigurationMessage.ResponseIDs.WeatherForecastAck - 1;
160 | this.createBaseMessage(senderId);
161 | this.writeInt32LE(0);
162 | this.writeInt32LE(0);
163 | this.unit.write(this.toBuffer());
164 | return this;
165 | }
166 | public sendSetSystemTimeMessage(date: Date, shouldAdjustForDST: boolean, senderId?: number): EquipmentCommands {
167 | this.action = EquipmentStateMessage.ResponseIDs.SetSystemTime - 1;
168 | this.createBaseMessage(senderId);
169 | this.writeSLDateTime(date);
170 | this.writeInt32LE(shouldAdjustForDST ? 1 : 0);
171 | this.unit.write(this.toBuffer());
172 | return this;
173 | }
174 | public sendGetHistoryMessage(fromTime: Date, toTime: Date, senderId?: number): EquipmentCommands {
175 | this.action = EquipmentConfigurationMessage.ResponseIDs.HistoryDataPending - 1;
176 | this.createBaseMessage(senderId);
177 | this.writeInt32LE(this.controllerId);
178 | this.writeSLDateTime(fromTime);
179 | this.writeSLDateTime(toTime);
180 | this.writeInt32LE(senderId ?? this.senderId);
181 | this.unit.write(this.toBuffer());
182 | return this;
183 | }
184 | }
185 |
186 | export class CircuitCommands extends Commands {
187 | public sendSetCircuitMessage(circuitId: number, nameIndex: number, circuitFunction: number, circuitInterface: number, freeze: boolean, colorPos: number, senderId?: number): CircuitCommands {
188 | this.action = CircuitMessage.ResponseIDs.SetCircuitInfo - 1;
189 | this.createBaseMessage(senderId);
190 | this.writeInt32LE(this.controllerId);
191 | this.writeInt32LE(circuitId + 499);
192 | // normalize to 1 based ids for default names; 100 based for custom names
193 | // circuitArray[i].nameIndex = circuitArray[i].nameIndex < 101 ? circuitArray[i].nameIndex + 1 : circuitArray[i].nameIndex + 99;
194 | this.writeInt32LE(nameIndex < 102 ? nameIndex - 1 : nameIndex - 99);
195 | this.writeInt32LE(circuitFunction);
196 | this.writeInt32LE(circuitInterface);
197 | this.writeInt32LE(freeze ? 1 : 0); // could be other bits; this is a flag
198 | this.writeInt32LE(colorPos);
199 | this.encode();
200 | this.unit.write(this.toBuffer());
201 | return this;
202 | }
203 | public sendSetCircuitStateMessage(circuitId: number, circuitState: boolean, senderId?: number): CircuitCommands {
204 | this.action = CircuitMessage.ResponseIDs.SetCircuitState - 1;
205 | this.createBaseMessage(senderId);
206 | // this.addHeader(this.senderId, this.messageId);
207 | // this._controllerId = controllerId;
208 | this.writeInt32LE(this.controllerId);
209 | this.writeInt32LE(circuitId + 499);
210 | this.writeInt32LE((circuitState ? 1 : 0) || 0);
211 | this.encode();
212 | this.unit.write(this.toBuffer());
213 | return this;
214 | }
215 | public sendIntellibriteMessage(command: LightCommands, senderId?: number): CircuitCommands {
216 | this.action = CircuitMessage.ResponseIDs.SetLightState - 1;
217 | this.createBaseMessage(senderId);
218 | this.writeInt32LE(this.unit.controllerId);
219 | this.writeInt32LE(command || 0);
220 | this.unit.write(this.toBuffer());
221 | return this;
222 | }
223 | public sendSetCircuitRuntimeMessage(circuitId: number, runTime: number, senderId?: number): CircuitCommands {
224 | this.action = CircuitMessage.ResponseIDs.SetCircuitRunTime - 1;
225 | this.createBaseMessage(senderId);
226 | this.writeInt32LE(this.unit.controllerId);
227 | this.writeInt32LE(circuitId + 499);
228 | this.writeInt32LE(runTime);
229 | this.unit.write(this.toBuffer());
230 | return this;
231 | }
232 | }
233 | export class ChlorCommands extends Commands {
234 | public sendSetChlorOutputMessage(poolOutput: number, spaOutput: number, senderId?: number): ChlorCommands {
235 | this.action = ChlorMessage.ResponseIDs.SetIntellichlorConfig - 1;
236 | this.createBaseMessage(senderId);
237 | this.writeInt32LE(this.unit.controllerId);
238 | this.writeInt32LE(poolOutput || 0);
239 | this.writeInt32LE(spaOutput || 0);
240 | this.writeInt32LE(0);
241 | this.writeInt32LE(0);
242 | this.unit.write(this.toBuffer());
243 | return this;
244 | }
245 | public sendGetSaltCellConfigMessage(senderId?: number): ChlorCommands {
246 | this.action = ChlorMessage.ResponseIDs.GetIntellichlorConfig - 1;
247 | this.createBaseMessage(senderId);
248 | this.writeInt32LE(this.unit.controllerId);
249 | this.unit.write(this.toBuffer());
250 | return this;
251 | }
252 | public sendSetSaltCellEnableMessage(isActive?: boolean, senderId?: number): ChlorCommands {
253 | this.action = ChlorMessage.ResponseIDs.SetIntellichlorEnabled - 1;
254 | this.createBaseMessage(senderId);
255 | this.writeInt32LE(this.unit.controllerId);
256 | this.writeInt32LE(isActive ? 1 : 0);
257 | this.unit.write(this.toBuffer());
258 | return this;
259 | }
260 | }
261 | export class ChemCommands extends Commands {
262 | public sendGetChemStatusMessage(senderId?: number): ChemCommands {
263 | this.action = ChemMessage.ResponseIDs.GetChemicalData - 1;
264 | this.createBaseMessage(senderId);
265 | this.writeInt32LE(0);
266 | this.unit.write(this.toBuffer());
267 | return this;
268 | }
269 | public sendGetChemHistoryMessage(fromTime: Date, toTime: Date, senderId?: number): ChemCommands {
270 | this.action = ChemMessage.ResponseIDs.HistoryDataPending - 1;
271 | this.createBaseMessage(senderId);
272 | this.writeInt32LE(0);
273 | this.writeSLDateTime(fromTime);
274 | this.writeSLDateTime(toTime);
275 | this.writeInt32LE(senderId ?? this.senderId);
276 | this.unit.write(this.toBuffer());
277 | return this;
278 | }
279 | }
280 | export class BodyCommands extends Commands {
281 | public sendSetPointMessage(bodyType: number, temperature: number, senderId?: number): BodyCommands {
282 | this.action = HeaterMessage.ResponseIDs.SetHeatSetPoint - 1;
283 | this.createBaseMessage(senderId);
284 | this.writeInt32LE(this.unit.controllerId);
285 | this.writeInt32LE(bodyType || 0);
286 | this.writeInt32LE(temperature || 0);
287 | this.unit.write(this.toBuffer());
288 | return this;
289 | }
290 | public sendCoolSetPointMessage(bodyType: number, temperature: number, senderId?: number): BodyCommands {
291 | this.action = HeaterMessage.ResponseIDs.SetCoolSetPoint - 1;
292 | this.createBaseMessage(senderId);
293 | this.writeInt32LE(this.unit.controllerId);
294 | this.writeInt32LE(bodyType || 0);
295 | this.writeInt32LE(temperature || 0);
296 | this.unit.write(this.toBuffer());
297 | return this;
298 | }
299 | public sendHeatModeMessage(bodyType: number, heatMode: number, senderId?: number): BodyCommands {
300 | this.action = HeaterMessage.ResponseIDs.SetHeatMode - 1;
301 | this.createBaseMessage(senderId);
302 | this.writeInt32LE(this.unit.controllerId);
303 | this.writeInt32LE(bodyType || 0);
304 | this.writeInt32LE(heatMode || 0);
305 | this.unit.write(this.toBuffer());
306 | return this;
307 | }
308 | }
309 | export class ScheduleCommands extends Commands {
310 | public sendGetSchedulesMessage(schedType: number, senderId?: number): ScheduleCommands {
311 | this.action = ScheduleMessage.ResponseIDs.GetSchedule - 1;
312 | this.createBaseMessage(senderId);
313 | this.writeInt32LE(0);
314 | this.writeInt32LE(schedType);
315 | this.unit.write(this.toBuffer());
316 | return this;
317 | }
318 | public sendAddScheduleEventMessage(schedType: number, senderId?: number): ScheduleCommands {
319 | this.action = ScheduleMessage.ResponseIDs.AddSchedule - 1;
320 | this.createBaseMessage(senderId);
321 | this.writeInt32LE(0);
322 | this.writeInt32LE(schedType);
323 | this.unit.write(this.toBuffer());
324 | return this;
325 | }
326 | public sendDeleteScheduleEventMessage(schedId: number, senderId?: number): ScheduleCommands {
327 | this.action = ScheduleMessage.ResponseIDs.DeleteSchedule - 1;
328 | this.createBaseMessage(senderId);
329 | this.writeInt32LE(this.controllerId);
330 | this.writeInt32LE(schedId + 699);
331 | this.unit.write(this.toBuffer());
332 | return this;
333 | }
334 | public sendSetScheduleEventMessage(scheduleId: number, circuitId: number, startTime: number, stopTime: number, dayMask: number, flags: number, heatCmd: number, heatSetPoint: number, senderId?: number): ScheduleCommands {
335 | this.action = ScheduleMessage.ResponseIDs.SetSchedule - 1;
336 | this.createBaseMessage(senderId);
337 | this.writeInt32LE(0);
338 | this.writeInt32LE(scheduleId + 699);
339 | this.writeInt32LE(circuitId + 499);
340 | this.writeInt32LE(startTime);
341 | this.writeInt32LE(stopTime);
342 | this.writeInt32LE(dayMask);
343 | this.writeInt32LE(flags);
344 | this.writeInt32LE(heatCmd);
345 | this.writeInt32LE(heatSetPoint);
346 | this.unit.write(this.toBuffer());
347 | return this;
348 | }
349 | }
350 | export class PumpCommands extends Commands {
351 | public sendGetPumpStatusMessage(pumpId: number, senderId?: number): PumpCommands {
352 | this.action = PumpMessage.ResponseIDs.PumpStatus - 1;
353 | this.createBaseMessage(senderId);
354 | this.writeInt32LE(this.controllerId);
355 | this.writeInt32LE(pumpId - 1);
356 | this.unit.write(this.toBuffer());
357 | return this;
358 | }
359 | public sendSetPumpSpeed(pumpId: number, circuitId: number, speed: number, isRPMs?: boolean, senderId?: number): PumpCommands {
360 | this.action = PumpMessage.ResponseIDs.SetPumpSpeed - 1;
361 | if (typeof isRPMs === 'undefined') {
362 | if (speed < 400) { isRPMs = false; }
363 | else isRPMs = true;
364 | }
365 | const _isRPMs = isRPMs ? 1 : 0;
366 | this.createBaseMessage(senderId);
367 | this.writeInt32LE(this.controllerId);
368 | this.writeInt32LE(pumpId - 1);
369 | this.writeInt32LE(circuitId); // This is indexed to the array of circuits returned in GetPumpStatus
370 | this.writeInt32LE(speed);
371 | this.writeInt32LE(_isRPMs);
372 | this.unit.write(this.toBuffer());
373 | return this;
374 | }
375 | }
376 | export class OutboundGateway extends Outbound {
377 | public createSendGatewayMessage(systemName: string, senderId?: number): Buffer {
378 | this.action = ConnectionMessage.ResponseIDs.GatewayResponse - 1;
379 | this.createBaseMessage(senderId);
380 | this.writeSLString(systemName);
381 | this.writeSLString(systemName);
382 | return this.toBuffer();
383 | }
384 | }
--------------------------------------------------------------------------------
/dist/messages/OutgoingMessages.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | exports.OutboundGateway = exports.PumpCommands = exports.ScheduleCommands = exports.BodyCommands = exports.ChemCommands = exports.ChlorCommands = exports.CircuitCommands = exports.EquipmentCommands = exports.ConnectionCommands = exports.Commands = void 0;
4 | const SLMessage_1 = require("./SLMessage");
5 | const index_1 = require("../index");
6 | const EquipmentConfig_1 = require("./config/EquipmentConfig");
7 | class Commands extends SLMessage_1.Outbound {
8 | constructor(unit, senderId) {
9 | super(unit.controllerId, senderId !== null && senderId !== void 0 ? senderId : unit.senderId);
10 | this.unit = unit;
11 | }
12 | }
13 | exports.Commands = Commands;
14 | class ConnectionCommands extends Commands {
15 | sendLoginMessage(password, senderId) {
16 | this.action = index_1.ConnectionMessage.ResponseIDs.Login - 1;
17 | this.createBaseMessage(senderId);
18 | // this.addHeader(this.senderId, this.messageId)
19 | this.writeInt32LE(348); // schema
20 | this.writeInt32LE(0); // connection type
21 | this.writeSLString('node-screenlogic'); // version
22 | if (!password) {
23 | password = Buffer.alloc(16);
24 | }
25 | if (password.length > 16) {
26 | password = password.slice(0, 16);
27 | }
28 | this.writeSLArray(password); // encoded password. empty/unused for local connections
29 | this.writeInt32LE(2); // procID
30 | this.unit.write(this.toBuffer());
31 | return this;
32 | }
33 | sendChallengeMessage(senderId) {
34 | this.action = index_1.ConnectionMessage.ResponseIDs.Challenge - 1;
35 | this.createBaseMessage(senderId);
36 | this.unit.write(this.toBuffer());
37 | return this;
38 | }
39 | sendVersionMessage(senderId) {
40 | this.action = index_1.ConnectionMessage.ResponseIDs.Version - 1;
41 | this.createBaseMessage(senderId);
42 | this.unit.write(this.toBuffer());
43 | return this;
44 | }
45 | sendAddClientMessage(clientId, senderId) {
46 | this.action = index_1.ConnectionMessage.ResponseIDs.AddClient - 1;
47 | this.createBaseMessage(senderId);
48 | this.writeInt32LE(this.unit.controllerId);
49 | this.writeInt32LE(clientId !== null && clientId !== void 0 ? clientId : this.unit.clientId);
50 | this.unit.write(this.toBuffer());
51 | return this;
52 | }
53 | sendRemoveClientMessage(clientId, senderId) {
54 | this.action = index_1.ConnectionMessage.ResponseIDs.RemoveClient - 1;
55 | this.createBaseMessage(senderId);
56 | this.writeInt32LE(this.unit.controllerId);
57 | this.writeInt32LE(clientId !== null && clientId !== void 0 ? clientId : this.unit.clientId);
58 | this.unit.write(this.toBuffer());
59 | return this;
60 | }
61 | sendPingMessage(senderId) {
62 | this.action = index_1.ConnectionMessage.ResponseIDs.Ping - 1;
63 | this.createBaseMessage(senderId);
64 | this.unit.write(this.toBuffer());
65 | return this;
66 | }
67 | }
68 | exports.ConnectionCommands = ConnectionCommands;
69 | class EquipmentCommands extends Commands {
70 | sendGetEquipmentStateMessage(senderId) {
71 | this.action = index_1.EquipmentStateMessage.ResponseIDs.EquipmentState - 1;
72 | this.createBaseMessage(senderId);
73 | this.writeInt32LE(0);
74 | this.unit.write(this.toBuffer());
75 | return this;
76 | }
77 | sendGetControllerConfigMessage(senderId) {
78 | this.action = EquipmentConfig_1.EquipmentConfigurationMessage.ResponseIDs.GetControllerConfig - 1;
79 | this.createBaseMessage(senderId);
80 | this.writeInt32LE(0);
81 | this.writeInt32LE(0);
82 | this.unit.write(this.toBuffer());
83 | return this;
84 | }
85 | sendGetNumCircuitNamesMessage(senderId) {
86 | this.action = EquipmentConfig_1.EquipmentConfigurationMessage.ResponseIDs.NumCircuitNames - 1;
87 | this.createBaseMessage(senderId);
88 | this.writeInt32LE(0);
89 | this.writeInt32LE(0);
90 | this.unit.write(this.toBuffer());
91 | return this;
92 | }
93 | sendGetCircuitNamesMessage(idx, cnt, senderId) {
94 | this.action = EquipmentConfig_1.EquipmentConfigurationMessage.ResponseIDs.GetCircuitNames;
95 | this.createBaseMessage(senderId);
96 | this.writeInt32LE(0);
97 | this.writeInt32LE(idx);
98 | this.writeInt32LE(cnt);
99 | this.unit.write(this.toBuffer());
100 | return this;
101 | }
102 | sendGetCircuitDefinitionsMessage(senderId) {
103 | this.action = EquipmentConfig_1.EquipmentConfigurationMessage.ResponseIDs.GetCircuitDefinitions - 1;
104 | this.createBaseMessage(senderId);
105 | this.writeInt32LE(0);
106 | this.writeInt32LE(0);
107 | this.unit.write(this.toBuffer());
108 | return this;
109 | }
110 | sendGetEquipmentConfigurationMessage(senderId) {
111 | this.action = EquipmentConfig_1.EquipmentConfigurationMessage.ResponseIDs.GetEquipmentConfiguration - 1;
112 | this.createBaseMessage(senderId);
113 | this.writeInt32LE(0);
114 | this.writeInt32LE(0);
115 | this.unit.write(this.toBuffer());
116 | return this;
117 | }
118 | sendSetEquipmentConfigurationMessageAsync(data, senderId) {
119 | this.action = EquipmentConfig_1.EquipmentConfigurationMessage.ResponseIDs.SetEquipmentConfiguration; //setequipconfg
120 | this.createBaseMessage(senderId);
121 | this.writeInt32LE(0);
122 | this.writeInt32LE(0);
123 | this.unit.write(this.toBuffer());
124 | return this;
125 | }
126 | sendGetSystemTimeMessage(senderId) {
127 | this.action = index_1.EquipmentStateMessage.ResponseIDs.SystemTime - 1;
128 | this.createBaseMessage(senderId);
129 | this.unit.write(this.toBuffer());
130 | return this;
131 | }
132 | sendCancelDelayMessage(senderId) {
133 | this.action = index_1.EquipmentStateMessage.ResponseIDs.CancelDelay - 1;
134 | this.createBaseMessage(senderId);
135 | this.writeInt32LE(0);
136 | this.unit.write(this.toBuffer());
137 | return this;
138 | }
139 | sendGetCustomNamesMessage(senderId) {
140 | this.action = EquipmentConfig_1.EquipmentConfigurationMessage.ResponseIDs.GetCustomNamesAck - 1;
141 | this.createBaseMessage(senderId);
142 | this.writeInt32LE(0);
143 | this.unit.write(this.toBuffer());
144 | return this;
145 | }
146 | sendSetCustomNameMessage(idx, name, senderId) {
147 | this.action = EquipmentConfig_1.EquipmentConfigurationMessage.ResponseIDs.SetCustomNameAck - 1;
148 | this.createBaseMessage(senderId);
149 | this.writeInt32LE(this.controllerId);
150 | this.writeInt32LE(idx);
151 | this.writeSLString(name);
152 | this.unit.write(this.toBuffer());
153 | return this;
154 | }
155 | sendGetWeatherMessage(senderId) {
156 | this.action = EquipmentConfig_1.EquipmentConfigurationMessage.ResponseIDs.WeatherForecastAck - 1;
157 | this.createBaseMessage(senderId);
158 | this.writeInt32LE(0);
159 | this.writeInt32LE(0);
160 | this.unit.write(this.toBuffer());
161 | return this;
162 | }
163 | sendSetSystemTimeMessage(date, shouldAdjustForDST, senderId) {
164 | this.action = index_1.EquipmentStateMessage.ResponseIDs.SetSystemTime - 1;
165 | this.createBaseMessage(senderId);
166 | this.writeSLDateTime(date);
167 | this.writeInt32LE(shouldAdjustForDST ? 1 : 0);
168 | this.unit.write(this.toBuffer());
169 | return this;
170 | }
171 | sendGetHistoryMessage(fromTime, toTime, senderId) {
172 | this.action = EquipmentConfig_1.EquipmentConfigurationMessage.ResponseIDs.HistoryDataPending - 1;
173 | this.createBaseMessage(senderId);
174 | this.writeInt32LE(this.controllerId);
175 | this.writeSLDateTime(fromTime);
176 | this.writeSLDateTime(toTime);
177 | this.writeInt32LE(senderId !== null && senderId !== void 0 ? senderId : this.senderId);
178 | this.unit.write(this.toBuffer());
179 | return this;
180 | }
181 | }
182 | exports.EquipmentCommands = EquipmentCommands;
183 | class CircuitCommands extends Commands {
184 | sendSetCircuitMessage(circuitId, nameIndex, circuitFunction, circuitInterface, freeze, colorPos, senderId) {
185 | this.action = index_1.CircuitMessage.ResponseIDs.SetCircuitInfo - 1;
186 | this.createBaseMessage(senderId);
187 | this.writeInt32LE(this.controllerId);
188 | this.writeInt32LE(circuitId + 499);
189 | // normalize to 1 based ids for default names; 100 based for custom names
190 | // circuitArray[i].nameIndex = circuitArray[i].nameIndex < 101 ? circuitArray[i].nameIndex + 1 : circuitArray[i].nameIndex + 99;
191 | this.writeInt32LE(nameIndex < 102 ? nameIndex - 1 : nameIndex - 99);
192 | this.writeInt32LE(circuitFunction);
193 | this.writeInt32LE(circuitInterface);
194 | this.writeInt32LE(freeze ? 1 : 0); // could be other bits; this is a flag
195 | this.writeInt32LE(colorPos);
196 | this.encode();
197 | this.unit.write(this.toBuffer());
198 | return this;
199 | }
200 | sendSetCircuitStateMessage(circuitId, circuitState, senderId) {
201 | this.action = index_1.CircuitMessage.ResponseIDs.SetCircuitState - 1;
202 | this.createBaseMessage(senderId);
203 | // this.addHeader(this.senderId, this.messageId);
204 | // this._controllerId = controllerId;
205 | this.writeInt32LE(this.controllerId);
206 | this.writeInt32LE(circuitId + 499);
207 | this.writeInt32LE((circuitState ? 1 : 0) || 0);
208 | this.encode();
209 | this.unit.write(this.toBuffer());
210 | return this;
211 | }
212 | sendIntellibriteMessage(command, senderId) {
213 | this.action = index_1.CircuitMessage.ResponseIDs.SetLightState - 1;
214 | this.createBaseMessage(senderId);
215 | this.writeInt32LE(this.unit.controllerId);
216 | this.writeInt32LE(command || 0);
217 | this.unit.write(this.toBuffer());
218 | return this;
219 | }
220 | sendSetCircuitRuntimeMessage(circuitId, runTime, senderId) {
221 | this.action = index_1.CircuitMessage.ResponseIDs.SetCircuitRunTime - 1;
222 | this.createBaseMessage(senderId);
223 | this.writeInt32LE(this.unit.controllerId);
224 | this.writeInt32LE(circuitId + 499);
225 | this.writeInt32LE(runTime);
226 | this.unit.write(this.toBuffer());
227 | return this;
228 | }
229 | }
230 | exports.CircuitCommands = CircuitCommands;
231 | class ChlorCommands extends Commands {
232 | sendSetChlorOutputMessage(poolOutput, spaOutput, senderId) {
233 | this.action = index_1.ChlorMessage.ResponseIDs.SetIntellichlorConfig - 1;
234 | this.createBaseMessage(senderId);
235 | this.writeInt32LE(this.unit.controllerId);
236 | this.writeInt32LE(poolOutput || 0);
237 | this.writeInt32LE(spaOutput || 0);
238 | this.writeInt32LE(0);
239 | this.writeInt32LE(0);
240 | this.unit.write(this.toBuffer());
241 | return this;
242 | }
243 | sendGetSaltCellConfigMessage(senderId) {
244 | this.action = index_1.ChlorMessage.ResponseIDs.GetIntellichlorConfig - 1;
245 | this.createBaseMessage(senderId);
246 | this.writeInt32LE(this.unit.controllerId);
247 | this.unit.write(this.toBuffer());
248 | return this;
249 | }
250 | sendSetSaltCellEnableMessage(isActive, senderId) {
251 | this.action = index_1.ChlorMessage.ResponseIDs.SetIntellichlorEnabled - 1;
252 | this.createBaseMessage(senderId);
253 | this.writeInt32LE(this.unit.controllerId);
254 | this.writeInt32LE(isActive ? 1 : 0);
255 | this.unit.write(this.toBuffer());
256 | return this;
257 | }
258 | }
259 | exports.ChlorCommands = ChlorCommands;
260 | class ChemCommands extends Commands {
261 | sendGetChemStatusMessage(senderId) {
262 | this.action = index_1.ChemMessage.ResponseIDs.GetChemicalData - 1;
263 | this.createBaseMessage(senderId);
264 | this.writeInt32LE(0);
265 | this.unit.write(this.toBuffer());
266 | return this;
267 | }
268 | sendGetChemHistoryMessage(fromTime, toTime, senderId) {
269 | this.action = index_1.ChemMessage.ResponseIDs.HistoryDataPending - 1;
270 | this.createBaseMessage(senderId);
271 | this.writeInt32LE(0);
272 | this.writeSLDateTime(fromTime);
273 | this.writeSLDateTime(toTime);
274 | this.writeInt32LE(senderId !== null && senderId !== void 0 ? senderId : this.senderId);
275 | this.unit.write(this.toBuffer());
276 | return this;
277 | }
278 | }
279 | exports.ChemCommands = ChemCommands;
280 | class BodyCommands extends Commands {
281 | sendSetPointMessage(bodyType, temperature, senderId) {
282 | this.action = index_1.HeaterMessage.ResponseIDs.SetHeatSetPoint - 1;
283 | this.createBaseMessage(senderId);
284 | this.writeInt32LE(this.unit.controllerId);
285 | this.writeInt32LE(bodyType || 0);
286 | this.writeInt32LE(temperature || 0);
287 | this.unit.write(this.toBuffer());
288 | return this;
289 | }
290 | sendCoolSetPointMessage(bodyType, temperature, senderId) {
291 | this.action = index_1.HeaterMessage.ResponseIDs.SetCoolSetPoint - 1;
292 | this.createBaseMessage(senderId);
293 | this.writeInt32LE(this.unit.controllerId);
294 | this.writeInt32LE(bodyType || 0);
295 | this.writeInt32LE(temperature || 0);
296 | this.unit.write(this.toBuffer());
297 | return this;
298 | }
299 | sendHeatModeMessage(bodyType, heatMode, senderId) {
300 | this.action = index_1.HeaterMessage.ResponseIDs.SetHeatMode - 1;
301 | this.createBaseMessage(senderId);
302 | this.writeInt32LE(this.unit.controllerId);
303 | this.writeInt32LE(bodyType || 0);
304 | this.writeInt32LE(heatMode || 0);
305 | this.unit.write(this.toBuffer());
306 | return this;
307 | }
308 | }
309 | exports.BodyCommands = BodyCommands;
310 | class ScheduleCommands extends Commands {
311 | sendGetSchedulesMessage(schedType, senderId) {
312 | this.action = index_1.ScheduleMessage.ResponseIDs.GetSchedule - 1;
313 | this.createBaseMessage(senderId);
314 | this.writeInt32LE(0);
315 | this.writeInt32LE(schedType);
316 | this.unit.write(this.toBuffer());
317 | return this;
318 | }
319 | sendAddScheduleEventMessage(schedType, senderId) {
320 | this.action = index_1.ScheduleMessage.ResponseIDs.AddSchedule - 1;
321 | this.createBaseMessage(senderId);
322 | this.writeInt32LE(0);
323 | this.writeInt32LE(schedType);
324 | this.unit.write(this.toBuffer());
325 | return this;
326 | }
327 | sendDeleteScheduleEventMessage(schedId, senderId) {
328 | this.action = index_1.ScheduleMessage.ResponseIDs.DeleteSchedule - 1;
329 | this.createBaseMessage(senderId);
330 | this.writeInt32LE(this.controllerId);
331 | this.writeInt32LE(schedId + 699);
332 | this.unit.write(this.toBuffer());
333 | return this;
334 | }
335 | sendSetScheduleEventMessage(scheduleId, circuitId, startTime, stopTime, dayMask, flags, heatCmd, heatSetPoint, senderId) {
336 | this.action = index_1.ScheduleMessage.ResponseIDs.SetSchedule - 1;
337 | this.createBaseMessage(senderId);
338 | this.writeInt32LE(0);
339 | this.writeInt32LE(scheduleId + 699);
340 | this.writeInt32LE(circuitId + 499);
341 | this.writeInt32LE(startTime);
342 | this.writeInt32LE(stopTime);
343 | this.writeInt32LE(dayMask);
344 | this.writeInt32LE(flags);
345 | this.writeInt32LE(heatCmd);
346 | this.writeInt32LE(heatSetPoint);
347 | this.unit.write(this.toBuffer());
348 | return this;
349 | }
350 | }
351 | exports.ScheduleCommands = ScheduleCommands;
352 | class PumpCommands extends Commands {
353 | sendGetPumpStatusMessage(pumpId, senderId) {
354 | this.action = index_1.PumpMessage.ResponseIDs.PumpStatus - 1;
355 | this.createBaseMessage(senderId);
356 | this.writeInt32LE(this.controllerId);
357 | this.writeInt32LE(pumpId - 1);
358 | this.unit.write(this.toBuffer());
359 | return this;
360 | }
361 | sendSetPumpSpeed(pumpId, circuitId, speed, isRPMs, senderId) {
362 | this.action = index_1.PumpMessage.ResponseIDs.SetPumpSpeed - 1;
363 | if (typeof isRPMs === 'undefined') {
364 | if (speed < 400) {
365 | isRPMs = false;
366 | }
367 | else
368 | isRPMs = true;
369 | }
370 | const _isRPMs = isRPMs ? 1 : 0;
371 | this.createBaseMessage(senderId);
372 | this.writeInt32LE(this.controllerId);
373 | this.writeInt32LE(pumpId - 1);
374 | this.writeInt32LE(circuitId); // This is indexed to the array of circuits returned in GetPumpStatus
375 | this.writeInt32LE(speed);
376 | this.writeInt32LE(_isRPMs);
377 | this.unit.write(this.toBuffer());
378 | return this;
379 | }
380 | }
381 | exports.PumpCommands = PumpCommands;
382 | class OutboundGateway extends SLMessage_1.Outbound {
383 | createSendGatewayMessage(systemName, senderId) {
384 | this.action = index_1.ConnectionMessage.ResponseIDs.GatewayResponse - 1;
385 | this.createBaseMessage(senderId);
386 | this.writeSLString(systemName);
387 | this.writeSLString(systemName);
388 | return this.toBuffer();
389 | }
390 | }
391 | exports.OutboundGateway = OutboundGateway;
392 | //# sourceMappingURL=OutgoingMessages.js.map
--------------------------------------------------------------------------------