poolhound

Source

Poolhound is a remote pool management, chemistry tracking and analytics tool for one pool and its spa — one address for the equipment panel, and one record of every reading, every dose and what happened next.

Three pieces: the panel, the Pi and the web server

poolhound in three piecesLeft to right: the Jandy Aqualink panel that runs the pool equipment, wired to a Raspberry Pi in the house, which connects out over the internet to the web server. The Pi sends readings up every fifteen minutes and collects commands back down the same connection. The server never opens a connection toward the house.AT THE HOUSEON THE INTERNETJandy panelruns the pumps,heater, salt celland lightswireRaspberry Pireads the panel andpasses commands to itOUTBOUND ONLYreadingscommandsWeb serverkeeps every readingand serves this sitepoolhound in three piecesTop to bottom: the Jandy Aqualink panel that runs the pool equipment, wired to a Raspberry Pi in the house, which connects out over the internet to the web server. The Pi sends readings up every fifteen minutes and collects commands back down the same connection. The server never opens a connection toward the house.AT THE HOUSEJandy panelruns the pumps,heater, salt celland lightswireRaspberry Pireads the panel andpasses commands to itOUTBOUND ONLYreadingscommandsON THE INTERNETWeb serverkeeps every readingand serves this site
The Pi starts every connection to the server. It sends readings up every fifteen minutes and collects commands on the way back, so nothing on the internet can reach the pool directly. The full picture is further down.

What poolhound is for

Three problems. They belong to the same pool, which is why one tool holds all three — but they are not the same problem, and most of what is written about pools answers only the middle one.

Replace the panel's remote with any browser

The panel is driven by its PDA: one handheld, in one place, and whoever is holding it. Poolhound puts the same circuits and setpoints in any phone or browser, at one address that works from the garden or from another country — no port forwarding, no VPN, nothing to install. The panel itself is never exposed: a sampler on the house network connects outward and waits. It is built on AqualinkD, the open-source project that speaks the panel's undocumented RS485 protocol; poolhound adds the sign-in, the outward connection and the record of what was done.

Dose from what this pool actually does

Every dose is recorded with what happened next, so the advice is fitted to this pool's own response rather than read off a band written for a pool nobody here has seen. Where two labs disagree that is kept as a disagreement, not averaged into a number neither of them reported.

Know how much water there really is

Every dose figure multiplies through the volume, so a guess there is a wrong answer everywhere else. Trace a photograph of the pool or pick a stock shape, and get an uncertainty band instead of one confident number. Pool and spa are measured separately.

Underneath all three is one record: every reading, every dose, and what happened next. The output is a small number of things worth doing, each with an amount, and each traceable back to the measurement that asked for it.

What it reads

Four sources, none of which agrees with the others all the time. Where two instruments disagree that is recorded as a disagreement — it is usually the pool having moved between the two dates — and neither is quietly averaged away or called wrong.

The pool panel

A sampler on a Raspberry Pi reads the controller on the house network and pushes readings outward. Water and air temperature, what is running, what every setpoint is, and the salt cell's output.

A sensor in the water

A floating pod measures free chlorine and pH continuously and posts a water sample away for a full panel every few weeks.

A counter test

Results from carrying a sample in to a pool store, which measures things no daily sensor covers — alkalinity, cyanuric acid, calcium, salt.

What was actually poured in

Every dose, logged with its strength and its amount. This is the half that makes the rest fittable: without knowing what went in, a change in the water is an observation rather than a measurement.

What it looks like

These are a pool that does not exist. Every figure below is rendered from a synthetic dataset by bin/screenshots, so nothing on this page is anybody's real water. The live screens look like this and hold real readings.
The Home screen: two ranked actions, each with the dose it would take, above a row of tiles giving the current value of every measure with its source and its age.
Home What to do next, ordered by consequence rather than by how far a number sits outside its band — and the dose that would do it, computed for this pool's volume rather than read off a chart.
The Pool control screen: one card per circuit showing the panel's last reported state with on and off buttons, and below them a setpoints section with each heater, freeze protection and the salt cell output.
Pool control Every circuit and every setpoint the panel exposes, with what the panel itself last reported beside what it was asked for. A command that has not been confirmed says so.
poolhound local, a dark page on the house network: a grid of circuits, each with its friendly name, the panel's own label beneath it and an on/off switch, with the filter pump, sheer descent and solar heat on.
poolhound local Optional, and installed by nothing here: a page served by the Pi itself, on the house network, talking to AqualinkD directly. It works when the internet does not, and shows poolhound's record of every change at the panel. poolhound runs the same without it; a copy is in deploy/poolhound-local.html.
The Pool chemistry screen: for each factor, what pushes it, how strongly, and what to do about it.
Pool chemistry The reference half — what each measure does, what moves it, and how the six of them pull against each other. Public, because it is the part that is useful to somebody else's pool too.
The Pool Volume Calculator: stock pool shapes to choose from and a tool for tracing a photograph, with the computed volume and its uncertainty band.
Pool Volume Calculator Trace a photograph of a pool, or pick a stock shape. Every dose on every other screen is a volume multiplied by a coefficient, so this is the number the rest of it rests on.
The Ask AI screen: a question box, a note saying exactly what is sent and where, and below it the full context the model receives.
Ask AI The advantage over asking a chatbot is that it is tuned to THIS pool's parameters — its volume, its targets, its actual readings and the doses that have gone in. It answers from the record rather than from pool chemistry in general, and the screen prints everything it sends.
The Collection screen: one card per data source with when it last ran and what it returned, then a table of every attempt.
Collection Every attempt to fetch anything, whether it worked or not — including whether an alarm that was raised actually reached somebody.

What you can use here

Three of these screens need no sign-in, because they are the part that is useful to a pool that is not this one.

  • Pool Volume Calculator — trace a photograph or pick a stock shape, and get a volume with an honest uncertainty band rather than a single confident number.
  • Pool chemistry — what each measure does, what moves it, how far, and why the six of them cannot all be satisfied at once.
  • Guide — how this one is built, down to the wiring and the adapter, if you want to build the same thing.

How it is put together

Five pieces and the direction of every arrow. The one that matters is the arrow out of the house: the equipment panel has no password of its own, so nothing outside opens a connection toward it — the Pi pushes a sample out every fifteen minutes and holds one connection open for commands to come back down.

How the pieces of poolhound connectLeft to right: a Jandy Aqualink panel with an AquaPure salt cell is wired over RS485 to an FTDI USB adapter, which plugs into a Raspberry Pi running AqualinkD and the poolhound agent. The Pi opens both connections to the web server, pushing a sample out every fifteen minutes and holding one open for commands to come back down it; nothing outside the house opens a connection toward the pool. The server runs Caddy, an Entra ID sign-in, the poolhound container and Azure storage. A browser out on the public internet reaches the server, and the server pulls WaterGuru and Leslie's once a day. There is a second route that does not involve the server at all: a browser already on the house network can reach the web interface AqualinkD serves on the Pi and control the panel directly, with no sign-in; the change is recorded only as one the agent saw. The Pi also runs an optional web server of its own, serving the household's pool page: it reaches AqualinkD through /poolapi, and before each command it tells the agent through /poolclaim that the change is its own, and it shows the agent's list of recent activity through /poolactivity. HOW TO READ THE ARROWSreadings, pushed out by the Picommands, collected by the Pirequests, and the daily pullsAT THE POOLAqualink PDA-6+ AquaPure salt cellFILTER PUMPsalt cell · heatersAUX1 pool lightAUX2 sheer descentAUX3 spa lightthe only thing here thatactually controls anythingFTDI USB-RS485two wires, 9600 baudRaspberry Piwrites nothing to its cardaqualinkd.service:8000, open on the house LANno authentication at allpoolhound-agent.servicereads it every fifteen minutesand connects OUT to the serverit checks every command againbefore the panel sees itcaddy :80 · poolhound localthe page at the pool, OPTIONAL/poolapi → aqualinkd/poolclaim → the agent: “mine”/poolactivity ← the agent’s logRS485USBYou, on the house LANaqualinkd’s web UI, or poolhoundlocal on the Pi — straight to thepanel, no sign-in, logged as seen:8000 · no authoutbound only15 mincommandsWeb serverone container behind a reverse proxyCaddy — TLS, and who may do whatEntra ID — sign-in for the private halfpoolhound — the site, API and queueAzure Files + Key Vault — data, secretspublic · private · agent — which one arequest is, is decided at the proxyYou, on the public internetpublic: stats · chemistry · calculatorsigned in: control · doses · settingstwo builds, not one page with tabs hiddenSOMEBODY ELSE'S SERVICEWaterGuru — pod daily + mail-in labin-store bench photometeronce a day from 23:00 UTC, bothkept apart: two labs disagreeing is data
The pair of arrows across the dashed line is the whole design. The Pi pushes a sample out every fifteen minutes and holds one connection open for commands to come back down it; nothing outside the house ever opens a connection toward the pool. The arrow at the top of the pool is the other half of the truth: AqualinkD serves its own web interface on the Pi, so a browser already on the house network controls the panel without poolhound in the path — which is why being on that network is the thing this design treats as privileged.

Python and its standard library, almost entirely. The pages are rendered to static files — this one and a second one with the private screens in it, which is a different file rather than the same page with things hidden. The equipment panel has no authentication of its own, so it is never exposed and never proxied: the sampler on the house network connects outward and waits. The readings live on network storage that outlives the machine serving them.

The long version, including the parts list and the wiring, is on Guide.

Built on AqualinkD, which speaks the panel's undocumented RS485 protocol. Water tests by WaterGuru and Leslie’s. poolhound is open source.

Reading