Skip to content

Commit

Permalink
Move screenlogic as part of comms
Browse files Browse the repository at this point in the history
  • Loading branch information
tagyoureit committed Dec 18, 2022
1 parent f69e7e5 commit 80106f2
Show file tree
Hide file tree
Showing 10 changed files with 246 additions and 185 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# nodejs-poolController - Version 7.7
# nodejs-poolController - Version 8.0

## What is nodejs-poolController

Expand All @@ -11,8 +11,8 @@ nodejs-poolController is an application to communicate and control your Pentair
* Want to control your pumps or chlorinator without a pool controller?

Equipment supported
1. Controllers: IntelliCenter, Intellitouch, EasyTouch, No controller (standalone equimpent)
1. Pumps: Intelliflow VS/VSF/VF, older models
1. Controllers: IntelliCenter, Intellitouch, EasyTouch, Nixie (standalone equimpent), Aqualink
1. Pumps: Intelliflow VS/VSF/VF, older models, relay controlled pumps, Whisperflo
1. Chlorinators: Intellichlor, Aqua-Rite and OEM brands
1. Heaters: Gas, solar, heatpump
1. Intellichem and Relay Equipment Manager (REM) chemical controllers
Expand All @@ -23,6 +23,10 @@ Equipment supported
## Latest Changes
See [Changelog](https://github.com/tagyoureit/nodejs-poolController/blob/master/Changelog)

## What's new in 8.0?

Screenlogic can now be used as a direct connection point. If you feel that integrating an RS-485 adapter is a bit too much, then this is an option for you. The preferred method is still RS-485 as it is more fully featured.

## What's new in 7.0?

The current version includes very tight intergation with [relayEquipmentManager](https://github.com/rstrouse/relayEquipmentManager) which allows for hardware control over your ancillary pool equipment (chemical probes, pumps, tanks, heaters, pumps, etc).
Expand Down
4 changes: 2 additions & 2 deletions app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export async function initAsync() {
await conn.initAsync();
await sys.start();
await webApp.initAutoBackup();
await sl.initAsync();
await sl.openAsync();
} catch (err) { console.log(`Error Initializing nodejs-PoolController ${err.message}`); }
}

Expand Down Expand Up @@ -70,7 +70,7 @@ export async function stopAsync(): Promise<void> {
await sys.stopAsync();
await state.stopAsync();
await conn.stopAsync();
await sl.stopAsync();
await sl.closeAsync();
await webApp.stopAsync();
await config.updateAsync();
await logger.stopAsync();
Expand Down
2 changes: 1 addition & 1 deletion controller/boards/IntelliCenterBoard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ export class IntelliCenterBoard extends SystemBoard {
this.modulesAcquired = false;
}
public checkConfiguration() {
if (!conn.mockPort) {
if (!conn.mock) {
(sys.board as IntelliCenterBoard).needsConfigChanges = true;
// Send out a message to the outdoor panel that we need info about
// our current configuration.
Expand Down
296 changes: 169 additions & 127 deletions controller/comms/Comms.ts

Large diffs are not rendered by default.

36 changes: 16 additions & 20 deletions controller/comms/ScreenLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,27 +41,22 @@ export class ScreenLogicComms {
private pollingInterval = 10000;
public enabled: boolean = false;

public async initAsync() {
public async openAsync() {
let self = this;
process.stdout.on('error', function (err) {
if (err.code == "EPIPE") {
process.exit(0);
}
});
this.circuits = new SLCircuits(this._client);
this.bodies = new SLBodies(this._client);
this.chlor = new SLChlor(this._client);
this.schedules = new SLSchedule(this._client);
this.pumps = new SLPump(this._client);
let cfg = config.getSection('controller.screenlogic');
let cfg = config.getSection('controller.comms');
if (typeof cfg !== 'undefined') this._cfg = cfg;
this.enabled = this._cfg.enabled;
if (!this._cfg.enabled) {
if (!this._cfg.enabled || this._cfg.type !== 'screenlogic') {
return;
}

let systemName = this._cfg.systemName; // 'Pentair: 00-00-00';
let password = this._cfg.password; // '1111';
let systemName = this._cfg.screenlogic.systemName; // 'Pentair: 00-00-00';
let password = this._cfg.screenlogic.password.toString(); // '1111';

this._gateway = new ScreenLogic.RemoteLogin(systemName);
this._gateway.on('error', async (err) => {
Expand Down Expand Up @@ -326,25 +321,25 @@ export class ScreenLogicComms {
return Promise.resolve(error);
}
}
public async stopAsync() {
public async closeAsync() {
await this._client.closeAsync();
this._client.removeAllListeners();
this.isOpen = false;
if (typeof this._pollTimer !== 'undefined') clearTimeout(this._pollTimer);
this._pollTimer = null;
}
public async setScreenlogicAsync(data) {
/* public async setScreenlogicAsync(data) {
let enabled = typeof data.enabled !== 'undefined' ? utils.makeBool(data.enabled) : false;
let systemName = typeof data.systemName !== 'undefined' ? data.systemName : this._cfg.systemName;
let password = typeof data.password !== 'undefined' ? data.password.toString() : this._cfg.password;
let regx = /Pentair: (?:(?:\d|[A-Z])(?:\d|[A-Z])-){2}(?:\d|[A-Z])(?:\d|[A-Z])/g;
let type = typeof data.type !== 'undefined' ? data.type : this._cfg.type;
let type = typeof data.connectionType !== 'undefined' ? data.connectionType : this._cfg.connectionType;
if (type !== 'remote' && type !== 'local') return Promise.reject(new InvalidEquipmentDataError(`An invalid type was supplied for Screenlogic ${type}. Must be remote or local.`, 'Screenlogic', data));
if (systemName.match(regx) === null) return Promise.reject(new InvalidEquipmentDataError(`An invalid system name was supplied for Screenlogic ${systemName}}. Must be in the format 'Pentair: xx-xx-xx'.`, 'Screenlogic', data));
if (password.length > 4) return Promise.reject(new InvalidEquipmentDataError(`An invalid password was supplied for Screenlogic ${password}. (Length must be <= 4)}`, 'Screenlogic', data));
this.enabled = enabled;
if (this._cfg.enabled && !enabled || this._cfg.systemName !== systemName || this._cfg.password !== password || this._cfg.cype !== type) {
await this.stopAsync();
await this.closeAsync();
}
let obj = {
enabled,
Expand All @@ -355,11 +350,11 @@ export class ScreenLogicComms {
config.setSection('controller.screenlogic', obj);
this._cfg = config.getSection('controller.screenlogic');
if (this._cfg.enabled) {
let error = await this.initAsync();
let error = await this.openAsync();
if (typeof error !== 'undefined') return Promise.reject(error);
}
}
} */
public async pollAsync() {
let self = this;
try {
Expand All @@ -378,17 +373,18 @@ export class ScreenLogicComms {
}
catch (err) {
logger.error(`Error polling screenlogic (${this._pollCountError} errors)- ${err}`); this._pollCountError++;
if (this._pollCountError > 3) {
/* if (this._pollCountError > 3) {
await this.initAsync();
}
} */
}
finally { this._pollTimer = setTimeout(async () => await self.pollAsync(), this.pollingInterval || 10000); }
}
public static async searchAsync() {
try {
let finder = new ScreenLogic.FindUnits();
let localUnit = await finder.searchAsync();
return Promise.resolve(localUnit);
let localUnits = await finder.searchAsync();
finder.close();
return Promise.resolve(localUnits);
}
catch (err) {
logger.error(`Screenlogic: Error searching for units: ${err.message}`);
Expand Down
2 changes: 1 addition & 1 deletion controller/comms/messages/Messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ export class Inbound extends Message {
if (this.portId === sys.anslq25.portId) {
return MessagesMock.process(this);
}
if (port.mockPort && port.hasAssignedEquipment()){
if (port.mock && port.hasAssignedEquipment()){
return MessagesMock.process(this);
}
switch (this.protocol) {
Expand Down
14 changes: 7 additions & 7 deletions defaultConfig.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
{
"controller": {
"comms": {
"type": "local",
"portId": 0,
"enabled": true,
"rs485Port": "/dev/ttyUSB0",
"mockPort": false,
"mock": false,
"netConnect": false,
"netHost": "raspberrypi",
"netPort": 9801,
Expand All @@ -22,6 +23,11 @@
"allowHalfOpen": false,
"keepAlive": false,
"keepAliveInitialDelay": 5
},
"screenlogic": {
"connectionType": "local",
"systemName": "Pentair: 00-00-00",
"password": 1234
}
},
"backups": {
Expand All @@ -33,12 +39,6 @@
"keepCount": 5,
"njsPC": true,
"servers": []
},
"screenlogic": {
"enabled": false,
"type": "local",
"systemName": "Pentair: 00-00-00",
"password": 1234
}
},
"web": {
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 35 additions & 19 deletions web/services/config/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,30 +67,46 @@ export class ConfigRoute {
});
app.get('/config/options/rs485', async (req, res, next) => {
try {
let opts = { ports: [], local: [] }
let opts = { ports: [], local: [], screenlogic: {} }
let cfg = config.getSection('controller');
for (let section in cfg) {
if (section.startsWith('comms')) {
let cport = extend(true, { enabled: false, netConnect: false, mockPort: false }, cfg[section]);
let cport = extend(true, { enabled: false, netConnect: false, mock: false }, cfg[section]);
let port = conn.findPortById(cport.portId || 0);
if (typeof cport.type === 'undefined'){
cport.type = cport.netConnect ? 'netConnect' : cport.mockPort || cport.mock ? 'mock' : 'local'
}
if (typeof port !== 'undefined') cport.stats = port.stats;
if (port.portId === 0 && port.type === 'screenlogic') {
cport.screenlogic.stats = sl.stats;
}
opts.ports.push(cport);
}
// if (section.startsWith('screenlogic')){
// let screenlogic = cfg[section];
// screenlogic.types = [{ val: 'local', name: 'Local', desc: 'Local Screenlogic' }, { val: 'remote', name: 'Remote', desc: 'Remote Screenlogic' }];
// screenlogic.stats = sl.stats;
// opts.screenlogic = screenlogic;
// }
}
opts.local = await conn.getLocalPortsAsync() || [];
return res.status(200).send(opts);
} catch (err) { next(err); }
});
app.get('/config/options/screenlogic', async (req, res, next) => {
try {
let localUnit = await ScreenLogicComms.searchAsync();
let cfg = config.getSection('controller.screenlogic');
let data = {
cfg,
localUnit,
types: [{ val: 'local', name: 'Local', desc: 'Local Screenlogic' }, { val: 'remote', name: 'Remote', desc: 'Remote Screenlogic' }]
}
return res.status(200).send(data);
// app.get('/config/options/screenlogic', async (req, res, next) => {
// try {
// let cfg = config.getSection('controller.screenlogic');
// let data = {
// cfg,
// types: [{ val: 'local', name: 'Local', desc: 'Local Screenlogic' }, { val: 'remote', name: 'Remote', desc: 'Remote Screenlogic' }]
// }
// return res.status(200).send(data);
// } catch (err) { next(err); }
// });
app.get('/config/options/screenlogic/search', async (req, res, next) => {
try {
let localUnits = await ScreenLogicComms.searchAsync();
return res.status(200).send(localUnits);
} catch (err) { next(err); }
});
app.get('/config/options/circuits', async (req, res, next) => {
Expand Down Expand Up @@ -842,13 +858,13 @@ export class ConfigRoute {
}
catch (err) { next(err); }
});
app.put('/app/screenlogic', async (req, res, next) => {
try {
let screenlogic = await sl.setScreenlogicAsync(req.body);
return res.status(200).send(screenlogic);
}
catch (err) { next(err); }
});
// app.put('/app/screenlogic', async (req, res, next) => {
// try {
// let screenlogic = await sl.setScreenlogicAsync(req.body);
// return res.status(200).send(screenlogic);
// }
// catch (err) { next(err); }
// });
app.delete('/app/rs485Port', async (req, res, next) => {
try {
let port = await conn.deleteAuxPort(req.body);
Expand Down
9 changes: 6 additions & 3 deletions web/services/state/State.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,14 @@ export class StateRoute {
reconnects: 0,
inactivityRetry: cfg.inactivityRetry,
isOpen: false,
mockPort: cfg.mockPort || false
mock: cfg.mock || false
}
if (cfg.netConnect) sport.netConnect = { host: cfg.netHost, port: cfg.netPort }
else if (typeof cfg.type !== 'undefined' && cfg.type === 'screenlogic'){
sport.screenlogic = cfg.screenlogic;
}
if (cfg.netConnect) sport.network = { host: cfg.netHost, port: cfg.netPort };
else sport.settings = extend(true, { name: cfg.rs485Port }, cfg.portSettings);
if (typeof port !== 'undefined') {
if (typeof port !== 'undefined' && port.type !== 'screenlogic') {
let stats = port.stats;
sport.reconnects = port.reconnects;
sport.isOpen = port.isOpen;
Expand Down

0 comments on commit 80106f2

Please sign in to comment.