Farm automation & remote access
Controlling a water pump, a solar inverter and a chicken farm — where a wrong decision doesn't mean a failed request, it means a burnt-out pump or a house with no power.
Two failure modes that shaped everything
Running the pump dry destroys it. If the well is low or a valve is shut, the motor keeps spinning against nothing and cooks itself in minutes.
Putting the pump on inverter power on a cloudy day blacks out the house. The pump's starting current is more than the battery can sustain without solar topping it up, so the inverter overloads and shuts down its entire output — not just the pump, but everything else on that bus, including, if you're careless about wiring, the automation that's supposed to notice and recover.
Both of those are physical, expensive and fast. Neither can be allowed to depend on a server being reachable.
The core principle: safety lives in the firmware
Every protection is enforced on the microcontroller itself — not in the cloud, not in the app, not even in the local hub. The server can be off, the broker can be down, the Wi-Fi can be dead, and the pump still shuts itself off when it should.
What that means concretely, in the pump controller firmware:
- Dry-run cutoff — if measured current stays below the floor for 10 seconds, the relay opens and the node latches a fault that requires an explicit clear command. It will not quietly retry.
- Hard maximum runtime — a run-for timer counted down by the node, so a lost connection can never leave the pump running.
- Minimum rest window — a new "on" command inside the cooldown is actively refused with a reason, not silently ignored.
- Boot off, and retained commands never replayed — a power cut can't bring the pump back mid-cycle from a stale message sitting on the broker.
- A physical button that works with everything else dead.
A tank interlock with no hub in the middle
The pump node subscribes directly to the water tank sensor's telemetry topic on the local broker and stops itself at 95% full. There is no rule, no server and no hub in that path — two devices agreeing between themselves, which is one fewer thing that has to be alive for the tank not to overflow.
Break-before-make power transfer
A single ESP32 hosts two logical devices: a power monitor reading grid and inverter output through two energy meters, and the transfer switch itself. Changeover always opens both contactors, waits out a dead time, then closes the target — never both at once. A command arriving mid-sequence is rejected with an explicit "interlock wait" rather than queued. And the real guarantee isn't the code at all: the contactors are mechanically interlocked, so the firmware can only ever request a state the hardware permits.
Deciding when solar is safe: the Power Advisor
Rather than switching to inverter power whenever the sun is out, the server computes whether there is genuine headroom: sun elevation from an astronomical calculation, cloud cover from a weather API, the inverter's measured current load, and the pump's expected draw learned from its own history. It only suggests inverter power if the projected total stays under 75% of the inverter's continuous rating, and it degrades gracefully to elevation-and-battery reasoning when the weather API is unreachable.
Crucially, it suggests — it does not switch. A missed suggestion costs a manual tap. A wrong automatic switch costs the whole inverter bus.
The farm rules
Climate control for the chicken farm is expressed as a rule that runs on the local Raspberry Pi, not the server: if inverter-room temperature stays above 30 °C for two minutes, turn on the exhaust fan and the cooler fan, run the mist pump for thirty minutes, and notify the admins — then reset when it drops below 28 °C for two minutes, with a cooldown so it can't oscillate. Eight more rules ship alongside it, covering feeder top-up, leak detection, boundary motion, night lights and an inverter-tripped failsafe.
Cameras: remote viewing with nothing exposed
The requirement was to watch the gate, the farm and the pump house from another country, without a vendor cloud subscription and without forwarding a single port to the internet. The design routes camera streams through a media server that is reachable only across a private WireGuard tunnel — the cameras themselves sit on an isolated network segment and are never addressable from outside.
This part is configured but not yet switched on: the stream definitions and the compose service exist behind a feature profile, with a written warning about binding those ports to the VPN interface rather than the public one. It goes live with the camera installation.
Stack
Status, honestly
Nine firmware projects are written and compile — the pump controller uses about 74% of the ESP32's flash — and the control paths are proven against a bench board and the live server. What remains is physical: mounting the sensors, wiring the contactors (a licensed electrician handles the panel work), and commissioning each node in place. Until a node is on the wall, I describe it as built, not deployed.