An AI sprinkler brain that fails back to dumb.
Turfy is a weather-informed, camera-and-sensor irrigation controller — but the clever part isn’t the AI, it’s that it only touches your lawn when it’s provably healthy. It rides alongside a 1990s Rain Bird as a fail-safe sidecar: take authority while the watchdog is fed, and hand control straight back the instant anything goes wrong. In hardware. Because a stuck valve is a flooded yard and a very large water bill.

Safe by construction
Rain Bird keeps authority
The 1990s controller stays wired exactly as it is. Turfy is a sidecar on the station outputs — it never replaces the brain, it borrows it.
A hardware dead-man
A 555 missing-pulse watchdog must be fed by the daemon's own main loop every ~24s. Miss a beat and the transfer relays physically drop.
Fail back to dumb
Power loss, kernel panic, daemon hang, wedged I²C — every failure reverts to the Rain Bird with zero software involved. A stuck valve floods a yard; this can't stick.
A de-energized transfer bank leaves the Rain Bird wired exactlyas it is today. It’s the first line of the acceptance test — proven with a continuity meter before anything is ever powered on.
The transfer-switch architecture
It’s the classic automatic-transfer-switch pattern applied to sprinklers. An SPDT relay per zone: Rain Bird output on NC, Turfy output on NO, valve wire on the common pole. One authority line pulls the whole bank — unpowered, crashed, or watchdog-tripped, the relays drop and the Rain Bird is back in control.
24VAC (Rain Bird VT terminals, shared transformer)
│
┌─────────┴──────────┐
│ fuse 1A + MOV │
┌────────────┐ ┌─────────────┐ │
│ Rain Bird │──▶│ ZONE BANK │◀──┼── MCP23017 (I2C 0x20) ◀── Pi
│ ESP-6Si │ │ (Turfy out) │ │
│ ST1..ST6 │ └──────┬──────┘ │
└─────┬──────┘ │ NO │
│ NC ▼ │
┌──────────────────────────────┐ │
│ TRANSFER BANK 8ch SPDT relay │◀──┴── AUTHORITY line
│ COM ─▶ valve field wires 1..6 │ (Pi GPIO ∧ watchdog)
└──────────────────────────────┘ ▲
555 missing-pulse detector
▲
HEARTBEAT GPIO (daemon-toggled)The one rule that must survive every revision:never run a second 24VAC transformer while the NC path to the Rain Bird exists. Out-of-phase secondaries through the transfer relay = circulating current and dead triacs. Turfy steals 24VAC from the Rain Bird’s own terminals so both controllers switch the same hot leg.
Reverse-engineering the box
Before you can sidecar a sealed 1990s controller, you have to map it. Board by board: what’s the tap point, where does 24VAC come from, and is the fallback actually trustworthy?
The brief
Fully mapped
The tap point
The blobThe safety core
“The heartbeat must prove applicationliveness, not kernel liveness.”So it’s toggled from the daemon main loop — never cron, never hardware PWM. A cron job would keep ticking after a crash and defeat the entire point.
- 1Pi boots. AUTHORITY GPIO defaults pull-down → Rain Bird stays in control regardless of any GPIO chatter.
- 2MCP23017 powers up all-inputs (POR default) → zone relays held off. Defined state, no init race.
- 3turfy.service self-checks (I²C ack, config sane, time synced), starts the heartbeat, then raises AUTHORITY.
- 4Watchdog charges within one timeout; the transfer bank engages and Turfy is driving.
Every way it can fail
| Failure | Result |
|---|---|
| Pi power loss / kernel panic | fails safeHeartbeat stops → watchdog drops → Rain Bird |
| Daemon crash or hang | fails safeSame — the heartbeat is owned by the daemon loop |
| Pi reboot GPIO chatter | fails safeAUTHORITY pull-down + MCP POR = no valve action |
| I²C bus wedge | fails safeDaemon detects NAK → drops AUTHORITY |
| Relay 5V supply dies | fails safeTransfer coils drop → Rain Bird |
| Both controllers fire one zone | fails safeHarmless — shared transformer, same phase |
| Healthy daemon, latched zone | software invariantNot caught by the watchdog → hard-capped by a per-zone max-runtime in the driver layer, plus flow-meter alarm in v0.2 |
Validate each layer
Passive learn
An H11AA1 opto per station output logs when the Rain Bird actually waters. Validates zone mapping and collects a baseline schedule — zero risk, Turfy never asserts.
instrumentationTake authority
Transfer relays + watchdog go live. Turfy replicates the dumb schedule first, proving the fail-safe handover with a meter before anything smart happens.
the sidecarFlow metering
An inline pulse flow meter learns each zone's baseline GPM — the killer feature. Detects stuck valves, broken heads (flow too high) and clogged lines (flow too low), per zone.
closing the loopWeather + vision
ET-based scheduling (Penman-Monteith / Hargreaves) scales runtime to replace the daily deficit, minus rainfall. A cheap camera adds an NDVI-ish turf-stress index on top.
the AI layerTwo stock relay boards, an MCP23017 for defined power-on state, a 555 watchdog, and an H11AA1 sense bank — a parametric schemdraw source renders the four schematic sheets, so a board photo becomes a one-line edit and re-render.