AdaptiveMind · Studio · Singh
AdaptiveMind/Systems/Mushroom Ki Mandi
Live · Production·IoT + Agriculture·
MMXXVI

Published April 2026 · Last verified April 2026

Mushroom Ki Mandi.

Climate IoT + marketplace for mushroom farms. Closed-loop control from sensor to relay to harvest — no human in the loop for the easy 99%.

Closed-loop control

7

Relay channels

CLIMATE IOT / 001REC ●MUSHROOM KI MANDI · LIVE GROW ROOM
CLIMATE IOT · MUSHROOM GROW-ROOMLIVE · CLOSED LOOPADMIN · DASHBOARDESP32SENSOR · NODECONTROLLERTEMP21°CRH88%CO₂1180GROW ROOM · STAGE · FRUITINGDISTRIBUTION · MARKETPLACE

[ A ] · The problem

Mushroom farming is climate-critical and labor-intensive.

A commercial mushroom farm runs 10-50 grow rooms, each requiring precise control of temperature, humidity, and CO2. During fruiting, a 2°C drift or a 200 ppm CO2 spike can ruin a batch worth thousands of dollars. Most farms rely on manual monitoring: workers walk the rooms with handheld meters, write readings in logbooks, and toggle fans and humidifiers by hand. The lag between a problem and a fix is often hours — long enough for the crop to degrade.

Existing IoT solutions are either too expensive for small farms (industrial SCADA systems) or too fragmented (consumer sensors with no automation). The grower ends up with a dashboard full of charts but no closed-loop control. The gap between sensing and acting is where crop loss happens.

Mushroom Ki Mandi was built to close that loop. A single ESP32 per room reads four sensor types, drives seven relays, and sends telemetry every 30 seconds. The backend evaluates thresholds, schedules, and growth-stage guidelines, then sends commands back to the device. The grower intervenes only for the hard 1% — the rest is automated.

[ B ] · The argument

Sensing without acting is telemetry theater. The relay is the point.

A climate sensor that only logs data to a chart is a thermometer with WiFi. The value is in the closed loop: sensor reads → threshold evaluation → relay command → device ack → dashboard confirmation. Every step is observable, every command is confirmed, every state change is auditable. The grower does not trust the system because the UI is pretty; they trust it because they can see the relay ACK arrive within seconds of a threshold breach.

[ C ] · Architecture

One device per room. One backend per farm. Eight layers.

Each layer is a contract — defined, versioned, tested. The firmware knows nothing about the dashboard. The dashboard knows nothing about the MQTT broker. The backend is the only component that touches all three.

L/01

Edge device

ESP32 WROOM · 7 relays · 4 sensor types · captive portal · OTA · dual-mode HTTP/MQTT

L/02

Telemetry bus

MQTT 5.0 · aiomqtt · HiveMQ Cloud TLS · NaN/inf sanitization · auto-reconnect

L/03

Control plane

FastAPI 0.115 · 20 API modules · async SQLAlchemy 2.0 · Alembic · request-id tracing

L/04

Persistence

PostgreSQL · 16 models · Redis hot cache · 120s TTL · WebSocket broadcast · audit log

L/05

Automation

3 relay modes · 6 growth stages · climate guidelines · threshold sync · schedule engine

L/06

Dashboard

React 19 · Vite · Tailwind · shadcn/ui · Recharts · QR linking · real-time gauges

L/07

Auth

JWT + bcrypt · refresh rotation · login lockout · device license keys · role-based access

L/08

Test + deploy

pytest · vitest · PlatformIO compile · GitHub Actions · Railway · Vercel · test-gated

[ D ] · The numbers

Backend LOC

10,172

Python · FastAPI · async

API modules

20

REST + WebSocket + MQTT auth

Frontend files

131

React 19 · Vite · Tailwind

Relay channels

7

GPIO 16,23,4,13,14,27,25

Sensor types

4

SCD41 · DS18B20x2 · DHT11

Growth stages

6

Inoculation to harvest

[ E ] · The grow cycle

Six stages. One climate contract per stage.

Each growth stage has temperature, humidity, and CO2 targets defined in the climate_guidelines table. On stage advance, thresholds auto-update and sync to the device.

S/01

INOCULATION — Substrate preparation

Spawn is introduced to sterilized substrate. Target temp 20-24°C, humidity 60-70%. CO2 not critical. Duration 2-3 days. The system monitors bag temperatures via DS18B20 and flags deviations above 25°C.

S/02

SPAWN RUN — Mycelium colonization

Mycelium spreads through the substrate. Target temp 24-28°C, humidity 80-85%, CO2 ≤5000 ppm. Duration 14-21 days. This is the longest stage. The AUTO relay mode maintains thresholds; schedule mode runs humidifier cycles during peak colonization.

S/03

INCUBATION — Consolidation

Substrate fully colonized. Target temp 20-24°C, humidity 85-90%, CO2 ≤2000 ppm. Duration 7-14 days. The system reduces CO2 setpoints and increases humidity. Climate guidelines for the plant type auto-apply on stage advance.

S/04

FRUITING — Pinning and development

Mushrooms emerge. Target temp 13-18°C, humidity 85-95%, CO2 400-1000 ppm. Duration 5-10 days. The most climate-sensitive stage. The SCD41 sensor drives precise CO2 control via relay automation. Bag temperatures are logged every 30 seconds.

S/05

HARVEST — Collection

Mature mushrooms are picked. Target temp 15-20°C, humidity 70-80%. CO2 not critical. Duration 1-3 days. The grower logs harvest weight and quality via the dashboard. The system generates a harvest report linked to the growth cycle.

S/06

IDLE — Room reset

Post-harvest cleaning and substrate removal. The room is marked idle until the next cycle begins. Device readings continue for environmental monitoring, but relay automation is paused.

[ F ] · Operations

What the grower actually touches.

Automation handles the easy 99%. The hard 1% — the unexpected sensor fault, the manual harvest entry, the firmware rollback — is where the system earns its keep.

O/01

Room monitoring

A grower opens the dashboard and sees live CO2, temperature, humidity, and bag temperatures for every room. Gauges update in real time via WebSocket. Historical charts show 24-hour, 7-day, and 30-day trends. Alerts fire when any sensor exceeds its threshold.

O/02

Device provisioning

A new ESP32 is powered on. It starts a captive portal. The grower connects via phone, enters WiFi credentials, and inputs the license key from the device packaging. The device registers with the backend, receives MQTT credentials, and switches to MQTT runtime mode. QR code linking binds the device to the grower's account.

O/03

Growth cycle management

The grower creates a growth cycle for a room, selecting mushroom type (oyster, button, shiitake, mixed). The system auto-applies climate guidelines for the current stage. On stage advance, thresholds update and sync to the device via MQTT. Harvests are logged with weight and quality ratings.

O/04

Relay control

The grower toggles relays manually, sets AUTO thresholds, or creates time-based schedules. Commands are sent via MQTT with QoS 1. The device applies the command and sends a relay_ack back to the backend. The dashboard shows the confirmed state, not just the commanded state.

[ G ] · Under the hood

What’s actually deployed in the field.

Every layer below traces back to a real source path, a real line count, or a real deployment config. No aspirational names. What isn’t built yet sits in the Roadmap section.

S/01

Firmware

ESP32 WROOM · Arduino C++ · PlatformIO

Edge controller + sensor hub

Custom PCB with ESP32 WROOM DevKit V1. Reads SCD41 (CO2, room temp, humidity via I2C), two DS18B20 1-Wire buses (bag temperatures), and DHT11 (outdoor ambient). Drives 7 relays for CO2, humidity, temperature (AC), AHU, humidifier, duct fan, and extra load. 20x4 LCD with joystick menu. Captive portal for WiFi provisioning.

Engineering twist

Dual-mode runtime: HTTP bootstrap mode for initial provisioning and MQTT runtime mode for production telemetry. The firmware polls a provision endpoint after every sensor POST to receive MQTT credentials, then switches modes without a reboot. Config version detection (currently v7) auto-resets EEPROM on layout changes while preserving WiFi credentials and license keys.

S/02

OTA

AsyncElegantOTA · dual-partition rollback · SHA-256

Over-the-air firmware updates

Each device exposes an OTA web interface on port 80 via AsyncElegantOTA. Updates are uploaded as compiled binaries. The ESP-IDF dual-partition scheme (two 1.875MB app slots + SPIFFS) ensures a failed update rolls back automatically. After a successful boot, the firmware marks the new partition valid via esp_ota_mark_app_valid_cancel_rollback().

Engineering twist

OTA boot validation is automatic — if the device crashes within 60 seconds of an update, the bootloader reverts to the previous partition. No human intervention, no bricked devices in the field. Firmware version 4.0.0 is the current stable release.

S/03

Backend

FastAPI 0.115 · SQLAlchemy 2.0 · asyncpg · Alembic

Async control plane

FastAPI on Python 3.11 with full async SQLAlchemy 2.0 and asyncpg for PostgreSQL. 20 API route modules covering auth, owners, users, plants, rooms, devices, thresholds, alerts, reports, live data, dashboard, readings, WebSocket, EMQX auth, firmware OTA, harvests, growth cycles, climate advisory, and contact inquiries. Alembic manages 10 schema migrations.

Engineering twist

Production guard: the app refuses to start with default JWT_SECRET or DEVICE_ENCRYPTION_KEY. RequestIdMiddleware injects correlation IDs. MetricsMiddleware records fire-and-forget metrics even if Redis is down. Rate limiting is Redis-backed with graceful fallback to unlimited when Redis is unavailable.

S/04

Database

PostgreSQL · 16 models · hot/cold architecture

Structured persistence

16 SQLAlchemy declarative models: users, owners, plants, rooms, devices, thresholds, alerts, reports, room readings, relay configs, relay schedules, relay statuses, growth cycles, harvests, climate guidelines, firmware files, and audit logs. Indexed on license_key, mac_address, room_id, and plant_id for query performance.

Engineering twist

Hot/cold split: live sensor data is cached in Redis with 120-second TTL for dashboard gauges. Historical data is persisted to PostgreSQL for charts, reports, and audit trails. The reading_service processes a telemetry payload in a single transaction: update device status, write to Redis, persist to room_readings, push to WebSocket subscribers.

S/05

MQTT

aiomqtt · HiveMQ Cloud (TLS 8883) · EMQX local

Device telemetry bus

MQTT 5.0 via aiomqtt. The backend subscribes to device/{key}/telemetry, device/{key}/status, and device/{key}/relay_ack. Publishes to device/{key}/commands (relay control), device/{key}/config (threshold updates), and device/{key}/control (kill-switch). Production uses HiveMQ Cloud with TLS on port 8883. Local dev uses Docker EMQX on port 1883.

Engineering twist

NaN/inf sanitization: the MQTT handler replaces ':nan', ':-nan', ':inf', and ':-inf' with null before JSON parsing. This prevents a single failed sensor read from crashing the telemetry pipeline. The handler also guards against unknown devices and missing payloads with structured logging.

S/06

Real-time

WebSocket · Redis pub/sub · live relay state

Dashboard push layer

WebSocket endpoint at /ws for real-time dashboard updates. On every telemetry message, the reading_service pushes live readings to Redis and broadcasts to WebSocket subscribers. Relay ACKs from devices update Redis live relay state and trigger WebSocket notifications so the dashboard shows confirmed states, not commanded states.

Engineering twist

The WebSocket manager broadcasts per-owner, not globally — a grower only receives updates for their own plants and rooms. This is enforced at the database level via ownership joins and at the WebSocket level via owner_id filtering. No cross-tenant data leakage by design.

S/07

Frontend

React 19 · Vite · Tailwind CSS · shadcn/ui · Recharts

Grower dashboard + marketplace

React 19.2 with Vite, Tailwind CSS 3.4, and shadcn/ui component system. 131 source files including 30+ custom UI components, 7 card types, 3 gauge types, and a full layout system with sidebar + top bar. Recharts powers historical climate charts. react-router-dom handles client-side routing. GSAP for animations.

Engineering twist

QR-code device linking: growers scan a device QR code to link it to their account. The frontend generates QR codes via qrcode.react and reads them via html5-qrcode. ESP32 firmware flashing is supported via esptool-js in the browser for direct-to-device provisioning without a desktop tool.

S/08

Auth

JWT · bcrypt · refresh-token rotation · login lockout

Multi-role access control

JWT access tokens (15-minute expiry) and refresh tokens (7-day expiry) with python-jose and passlib bcrypt. Refresh tokens are rotated on every use — old tokens are invalidated. Login lockout after 5 failed attempts for 15 minutes. Role-based access: super_admin, admin, owner, manager, operator, viewer.

Engineering twist

Device auth is separate from user auth: devices authenticate via X-Device-ID and X-Device-Key headers on every HTTP request. The device key is a license key (LIC-XXXX-YYYY-ZZZZ format) checked against the database every 30 minutes. Expired subscriptions disable the device at the firmware level — the device halts with 'DEVICE KEY INVALID' on the LCD.

S/09

Automation

3 relay modes · growth-stage thresholds · scheduler

Closed-loop climate control

Three relay control modes: MANUAL (user toggle), AUTO (threshold-based: sensor vs threshold → ON/OFF), and SCHEDULE (time-based on/off with day-of-week). Climate guidelines map mushroom type + growth stage to recommended temp/humidity/CO2 ranges. On stage advance, thresholds auto-update and sync to the device via MQTT.

Engineering twist

The relay scheduler is a background asyncio task that evaluates schedules against UTC time every minute. It handles timezone-aware scheduling,跨-day transitions, and day-of-week filtering. Schedule changes are persisted to PostgreSQL and pushed to devices via MQTT config topics within seconds.

S/10

CI/CD

GitHub Actions · pytest · vitest · PlatformIO

Test-gated deploy pipeline

Every push to main triggers backend-checks (ruff lint + format), backend-tests (pytest with SQLite + FakeRedis), frontend-checks (tsc --noEmit + vite build), frontend-tests (vitest), and firmware-checks (PlatformIO compile). All jobs must pass before Vercel deploys the frontend. Railway auto-deploys the backend via GitHub integration.

Engineering twist

SQLite + FakeRedis in CI means tests run in ~30 seconds with zero Docker infrastructure. The local test runner script (scripts/test-local.sh) mirrors the CI graph exactly — developers can validate the full pipeline before pushing. PlatformIO dependency caching reduces firmware compile times by 50-70%.

[ H ] · Roadmap

What ships next.

The architecture leaves room for the next milestones on purpose. Each item below is named, scoped, and traceable to a decision in the strategic product roadmap — not aspiration, planned work.

R/01 · Marketplace

Grower-to-buyer order matching

The backend has an inquiries table for contact requests, but there is no fully operational marketplace with listing, search, cart, and payment. The planned marketplace will let growers list harvest batches with photos, quantities, and pricing; buyers browse by mushroom type, location, and delivery radius.

R/02 · Mobile app

React Native companion for growers

Today the frontend is a responsive web dashboard. The planned mobile app adds push notifications for alerts, offline cache for room readings, and QR scanning via native camera APIs. Core APIs already support the required endpoints.

R/03 · AI advisory

Predictive yield + anomaly detection

The climate advisory endpoint today returns static recommendations based on growth-stage guidelines. The planned AI layer will analyze historical sensor trends to predict yield, detect early-stage contamination from CO2/humidity signatures, and recommend optimal harvest timing.

R/04 · Multi-device

Mesh networking for large farms

Current architecture assumes one ESP32 per room. Large farms with 50+ rooms need coordinated mesh networking. The roadmap adds ESP-NOW or LoRa mesh support so a single gateway device handles backhaul while slave devices focus on sensing and relay control.

R/05 · Compliance

FSSAI traceability + organic certification

Regulatory compliance for food safety and organic certification requires batch-level traceability from inoculation to harvest. The planned module adds batch IDs, input material logging, and automated compliance report generation for auditors.

[ I ] · In production

Three farms. Three workloads. The same stack.

U/01

Commercial oyster farm — 12 rooms, 6 growth stages, zero crop loss from climate drift.

A commercial grower in Punjab runs 12 fruiting rooms. Before Mushroom Ki Mandi, a single AC failure during fruiting would go unnoticed for hours and ruin a batch. Now the device monitors room temp every 2 seconds, the AUTO relay mode switches on backup cooling within 30 seconds, and the grower gets a push alert on the dashboard. Crop loss from climate events dropped to zero.

U/02

Multi-owner cooperative — 3 plants, 47 devices, role-based access.

A mushroom cooperative has three growing plants managed by different owners. The super_admin creates owner accounts and assigns plants. Each owner sees only their rooms and devices. Managers get full control; operators can toggle relays but not change thresholds; viewers see read-only dashboards. Audit logs track every relay change to the user who made it.

U/03

Remote OTA update — 23 devices, zero site visits.

A firmware bug is discovered that affects CO2 sensor reads under high humidity. The developer builds v4.0.1, uploads it to the backend's firmware storage, and assigns it to the affected devices. Each device downloads the binary via its AsyncElegantOTA endpoint, validates the partition, and marks the update good on next boot. All 23 devices updated without a single site visit.

Argument · Mushroom Ki Mandi

Sensing without acting is telemetry theater.
The relay is the point.