Aqualink PDA automation using RS485

Woot.

I have it working. I'm trying to upload it here but it's too big. efp3, would you mind adding me to your GitHub repo so I can add to it (my GitHub name is johnnytaco)? Or I'm happy to create a new one, but since it's mostly the same code, I thought it would be cool to combine.

I've created a temporary home for the script so you can all try it out. You should be able to access without logging in, if I set it up right. The link is legit!

Download the latest version of aquawebpda.py here: aquawebpda.py - Google Drive

Notes:
  • Debug logging is on, although it's just logging cmds sent to the PDA and button responses back. It goes to both the terminal and aw.log.
  • Assumes your usb/rs485 is at ttyUSB0 and is talking 9600 baud / 8N1
  • The time/air/temp lines are little messed up. the controller sends very weird line numbers for these so I have to catch them and change them. I'll clean this up later.
  • The web interface buttons are still placed where the Aqualink RS remote buttons are. I'll move them around to make sense more like the PDA at some point.
  • It's still laggy due to the way the controller and PDA talk. It should be better than the PDA though, assuming network connectivity to the rpi is good and there's low latency everywhere else.
  • I haven't done any kind of macro work but plan to, along with grabbing the time, air temp, water temp, what equipment is running, and pump RPM/power usage and displaying them differently. Basically I need to capture the text the controller is sending and work on it in the background. Lots of regex in my future. ;)

jt
 
Woot.
I have it working. I'm trying to upload it here but it's too big. efp3, would you mind adding me to your GitHub repo so I can add to it (my GitHub name is johnnytaco)? Or I'm happy to create a new one, but since it's mostly the same code, I thought it would be cool to combine.

Great work!

My condolences on the REGEX work. Can you fork my repo @ GitHub and then submit a pull request? That's the normal way I've seen this done, and it gives you a private git repo as well as tracibility in the final product.

I think the way to make it merge easiest is to pull my latest changes and then subclass the Screen(), replace the writeLine and HTML report section, and update the class global ACK and ID variables. The changes should then be quite small.

Also, for your regexes, I suggest you don't do it in the python script. Let it stay a simple daemon that serves web pages and not too smart for its own good.

A new app w/MQTT interfaces feels like the right spot for this intelligence. There is a CGI to get the raw screen text and to send buttons, use that in whatever language you like to screen-scrape and diddle with buttons. It'll be much easier to update and fix, and you won't be limited to Python. See the embedded javascript to get the simple URLs needed...
 
Last edited:
>My condolences on the REGEX work. Can you fork my repo @ GitHub and then submit a pull request? That's the normal way I've seen this done, and it gives you a private git repo as well as tracibility in the final product.

Absolutely. I've never used Git but it looks pretty straightforward. For some reason I love regex and a good challenge. I've done a lot of perl regex and in other areas so I'm up for the challenge. ;)

>I think the way to make it merge easiest is to pull my latest changes and then subclass the Screen(), replace the writeLine and HTML report section, and update the class global ACK and ID variables. The changes should then be quite small.

I may end up just doing this independently; I'm not a developer by trade (I've done many dev-type projects over the years but more scripting and less OO). Definitely not in an open source /multiple people working on the same code sort of thing. But I'll take a look. I would like to do it right... Open to your assistance if you're up for it. I'm always up for a challenge. But I also have a sprinkler system and alarm system to hack into - they're waiting impatiently for me.

>Also, for your regexes, I suggest you don't do it in the python script. Let it stay a simple daemon that serves web pages and not too smart for its own good.

Good thought. I may just make another script/app altogether, taking the screen part out of your code and doing more regex + macro work to make more of a traditional control system, if that makes sense. Basically on/off stuff using regex/rs485 "line scraping". This is my first foray into Python and it's pretty easy to pick up.

>A new app w/MQTT interfaces feels like the right spot for this intelligence. There is a CGI to get the raw screen text and to send buttons, use that in whatever language you like to screen-scrape and diddle with buttons. It'll be much easier to update and fix, and you won't be limited to Python. See the embedded javascript to get the simple URLs needed...

Now you're moving way out of my experience and comfort zone, especially with message queues (had to google MQTT). ;) Screen/line-scraping is easiest for me in Perl/PHP but figured it wouldn't be rocket science in Python.

I've got aquawebpda.py as a true service now so I can stop/start/restart on a whim and editing the script is super easy.

Thanks for all your input, thoughts, and help on this!! This is my crash course in Python and a fresher in classes / methods / etc which I rarely touch anymore. I've been in management too long. :D

jt
 
Now you're moving way out of my experience and comfort zone, especially with message queues (had to google MQTT). ;) Screen/line-scraping is easiest for me in Perl/PHP but figured it wouldn't be rocket science in Python.

The scraping from the web daemon is very easy with any language that can do HTTP POSTs. The same thing can be used to send a key up/down...

root@pool:~/aquaweb# curl -X POST http://192.168.1.32/screen.cgi -d screen
<pre>JANDY AquaLinkRS

07/24/17 MON
1:11 PM

POOL 85`F
AIR 79`F


<span style="background-color: #FFFF00"><b>EQUIPMENT ON/OFF</b></span>
ONETOUCH ON/OFF
MENU / HELP
</pre>


Since Python isn't your cup of tea, this'll let you work in Java, etc. much easier. When you really get into automation, you'll see why MQTT on this would be a great idea. You'd be able to interface with pretty much any home automation system and not need to do any UI or logic work at all. Check out OpenHab or others and you'll see how powerful it can be. "Turn on the pool cleaner once a week unless the temperature is under 70F, then do it once every 2 weeks" is a couple clicks in a GUI w/these tools.

Feel free to just fork and not send in any PR. I'll monitor your interface changes and patch back in the stuff you find to the main branch. I think right now it's only ~10 lines difference with the proper subclassing/abstraction. Jandy must have reused most of their code in the updated HW.
 
I just committed an update to my main repo with your findings, johnnytaco. So now there's support for all remote styles, including a simple web page (which is great to use on a $5 cellphone in a ziplock as your in-pool remote)! The PDA() class is only 10 lines, of which 3 are comments, thanks to Python subclassing.

Screenshot from 2017-07-24 18-09-01.jpg

If you've got a second, can you re-clone "git clone repo https://github.com/earlephilhower/aquaweb", kill any running daemons you've got, and then run ./aquaweb -p -d /dev/ttyUSB0 and give it a whirl?
 
Awesome. I love that you're re-engaged in this! :)

It works, but it's showing the non-PDA html. Here's what is logging in the terminal:

Creating PDA emulator...
Creating RS485 port...
Creating web server...
Main loop begins...
Started httpserver on port 80
unk: cmd=1b args=0000
unk: cmd=1b args=0100
192.x.x.x - - [25/Jul/2017 03:44:09] Request timed out: timeout('timed out',)
192.x.x.x - - [25/Jul/2017 03:44:16] Request timed out: timeout('timed out',)
192.x.x.x - - [25/Jul/2017 03:49:34] code 404, message File Not Found: /favicon.ico

Those unknown cmds are still unknown to me. Timeouts are due to wireless issues tonight - wondering if my neighbor is up to something. lol... and I've seen that favicon.ico error a few times.

Funny seeing johnnytaco on all the notes. I don't usually go by this... suppose it's time to go with my real name or initials one of these days. ;)
 

Enjoying this content?

Support TFP with a donation.

Give Support
Awesome. I love that you're re-engaged in this! :)
It works, but it's showing the non-PDA html. Here's what is logging in the terminal:

Creating PDA emulator...
Creating RS485 port...
Creating web server...
Main loop begins...
Started httpserver on port 80
unk: cmd=1b args=0000
unk: cmd=1b args=0100
192.x.x.x - - [25/Jul/2017 03:44:09] Request timed out: timeout('timed out',)
192.x.x.x - - [25/Jul/2017 03:44:16] Request timed out: timeout('timed out',)
192.x.x.x - - [25/Jul/2017 03:49:34] code 404, message File Not Found: /favicon.ico

Those unknown cmds are still unknown to me. Timeouts are due to wireless issues tonight - wondering if my neighbor is up to something. lol... and I've seen that favicon.ico error a few times.

Funny seeing johnnytaco on all the notes. I don't usually go by this... suppose it's time to go with my real name or initials one of these days. ;)

Oops. I set the INDEX.HTML file properly in line 1 of the PDA class. Then, in line 2, I called the base class constructor (squarepda) to get everything else working. And it promptly overwrote the INDEX.HTML file I'd just set. Sorry!

I've pushed a fixed version to the repository, where I set the HTML file *after* calling the base constructor. I also added a silly 16x16 favicon.ico file (it's the little picture in the web browser tab) to the server so your other error won't appear.

As for the unknown commands, sorry but I don't see them on the older model. If all seems to be working, I wouldn't sweat it as you can now screen scrape and run through menus in any language you want...*that's* probably going to be harder to get right than this little glass TTY! :) If they're periodic, do they correspond to something blinking (led on the display? colon on the time?)?
 
I looked briefly and figured it was something with INDEXHTML but wasn't sure and was already off on my regex project (which I'm going to do in Python for now). I'll test your new version here in a bit.

Agreed, don't know what the unknown commands are and it doesn't seem to matter. There's no blinking ... The emulated PDA screen looks just like the real one. It gets very interesting when the wife pulls out the PDA and turns on the cleaner while I'm testing the python script. LOL... all kinds of conflicts, bad checksums, out of whack acks, etc.

I've been ignoring the actual pool and let it get to 0 chlorine. Good thing I've got everything else in check, no signs of algae yet. ha.

jt
 
Gentlemen! I salute you, my comrades in hacking! I'm so excited! Here is my working web-based PDA.

Screen Shot on 2017-07-25 at 08:59:15.png Droplr

This is awesome. We had lost power and without the remote my pool's program was running at weird times. I was finally able to fix the date/time.

For those following along if you had trouble running the program the actual command I had used to get it running was:
Code:
sudo python aquaweb.py -p -d /dev/ttyUSB0 &

This runs the program in the background. You can cntrl-C out of it and it will continue to run.

My next questions which are more specific to my situation, but for which I'd welcome ideas/suggestions:

- How can I power the raspberry pi? I would prefer to do so from the board so I don't need to keep the pi plugged into an outside outlet. I seem to recall someone in the older thread saying that pins 1 and 4 corresponded to power. But I'm not quite sure what I need to hook that up. Any ideas?
- As johnnytaco had mentioned I need an external box to house the pi and its rs485 adaptor. Can't just leave it in the metal box or that'll interfere with wifi. If it weren't for the usb-rs485 dongle I think it'd all fit into the JBOX housing if I gutted it. Maybe there's a smaller rs485 module compatible with the zerow that would make it small enough to fit. I'll look around. But I'd welcome suggestions for a weather-proof box as well. I don't even know where to look for such a thing.

Possible next steps for the project in general;

- Improve the screens, give it a more natural mobile view.
- Extend aquaweb to a REST-API to allow a native app to communicate
 
Gentlemen! I salute you, my comrades in hacking! I'm so excited! Here is my working web-based PDA.This is awesome. We had lost power and without the remote my pool's program was running at weird times. I was finally able to fix the date/time.

AWESOME NEWS! I can't believe you survived this long with no way to program the system (or do anything with it outside of the control panel)! Very cool that you don't have to spend $300 on a new crappy remote or $500+ for the iaqualink upgrade.

This runs the program in the background. You can cntrl-C out of it and it will continue to run.

I was having the ctrl-c problem with it still running in the background. Two ways to fix:
Code:
sudo pkill -f aquaweb
or do what I did and make it a service. If using raspbian, refer to this: How to run a script as a service in Raspberry Pi Food Concerns. Works great and now I can start/stop it on a whim (makes for easy code edits and restarts).

How can I power the raspberry pi? I would prefer to do so from the board so I don't need to keep the pi plugged into an outside outlet. I seem to recall someone in the older thread saying that pins 1 and 4 corresponded to power. But I'm not quite sure what I need to hook that up. Any ideas?
- As johnnytaco had mentioned I need an external box to house the pi and its rs485 adaptor. Can't just leave it in the metal box or that'll interfere with wifi. If it weren't for the usb-rs485 dongle I think it'd all fit into the JBOX housing if I gutted it. Maybe there's a smaller rs485 module compatible with the zerow that would make it small enough to fit. I'll look around. But I'd welcome suggestions for a weather-proof box as well. I don't even know where to look for such a thing.

I think I'm going to move the rpi inside the house and run an ethernet cable (as a serial cable) from the power center box to inside where the rpi (or computer) is. I continue to have wifi issues (unless it's actually power issues, now I'm not sure) and now I'm wondering if there are heat issues. The rpi is baking inside the power center metal box. As for power, I've just routed a thick USB cable out of the box to where I have a sealed outlet below and into a 2.1a adapter. It's not perfect but works for now. And I have the wifi dongle on a USB extension cable duct taped (LOL) to my brick about 3' above the power center box.

Possible next steps for the project in general;

- Improve the screens, give it a more natural mobile view.
- Extend aquaweb to a REST-API to allow a native app to communicate

Agreed on both. I hadn't thought about REST-API but that's a good idea. I'm working on regex'ing all the text coming from the master then I'll work on some logic/flow to "macrotize" a few things. It will involve programming a series of events like down, down, down, enter, down, down, enter, wait for confirmation, then print something, or something like that. Once I figure out the logic, we should be able to plug that into any kind of system. I've only just started this but I don't think it will take me long. I really hate the lag with screen printing due to the send button, wait for ack, then display issue.

jt
 
Howdy, great to hear.

Keep the RPI out of the JANDY box and on a separate electrical circuit if at all possible. I've got a 50A line to my setup, and when the pump kicks on the voltage still droops enough to cause trouble w/the RPI. I'm running wired ethernet, but I imagine a metal box would also be bad for WiFi connectivity, too. Under no circumstances should the RPI go anywhere near the hi-voltage section w/relays on the lower bit of the box.

What I've been doing is using an external, waterproof PVC junction box. $15 at the Home Depot or Lowes. Screwed to the house and plugged in to a USB power adapter in an external (GFCI and in-use cover, of course) outlet. I've installed a RJ45 jack for the RS485 and run cable from the remote housing to the RPI adaptor. It *should* be in PVC or using a direct-bury cabling for this, but in my case I don't have to worry about extreme temps or weather so I'm just running cable on the ground. Worked like a champ for 2 years, then the rpi SD card died and I needed to replace it....luckily I had my code in GitHub! When the cable dies, it's about 2 minutes and $0.30 for me to make a new one and install it into the jacks...

For the UI, yes it stinks. But it's my only working pool remote and I'm using burner $10 Android phones (in a Ziploc == waterproof!) to control things remotely, so simple is good. The way the app is architected, you should be able to make a real web page w/HTML, GIFs, and Javascript, and serve it via Apache from the RPI, and then your webpage's Javascript will just use AJAX to get the screen and send button commands. I didn't want to make it too complicated or require add'l programs of files, so I've packed everything into one .PY file for my own sanity.

And it already does have a REST API. :) That's how the screen is updated and buttons pressed from the HTML. Next step looks like jt's going to be doing serious regex (although I think a brute-force, no regex way would be simpler and faster to get it done) to give it real command capability.
 
Next step looks like jt's going to be doing serious regex (although I think a brute-force, no regex way would be simpler and faster to get it done) to give it real command capability.

I'm thinking regex is required so I can confirm commands. Example, turning on the filter pump is as "simple" as navigating to "POOL MODE" and hitting select, but the only way to really know it's on is to regex/scrape for "POOL MODE ON" or on the other page that cycles equipment on, "FILTER PUMP". I think it'll be a two-pronged approach - brute-force, ie move-ack-move-ack-move-ack-move-ack-select-act, then confirm with a screen scrape before updating on the web interface. Can't think of a better way to do it that I'd trust. I need to scrape anyway for air and water temp along with variable speed pump RPM/wattage. Sure would be nice to be able to send actual commands and not a series of button pushes!

I'll get some basic things going then stick them in GitHub (thanks efp3) and get everyone's take on them. Will probably lean on efp3 to make it all purty. ;)

On a separate note... if I'm going to run Ethernet outside, I might as well use that (or a lower gauge wire) for serial and keep the rpi inside where it's much less likely to die from the Texas heat. Currently not only is it using the same circuit as the pump, but it is literally shoved in the box near all the hot wires and relays. ;) I'm mistreating the rpi for sure!

jt
 
Ah, good point, I see you're in REGEX purgatory no matter what. However, if you have a SpaLink option enabled (maybe just a DIP setting) they each have up to 8 buttons which can be programmed to do one thing w/no effort or scraping required since aquaweb can emulate the spalink as wekk.

I hear Texas gets lots of lightning storms. Long cable runs into the house should probably have lightning arrestors/snubbers on them just in case. You should check local codes and see what your telephone and cable drops come in through to be safe...
 
I'm assuming my Aqualink PDA system doesn't have SpaLink but I'll check. I only have the PDA and the buttons on the actual power center/main board. No other devices/wall panels/etc.

Yes, we get lightning. If I really want to get crazy, I'll drill a hole in the brick and run the wire behind the brick. Sounds like h*ll running that cable... But that would be a pretty amazing feat. Hmmmm.
 
I've got all the regex done to get and set global variables with: pool mode, spa mode, heater, air temp, water temp, pump rpm, pump watts. Here's an example from my logging where I had the pump on (pool mode) along with the heater:

Code:
poolmode=1 spamode=0 heater=1 pump=1 pumprpm=3000 pumpwatts=1513 air=87 water=89

Here's one of the hairier regex searches with temps, grabs #s from a string like this: " 86` 88`":

Code:
# get temps - first is air, second is water (only shows water temp if pump is running)

searchObj = re.search("^\s*(\d+)`\s+((\d+)`|)",text)
if searchObj:
        if searchObj.group(1): tempair = searchObj.group(1)
        if searchObj.group(3):
              tempwater =  searchObj.group(3)
        else:
              tempwater = 0


Now I just need to figure out how to display them in the web interface. I'd really like to have toggle buttons that both show and change the status, along with an area just for stats.

Next up, I'd like to try to playback a sequence of buttons. I started looking at how to do that in the existing aquaweb code, but I don't think it will work as is. For example, to turn my light on without one of the custom buttons (thus going through the menus), I have to press:

back 4 (worse case I'm 4 menus in, this will ensure I'm back at the main menu at the top)
up 1 (goes to equip on/off)
select (selects equip on/off)
down 6 (goes to pool light)
select (selects pool light, turns on)
back 2 (back to the main screen, then again to go to the top)

I'd have to simulate button presses/keys, wait for the appropriate ack, then go to the next key. The problem is the PDA/controller are very chatty - the controller likes to send updates like what equipment is on, pump info, etc. So getting the keys sent / queued and getting the right acks back will probably be tricky.

EFP3 - before I rack my brain trying to figure out how best to do it with your code, any thoughts on how to achieve this and other macros? If I can stay within python / your code, I'd be up for that.
 

Enjoying this content?

Support TFP with a donation.

Give Support
Thread Status
Hello , This thread has been inactive for over 60 days. New postings here are unlikely to be seen or responded to by other members. For better visibility, consider Starting A New Thread.