- Joined
- Jul 16, 2009
- Messages
- 10,011
- Reaction score
- 16,703
I built a custom monitoring/control layer for my GHL ProfiLux Ecosystem.
I am going to share the highlights here.
The source is approaching 20,000 lines of code, mostly Python and Javascript.
Given the scope and time spent, I have not made a decision on sharing the source publicly, or at all.
So, this may pop up as a freebie, or may not. I hope that you all understand. But I do want to share what is possible.
I think many of you know how I feel about GHL's dashboard. This project has been started and abandoned several times since 2021, mostly because of the incomplete GHL API creating a loss of interest for the diminished return, and hopes that GHL would eventually realize that 1990 wanted their dashboard back and build a new one.
So, with the recent API release, I picked the project back up.
I'd been through Home Assistant + Grafana + a proper time-series database for this, and honestly, all of it was a mess that never yielded clean results. HA integrations breaking on updates, Grafana and its bugs and rather rigid dashboards, even though they feel flexible at first. The time-series DB (InfluxDB) is bug-riddled, breaking-change garbage. The closest I got was with HA, but the integration eventually caused a real connection churn problem against the ProfiLux. It led to memory exhaustion on the P4, meaning hard boots every few days.
I am going to say this openly, not as an insult, but as an honest assessment. The GHL API is bespoke, finicky, and feels like it should have been abandoned instead of finished. The ProfiLux is genuinely fussy about its one TCP client. Reconnect too often or too aggressively and you're asking for trouble. Stay connected and poll, and you're guaranteed out-of-order responses, but responses aren't tagged to the request. It is, frankly, a mess. It should have been scrapped for a proper RESTful API and/or an MQTT server. I will note on that again in the summary.
Anyway, I scrapped all of it and built this ground-up on a Raspberry Pi with my own custom software stack.
This is the dash (almost complete) that will run on a 14" wall mounted touch kiosk in the office.
Part of the system screen. Stats, error rate, etc for the system and poller service.
Full control of associated services.
All available endpoints are automatically pulled into the app and can be given friendly names
Full debug and diagnostics logging with search for all poller and services.
Part of the config for the 4:3 wall kiosk dashboard. The appliance can server numerous custom responses and fixed ratio dashes.
Bult in code editor with highlighting, auto indent and syntax checking.
Example Alkalinity Drill down and chart
The illumination schedule drill down
Some of the certificate and remote config settings.
I am happy to answer questions but as I mentioned above I am not sure yet if I'll open-source the whole thing or not.
To the note about this API and GHL's options: I have leveraged the API into a workable piece of software, but it didn't have to be this hard. Even if the P4 doesn't have the capacity to house a real RESTful API, I can't fathom why they don't build a small add-on PAB card or PAB appliance that basically does what I just built. And or a less expensive option that streams MQTT. They would get their data off the PAB bus and act as a user-customizable dashboard server or standard MQTT data source. No SaaS or cloud needed.
I am going to share the highlights here.
The source is approaching 20,000 lines of code, mostly Python and Javascript.
Given the scope and time spent, I have not made a decision on sharing the source publicly, or at all.
So, this may pop up as a freebie, or may not. I hope that you all understand. But I do want to share what is possible.
I think many of you know how I feel about GHL's dashboard. This project has been started and abandoned several times since 2021, mostly because of the incomplete GHL API creating a loss of interest for the diminished return, and hopes that GHL would eventually realize that 1990 wanted their dashboard back and build a new one.
So, with the recent API release, I picked the project back up.
I'd been through Home Assistant + Grafana + a proper time-series database for this, and honestly, all of it was a mess that never yielded clean results. HA integrations breaking on updates, Grafana and its bugs and rather rigid dashboards, even though they feel flexible at first. The time-series DB (InfluxDB) is bug-riddled, breaking-change garbage. The closest I got was with HA, but the integration eventually caused a real connection churn problem against the ProfiLux. It led to memory exhaustion on the P4, meaning hard boots every few days.
I am going to say this openly, not as an insult, but as an honest assessment. The GHL API is bespoke, finicky, and feels like it should have been abandoned instead of finished. The ProfiLux is genuinely fussy about its one TCP client. Reconnect too often or too aggressively and you're asking for trouble. Stay connected and poll, and you're guaranteed out-of-order responses, but responses aren't tagged to the request. It is, frankly, a mess. It should have been scrapped for a proper RESTful API and/or an MQTT server. I will note on that again in the summary.
Anyway, I scrapped all of it and built this ground-up on a Raspberry Pi with my own custom software stack.
- Custom poller service
- SQLite instead of a dedicated time-series DB
- Custom configurable dashboard system
- responsive and fixed pages
- kiosk (full screen) modes
- editable html template and css templates
- Full setup menus
- Auth providers and tunneling so no firewall rules needed for remote access
- Back and Restore data and settings
- Panel drill downs for data
- Custom charting tool
- Adjustable warn and alarm thresholds per input/source
- Auto mapping of available GHL sensors, dosers, switches, level sensors, illumination, etc, .
This is the dash (almost complete) that will run on a 14" wall mounted touch kiosk in the office.
GHL gotchas that shaped the design
A few things I only found out by getting burned:- Replies carry zero identifying information.** The protocol's response to a query is just a bare acknowledgement with a value. No sensor ID, no echo of what was asked. The only thing that tells you which reading belongs to which sensor is strict request-then-reply ordering. Get that ordering wrong even once and a reading from one sensor lands in another sensor's slot. So instant data corruption and no easy way to guardrail against it. There is no way to sugar coat it, the API structure is not good.
- The device sometimes sends a duplicate reply to a single command. Undetected, that extra reply shifts everything polled after it out of sync.
- The way to combat items 1 and 2 is to disconnect the socket after each call and then reconnect for the next call. This quickly exhausts resources on the P4 and it must be rebooted to recover from the bad socket state.
Part of the system screen. Stats, error rate, etc for the system and poller service.
Full control of associated services.
The polling layer
The ProfiLux only accepts one connection at a time and it's genuinely picky about it. To work around the bad state caused by excessive connection flap. this runs a single persistent connection. Strict request/reply in order, with a plausibility check on every reading. Example brightness value that suddenly reads 2600% gets caught and thrown out before it ever hits a chart, not trusted as real. Everything gets written to a local SQLite history, polled at different rates depending on what the sensor actually is, and configurable in the settings. The poller is self healing with backoff states, reconnection logic and several watchdog mechanisms.All available endpoints are automatically pulled into the app and can be given friendly names
Full debug and diagnostics logging with search for all poller and services.
Dashboards that are actually configurable
Every tile, chart, and container on the wall-mounted display is built from a shared pool of panel definitions, not hardcoded per screen. Add a sensor once, place it on as many dashboards as you want, each with its own layout. There's a real Setup UI for all of it. It is not drag and drop (maybe one day) and all dashboards have editable HTML/CSS for customization, syntax checking, etc. So there is a code editor built in!Part of the config for the 4:3 wall kiosk dashboard. The appliance can server numerous custom responses and fixed ratio dashes.
Bult in code editor with highlighting, auto indent and syntax checking.
Drill-downs
Tap any tile on the kiosk screen and it opens a full, responsive detail view. A real chart with adjustable time range and bucket size (raw / 5-min / hourly) and smoothing. The illumination schedule: tap the light bar, see the actual programmed curve. Click a sensor and see its charted data with a data table beneath, also with time range and bucket size options.Example Alkalinity Drill down and chart
The illumination schedule drill down
Remote access, without opening my network up
This is the part I think is actually worth mentioning to anyone else doing something similar. Three independent options, pick any combination:- Plain LAN access no cert needed http://
- Old-school port-forward + real cert, upload your own via CSR or use Acme certbot. Caddy handles the reverse proxy and TLS automatically. Set your own ports as needed
- Cloudflare Tunnel - this is the one I actually use. No port forwarding, works fine behind CGNAT or a dynamic IP since there's nothing to forward to! The Pi makes an outbound-only connection to Cloudflare, and my public hostname just rides on top of that. I Added Google login in front of it through Cloudflare Access. Any other provide or method can be added at the Cloudflare node, nothing has to be changed on the appliance.
Some of the certificate and remote config settings.
Backup/restore
Full snapshots. Database, dashboard layouts, systemd services, everything. They scheduled automatically and adjustable, restorable from a browser upload if the SD card ever dies and can be routed to a Google drive.I am happy to answer questions but as I mentioned above I am not sure yet if I'll open-source the whole thing or not.
To the note about this API and GHL's options: I have leveraged the API into a workable piece of software, but it didn't have to be this hard. Even if the P4 doesn't have the capacity to house a real RESTful API, I can't fathom why they don't build a small add-on PAB card or PAB appliance that basically does what I just built. And or a less expensive option that streams MQTT. They would get their data off the PAB bus and act as a user-customizable dashboard server or standard MQTT data source. No SaaS or cloud needed.
