System · The smallholding in Vevring
The greenhouse
In production
The tunnel measures itself and decides on its own when to open the roof. The panel below reads the latest snapshot. It is not a picture, and it is not written in advance.
Facts
- Status
- In production
- Stack
- Homey · Python · PyRunner DataStore · Next.js 15
- Cadence
- Snapshot every fifteen minutes
- Sensors
- Weather station, four tunnel probes, soil, roof window, fan
- Secrets
- Only in the scheduled job, never in the website
- Proof
- The panel below, with a timestamp
Live from the smallholding
The greenhouse right now
Sensors in the polytunnel report to a Homey at home in Vevring. A scheduled job reads them every fifteen minutes and pushes a snapshot here. Nothing below is written in advance. The system opens the roof and starts the fan, not me.
The problem
A polytunnel on the west coast swings fast. Sun through plastic takes it from twelve degrees to near thirty in under an hour, and there is nobody home to open the roof in the middle of the day. So the tunnel had to do it itself.
That part is straightforward enough. The hard part was showing that it does, without making the website depend on the farm being online.
Why the job pushes instead of the site pulling
The obvious build has the website ask the Homey directly. That build puts a home-automation token on a public web server and makes every visitor wait for my home network to answer.
Instead a scheduled job reads the sensors every fifteen minutes and writes a small snapshot to a datastore. The website only ever reads that snapshot. The token never exists outside the job, and a router rebooting produces an old reading rather than an error.
It is the same move as the NDA signing: put the keys where the job runs, never where the public lands.
The sensors lie, so the code assumes it
Four probes measure inside the tunnel and they disagree. One says 19 degrees, another says 26. Three of them are cheap Sonoff units reporting one percent battery, and have been for a while.
So the job walks a preference list and takes the first reading that is physically plausible, rather than trusting one named probe. Values outside sane bounds are discarded. If one field is missing, that field stays blank in the panel and the rest renders normally.
If none of them produce a usable temperature, the job writes nothing at all. The previous reading then ages and labels itself as old, which is more honest than an empty panel that looks confident.
What happens when something fails
The panel has four states and three of them are failure states. A fresh reading shows the figures with a timestamp. Older than ninety minutes says so outright and shows the last known values. If the site cannot reach the source, it says that. If no source is configured at all, the panel renders nothing, because then there is nothing honest to show.
The call to the datastore gets two and a half seconds and is shared by every visitor for a minute at a time, so traffic to the front page never becomes traffic to the farm.
What this is not
It is one greenhouse. No multi-user, no history in the panel, no alerting. The measurement history exists in Homey, but at least one probe has a log that disagrees with its own live value, and that is not worked out yet. So the panel shows a snapshot rather than a curve.
The fan and the roof window are driven by rules in Homey, not by anything I wrote. What is interesting here is the data path and the failure handling, not the climate control.