dieselrabbit / screenlogicpy

Interface for Pentair Screenlogic connected pool controllers over IP in Python
GNU General Public License v3.0
17 stars 5 forks source link

Collaboration #26

Open parnic opened 1 year ago

parnic commented 1 year ago

Hey @dieselrabbit, I just installed HomeAssistant today and found your lovely ScreenLogic adapter. I'm the maintainer of https://github.com/parnic/node-screenlogic for the node.js ecosystem, and figured we might be able to collaborate a bit on message formats and stuff. For example, I see your response 13 is labeled as "unknown" - we've determined that 13 is a login failure, 31 is an "unknown parameter" error code, etc. We've also got support for an "add client" message which allows one to subscribe to push notifications from the system when anything changes, allowing for a long-held connection (so long as you ping it every now and then, which is its own message) and immediate updates without polling.

I don't work in Python very often, but figured I'd at least reach out and see if you had any thoughts about this. I'm sure you have some stuff we haven't figured out yet as well!

dieselrabbit commented 1 year ago

Hi @parnic! I'm absolutely open to collaborating. The more messages we can evaluate across a broader set of system configurations, the better IMO.

TBH, your node-screenlogic project was one of the ones I studied when initially trying to wrap my head around this undertaking. A good amount of the message decoding beyond what's documented in the protocol document is possible because of your previous work, so thank you for that.

How would you like to proceed? Off the top of my head, maybe we could start by listing our own deficiencies and/or pointing out message decodings we're pretty confident in? Open to other approaches too.

parnic commented 1 year ago

Any way that I can help improve the hass integration would benefit myself and others, so I'd be happy to provide feedback on anything you've got questions about. I don't know much about how hass plugins work, but if there's a way to get AddClient working for a poll-based approach, that could be useful. My MagicMirror plugin, https://github.com/parnic/MMM-ScreenLogic, uses that and it's been awesome.

One example of a message that I've got partially decoded but am still stuck on is https://github.com/parnic/node-screenlogic/issues/26. I'm not sure if it's worth trying to decode the rest of it or if I should just publish documentation for what's there now. Otherwise, if you've figured out anything that I can add, I'd be happy to do that as well.

dieselrabbit commented 1 year ago

Thanks. Adding client subscription for push messages has been something i've been interested in and played around with a little bit. It will require a bit of rework/addition to screenlogicpy and the Home Assistant integration, but it should be doable. screenlogicpy already has the foundation to handle async messages from the pool controller so it shouldn't be a big rewrite. Making sure it all works with asyncio will be the wrinkle, but again it shouldn't be a problem.

My current roadmap is:

  1. Correct range for Spa chlorination percent. (Done in SLP, ready for HA work)
  2. Device class support in HA. (Done in SLP, ready for HA work)
  3. Freeze Mode binary_sensor in HA. (Done in SLP, ready for HA work)
  4. Support for controlling super chlorinate. (80% done in SLP) <-currently
  5. Support for user defined message sending and handling of async pool controller messages. (80% done in the async_listen branch)
  6. Support for client subscription and push messages. (20% done with work from 5.)

And at some point:

For 4. I'm currently trying to figure out where I can read if super chlorinate is active or not. I don't have a SCG so I'm unable to test. Integer bitmasks are fun.... If someone with an SCG were able to provide data dumps for the various possible states (scg off, scg on normally, scg super chlorinating) we might be able to decode the state and flags values in the SCG Configuration response.

EdDuran commented 1 year ago

I have implemented a full-stack HomeSeer Plugin in C# for ScreenLogic, which supports the Async Client as well.

Using the ScreenLogic WireShark dissector I wrote (It was must first WireShark dissector, please don't judge) I have found:

To Set the Super Chlor Timer:

CODE.SETSCG_QUERY,
     struct.pack("<IIIII", 0, pool_output, spa_output, 1, chlor_timer), # chlor_timer in hours, 0 to 24

To Not Set the Super Chlor Timer:

CODE.SETSCG_QUERY,
struct.pack("<IIIII", 0, pool_output, spa_output, 0, 0),

And to Decode Super Chlor Timer:

def decode_scg_config(buff: bytes, data: dict) -> None:
    scg = data.setdefault(DATA.KEY_SCG, {})

    present, offset = getSome("I", buff, 0)
    scg["scg_present"] = present

    status, offset = getSome("I", buff, offset)
    scg["scg_status"] = {"name": "SCG Status", "value": status}

    level1, offset = getSome("I", buff, offset)
    scg["scg_level1"] = {"name": "Pool SCG Level", "value": level1, "unit": "%"}

    level2, offset = getSome("I", buff, offset)
    scg["scg_level2"] = {"name": "Spa SCG Level", "value": level2, "unit": "%"}

    salt, offset = getSome("I", buff, offset)
    scg["scg_salt_ppm"] = {"name": "SCG Salt", "value": (salt * 50), "unit": "ppm"}

    flags, offset = getSome("I", buff, offset)
    scg["scg_flags"] = flags

    superChlorTimer, offset = getSome("I", buff, offset)
    scg["scg_super_chlor_timer"] = {
        "name": "SCG Super Chlorination Timer",
        "value": superChlorTimer,
    }

/keith

parnic commented 1 year ago

I have a salt cell if you need data from me as well.

dieselrabbit commented 1 year ago

@EdDuran Thanks. That's basically what I have in the dev branch of ..\requests\scg.py

I'm specifically looking to decode the scg_status bitmask and hopefully the scg_flags bitmask as well, but I don't think the flags are necessary to finishing out super chlorination control.

Outstanding questions for me to wrap up super chlorination control are:

@parnic Any actual comms data you (or anyone) could provide - even raw Wireshark hex dumps - for the states I listed above (scg off, scg on normally, scg super chlorinating) would be helpful.

It would also be helpful to have Wireshark dumps for simply changing the super chlorinate hours from 0 to 1 in the ScreenLogic app to know if the app is auto setting the super chlorinate value to 1 when hours are increased above 0.

dieselrabbit commented 1 year ago

@EdDuran Also, the EasyTouch documentation says that the valid range for super chlorinate hours is 0-72, not 0-24. IntelliTouch and ScreeLogic documentation doesn't seem to specify the max. Have you hit a 24hr limit in your testing?

parnic commented 1 year ago

I may need to bypass my IntelliChlor to get that - it's normally what controls the SCG and tells it what to do. Will see how difficult that is.

dieselrabbit commented 1 year ago

Hey @EdDuran, I'm interested in taking a look at your ScreenLogic WireShark dissector, but I'm not really comfortable with giving out my gmail to request access. Is there another way I can download it?

EdDuran commented 1 year ago

Clicking on the link in this thread above didn't just download the .lua file? Tell me what would work best for you. Can I add it to the screenlogicpy project?

dieselrabbit commented 1 year ago

It says I'm not authorized and wants me to request access via my Google account.

Would you be ok with simply attaching it to a comment here? Or if you feel like it could evolve with collaboration, you could create a new repository for it.

EdDuran commented 1 year ago

screenlogic.lua.zip

Unzip - open WireShark and go to Help->About->Personal Plugins .. this is where you need to copy the dissector to. Then restart WIreShark

dieselrabbit commented 1 year ago

screenlogic.lua.zip

Thanks. I must say, this is much more extensive than what I was even imagining would be helpful. Thank you for sharing! It's so far along. Seems like it would be really easy for people to contribute to it if you were to start up a repository for it. Completely up to you, of course.

It already helped me identify 8110 as a get date/time request and 8112 as set date/time.

EdDuran commented 1 year ago

Thanks - and I'm happy you found those functions. I started with WIreShark just to capture packets and looking at them with my eyes, and that got old fast. I found some simple examples online; the dissector grew out organically from there. I learned a lot and it was a fun puzzle. Yeah, good idea .. I'll create a repository for it.

While I'm here I want to say how impressed I am with your screenlogicpy project. For 5 years I'd been hoping something like this would come about, foolishly thinking Pentair would publish some decent docs ¯_(ツ)_/¯ It's a labor of love.

I had started a plugin for HomeSeer using screenlogicpy, but supporting different platforms (HS is built on windows .net and also runs on Linux via Mono) and ran into compatibility issue. I wanted to support the AddClient function for async change notification and decided to reimplement in 100% C#, which was not without its challenges. I found a C# implementation of python "struct" that only needed a few tweaks. It all came together pretty well in the end. And again, learned a lot along the way.

I had been playing around with HomeRemote - it has a steep learning curve but the results are pretty nice. I wrote a BlueIris and Volumio plugin for it. The HomeSeer backend is pretty good, though their "HSTouch" phone/table app framework" is just-ok. I was thinking of building out UI with HomeRemote and layer on top of HomeSeer. I need to dig into HomeAssistant.

Oh yeah .. one Thanksgiving we had 7 diesel rabbits in the driveway - started with my grandparents and seemed everyone in my family got one after that. I had two; '80 and '83 .. fun cars.

/keith

dieselrabbit commented 1 year ago

v0.7.0 adds support for 'add client' messages, ping keep-alive of the connection, and more. This crosses off # 5 and # 6 on the previous list.

dieselrabbit commented 1 year ago

Opened a separate issue for Super chlorinate conversation here: #37

dieselrabbit commented 1 year ago

FYI, I found myself wanting to know if any of the currently unknown or questionable data points changed in concert with other known state changes, so I created a custom integration for Home Assistant that exposes unknown and in-question data points as sensors so changes can be tracked over time. If anyone is interested it's available here: https://github.com/dieselrabbit/screenlogic-debug