diff --git a/README.md b/README.md new file mode 100755 index 0000000..02f3b38 --- /dev/null +++ b/README.md @@ -0,0 +1,267 @@ +# node-screenlogic + +This is a Node.JS library for interfacing with Pentair ScreenLogic systems over your local network. It requires a Pentair ScreenLogic device on the same network (a network which supports UDP broadcasts). + +Tested on node v8.11.1 with a system on firmware version 5.2 Build 736.0 Rel + +# Usage + +See example.js for an example of interfacing with the library. Broadly, import the library with + +```javascript +const ScreenLogic = require('node-screenlogic'); +``` + +then create a new ScreenLogic unit finder with + +```javascript +new ScreenLogic.FindUnits(); +``` + +Hook its `serverFound` event with + +```javascript +.on('serverFound', function(server) { }) +``` + +and call it via `search()`. This performs a UDP broadcast on 255.255.255.255, port 1444, so ensure your network supports UDP broadcasts and the device is on the same subnet. + +When a server is found, create a new UnitConnection with + +```javascript +new ScreenLogic.UnitConnection(server); +``` + +Once you've connected with `connect()`, there are a number of methods available and corresponding events for when they've completed successfully. See [UnitConnection](#unitconnection) API reference. + +All communication with a ScreenLogic unit is done via TCP, so responses will come back in the order they were requested. + +# Notes + +Contributions welcome. There are lots of available messages supported by ScreenLogic that the app doesn't support yet, but can be added pretty easily as needed. + +# Packet format + +All ScreenLogic packets are sent with an 8-byte header. The first 2 bytes are a little-endian-encoded sender ID (which is normally specified when making the original request). The second 2 bytes are a little-endian-encoded message ID. The final 4 bytes are a little-endian-encoded length of the data payload on the packet. The data payload is handled per-message. + +# API Reference + +Pull requests to document undocumented properties are most welcome. + +## FindUnits + +### constructor() + +Examples: +```javascript +const ScreenLogic = require('./index'); + +var finder = new ScreenLogic.FindUnits(); +``` + +### search() + +Begins a UDP broadcast search for available units. + +### close() + +Closes the socket. + +### Events + +* `serverFound` - Indicates that a ScreenLogic unit has been found. Event handler receives a [`UnitConnection`](#unitconnection) object. + +Examples: +```javascript +finder.on('serverFound', function(server) { + var client = new ScreenLogic.UnitConnection(server); +}) +``` + +## UnitConnection + +### constructor(server) + +Argument is a server returned from [`FindUnits`](#findunits) `serverFound` event. + +Examples: +```javascript +finder.on('serverFound', function(server) { + var client = new ScreenLogic.UnitConnection(server); +}) +``` + +### connect() + +Connects to the server passed to its constructor. + +Examples: +```javascript +var client = new ScreenLogic.UnitConnection(server); +client.connect(); +``` + +### close() + +Closes the connection. + +### getVersion() + +Requests the system version string from the connected unit. Emits the `version` event when the response comes back. + +### getPoolStatus() + +Requests pool status from the connected unit. Emits the `poolStatus` event when the response comes back. + +### getChemicalData() + +Requests chemical data from the connected unit (may require an IntelliChem or similar). Emits the `chemicalData` event when the response comes back. + +### getSaltCellConfig() + +Requests salt cell status/configuration from the connected unit (requires an IntelliChlor or compatible salt cell). Emits the `saltCellConfig` event when the response comes back. + +### getControllerConfig() + +Requests controller configuration from the connected unit. Emits the `controllerConfig` event when the response comes back. + +### Events + +* `loggedIn` +* `version` - Indicates that a response to `getVersion()` has been received. Event handler receives a [`SLVersionMessage`](#slversionmessage) object. +* `poolStatus` - Indicates that a response to `getPoolStatus()` has been received. Event handler receives a [`SLPoolStatusMessage`](#slpoolstatusmessage) object. +* `chemicalData` - Indicates that a response to `getChemicalData()` has been received. Event handler receives a [`SLChemDataMessage`](#slchemdatamessage) object. +* `saltCellConfig` - Indicates that a response to `getSaltCellConfig()` has been received. Event handler receives a [`SLSaltCellConfigMessage`](#slsaltcellconfigmessage) object. +* `controllerConfig` - Indicates that a response to `getControllerConfig()` has been received. Event handler receives a [`SLControllerConfigMessage`](#slcontrollerconfigmessage) object. + +## SLVersionMessage + +Passed as an argument to the emitted `version` event handler. + +### Properties + +* `version` - a string representing the system's version + +## SLPoolStatusMessage + +Passed as an argument to the emitted `poolStatus` event handler. + +### isDeviceReady() + +Returns a bool indicating whether the device is in a normal operating state. + +### isDeviceSync() + +Returns a bool. + +### isDeviceServiceMode() + +Returns a bool indicating whether the device is in service mode or not. + +### isSpaActive() + +Returns a bool indicating whether the spa is currently active or not. + +### isPoolActive() + +Returns a bool indicating whether the pool is currently active or not. + +### Properties + +* `ok` - can be interpreted with `isDevice...` methods. +* `freezeMode` - byte representing whether the device is in freeze mode or not. +* `remotes` - byte +* `poolDelay` - byte +* `spaDelay` - byte +* `cleanerDelay` - byte +* `airTemp` - integer representing the current temperature (check controller config to see if it's in celsius or fahrenheit) +* `currentTemp` - array of size 0-2 indicating current temperature of each body as an integer (spa/pool) (check controller config to see if it's in celsius or fahrenheit) +* `heatStatus` - array of size 0-2 indicating whether heat is active or not for each body as an integer (spa/pool) +* `setPoint` - array of size 0-2 holding the heating set point for each body as an integer (spa/pool) (check controller config to see if it's in celsius or fahrenheit) +* `coolSetPoint` - array of size 0-2 holding the cooling set point for each body as an integer (spa/pool) (check controller config to see if it's in celsius or fahrenheit) +* `heatMode` - array of size 0-2 indicating whether heating is enabled or not for each body as an integer (spa/pool) +* `circuitArray` - array holding all circuits in the system +** `id` - integer representing the circuit's ID (spa is 500, pool is 505) +** `state` - integer indicating whether the circuit is on or not (0/1) +** `colorSet` - byte +** `colorPos` - byte +** `colorStagger` - byte +** `delay` - byte +* `pH` - float indicating the current pH level (e.g.: 7.62) +* `orp` - integer indicating the current ORP value if available (e.g.: 650) +* `saturation` - float indicating the water balance/saturation level (e.g.: -0.13) +* `saltPPM` - integer indicating the salt level in parts-per-million (e.g.: 3000) +* `pHTank` - integer indicating the fill level of the pH tank (e.g.: 4) +* `orpTank` - integer indicating the fill level of the ORP tank +* `alarms` - integer indicating how many alarms are currently active + +## SLChemDataMessage + +Passed as an argument to the emitted `chemicalData` event handler. + +### Properties + +* `isValid` - boolean indicating whether we got a valid response back or not +* `pH` - float indicating the current pH level +* `orp` - short indicating the current ORP level +* `pHSetPoint` - float indicating the desired pH level +* `orpSetPoint` - short indicating the desired ORP level +* `pHTankLevel` - byte indicating how full the pH tank is. I believe this operates on a 0-6 scale +* `orpTankLevel` - byte indicating how full the ORP tank is +* `saturation` - float indicating water balance/LSI saturation +* `calcium` - short indicating the calcium level (manually set) +* `cyanuricAcid` - short indicating the CYA level (manually set) +* `alkalinity` - short indicating the alkalinity level (manually set) +* `saltPPM` - integer representing the salt level in parts-per-million +* `temperature` - byte indicating the current water temperature +* `corrosive` - boolean indicating whether the water balance is corrosive or not +* `scaling` - boolean indicating whether the water balance is scaling or not +* `error` - boolean indicating whether there's currently an error in the chem system or not + +## SLSaltCellConfigMessage + +Passed as an argument to the emitted `saltCellConfig` event handler. + +### Properties + +* `installed` - boolean indicating whether a salt cell is installed or not +* `status` - integer +* `level1` - integer +* `level2` - integer +* `salt` - integer indicating salt level in parts-per-million +* `flags` - integer +* `superChlorTimer` - integer + +## SLControllerConfigMessage + +Passed as an argument to the emitted `controllerConfig` event handler. + +### Properties + +* `controllerId` - integer indicating the controller's ID +* `minSetPoint` - array (size 2) indicating the minimum setpoint available for the pool or spa +* `maxSetPoint` - array (size 2) indicating the maximum setpoint available for the pool or spa +* `degC` - boolean indicating whether the system is using the centigrade scale for temperatures or not +* `controllerType` - byte +* `hwType` - byte +* `controllerData` - byte +* `equipFlags` - integer +* `genCircuitName` - string indicating the circuit name +* `bodyArray` - array (size number-of-circuits) holding circuit data +** `circuitId` - integer indicating circuit ID (e.g.: 500 is spa, 505 is pool) +** `name` - string representing the name of the circuit +** `nameIndex` - byte +** `function` - byte +** `interface` - byte +** `flags` - byte +** `colorSet` - byte +** `colorPos` - byte +** `colorStagger` - byte +** `deviceId` - byte +** `dfaultRt` - short +* `colorArray` - array (size number-of-colors) holding data about available light colors +** `name` - color name +** `color` - object containing `r`/`g`/`b` properties as bytes (values from 0-255) indicating the color +* `pumpCircArray` - array (size 8) holding data about pumps attached to the system +* `interfaceTabFlags` - integer +* `showAlarms` - integer