The box at the top of this section shows what is going on in the house right now: what the panels are making, what we are burning, how warm it is inside and out, the air pressure, and how clean the bedroom air is. It updates every five minutes.
Getting that onto a web page turned out to be less obvious than I expected, and the interesting part is the bit I decided not to do. So here is how it works, in case anyone fancies the same thing. Usual disclaimer: this is how I did it, not how it ought to be done.
The rule: push, never pull
The obvious approach is to let the website ask Home Assistant for the numbers. Don’t. That means either opening a hole in your router or putting a Home Assistant address and an access token into a web page, and anything a web page downloads is public by definition. Home Assistant tokens are not read-only either — they are full admin. Hand one out and you have handed over the house.
So it works the other way round. Home Assistant reaches out every five minutes and posts a handful of numbers to this site. Nothing can reach in. There is no port open, no token in your browser, and if Home Assistant falls over the page just says the readings are unavailable.
The moving parts
- An automation in Home Assistant fires every five minutes, and again whenever it restarts.
- It builds a small lump of JSON — six readings and a couple of extras — and posts it to a little WordPress plugin I had built for the job.
- The plugin checks it, stores it, and the page prints it. That is it.
The page is rendered on the server in PHP. No JavaScript, nothing fetched from anywhere else, and no cookies — which matters, because this site doesn’t set any and I would like to keep it that way.
Keeping it honest
The connection is just HTTPS, which is the actual encryption and is plenty. A few other bits earn their keep:
- A long random token proves the post really came from my house. It lives in a PHP constant rather than the database, so a database dump doesn’t leak it.
- Every payload is stamped with the time. Anything more than ten minutes old is thrown away, so nobody can capture one and replay it later.
- Every number is range-checked. If something claims the lounge is at 9,999 degrees, that reading is dropped and the rest are kept.
- There is a cap on how many posts an hour are accepted.
The point of all that is not that anyone is desperate to know my air pressure. It is that even if the token did get out, the worst anyone could do is post six plausible numbers at me.
What is deliberately missing
No motion sensors, no doors, no locks, no cameras, and nothing about where anybody’s phone is. All of those broadcast “the house is empty right now” to whoever is reading, and that seemed like a poor trade for a bit of novelty on a hobby blog.
Temperature, pressure, solar and power are weather-station stuff. Harmless. Power use at fine resolution does quietly give away when you get up and go to bed, which is why it is an average over five minutes rather than a live trace.
Two things that caught me out
The pressure was wrong. Not broken — just not what anyone expects. My barometers read about 982 hPa, while every forecast says 1013. Neither is lying: we are roughly 250 metres up, and that is simply what the air weighs here. Forecasts quote pressure corrected to sea level. So the push now does that correction, using the altitude and the current outside temperature, and it reads about 1011. Every 10 metres of altitude you get wrong is worth about 1.2 hPa, so it pays to be honest about how high up you are.
Missing is not the same as zero. First version, if the air purifier was switched off, the reading came through as 0 — and 0 on an air quality scale means perfect air. The page was cheerfully reporting pristine conditions whenever the sensor wasn’t looking. It now sends a proper “nothing here” and the page shows a dash. Worth remembering anywhere a real zero is a plausible value.
Dark, or cut off?
Solar output sitting at zero means one of two very different things, and I wanted the page to say which.
If the sun is below the horizon, the panels are asleep and the page says so. If the sun is well up and a clear-sky model reckons they ought to be producing several hundred watts, yet they are producing nothing, then the odds are the EAC have cut us off again — and the page says that instead.
That works because a grid-tied inverter shuts itself down the moment the grid disappears. It has to, so it doesn’t electrocute somebody up a pole. Panels at nothing in good sunshine really is a decent tell. Using the clear-sky model rather than simply asking “is it daytime” is what stops a thoroughly miserable cloudy morning being reported as a power cut.
The one hole in it: if the power cut takes the router out too, nothing gets sent and the page just goes quiet. Which, I suppose, tells you something as well.
The bit I threw away
I had outdoor air quality working and then took it out. The figure came from a forecasting service that models air quality across a grid, and the nearest actual sensor is nowhere near this village. It looked like data but it was really just a nicely formatted guess, and a guess with a number on it is worse than no number at all. The indoor reading comes from a real sensor in the house, so that stayed.
