diff --git a/index.js b/index.js index 29e5868..1e54c8d 100644 --- a/index.js +++ b/index.js @@ -104,6 +104,21 @@ class UnitConnection extends EventEmitter { this.client.write(new messages.SLControllerConfigMessage().toBuffer()); } + getChemicalData() { + console.log('sending chemical data query...'); + this.client.write(new messages.SLChemDataMessage().toBuffer()); + } + + getSaltCellConfig() { + console.log('sending salt cell config query...'); + this.client.write(new messages.SLSaltCellConfigMessage().toBuffer()); + } + + getVersion() { + console.log('sending version query...'); + this.client.write(new messages.SLVersionMessage().toBuffer()); + } + onClientMessage(msg) { console.log('received message of length ' + msg.length); var msgType = msg.readInt16LE(2); @@ -119,6 +134,17 @@ class UnitConnection extends EventEmitter { } else if (msgType === 12533) { console.log(" it's controller configuration"); this.emit('controllerConfig', new messages.SLControllerConfigMessage(msg)); + } else if (msgType === 12593) { + console.log(" it's chem data"); + this.emit('chemicalData', new messages.SLChemDataMessage(msg)); + } else if (msgType === 12573) { + console.log(" it's salt cell config"); + this.emit('saltCellConfig', new messages.SLSaltCellConfigMessage(msg)); + } else if (msgType === 8121) { + console.log(" it's version"); + this.emit('version', new messages.SLVersionMessage(msg)); + } else { + console.log(" it's unknown. type: " + msgType); } } } diff --git a/messages/SLChemDataMessage.js b/messages/SLChemDataMessage.js new file mode 100755 index 0000000..9ed57d4 --- /dev/null +++ b/messages/SLChemDataMessage.js @@ -0,0 +1,48 @@ +const SLMessage = require('./SLMessage.js').SLMessage; + +exports.SLChemDataMessage = class SLChemDataMessage extends SLMessage { + constructor(buf) { + super(0, 12592); + if (!buf) { + this.writeInt32LE(0); // controller index + } else { + this._wroteSize = true; + this.writeBuffer(buf, 0); + + this.decode(); + } + } + + decode() { + super.decode(); + + let sentinel = this.readInt32LE(); + if (sentinel === 42) { + this.isValid = true; + this._readOffset++; + this.pH = this.readUInt16BE() / 100; + this.orp = this.readUInt16BE(); + this.pHSetPoint = this.readUInt16BE() / 100; + this.orpSetPoint = this.readUInt16BE(); + this._readOffset += 12; + this.pHTankLevel = this.readUInt8(); + this.orpTankLevel = this.readUInt8(); + this.saturation = this.readUInt8(); + if ((this.saturation & 128) !== 0) { + this.saturation = -(256 - this.saturation); + } + this.saturation /= 100; + this.calcium = this.readUInt16BE(); + this.cyanuricAcid = this.readUInt16BE(); + this.alkalinity = this.readUInt16BE(); + let salt = this.readUInt16LE(); + this.saltPPM = salt * 50; + this.temperature = this.readUInt8(); + this._readOffset += 2; + let balance = this.readUInt8(); + this.corrosive = (balance & 1) !== 0; + this.scaling = (balance & 2) !== 0; + this.error = (salt & 128) !== 0; + } + } +} diff --git a/messages/SLPoolStatusMessage.js b/messages/SLPoolStatusMessage.js index 0d2d6f3..6c8d69b 100755 --- a/messages/SLPoolStatusMessage.js +++ b/messages/SLPoolStatusMessage.js @@ -59,10 +59,10 @@ exports.SLPoolStatusMessage = class SLPoolStatusMessage extends SLMessage { } } - this.pH = this.readInt32LE(); + this.pH = this.readInt32LE() / 100; this.orp = this.readInt32LE(); - this.saturation = this.readInt32LE(); - this.saltPPM = this.readInt32LE(); + this.saturation = this.readInt32LE() / 100; + this.saltPPM = this.readInt32LE() * 50; this.pHTank = this.readInt32LE(); this.orpTank = this.readInt32LE(); this.alarms = this.readInt32LE(); diff --git a/messages/SLSaltCellConfigMessage.js b/messages/SLSaltCellConfigMessage.js new file mode 100755 index 0000000..b542f31 --- /dev/null +++ b/messages/SLSaltCellConfigMessage.js @@ -0,0 +1,27 @@ +const SLMessage = require('./SLMessage.js').SLMessage; + +exports.SLSaltCellConfigMessage = class SLSaltCellConfigMessage extends SLMessage { + constructor(buf) { + super(0, 12572); + if (!buf) { + this.writeInt32LE(0); // controller index + } else { + this._wroteSize = true; + this.writeBuffer(buf, 0); + + this.decode(); + } + } + + decode() { + super.decode(); + + this.installed = this.readInt32LE() === 1; + this.status = this.readInt32LE(); + this.level1 = this.readInt32LE(); + this.level2 = this.readInt32LE(); + this.salt = this.readInt32LE() * 50; + this.flags = this.readInt32LE(); + this.superChlorTimer = this.readInt32LE(); + } +} diff --git a/messages/SLVersionMessage.js b/messages/SLVersionMessage.js new file mode 100755 index 0000000..35c58de --- /dev/null +++ b/messages/SLVersionMessage.js @@ -0,0 +1,19 @@ +const SLMessage = require('./SLMessage.js').SLMessage; + +exports.SLVersionMessage = class SLVersionMessage extends SLMessage { + constructor(buf) { + super(0, 8120); + if (buf) { + this._wroteSize = true; + this.writeBuffer(buf, 0); + + this.decode(); + } + } + + decode() { + super.decode(); + + this.version = this.readSLString(); + } +} diff --git a/messages/index.js b/messages/index.js index abe6af3..d7d7377 100755 --- a/messages/index.js +++ b/messages/index.js @@ -2,3 +2,6 @@ exports.SLPoolStatusMessage = require("./SLPoolStatusMessage.js").SLPoolStatusMe exports.SLControllerConfigMessage = require("./SLControllerConfigMessage.js").SLControllerConfigMessage; exports.SLChallengeMessage = require("./SLChallengeMessage.js").SLChallengeMessage; exports.SLLoginMessage = require("./SLLoginMessage.js").SLLoginMessage; +exports.SLChemDataMessage = require("./SLChemDataMessage.js").SLChemDataMessage; +exports.SLSaltCellConfigMessage = require("./SLSaltCellConfigMessage.js").SLSaltCellConfigMessage; +exports.SLVersionMessage = require("./SLVersionMessage.js").SLVersionMessage; diff --git a/test.js b/test.js index b228978..a024230 100755 --- a/test.js +++ b/test.js @@ -4,17 +4,29 @@ var finder = new ScreenLogic.FindUnits(); finder.on('serverFound', function(server) { var client = new ScreenLogic.UnitConnection(server); client.on('loggedIn', function() { + this.getVersion(); this.getPoolStatus(); + this.getChemicalData(); + this.getSaltCellConfig(); this.getControllerConfig(); }).on('poolStatus', function(status) { console.log(" pool ok=" + status.ok); console.log(" air temp=" + status.airTemp); - console.log(" salt ppm=" + status.saltPPM * 50); - console.log(" pH=" + status.pH / 100); + console.log(" salt ppm=" + status.saltPPM); + console.log(" pH=" + status.pH); + console.log(" saturation=" + status.saturation); }).on('controllerConfig', function(config) { console.log(" controller is in celsius=" + config.degC); client.close(); finder.close(); + }).on('chemicalData', function(chemData) { + console.log(" calcium=" + chemData.calcium); + console.log(" cyanuric acid=" + chemData.cyanuricAcid); + console.log(" alkalinity=" + chemData.alkalinity); + }).on('saltCellConfig', function(saltCellConfig) { + console.log(" salt cell installed=" + saltCellConfig.installed); + }).on('version', function(version) { + console.log(" version=" + version.version); }); client.connect();