Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration with nodejs-poolController #61

Closed
tagyoureit opened this issue Nov 3, 2022 · 54 comments
Closed

Integration with nodejs-poolController #61

tagyoureit opened this issue Nov 3, 2022 · 54 comments

Comments

@tagyoureit
Copy link
Contributor

Hey @parnic! This is long overdue, but I'm finally at a place where I can integrate direct Screenlogic control into nodejs-poolController. I've been wanting to dig into this for quite a while.

To that end, I've gone through and converted all of your code to Typescript + Promises. It still supports the events, too. I've published this up to my repo at https://github.com/tagyoureit/node-screenlogic/tree/typescript. I've changed quite a bit (event names, data structure, return values, etc etc). I can keep this as a separate repo if that makes more sense. I haven't updated the docs yet but the example.ts shows how to use all of the methods.

First question is whether or not you are ok with moving to Typescript + Promises or you would rather keep the plain 'ole Javascript.

Second question is do you have any bandwidth to flush out more of the commands?

I'll also be able to help debugging/decoding many of the other aspects as I've got in-depth knowledge of how the RS485 packets work.

I've got a short list of items that I've compiled so far, but haven't gone through everything to validate it yet. Need to put it through a fine tooth comb.

  1. Equipment config - I see you have a separate thread on this... will try to dig into what I can find.
  2. Do you know how often a ping needs to be sent to keep a connection to the server?
  3. What's the difference between the clientId and senderId?
  4. I'm getting bad parameters trying to run the following: set circuit state, set circuit run time, delete schedule by id, set schedule
  5. 12504 is async message that the intellibrite is changing colors (~16s)
  6. I have not yet tested the local connection; I'm currently working remotely and also need to replace a fried chip on my transceiver
@parnic
Copy link
Owner

parnic commented Nov 3, 2022

Hey, thanks for opening this issue!

Generally-speaking, I'm on board with a TypeScript conversion. I got a wild hair and tried to teach myself TypeScript a while back, but Real Life™ got in the way and I kinda stopped working on it: https://github.com/parnic/node-screenlogic/tree/dev/typescript

I'd love to integrate this and tag a v2 so long as it keeps working with the primary audience, which is my MagicMirror plugin (which I am happy to make changes to) https://github.com/parnic/MMM-ScreenLogic, the Homebridge integration (which maybe isn't alive anymore?) https://github.com/schemers/homebridge-screenlogic, and the web interface https://github.com/mikemucc/screenlogic-api

I definitely can help work out more commands if there's stuff to be added, especially if you/others are in it with me. :)

Do you know how often a ping needs to be sent to keep a connection to the server?

My MagicMirror plugin sends a ping every minute currently, which works. I remember trying a few different values and 5mins was definitely too long, but a 1-minute ping has been working for probably 6mo now, so that was good enough for me.

What's the difference between the clientId and senderId?

The senderId is an arbitrary number which comes back in the response to any given command to allow you to track multiple requests in flight simultaneously. The clientId is an arbitrary number that allows you to unregister/remove an added client later. So: sender id is for the current message only, client id is for the lifetime of a client session.

I'm getting bad parameters trying to run the following: set circuit state, set circuit run time, delete schedule by id, set schedule

Interesting, if you've got a repro I could help look into it. I use Set Circuit State quite a bit.

12504 is async message that the intellibrite is changing colors (~16s)

👍

@tagyoureit
Copy link
Contributor Author

I got the bad parameters working. I forget that I normalized the indexes to start at 1 (circuitId - 499; schedId - 699). Just had to add them back. That's what I get for working on this late at night.

I'm going through the equipment configuration and already finding a few items to clean up/add.

@tagyoureit
Copy link
Contributor Author

Making a bunch of progress... this is all coming directly from ScreenLogic. This system only has basic circuits, but I already have done the chemistry, chlorinator, equipment/controller config, time... Still need to do the pumps, finish the schedules, and then have njsPC send the commands out to SL.

image

@tagyoureit
Copy link
Contributor Author

Happy Thanksgiving! It's time to test. 😄

I'm still working on a dev branch, so please follow these directions:
nodejs-Poolcontroller

  1. Pull with git clone -b 8.0.0 https://github.com/tagyoureit/nodejs-poolController.git
  2. change dir to nodejs-poolController
  3. run npm i
  4. start app with npm start

dashPanel (in a new terminal window)

  1. Pull with git clone -b 8.0.0 https://github.com/rstrouse/nodejs-poolController-dashPanel.git
  2. change dir to nodejs-poolController-dashPanel
  3. run npm i
  4. start app with npm start

You can us PM2 if you want to monitor/restart the services automatically and keep them running in the background. There are still times when the underlying socket goes down and it is tricky to catch but PM2 will restart the app if it fails.

One you have the apps running, open a browser to http://localhost:5150. It should look like the following:
2022-11-24_12-05-22

Nixie is the name of our standalone controller. But we want to connect with Screenlogic so go to the config (gears) -> Controller tab -> Screenlogic. Click enabled and enter your SL address (it should get picked up after 10s and this wait time can definitely be reduced). If your unit is local and is found you can click the button to copy the address to the system name field.
2022-11-24_12-05-46

The app should load all of the system, controller, circuit, intellichlor, schedule, intellichem, pump, etc information...
2022-11-24_12-12-33

Nearly everything should be enabled. This includes turning circuits on/off, changing circuit configurations, intellibrite, etc.
The only thing I need to go through and check (that I know of) are setting the pump circuits. Everything else that can be done via Screenlogic should be able to be don through the app.

Of course there are likely to be some bugs, so please keep that in mind as you test. But that's also why I'm asking for your testing - to fix any bugs you might find.

cheers!

@parnic
Copy link
Owner

parnic commented Nov 25, 2022

I'm able to load up the app and find the device through the config page, but every time I try to save, I get:

Error: Login Failed
    at UnitConnection. (/Users/chris/dev/nodejs-poolController/node_modules/node-screenlogic/index.ts:450:16)
    at Object.onceWrapper (node:events:627:28)
    at UnitConnection.emit (node:events:513:28)
    at UnitConnection.onClientMessage (/Users/chris/dev/nodejs-poolController/node_modules/node-screenlogic/index.ts:570:14)
    at UnitConnection.processData (/Users/chris/dev/nodejs-poolController/node_modules/node-screenlogic/index.ts:346:14)

I do get an appropriate host found Local Screenlogic: Pentair: xx-xx-xx found at 10.0.0.148:80

image

@tagyoureit
Copy link
Contributor Author

tagyoureit commented Nov 25, 2022

I'm assuming you have no password, correct? If you do not have one, it doesn't matter.

Can you also try a remote connection with the same system name (for now)? It should be able to login, but just go through the gateway instead of local.

I'm traveling through the weekend so will look at this again when I get back but I was able to log in to my local system so will need to see what it thinks is happening.

@parnic
Copy link
Owner

parnic commented Nov 25, 2022

Full stack:

Error: Login Failed
    at UnitConnection. (/Users/chris/dev/nodejs-poolController/node_modules/node-screenlogic/index.ts:450:16)
    at Object.onceWrapper (node:events:627:28)
    at UnitConnection.emit (node:events:513:28)
    at UnitConnection.onClientMessage (/Users/chris/dev/nodejs-poolController/node_modules/node-screenlogic/index.ts:570:14)
    at UnitConnection.processData (/Users/chris/dev/nodejs-poolController/node_modules/node-screenlogic/index.ts:346:14)
    at Socket. (/Users/chris/dev/nodejs-poolController/node_modules/node-screenlogic/index.ts:250:12)
    at Socket.emit (node:events:513:28)
    at addChunk (node:internal/streams/readable:324:12)
    at readableAddChunk (node:internal/streams/readable:297:9)
    at Socket.Readable.push (node:internal/streams/readable:234:10)
    at TCP.onStreamRead (node:internal/stream_base_commons:190:23)

My system does have a password (edit: but a local login doesn't need a password, only remote gateway logins do). Remote login, through Nixie, also fails:

Error: Login Failed
    at UnitConnection. (/Users/chris/dev/nodejs-poolController/node_modules/node-screenlogic/index.ts:450:16)
    at Object.onceWrapper (node:events:627:28)
    at UnitConnection.emit (node:events:513:28)
    at UnitConnection.onClientMessage (/Users/chris/dev/nodejs-poolController/node_modules/node-screenlogic/index.ts:570:14)
    at UnitConnection.processData (/Users/chris/dev/nodejs-poolController/node_modules/node-screenlogic/index.ts:346:14)
    at Socket. (/Users/chris/dev/nodejs-poolController/node_modules/node-screenlogic/index.ts:250:12)
    at Socket.emit (node:events:513:28)
    at addChunk (node:internal/streams/readable:324:12)
    at readableAddChunk (node:internal/streams/readable:297:9)
    at Socket.Readable.push (node:internal/streams/readable:234:10)
    at TCP.onStreamRead (node:internal/stream_base_commons:190:23)

I can connect with local or remote login through node-screenlogic's example script.

@tagyoureit
Copy link
Contributor Author

Can you please attach the console output? I will clean these up and add them to the official logs but haven't gotten that far. (Your system name will be logged in there so remove that first.)

And just for kicks, what version of Node are you running?

@parnic
Copy link
Owner

parnic commented Nov 25, 2022

dashPanel:

> npm start

> [email protected] start
> npm run build && node dist/app.js


> [email protected] build
> tsc

Updated configuration file
info: Server is now listening on 0.0.0.0:5150
127.0.0.1 GET /config/serviceUri?null
127.0.0.1 GET /
127.0.0.1 GET /config/serviceUri?null
127.0.0.1 GET /config/serviceUri?null

poolControllers:

> npm start

> [email protected] start
> npm run build && node dist/app.js


> [email protected] build
> tsc

Init state for Pool Controller
[11/25/2022, 2:33:13 PM] info: The current git branch output is 8.0.0
[11/25/2022, 2:33:13 PM] info: The current git commit output is 8dadb0183d642466155b4bc056d57190c5628eb4
[11/25/2022, 2:33:13 PM] info: Starting up SSDP server
[11/25/2022, 2:33:13 PM] info: Server is now listening on 0.0.0.0:4200
[11/25/2022, 2:33:13 PM] error: Error opening port 0: Error: No such file or directory, cannot open /dev/ttyUSB0. Retry in 10 seconds
[11/25/2022, 2:33:13 PM] info: Checking njsPC versions...
[11/25/2022, 2:33:13 PM] info: Starting Pool System nixie
[11/25/2022, 2:33:13 PM] info: Initializing Nixie Control Panel for Nixie Single Body
[11/25/2022, 2:33:13 PM] info: Initializing Intake/Return valves
[11/25/2022, 2:33:13 PM] info: Initializing Nixie Controller
[11/25/2022, 2:33:13 PM] info: Initializing Nixie body Pool
[11/25/2022, 2:33:13 PM] info: Initializing Filter Filter
[11/25/2022, 2:33:13 PM] info: Auto-backup initialized Last Backup: 1969-12-31T18:00:00.000-0600
[11/25/2022, 2:33:13 PM] info: Initializing Nixie circuit Pool
[11/25/2022, 2:33:13 PM] info: Nixie Controller Initialized
[11/25/2022, 2:33:13 PM] info: Nixie Single Body control board initialized
[11/25/2022, 2:33:13 PM] info: Screenlogic: Unit Pentair: xx-xx-xx found at 23.253.89.11:9934
[11/25/2022, 2:33:14 PM] error: Screenlogic error: Login Failed
[11/25/2022, 2:33:17 PM] info: New socket client connected 5ObHfHhOUoN-aPMjAAAB -- 127.0.0.1
[11/25/2022, 2:33:17 PM] info: [2:33:17 PM] 127.0.0.1 GET /state/all?null {}
sendRS485PortStats set to false
[11/25/2022, 2:33:21 PM] info: [2:33:21 PM] 127.0.0.1 GET /state/all?null {}
[11/25/2022, 2:33:21 PM] info: New socket client connected r57fbLWsGHJ__4nfAAAD -- 127.0.0.1
[11/25/2022, 2:33:21 PM] info: [2:33:21 PM] 127.0.0.1 GET /state/all?null {}
[11/25/2022, 2:33:23 PM] info: [2:33:23 PM] 127.0.0.1 GET /config/all?null {}
[11/25/2022, 2:33:23 PM] info: [2:33:23 PM] 127.0.0.1 GET /config/options/general?null {}
[11/25/2022, 2:33:23 PM] warn: Inactivity timeout for 0 serial port /dev/ttyUSB0 after 10 seconds
[11/25/2022, 2:33:23 PM] error: Error opening port 0: Error: No such file or directory, cannot open /dev/ttyUSB0. Retry in 10 seconds
[11/25/2022, 2:33:24 PM] info: [2:33:24 PM] 127.0.0.1 GET /app/options/interfaces?null {}
[11/25/2022, 2:33:25 PM] info: [2:33:25 PM] 127.0.0.1 GET /config/options/screenlogic?null {}
sendScreenlogicStats set to true
[11/25/2022, 2:33:29 PM] info: [2:33:29 PM] 127.0.0.1 PUT /app/screenlogic {"enabled":true,"type":"local","systemName":"Pentair: xx-xx-xx","password":1234[redacted],"status":"","readyState":"","connecting":"","destroyed":"","bytesReceived":null,"bytesSent":null}
[11/25/2022, 2:33:29 PM] info: Screenlogic: Unit Pentair: xx-xx-xx found at 23.253.89.11:9934
[11/25/2022, 2:33:30 PM] error: Screenlogic error: Login Failed
[11/25/2022, 2:33:30 PM] error: Login Failed
[11/25/2022, 2:33:33 PM] warn: Inactivity timeout for 0 serial port /dev/ttyUSB0 after 10 seconds
[11/25/2022, 2:33:33 PM] error: Error opening port 0: Error: No such file or directory, cannot open /dev/ttyUSB0. Retry in 10 seconds
^CShutting down open processes
[11/25/2022, 2:33:33 PM] info: Shut down sys (config) object timers
Stopping sys
[11/25/2022, 2:33:33 PM] info: Closing filter Filter 1
[11/25/2022, 2:33:33 PM] info: State process shut down
[11/25/2022, 2:33:33 PM] info: Closed all serial communications connection.
[11/25/2022, 2:33:33 PM] info: Shut down MDNS Server mdns
[11/25/2022, 2:33:33 PM] info: Stopped SSDP server: ssdp
[11/25/2022, 2:33:34 PM] error: Cannot read properties of undefined (reading 'name')
[11/25/2022, 2:33:34 PM] error: Cannot read properties of undefined (reading 'name')
[11/25/2022, 2:33:35 PM] info: Stopping logger Process.
Logger Process Stopped
> node --version
v18.12.1

@parnic
Copy link
Owner

parnic commented Nov 25, 2022

Seems like maybe it's only attempting a remote login through the pentair gateway and isn't able to connect directly to the discovered local IP?

@tagyoureit
Copy link
Contributor Author

Errr, strange. Can you try running with DEBUG=sl* npm start? Your original debug statements should come through. It's not clear from the logs why it's failing esp. when it can connect with the sample code. I'm able to connect remotely here (will test local connection next week). Pls paste the output here? (I don't need the dashPanel output, just njsPC.)

This is what I'm seeting:

Successful output

[11/25/2022, 6:41:00 PM] info: The current git branch output is 8.0.0
[11/25/2022, 6:41:00 PM] info: The current git commit output is 8dadb0183d642466155b4bc056d57190c5628eb4
[11/25/2022, 6:41:00 PM] warn: HTTPS not enabled because key or crt file is missing.
[11/25/2022, 6:41:00 PM] info: Server is now listening on 0.0.0.0:4200
[11/25/2022, 6:41:00 PM] info: Serial port: MOCK_PORT request to open successful 9600b 8-none-1
[11/25/2022, 6:41:00 PM] info: Checking njsPC versions...
[11/25/2022, 6:41:00 PM] info: Starting Pool System easytouch
[11/25/2022, 6:41:00 PM] info: Auto-backup initialized Last Backup: 2022-10-03T15:17:32.073-0400
sl:remote connecting to dispatcher... +0ms
sl:remote connected to dispatcher +162ms
sl:remote received message of length 45 and messageId 18004 +59ms
sl:remote it's a gateway response +0ms
sl:remote Gateway request to close. +1ms
sl:remote Gateway request to close. +1ms
sl:remote Gateway closed +1ms
sl:remote Gateway closed +0ms
[11/25/2022, 6:41:00 PM] info: Screenlogic: Unit Pentair: xx-xx-xx found at xxx.xxx.xxx.xxx:xxxxx
sl:unit connecting... +0ms
sl:remote Gateway server connection closed (close emit) +50ms
sl:unit connected, sending init message... +49ms
sl:unit sending challenge message... +0ms
sl:unit received message of length 32 +329ms
sl:unit it's a challenge response +0ms
sl:unit challenge string emit +0ms
sl:unit sending login message... +0ms
sl:unit received message of length 24 +74ms
sl:unit it's a login response +0ms
sl:unit received loggedIn event +1ms
sl:unit [NaN] sending version query... +0ms
sl:unit received message of length 64 +64ms
sl:unit it's version +0ms
sl:unit received version event +0ms
[11/25/2022, 6:41:01 PM] info: Screenlogic: connect to Pentair: xx-xx-xx POOL: 5.2 Build 738.0 Rel at xxx.xxx.xxx.xxx:xxxxx
sl:unit [NaN] sending add client command, clientId 79294... +1ms
sl:unit received message of length 8 +61ms
sl:unit it's an add client ack +0ms
sl:unit received addClient event +1ms
Add client result: true
sl:unit [NaN] sending equipment configuration query... +1ms
sl:unit received message of length 728 +85ms
sl:unit it's equipment configuration +1ms
unused valve, loadCenterIndex = 0 valveIndex = 0
sl:unit received equipmentConfiguration event +1ms

You can also go into the Controller->RS485 tab and disable the port so it doesn't try to open that. It will just continue to flood the logs with error messages.

@rstrouse
Copy link

@tagyoureit are you running node 18. If you are then the socket libs may need updating. I messed around with node 16 and was disappointed that they changed the underlying bindings for socket io. I assume you are connecting with raw sockets. Try installing node 14 to see if it sends an empty auth header correctly.

@parnic on the rs485 tab uncheck enabled for the primary port.

@parnic
Copy link
Owner

parnic commented Nov 26, 2022

Yeah, it's connecting to the dispatcher even when set to local.

[11/25/2022, 6:01:06 PM] info: [6:01:06 PM] 127.0.0.1 GET /config/options/screenlogic?null {}
  sl:find Screenlogic finder searching for local units... +0ms
  sl:find Looking for ScreenLogic hosts... +2ms
  sl:find found something +7ms
  sl:find   type: 2, host: 10.0.0.148:80, identified as Pentair: xx-xx-xx +0ms
  sl:find Screenlogic found unit {"address":"10.0.0.148","type":2,"port":80,"gatewayType":2,"gatewaySubtype":12,"gatewayName":"Pentair: xx-xx-xx"} +0ms
sendScreenlogicStats set to true
[11/25/2022, 6:01:06 PM] warn: Inactivity timeout for 0 serial port /dev/ttyUSB0 after 10 seconds
[11/25/2022, 6:01:06 PM] error: Error opening port 0: Error: No such file or directory, cannot open /dev/ttyUSB0. Retry in 10 seconds
[11/25/2022, 6:01:09 PM] info: [6:01:09 PM] 127.0.0.1 PUT /app/screenlogic {"enabled":true,"type":"local","systemName":"Pentair: xx-xx-xx,"password":1234,"status":"","readyState":"","connecting":"","destroyed":"","bytesReceived":null,"bytesSent":null}
  sl:remote connecting to dispatcher... +43s
  sl:remote connected to dispatcher +12ms
  sl:remote received message of length 41 and messageId 18004 +18ms
  sl:remote   it's a gateway response +0ms
  sl:remote Gateway request to close. +1ms
  sl:remote Gateway request to close. +0ms
  sl:remote Gateway closed +0ms
  sl:remote Gateway closed +0ms
[11/25/2022, 6:01:09 PM] info: Screenlogic: Unit Pentair: xx-xx-xx found at 23.253.89.11:9934
  sl:unit connecting... +42s
  sl:remote Gateway server connection closed (close emit) +8ms
  sl:unit connected, sending init message... +9ms
  sl:unit sending challenge message... +1ms
  sl:unit received message of length 32 +242ms
  sl:unit   it's a challenge response +0ms
  sl:unit    challenge string emit +0ms
  sl:unit sending login message... +0ms
  sl:unit received message of length 8 +33ms
  sl:unit   it's a login failure. +0ms
  sl:unit loginFailed +0ms
[11/25/2022, 6:01:09 PM] error: Screenlogic error: Login Failed
[11/25/2022, 6:01:09 PM] error: Login Failed

@parnic
Copy link
Owner

parnic commented Nov 26, 2022

@tagyoureit The problem is that your loginAsync() has this.password as a number type instead of a string. So when it passes the password in, it isn't able to encode properly. If I force the password in dist/index.js to new Encoder('1234') everything works. This is some logging I added to dist/index.js async loginAsync() to see what was up:

debugUnit(`pw: ${this.password} ${this.password.length} ${typeof(this.password)}`);
  sl:unit pw: 1234 undefined number +0ms

edit: well, in addition to using remote login even when set to Local. :)

Looks awesome when it's all connected and working, though! I see everything filled out correctly. Very cool!

@tagyoureit
Copy link
Contributor Author

Ah! Yes, thank you. The data is usually resolved from dashPanel to njsPC as a string but in this case it was happy to send a number. Nice catch. I updated both the node-screenlogic and njsPC to account for this.

You can run a git pull in the njsPC directory, but you will also need to re-pull the node-screenlogic module. The easiest way to do that is blow away the node_modules directory and re-run npm i.

@tagyoureit
Copy link
Contributor Author

@tagyoureit are you running node 18.

@rstrouse - I tried with both node 16 and 18. The node-screenlogic uses the underlying net.socket module. The only place we would see any change would be between dP<-->njsPC and I haven't noticed anything awry there, luckily.

@parnic
Copy link
Owner

parnic commented Nov 26, 2022

Looks good! 👍

@tagyoureit
Copy link
Contributor Author

Thoughts on where to publish the Typescript branch? Happy to post it under my account as a project or if you want to keep it under your account that would work, too.

Also, have you ever tried to snoop on the packets to set the pump speeds? Looks like it should be 12586 but don't know the right format. I imagine I could get wireshark up and running to snoop on the packets but wanted to ask first.

@parnic
Copy link
Owner

parnic commented Dec 4, 2022

I'd be happy to bring it into my main branch and declare a 2.0. I'm pretty unfamiliar with it, though, so if there's a packaging/distribution process, that would probably be good to know.

I already have support for message 12586. In the current main branch, it's called SLSetPumpFlow.

@tagyoureit
Copy link
Contributor Author

There are quite a few changes, as you saw. First, I need to start working on the updated readme. But it should work standalone and also as a module (like I'm using it). For anyone else that is using your original code, there will be breaking changes to get it to work with the 2.0 version.

Let me check out the SLSetPumpFlow further. I was having some issues and will let you know.

@tagyoureit
Copy link
Contributor Author

I updated a bunch of the docs. When you are ready to pull, you should probably save the current master as a separate branch so folks that may not want to update can reference.

@tagyoureit
Copy link
Contributor Author

I could also not get the SLSetPumpFlow to work. If you get a chance to help me look into, that would be appreciated.

@parnic
Copy link
Owner

parnic commented Dec 13, 2022

Sorry it took me a while to get back to this. If I run the following, it appropriately sets my first pump's first circuit's flow rate to 2010 RPMs:

const ScreenLogic = require('./index');

connect(new ScreenLogic.UnitConnection(80, '10.0.0.148'));

function connect(client) {
  client.on('loggedIn', function() {
    this.setPumpFlow(0, 0, 2010, true);
  }).on('setPumpFlow', function() {
    client.close();
  });

  client.connect();
}

Changing the second 0 in setPumpFlow to a 1 sets the flow rate for my spa, and changing the first 0 to a 1 sets circuits on my second pump appropriately. I can see it changing in the Pentair ScreenLogic desktop app (for PC) after running the script.

Maybe different kinds of pumps behave differently? Or it's a GPMs vs RPMs thing?

Attached my Wireshark capture. This is the ScreenLogic desktop app setting pump 0 circuit 0 to 2010 RPMs. My machine is 10.0.0.3 and the pool equipment is 10.0.0.148.
SetPumpFlow.zip

@parnic
Copy link
Owner

parnic commented Dec 13, 2022

Also if you want to go ahead and open a PR for your Typescript conversion, I can start working on getting a v1 branched and that pulled in as a v2.

@ivanvach
Copy link

@tagyoureit

I just jumped on the beta bandwagon. Good news is that it does find my Screenlogic adapter (one of them, as I have two but later on the subject of two Screenlogics) I do not have a password and I am getting an error as well.
HomeScreen of the dash panel is generic (none of my devices/settings), which is normal provided that the connection failed with the Error below.

Error: Login Failed
at UnitConnection. (/home/ivan/nodejs-poolController/node_modules/node-screenlogic/index.ts:484:16)
at Object.onceWrapper (node:events:627:28)
at UnitConnection.emit (node:events:513:28)
at UnitConnection.onClientMessage (/home/ivan/nodejs-poolController/node_modules/node-screenlogic/index.ts:604:14)
at UnitConnection.processData (/home/ivan/nodejs-poolController/node_modules/node-screenlogic/index.ts:342:14)
at Socket. (/home/ivan/nodejs-poolController/node_modules/node-screenlogic/index.ts:405:16)
at Socket.emit (node:events:513:28)
at addChunk (node:internal/streams/readable:324:12)
at readableAddChunk (node:internal/streams/readable:297:9)
at Socket.Readable.push (node:internal/streams/readable:234:10)
at TCP.onStreamRead (node:internal/stream_base_commons:190:23)

@ivanvach
Copy link

It is working now !!! I did setup a password and that was it.

Screenshot (517)

@ivanvach
Copy link

@tagyoureit

Thanks for the great idea and brilliant implementation and thanks to @parnic for making it possible.

Here is some feedback.

My particular system shown above has 2 Pentair Controllers in master-slave configuration. The reason for two controllers is that the system manages two bodies of water that are at 200 ft distance. So we installed one controller per site, not that we have that many pumps or devices to manage. The two controllers do not matter for the purpose of Screenlogic (SL). SL does see larger number of devices and features most of which are unused. The whole system has 5 pumps. 3 are hooked to the master controller and 2 are hooked to the slave. However, two of the 3 pumps that are hooked to the master are controlled by on/off relays (circuits) As a result Screenlogic sees 3 pumps total - Pool pump plus the 2 pumps hooked to the slave.

Problems.

  1. I have only 4 features set in Screenlogic. The actual features correspond to features 2, 7, 6 and 5 above. For some reason the screen above shows 7 features instead of 4.
  2. I have two lights that show as "lights" in Screenlogic. Names are "Spa Light" and "FWF light", Here one shows as "Spa Light" but not as part of the lights group and the other shows as "Feature 4".
  3. What is listed as "Feature 1" above is actually a circuit called "SPA Jets". It is on/off circuit that turns on the SPA Jets.
  4. There is no such thing as AUX EXTRA in Screenlogig settings, yet it shows at the screen above.
  5. What is listed as AUX EXTRA above is another circuit called "SPA WF Xtr.". This is another on/off circuit that controls another pump.
  6. What is listed as "Feature 6" above is another circuit called "FWF Med"
  7. The screen above shows two pumps only whereas Screenlogic does see 3 pumps. The pool pump is missing.

None of the above problems is a game changer for me. Those are minor mostly naming and grouping issues

Questions.

  1. How do I turn on/off circuits and features shown on the screen above by MQTT directly?
  2. How do I setup a second Screenlogic adapter in the system?

Thanks,
Ivan

@ivanvach
Copy link

@tagyoureit

I have serious problem. The poolController stops with this error after only 3-4 minutes of working

Error: read ECONNRESET
at TCP.onStreamRead (node:internal/stream_base_commons:217:20)

@tagyoureit
Copy link
Contributor Author

My particular system shown above has 2 Pentair Controllers in master-slave configuration

Can you tell me more about this? I wonder if some of the missing circuits are due to your configuration. I've never heard of Intellitouch in master/slave mode and there isn't anything in the manuals about this. How are they "connected"?

  1. I have only 4 features set in Screenlogic. The actual features correspond to features 2, 7, 6 and 5 above. For some reason the screen above shows 7 features instead of 4.

You can go into the config (gears in upper right) and go to circuits and hide any circuits that you don't want to see. There is not a 1:1 correlation between how SL shows the circuits and how we show them.

How do I turn on/off circuits and features shown on the screen above by MQTT directly?

https://github.com/tagyoureit/nodejs-poolController/wiki/Bindings-Integrations#mqtt

How do I setup a second Screenlogic adapter in the system?

You can't. This app is designed to control a single pool system. You would need to setup two separate njsPC installations to control each ScreenLogic. But again, I'm not clear on your configuration and how the 2 systems interact and whether you are controlling both systems from one SL or you use both. Can you send some screenshots?

I also need to add logging to the ScreenLogic system. We log everything with RS-485 which allows us to find issues quickly. I'll work on adding this and then will ask you for a replay.

I had some issues with the ECONNRESET previously, but some recent changes I made are supposed to capture that. Can you make sure that you have the most recent code? Run the following in the njsPC directory:

  1. git pull
  2. npm rm node-screenlogic
  3. npm i tagyoureit/node-screenlogic#typescript
  4. Restart the app

@ivanvach
Copy link

@tagyoureit

Thanks for the prompt response.
Understood.

My major major major problem now is that the controller doesn’t last more than 2-3 minutes. I can’t do anything. As far as I downloaded it 2 days ago I think that I’m on the latest version but will do the upgrade procedure later today anyhow.

I will also provide screenshots of my SL later today.

I’ll appreciate it greatly if you look into the error that stops the controller after 2-3 minutes of working.

Thanks,

Ivan

@ivanvach
Copy link

@tagyoureit

Attached below are screenshots of ScreenLogic setup menu showing how dual controller system looks in ScreenLogic. Nothing fancy. As you can see it shows two "main" load centers. To your credit your software managed to recognize all circuits from both load centers.
As far as connection between them goes they are connected by the 4 wire connection (same that is used for everything else). Two conductors are for power and the other two RS485.
Screenshot (521)
Screenshot (522)
Screenshot (523)

@ivanvach
Copy link

ivanvach commented Dec 17, 2022

@tagyoureit

P.S. Followed your advise to update. I got a message "Already up to date" when running "git pull" so I assume that I have the latest version of the Controller.

@tagyoureit
Copy link
Contributor Author

tagyoureit commented Dec 17, 2022

Ah, now I got it... master/slave is different load centers, of course. You have no idea how rare it is that we see these. You are probably the second person. If you are able to do a replay capture with the rs-485 that would be amazing and I can check things out there. If you are also open to allowing me to remote into your system with ScreenLogic I can also see what's going on. I'd also be able to see with a replay from that, but again, I have to add that to the code.

@ivanvach
Copy link

@tagyoureit

Yes, you are more than welcome to connect to my computer by AnyDesk and poke around to see what is going on. Let me know when do you want to do it by e-mail to admin at zumungo dot com

@ivanvach
Copy link

... also you can connect to my ScreenLogic adapter remotely to see what's going on. Please let me know.

@tagyoureit
Copy link
Contributor Author

@ivanvach Pull the latest on njsPC (steps 1-4) and dashpanel (step 1 & 4 only).

  1. git pull
  2. npm rm node-screenlogic
  3. npm i tagyoureit/node-screenlogic#typescript
  4. Restart the app

@ivanvach
Copy link

git pull produced errors in both directories Controller and Dashpanel

Tried to correct by

git stash
git pull
git stash apply

not sure this is the right thing to do.

@ivanvach
Copy link

When I start them Both controller and dashpanel show version 7.7.0 ofter the upgrade. Is this right.

@ivanvach
Copy link

Good news is that it shows all 3 pumps now. Bad news I can't activate any circuit getting this error everywhere

TypeError: Cannot read properties of undefined (reading 'setCircuitStateAsync')
at SLCircuits.setCircuitStateAsync (/home/ivan/nodejs-poolController/controller/comms/ScreenLogic.ts:1080:33)
at ITTouchCircuitCommands.setCircuitStateAsync (/home/ivan/nodejs-poolController/controller/boards/EasyTouchBoard.ts:1531:31)
at /home/ivan/nodejs-poolController/web/services/state/State.ts:300:55
at Layer.handle [as handle_request] (/home/ivan/nodejs-poolController/node_modules/express/lib/router/layer.js:95:5)
at next (/home/ivan/nodejs-poolController/node_modules/express/lib/router/route.js:144:13)
at Route.dispatch (/home/ivan/nodejs-poolController/node_modules/express/lib/router/route.js:114:3)
at Layer.handle [as handle_request] (/home/ivan/nodejs-poolController/node_modules/express/lib/router/layer.js:95:5)
at /home/ivan/nodejs-poolController/node_modules/express/lib/router/index.js:284:15
at Function.process_params (/home/ivan/nodejs-poolController/node_modules/express/lib/router/index.js:346:12)
at next (/home/ivan/nodejs-poolController/node_modules/express/lib/router/index.js:280:10)
at /home/ivan/nodejs-poolController/web/Server.ts:719:25
at Layer.handle [as handle_request] (/home/ivan/nodejs-poolController/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/home/ivan/nodejs-poolController/node_modules/express/lib/router/index.js:328:13)
at /home/ivan/nodejs-poolController/node_modules/express/lib/router/index.js:286:9
at Function.process_params (/home/ivan/nodejs-poolController/node_modules/express/lib/router/index.js:346:12)
at next (/home/ivan/nodejs-poolController/node_modules/express/lib/router/index.js:280:10)

@ivanvach
Copy link

Also good news is that PoolController doesn't die after 2-3 min work as it used to.

@ivanvach
Copy link

Bad news "screenlogic" tab is missing and the dash shows "initializing" status forever.

@tagyoureit
Copy link
Contributor Author

Sorry - moved the ScreenLogic settings into the Controller->Comms tab.

@ivanvach
Copy link

Is this a fork of your main poolController software to connect to @parnic 's library or did you make your main one to go both ways RS485 and/or Screenlogic.

@tagyoureit
Copy link
Contributor Author

The njsPC app can now speak to both RS-485 and SL with @parnic's library. It is just the 8.0.0 branch now but once stabilized it will be pushed back to the main branch.

@parnic parnic mentioned this issue Dec 22, 2022
@tagyoureit
Copy link
Contributor Author

tagyoureit commented Dec 22, 2022

Sorry it took me a while to get back to this. If I run the following, it appropriately sets my first pump's first circuit's flow rate to 2010 RPMs:

const ScreenLogic = require('./index');

connect(new ScreenLogic.UnitConnection(80, '10.0.0.148'));

function connect(client) {
  client.on('loggedIn', function() {
    this.setPumpFlow(0, 0, 2010, true);
  }).on('setPumpFlow', function() {
    client.close();
  });

  client.connect();
}

Changing the second 0 in setPumpFlow to a 1 sets the flow rate for my spa, and changing the first 0 to a 1 sets circuits on my second pump appropriately. I can see it changing in the Pentair ScreenLogic desktop app (for PC) after running the script.

Maybe different kinds of pumps behave differently? Or it's a GPMs vs RPMs thing?

Attached my Wireshark capture. This is the ScreenLogic desktop app setting pump 0 circuit 0 to 2010 RPMs. My machine is 10.0.0.3 and the pool equipment is 10.0.0.148. SetPumpFlow.zip

I did get this one working, thanks!
EDIT: This is the right call for the typescript branch: let pumpRes = await client.pump.setPumpSpeedAsync(1, 1, 2000, true);. This would set the 2nd circuit in the array of the first pump to 2000rpm. I have all the ID's starting at 1 so SL would natively call this pump 0. On all the API's to get the status (and set the equipment) the same 1 based ID's are used. The index for the array of the pump speed is a bit whacky, but it is what it is.

FWIW, this API call works for this page:

image

I believe, when you get to the setup you need to send the full equipment configuration:

image

On a separate note, can you write up the instructions for doing a Wireshark capture (maybe in a wiki entry)? I try to do them but always get a bit tripped up and would really like to use this to decode some other config packets. That would be uber helpful!

@parnic
Copy link
Owner

parnic commented Dec 22, 2022

Yeah, I think those two screens you show are sending different message IDs, the "setup" page, I believe, is the undocumented Equipment Configuration message that #26 exists for.

I'm not sure if I'll have time to write up Wireshark instructions, but maybe. I kinda have to fumble my way through it every time I need to do it again as well, haha. It would largely be the same as any other Wireshark tutorial. Usually I use the decompiled Android app source as my go-to for understanding how messages work, but some, such as SetPumpFlow, aren't implemented in that app and require Wireshark to figure it out.

The APK can be grabbed at any app re-hosting site such as https://apkpure.com/screenlogic-connect/com.app.pentair (or https://apkpure.com/screenlogic-config/com.app.pentair_slconfig for the Config app) and then decompiled with a tool such as JADX or similar https://github.com/skylot/jadx

@tagyoureit
Copy link
Contributor Author

I'm definitely using both APK's and they are super helpful. Meanwhile...

Pool.Control.Dashboard.-.Google.Chrome.2022-12-22.12-41-15.mp4

(I'm only polling the pump speeds - unless I'm missing it I don't see an async method for this. This is where WireShark would be useful ;)...) The app reflects the new speed at the end of the video .

@parnic
Copy link
Owner

parnic commented Dec 22, 2022

No, I don't think I'm processing the async addClient() callback for adjusting pump speeds. I'm sure there's something for it. The library logs any unrecognized messages it gets, which might be a starting point.

@tagyoureit
Copy link
Contributor Author

I have "subscribed" via the addClient method. It sends over the equipment config (and a few others, I believe -- need to get a list), but I am manually polling the pumps for updates. I'm not seeing anything (besides 8300, which isn't related) that is being proactively sent.

@parnic
Copy link
Owner

parnic commented Jan 9, 2023

@tagyoureit were you ready to open a PR for the typescript conversion?

@tagyoureit
Copy link
Contributor Author

Hey, I'm real close. Curiosity got the best of me and I got proficient at using Wireshark to help decode some more packets. I couldn't just leave the configuration side alone so I've been adding a few more API's (get circuit name, set circuit names, and more). I've also decoded quite a bit more of the Equipment Configuration packet (12566) and the final part is setting the equipment configuration (12568) back to the controller

@parnic
Copy link
Owner

parnic commented Jan 9, 2023

Awesome, sounds super useful!

@tagyoureit
Copy link
Contributor Author

tagyoureit commented Jan 11, 2023

Can you give the latest code a try? Specifically the "set equipment" message. Pull both njsPC and the new node-screenlogic code with the method I outlined above (#61 (comment))

I have it set so it's not actually wired up to change anything on the OCP, yet. I just have a flag set because I don't want to mess anything up due to a lack of testing. (See below.)

If you startup the app with the DEBUG=sl* you will see the same types of debug code that you previously used.
The following are the items which can be set via ScreenLogic and the config packet. Some of them we don't really handle today in njsPC and I'll note that below:

  • High Speed Circuits for dual speed pumps
  • Valves (read values, but not wired in yet for writing)
  • Remotes (read values, no interface for changing these)
  • Heaters (should be fully working including units; except for Dual Body OCPs)
  • Misc (things like spa manual heat, intellichem installed, pump on during X activation...)
  • Circuit Groups aka macros (not wired in yet - need to explore with Intellitouch users)
  • Light groups aka Intellibrite (the set equip packet only has the all-on/all-off group members. position, color, delay are set through the set circuit packet)
  • Pumps (should be fully working including changing type, circuits, speed, and other attributes)
  • Spa Command (not wired in; we don't manage remotes today. In early ET firmware this is a 4-button controller only for dual-speed pumps but in later versions it was also a remote).

When you run the code you'll see the debug statements as below. It is indicating which bit in which array is changing.

sl:unit Difference at miscData[4]. prev: 0 (00000000)-> new: 1 (00000001) +0ms

If/when you want to try changing actual values, do the following:

  1. take screenshots of EVERY page/option/button/etc in screenlogic. I'm pretty sure I won't be arbitrarily changing anything but best to be safe. (No bits will be changed that are not affected.)
  2. if node-screenlogic/dist/index.js#1153 you can change the let ready=false; to be true; This will send the command to the screenlogic unit. (This file is the compiled version.)

lmk if you have any questions.

@parnic
Copy link
Owner

parnic commented Mar 4, 2023

I think we're all set here? Let me know if that's not the case.

@parnic parnic closed this as completed Mar 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants