Speakeasy Growroom
A fully automated grow operation with an AI botanist on staff.
- VIVOSUN GrowHub controller (climate)
- Mac host (vitals pipeline + dashboard)
- VIVOSUN cloud API ingest (migrating from emulator + OCR)
- Claude API
- OBS + Twitch
- Supabase (heartbeat) [planned]
Legal context: operated for personal use, fully compliant with applicable state law. That’s the only line this page spends on it; the rest is about the control system.
The Pitch
Problem. A grow is a continuous control problem. Temperature and humidity drift every hour, and a single bad night (a stuck fan, a missed watering, a heat spike overnight) can set a cycle back weeks. Doing it well by hand means being on call 24/7 for about 10 weeks, which is hard to sustain.
System. The climate control runs on a VIVOSUN GrowHub controller, a commercial grow controller that drives lights, fans, humidifier, and heater to setpoints. The layer on top of it is a Mac host that reads the room’s telemetry, narrates it, and streams it. Today telemetry is pulled by running the VIVOSUN app in an Android emulator, screen-capturing it, and OCR’ing the readings every 30 minutes, a pipeline being retired in favor of a direct pull from the VIVOSUN GrowHub cloud API (see Challenges). On top of that telemetry layer sits an AI botanist: Claude monitors temperature and humidity, writes a plain-language daily growth report against the photo log, and escalates anything off-band. The design principle is graduated autonomy: routine is handled silently, anomalies raise an alert, and anything that changes the plan waits for human sign-off before it touches the room.
Payoff. The grow runs whether or not I’m paying attention, and I find out about problems while they’re still cheap to fix instead of at harvest. Every day there’s a report explaining what changed and why, and the whole thing streams live, so it can be checked in real time.
The Loops
Sensing, reporting, and anomaly detection run with no human in the loop. The one thing the system is not allowed to do on its own is change the plan; that gate is deliberate.
| Cadence | What happens | Automation |
|---|---|---|
| ~30 min | Telemetry sweep — temperature + humidity read from the VIVOSUN feed and pushed to the status store | full |
| daily | Photo log + AI growth report (telemetry + image -> written daily report -> stream overlay) | full |
| daily | Anomaly check — readings compared against target bands; alert fires if off-band | full |
| weekly | Nutrient / environment plan revision drafted by the AI agronomist | human-approve |
AI Architecture
Three named AI roles sit on top of a deterministic control layer:
- monitor
- anomaly-analyst
- daily-reporter
- Monitor. Watches the telemetry stream (temperature + humidity). Its job is cheap and constant: is every reading inside its target band? It holds no opinions; it establishes ground truth and hands anomalies up the chain.
- Anomaly-analyst. Wakes only when the monitor flags an out-of-band reading. It reasons about what kind of problem this is — transient (a door left open) vs. structural (a failing fan) — and decides whether to alert. This is where the judgment is, so it gets the harder model call.
- Daily-reporter. Once per day, takes the photo log plus 24 hours of telemetry and writes the growth report that lands on the Twitch overlay and in the changelog.
Where the human gate sits. The VIVOSUN controller’s climate loop and all three AI roles run autonomously. The single human-approve gate is the weekly plan revision: the system can recommend a nutrient or environment change, but a human approves it before it’s applied. Sensing and reporting ship freely; plan changes wait for a human.
The Flowchart
flowchart TD
subgraph CLIMATE["Climate control"]
CTRL["VIVOSUN GrowHub<br/>controller"]
A["Actuators<br/>lights · fans · humidifier · heater"]
end
CTRL --> A
subgraph HOST["Mac host"]
INGEST["Telemetry ingest<br/>emulator+OCR → VIVOSUN cloud API"]
end
CTRL -->|temp · RH| INGEST
INGEST -->|~30 min| TEL["Telemetry sweep"]
TEL --> STORE[("Status store<br/>Supabase")]
PHOTO["Daily photo log"] --> REPORT["Claude<br/>daily-reporter"]
TEL --> REPORT
REPORT --> OVERLAY["Twitch overlay"]
TEL --> CHECK{"Reading<br/>off-band?"}
CHECK -->|no| STORE
CHECK -->|yes| ANOM["Claude<br/>anomaly-analyst"]
ANOM --> ALERT["Alert to Chris"]
WEEK["Weekly plan revision<br/>drafted by AI"] --> GATE{"Human<br/>approve?"}
GATE -->|approved| CTRL
GATE -->|rejected| WEEK
Challenges & Lessons
- The capture pipeline was the fragile part, not the grow. The hardest reliability problems weren’t about growing; they were the plumbing: the dashboard server, the VIVOSUN-app emulator + OCR job that scrapes the readings, and the OBS scene feeding Twitch. The emulator path is the top source of silent failures. The fix in progress is to retire the emulator + OCR entirely and pull telemetry straight from the VIVOSUN GrowHub cloud API over HTTPS, which also removes the watchdog and the OBS-for-data contention. An automated grow is only as live as its flakiest capture job.
- Not letting the AI drive. The tempting design is to let Claude adjust nutrients automatically. I didn’t. A wrong autonomous nutrient change is irreversible within a cycle, so the plan-revision gate stays human: automate sensing and reporting, gate anything irreversible.
- Pull from the cloud, not the house. Rather than expose the home network to let a hub poll the grow directly, telemetry comes from the VIVOSUN cloud: the Mac host pulls readings, and the public site never has an inbound path to the house.
- What I’d redo. Build the heartbeat emitter first, before the dashboard. Early on, “is it alive?” was answered by looking at the stream, which failed once the stream itself broke.
Live
Live Twitch embed — degrades to the latest timelapse when the stream is offline.
What you see: a live Twitch embed of the room — plants under lights, the current cycle in progress — with a telemetry panel beside it reading the latest heartbeat metrics (days running, cycle day, current temperature + humidity, anomalies caught to date). The most recent AI daily report is shown as an overlay so a visitor can read, in plain language, what the room did today.
What you do: mostly watch. When Twitch is offline, the panel falls back to the latest cycle timelapse rather than going dark, so the page is never blank.
Opsec note: no street-level or location-identifying detail appears in the stream, overlay, or copy.
Changelog & Metrics
Recent activity (newest first — final entries come from CHANGELOG.md)
- 2026-06-13 — Daily grow-check + live Twitch dashboard running; dual-cam capture in progress.
- 2026-06 — Dashboard server migrating to new Mac host; old-Mac emulator + OCR jobs being retired.
- 2025-11 — Grow operation brought online; first automated cycle begins.
Metrics this page surfaces
-
uptime_daysheartbeat - Days running
-
cycle_dayheartbeat - Cycle day
-
alerts_totalheartbeat - Anomalies caught
Roadmap
- Heartbeat from the Mac host — the small remaining task that lights up the live telemetry panel and the homepage status badge.
- Finish the capture migration — complete the move to the new Mac host, switch telemetry to the VIVOSUN cloud API, and retire the legacy emulator/OCR jobs and watchdog for good.
- Dual-cam capture — second camera angle into the stream and timelapse.
- CV growth tracking — daily photos → auto-timelapse per cycle + a growth-rate curve, with the anomaly-analyst flagging growth-rate stalls.
- Cocktail Lab spinoff — extend the Speakeasy brand world: photograph the bar → inventory → guest-aware menu cards.