New Binding for iAquaLink internet connected pools (Jandy/Zodiac)

Hi @digitaldan, I have installed your iAqualink addon today to control my Zodiac Exo IQ (this device includes some iAqualink features). But, I have also the error “OFFLINE - COMMUNICATION_ERROR - Forbidden” on my iAqualink thing, and my OpenHAB version is still in 2.5.12.
Do you plan to fix also on branch 2.5 ?

Thanks

Building for the 2.x branches is not possible anymore that i know of (the last commit to our 2.x addon repository was in February). You will need to upgrade to our 3.1 stable release if you want to continue using the binding.

Hi @digitaldan, I have try your iAqualink addon on my new OpenHab 3.1 instance. The iAqualink controller thing displays an “COMMUNICATION_ERROR” error. There is no debug logs related to this error.
After many searches, I think that the iAqualink API of Zodiac EXO IQ device (eXO<sup>®</sup> iQ | Zodiac Poolcare) is a little different of iAqualink classic devices.
Based on a Home Assistant thread, I have successfully connected to my Zodiac Exo IQ with few Postman requests.
Is it possible to include Zodiac EXO IQ device to your iAqualink addon ?

Thx

Hi, if you have some example responses I will take a look, you can also turn the logging to TRACE, so

log:set TRACE org.openhab.binding.iaqualink

and see if there is some additional information when trying to log in.

Here, the thread about iAqualink EXO IQ : Jandy iAqualink Pool Integration - #157 by Markus99 - Custom Components - Home Assistant Community

The “login” and “get devices” requests for Zodiac EXO IQ are similar to your addon requests.
To get informations (water temp, chlorination status, etc.), you must execute this request:
GET https://prod.zodiac-io.com/devices/v1/<serial_number of a device>/shadow
with headers:

authorization:<value of IdToken field in Login response>
user-agent:okhttp/3.12.0
accept:application/json
accept-encoding:gzip

Sample response body:

{
    "state": {
        "reported": {
            "vr": "xxxxxxxx",
            "aws": {
                "status": "connected",
                "timestamp": 1626933352383,
                "session_id": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
            },
            "debug": {
                "RSSI": -66,
                "OTA fail": 0,
                "OTA State": 0,
                "Last error": 65278,
                "Still alive": 2,
                "OTA success": 0,
                "MQTT connection": 2,
                "OTA fail global": 0,
                "Version Firmware": "V85W4B0",
                "Nb_Success_Pub_MSG": 15,
                "Nb_Fail_Publish_MSG": 0,
                "Nb_Success_Sub_Receive": 2,
                "MQTT disconnection total": 1,
                "OTA fail by disconnection": 0,
                "Nb reboot du to MQTT issue": 124
            },
            "equipment": {
                "swc_0": {
                    "sn": "ALWAxxxxxxxxxxxxxx",
                    "vr": "V85R67",
                    "low": 0,
                    "vsp": 1,
                    "swc": 70,
                    "amp": 1,
                    "temp": 1,
                    "lang": 1,
                    "boost": 0,
                    "ph_sp": 72,
                    "aux_1": {
                        "type": "none",
                        "mode": 0,
                        "state": 0,
                        "color": 0
                    },
                    "aux_2": {
                        "mode": 0,
                        "type": "none",
                        "color": 0,
                        "state": 0
                    },
                    "sns_2": {
                        "state": 0,
                        "value": 0,
                        "sensor_type": "Orp"
                    },
                    "sns_1": {
                        "state": 1,
                        "value": 70,
                        "sensor_type": "Ph"
                    },
                    "sns_3": {
                        "state": 1,
                        "value": 29,
                        "sensor_type": "Water temp"
                    },
                    "orp_sp": 700,
                    "aux230": 1,
                    "version": "V1",
                    "ph_only": 0,
                    "swc_low": 10,
                    "dual_link": 0,
                    "exo_state": 1,
                    "production": 1,
                    "error_code": 0,
                    "boost_time": "24:00",
                    "filter_pump": {
                        "type": 0,
                        "state": 0
                    },
                    "error_state": 0
                }
            },
            "schedules": {
                "sch1": {
                    "id": "sch_1",
                    "name": "Salt Water Chlorinator 1",
                    "timer": {
                        "end": "22:00",
                        "start": "07:00"
                    },
                    "active": 1,
                    "enabled": 1,
                    "endpoint": "swc_1"
                },
                "sch2": {
                    "id": "sch_2",
                    "name": "Salt Water Chlorinator 2",
                    "timer": {
                        "end": "00:00",
                        "start": "00:00"
                    },
                    "active": 0,
                    "enabled": 0,
                    "endpoint": "swc_2"
                },
                "sch9": {
                    "id": "sch_9",
                    "name": "Aux 1",
                    "timer": {
                        "end": "00:00",
                        "start": "00:00"
                    },
                    "active": 0,
                    "enabled": 0,
                    "endpoint": "aux1"
                },
                "sch10": {
                    "id": "sch_10",
                    "name": "Aux 2",
                    "timer": {
                        "end": "00:00",
                        "start": "00:00"
                    },
                    "active": 0,
                    "enabled": 0,
                    "endpoint": "aux2"
                },
                "supported": 4,
                "programmed": 1
            }
        }
    },
    "deviceId": "xxxxxxxxxxxx",
    "ts": 1626938778
}

Dan - nice job on this binding. I’m experimenting with OpenHab just because of your binding. I had previously written a c# program which uses the mobile api, as you do, and has many other features, i.e. weather, sports, news, photos, smartthings, calendar, Google, etc, but the jandy stuff stopped working when they moved to AWS.

When I use your binding it sometimes goes online, but never shows values. However, whenever I enable it it makes my other systems go offline, both web and mobile.

I’d like to use OpenHab as I have another application for it, but would need to get past this issue. Or I can fix my c# authentication issue, or I can do both and have my c# program call OpenHab api to get the pool stuff.

Have you seen the issue I am describing before? Any thoughts?

Thanks

Jim

No i have not seen any of those issues.

When I use your binding it sometimes goes online, but never shows values.

If its offline it should say why in the UI, so that would be helpful to report here. When you say never shows “values”, do you have items linked to the pool thing? If the binding comes online it should update any linked things, if it never comes online, then no, there would be no values.

However, whenever I enable it it makes my other systems go offline, both web and mobile.

I just tried this, i am logged in on their mobile app, and i can switch something on in OH, and the mobile app reflects it a few seconds later, so both have valid sessions. It’s possible they try to limit a single session per user, but i have not noticed it.

It would be helpful to have more detailed information like what type of pool system you have, any errors in the log (including increasing the log level to DEBUG and reporting back) and your general item and thing configuration.

Thanks for the quick response. I just enabled it again and it went online for maybe 30 seconds and then switched to Communication Error.

I do have items linked to the things and they did have values while the thing was online. In fact, I turned on the pool pump outside of OH and for the brief period of time it was online, it showed as on in OH.

Once the communication error showed up in OH, my app went offline as well. When I disable the iaqualink thing, the app goes back online after about a minute.

I have a jandy rs-aqualink to which I added an iaqualink 2.0.

The thing is configured as is out of the box. I just entered my credentials.

The items I have added were added from the thing channels.

The error shows as java.io.eofexception sometimes, but most of the time it only shows communication error.

I’ll send debug logs tomorrow.

Thanks again for your attention to this.

1 Like

Here’s the error I am receiving…

08:36:56.526 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing ‘iaqualink:controller:593b174dbc’ changed from UNINITIALIZED (DISABLED) to INITIALIZING
08:37:18.207 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing ‘iaqualink:controller:593b174dbc’ changed from INITIALIZING to OFFLINE (COMMUNICATION_ERROR): java.util.concurrent.ExecutionException: java.io.EOFException: HttpConnectionOverHTTP@126746f1::DecryptedEndPoint@412b84b1{l=/192.168.86.35:61915,r=prod.zodiac-io.com/44.195.149.167:443,OPEN,fill=-,flush=-,to=34920215/0}

As soon as this error triggers, my web and app also go offline. About 60 seconds after disabling the thing, both the web and app go back online.

As update… I created a new UID and pwd and attached my iAqualink to that account. I then changed the uid/pwd in OH thing and it caused a bunch of errors. So I changed it back to the original account UID/pwd and everything worked fine for about 2-1/2 minutes. I was able to change the pump status using OH and the other connections stayed stable.

So, when it’s online, it works great, it just won’t stay online.

Logs:

14:11:43.114 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item ‘iAquaLinkPoolController_PoolPump’ changed from OFF to ON
14:14:17.150 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing ‘iaqualink:controller:593b174dbc’ changed from ONLINE to OFFLINE (COMMUNICATION_ERROR): Service reports controller status as: Offline
14:16:17.963 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item ‘iAquaLinkPoolController_PoolPump’ changed from ON to OFF
14:16:28.465 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing ‘iaqualink:controller:593b174dbc’ changed from OFFLINE (COMMUNICATION_ERROR): Service reports controller status as: Offline to ONLINE
14:16:58.622 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing ‘iaqualink:controller:593b174dbc’ changed from ONLINE to OFFLINE (COMMUNICATION_ERROR): Service reports controller status as: Offline .

You mentioned you have something else you wrote that is using the API, is this also connected and polling at the same time? It does seem like something else is causing the API to reject the API request we send. Can you increase the logging level to DEBUG and post those when it fails? In the OH console the command for this would be:
log:set DEBUG org.openhab.binding.iaqualink

Thanks for the advice. Sorry for the slow response - I was out of town and couldn’t test.

When I tried to set the logging level, I was getting an EOF error in an XML file, so I moved the OH running directory from inside my downloads folder to my Program Files folder. This fixed that error.

I then disabled my C# program but the problem persists. I did let it run for a while and what I found was some interesting timing. It keeps cycling from Offline to ONLINE and back again. It is very consistent in that it goes from On to Off at almost exactly 30 seconds. It then goes from Off to On after almost exactly 2 minutes, 12 seconds.

09:41:06.071 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing ‘iaqualink:controller:593b174dbc’ changed from OFFLINE (COMMUNICATION_ERROR): Service reports controller status as: Offline to ONLINE
09:41:36.200 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing ‘iaqualink:controller:593b174dbc’ changed from ONLINE to OFFLINE (COMMUNICATION_ERROR): Service reports controller status as: Offline
09:43:48.023 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing ‘iaqualink:controller:593b174dbc’ changed from OFFLINE (COMMUNICATION_ERROR): Service reports controller status as: Offline to ONLINE
09:44:18.121 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing ‘iaqualink:controller:593b174dbc’ changed from ONLINE to OFFLINE (COMMUNICATION_ERROR): Service reports controller status as: Offline
09:46:30.382 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing ‘iaqualink:controller:593b174dbc’ changed from OFFLINE (COMMUNICATION_ERROR): Service reports controller status as: Offline to ONLINE
09:47:00.672 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing ‘iaqualink:controller:593b174dbc’ changed from ONLINE to OFFLINE (COMMUNICATION_ERROR): Service reports controller status as: Offline
09:49:12.468 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing ‘iaqualink:controller:593b174dbc’ changed from OFFLINE (COMMUNICATION_ERROR): Service reports controller status as: Offline to ONLINE
09:49:42.742 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing ‘iaqualink:controller:593b174dbc’ changed from ONLINE to OFFLINE (COMMUNICATION_ERROR): Service reports controller status as: Offline
09:51:54.118 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing ‘iaqualink:controller:593b174dbc’ changed from OFFLINE (COMMUNICATION_ERROR): Service reports controller status as: Offline to ONLINE
09:52:24.276 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing ‘iaqualink:controller:593b174dbc’ changed from ONLINE to OFFLINE (COMMUNICATION_ERROR): Service reports controller status as: Offline

Hmm, i’m not sure i know what you mean, is that the log4j config file? What file was giving a EOF?

The log you posted shows only INFO , and is from the event log, can you post the relevant parts from the openhab.log file ? They should be logged at the DEBUG level.

I moved the contents of openhab-3.1.0, which was in my “Program Files” directory to c:\openhab and now everything is working fine. iAqualink stays online and my other connections to my pool stay on line too. Thanks for your help.

Great, glad its working for you.

I now have a new challenge. As I mentioned, I created a C# program to show and control my pool. I have this running on a computer with a touch panel on the wall. It does a lot of other things, which I don’t necessarily want to recreate in OH. I have updated my program to read the pool status using the api and my panel looks like this:

Touching on a button used to call the Jandy api to update the pool. Now touching a button updates the OH database, but the iAqualink binding does not send it on to the pool. Do I need to send a different api call to force your binding to relay the command? Thanks!

What buttons are you referring to? You mean something in the OH UI you have setup? Or do you mean in your own C# app? And what do you mean “updates the OH database”, are you calling the OH API directly or trying to manipulate the OH JSON DB? Just trying to clarify the situation.

If you are trying to use your GUI with openHAB, thats super doable, i just need some more details about how you are going about it (and using the OH api presumably)

How this usually works is Items send commands through a channel to the iAqualink binding which will in turn call the iAqulink cloud API if your pool thing is online (it ignores commands if offline). After sending a command we immediately poll the API for the updated state and use that to update the channel and corresponding item.

Again, setting the log level to DEBUG or even TRACE like log:set DEBUG org.openhab.binding.iaqualink using the OH console ( The Console | openHAB) will log all sorts of stuff out to the openhab.log file and will let you see exactly what the binding is doing if you think there is a communication issue.

Okay, I found my own problem again. I was using PUT on the state, which was doing exactly what it should do, i.e. update the OH database. I changed it to a POST and now it sends the command on to the pool controller through the binding.

Great, glad you found the issue.

Hi Dan
I am new to this community , Learning about pool automation and integration

I wanted to integrate with latest Roboitic Pool cleaner (Zodiac – Polaris / Jandy ) in my mobile application . I believe the devices are supported by iAqualink protocol .

I am interested to use iAqualink protocol to control pool robot and pool control automation in my mobile application developed using C#.NET and Xamarin .

Kindly advise me or share if there is any plugin which can be used in my mobile application in developed in C#.
or What could be best approach to integrate with iAqualink protocol device (Jandy / Polaris ) in mobile application written in Xamarin and C#.NET

Your response would be highly appreciate

Thanks