michaelusner / esp32-pentair-controller

Control your Pentair pool equipment via RS485->ESP32->MQTT->Home Assistant
22 stars 7 forks source link

Sending commands doesn’t work #2

Open kgstorm opened 2 years ago

kgstorm commented 2 years ago

Awesome code! It was my first time using ESP-IDF, so that was a bit of a learning curve. But once I got the code compiled, the code read all of the states and sent them to home assistant through MQTT perfectly. However, when I send commands it seems that nothing happens. It looks like I have a Pentair EasyTouch part number 521241. Is that different than your model? Thanks again!

michaelusner commented 2 years ago

Hi, I'm currently out of town but will take a look when I get home. Likely Monday.

Some things that I've found when messages aren't being sent are a loose wire on the proto board, or an issue with the mqtt configuration.

I wired up an rgb led that blinks on send/receive for exactly that reason.

Another thing you can do is to watch the messages on the RS485 bus to see if commands get sent.

I can help troubleshoot more when I'm home.

Thanks, Mike

On Fri, Oct 29, 2021, 2:24 PM kgstorm @.***> wrote:

Awesome code! It was my first time using ESP-IDF, so that was a bit of a learning curve. But once I got the code compiled, the code read all of the states and sent them to home assistant through MQTT perfectly. However, when I send commands it seems that nothing happens. It looks like I have a Pentair EasyTouch part number 521241. Is that different than your model? Thanks again!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/michaelusner/esp32_pentair_controller/issues/2, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQ5DF6YPFD3J4VKAAPTLFTUJLYH5ANCNFSM5HAAHKZA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

michaelusner commented 2 years ago

Oh, I just remembered that there's a bug in the code too which can sometimes manifest as commands being sent but not applied. For example, if you send a command to the pump to power on, but is receives a message that the pump is off then you'll see HA toggle the state back to off shortly afterward.

Also, if you install something like mqttexplorer then you can watch commands and how they're processed. It's really helpful.

Thanks, Mike

On Fri, Oct 29, 2021, 2:24 PM kgstorm @.***> wrote:

Awesome code! It was my first time using ESP-IDF, so that was a bit of a learning curve. But once I got the code compiled, the code read all of the states and sent them to home assistant through MQTT perfectly. However, when I send commands it seems that nothing happens. It looks like I have a Pentair EasyTouch part number 521241. Is that different than your model? Thanks again!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/michaelusner/esp32_pentair_controller/issues/2, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQ5DF6YPFD3J4VKAAPTLFTUJLYH5ANCNFSM5HAAHKZA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

michaelusner commented 2 years ago

Last but not least, the way I found several command codes was to hook up to the RS485 bus with a similar USB RS485 to serial adapter. Then, as I pressed buttons on the remote, I could capture the messages and "try" to figure them out. That could help in your case if we have different models of pool controllers.

On Fri, Oct 29, 2021, 2:24 PM kgstorm @.***> wrote:

Awesome code! It was my first time using ESP-IDF, so that was a bit of a learning curve. But once I got the code compiled, the code read all of the states and sent them to home assistant through MQTT perfectly. However, when I send commands it seems that nothing happens. It looks like I have a Pentair EasyTouch part number 521241. Is that different than your model? Thanks again!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/michaelusner/esp32_pentair_controller/issues/2, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQ5DF6YPFD3J4VKAAPTLFTUJLYH5ANCNFSM5HAAHKZA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

kgstorm commented 2 years ago

Thanks for the help! I just bought a usb->rs485, so I’ll see if I can capture the codes. I was wondering how the code sends the rs485 command when it receives the mqtt message saying the pool switch is on/off. I’m far from fluent in … is this c++? I’ll keep digging. Thanks again! Kevin

On Sat, Oct 30, 2021 at 10:00 AM Michael Usner @.***> wrote:

Last but not least, the way I found several command codes was to hook up to the RS485 bus with a similar USB RS485 to serial adapter. Then, as I pressed buttons on the remote, I could capture the messages and "try" to figure them out. That could help in your case if we have different models of pool controllers.

On Fri, Oct 29, 2021, 2:24 PM kgstorm @.***> wrote:

Awesome code! It was my first time using ESP-IDF, so that was a bit of a learning curve. But once I got the code compiled, the code read all of the states and sent them to home assistant through MQTT perfectly. However, when I send commands it seems that nothing happens. It looks like I have a Pentair EasyTouch part number 521241. Is that different than your model? Thanks again!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/michaelusner/esp32_pentair_controller/issues/2, or unsubscribe < https://github.com/notifications/unsubscribe-auth/ABQ5DF6YPFD3J4VKAAPTLFTUJLYH5ANCNFSM5HAAHKZA

. Triage notifications on the go with GitHub Mobile for iOS < https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675

or Android < https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub .

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/michaelusner/esp32_pentair_controller/issues/2#issuecomment-955483364, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQZHKYCHVTCWMBZBEXEAOBDUJQQC3ANCNFSM5HAAHKZA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

michaelusner commented 2 years ago

Hi, sorry for the late reply.

When the MQTT message is received by the mqtt_event_handler_cb function, it decodes it and calls "sendCommand()". All this code is written in C using FreeRTOS.

Thanks, Mike

On Sat, Oct 30, 2021 at 11:35 PM kgstorm @.***> wrote:

Thanks for the help! I just bought a usb->rs485, so I’ll see if I can capture the codes. I was wondering how the code sends the rs485 command when it receives the mqtt message saying the pool switch is on/off. I’m far from fluent in … is this c++? I’ll keep digging. Thanks again! Kevin

On Sat, Oct 30, 2021 at 10:00 AM Michael Usner @.***> wrote:

Last but not least, the way I found several command codes was to hook up to the RS485 bus with a similar USB RS485 to serial adapter. Then, as I pressed buttons on the remote, I could capture the messages and "try" to figure them out. That could help in your case if we have different models of pool controllers.

On Fri, Oct 29, 2021, 2:24 PM kgstorm @.***> wrote:

Awesome code! It was my first time using ESP-IDF, so that was a bit of a learning curve. But once I got the code compiled, the code read all of the states and sent them to home assistant through MQTT perfectly. However, when I send commands it seems that nothing happens. It looks like I have a Pentair EasyTouch part number 521241. Is that different than your model? Thanks again!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/michaelusner/esp32_pentair_controller/issues/2, or unsubscribe <

https://github.com/notifications/unsubscribe-auth/ABQ5DF6YPFD3J4VKAAPTLFTUJLYH5ANCNFSM5HAAHKZA

. Triage notifications on the go with GitHub Mobile for iOS <

https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675

or Android <

https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub

.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub < https://github.com/michaelusner/esp32_pentair_controller/issues/2#issuecomment-955483364 , or unsubscribe < https://github.com/notifications/unsubscribe-auth/AQZHKYCHVTCWMBZBEXEAOBDUJQQC3ANCNFSM5HAAHKZA

. Triage notifications on the go with GitHub Mobile for iOS < https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675

or Android < https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub .

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/michaelusner/esp32_pentair_controller/issues/2#issuecomment-955635078, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQ5DFYGM4FTXGB6J7X6OSDUJTBQTANCNFSM5HAAHKZA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

kgstorm commented 2 years ago

No problem on the delay. Thanks again for the help!

I was looking around at some other codes, and noticed the tagyoureit GitHub site mentions that you should expect to see FFA5FF when you have it connected correctly. Looking at your ‘sendCommand’ function, it looks like you found that the send command always starts with “00FFA51F”

Did I read that correctly?

Thanks! Kevin

On Mon, Nov 1, 2021 at 1:31 PM Michael Usner @.***> wrote:

Hi, sorry for the late reply.

When the MQTT message is received by the mqtt_event_handler_cb function, it decodes it and calls "sendCommand()". All this code is written in C using FreeRTOS.

Thanks, Mike

On Sat, Oct 30, 2021 at 11:35 PM kgstorm @.***> wrote:

Thanks for the help! I just bought a usb->rs485, so I’ll see if I can capture the codes. I was wondering how the code sends the rs485 command when it receives the mqtt message saying the pool switch is on/off. I’m far from fluent in … is this c++? I’ll keep digging. Thanks again! Kevin

On Sat, Oct 30, 2021 at 10:00 AM Michael Usner @.***> wrote:

Last but not least, the way I found several command codes was to hook up to the RS485 bus with a similar USB RS485 to serial adapter. Then, as I pressed buttons on the remote, I could capture the messages and "try" to figure them out. That could help in your case if we have different models of pool controllers.

On Fri, Oct 29, 2021, 2:24 PM kgstorm @.***> wrote:

Awesome code! It was my first time using ESP-IDF, so that was a bit of a learning curve. But once I got the code compiled, the code read all of the states and sent them to home assistant through MQTT perfectly. However, when I send commands it seems that nothing happens. It looks like I have a Pentair EasyTouch part number 521241. Is that different than your model? Thanks again!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/michaelusner/esp32_pentair_controller/issues/2, or unsubscribe <

https://github.com/notifications/unsubscribe-auth/ABQ5DF6YPFD3J4VKAAPTLFTUJLYH5ANCNFSM5HAAHKZA

. Triage notifications on the go with GitHub Mobile for iOS <

https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675

or Android <

https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub

.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub <

https://github.com/michaelusner/esp32_pentair_controller/issues/2#issuecomment-955483364

, or unsubscribe <

https://github.com/notifications/unsubscribe-auth/AQZHKYCHVTCWMBZBEXEAOBDUJQQC3ANCNFSM5HAAHKZA

. Triage notifications on the go with GitHub Mobile for iOS <

https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675

or Android <

https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub

.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub < https://github.com/michaelusner/esp32_pentair_controller/issues/2#issuecomment-955635078 , or unsubscribe < https://github.com/notifications/unsubscribe-auth/ABQ5DFYGM4FTXGB6J7X6OSDUJTBQTANCNFSM5HAAHKZA

. Triage notifications on the go with GitHub Mobile for iOS < https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675

or Android < https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub .

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/michaelusner/esp32_pentair_controller/issues/2#issuecomment-956567625, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQZHKYGXMSCMHSQ5U5HS7XTUJ32J5ANCNFSM5HAAHKZA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

michaelusner commented 2 years ago

The 00FFA51F signifies the start of a command packet according to the spec. The leading 0x00 might not be strictly necessary but from all the command captures I made, it seemed like the correct pattern. Plus it aligned with a 32-bit value so I liked it.

I've attached the original packet spec document that I found online and used to gain an understanding of how traffic works on the 485 bus.

Thanks, Mike

Thanks, Mike

On Mon, Nov 1, 2021 at 10:47 PM kgstorm @.***> wrote:

No problem on the delay. Thanks again for the help!

I was looking around at some other codes, and noticed the tagyoureit GitHub site mentions that you should expect to see FFA5FF when you have it connected correctly. Looking at your ‘sendCommand’ function, it looks like you found that the send command always starts with “00FFA51F”

Did I read that correctly?

Thanks! Kevin

On Mon, Nov 1, 2021 at 1:31 PM Michael Usner @.***> wrote:

Hi, sorry for the late reply.

When the MQTT message is received by the mqtt_event_handler_cb function, it decodes it and calls "sendCommand()". All this code is written in C using FreeRTOS.

Thanks, Mike

On Sat, Oct 30, 2021 at 11:35 PM kgstorm @.***> wrote:

Thanks for the help! I just bought a usb->rs485, so I’ll see if I can capture the codes. I was wondering how the code sends the rs485 command when it receives the mqtt message saying the pool switch is on/off. I’m far from fluent in … is this c++? I’ll keep digging. Thanks again! Kevin

On Sat, Oct 30, 2021 at 10:00 AM Michael Usner @.***> wrote:

Last but not least, the way I found several command codes was to hook up to the RS485 bus with a similar USB RS485 to serial adapter. Then, as I pressed buttons on the remote, I could capture the messages and "try" to figure them out. That could help in your case if we have different models of pool controllers.

On Fri, Oct 29, 2021, 2:24 PM kgstorm @.***> wrote:

Awesome code! It was my first time using ESP-IDF, so that was a bit of a learning curve. But once I got the code compiled, the code read all of the states and sent them to home assistant through MQTT perfectly. However, when I send commands it seems that nothing happens. It looks like I have a Pentair EasyTouch part number 521241. Is that different than your model? Thanks again!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <https://github.com/michaelusner/esp32_pentair_controller/issues/2 , or unsubscribe <

https://github.com/notifications/unsubscribe-auth/ABQ5DF6YPFD3J4VKAAPTLFTUJLYH5ANCNFSM5HAAHKZA

. Triage notifications on the go with GitHub Mobile for iOS <

https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675

or Android <

https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub

.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub <

https://github.com/michaelusner/esp32_pentair_controller/issues/2#issuecomment-955483364

, or unsubscribe <

https://github.com/notifications/unsubscribe-auth/AQZHKYCHVTCWMBZBEXEAOBDUJQQC3ANCNFSM5HAAHKZA

. Triage notifications on the go with GitHub Mobile for iOS <

https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675

or Android <

https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub

.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub <

https://github.com/michaelusner/esp32_pentair_controller/issues/2#issuecomment-955635078

, or unsubscribe <

https://github.com/notifications/unsubscribe-auth/ABQ5DFYGM4FTXGB6J7X6OSDUJTBQTANCNFSM5HAAHKZA

. Triage notifications on the go with GitHub Mobile for iOS <

https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675

or Android <

https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub

.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub < https://github.com/michaelusner/esp32_pentair_controller/issues/2#issuecomment-956567625 , or unsubscribe < https://github.com/notifications/unsubscribe-auth/AQZHKYGXMSCMHSQ5U5HS7XTUJ32J5ANCNFSM5HAAHKZA

. Triage notifications on the go with GitHub Mobile for iOS < https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675

or Android < https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub .

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/michaelusner/esp32-pentair-controller/issues/2#issuecomment-957075958, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQ5DF3CUNTTTY6ZC6XNXD3UJ5NNDANCNFSM5HAAHKZA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

WHEN: September 2009 WHO: @.*** WHAT: Controlling an IntelliFlow VS pump sans Pentair controller.

WHY: I bought an IntelliFlow VS pump for my pool in 2007 and was surprised to learn that I had to get a Pentair Controller to use most of its advanced features. Granted, you can run it like a 'regular pump' by switching power ON/OFF and get the benefit of a variable speed pump that can regulate its flow, but you are stuck with a manual setting of the flow rate on the pump. Talking to Pentair, I was told out that the protocol on the RS485 bus is proprietary and therefore there is no documentation available to anybody. The most cost effective Pentair solution to this problem is the Pentair IntelliCom* controller, that will 'talk' to the pump in response to activation of one of 4 inputs if the pump is in the 'right' mode. It is still a $385 list solution with the only benefit being able to run 4 different 'Ext.Ctrl' programs on a VS or to select one of the 4 speeds of a 4x160. This is, at least in my book, not good enough to justify the investment, so I put this project on the shelf until I had some more time to deal with this shortcoming. Early 2009 research on the Internet surfaced that the hardware protocol is 9600N81 and that this bus is quite active once a Pentair controller is on it, which explained why one does not see any activity if one looks for data in a system with just 'the pump'. It turns out the pump is quite communicative once you know how to ask it for information. In addition to that it will take instructions on what to do! Called Pentair again, they had not changed their position on sharing the protocol, this time around I was told some mambo about safety ... so I decided to figure out what is so special about it, that they will not share this information.

HOW: I wrote a collection of small programs on a Linux system that put me into the position to monitor and log bus traffic on a life Pentair bus with a controller that is running the show. All one needs is a cheap RS485 adapter hooked up to a serial port of a computer. Friends chimed in and sent me lots of raw data from their systems for analysis.

HOWTO: This collection comes with a Makefile and all the sources. A 'make' does compile all programs in the current directory on a Linux 2.6.21.5 with make 3.81 and gcc 3.4.1. There are NO errors or warnings! (FYI: on my system 'vi' is setup with 'ts=8 sw=8') It helps to be fluent in 'C' and Linux to understand and modify the programs. Due to portability and demonstration purposes all programs are single threaded and use the 'select' system call to do multi point I/O and timeouts. An understanding of sockets helps, but is not really necessary. The important thing is that a SOCK_DGRAM socket in Linux never returns an incomplete packet on a read() call as long as the packets are small. This is not true for the interface, since it is byte oriented and does not do packages without a defined end of package indicator, which does not exist in this application.

APRS485 access point to RS485 network

NAME aprs485 - RS485 access point USAGE aprs485 [-] INFO All programs in this collection use the servives of this access point server to communicate with the RS485 half-duplex bus. The access point uses datagrams for communication. It provides the ability for multiple programs to share the physical RS485 bus. Programs connect to 'tabs' in the access point server. All 'tabs' receive data occurring on the bus and may send data to the bus.

<bus>   can be either a <tty> like '/dev/ttyS4' with a RS485 adapter or
    an IP address of a tunnel device port. A tunnel device could be
    the TCP port of a wireless communication endpoint.

options:

-d  Debug mode, aprs485 will not go into the background and print
    all activity of the access point with a timestamp.
    Hit <Escape> to terminate the program.

-p <#>  Use alternate portnumber <#> as server port (default is 10485).
    This comes in handy if you need to run two or more instances of
    'aprs485' on the same computer.

-l <dir> Creates log files in directory <dir>. The filenames used are
    constructed from the current date on the machine: 'YYMMDD.log'.
    Files are appended to and created if they don't exist. The log
    file records are ASCII, 1 record per line. They start with the
    date followed by a timestamp, a single character record type,
    a size field and the message. Most messages are a hexadecimal
    representation of data on the bus.

API 'aprs485.h' contains code to support 'easy' attachment to a tab.

define APRS485_API 1

#include "aprs485.h"
int main(int ac, char **av)
{
    int bd, n;
    char    msg[128];

    if ((bd = hub_at(0,0)) < 0) return -1;
    n = read(bd,msg,sizeof(msg)); /* would be a receive */
    if (0) write(bd,"hello",5); /* would be a send */
    hub_dt(bd);
    return 0;
}

The protocol

The protocol uses short binary packages for information exchange. The
packages have variable size. The minimum length is 8 bytes and the
theoretical maximum is 6+256+2=264 bytes. The largest I have seen on
a live Pentair bus is 37 bytes.
The format is:

<ldb> <sub> <dst> <src> <cfi> <len> [<data>] <ckh> <ckl>

10 <lpb> - leading packet byte, 0xa5
11 <sub> - ?
12 <dst> - destination address
13 <src> - source address
14 <cfi> - command/function/instruction
15 <len> - size of data field (may be 0!)
16 <data ...>
<ckh> - most significant byte of checksum
<ckl> - least significant byte of checksum

The checksum is a 16 bit unsigned sum of all bytes in the message up to
the checksum field.
Most packages are preceded by a preamble of 1 or more 0xff bytes and a
0x00 0xff sequence.

Every device on the bus has an address:
0x0f - is the broadcast address, it is used by the more sophisticated
       controllers as <dst> in their system status broadcasts most
       likely to keep queries for system status low.
0x1x - main controllers (IntelliComII, IntelliTouch, EasyTouch ...)
0x2x - remote controllers
0x6x - pumps, 0x60 is pump 1

Apart from unsolicited broadcasts, information exchange is done by
a device A sending a message to device B and device B sending an answer
to device A. Messages for simple exchanges only differ in the fact
that <dst> and <src> are swapped.
For example:
    C: A5 00 60 10 04 01 ff 02 19
    P: A5 00 10 60 04 01 ff 02 19
is a request from the controller to the pump to turn panel control off,
which enables it to send other commands to the pump. The pump confirms
the action in the answer.
The following sequence will turn panel control back on:
    C: A5 00 60 10 04 01 00 01 1A
    P: A5 00 10 60 04 01 00 01 1A

The interpretation of a <cfi> depends on the destination of a message,
meaning a <cfi> for one device might mean something else for another.

And there are exceptions to this protocol. The IntelliChlor C40 puts
messages on the bus that start with a 0x10 0x02 sequence, a data field,
a single byte checksum and a 0x10 0x03 trailer sequence... The checksum
is the unsigned sum over the data field + 18.

There are many <cfi>s I have seen in data dumps, the interpretation of
the datafield is somewhat cumbersome without knowing the system, so my
focus is more on messages to and from a pump.
However, here are some basics I found:
A <cfi> to a controller seems to work like this:
bits   <76543210>
    00xxxxxx - ?
    01xxxxxx - ?
    10xxxxxx - transfer(write) <cfi>&0x3f to controller
               controller acknowledges the write with <0x01><0x01><cfi>
    11xxxxxx - request <cfi>&0x3f from controller
               the controller broadcasts it in response

My pump is an IntelliFlow VS, it does follow instructions from an
IntelliComII controller, provided the external programs are setup and
enabled. It has to be in FILTER mode AND Started to make it go.
Unlike other controllers, which take over full control of the pump, the
IntelliComII grabs control only for a short interval of time, every 30
seconds, to communicate what external program to run. If all inputs are
off it does not even do that after it has had a respone from the pump.

The sequence for input 1 active is:

    C: A500 d=60 s=10 c=04 l=01 FF       <0219> SETCTRL remote
    P: A500 d=10 s=60 c=04 l=01 FF       <0219> CTRL is remote
*   C: A500 d=60 s=10 c=01 l=04 03210008 <0146> WRITE (0x0008) to 0x0321
    P: A500 d=10 s=60 c=01 l=02 0008     <0120> VALIS (0x0008)
    C: A500 d=60 s=10 c=04 l=01 00       <011A> SETCTRL local
    P: A500 d=10 s=60 c=04 l=01 00       <011A> CTRL is local

*       C: A500 d=60 s=10 c=01 l=04 03210000 <013E> is a stop
*   C: A500 d=60 s=10 c=01 l=04 03210010 <014E> is program 2
*   C: A500 d=60 s=10 c=01 l=04 03210018 <0156> is program 3
*   C: A500 d=60 s=10 c=01 l=04 03210020 <015E> is program 4

If one quits repeating the sequence for about a minute the pump stops.
The IntelliComII is not aware of the status of the pump and will keep
repeating the sequence as long as an input is active. You can stop and
start the pump with the START/STOP button on the control panel anytime,
unless, of course, you hit the period when it is in remote control.

More decoding of binary data from an IntelliTouch controlled system
with a VS pump surfaced that there is a status report from the pump.
It is only obtainable when the pump is in remote control.

    C: A500 d=60 s=10 c=07 l=00 <011C> SEND status
    P: A500 d=10 s=60 c=07 l=0f 0A0602024A08AC120000000A000F22 <028A>
            RUN 0a   Started
        MOD 06   Feature 1
        PMP 02   ? drive state
        PWR 024a  586 WATT
        RPM 08ac 2220 RPM
        GPM 12     18 GPM
        PPC 00      0 %
        b09 00   ? 
        ERR 00   ok
        b11 0a   ? 
        TMR 00   0 MIN
        CLK 0f22 15:34

The above sequence is embedded within the cyclic exchange of data
between the controller and the pump. The full cyclic sequence is:

    C: A500 d=60 s=10 c=04 l=01 FF       <0219> SETCTRL remote
    P: A500 d=10 s=60 c=04 l=01 FF       <0219> CTRL is remote
    C: A500 d=60 s=10 c=01 l=04 02E40012 <0212> WRITE (18) to 0x02e4
    P: A500 d=10 s=60 c=01 l=02 0012 <012A>     VALIS (18)
    C: A500 d=60 s=10 c=05 l=01 06       <0121> SETMOD 06 (Feature 1)
    P: A500 d=10 s=60 c=05 l=01 06       <0121> MOD is 06
    C: A500 d=60 s=10 c=06 l=01 0A       <0126> SETRUN 0a Started
    P: A500 d=10 s=60 c=06 l=01 0A       <0126> RUN is 0a Started
    C: A500 d=60 s=10 c=07 l=00          <011C> SEND status
    P: A500 d=10 s=60 c=07 l=0f 0A0602024908B1120000000A000F22 <028E>

The controller never releases the pump as long as it is in AUTO mode.
The display on the pump shows "Display not active..." and the LEDs
above FEATURE 1 and START/STOP are on. Experiments with my pump showed
that one can change the GPM setpoint 0x02e4 on the fly, it follows it!
If the controller releases the pump the cyclic sequence changes to:

    C: A500 d=60 s=10 c=04 l=01 00 <011A> SETCTRL local
    P: A500 d=10 s=60 c=04 l=01 00 <011A> CTRL is local

It is important for any serious controller implementation to know when a
pump runs into trouble and the Pentair IntelliFlow VS is fully capable
of doing that!

Data decoder

NAME padec - pabus data decoder USAGE padec [-] INFO Offline binary decoder. Prints to standard output. The may be a raw dump of traffic from a Pentair RS485 bus or the of 'palog'. Options (default is to 'skip it' if not set): -d decode messages -s print preamble bytes (if you really care) -a print record positions in -f <#> print only messages from/to address <#> -r print full decode of repeated messages -h print 'palog' records -t print timestamps, only useful if data is from 'palog'

Should you decide to experiment with the programs below ...

    !BE WARE YOU ARE ON YOUR OWN!
  !! THE FOLLOWING PROGRAMS PUT DATA ON THE BUS !!

! DO NOT USE THIS IF YOU ALREADY HAVE A CONTROLLER IN YOUR SYSTEM ! ! MAKE SURE YOU CAN KILL POWER TO THE PUMP BY A HW SWITCH ANYTIME !

You will need the HW switch in case things get out of control! Especially when you start messing with the code and work on a live system.

Simulator Program

NAME iFlow - IntelliFlow simulator on pabus USAGE iFlow [] INFO Attaches to an 'aprs485' tab and emulates bus behavior of an IntelliFlow pump. This program can be used to test controller software before you let it go for the real thing. It is not a full implementation, but has enough to get the basic bugs out of controller programs, and then, one can always add to it... Program exits if you type 'q' followed by a or it receives an EOT from the hub.

Simple Controller programs

The programs in this section will exit if they detect traffic on the bus.

NAME iComII - IntelliComII emulator on pabus USAGE iComII [] INFO Interactive program, attaches to access point tab and emulates behavior of an IntelliComII controller. It has an 'extra' feature which gives you, the user, the ability to pull status from the pump. The pump will will follow your commands, if the external programs are setup AND it is in FILTER mode AND the START/STOP light is on. The commands are: q - quit s - pump status 0 - all inputs off 1 - input 1 active 2 - input 2 active 3 - input 3 active 4 - input 4 active The prompt displays the version number of the program, the count down timer for the next cyclic transmission and the currently active program sent to the pump. Program exits if you enter the 'quit' command or it receives an EOT from the hub.

NAME iPump - IntelliFlow controller USAGE iPump [] INFO Experimental interactive controller program. Program exits if you enter the 'quit' command or it receives an EOT from the hub.

NAME iPmon - IntelliFlow pump status monitor USAGE iPmon [] INFO Attaches to access point tab and polls pump status every 15 seconds. Program exits if you enter the 'quit' command or it receives an EOT from the hub.

from https://github.com/tagyoureit/nodejs-poolController

var controllerStatusPacketFields = { HOUR: 6, MIN: 7, EQUIP1: 8, EQUIP2: 9, EQUIP3: 10, UOM: 15, //Celsius (4) or Fahrenheit (0); Also Service/Timeout. See strRunMode below. VALVE: 16, DELAY: 18, //64==??; 65-135 (for 50 circuits) is the circuit that is currently delayed. UNKNOWN: 19, //Something to do with heat. POOL_TEMP: 20, SPA_TEMP: 21, HEATER_ACTIVE: 22, //0=off. 32=on. More here? AIR_TEMP: 24, SOLAR_TEMP: 25, HEATER_MODE: 28, MISC2: 32 //0=do not automatically adjust DST, 1=automatically adjust DST }

// this is from the chlorinator itself = 16,2,...,16,3 var chlorinatorPacketFields = { DEST: 2, ACTION: 3 }

var pumpPacketFields = { DEST: 2, FROM: 3, ACTION: 4, LENGTH: 5, CMD: 6, // MODE: 7, //?? Mode in pump status. Means something else in pump write/response DRIVESTATE: 8, //?? Drivestate in pump status. Means something else in pump write/response WATTSH: 9, WATTSL: 10, RPMH: 11, RPML: 12, GPM: 13, PPC: 14, //?? //14 Unknown ERR: 15, //16 Unknown TIMER: 18, //Have to explore HOUR: 19, //Hours MIN: 20 //Mins }

var pumpConfigFieldsCommon = { NUMBER: 6, TYPE: 7 }

var pumpConfigFieldsVS = { PRIMINGMINS: 8, UNKNOWNCONSTANT_9: 9, UNUSED_10: 10, CIRCUIT1: 11, CIRCUIT1RPMH: 12, CIRCUIT2: 13, CIRCUIT2RPMH: 14, CIRCUIT3: 15, CIRCUIT3RPMH: 16, CIRCUIT4: 17, CIRCUIT4RPMH: 18, CIRCUIT5: 19, CIRCUIT5RPMH: 20, CIRCUIT6: 21, CIRCUIT6RPMH: 22, CIRCUIT7: 23, CIRCUIT7RPMH: 24, CIRCUIT8: 25, CIRCUIT8RPMH: 26, PRIMERPMH: 27, CIRCUIT1RPML: 28, CIRCUIT2RPML: 29, CIRCUIT3RPML: 30, CIRCUIT4RPML: 31, CIRCUIT5RPML: 32, CIRCUIT6RPML: 33, CIRCUIT7RPML: 34, CIRCUIT8RPML: 35, PRIMERPML: 36 // CIRCUITS 37-51 ARE ALL 0 FOR VS WITH EXTENDED CONFIG } var pumpConfigFieldsVF = { POOLSIZE: 8, // GALLONS TURNOVERS: 9, // PER DAY UNUSED_10: 10, CIRCUIT1: 11, CIRCUIT1GPM: 12, CIRCUIT2: 13, CIRCUIT2GPM: 14, CIRCUIT3: 15, CIRCUIT3GPM: 16, CIRCUIT4: 17, CIRCUIT4GPM: 18, CIRCUIT5: 19, CIRCUIT5GPM: 20, CIRCUIT6: 21, CIRCUIT6GPM: 22, CIRCUIT7: 23, CIRCUIT7GPM: 24, CIRCUIT8: 25, CIRCUIT8GPM: 26, MANUALFILTERGPM: 27, MAXPRIMEFLOW: 28, MAXPRIMESYSTEMTIME: 29, MAXPRESSUREINCREASE: 30, BACKWASHFLOW: 31, BACKWASHTIME: 32, RINSETIME: 33, VACUUMFLOW: 34, // +1 FOR ACTUAL VALUE UNUSED_35: 35, VACUUMTIME: 36 // CIRCUITS 37-51 ARE ALL 0 FOR VF WITH EXTENDED CONFIG }

var pumpConfigFieldsVSF = {
  PRIMINGMINS: 8, // ALWAYS 0?
  UNKNOWNCONSTANT_9: 9,
  RPMGPMFLAG: 10,
  CIRCUIT1: 11,
  CIRCUIT1H: 12,
  CIRCUIT2: 13,
  CIRCUIT2H: 14,
  CIRCUIT3: 15,
  CIRCUIT3H: 16,
  CIRCUIT4: 17,
  CIRCUIT4H: 18,
  CIRCUIT5: 19,
  CIRCUIT5H: 20,
  CIRCUIT6: 21,
  CIRCUIT6H: 22,
  CIRCUIT7: 23,
  CIRCUIT7H: 24,
  CIRCUIT8: 25,
  CIRCUIT8H: 26,
  PRIMERPMH: 27,  // NOT USED WITH VSF?
  CIRCUIT1RPML: 28,
  CIRCUIT2RPML: 29,
  CIRCUIT3RPML: 30,
  CIRCUIT4RPML: 31,
  CIRCUIT5RPML: 32,
  CIRCUIT6RPML: 33,
  CIRCUIT7RPML: 34,
  CIRCUIT8RPML: 35,
  PRIMERPML: 36  // NOT USED WITH VSF?
  // CIRCUITS 37-44 ARE ALL 255 FOR VS WITH EXTENDED CONFIG
  // CIRCUITS 45-51 ARE ALL 0 WITH VS FOR EXTENDED CONFIG
}

var pumpTypeStr = {
  0: 'None',
  1: 'VF', // VF is really any circuit assignment between 1-63(?)
  64: 'VSF',
  128: 'VS'
}

var pumpType = {
  NONE: 0,
  VF: 1,
  VSF: 64,
  VS: 128
}

var namePacketFields = {
    NUMBER: 6,
    CIRCUITFUNCTION: 7,
    NAME: 8,
}

var pumpAction = {
    1: 'WRITE', //Write commands to pump
    4: 'REMOTE', //Turn on/off pump control panel
    5: 'MODE', //Set pump mode
    6: 'RUN', //Set run mode
    7: 'STATUS' //Request status
}

var strCircuitName = {
    0: 'NOT USED',
    1: 'AERATOR',
    2: 'AIR BLOWER',
    3: 'AUX 1',
    4: 'AUX 2',
    5: 'AUX 3',
    6: 'AUX 4',
    7: 'AUX 5',
    8: 'AUX 6',
    9: 'AUX 7',
    10: 'AUX 8',
    11: 'AUX 9',
    12: 'AUX 10',
    13: 'BACKWASH',
    14: 'BACK LIGHT',
    15: 'BBQ LIGHT',
    16: 'BEACH LIGHT',
    17: 'BOOSTER PUMP',
    18: 'BUG LIGHT',
    19: 'CABANA LTS',
    20: 'CHEM. FEEDER',
    21: 'CHLORINATOR',
    22: 'CLEANER',
    23: 'COLOR WHEEL',
    24: 'DECK LIGHT',
    25: 'DRAIN LINE',
    26: 'DRIVE LIGHT',
    27: 'EDGE PUMP',
    28: 'ENTRY LIGHT',
    29: 'FAN',
    30: 'FIBER OPTIC',
    31: 'FIBER WORKS',
    32: 'FILL LINE',
    33: 'FLOOR CLNR',
    34: 'FOGGER',
    35: 'FOUNTAIN',
    36: 'FOUNTAIN 1',
    37: 'FOUNTAIN 2',
    38: 'FOUNTAIN 3',
    39: 'FOUNTAINS',
    40: 'FRONT LIGHT',
    41: 'GARDEN LTS',
    42: 'GAZEBO LTS',
    43: 'HIGH SPEED',
    44: 'HI-TEMP',
    45: 'HOUSE LIGHT',
    46: 'JETS',
    47: 'LIGHTS',
    48: 'LOW SPEED',
    49: 'LO-TEMP',
    50: 'MALIBU LTS',
    51: 'MIST',
    52: 'MUSIC',
    53: 'NOT USED',
    54: 'OZONATOR',
    55: 'PATH LIGHTS',
    56: 'PATIO LTS',
    57: 'PERIMETER L',
    58: 'PG2000',
    59: 'POND LIGHT',
    60: 'POOL PUMP',
    61: 'POOL',
    62: 'POOL HIGH',
    63: 'POOL LIGHT',
    64: 'POOL LOW',
    65: 'SAM',
    66: 'POOL SAM 1',
    67: 'POOL SAM 2',
    68: 'POOL SAM 3',
    69: 'SECURITY LT',
    70: 'SLIDE',
    71: 'SOLAR',
    72: 'SPA',
    73: 'SPA HIGH',
    74: 'SPA LIGHT',
    75: 'SPA LOW',
    76: 'SPA SAL',
    77: 'SPA SAM',
    78: 'SPA WTRFLL',
    79: 'SPILLWAY',
    80: 'SPRINKLERS',
    81: 'STREAM',
    82: 'STATUE LT',
    83: 'SWIM JETS',
    84: 'WTR FEATURE',
    85: 'WTR FEAT LT',
    86: 'WATERFALL',
    87: 'WATERFALL 1',
    88: 'WATERFALL 2',
    89: 'WATERFALL 3',
    90: 'WHIRLPOOL',
    91: 'WTRFL LGHT',
    92: 'YARD LIGHT',
    93: 'AUX EXTRA',
    94: 'FEATURE 1',
    95: 'FEATURE 2',
    96: 'FEATURE 3',
    97: 'FEATURE 4',
    98: 'FEATURE 5',
    99: 'FEATURE 6',
    100: 'FEATURE 7',
    101: 'FEATURE 8',
    200: 'USERNAME-01',
    201: 'USERNAME-02',
    202: 'USERNAME-03',
    203: 'USERNAME-04',
    204: 'USERNAME-05',
    205: 'USERNAME-06',
    206: 'USERNAME-07',
    207: 'USERNAME-08',
    208: 'USERNAME-09',
    209: 'USERNAME-10'
}

var strCircuitFunction = {
    0: 'Generic',
    1: 'Spa',
    2: 'Pool',
    5: 'Master Cleaner',
    7: 'Light',
    9: 'SAM Light',
    10: 'SAL Light',
    11: 'Photon Gen',
    12: 'Color Wheel',
    13: 'Valve',
    14: 'Spillway',
    15: 'Floor Cleaner',
    16: 'Intellibrite',
    17: 'MagicStream',
    19: 'Not Used',
    64: 'Freeze protection on',
    // Not exactly sure if the following belong in this list...
    // they show up in the pump circuit assignment packets (24/27)
    128: 'Solar',
    129: 'Either Heater',
    130: 'Pool Heater',
    131: 'Spa Heater',
    132: 'Freeze'
}

var strPumpActions = {
    1: 'Pump set speed/program or run program',
    4: 'Pump control panel',
    5: 'Pump speed',
    6: 'Pump power',
    7: 'Pump Status'
}

var strChlorinatorActions = {
    0: 'Get Status',
    1: 'Response to Get Status',
    3: 'Response to Get Version',
    17: 'Set Salt %',
    18: 'Response to Set Salt % & Salt PPM',
    20: 'Get Version',
    21: 'Set Salt Generate % / 10'
}

var strControllerActions = {
    // Response/information/settings
    1: 'Ack Message',
    2: 'Controller Status',
    5: 'Date/Time',
    7: 'Pump Status',
    8: 'Heat/Temperature Status',
    10: 'Custom Names',
    11: 'Circuit Names/Function',
    16: 'Heat Pump Status?',
    17: 'Schedule details',
    18: 'IntelliChem',
    19: 'Intelli(?)',  //Packet never seen...
    22: 'Get Intelliflo Spa Side Control',
    23: 'Pump Status',
    24: 'Pump Config',
    25: 'IntelliChlor Status',
    27: 'Pump Config (Extended)',
    29: 'Valve Status',
    30: 'High Speed Circuits for Valve',
    32: 'is4/is10 Settings',
    33: 'Intelliflo Spa Side Remote settings',
    34: 'Solar/Heat Pump Status',
    35: 'Delay Status',
    39: 'Light Groups/Positions',
    40: 'Settings, Heat Mode?',  //

    // Set commands
    96: 'Set Color',
    131: 'Set Delay Cancel',
    133: 'Set Date/Time',
    134: 'Set Circuit',
    136: 'Set Heat/Temperature',
    138: 'Set Custom Name',
    139: 'Set Circuit Name/Function',
    144: 'Set Heat Pump',
    145: 'Set Schedule',
    146: 'Set IntelliChem',
    147: 'Set Intelli(?)',
    150: 'Set Intelliflow Spa Side Control',
    152: 'Set Pump Config',
    153: 'Set IntelliChlor',
    155: 'Set Pump Config (Extended)',
    157: 'Set Valves',
    158: 'Set High Speed Circuits for Valves',  //Circuits that require high speed
    160: 'Set is4/is10 Spa Side Remote',
    161: 'Set QuickTouch Spa Side Remote',
    162: 'Set Solar/Heat Pump',
    163: 'Set Delay',
    167: 'Set Light Groups/Positions',
    168: 'Set Heat Mode',  //probably more

    // Get commands
    194: 'Get Status/',
    197: 'Get Date/Time',
    200: 'Get Heat/Temperature',
    202: 'Get Custom Name',
    203: 'Get Circuit Name/Function',
    208: 'Get Heat Pump',
    209: 'Get Schedule',
    210: 'Get IntelliChem',
    211: 'Get Intelli(?)',
    214: 'Get Inteliflo Spa Side Control',
    215: 'Get Pump Status',
    216: 'Get Pump Config',
    217: 'Get IntelliChlor',
    219: 'Get Pump Config (Extended)',
    221: 'Get Valves',
    222: 'Get High Speed Circuits for Valves',
    224: 'Get is4/is10 Settings',
    225: 'Get Intelliflo Spa Side Remote settings',
    226: 'Get Solar/Heat Pump',
    227: 'Get Delays',
    231: 'Get Light group/positions',
    232: 'Get Settings, Heat Mode?',
    252: 'SW Version Info',
    253: 'Get SW Version'
}

var lightColors = {
    0: "White",
    1: "Custom", // custom addition for when save/recall are used
    2: "Light Green",
    4: "Green",
    6: "Cyan",
    8: "Blue",
    10: "Lavender",
    12: "Magenta",
    14: "Light Magenta"
}

var strIntellibriteModes = {
    0: 'Off',
    1: 'On',
    128: 'Color Sync',
    144: 'Color Swim',
    160: 'Color Set',
    177: 'Party',
    178: 'Romance',
    179: 'Caribbean',
    180: 'American',
    181: 'Sunset',
    182: 'Royal',
    190: 'Save',
    191: 'Recall',
    193: 'Blue',
    194: 'Green',
    195: 'Red',
    196: 'White',
    197: 'Magenta'
}
var intellibriteModes = {
    'Off': 0,
    'On': 1,
    'Color Sync': 128,
    'Color Swim': 144,
    'Color Set': 160,
    'Party': 177,
    'Romance': 178,
    'Caribbean': 179,
    'American': 180,
    'Sunset': 181,
    'Royal': 182,
    'Save': 190,
    'Recall': 191,
    'Blue': 193,
    'Green': 194,
    'Red': 195,
    'White': 196,
    'Magenta': 197
}

var strRunMode = {
    //same bit as UOM.  Need to fix naming.
    0: 'Auto', //0x00000000
    1: 'Service', //0x00000001
    4: 'Celsius', //if 1, Celsius.  If 0, Fahrenheit
    8: 'Freeze', //0 if no freeze, 1 if freeze mode active
    128: '/Timeout' //Timeout always appears with Service; eg this bit has not been observed to be 128 but rather 129.  Not sure if the timer is in the controller.  0x10000001

}

var strValve = {
    3: 'Pool',
    15: 'Spa',
    48: 'Heater',
    51: 'Solar'
}

var heatModeStr = {
    //Pentair controller sends the pool and spa heat status as a 4 digit binary byte from 0000 (0) to 1111 (15).  The left two (xx__) is for the spa and the right two (__xx) are for the pool.  EG 1001 (9) would mean 10xx = 2 (Spa mode Solar Pref) and xx01 = 1 (Pool mode Heater)
    //0: all off
    //1: Pool heater            Spa off
    //2: Pool Solar Pref        Spa off
    //3: Pool Solar Only        Spa off
    //4: Pool Off               Spa Heater
    //5: Pool Heater            Spa Heater
    //6: Pool Solar Pref        Spa Heater
    //7: Pool Solar Only        Spa Heater
    //8: Pool Off               Spa Solar Pref
    //9: Pool Heater            Spa Solar Pref
    //10: Pool Solar Pref       Spa Solar Pref
    //11: Pool Solar Only       Spa Solar Pref
    //12: Pool Off              Spa Solar Only
    //13: Pool Heater           Spa Solar Only
    //14: Pool Solar Pref       Spa Solar Only
    //15: Pool Solar Only       Spa Solar Only
    0: 'OFF',
    1: 'Heater',
    2: 'Solar Pref',
    3: 'Solar Only'
}

var heatMode = {
    OFF: 0,
    HEATER: 1,
    SOLARPREF: 2,
    SOLARONLY: 3
}

var ctrl = {
    CHLORINATOR: 2,
    BROADCAST: 15,
    INTELLITOUCH: 16,
    REMOTE: 32,
    WIRELESS: 34, //Looks like this is any communications through the wireless link (ScreenLogic on computer, iPhone...)
    PUMP1: 96,
    PUMP2: 97,
    PUMP3: 98,
    PUMP4: 99,
    PUMP5: 100,
    PUMP6: 101,
    PUMP7: 102,
    PUMP8: 103,
    PUMP9: 104,
    PUMP10: 105,
    PUMP11: 106,
    PUMP12: 107,
    PUMP13: 108,
    PUMP14: 109,
    PUMP15: 110,
    PUMP16: 111,
    INTELLICHEM: 144
}

var ctrlString = {
    2: 'Chlorinator',
    15: 'Broadcast',
    16: 'Main',
    32: 'Remote',
    33: 'PoolControllerApp', //default address
    34: 'Wireless',
    96: 'Pump 1',
    97: 'Pump 2',
    98: 'Pump 3',
    99: 'Pump 4',
    100: 'Pump 5',
    101: 'Pump 6',
    102: 'Pump 7',
    103: 'Pump 8',
    104: 'Pump 9',
    105: 'Pump 10',
    106: 'Pump 11',
    107: 'Pump 12',
    108: 'Pump 13',
    109: 'Pump 14',
    110: 'Pump 15',
    111: 'Pump 16',
    144: 'Intellichem',
    appAddress: 'nodejs-poolController Server'
}

var schedulePacketBytes = {
    "ID": 6,
    "CIRCUIT": 7,
    "TIME1": 8,
    "TIME2": 9,
    "TIME3": 10,
    "TIME4": 11,
    "DAYS": 12
};

var intellichemPacketFields = {
  DEST: 2,
  ACTION: 3,
  PHREADINGHI: 6,
  PHREADINGLO: 7,
  ORPREADINGHI: 8,
  ORPREADINGLO: 9,
  PHSETPOINTHI: 10,
  PHSETPOINTLO: 11,
  ORPSETPOINTHI: 12,
  ORPSETPOINTLO: 13,
  TANK1: 26,
  TANK2: 27,
  CALCIUMHARDNESSHI: 29,
  CALCIUMHARDNESSLO: 30,
  CYAREADING: 32,
  TOTALALKALINITYREADINGHI: 33,
  TOTALALKALINITYREADINGLO: 34,
  WATERFLOW: 36,
  MODE1: 40,
  MODE2: 41
}

/*istanbul ignore next */
if (container.logModuleLoading)
    container.logger.info('Loaded: ants.js')

return {
    packetFields: packetFields,
    controllerStatusPacketFields: controllerStatusPacketFields,
    controllerChlorinatorPacketFields: controllerChlorinatorPacketFields,
    chlorinatorPacketFields: chlorinatorPacketFields,
    pumpPacketFields: pumpPacketFields,
    pumpType: pumpType,
    pumpTypeStr: pumpTypeStr,
    pumpConfigFieldsCommon: pumpConfigFieldsCommon,
    pumpConfigFieldsVS: pumpConfigFieldsVS,
    pumpConfigFieldsVF: pumpConfigFieldsVF,
    pumpConfigFieldsVSF: pumpConfigFieldsVSF,
    namePacketFields: namePacketFields,
    pumpAction: pumpAction,
    strCircuitName: strCircuitName,
    strCircuitFunction: strCircuitFunction,
    strPumpActions: strPumpActions,
    strChlorinatorActions: strChlorinatorActions,
    strControllerActions: strControllerActions,
    strRunMode: strRunMode,
    strValve: strValve,
    heatModeStr: heatModeStr,
    heatMode: heatMode,
    ctrl: ctrl,
    ctrlString: ctrlString,
    schedulePacketBytes: schedulePacketBytes,
    intellichemPacketFields: intellichemPacketFields,
    strIntellibriteModes: strIntellibriteModes,
    intellibriteModes: intellibriteModes,
    lightColors: lightColors
}

}

rsumner commented 2 years ago

Sending commands also isn't working for me. The the circuit will return back to it's previous state. The MQTT command seems to be received with no problem. Here's some output from serial:

I (35183) RS485_PENTAIR_CONTROLLER: Received 47 bytes:
I (35183) RS485_PENTAIR_CONTROLLER: Found header start at offset 7
I (35183) RS485_PENTAIR_CONTROLLER: Source  : (0x10) Main
I (35183) RS485_PENTAIR_CONTROLLER: Dest    : (0x0f) Broadcast
I (35193) RS485_PENTAIR_CONTROLLER: Command : (0x02) 2

I (35203) RS485_PENTAIR_CONTROLLER: Time:        8:9
I (35203) RS485_PENTAIR_CONTROLLER: Pump1:       on
I (35213) RS485_PENTAIR_CONTROLLER: Cleaner:     off
I (35213) RS485_PENTAIR_CONTROLLER: Air Blower:  off
I (35223) RS485_PENTAIR_CONTROLLER: Pool temp:   78
I (35223) RS485_PENTAIR_CONTROLLER: Spa temp:    78
I (35233) RS485_PENTAIR_CONTROLLER: Air temp:    72
I (35233) RS485_PENTAIR_CONTROLLER: Heater:      32
I (35243) RS485_PENTAIR_CONTROLLER: Heater mode: 4
I (35253) RS485_PENTAIR_CONTROLLER: Unknown:     4
I (35253) RS485_PENTAIR_CONTROLLER: Spa:         off
I (35263) RS485_PENTAIR_CONTROLLER: Pool light:  off
I (35263) RS485_PENTAIR_CONTROLLER: Spa light:   off

I (36173) RS485_PENTAIR_CONTROLLER: MQTT_EVENT_DATA
I (36173) RS485_PENTAIR_CONTROLLER: TOPIC='homeassistant/switch/pool/water_feature1/set'

I (36173) RS485_PENTAIR_CONTROLLER: DATA='on'

I (36183) RS485_PENTAIR_CONTROLLER: Switching feature 07 ON **********************
I (36183) RS485_PENTAIR_CONTROLLER: Sending command from=20 to=10 command=86 feature=07 state=01
00 ff a5 1f 10 20 86 02 07 01 01 84 I (36693) RS485_PENTAIR_CONTROLLER: 12
I (37043) RS485_PENTAIR_CONTROLLER: Received 47 bytes:
I (37043) RS485_PENTAIR_CONTROLLER: Found header start at offset 7
I (37043) RS485_PENTAIR_CONTROLLER: Source  : (0x10) Main
I (37043) RS485_PENTAIR_CONTROLLER: Dest    : (0x0f) Broadcast
I (37053) RS485_PENTAIR_CONTROLLER: Command : (0x02) 2

I (37063) RS485_PENTAIR_CONTROLLER: Time:        8:9
I (37063) RS485_PENTAIR_CONTROLLER: Pump1:       on
I (37073) RS485_PENTAIR_CONTROLLER: Cleaner:     off
I (37073) RS485_PENTAIR_CONTROLLER: Air Blower:  off
I (37083) RS485_PENTAIR_CONTROLLER: Pool temp:   78
I (37083) RS485_PENTAIR_CONTROLLER: Spa temp:    78
I (37093) RS485_PENTAIR_CONTROLLER: Air temp:    72
I (37093) RS485_PENTAIR_CONTROLLER: Heater:      32
I (37103) RS485_PENTAIR_CONTROLLER: Heater mode: 4
I (37113) RS485_PENTAIR_CONTROLLER: Unknown:     4
I (37113) RS485_PENTAIR_CONTROLLER: Spa:         off
I (37123) RS485_PENTAIR_CONTROLLER: Pool light:  off
I (37123) RS485_PENTAIR_CONTROLLER: Spa light:   off

I (39153) RS485_PENTAIR_CONTROLLER: Received 127 bytes:
I (39153) RS485_PENTAIR_CONTROLLER: Found header start at offset 7
I (39153) RS485_PENTAIR_CONTROLLER: Source  : (0x10) Main
I (39153) RS485_PENTAIR_CONTROLLER: Dest    : (0x0f) Broadcast
I (39163) RS485_PENTAIR_CONTROLLER: Command : (0x02) 2

I do have a USB-to-RS485 adapter on the way so I can see if the serial commands are making it from my data closet (where the ESP32 resides) to the EasyTouch (about 100 linear feet away). One thing that concerns me is the distance the cheap max485 devboards are capable of.

michaelusner commented 2 years ago

@rsumner The same thing is happening for me. I believe it's a race condition where the status message is overwriting the state before it gets written to the controller. I'll try to sort it out because it's preventing HA from effectively controlling things reliably. If I run MQTTExplorer to probe the values, the problem doesn't happen anymore which is strange.

Regarding your distance concern. I don't know the max distance but from what I read, speed will decrease with distance. One thing you could watch is the number of rejected packets due to checksum error. That should indicate that there's transmission problems. I don't know that it would depend on the power of the MAX485 adapter or not. That's probably a question for a EE or someone more knowledgeable about the MAX485 than I am.

jbishop129 commented 1 year ago

Same issue here: ESP32 + MAX485 breakout board. I can read the bus just fine and have the respective switches and sensors in HA... terrific! but trying to write a setting, either from the switch in HA or directly via mosquitto_pub, I can see the attempt on the RS-485 bus to send the cmd, but it doesnt successfully write the setting (or the controller ignores it).

One other thing worth noting, is out of the box the various pool devices (lights, air blower, edge pump, etc) are not mapped correctly: example - Air Blower is actually the Spa Light. Easy fix in HA itself to remap, but thought I'd mention it.

Here's a snippet where I was trying to turn some features on/off, to no avail:

I (79869) RS485_PENTAIR_CONTROLLER: Time:        14:33
I (79879) RS485_PENTAIR_CONTROLLER: Pump1:       on
I (79889) RS485_PENTAIR_CONTROLLER: Cleaner:     on
I (79889) RS485_PENTAIR_CONTROLLER: Air Blower:  off
I (79899) RS485_PENTAIR_CONTROLLER: Pool temp:   56
I (79899) RS485_PENTAIR_CONTROLLER: Spa temp:    56
I (79909) RS485_PENTAIR_CONTROLLER: Air temp:    54
I (79909) RS485_PENTAIR_CONTROLLER: Heater:      0
I (79919) RS485_PENTAIR_CONTROLLER: Heater mode: 0
I (79919) RS485_PENTAIR_CONTROLLER: Unknown:     4
I (79929) RS485_PENTAIR_CONTROLLER: Spa:         off
I (79939) RS485_PENTAIR_CONTROLLER: Pool light:  off
I (79939) RS485_PENTAIR_CONTROLLER: Spa light:   off

I (80319) RS485_PENTAIR_CONTROLLER: Received 9 bytes:
I (81079) RS485_PENTAIR_CONTROLLER: Received 6 bytes:
I (81459) RS485_PENTAIR_CONTROLLER: Received 14 bytes:
I (81869) RS485_PENTAIR_CONTROLLER: Received 11 bytes:
I (82009) RS485_PENTAIR_CONTROLLER: MQTT_EVENT_DATA
I (82009) RS485_PENTAIR_CONTROLLER: TOPIC='homeassistant/switch/pool/spa/set'

I (82009) RS485_PENTAIR_CONTROLLER: DATA='on'

I (82019) RS485_PENTAIR_CONTROLLER: Switching feature 01 ON **********************
I (82019) RS485_PENTAIR_CONTROLLER: Sending command from=20 to=10 command=86 feature=01 state=01
00 ff a5 1f 10 20 86 02 01 01 01 7e I (82219) RS485_PENTAIR_CONTROLLER: Received 12 bytes:
I (82219) RS485_PENTAIR_CONTROLLER: Found header start at offset 0
I (82219) RS485_PENTAIR_CONTROLLER: Source  : (0x10) Main
I (82229) RS485_PENTAIR_CONTROLLER: Dest    : (0x90) Unknown
I (82229) RS485_PENTAIR_CONTROLLER: Command : (0xd2) 210

I (82529) RS485_PENTAIR_CONTROLLER: 12
I (82629) RS485_PENTAIR_CONTROLLER: Received 3 bytes:
I (83099) RS485_PENTAIR_CONTROLLER: Received 5 bytes:
I (83509) RS485_PENTAIR_CONTROLLER: Received 47 bytes:
I (83509) RS485_PENTAIR_CONTROLLER: Found header start at offset 7
I (83509) RS485_PENTAIR_CONTROLLER: Source  : (0x10) Main
I (83509) RS485_PENTAIR_CONTROLLER: Dest    : (0x0f) Broadcast
I (83519) RS485_PENTAIR_CONTROLLER: Command : (0x02) 2
michaelusner commented 1 year ago

I got distracted away from this project trying to migrate the code to a ESPHome custom component. I'll pick this back up to at least get things working again.

On Mon, Jan 2, 2023 at 4:16 PM Joe @.***> wrote:

Same issue here: ESP32 + MAX485 breakout board. I can read the bus just fine and have the respective switches and sensors in HA... terrific! but trying to write a setting, either from the switch in HA or directly via mosquitto_pub, I can see the attempt on the RS-485 bus to send the cmd, but it doesnt successfully write the setting (or the controller ignores it).

One other thing worth noting, is out of the box the various pool devices (lights, air blower, edge pump, etc) are not mapped correctly: example - Air Blower is actually the Spa Light. Easy fix in HA itself to remap, but thought I'd mention it.

Here's a snippet where I was trying to turn some features on/off, to no avail:

I (79869) RS485_PENTAIR_CONTROLLER: Time: 14:33 I (79879) RS485_PENTAIR_CONTROLLER: Pump1: on I (79889) RS485_PENTAIR_CONTROLLER: Cleaner: on I (79889) RS485_PENTAIR_CONTROLLER: Air Blower: off I (79899) RS485_PENTAIR_CONTROLLER: Pool temp: 56 I (79899) RS485_PENTAIR_CONTROLLER: Spa temp: 56 I (79909) RS485_PENTAIR_CONTROLLER: Air temp: 54 I (79909) RS485_PENTAIR_CONTROLLER: Heater: 0 I (79919) RS485_PENTAIR_CONTROLLER: Heater mode: 0 I (79919) RS485_PENTAIR_CONTROLLER: Unknown: 4 I (79929) RS485_PENTAIR_CONTROLLER: Spa: off I (79939) RS485_PENTAIR_CONTROLLER: Pool light: off I (79939) RS485_PENTAIR_CONTROLLER: Spa light: off

I (80319) RS485_PENTAIR_CONTROLLER: Received 9 bytes: I (81079) RS485_PENTAIR_CONTROLLER: Received 6 bytes: I (81459) RS485_PENTAIR_CONTROLLER: Received 14 bytes: I (81869) RS485_PENTAIR_CONTROLLER: Received 11 bytes: I (82009) RS485_PENTAIR_CONTROLLER: MQTT_EVENT_DATA I (82009) RS485_PENTAIR_CONTROLLER: TOPIC='homeassistant/switch/pool/spa/set'

I (82009) RS485_PENTAIR_CONTROLLER: DATA='on'

I (82019) RS485_PENTAIR_CONTROLLER: Switching feature 01 ON ** I (82019) RS485_PENTAIR_CONTROLLER: Sending command from=20 to=10 command=86 feature=01 state=01 00 ff a5 1f 10 20 86 02 01 01 01 7e I (82219) RS485_PENTAIR_CONTROLLER: Received 12 bytes: I (82219) RS485_PENTAIR_CONTROLLER: Found header start at offset 0 I (82219) RS485_PENTAIR_CONTROLLER: Source : (0x10) Main I (82229) RS485_PENTAIR_CONTROLLER: Dest : (0x90) Unknown I (82229) RS485_PENTAIR_CONTROLLER: Command : (0xd2) 210

I (82529) RS485_PENTAIR_CONTROLLER: 12 I (82629) RS485_PENTAIR_CONTROLLER: Received 3 bytes: I (83099) RS485_PENTAIR_CONTROLLER: Received 5 bytes: I (83509) RS485_PENTAIR_CONTROLLER: Received 47 bytes: I (83509) RS485_PENTAIR_CONTROLLER: Found header start at offset 7 I (83509) RS485_PENTAIR_CONTROLLER: Source : (0x10) Main I (83509) RS485_PENTAIR_CONTROLLER: Dest : (0x0f) Broadcast I (83519) RS485_PENTAIR_CONTROLLER: Command : (0x02) 2

— Reply to this email directly, view it on GitHub https://github.com/michaelusner/esp32-pentair-controller/issues/2#issuecomment-1369245286, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQ5DF6GMVY7PVBTGKOAPDTWQNHUNANCNFSM5HAAHKZA . You are receiving this because you commented.Message ID: @.***>

jbishop129 commented 1 year ago

I am very interested in this being part of ESPHome!! A few years ago I had this working via an implementation of ser2net when I was on OpenHAB, but was not able to get it working again after I moved to Home Assistant. Very much agree this would be absolutely wonderful if it were part of ESPHome instead of a stand-alone project. Anything I can do to help, test, cheer on the efforts, I'm all-in on this direction.

Cheers

rsumner commented 1 year ago

I've contributed code for custom components to ESPHome in the past and happy to help here too. @michaelusner if you get a Github fork up and running and want some help, send over the details.

michaelusner commented 1 year ago

OK - I'll continue my efforts in that arena. I was able to get this project flashed again but can't figure out why it's not able to write. I suspect a flow control setting but can't narrow it down. I'll try to focus on ESPHome but would like to have this working at least...

Thanks!

On Tue, Jan 3, 2023 at 12:30 PM Joe @.***> wrote:

I am very interested in this being part of ESPHome!! A few years ago I had this working via an implementation of ser2net when I was on OpenHAB, but was not able to get it working again after I moved to Home Assistant. Very much agree this would be absolutely wonderful if it were part of ESPHome instead of a stand-alone project. Anything I can do to help, test, cheer on the efforts, I'm all-in on this direction.

Cheers

— Reply to this email directly, view it on GitHub https://github.com/michaelusner/esp32-pentair-controller/issues/2#issuecomment-1370094867, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQ5DFZKHJWFRZCY3VRL2GTWQRV4BANCNFSM5HAAHKZA . You are receiving this because you commented.Message ID: @.***>

michaelusner commented 1 year ago

Thanks! Once I figure out the details I'll get a repo up and running to share.

On Tue, Jan 3, 2023 at 1:07 PM rsumner @.***> wrote:

I've contributed code for custom components to ESPHome in the past and happy to help here too. @michaelusner https://github.com/michaelusner if you get a Github fork up and running and want some help, send over the details.

— Reply to this email directly, view it on GitHub https://github.com/michaelusner/esp32-pentair-controller/issues/2#issuecomment-1370127053, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQ5DF3OSPZHP7UVOK3M4C3WQR2HNANCNFSM5HAAHKZA . You are receiving this because you were mentioned.Message ID: @.***>

jbishop129 commented 1 year ago

Any update on ESPHome?

michaelusner commented 1 year ago

Thanks for checking in. It's coming along slowly because I didn't have a good understanding of custom components in ESPHome. I think I'm past that hurdle now and was actually working on it last night when I hit a strange issue where I'm not able to read from the UART anymore. If I flash my old firmware, I can see the traffic fine but with my ESPHome FW, it's not working.

Anyway, it's still a WIP but I haven't forgotten about it and am making some progress.

On Fri, Mar 17, 2023 at 11:53 AM Joe @.***> wrote:

Any update on ESPHome?

— Reply to this email directly, view it on GitHub https://github.com/michaelusner/esp32-pentair-controller/issues/2#issuecomment-1474125318, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQ5DF77EJXGFKJY7YQKWN3W4SJJXANCNFSM5HAAHKZA . You are receiving this because you were mentioned.Message ID: @.***>

jbishop129 commented 1 year ago

Awesome, glad to hear this is still on the radar! I've been happily using your existing code on my pool for a few months, works great! Only issue that still remains (and I know you're aware of) is it doesnt seem to be able to write data to the pool bus, i.e. turn on the lights, turn on the heater, etc. Hopefully this issue goes away once it hits ESPhome!

michaelusner commented 1 year ago

Unfortunately, our house took a lightning strike last week. Several components in our home were destroyed including my pool controller board and proto-board for the ESPHome project.

I have some parts arriving Friday to hopefully fix the pool and have to do some solder work on my proto-board to put another ESP32 on it but will hopefully be up and running again in a week or so.

If the pool controller needs to be replaced, it'll take a bit longer.

jbishop129 commented 1 year ago

Very sorry to hear about the lightening strike on your home :(

npawelek commented 2 months ago

I feel your pain about the lightning, and I'm sorry to hear that. We had a power outage during a storm last week and it knocked out our remote antenna (NO COMM and reattempting the address sync doesn't work). Instead of replacing I decided to give this a try.

After a bit of learning with esp-idf, I was able to get this connected to my EasyTouch panel. I can see the states, but I'm in the same boat as most of the others. Flipping a switch in home assistant does issue the set = on to the appropriate topic in MQTT, but the switch flips back to the off position shortly after being turned on.

jbishop129 commented 1 month ago

Hi @michaelusner I hope your home and pool recovered well from the lightning strike! Have you made any progress with porting over to ESPhome? Happy to contribute in any way that’s helpful!