Alacrity Wiki

Terarii

MICROCOSM — Technical and Educational Plan

Project: MICROCOSM — nine student-built instrumented ecosystems at Ioanid school, Bucharest
Funder: ARCUB (approved equipment list, Annex 2) · Technical partner: Alacrity
Document: v1.0, 2026-10-20 · Status: proposal for discussion with the school and reconciliation with procurement
Replaces: "MICROCOSM — Alacrity Education, Ecosystems & Approved Technical Equipment" (5 pages, undated)

How to read this document: Chapter 0 is the two-page summary. Chapter 1 explains what was wrong with the proposal and what changed. Chapters 2–4 fix the platform every ecosystem shares. Chapter 5 is the core: one detailed design per ecosystem, written so that a team of students with a teacher-coach can build it. Chapter 6 is the priced budget and the line-by-line reconciliation with the approved list. Chapter 7 is the schedule to 2026-12-18 and beyond, the people, the workshops and the risks. Chapter 8 answers the proposal's open questions. Diagrams are in Mermaid and render on GitHub, GitLab, Obsidian, VS Code and most Markdown viewers.

0. Executive summary

Nine living, instrumented ecosystems on one shared platform (an ESP32 node per ecosystem running ESPHome, a Raspberry Pi 5 hub running Home Assistant on the school's existing Wi-Fi), each with a written science track (question, hypotheses, variables, controls, replication, analysis) and an engineering track (requirements, prototype, test, iterate), at least two weeks of data, one chart per team at the showcase, and a Time Capsule designed to run for ten years without depending on its electronics.

Safety is designed in. No student or teacher ever builds, wires or switches 230 V. Mains exists only inside certified products on a shelf, on RCD-protected strips, switched only through smart plugs. Everything in water, substrate or inside an enclosure is 12 V DC or less. Safety interlocks (heater cut-offs, pump limits, dry-run guards) live in the node firmware and in hardware thermal fuses, not in the hub.

Budget. The recommended plan costs about 20 989 RON (4 115 EUR) for equipment, enclosures, hub, network and biology, or 24 137 RON with a 15 % contingency. Of this, about 7 263 RON is biology, substrates and consumables that the proposal did not budget at all, and about 961 RON is the hub and network it did not list. The approved list, priced as written, would have cost about 8 500 RON and would not have produced a working project.

Group RON EUR
A. Controllers and sensors 4 615 905
B. Automation and power 4 064 797
C. Enclosures and construction 4 086 801
D. Hub and network 961 188
E. Biology and consumables per ecosystem 7 263 1 424
Total (recommended) 20 989 4 115
Total with 15 % contingency 24 137 4 733

Schedule. Orders go out 2026-10-21 to 10-23. Hub and standard node are built during the autumn break. Teams assemble nodes 2026-11-10, enclosures 11-09 to 11-20, biology is established by 11-20 to 12-04, treatments run 12-01 to 12-18, Time Capsule is built 12-01 to 12-11, showcase 12-15 to 12-17, ARCUB report 12-18. The interesting biology (decomposition, blooms, restoration, harvests) is expected January to June 2027; the plan schedules those rounds too.

1. Review of the current proposal

The proposal ("MICROCOSM — Alacrity Education, Ecosystems & Approved Technical Equipment", 5 pages) has a good skeleton: nine distinct ecosystems, a clear science/engineering split per ecosystem, a paired 2026/2056 experiment, a ten-year Time Capsule, and the right priority (educational outcomes before scientific results). Everything below the skeleton is missing or inconsistent. The equipment list reads as a generic "IoT terrarium" shopping list that was never checked against the nine ecosystems it is supposed to serve.

1.1 What is sound and is kept

Kept from the proposal Why
Nine ecosystems with the stated themes Diverse, teachable, and each maps to a real scientific method
One ESP32 per ecosystem, 12 boards (9 + 3 spares) Correct choice and correct quantity
DS18B20 waterproof probes, BH1750 lux sensors, SSD1306 OLEDs Cheap, robust, well supported
"Real CO2" sensors (NDIR) rather than eCO2 estimates Correct instinct; quantity and placement fixed below
Capacitive (not resistive) soil moisture probes Correct type; the specific v2.0 board needs mitigation
2026 vs 2056 as a matched pair The only ecosystem in the proposal with a built-in control
Time Capsule as a collaborative, decade-long closing project Strong idea; it only needs a design that survives without electronics
"Educational outcomes are more important than scientific results" Drives every simplification in this plan

1.2 Structural problems

# Problem Consequence
S1 No prices anywhere. The "approved budget" is a quantity list. Nobody can tell whether the project is affordable or where the money goes. Chapter 6 supplies a full priced BOM.
S2 No schedule. The ARCUB year ends in December; biology needs weeks to show anything. Without a plan, biology starts too late and the showcase shows empty tanks. Chapter 7 supplies a week-by-week schedule; biology must be established by 2026-11-20.
S3 No science design. Each ecosystem says "investigate X" with no question, hypothesis, variables, control or replication. Students would collect data with no way to interpret it. Every ecosystem section now has a Science track with hypotheses, variables, controls, replication and analysis.
S4 No safety content at all. Relays, pumps, misters, heaters and water in a classroom, and the word "safety" does not appear. Chapter 2 sets hard rules: mains only inside certified COTS products, 12 V DC maximum in or near water, no student-built mains wiring.
S5 No biology budget. Not one plant, seed, organism, substrate or nutrient is listed. The living part of nine living systems was unfunded. Chapter 6 adds a biology and consumables budget per ecosystem.
S6 No hub. A "microSD card for Raspberry Pi" is listed; the Raspberry Pi, its power supply and case are not. Nine loggers with no dashboard, no alerts, no shared dataset. Chapter 3 defines the hub on the school's existing Wi-Fi.
S7 Ten-year requirement has no design consequence. The Time Capsule section now designs for longevity: sealed glass, external sensor pod, light independent of the hub, a maintenance calendar and a data custody plan.
S8 Items are listed per "ecosystem count", not per need. 9 BME680, 9 DS18B20, 9 BH1750, 9 SD modules, 9 cards. The hydroponics unit gets a soil probe it cannot use and the EcoColumn gets one water sensor where it needs five. Chapter 4 allocates by need.

1.3 Component-level problems

# Item in proposal Problem Fix in this plan
C1 BME680 ×9 "temperature/humidity/VOC" The gas output is a resistance proxy for VOCs, not CO2. The humidity element drifts and saturates in closed terrariums at >90 % RH. Over-specified and wrong tool for 7 of 9 ecosystems. 2× BME680 (both in Rot, before and after the carbon filter, where "smell" is the science); 8× SHT31 with PTFE membrane for all other air T/RH.
C2 CO2 breakouts ×3, type unspecified Four ecosystems need real CO2 (Rot, Living Earth, 2026, 2056) and the paired experiment needs two identical sensors. 4× Sensirion SCD41 (NDIR, I2C, also T/RH): Rot, Living Earth, 2026, 2056. The Time Capsule's sensor is deferred to 2027 as a cost cut. Automatic self-calibration must be disabled in sealed tanks.
C3 Capacitive soil probes v2 ×12 Known batch defects (wrong timer IC on clones), unsealed top edge corrodes, output depends on substrate, needs per-probe calibration. 12 is too few for replicated plots. 22 probes (TL555 version), conformal-coated, two-point calibrated per probe per substrate.
C4 Water-level sensors ×3, type unspecified A float gives one bit; a level gives a curve. Both are needed in different places. 10× float switches (low/high per reservoir, 2 spare) + 2× JSN-SR04T waterproof ultrasonic for continuous level (EcoColumn pond, hydroponics reservoir).
C5 Water-flow sensors ×2, type unspecified The usual YF-S201 starts reading at 1 L/min; the 12 V pumps in this project deliver 0.2–0.4 L/min through a rain bar. YF-S401 (0.3–6 L/min). Even so, rain-event volume is better computed from pump run time and a one-off calibration.
C6 pH/EC calibration solutions listed, no pH/EC probes Solutions without probes. 2× analog pH kits (Hydroponics, EcoColumn pond), 1× TDS module (Hydroponics), 2× handheld pH pens, 2× TDS pens for soil-extract measurements in every ecosystem.
C7 No turbidity sensor The EcoColumn science is literally sediment transport and algal blooms. 2× analog turbidity modules (one in the pond, one bench probe for runoff and jar samples).
C8 Relay modules ×4 In a school, a bare relay module invites switching 230 V. 6 relay modules, only for low-voltage loads (24 V misters, probe power selection, LED fail-safe path). Mains switched only through 2 certified smart plugs.
C9 Grow lights ×4 at 5–10 W 5–10 W lights a 12 L tank; the hydroponics unit alone needs 30–45 W; seven ecosystems have plants and Bucharest classrooms in November–February have almost no usable daylight. 4× 5 m reels of 12 V LED strip (4000 K white COB, in stock in Romania; full-spectrum from AliExpress as an option) in 16 aluminium profiles (cut to length, PWM-dimmable, SELV) for eight enclosures + 1× COTS 230 V 36 W panel for hydroponics only.
C10 Power supplies ×4 Nine nodes, five pumps, six fans, three heat pads, ten metres of LED strip and a Raspberry Pi cannot run on four adapters. 9× 12 V 5 A certified bricks + 2× 5 V USB adapters + 10 buck modules + Pi PSU.
C11 "Heating" in the 2056 automation, no heater listed The treatment that defines the experiment has no hardware. 4× 12 V silicone heat pads (10–25 W: 2056, 2026 for identical hardware, Brownfield, 1 spare) with DS18B20 thermostat loop, 45 °C thermostat and one-shot thermal fuse.
C12 Peristaltic pumps ×2, no sensing Dosing without pH/EC feedback is dosing blind. 3 (hydroponics nutrient A, B and pH-down) with the pH/TDS kit, dose caps and daily pen cross-checks.
C13 Ultrasonic misters ×2 Most COTS mist modules run on 24 V DC and need their own adapter. Kept at 2, each with its own 24 V adapter, switched through a relay module (low voltage).
C14 Hydroponics: no air pump, no media, no nutrients A "hydroponic jungle" without aeration or nutrient solution does not grow. 1× COTS 230 V aquarium air pump (shelf-mounted, air line only in water) + nutrients, plugs, net pots.
C15 microSD modules ×9 + cards ×9 + RTC ×2 Nine loggers but two clocks: seven loggers would write timestamps from a reset counter. Hub logging is primary. Local SD + RTC only on the Time Capsule node and two advanced spare boards (3 sets).
C16 OLED ×12 Fine. Kept.
C17 "Glass-panel construction packs" ×9 Undefined item; implies students cutting and gluing float glass: cut hazards, leaks, lost weeks. COTS aquariums are leak-tested and cost about the same. 8 COTS glass aquariums (1× 25 L, 3× 45 L, 4× 54 L) plus the hydroponics unit in an opaque food-grade box. Students design and build lids, vents, mounts, dividers and internal structures from polycarbonate and acrylic (6 panels of 50×100 cm, approved 3), mesh, hinges, PVC and silicone.
C18 Electronics cases ×6 Nine nodes need nine boxes plus one for the hub. 9× IP65 junction boxes with 80 cable glands (approved 20).
C19 SG90 servos ×4, no stated use Harmless; a use is now defined (EcoColumn rain gate, Living Earth chamber lid, vents). 8 (Rot intake flap, EcoColumn rain valve, 2026 and 2056 CO2 and vent gates, Living Earth lid, 1 spare).
C20 Fans ×4 Six enclosures need ventilation control. 6× 12 V 80 mm PC fans.
C21 Water reservoirs ×4, "sprayers, nozzles" Fine as a lot, but needs sizes and food-grade material. 5× 10–20 L food-grade containers with lids + 3 opaque storage boxes.
C22 Nothing about the network ESP32 joins only 2.4 GHz WPA2-PSK networks; school Wi-Fi is often enterprise-only or captive-portal. Use the existing school Wi-Fi: ask IT for a 2.4 GHz WPA2-PSK SSID with 12 DHCP reservations and the Pi reachable from student devices. A fallback router (≈ 160 RON) is listed as optional, not bought.
C23 Nothing for electrical protection Water and 230 V adapters on the same bench. 2× RCD (30 mA) adapters, one per shelf power group.

1.4 Net effect of the fixes

The nine ecosystems keep their identity. The equipment list changes in three directions: fewer of the wrong sensors (BME680, SD modules), more of the cheap right ones (soil probes, DS18B20, floats, LED strip), and the addition of everything the proposal forgot (hub, network, power, protection, heaters, air pumps, enclosures as COTS tanks, and the entire biology budget). The full reconciliation, line by line against the approved list, is in Chapter 6.

2. Design principles and hard rules

Every decision in this plan follows from seven rules. Where a later chapter deviates, it says so and why.

2.1 Hard safety rules (non-negotiable)

  1. Mains (230 V AC) is never built, wired, modified or switched by students or teachers. All 230 V exists only inside certified COTS products with their own cord and plug: 12 V power bricks, the Raspberry Pi power supply, the hydroponics LED panel, the aquarium air pumps, the mister adapters.
  2. Nothing mains-powered is ever inside an enclosure, in water, or in substrate. Everything that touches water, substrate or the inside of an enclosure is SELV: sensors at 3.3 V or 5 V; pumps, fans, LED strips and heat pads at 12 V DC; misters at 24 V DC from their own adapter.
  3. Mains devices live on the shelf or wall, above and away from water, with a drip loop on every cable, on an RCD-protected (30 mA) power strip. Mains is switched only through certified COTS smart plugs, never through relay modules.
  4. Node boxes mount outside the enclosure, above the water line. Cables enter through glands. Every 12 V brick is a certified adapter.
  5. Simulated contamination only. Salinity is table salt, pH is vinegar or baking soda, disturbance is compaction, paving and heat. No heavy metals, no real pollutants, no vertebrates, no toxic plants. Gloves for soil and compost work, FFP2 masks when sieving mineral dust.

2.2 Engineering principles

  1. COTS first. Complete, cased, cabled modules over loose parts: waterproof DS18B20, cased SHT31, Gravity-style sensors with cables, pre-made MOSFET and buck modules, ESP32 screw-terminal breakouts, pre-crimped cables, COTS glass aquariums, COTS pumps, COTS LED strips and profiles, COTS smart plugs, COTS junction boxes. Breadboards are for the 3.3 V / 5 V sensor side during prototyping only. Final assemblies use screw terminals or JST connectors, with no loose jumper wires.
  2. Safety logic lives in the node, not in the hub. Heat-pad cut-offs, pump run-time limits and reservoir-low interlocks are implemented in ESPHome firmware on the ESP32 and backed by hardware thermal fuses. Home Assistant adds schedules, dashboards and alerts on top, so a hub outage never creates a hazard.
  3. One platform, nine configurations. Every node is the same box, same pin map, same base firmware. A team configures, it does not re-invent. Spare nodes are interchangeable with any ecosystem.
  4. Education before results. A well-documented failed experiment is a full success. Each ecosystem has a Science track (question, hypothesis, variables, control, replication, analysis) and an Engineering track (requirements, prototype, test, iterate). Adults set up the mains side and cut glass; students do everything else.
  5. Design for December first, for spring second, for 2036 last. By 2026-12-18 all nine ecosystems must be alive, instrumented and reporting with at least two weeks of data. The interesting biology (decomposition, blooms, restoration, harvests) is expected in January–June 2027. The Time Capsule is designed so that the living system never depends on the electronics.

2.3 Fixed platform decisions

Decision Choice Rationale
Controller ESP32-WROOM-32 DevKitC, 38-pin, one per ecosystem, 3 spares Approved quantity; Wi-Fi, enough ADC1 pins, ESPHome support
Firmware ESPHome (YAML) No code needed for the base; OTA updates; students extend by editing YAML; advanced track can use Arduino on spare boards
Hub Raspberry Pi 5 (4 GB), Home Assistant OS, add-ons: ESPHome, Mosquitto, InfluxDB, Grafana Turnkey dashboards, automations, alerts, long-term storage, CSV export
Network The school's existing Wi-Fi: a 2.4 GHz WPA2-PSK SSID for the project, 12 DHCP reservations, Pi on Ethernet or Wi-Fi No new hardware; ESP32 needs 2.4 GHz PSK; a 160 RON fallback router is listed as optional if IT cannot provide this
Sampling Every sensor every 60 s; soil moisture averaged over 10 samples Enough for daily cycles; small dataset (about 1.5 million rows per year for all nodes)
Time NTP from the hub; DS3231 RTC + microSD only on the Time Capsule node and two advanced spare boards Hub logging is primary; local logging where independence matters
Power 12 V 5 A certified brick per automated node, LM2596 buck to 5 V for the ESP32; 5 V USB adapter for passive nodes Single SELV rail per ecosystem; all actuators 12 V
Switching D4184-type MOSFET modules for 12 V PWM loads; relay modules for 24 V misters only; smart plugs for mains Rule 1 and 3
Enclosures COTS glass aquariums (12, 25, 45, 63 L); students build lids, vents, dividers, mounts Leak-tested, cheap, safe; the engineering is in the lids and internals
Naming Nodes mc-01-rot … mc-09-capsule; entities <node>_<quantity>_<position> One convention for dashboards, CSV columns and lab notebooks

2.4 Standard pin map

Every node uses the same map, so any node YAML differs only in which packages are enabled and which setpoints apply.

Function GPIO Notes
I2C SDA / SCL 21 / 22 SHT31 0x44, SCD41 0x62, BH1750 0x23, BME680 0x76 or 0x77, SSD1306 0x3C
1-Wire bus (DS18B20) 4 4.7 kΩ pull-up to 3.3 V; several probes on one bus
Analog A–D (soil moisture) 32, 33, 34, 35 ADC1 only (ADC2 is unusable while Wi-Fi is on); 34 and 35 are input-only
Analog E / F (pH, TDS boards) 36, 39 Input-only, 11 dB attenuation
PWM out 1–4 (MOSFET modules) 16, 17, 18, 19 Light, fan, pump, heater or mister, always in this order
Relay 1–2 23, 25 Low-voltage loads only
Servo 1–2 26, 27 SG90 at 50 Hz
Digital in 1–2 (float switches) 13, 14 Internal pull-up, switch to GND
Pulse counter (flow sensor) 5 YF-S401 signal through a level check or divider
Ultrasonic TRIG / ECHO 15 / 12 JSN-SR04T; ECHO through a 1 kΩ / 2 kΩ divider
Reserved 0, 2 Boot button, onboard LED

3. Common platform

Architecture overview

Nine identical ESP32 nodes ("MICROCOSM node v1") talk over the project's own 2.4 GHz Wi-Fi to one Raspberry Pi 5 running Home Assistant OS (HAOS). The Pi stores the data, serves the dashboards and builds/flashes the firmware. The school network is optional: it gives Internet for NTP, remote access and off-site backup, and the lab keeps working without it.

flowchart LR
  subgraph NODES["9 ESP32 nodes - ESPHome - Wi-Fi 2.4 GHz"]
    N1["mc-01-rot"]
    N2["mc-02-ecocolumn"]
    N3["mc-03-brownfield"]
    N4["mc-04-future2026"]
    N5["mc-05-future2056"]
    N6["mc-06-regolith"]
    N7["mc-07-hydro"]
    N8["mc-08-soil"]
    N9["mc-09-capsule"]
  end
  SP["Smart plugs - hydro LED panel, air pump"]
  R["School Wi-Fi - 2.4 GHz WPA2-PSK SSID for the project"]
  subgraph PI["Raspberry Pi 5 - Home Assistant OS - 192.168.50.10"]
    HA["HA Core - recorder SQLite 30 d"]
    EH["ESPHome Device Builder"]
    MQ["Mosquitto MQTT"]
    IDB["InfluxDB 1.8 - keep forever"]
    GF["Grafana"]
  end
  C["Student laptops and phones on MICROCOSM Wi-Fi"]
  W["School network and Internet"]
  X["NTP - Tailscale or Nabu Casa - Google Drive backup"]
  N1 & N2 & N3 & N4 & N5 & N6 & N7 & N8 & N9 -->|"native API"| R
  SP -->|"API or MQTT"| R
  R ---|"Ethernet"| PI
  HA --> IDB
  IDB --> GF
  EH -->|"OTA firmware"| R
  MQ -.->|"advanced track"| R
  C -->|"HA and Grafana dashboards"| R
  R -->|"WAN optional"| W
  W --> X

One measurement, end to end:

sequenceDiagram
  participant S as Sensor (SHT31)
  participant E as ESPHome node
  participant H as HA Core
  participant R as Recorder (SQLite)
  participant I as InfluxDB
  participant G as Grafana or CSV export
  E->>S: I2C read every 60 s
  S-->>E: raw temperature and RH
  E->>E: filters - average, calibrate_linear, range check
  E->>H: native API push (Noise-encrypted protobuf)
  H->>R: state row, purged after 30 days
  H->>I: point - measurement = unit, tag entity_id, field value
  G->>I: InfluxQL query per node
  I-->>G: time series to panel, CSV download or nightly file

Why the ESPHome native API for the base, not raw MQTT

Need Native API Raw MQTT
Entities appear in HA with name, unit, device class automatic needs a discovery payload per entity
Firmware update OTA from the ESPHome dashboard, one click separate OTA mechanism
Students write code no; YAML only topic design, payloads, retained flags
Time sync, HA → node actions (buttons, numbers) built in hand-built topics
Security per-node 32-byte encryption key broker users + ACLs, TLS rarely used
Broker outage risk none (no broker) Mosquitto is a single point of failure

Mosquitto stays installed for three uses: (1) the advanced track (Arduino/PlatformIO on the spare boards with PubSubClient, topics microcosm/<node>/<quantity>, HA MQTT discovery as a learning task); (2) Tasmota-flashed smart plugs, if those are bought instead of ESPHome-flashable ones; (3) third-party devices. ESPHome nodes may also add an mqtt: block as an Engineering-track exercise. The base firmware does not depend on it.

The standard node ("MICROCOSM node v1")

Specification

Item Spec
Controller ESP32 ESP32-WROOM-32 DevKitC, 38-pin, plugged into a TERMBOARD 38-pin screw-terminal breakout. Buy the breakout for the same pin-row width as the DevKitC (25.4 mm, i.e. "1 inch", is the common one). Check this before ordering 12 of each.
Enclosure BOX IP65 ABS, ≈150×110×70 mm, clear or grey lid (OLED behind a clear lid or a 30×15 mm acrylic window siliconed in), on a 3 mm acrylic back plate with M3 nylon standoffs. Mounted outside the ecosystem enclosure, above the highest water level, glands facing down.
Cable entry 6× GLAND (4× PG7 for 3–6.5 mm sensor cables, 2× PG9 for 4–8 mm 12 V load cables). Unused glands are closed with a blank or a short rod.
Power in PSU12 certified 12 V 5 A desktop brick → 5.5/2.1 mm DC jack (centre +) on the box → inline 5 A blade fuse → 12 V terminal bus.
Logic power BUCK LM2596, set to 5.1 V before anything is connected → TERMBOARD 5V/VIN terminal. Do not feed 12 V into the breakout's own DC jack: it uses an AMS1117 linear regulator that dissipates ≈2 W at 12 V and overheats. Nodes without 12 V loads (spares, bench) use PSU5 into the DevKitC USB.
12 V loads MOSFET single-channel PWM modules, D4184 (AOD4184A) type only. IRF520 modules are not logic-level and only half-switch on at 3.3 V gate drive. One module per load, GPIO 16/17/18/19. Schottky diode (SS34/1N5819) across every motor/pump/fan terminal if the module has none.
Isolated LV loads RELAY (GPIO 23/25), 3.3 V-trigger compatible, only for the 24 V mister. Never mains.
I2C GPIO21 SDA / GPIO22 SCL, 3.3 V, 100 kHz. Each breakout carries its own 4.7–10 kΩ pull-ups; up to 5 boards in parallel (≈2 kΩ) is fine. With more boards, remove pull-up resistors from the extras. Total bus cable < 1 m. Above 50 cm, use twisted pairs (SDA twisted with GND, SCL twisted with 3.3 V) or shielded cable and drop to 50 kHz. Otherwise, put the I2C sensors close to the box (box on the enclosure side wall, sensors through the lid, ≤ 40 cm).
1-Wire GPIO4, 4.7 kΩ pull-up to 3.3 V (2.2 kΩ if total cable > 5 m). Daisy-chain or short star (≤ 3 probes × 1 m stock cables). Fine to 5–10 m total. Every probe is labelled with the last 4 hex digits of its ROM address.
Analog ADC1 only: GPIO32–35 (soil A–D), GPIO36/39 (pH/TDS). Attenuation 12 dB (formerly called "11 dB"): usable ≈0.15–3.1 V. 10-sample average per reported value. ADC2 pins are unusable while Wi-Fi is on.
5 V signals ESP32 GPIOs are not 5 V tolerant. JSN-SR04T ECHO → 1 kΩ series / 2 kΩ to GND (5 V → 3.33 V). YF-S401 signal → 10 kΩ / 20 kΩ. Analog boards: power the Gravity pH/TDS boards at 3.3 V (output ≤ 3.0 V). A PH-4502C at 5 V can output > 3.3 V, so give it a 10k/20k divider or use the Gravity pH v2 instead. Soil probes v2.0 are powered at 3.3 V (output ≈1.1–2.7 V).
Strapping pins GPIO12 (ECHO) must be low at boot. The 2 kΩ to GND guarantees this; never add a pull-up there. GPIO0/2 are kept free. GPIO5/15 are fine as wired.
Display OLED SSD1306 0.96" I2C 0x3C, shows node name, Wi-Fi/HA status + RSSI, air T/RH, two team-selected values.

Power budget (worst case per node)

Load Rail Typical Peak At 12 V input (peak)
ESP32 (Wi-Fi TX) 5 V → 3.3 V 80 mA 250 mA 0.13 A
SCD41 (during measurement) 3.3 V 15 mA 200 mA 0.10 A
OLED + SHT31 + BH1750 + 3 DS18B20 + 4 soil probes 3.3 V 40 mA 50 mA 0.03 A
JSN-SR04T + YF-S401 5 V 35 mA 50 mA 0.03 A
2× SG90 servo 5 V 10 mA 1.2 A (stall) 0.60 A
LED strip, 1.2 m full-spectrum (≈12 W/m) 12 V PWM 0.8 A 1.2 A 1.20 A
80 mm fan 12 V PWM 0.10 A 0.20 A 0.20 A
Submersible pump 3–5 W 12 V PWM 0.30 A 0.45 A 0.45 A
Heat pad 20 W 12 V on/off 0–1.7 A 1.7 A 1.70 A
Total (Future 2056, the heaviest node) ≈4.4 A worst case, ≈3.2 A realistic

Rules: the 5 V rail via the LM2596 stays ≤ 2 A (no heatsink), so at most 2 servos per node. The sum of 12 V loads that can be on at the same time is ≤ 4 A (80 % of the 5 A brick). If a node exceeds this (e.g. a 25 W pad plus 2 m of LED), split it: the LED strip gets its own PSU12, with grounds joined at the box. Misters run from their own 24 V adapter through the relay. Wire: 0.75 mm² for the 12 V input, 0.5 mm² for 12 V loads ≤ 2 A, 0.25 mm² (stock sensor leads) for signals.

Block / wiring diagram

flowchart TB
  PSU["PSU12 brick 12 V 5 A - 230 V side on the RCD shelf"] -->|"P1 DC jack 5.5/2.1, centre +"| F
  subgraph BOX["IP65 node box - outside the enclosure, above water line, glands down"]
    F["Inline fuse 5 A"] --> B12["12 V terminal bus + GND bus"]
    B12 --> BK["LM2596 set to 5.1 V"]
    BK -->|"5 V to VIN"| ESP["ESP32 DevKitC on TERMBOARD"]
    ESP -->|"3.3 V"| BUS["I2C GPIO21/22 and 1-Wire GPIO4 with 4.7k"]
    OLED["OLED 0x3C behind lid window"]
    DIV["Dividers - 1k/2k ECHO, 10k/20k flow"]
    M1["MOSFET 1 - GPIO16"]
    M2["MOSFET 2 - GPIO17"]
    M3["MOSFET 3 - GPIO18"]
    M4["MOSFET 4 - GPIO19"]
    RL["Relay 1/2 - GPIO23/25"]
    B12 --> M1
    B12 --> M2
    B12 --> M3
    B12 --> M4
    ESP --> M1
    ESP --> M2
    ESP --> M3
    ESP --> M4
    ESP --> RL
    ESP --> DIV
  end
  BUS --> OLED
  BUS -->|"S1 JST-XH 4p"| I2CS["SHT31 / SCD41 / BH1750 / BME680"]
  BUS -->|"S2 JST-XH 3p"| DS["DS18B20 probes"]
  ESP -->|"S3-S6 JST-XH 3p, GPIO32-35"| SOIL["Soil probes A-D"]
  ESP -->|"S7 JST-XH 3p, GPIO36/39"| AN["pH / TDS boards"]
  ESP -->|"S8 JST-XH 2p, GPIO13/14"| FL["Float switches"]
  DIV -->|"S9 JST-XH 4p"| JSN["JSN-SR04T level"]
  DIV -->|"S10 JST-XH 3p"| FLOW["YF-S401 flow"]
  ESP -->|"S11/S12 JST-XH 3p, GPIO26/27"| SV["SG90 servos"]
  M1 -->|"A1 screw terminal"| LED["12 V LED strip in profile"]
  M2 -->|"A2"| FAN["12 V fan"]
  M3 -->|"A3"| PUMP["12 V pump"]
  M4 -->|"A4, via 72 C thermal fuse"| HEAT["12 V heat pad"]
  RL -->|"A5"| MIST["24 V mister - own adapter"]

Connectors, colours, labels

Port Connector Pin order (pin 1 = marked side) Use
P1 5.5/2.1 mm DC jack, panel mount centre +12 V power in
S1 JST-XH 2.54, 4-pin GND, 3.3 V, SDA, SCL I2C sensor (daisy-chain via a 4-way JST hub board or a terminal block)
S2 JST-XH 3-pin GND, 3.3 V, DATA 1-Wire (DS18B20)
S3–S7 JST-XH 3-pin GND, 3.3 V, SIG analog: soil A–D, pH, TDS
S8 JST-XH 2-pin ×2 GND, SIG float low / float high
S9 JST-XH 4-pin GND, 5 V, TRIG, ECHO JSN-SR04T
S10–S12 JST-XH 3-pin GND, 5 V, SIG flow sensor, servos
A1–A4 2-way screw terminal on the MOSFET module (+12 V, LOAD−) + then − 12 V PWM loads
A5 relay COM/NO screw terminal — 24 V mister loop

Wire colours (all nodes, all harnesses): red = 12 V, black = GND, orange = 5 V, yellow = 3.3 V, blue = signal (second signal in the same cable: green, e.g. SCL). Loads switched by a MOSFET: red to +12 V, black to LOAD−; the load's black wire is never connected to the GND bus directly.

Labels: printed heat-shrink or flag labels at both ends of every cable, format <node#>-<port> <device> <position>, e.g. 04-S3 SOIL A, 04-A3 PUMP. The box lid carries a port map sticker (copy of the table above with the node's actual devices) and the node name + IP.

BOM for one node (Future 2026 example, 3 PWM loads)

ID Qty Est. RON each RON Basis
ESP32 1 43 43 sigmanortec.ro ESP32-DevKitC 38P, 42.56 RON (checked 2026-10)
TERMBOARD 1 30 30 optimusdigital/emag "ESP32 38P expansion board", estimate
BOX 1 35 35 dedeman/emag IP65 150×110×70, estimate
GLAND 6 2 12 PG7/PG9 nylon, bag price
BUCK 1 10 10 emag LM2596 module 6–15 RON (checked)
MOSFET 3 15 45 D4184 module ≈ €3.20 (checked, ebay.de); RO shops similar
OLED 1 20 20 SSD1306 0.96" I2C, estimate
PSU12 1 60 60 12 V 5 A brick + DC jack, emag, estimate
Free: node cable kit 1 40 40 JST-XH pre-crimped pigtails 2/3/4-pin, 0.5/0.75 mm² red/black, ferrules, heat-shrink
Free: inline fuse holder + 5 A fuse 1 8 8 auto blade type
Free: backplate, M3 nylon standoffs, dividers (1k/2k, 10k/20k), SS34 diodes, labels 1 15 15 consumables
Node core total 318 (≈ €62) sensors and actuators are in the ecosystem chapters

Assembly session (one team, 90 min, checklist)

Prerequisites (done by Alacrity/teacher beforehand): kits bagged per node; glands holes pre-marked from a paper template; firmware compiled and flashed once via USB to each ESP32 (so on the day the board only needs OTA); multimeter per team.

Time Step Done
0–10 Check the bag against the BOM; write the node name on the box with a marker; photograph the parts. ☐
10–20 Drill gland holes with a step drill (PG7 = 12.5 mm, PG9 = 15.5 mm), all on the bottom face. Wear goggles, box clamped. Fit glands. ☐
20–30 Mount backplate: TERMBOARD (without the ESP32), buck, MOSFET modules, fuse holder, terminal bus. Nothing powered. ☐
30–40 Set the buck: brick → jack → fuse → buck input only. Turn the trimmer until the output reads 5.05–5.15 V. Unplug. ☐
40–55 Wire 12 V bus → MOSFET V+, buck → TERMBOARD 5V/VIN, GND star, MOSFET signal inputs → GPIO16/17/18/19, using ferrules in all screw terminals. ☐
55–70 Fit the sensor harness: JST-XH tails to TERMBOARD terminals per the port table. Fit dividers on the ECHO/flow lines if used. Fit labels at both ends. ☐
70–80 Run the QA checklist below. Then insert the ESP32 (USB port towards the lid opening), power on, and check that the OLED shows the node name and "HA ok". ☐
80–90 Connect each actuator and dry-run it from the HA page. Close the lid, tighten glands (pull test), take a photo of the inside for the logbook, sign the QA sheet. ☐

QA checklist (before the ESP32 goes in, then with it)

# Test Pass criterion Result
1 Continuity/short, unpowered: 12V↔GND, 5V↔GND, 3V3↔GND > 1 kΩ (no short)
2 Brick polarity at the jack terminals +12.0–12.6 V on red
3 Buck output, no load 5.05–5.15 V
4 5 V at TERMBOARD VIN, ESP32 not inserted 5.0–5.15 V, 3.3 V absent
5 ESP32 inserted, 3.3 V rail 3.25–3.35 V
6 Smoke test: 60 s powered, hand above parts no heat, smell or noise; buck and AMS1117 lukewarm only
7 OLED node name + "HA ok" + RSSI
8 ESPHome log I2C scan expected addresses only (0x3C, 0x44, 0x62, 0x23, 0x76/77)
9 1-Wire expected number of ROM addresses found
10 Each MOSFET channel 0 → 100 % with its real load load follows, module < 40 °C after 5 min at 100 %
11 Gland pull test cable does not move with a 2 kg pull
12 Labels both ends, port sticker, photo in logbook present

Hard safety rules restated for the node

  1. The node and everything connected to it is SELV ≤ 12 V DC (24 V for the mister loop only). No mains conductor ever enters a node box.
  2. 230 V exists only inside certified bricks/adapters, the Pi PSU, the COTS LED panel and the air pump, all plugged into the RCD-protected strip on the shelf. Mains loads are switched only by certified smart plugs, never by a relay module.
  3. The box hangs outside the enclosure, above the water line, glands down, with a drip loop on every cable.
  4. The heat pad is wired through MOSFET 4 and a 72 °C thermal fuse taped to the pad, and its firmware interlock is enabled (see Firmware).
  5. Unplug the brick before opening the box or (dis)connecting anything.

Firmware (ESPHome)

File layout (in /config/esphome/ on the Pi, edited from the ESPHome Device Builder or Studio Code Server)

/config/esphome/
  secrets.yaml                 # Wi-Fi, OTA, one API key per node; admin-only
  mc-01-rot.yaml ... mc-09-capsule.yaml   # one ~25-line file per node, owned by the team
  common/
    mc-base.yaml               # Wi-Fi, API, OTA, time, I2C, 1-Wire, OLED, diagnostics
    sens-sht31.yaml  sens-bme680.yaml  sens-scd41.yaml  sens-bh1750.yaml
    sens-ds18b20.yaml          # vars: sid, label, addr, offset   (one include per probe)
    sens-soil.yaml             # vars: pos, pin, dry_v, wet_v     (one include per probe)
    sens-analog.yaml           # vars: aid, pin, label, unit, v1, y1, v2, y2 (pH, TDS)
    act-light.yaml             # PWM1 GPIO16 + local photoperiod
    act-fan.yaml               # PWM2 GPIO17
    act-pump.yaml              # vars: pid, pin, label, max_s  (PWM3 GPIO18 by default)
    act-heater.yaml            # PWM4 GPIO19 + thermostat + latched interlock
    act-relay.yaml             # vars: rid, pin, label, max_s  (GPIO23/25)
    act-servo.yaml             # vars: sid, pin, label         (GPIO26/27)
    in-floats.yaml  guard-dryrun.yaml  in-flow.yaml  in-level.yaml

The common/ files are owned by Alacrity and changed only by pull request/teacher. Teams edit only their node file. Every file below passed esphome config, and both the example node and a test node with every package enabled compiled cleanly (ESPHome 2026.9.1, ESP-IDF 5.5.5). Node-level substitutions override the defaults in the packages.

ESPHome components used: sht3xd, scd4x, bh1750, bme680, one_wire + dallas_temp, adc, copy, ledc, monochromatic light, speed fan, output/template switch, servo, pulse_counter, ultrasonic, gpio/template/status binary_sensor, ssd1306_i2c + font, sntp + homeassistant time, wifi_signal, uptime, script, interval, globals, template number/button.

secrets.yaml (template; the real file stays on the Pi)

wifi_ssid: "MICROCOSM"
wifi_password: "<WPA2 key, 16+ chars>"
fallback_ap_password: "<12+ chars>"
ota_password: "<random 20 chars>"
mc00_api_key: "<32-byte base64>"   # generate: openssl rand -base64 32
mc01_api_key: "<...>"
mc04_api_key: "<...>"
# ... one per node incl. spares mc-10..mc-12

Base firmware and packages

The full listing of common/mc-base.yaml, the sensor packages, the actuator packages and the heater safety interlock is in Appendix B. All files compiled cleanly with esphome config and esphome compile on ESPHome 2026.9.1 and are delivered alongside this document in the microcosm-firmware/ folder.

Example node: mc-04-future2026.yaml

# mc-04-future2026.yaml — Future 2026 (paired with mc-05). Only this file is edited by the team.
substitutions:
  node_name: mc-04-future2026
  friendly_name: "MC 04"
  area: "Future 2026"
  api_key: !secret mc04_api_key
  user1_src: soil_a
  user1_label: "Soil A pct"
  user2_src: co2
  user2_label: "CO2 ppm"
  light_on_min: "420"              # 07:00 (identical in mc-05!)
  light_off_min: "1260"            # 21:00

packages:
  base: !include common/mc-base.yaml
  sht31: !include common/sens-sht31.yaml
  scd41: !include common/sens-scd41.yaml
  bh1750: !include common/sens-bh1750.yaml
  t_sub_a: !include
    file: common/sens-ds18b20.yaml
    vars: {sid: t_sub_a, label: "Substrate temp A", addr: "0x5a3c01f0956e2b28", offset: "0.0"}
  soil_a: !include
    file: common/sens-soil.yaml
    vars: {pos: a, pin: GPIO32, dry_v: "2.62", wet_v: "1.31"}
  soil_b: !include
    file: common/sens-soil.yaml
    vars: {pos: b, pin: GPIO33, dry_v: "2.58", wet_v: "1.27"}
  light: !include common/act-light.yaml
  fan: !include common/act-fan.yaml
  pump: !include
    file: common/act-pump.yaml
    vars: {pid: pump, pin: GPIO18, label: "Irrigation pump", max_s: "60"}

The resulting HA entities are sensor.mc_04_air_temp, sensor.mc_04_air_rh, sensor.mc_04_co2, sensor.mc_04_illuminance, sensor.mc_04_substrate_temp_a, sensor.mc_04_soil_moisture_a/_b (+ diagnostic sensor.mc_04_soil_raw_a/_b), light.mc_04_grow_light, switch.mc_04_grow_light_schedule, fan.mc_04_fan, fan.mc_04_irrigation_pump, sensor.mc_04_wifi_rssi and binary_sensor.mc_04_status. HA builds the id from the device's friendly name MC 04 plus the entity name. Check the ids once after adoption: they are frozen at first registration, and renaming later breaks the InfluxDB series.

mc-05-future2056 uses the same file plus act-heater.yaml (heat_probe: t_sub_a) and act-relay.yaml (mister, max_s: "30"), with identical light_on_min/light_off_min, so the only differences between 04 and 05 are the experimental variables.

Firmware rules

Rule Why
Safety logic (heater interlock, pump max-run, dry-run guard, mister timeout, photoperiod) lives in the node. It keeps working when HA, Wi-Fi or the Pi is down.
api.reboot_timeout: 0s and wifi.reboot_timeout: 0s The default makes nodes reboot every 15 min without HA, which resets actuator states.
Actuators restore_mode: ALWAYS_OFF (light: RESTORE_DEFAULT_OFF, then the schedule turns it on) After a power cut nothing starts unattended except the photoperiod.
All sensors 60 s. Exceptions: flow and level at 10 s internally (reported every 60 s for level) Matches the brief's sampling policy; flow events are short.
No % character in OLED labels The label is inserted into a printf format string.
Spare boards mc-10…mc-12: advanced track (Arduino/PlatformIO, MQTT, RTC + SD logging) Never on a production node without teacher review.

Hub (Raspberry Pi 5 + Home Assistant OS)

Install (≈ 90 min, teacher + Alacrity)

# Step
1 On a laptop: Raspberry Pi Imager → Choose device: Raspberry Pi 5 → Choose OS: Other specific-purpose OS → Home assistants and home automation → Home Assistant → Home Assistant OS (RPi 5) → Storage: the SD64 card (or the NVMe drive in a USB adapter, see the deviation below) → Write.
2 Fit the RTC battery on the Pi 5's J5 connector (keeps the clock through power cuts without Internet). Insert the card, connect Ethernet to router LAN port 1 and the 27 W PSU.
3 Wait 5–20 min. Open http://homeassistant.local:8123 (or http://192.168.50.10:8123 after the DHCP reservation).
4 Onboarding: owner account alacrity-admin (strong password, stored in the school's password manager); home name MICROCOSM Ioanid; location Bucharest; time zone Europe/Bucharest; metric; analytics off. Skip discovered devices for now.
5 Profile → enable Advanced mode. Settings → System → Updates: update HAOS and Core. Settings → System → Network: hostname microcosm-hub.
6 Install add-ons (Settings → Add-ons → Add-on store), all with Start on boot + Watchdog: see the table.
7 Configure the InfluxDB add-on (Chronograf UI → InfluxDB Admin): database homeassistant, user homeassistant (write), user grafana (read). Default retention autogen = infinite.
8 Paste the configuration.yaml blocks below; Developer tools → YAML → Check configuration → Restart.
9 ESPHome Device Builder: copy common/, secrets.yaml, node files; flash each node once by USB (or the browser at web.esphome.io), then OTA. HA → Settings → Devices → ESPHome → Configure each discovered node with its API key; assign the Area.
10 Backups: Settings → System → Backups → add the Google Drive location (HA built-in integration). Schedule daily 03:00, keep 14, encrypted; store the backup emergency kit (encryption key) offline with the teacher.

Storage: HAOS boots from the 64 GB A2 microSD card. SD wear is the usual hub failure, so the nightly backup below is mandatory and a second card with a restored image is kept in the hub box. An NVMe drive was considered and dropped as a cost cut; it can be added later without reinstalling.

Add-ons and roles

Add-on Role Notes
ESPHome Device Builder edit, compile, OTA-flash node firmware admin users only; compile needs Internet once to fetch toolchains and fonts
Mosquitto broker MQTT for the advanced track, Tasmota plugs user mc-mqtt, no anonymous access
InfluxDB (1.8, includes Chronograf) long-term time-series store, query UI with CSV download keep forever; ≈ 0.5 GB/year for 9 nodes
Grafana per-ecosystem analysis dashboards port 3000 exposed on LAN, anonymous Viewer for students
Studio Code Server YAML editing with validation (teacher, advanced students) admin only
File editor quick edits admin only
Samba share \\192.168.50.10\share → CSV exports on teacher laptop own user, LAN only
Tailscale remote access without port forwarding optional, needs a WAN
(built-in) Backups → Google Drive nightly full backup off-site encrypted
rclone (community add-on), optional sync /share/microcosm/csv → Google Drive folder alternative: Google Drive for Desktop on the teacher laptop syncing the Samba share

configuration.yaml blocks

recorder:
  purge_keep_days: 30          # short-term SQLite for HA history graphs
  commit_interval: 5
  exclude:
    entity_globs:
      - sensor.*_uptime

influxdb:
  host: a0d7b954-influxdb      # InfluxDB add-on hostname
  port: 8086
  database: homeassistant
  username: homeassistant
  password: !secret influxdb_password
  max_retries: 3
  default_measurement: state   # unit-less entities (switches, binary sensors)
  tags:
    project: microcosm
  include:
    entity_globs:
      - sensor.mc_*
      - binary_sensor.mc_*
      - switch.mc_*
      - light.mc_*
      - fan.mc_*
      - number.mc_*
      - input_boolean.mc_*     # mc_XX_maintenance flags -> quality = MAINT
  exclude:
    entity_globs:
      - sensor.mc_*_uptime

input_boolean:                 # one per node; set before hands-on work
  mc_04_maintenance:
    name: "MC 04 maintenance"
    icon: mdi:wrench
  # ... mc_01 ... mc_09

shell_command:
  mc_export_csv: "python3 /config/scripts/mc_export.py"

automation:
  - id: mc_nightly_csv
    alias: "MC nightly CSV export 02:15"
    triggers:
      - trigger: time
        at: "02:15:00"
    actions:
      - action: shell_command.mc_export_csv

InfluxDB writes one measurement per unit (°C, %, ppm, lx, L/min, m, state, …), tag entity_id (without the domain), field value.

Nightly CSV export: /config/scripts/mc_export.py

Writes yesterday (UTC) as microcosm_YYYY-MM-DD.csv to the USB stick (label it MCBACKUP; HAOS mounts it under /media/MCBACKUP) and to /share/microcosm/csv (Samba share, rclone). The InfluxDB password goes in /config/.influx_pass. Re-export any day with python3 /config/scripts/mc_export.py 2026-11-03 from the Studio Code Server terminal. Tested against a mock InfluxDB response.

#!/usr/bin/env python3
"""MICROCOSM nightly export: one UTC day from InfluxDB 1.8 -> long-format CSV.
Usage: python3 /config/scripts/mc_export.py [YYYY-MM-DD]   (default: yesterday UTC)
Columns: timestamp_utc,node,entity,value,unit,quality
"""
import base64, csv, datetime as dt, json, os, re, sys, urllib.parse, urllib.request

INFLUX = "http://a0d7b954-influxdb:8086/query"
DB, USER = "homeassistant", "homeassistant"
PASS = open("/config/.influx_pass").read().strip()
OUTDIRS = [("/media/MCBACKUP", "microcosm/csv"), ("/share", "microcosm/csv")]  # (mount, subdir)
# physical plausibility per unit -> quality RANGE outside it
LIMITS = {"°C": (-10, 60), "%": (0, 100), "ppm": (300, 10000), "lx": (0, 70000),
          "L/min": (0, 10), "m": (-0.05, 1.0), "pH": (2, 12), "µS/cm": (0, 5000)}

day = dt.date.fromisoformat(sys.argv[1]) if len(sys.argv) > 1 else \
    dt.datetime.now(dt.timezone.utc).date() - dt.timedelta(days=1)
t0, t1 = f"{day}T00:00:00Z", f"{day + dt.timedelta(days=1)}T00:00:00Z"

def query(q):
    url = INFLUX + "?" + urllib.parse.urlencode({"db": DB, "q": q, "epoch": "s"})
    req = urllib.request.Request(url)
    tok = base64.b64encode(f"{USER}:{PASS}".encode()).decode()
    req.add_header("Authorization", "Basic " + tok)
    with urllib.request.urlopen(req, timeout=120) as r:
        return json.load(r)["results"][0].get("series", [])

series = query(f"SELECT value FROM /.*/ WHERE entity_id =~ /^mc_/ "
               f"AND time >= '{t0}' AND time < '{t1}' GROUP BY entity_id")

def node_of(ent):
    return re.match(r"mc_\d+b?", ent).group(0)   # mc_04, mc_08b

# maintenance windows: input_boolean.mc_XX_maintenance (1 = on)
maint = {}
for s in series:
    e = s["tags"]["entity_id"]
    if e.endswith("_maintenance"):
        maint[node_of(e)] = sorted((int(t), v) for t, v in s["values"])

def in_maint(node, t):
    state = 0
    for ts, v in maint.get(node, []):
        if ts > t:
            break
        state = v
    return state == 1

rows = []
for s in series:
    unit, ent = s["name"], s["tags"]["entity_id"]
    node = node_of(ent)
    for t, v in s["values"]:
        if v is None:
            continue
        lo, hi = LIMITS.get(unit, (float("-inf"), float("inf")))
        q = "MAINT" if in_maint(node, t) else ("RANGE" if not lo <= v <= hi else "OK")
        ts = dt.datetime.fromtimestamp(t, dt.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
        rows.append((ts, node, ent, v, "" if unit == "state" else unit, q))
rows.sort()

for root, sub in OUTDIRS:
    if not os.path.isdir(root):
        continue                          # USB stick not mounted -> skip
    d = os.path.join(root, sub)
    os.makedirs(d, exist_ok=True)
    with open(os.path.join(d, f"microcosm_{day}.csv"), "w", newline="", encoding="utf-8") as f:
        w = csv.writer(f)
        w.writerow(["timestamp_utc", "node", "entity", "value", "unit", "quality"])
        w.writerows(rows)
print(f"{day}: {len(rows)} rows")

Grafana (one template dashboard for all nine)

Panel InfluxQL
Temperatures SELECT mean("value") FROM "°C" WHERE "entity_id" =~ /^${node}_/ AND $timeFilter GROUP BY time($__interval), "entity_id" fill(null)
Moisture and RH same, FROM "%"
CO2 same, FROM "ppm"
Light same, FROM "lx"
Actuators (state timeline) SELECT last("value") FROM "state" WHERE "entity_id" =~ /^${node}_(grow_light|fan|.*pump|heater_on|mister)$/ AND $timeFilter GROUP BY time(1m), "entity_id"
Data health SELECT mean("value") FROM "dBm" WHERE "entity_id" =~ /^${node}_wifi_rssi/ AND $timeFilter GROUP BY time(10m)

CSV export methods for students

Method Steps Best for
Grafana panel menu → Inspect → Data → options "Series joined by time", "Formatted data" off → Download CSV a figure's exact data, wide format
Chronograf (InfluxDB add-on, teacher session) Explore → SELECT "value" FROM "%" WHERE "entity_id"='mc_04_soil_moisture_a' AND time > now() - 14d → CSV raw values, any range
Flux (only if Flux is enabled, or after a later InfluxDB 2 migration) from(bucket:"homeassistant/autogen") \|> range(start:-7d) \|> filter(fn:(r) => r.entity_id =~ /^mc_04_/ and r._field == "value") \|> aggregateWindow(every:10m, fn:mean) aggregated series
HA History History → pick entities and dates → ⋮ → Download data quick look, last 30 days only
Nightly files Samba share or Google Drive folder microcosm/csv/ the official dataset, long format with quality flags

Naming conventions

Thing Pattern Example
ESPHome device / hostname mc-NN-<shortname> mc-04-future2026
HA device name (friendly_name) MC NN MC 04
Entity id <domain>.mc_NN_<quantity>[_<position>] sensor.mc_04_soil_moisture_a, sensor.mc_07_water_temp
Quantities air_temp, air_rh, co2, illuminance, substrate_temp_<pos>, water_temp, soil_moisture_<pos>, soil_raw_<pos>, water_level, flow_rate, flow_total, ph, ec, level_low_alarm, level_high_alarm, gas_resistance, air_pressure
Positions a–d = probe/plot, documented on the ecosystem map; top/bottom allowed for columns substrate_temp_bottom
HA area ecosystem name Future 2026
Probe labels <node>-<port> <type> <pos> #<last4 ROM or serial> 04-S2 DS18B20 A #2B28

Home Assistant dashboards

Dashboard Content Who
MICROCOSM overview 9 tile cards (one per ecosystem: status colour, key value, last update), plus a "problems" card filtering binary_sensor.mc_* with device class problem that are on everyone, wall display
One view per ecosystem (/microcosm/mc-04) gauges (air T, RH, CO2, soil A/B), history graphs 24 h/7 d, actuator card (light, fan, pump with sliders), heater setpoint + enable + interlock state, experiment-mode buttons (HA scripts), maintenance toggle, link to the Grafana dashboard with ?var-node=mc_04 team + teacher
Admin node diagnostics (RSSI, uptime, FRC buttons, restart), backup status teacher/Alacrity

Experiment-mode buttons are HA scripts. The node firmware still enforces the limits (pump max-run, heater interlock):

script:
  mc_05_rain_event:
    alias: "MC 05 rain event (2 min at 60 %)"
    sequence:
      - action: fan.turn_on
        target:
          entity_id: fan.mc_05_rain_pump
        data:
          percentage: 60
      - delay: "00:02:00"
      - action: fan.turn_off
        target:
          entity_id: fan.mc_05_rain_pump
  mc_05_heatwave_on:
    alias: "MC 05 heatwave (+5 C setpoint)"
    sequence:
      - action: number.set_value
        target:
          entity_id: number.mc_05_heater_setpoint
        data:
          value: "{{ states('number.mc_05_heater_setpoint') | float(25) + 5 }}"
      - action: switch.turn_on
        target:
          entity_id: switch.mc_05_heater_enable

Add a logbook.log step (name, message) to every experiment-mode script so interventions appear in the event log that teams export with their data.

Alerting (Telegram group "MICROCOSM staff"; e-mail via the SMTP integration as fallback)

Set up Settings → Integrations → Telegram bot (polling), with the bot added to the staff group. Alerts go to staff, not to students' private phones.

automation:
  - id: mc_node_offline
    alias: "MC node offline > 15 min"
    triggers:
      - trigger: state
        entity_id:
          - binary_sensor.mc_01_status
          - binary_sensor.mc_02_status
          - binary_sensor.mc_03_status
          - binary_sensor.mc_04_status
          - binary_sensor.mc_05_status
          - binary_sensor.mc_06_status
          - binary_sensor.mc_07_status
          - binary_sensor.mc_08_status
          - binary_sensor.mc_09_status
        to:
          - "off"
          - "unavailable"
        for: "00:15:00"
    actions:
      - action: telegram_bot.send_message
        data:
          message: "MICROCOSM: {{ trigger.to_state.name }} offline for 15 min"

  - id: mc_sensor_nan
    alias: "MC sensor unknown > 10 min"
    triggers:
      - trigger: template
        value_template: >
          {{ states.sensor | selectattr('entity_id', 'match', 'sensor\.mc_')
             | selectattr('state', 'in', ['unknown', 'unavailable']) | list | count > 0 }}
        for: "00:10:00"
    actions:
      - action: telegram_bot.send_message
        data:
          message: >
            MICROCOSM sensors without data:
            {{ states.sensor | selectattr('entity_id', 'match', 'sensor\.mc_')
               | selectattr('state', 'in', ['unknown', 'unavailable'])
               | map(attribute='entity_id') | join(', ') }}

  - id: mc_thresholds
    alias: "MC threshold / interlock"
    triggers:
      - trigger: state
        entity_id:
          - binary_sensor.mc_03_heater_interlock
          - binary_sensor.mc_05_heater_interlock
          - binary_sensor.mc_07_level_low_alarm
        to: "on"
      - trigger: numeric_state
        entity_id:
          - sensor.mc_04_air_temp
          - sensor.mc_05_air_temp
        above: 38
        for: "00:10:00"
      - trigger: numeric_state
        entity_id: sensor.mc_07_water_temp
        above: 28
        for: "00:30:00"
    actions:
      - action: telegram_bot.send_message
        data:
          message: "MICROCOSM alert: {{ trigger.to_state.name }} = {{ trigger.to_state.state }}"

User accounts

Account Type Use
alacrity-admin owner/admin platform maintenance
teacher-<name> (1–2) admin daily operation, ESPHome edits, backups
mc-team-01 … mc-team-09 user (non-admin), "local network only" team dashboards, actuator control, experiment buttons
mc-display user, local only wall-screen kiosk (overview dashboard)

HA has no per-entity permissions, so a team account can technically switch another team's pump. This is acceptable because every safety limit is in node firmware; misuse is a classroom-rule matter. Add-on panels (ESPHome, InfluxDB, terminals) are admin-only.

Data pipeline, retention and backup

flowchart LR
  N["9 nodes - 60 s values"] -->|"native API"| HA["HA Core"]
  HA --> REC["Recorder SQLite - 30 days"]
  HA --> IDB["InfluxDB - autogen, keep forever"]
  IDB --> GF["Grafana dashboards"]
  IDB --> EXP["02:15 mc_export.py - yesterday UTC"]
  EXP --> USB["USB stick MCBACKUP - CSV per day"]
  EXP --> SH["/share/microcosm/csv - Samba"]
  SH --> GD["Google Drive folder - rclone or Drive for Desktop"]
  HA --> BK["03:00 HA full backup, encrypted - incl. InfluxDB add-on data"]
  BK --> GDB["Google Drive backups - keep 14"]
  BK --> LOC["Local copy on the Pi"]

Restore test: once per term, restore the latest backup onto the spare SD64 in a second Pi (or the same Pi with a swapped card), check that dashboards and the last 24 h of InfluxDB data are present, then swap back.

Hub BOM

ID Qty Est. RON each RON Basis
PI5 1 560 560 Pi 5 4 GB ≈ €60–85 board (EU listings checked 2026-10) + official 27 W PSU ≈ 65 + active cooler/case ≈ 60, RO resellers (optimusdigital/robofun)
SD64 2 45 90 A2 64 GB (SanDisk Extreme class), emag; 1 boot/rescue, 1 spare
Free: M.2 HAT+ + 256 GB NVMe (recommended) 1 200 200 RO resellers, estimate
Free: Pi 5 RTC battery 1 30 30 official ML-2020 battery
ROUTER 1 160 160 TP-Link Archer C6/C54 class, emag
Free: Cat6 patch cable 1 m 2 10 20
Free: USB stick 64 GB (MCBACKUP) 2 35 70 one in the Pi, one rotated home by the teacher monthly
Hub subtotal 1 130

Network

The nodes use the school's existing Wi-Fi. No router is bought. What the project needs from school IT, in writing, by 2026-10-23:

Requirement Why
A 2.4 GHz SSID with WPA2-PSK (a plain password), visible in the lab ESP32 has no 5 GHz radio and cannot do WPA2-Enterprise or captive portals
12 DHCP reservations (9 nodes + 3 spares) and one for the Pi, by MAC address Stable addresses for ESPHome and the dashboards
The Pi reachable from student laptops and phones on the school network (port 8123) Dashboards; if client isolation is on, ask for an exception for the Pi's address
Pi on Ethernet if a socket exists in the lab, otherwise Wi-Fi Reliability
NTP and outbound HTTPS allowed for the Pi Time, updates, backups to Google Drive

Setup checklist (30 min): put the SSID and password in secrets.yaml; set manual_ip in each node YAML from the reservation list; check RSSI on every node after placement (acceptance: better than −75 dBm; move the node box or add a 2 m antenna extension if not); label each node box with its name and address.

What happens offline: nodes keep running their own automations and safety logic (heater interlock, pump limits, dry-run guard, light schedule all live in the firmware). Home Assistant schedules and alerts stop until the network returns. Design rule: safety logic is never in the hub. ESPHome's default reboot-on-no-connection is disabled so that a long outage does not restart the nodes.

Fallback: if IT cannot provide the SSID by 2026-10-27, buy a cheap 2.4 GHz router (≈ 160 RON) the same day and run an isolated "MICROCOSM" network with the Pi on its LAN port; the rest of this chapter is unchanged. Remote access, if wanted, is Tailscale (free) on the Pi.

Security basics: the Wi-Fi password may be given to students; the Home Assistant admin password and the ESPHome API keys are not. Students have non-admin Home Assistant accounts. Passwords are rotated at the start of each school year.

Calibration & metrology

General policy

Item Policy
Sampling every sensor read every 60 s (soil: 10 reads at 6 s, averaged; level: median of 6 at 10 s; analog water probes: median of 10 at 6 s)
Stored values the calibrated value and the raw value (soil V, pH V, TDS V) are both stored, so data can be re-calibrated later
Time UTC in all exported data; HA dashboards display local time
Calibration log every calibration goes on a record sheet (below) and in calibration_log.csv (shared folder), and the node is put in maintenance mode while it happens
Re-calibration soil: each new substrate or after 3 months; pH: monthly; TDS: monthly; SCD41: monthly FRC check + after transport; DS18B20 and SHT31: at commissioning and each term

M1. Capacitive soil probes (per probe, per substrate)

  1. Seal first: conformal coating or clear nail varnish over the PCB edge cut and components, heat-shrink over the electronics, mark the max insertion line.
  2. Flash the node; watch sensor.mc_XX_soil_raw_<pos> (V, 60 s average).
  3. Air: probe dry, held in air, 3 min → record V_air (sanity check only, ≈ 2.6–2.8 V at 3.3 V supply).
  4. Dry substrate: 500 mL of the actual substrate, air-dried 3 days on a tray (or 105 °C for 24 h in an oven where available), lightly packed to the planned density in a beaker. Insert to the line, 3 min → V_dry.
  5. Saturated substrate: add water until free water appears at the surface, wait 30 min, re-insert at the same depth, 3 min → V_wet.
  6. Enter dry_v/wet_v in the node YAML (sens-soil.yaml include) → OTA.
  7. Optional (Science track, gravimetric curve): from the dry sample, add water in 4 steps (e.g. 10/20/30/40 % of dry mass), mix, record V and the gravimetric water content (g water/g dry substrate). Fit a curve; this turns "% of saturation" into a real water content.

Output meaning: soil_moisture = relative saturation, 0 % = air-dry, 100 % = saturated, for that substrate. It is not volumetric water content and cannot be compared across substrates unless the gravimetric curve is done.

Record sheet M1

Node Pos Probe label Substrate Date V_air V_dry V_wet Optional points (V : g/g) By

M2. SHT31 cross-check: saturated salt (NaCl) at 75.3 % RH

  1. Small cup with ≈ 30 g table salt (NaCl, no iodine/anti-caking is best) + water dropwise until it is a wet slurry, like wet sand, with undissolved crystals always present.
  2. Cup + sensor (on its cable through the lid, sealed with Blu-Tack) in a 0.5–1 L airtight glass jar. The sensor must not touch the slurry.
  3. Stable room temperature (± 1 °C), out of sunlight, 12–24 h (overnight).
  4. Read air_rh: expected 75.3 % at 20–25 °C. SHT31 spec ±2 % RH → accept 73–78 %. Offset > 3 % → replace or note an offset filter. Also note T vs the reference thermometer.
  5. Optional second point: potassium carbonate K₂CO₃ slurry = 43 % RH.

Record sheet M2

Sensor (node/label) Jar start Read time T (°C) RH read (%) Expected (%) Error Pass?
75.3

M3. DS18B20 ice-water 0 °C check

  1. 1 L insulated cup packed full of crushed ice, filled with cold tap water to just below the ice top, stirred, 5 min.
  2. All probes in together (tips mid-depth, not touching the walls), plus the reference thermometer. 5 min, stirring every minute.
  3. Expected 0.0 °C; spec ±0.5 °C → pass. Write the offset -reading into the probe's offset var only if |error| > 0.2 °C.
  4. Second point: all probes + reference in a stirred room-temperature water bucket, to cross-check that probes agree within 0.3 °C.

Record sheet M3

Probe label ROM last4 Ice reading (°C) Room bath (°C) Reference (°C) Offset set Pass?

M4. SCD41 CO₂: forced recalibration (FRC), and why ASC is off

Record sheet M4

Node Date Location Reading before FRC FRC value Reading after 10 min Side-by-side offset vs mean By
425

M5. pH probe: 2-point (7, then 4), slope check at 10

  1. Rinse the probe in distilled water, blot (don't wipe). Buffers at room temperature, note T.
  2. pH 7.00 buffer, stir gently, wait for stable V (2 min) → V7. Rinse.
  3. pH 4.00 buffer → V4. Rinse. (pH 10 → V10 for a slope check only.)
  4. Set v1: V7, y1: "7.0", v2: V4, y2: "4.0" in the sens-analog.yaml include. Slope should be ≈ 0.17–0.18 V/pH for a Gravity v2 board (≈ 59 mV/pH at the electrode, amplified).
  5. Store the probe in KCl storage solution, never in distilled water. Recalibrate monthly. If pH and TDS probes sit in the same water, read them alternately or fit a galvanic isolator: they interfere.

M6. TDS/EC: 1413 µS/cm standard

  1. 1413 µS/cm solution at 25 °C (or note T); rinse, immerse, 2 min.
  2. The Gravity TDS conversion is EC = (133.42·V³ − 255.86·V² + 857.39·V) × K, with temperature compensation EC25 = EC / (1 + 0.02·(T − 25)) using the water DS18B20 (template sensor in the Hydro node). Adjust K until the reading is 1413 ± 2 %. TDS (ppm) = EC25 × 0.5.
  3. Monthly; probe rinsed and dried after use when not permanently installed.

M7. BH1750 plausibility vs phone lux app

  1. Same position, same angle: BH1750 vs phone app (front camera/ambient light sensor) under (a) room light, (b) the grow light at canopy height, (c) daylight at the window.
  2. Phones are uncalibrated: accept ±30 %. Purpose: catch a dead, saturated (> 54 000 lx default range) or shaded sensor.
  3. Limitation to teach: lux is weighted to the human eye, not PAR. For a white full-spectrum LED, PPFD (µmol·m⁻²·s⁻¹) ≈ lux / 70 is a rough guide only, and only valid for comparing the same light type.

Record sheets M5–M7 use the same layout: node, probe label, date, standard/condition, raw V or reading, set value, pass, by.

Dataset structure

Nightly files microcosm_YYYY-MM-DD.csv, long format, UTF-8, comma-separated:

Column Type Example Meaning
timestamp_utc ISO 8601, Z 2026-11-03T14:05:00Z time HA received the value
node text mc_04 ecosystem node
entity text mc_04_soil_moisture_a full entity object id
value float 41.0 calibrated value (on/off = 1/0)
unit text % unit of measurement (empty for on/off)
quality enum OK OK; RANGE = outside physical limits; MAINT = node in maintenance mode (hands in tank, calibration); CAL and SUSPECT set manually by teams during data review

Companion files in the same shared folder: sensors.csv (entity, probe label, ROM/serial, position, install date, calibration ref), calibration_log.csv (sheet rows M1–M7), events_log.csv (timestamp_utc, node, event, by: watering, feeding, salt added, experiment start/stop. HA logbook entries are exported here as well).

Data dictionary (base entities)

Entity suffix Unit Sensor Resolution / accuracy Valid range
air_temp °C SHT31 (BME680 in Rot) 0.01 / ±0.3 °C −10…60
air_rh % SHT31 (BME680) 0.01 / ±2 % RH 0…100
co2 ppm SCD41 1 / ±(40 ppm + 5 %) 400…5000 spec
co2_sensor_temp, co2_sensor_rh °C, % SCD41 (diagnostic; self-heated) — —
illuminance lx BH1750 1 / ±20 % 0…54 612
substrate_temp_<pos>, water_temp °C DS18B20 0.0625 / ±0.5 °C −10…85
soil_moisture_<pos> % rel. saturation capacitive v2.0 1 / see M1 0…100
soil_raw_<pos> V ADC1 0.001 0.15…3.1
water_level m JSN-SR04T 0.005 / ±1 cm 0…tank depth
flow_rate, flow_total L/min, L YF-S401 ±10 % uncalibrated, ±3 % calibrated 0.3…6 L/min
ph pH Gravity pH v2 / PH-4502C 0.01 / ±0.1 after cal. 2…12
ec µS/cm Gravity TDS ±10 % 0…5000
gas_resistance Ω BME680 relative only —
level_low_alarm, level_high_alarm on/off float switches — —
grow_light on/off (brightness in HA history) MOSFET PWM1 — —
fan, *_pump on/off (+ speed %) MOSFET PWM2/3 — —
heater_on, heater_interlock on/off template — —
wifi_rssi dBm ESP32 — −100…−30

Commissioning & acceptance

Per-node checklist (sign-off by teacher + team)

# Check Pass criterion ☐
1 QA checklist of the assembly session all 12 items passed ☐
2 Power brick on the RCD strip, drip loop, box above water line, glands down ☐
3 Wi-Fi RSSI > −75 dBm at the final position (OLED), reserved IP ☐
4 Entities every expected entity in HA reports a plausible value within 2 min; ids match the naming table ☐
5 OLED name, "HA ok", T/RH, two team values ☐
6 Actuators dry-run each actuator on/off and 30/60/100 % from HA; direction/flow correct; no water spilled ☐
7 Interlocks tested heater: unplug the DS18B20 → heater_interlock on and pad off within 10 s; warm the probe in hand-hot water (> 45 °C) → trip. Pump: max-run timer stops it; float low → dry-run guard stops it. Mister timeout. ☐
8 Offline test unplug the Pi Ethernet 20 min: photoperiod and thermostat continue, the node does not reboot, data gap only ☐
9 Calibrations records M1–M4 (and M5/M6 where fitted) filled ☐
10 24 h soak 24 h with the full biology/water: no gaps > 5 min in Grafana, no NaN, no alert except expected, box interior dry ☐
11 Documentation port sticker, photo, sensors.csv rows, YAML committed/backed up ☐

Per-hub checklist

# Check ☐
1 HAOS/Core/add-ons updated; all add-ons start on boot and have the watchdog on ☐
2 Pi on Ethernet, .10 reserved, RTC battery fitted (clock correct after 5 min unplugged from WAN and power) ☐
3 InfluxDB receiving all mc_* entities (Chronograf: SHOW TAG VALUES FROM "°C" WITH KEY = "entity_id") ☐
4 Grafana template dashboard works for all 9 node values; anonymous viewer works from a student laptop ☐
5 Nightly CSV produced on the USB stick and the share; opened in a spreadsheet; quality flags present ☐
6 Backup to Google Drive succeeded; restore test done on the spare SD ☐
7 Alerts: test message reaches the Telegram group; node-offline alert fires after 15 min ☐
8 Accounts: admins with 2FA, 9 team accounts + display, local-only ☐
9 Power-cut test: switch off the RCD strip 1 min → everything returns unattended within 5 min, actuators in safe state ☐

"Day-one data review" session (45 min, the day after each 24 h soak; repeat weekly in the first month)

Min Activity
0–5 Each team opens its Grafana dashboard for the last 24 h.
5–20 Checklist per team: (1) any gaps? (2) does each value make physical sense (T vs room, RH vs watering, CO₂ day/night, light matches schedule)? (3) do replicate probes agree? (4) do actuator events match changes in sensors (pump on → moisture up)?
20–30 Each team marks up to 3 anomalies in events_log.csv / sets SUSPECT flags, and writes one hypothesis for each anomaly (sensor fault vs real biology).
30–40 2-min report per team; teacher collects hardware issues into the fault log.
40–45 Decide fixes, assign owners, re-check at the next session.

Spare-parts policy

Item Spares held Rule
ESP32 3 (mc-10…12, pre-flashed with a base test config) a failed node is swapped in < 15 min: move the YAML name/key, OTA, re-adopt
Each sensor type (SHT31, SCD41, BH1750, BME680, JSN, FLOW) 1 DS18B20, SOIL, FLOAT, SERVO: 2 each
PSU12 1 plus 2 × PSU5 for bench work
BUCK, MOSFET, RELAY 3, 5, 2 in the spares box
SD64, USB stick 1, 1 cloned rescue card
Restock when a spare is used, reorder within 1 week (fault log entry)

Safety

Lab wall sheet: "MICROCOSM electrical & water safety rules" (print A4, laminate)

  1. Only 12 V (24 V for misters) inside or near the ecosystems. Nothing that plugs into a wall socket goes into an enclosure, into water or into soil.
  2. 230 V devices are only certified, closed products (power bricks, Pi charger, LED panel, air pump, smart plugs). Never open, cut, extend or repair them. No relay modules on 230 V, ever.
  3. All 230 V plugs live on the RCD-protected strip on the high shelf. Only the teacher plugs or unplugs at that strip.
  4. Every cable has a drip loop (a U-shaped dip below the socket/box) so water runs off the bottom of the loop, not into the plug or box.
  5. Before hands go into water or substrate: turn on maintenance mode in HA, unplug that node's 12 V DC jack at the box, switch the smart-plugged devices off at the plug, and hang the "OFF – working" tag on it.
  6. Dry hands, dry bench. No drinks on the electronics bench. Wipe spills before touching anything electrical.
  7. Node boxes stay closed, glands tight, above the water line. Open a box only after unplugging its brick.
  8. Power off before connecting or disconnecting anything. Check polarity, and check 5 V before inserting an ESP32.
  9. Heaters only through the node (interlock on, thermal fuse fitted). Never cover a heat pad or run one outside the enclosure.
  10. Smell, heat, smoke, a tingle, a warm brick or a cracked cable: stop, step back, call the teacher. The teacher switches off the RCD strip and logs the incident.

RCD and power distribution

Mains device list and placement

Device Qty Location Switched by
PSU12 12 V 5 A bricks 9 (+1 spare) shelf; low-voltage lead down to the node box with a drip loop not switched (always on)
Mister 24 V adapters 2 shelf 24 V side via node relay
Pi 5 27 W PSU 1 shelf, next to the Pi —
LEDPANEL 30–45 W (Hydro) 1 hanging ≥ 30 cm above the open hydro top, cord routed up to the shelf SMARTPLUG (own timer)
AIRPUMP (Hydro, EcoColumn if used) 1–2 shelf above the water level, with an anti-siphon loop/check valve in the air line SMARTPLUG
Smart plugs 2–3 on the RCD strip HA + local timer

Shelf: wall-mounted, top surface ≥ 40 cm above the tops of the tanks, front edge set back so that no open water is directly beneath it, bricks fixed with velcro or cable ties so they cannot fall. Cables run along the wall in a trunking/cable tray, never across walkways or over tank openings, and are fixed every 30 cm.

Who may plug and unplug what

Action Students Teacher
Plug/unplug at the 230 V strip, RCD test no yes
Toggle smart plugs from HA yes (own ecosystem) yes
12 V DC jack at the node box, JST/sensor connectors (power off) yes, after the maintenance-mode step yes
Open a node box with teacher present, brick unplugged yes
Change firmware via teacher/admin session yes

Platform BOM

The platform parts (nodes, hub, power, spares, tools) are priced in Chapter 6 together with everything else; the quantities there are the ones to order. One node core (ESP32, breakout, box, glands, buck, OLED, cable kit) costs about 250 RON; the hub (Pi 5 kit, SD cards, backup stick) about 700 RON.

4. Sensor and actuator policy

The proposal asked: "useful vs unnecessary sensors". The answer depends on what each ecosystem is trying to measure, so this chapter allocates by need, not by headcount.

4.1 Useful, unnecessary, and wrong

Sensor or actuator Verdict Where it earns its place Notes
SHT31 air T/RH (PTFE-membrane breakout) Useful, core Every enclosure with air to measure except Rot and EcoColumn Survives weeks at 95–100 % RH; BME280/BME680 humidity elements do not
BME680 Useful only for "smell" Rot (before and after the carbon filter) Gas resistance is a VOC proxy, not CO2; its T/RH drifts in wet air
SCD41 NDIR CO2 Useful, high value Rot, Living Earth (respiration tests), 2026 and 2056 (paired), Time Capsule (optional, recommended) Disable automatic self-calibration in sealed tanks; forced recalibration outdoors at 420 ppm
DS18B20 waterproof Useful, core Substrate core, water, under paving, thermostat feedback Cheap enough to put two where one would do
BH1750 lux Useful Every enclosure with plants or algae Lux, not PAR; fine for relative comparisons and for proving the LED schedule ran
Capacitive soil moisture v2.0 Useful with mitigation Every substrate Coat the top edge, calibrate per probe per substrate, average 10 samples; 24 units for replicates and spares
Float switch Useful, essential interlock Every reservoir (low), every pond (high) One bit, but it is the bit that stops a pump from running dry or flooding a desk
JSN-SR04T ultrasonic level Useful EcoColumn pond, hydroponics reservoir Mount in a PVC stilling tube; ignore out-of-range readings
YF-S401 flow Marginal EcoColumn rain line Starts at 0.3 L/min; rain volume is better computed from pump run time after a bucket calibration. Kept at 2 because approved and cheap
Analog pH kit Useful, needs care Hydroponics, EcoColumn pond Drifts; 2-point calibration weekly; storage solution; cross-check with pen
TDS/EC module Useful Hydroponics Never read at the same instant as the pH probe in the same water (ground loop); alternate readings
Turbidity module Useful EcoColumn pond The science is sediment and algae; this is the sensor for it
Handheld pH pen and TDS pen Useful, best value All ecosystems (soil 1:5 extract) More reliable than continuous probes everywhere; teaches the method
Dissolved oxygen probe Unnecessary – 1 000+ RON; aeration is verified by behaviour and by air pump power monitoring
Water-flow sensor on hydroponics Unnecessary – Circulation pump duty cycle is logged instead
Soil probe in hydroponics Wrong – Proposal implied one per ecosystem
Lux sensor in Rot Unnecessary – Decomposition is dark; the lid is opaque
OLED SSD1306 Useful Every node Students see the numbers at the tank, not only on a screen
SD card + RTC on every node Unnecessary Time Capsule node and two advanced spare boards only Hub logging is primary; local logging where independence from the hub matters
Relay module Low-voltage only 24 V mister switching Never on mains
Smart plug (COTS) Useful, the only mains switch Hydroponics LED panel and air pump; optional on any 12 V brick Reports power, which doubles as a "is the air pump running" sensor
12 V PC fan Useful Rot (filtered exhaust), Brownfield, 2026, 2056, Hydroponics, Bog Quiet, cheap, PWM-dimmable
12 V submersible pump Useful EcoColumn rain, 2026 and 2056 irrigation, Hydroponics circulation, Time Capsule sump 3–5 W; 12 V only
12 V peristaltic pump Useful Hydroponics dosing (nutrient, pH-down) With daily pen cross-checks and dose caps
12 V silicone heat pad Useful, with cut-offs 2056 (+3.5 °C), Brownfield (heat island), 1 spare DS18B20 loop in firmware, 45 °C thermostat, one-shot thermal fuse
Ultrasonic mister Useful, limited Rot, 2056 (or Bog) 24 V adapter; distilled water only; weekly cleaning
Aquarium air pump (230 V COTS) Useful Hydroponics (DWC), EcoColumn pond (optional) On the shelf, through a smart plug; only the air line enters the water
SG90 servo Useful, small Rot intake flap, EcoColumn rain gate, Living Earth chamber lid (phase 2), spare 4 approved, 4 used
12 V full-spectrum LED strip in profile Useful, core Every enclosure with plants or algae SELV, PWM-dimmable, cut to length; replaces "grow lights 5–10 W"
230 V LED grow panel Useful, one only Hydroponics, hung at 30 cm or more above the open top Own cord, smart plug, RCD strip

4.2 Allocation matrix

The matrix below is the result of the nine ecosystem designs in Chapter 5 after the cost-cut pass of 2026-10-20. "Spare" is the project-wide spare pool.

ID 1 Rot 2 Eco 3 Brown 4–5 Future 6 Regolith 7 Hydro 8 Soil 9 Capsule Used Spare Buy
ESP32 1 1 1 2 1 1 1 1 9 3 12
TERMBOARD 1 1 1 2 1 1 1 1 9 1 10
OLED 1 1 1 2 1 1 1 1 9 3 12
SHT31 1 2 1 1 1 1 7 1 8
BME680 2 2 0 2
SCD41 1 2 1 4 0 4
DS18B20 1 1 2 4 1 1 2 2 14 1 15
SOIL 2 2 4 4 3 3 2 20 2 22
BH1750 1 1 2 1 1 1 1 8 1 9
FLOAT 2 4 2 8 2 10
JSN 1 1 2 0 2
FLOW 1 1 1 2
PHKIT 1 1 2 0 2
TDS 1 1 0 1
TURB 2 2 0 2
CALSOL 1 1 2 0 2
FAN 1 1 2 1 1 6 0 6
PUMP 1 2 2 5 0 5
PERI 3 3 0 3
HEATPAD 1 2 3 1 4
MIST 1 1 2 0 2
AIRPUMP 1 1 0 1
LEDSTRIP 1 0.25 1 1 0.25 1 4.5 0 4
LEDPROFILE 5 2 3 2 2 2 16 0 16
LEDPANEL 1 1 0 1
SERVO 1 1 4 1 7 1 8
MOSFET 1 3 3 8 2 4 2 2 25 2 27
RELAY 1 2 2 1 6 0 6
PSU12 1 1 1 2 1 1 1 1 9 0 9
PSU5 1 1 1 2
BUCK 1 1 1 2 1 1 1 8 2 10
SMARTPLUG 2 2 0 2
BOX 1 1 1 2 1 1 1 1 9 0 9
GLAND 14 10 6 22 6 12 6 6 82 0 80
TANK25 1 1 0 1
TANK45 1 2 3 0 3
TANK63 1 1 1 1 4 0 4
ACRYLIC 0.6 1 1 1 1 1 0.25 5.85 0 6
MESH 0.25 0.25 0.1 0.25 0.1 0.25 0.25 1.45 0.8 3
SILICONE 1 1 1 1 1 1 6 0 6
TUBING 1 5 8 6 2 22 0 22
RESERVOIR 1 1 2 1 5 0 5
BOXPLASTIC 2 1 3 0 3
SD64 1 1 0 2
RTC 1 1 1 2
SDMOD 1 1 1 2
PI5 hub – 1
PHPEN / TDSPEN shared shared shared shared shared shared shared shared – – 2 / 1

Notes: LEDSTRIP is in 5 m reels (fractions are shares of a reel; about 14 m are actually cut, so 4 reels suffice); ACRYLIC in 50×100 cm panels (1 polycarbonate sheet gives 4, plus 2 acrylic panels); MESH in m²; TUBING in m; GLAND 80 covers 82 planned holes because several designs over-counted spares. The Carnivorous Bog alternative (Section 5.8b) is not counted; if chosen instead of Living Earth, its sub-BOM replaces that column. The Time Capsule's SCD41 is deferred to 2027 and not in the Buy column.

4.3 Automation policy

Automation is applied only where it serves a hypothesis or protects the system. Everything else stays manual and measured, because a student pouring 150 mL from a measuring cylinder and writing it down learns more than a pump that runs on a schedule.

Ecosystem Automated Manual by design
Rot Filtered exhaust fan on humidity and VOC; mister on humidity; nightly automatic respiration test (servo closes intake) Feeding, litter-bag harvest, moisture samples
EcoColumn Rain events (pump run with flow count, floats as interlocks); LED schedule Fertiliser dosing, sediment collection, filter swaps
Brownfield Heat island (heat pad thermostat with cut-offs); fan; LED schedule Watering with measured volumes, salt and pH treatments, soil extracts
2026 Steady irrigation schedule; fan; LED schedule Observations, harvests
2056 Heating loop; drought and extreme-rain calendar; CO2 vent and seal logic; humidity fan; LED schedule CO2 generator refresh, observations, harvests
Forests in Space LED schedule only Watering with measured volumes, everything else
Hydroponics Light, air pump (via smart plug), circulation duty, pH and nutrient dosing with caps and lockouts, level top-up Reservoir changes, pen cross-checks, harvests
Living Earth LED schedule; respiration-test mode (button starts, slope computed, alert when done) Tea-bag burial, Berlese extraction, rhizotron photos
Time Capsule LED 12 h/day with a timer-plug fallback; alerts; optional sump top-up Everything else, by design, for ten years

4.4 Spare capacity

After the cost-cut pass the spare pool is deliberately thin. It covers the failures that are common and cheap; anything else is a same-week purchase from a Romanian shop.

Spare Qty Purpose
ESP32 boards 3 Approved quantity; any node swap in minutes; advanced Arduino track
SHT31, BH1750, DS18B20 1 each One failure never stops an experiment
Soil probes 2 The most failure-prone sensor
Float switches, MOSFET modules, buck modules 2 each Power-side and interlock failures are the most common
Heat pad 1 2–3 week lead time from AliExpress justifies one spare
5 V USB adapter, servo, flow sensor, RTC, SD module 1 each Cheap
Not held – CO2 sensors, pumps, 12 V bricks, fans, air pump, tanks: buy on failure (all in stock in Bucharest shops)

5. Ecosystem designs

Each design follows the same template: concept, science track, engineering track, enclosure and build, biology, instrumentation, automation, operations, safety, educational outcomes, sub-BOM, timeline. Catalog IDs refer to the parts catalog in Chapter 6.

1. The Orchestra of Rot

Concept (refined)

A 45 L glass tank (TANK45) holds a living decomposer community: compost worms, two woodlouse species, springtails, oyster-mushroom mycelium and a compost/leaf-mould microbial inoculum. It sits on a moist, layered bed with a randomised grid of labelled litter bags buried in it. Each bag holds 3.00 g of one dry material (lime leaves, cardboard, cotton, bread, orange peel, or PE plastic as the control). Students measure how fast each material disappears, whether the animals speed it up (coarse- vs fine-mesh bags), and how the community "breathes" (CO2 production rate from a closed-lid test) and "smells" (BME680 gas resistance before and after an activated-carbon filter). Over the 8 weeks they will see bread and orange peel moulder and collapse, white mycelium spreading through cardboard, worms and isopods moving into coarse bags, and a measurable daily respiration curve. Leaves, cardboard and cotton are slow, so the clear differences between those materials and between mesh sizes only show up in the spring 2027 runs.

Node: mc-01-rot. Team: 3–4 students (one each for biology lead, data lead, engineering lead and logbook/QA).

Science track

Driving question: Which everyday materials does a decomposer community recycle fastest, which members of the "orchestra" do the work, and how do moisture and temperature change the tempo?

Hypotheses (testable)

Variables

Type H1 H2 H3
Independent material (6 levels) mesh size (5 mm vs 1 mm) feeding event (before/after); core temperature
Dependent % dry-mass loss, decay constant k, Visual Decomposition Index (VDI 0–5) % mass loss, animals counted inside bags CO2 rate (ppm/min → mg CO2/h), gas resistance ratio R/R0
Controlled 3.00 ± 0.02 g dry material per bag, bag size 6×6 cm, burial depth 5 cm, same tank/substrate, same duration, randomised positions same as H1 test length 30 min, fan/mister off, intake closed, same time of day (02:00 automatic + 12:00 manual)

Replication & controls (litter-bag method)

Sampling schedule

What When How
Sensors (CO2, T, RH, gas resistance ×2, core T, soil A/B) every 60 s, automatic ESPHome → Home Assistant → InfluxDB
Automatic respiration test nightly 02:00–02:30 servo closes intake, fan and mister off, CO2 slope computed on the node
Manual respiration test Tue + Fri 12:00 protocol below, logged on paper and in Grafana
Window-bag VDI photo Mon/Wed/Fri phone on a fixed cardboard jig 20 cm from glass, same lamp
Substrate pH (1:5 extract) weekly, Monday 10 g fresh substrate + 50 mL distilled water, shake 1 min, settle 30 min, shared PHPEN
Gravimetric moisture weekly 20 g sample from 2–4 cm and 9–11 cm depth, dried 60 °C 24 h → % water (wet basis)
Invertebrate bait count weekly, Thursday 3 carrot slices (3×3 cm) on the surface, lifted after 24 h; count springtails, isopods and worms under each
Isopod hide count weekly lift both cork pieces, count Porcellio / Armadillidium
Sniff panel weekly, Friday 3 students, blind, rate odour 0–3 at 30 cm from the lid and at the exhaust
Litter-bag harvest Run 1: 14 Dec; Run 2: 15 Mar lift bag, count animals inside, rinse over a 2 mm sieve, dry, weigh

Visual Decomposition Index (VDI): 0 = intact; 1 = discoloured or mould visible; 2 = softened, < 25 % fragmented; 3 = 25–50 % fragmented or holes; 4 = > 50 % gone, shape lost; 5 = unrecognisable or gone.

Analysis

Expected outcomes and when

Material (coarse) by 14 Dec (28 d) by March (Run 2, 90 d)
Bread 40–80 % loss, heavy mould, VDI 4–5 gone
Orange peel 20–50 %, VDI 3 60–90 %
Lime leaves 8–20 % (fine mesh 5–12 %) 30–60 %
Cardboard 10–25 % 40–80 %
Cotton 5–25 % (very variable) 30–80 %
PE 0 ± 2 % 0 ± 2 %

These are planning estimates for 20–23 °C and moist substrate. By mid-December, H1 is supported at the fast end only (bread and peel versus the rest). H2 will probably not be significant after 28 days and needs Run 2. H3a should be visible within 2 weeks of starting feeding. H3b needs the winter temperature range, so it shows by February. Expected respiration: 5–60 ppm/min headspace rise, i.e. roughly 10–100 mg CO2/h for the whole tank.

Engineering track

Problem statement: Design an indoor biological recycling unit, no bigger than a 50×30 cm shelf footprint, that processes the most class fruit/vegetable scraps per week. Along the way it must not release noticeable odour, must not let fungus gnats escape, and must keep the community aerobic and alive with ≤ 10 min of student work per school day.

Requirements and constraints

# Requirement Measure Target
R1 Throughput g fresh scraps fully processed per week (no recognisable food after 7 days) ≥ 200 g/week by week 8
R2 Odour outside sniff score at 30 cm; post-filter BME680 ratio R_out/R_room ≤ 1 of 3; ≥ 0.85
R3 Aerobic headspace CO2 median; H2S/sour smell < 2000 ppm, never > 5000; none
R4 Moisture substrate water, wet basis (gravimetric); headspace RH 60–75 %; 80–92 %
R5 Temperature core DS18B20 15–28 °C
R6 Containment gnats on the external yellow sticky card per week ≤ 3
R7 Energy/noise fan Wh/day; noise at 1 m ≤ 15 Wh/day; ≤ 35 dB(A) (phone app)
C Constraints SELV inside only (12 V fan/servo, 24 V mister); mains only as COTS bricks on the shelf; budget = sub-BOM; no change to the bag grid during a run –

Candidate solutions (students compare these, not just build them)

Sub-problem Option A Option B Option C
Odour passive vent: Ø 50 mm hole + mesh activated-carbon tube (75 g, 10 cm bed) + 12 V 80 mm fan running continuously at 30 % carbon tube + fan triggered by VOC/CO2 (state machine below)
Moisture hand spray bottle, mL logged 24 V ultrasonic mister in an external reservoir, fog drawn through the intake by the exhaust fan, RH loop wick/drip from reservoir (rejected for v1: risk of waterlogging)
Aeration 2 perforated Ø 20 mm PVC aeration tubes (passive chimney) weekly hand-turning of the feeding zone only, with a fork, to 8 cm depth (never the bag grid) scheduled fan exchange: 5 min every 30 min
Compartments single bed perforated acrylic divider (29×16 cm, Ø 10 mm holes on a 3 cm grid): left = feeding zone, right = undisturbed bag field stacked migration tray for harvesting vermicompost (spring v4, in a BOXPLASTIC)

Test criteria and methods

Iteration plan

Version Dates Change Data used to decide
v1 baseline 16–22 Nov passive vent, hand spray, fan off sniff score, R_in, RH, CO2
v2 23 Nov–2 Dec carbon + fan: continuous 30 % (odd days) vs VOC-triggered (even days) E, Wh/day, sniff score, RH drop
v3 3–11 Dec mister RH loop + servo intake damper, enabling automatic nightly respiration test RH SD, soil A trend, test success rate
v4 Jan–Mar 2027 student choice: carbon bed depth, divider feeding regime (chopped < 1 cm vs whole scraps), raising throughput to 300 g/week R1–R6

Enclosure & build

Tank: TANK45, glass 50×30×30 cm (≈ 45 L), internal floor ≈ 49×29 cm. It sits on a bench at 75 cm height. Directly above it, on a wall shelf at ≥ 120 cm, are the RCD (30 mA) power strip, PSU12 and the mister's 24 V adapter, with a drip loop on every cable.

Layers (bottom → top)

Layer Depth Volume Material
Drainage / leachate sump 3 cm 4.3 L LECA (expanded clay) 8–16 mm, rinsed
Separator – 50×30 cm fibreglass MESH (stops worms entering the sump)
Substrate, lower 7 cm 10 L substrate recipe (see Biology)
Litter-bag plane at 5 cm below the surface – 27 grid bags + 6 window bags, tags on lines to the surface
Substrate, upper 5 cm 7 L same recipe
Leaf-litter top 2–3 cm 2 L whole dry lime/maple leaves, 2 cork-bark hides 10×10 cm
Headspace ≈ 12 cm ≈ 17 L air, sensors under the lid

Two aeration tubes (Ø 20 mm PVC conduit, 25 cm long, 5 mm holes every 2 cm on the lower 15 cm, bottom capped, mesh-covered top) stand in the rear corners, touching the LECA. They double as leachate check and siphon ports: a 6 mm TUBING line and a 60 mL syringe go down one tube.

Lid (from ACRYLIC 3 mm): 50×30 cm in two pieces, sitting on 9×6 mm EPDM foam tape stuck around the rim (this seal makes the respiration test possible).

Node box: BOX (IP65, 150×110×70 mm) on an acrylic L-bracket screwed to the bench back wall, its bottom 10 cm above the tank rim, right side. Glands on the underside, cables with drip loops. The box holds the TERMBOARD + ESP32, BUCK (12 → 5 V), MOSFET (fan), RELAY (24 V mister) and the OLED behind a siliconed clear-acrylic window in the box lid.

Mister reservoir: RESERVOIR 10 L on the bench, left of the tank, below the node box. MIST float inside. Two holes in the reservoir lid: a 10 mm meshed fresh-air inlet and a 20 mm fog outlet → 60 cm of 16 mm hose → tank intake. Fog is drawn in by the exhaust fan running at 25–30 %.

flowchart TB
  subgraph SHELF["Wall shelf above, mains zone, RCD 30 mA strip"]
    PSU["PSU12 12 V 5 A brick"]
    AD24["Mister 24 V adapter"]
  end
  subgraph NODE["Node box mc-01-rot IP65"]
    ESP["ESP32 on TERMBOARD + OLED"]
    BUCK["BUCK 12 to 5 V"]
    MOS["MOSFET fan GPIO17"]
    REL["RELAY mister GPIO23"]
  end
  subgraph LID["Acrylic lid with EPDM gasket"]
    EXH["Exhaust tube with 75 g carbon"]
    FAN["FAN 80 mm 12 V"]
    BME2["BME680 no.2 post-filter 0x76"]
    SERVO["SG90 intake damper GPIO26"]
    UNDER["SCD41 and BME680 no.1 under lid"]
  end
  subgraph TANK["TANK45 50x30x30 cm"]
    HEAD["Headspace about 17 L"]
    LITTER["Leaf litter 2-3 cm, cork hides"]
    BAGS["Litter-bag plane at 5 cm, 27 + 6 window bags"]
    SOILA["SOIL A feeding zone GPIO32"]
    SOILB["SOIL B bag field GPIO33"]
    DS["DS18B20 core at 8 cm GPIO4"]
    LECA["LECA sump 3 cm"]
    AER["2 aeration and leachate tubes"]
  end
  RES["RESERVOIR 10 L with MIST float"]
  PSU --> BUCK --> ESP
  PSU --> MOS --> FAN
  AD24 --> REL --> RES
  RES -- "fog hose 16 mm" --> SERVO --> HEAD
  HEAD --> EXH --> FAN --> BME2
  UNDER --> ESP
  BME2 --> ESP
  SOILA --> ESP
  SOILB --> ESP
  DS --> ESP
  ESP --> SERVO

Step-by-step build (≈ 14 h of team time over weeks 1–3)

# Step Time Tools
1 Clean the tank (water + vinegar, no detergent), dry, check the rim is flat 20 min cloth, spirit level
2 Mark and cut the lid: 50×10 and 50×20 cm, plus the divider 29×16 cm and an 8×8 cm fan plate. Score 8–10 times, snap over the bench edge 60 min acrylic scoring knife, steel ruler, clamps, safety glasses
3 Drill: Ø 50 mm (hole saw, slow, wood backing), Ø 20 mm, 4 × Ø 12.5 mm (PG7), M3 hinge holes, divider Ø 10 mm holes 75 min cordless drill (teacher), step drill, hole saw, deburring tool
4 Glue the cleats under the fixed strip, apply EPDM tape to the rim, fit the hinges and knob. Silicone cures 24 h 45 min SILICONE, gun, screwdriver
5 Build the exhaust tube: drill the end cap with 15 × Ø 6 mm holes, add mesh discs, rinse and dry the carbon, fill 75 g, fit the fan plate and fan, BME680 #2 cap 60 min hacksaw, file, scale
6 Make 2 aeration tubes (drill holes, cap the bottoms, mesh the tops) 30 min drill 5 mm
7 Fit the servo damper: flap 3×3 cm acrylic on the servo horn, foam pad on the port, servo screwed to the lid 40 min M2 screws, hot-melt glue (outside only)
8 Node box: drill 10 × PG7 holes, mount TERMBOARD, BUCK (set to 5.0 V before connecting the ESP32), MOSFET, RELAY, OLED window. Wire with ferrules and label every cable 2.5 h multimeter, ferrule crimper, wire stripper, label tape
9 Flash ESPHome, bench-test every sensor and actuator, run BME680 burn-in for 48 h on the bench 2 h + 48 h laptop, USB cable
10 Seal the soil probes (conformal coat + heat-shrink over the top edge), calibrate soil probes and DS18B20 (see Instrumentation) 90 min heat gun, cups, oven-dried substrate
11 Make litter bags: cut mesh 13×7 cm, fold, sew 3 sides, fill 3.00 g, sew shut, attach the tag line. 33 grid/window bags + 6 travel bags, plus 27 for Run 2 later 3 h (whole team) scissors, needle, fishing line, 0.01 g scale
12 Layer the tank: LECA, mesh, lower substrate, aeration tubes, divider, probes, rest 3 days to settle 60 min gloves, trowel, measuring jug
13 Mount the node box and reservoir, route cables (drip loops, no cable over the open lid edge), connect the fog hose 45 min cable ties, adhesive cable clips

Biology

Organisms and Romanian sourcing

Organism Common name (EN / RO) Qty Role Source in Romania
Eisenia fetida red wiggler / râmă roșie californiană 150 g (≈ 300–400 worms) shred and digest scraps, mix the bed vermicompost (lombricultură) farms and OLX ads for "râme californiene"; fishing-bait shops sell small boxes (check the species is E. fetida, not Dendrobaena)
Porcellio scaber common rough woodlouse / porcușor de pământ 15–20 shred leaf litter, cardboard collect free from under logs/bark in the school garden (uncontaminated site), or buy a culture from terraristics shops/OLX ("izopode")
Armadillidium vulgare pill woodlouse / porcușor ghem 15–20 same, more drought-tolerant; easy to tell apart for counting as above (common in Bucharest gardens)
Folsomia candida white springtail / colembole 1 culture (≈ 200 mL) graze fungi and mould, suppress mould blooms terrarium/bioactive shops and OLX ("colembole")
Pleurotus ostreatus oyster mushroom / păstrăv de fag 500 g grain spawn (100 g used, the rest for Run 2 and spares) white-rot fungus that breaks down lignin and cellulose mushroom-growing suppliers / agro shops and eMAG ("miceliu pleurotus")
Microbes compost and leaf-mould bacteria/fungi 1 L mature compost + 0.5 L leaf mould inoculum school garden compost or the worm supplier's vermicompost; leaf mould from under the school's trees

No vertebrates. Isopods and worms are invertebrates, which is compliant with the brief.

Substrate recipe (≈ 17 L, made in a 30–60 L tub; wear gloves)

Establishment and acclimation

  1. Day 0 (Nov 9): layer the bed, insert the probes, close the lid, run the fan base schedule. Watch CO2, T and soil for 3 days. The core must stay < 30 °C; if it heats up, the bed is too rich, so mix in 1 L dry cardboard.
  2. Day 0: start a Pleurotus pocket in a separate 2 L lidded box. 200 g cardboard is soaked in boiling water for 1 h (pasteurisation), cooled and drained, then layered with 50 g spawn. It sits in the dark at room temperature for 2–3 weeks until white. Half goes into the tank on Dec 1 (rear-right corner, 5 cm deep); the rest makes the Run 2 "pre-colonised cardboard" bags.
  3. Day 3 (Nov 12): add the worms on the surface under room light. They burrow in within 30 min; any that stay on the surface after 2 h mean conditions are wrong (check moisture and pH). Day 4: add the springtail culture and the isopods under the cork hides.
  4. Days 3–7: no feeding beyond the bed's own cardboard and leaves. Weekly checks start.
  5. Nov 16: bury the Run 1 bags in the randomised map, then start feeding.

Feeding (left feeding zone only, rotate among 4 pockets, bury 2–3 cm under the litter)

Hygiene

Instrumentation

Catalog ID Qty Placement (exact) Interval Purpose
SCD41 1 under the fixed lid strip, centre, 2 cm below the lid (≈ 10 cm above the litter) 60 s (periodic mode) headspace CO2 = community respiration; also T/RH for the humidity loop
BME680 2 #1 (0x77): next to the SCD41, raw headspace air. #2 (0x76): 3 cm above the fan outlet, post-carbon air 60 s (heater 320 °C / 150 ms) "smell" (VOC proxy) in and out of the filter; P, T, RH
DS18B20 1 vertical, tip at 8 cm depth, centre of the bag field (between grid cells) 60 s compost core temperature (Q10, overheating alarm)
SOIL 2 A: feeding zone, 10 cm from the left wall, vertical to the probe line (senses ≈ 0–6 cm). B: bag field, 12 cm from the right wall, same depth 60 s, mean of 10 reads moisture in the fed vs undisturbed compartment
OLED 1 node box lid window 5 s refresh live CO2, R/R0, core T, soil A/B, mode, Wi-Fi
FAN 1 top of the exhaust tube PWM odour venting, aeration, drawing fog in
MIST 1 in the 10 L reservoir relay on/off headspace RH
SERVO 1 top of the lid, intake damper on demand seals the intake for respiration tests
Shared – PHPEN (team pool), 0.01 g scale weekly substrate pH, bag masses

What the BME680 does and does not measure. Its gas channel is a heated metal-oxide (MOX) film whose electrical resistance drops when reducing gases are present: ethanol, acetone, aldehydes, esters, terpenes (limonene from orange peel), H2S and amines from rotting food. It gives one number for the total of all of them. It does not identify which gas is present, does not give ppm, does not measure CO2 (the SCD41 does), and responds weakly to ammonia. It is affected by humidity and temperature and drifts over days. Therefore:

  1. Run a 48 h burn-in first.
  2. Use the ratio R/R0, where R0 is the 24 h median in the clean classroom before installation, re-checked monthly with the lid open for 30 min.
  3. Compare the two sensors under identical conditions (#1 vs #2) rather than absolute values.
  4. Validate against the blind sniff panel.

We use the raw bme680 ESPHome platform (gas resistance in Ω). Bosch's BSEC "IAQ" index is an optional extra for advanced students, with the caveat that it was tuned for living rooms, not compost. The BME680 RH reading is unreliable above 90 % RH, so the humidity loop uses the SCD41's RH.

Pin assignment (standard map only)

Function GPIO Device
I2C SDA / SCL 21 / 22 SCD41 0x62, BME680 #1 0x77, BME680 #2 0x76 (SDO to GND), SSD1306 0x3C. Bus at 50 kHz; total cable ≤ 1.5 m, 4-core shielded
1-Wire 4 DS18B20 (4.7 kΩ pull-up to 3.3 V on TERMBOARD)
Analog A 32 SOIL A (feeding zone)
Analog B 33 SOIL B (bag field)
PWM out 2 (fan) 17 MOSFET module → FAN, ledc 25 kHz
Relay 1 23 RELAY → switches the 24 V DC output of the mister adapter (low-voltage side only)
Servo 1 26 SG90 intake damper, 50 Hz, powered from 5 V BUCK
Unused 16, 18, 19, 25, 27, 34, 35, 36, 39, 13, 14, 5, 15, 12 free for student extensions (e.g. a FLOAT on GPIO13 for the reservoir)
Reserved 0, 2 boot / LED

Entity ids: mc_01_co2, mc_01_air_temp, mc_01_air_rh, mc_01_gas_res_in, mc_01_gas_res_out, mc_01_gas_ratio_in, mc_01_core_temp, mc_01_soil_moisture_a, mc_01_soil_moisture_b, mc_01_resp_rate, mc_01_fan, mc_01_mister, mc_01_intake.

Calibration

Respiration test protocol (30 min, manual version; the automatic nightly version is identical)

  1. Do not open the lid or feed for ≥ 2 h beforehand. Note the time, core T and air T.
  2. In HA, press "Start respiration test". The node turns the fan and mister off and the servo closes the intake. Cap the exhaust outlet with the rubber cap (manual tests only).
  3. Log CO2 every 60 s for 30 min. Discard minutes 0–5 (mixing). Abort if CO2 > 4500 ppm (sensor limit 5000).
  4. Slope s (ppm/min) = linear regression of minutes 5–30 (Sheets SLOPE). The node also publishes (C25 − C5)/20.
  5. CO2 production = s × 10⁻⁶ × V / Vm, where V = headspace 17 L (measure the actual headspace height) and Vm = 24.2 L/mol at 22 °C (scale by (273 + T)/295). Example: s = 20 ppm/min → 1.4 × 10⁻⁵ mol/min = 14 µmol/min → × 44 = 0.62 mg CO2/min = 37 mg CO2/h → ÷ 4 kg dry bed = 9 mg CO2/h/kg.
  6. Re-open the intake and run the fan at 60 % for 10 min. Record any leak notes (the gasket condition is checked monthly with a smoke/incense test held outside the gasket).
  7. Known bias: some CO2 leaks through the gasket and carbon tube, so rates are slight underestimates. Use them for comparisons, not absolutes.

Automation

All logic runs on the ESP32 (it keeps working if Wi-Fi or HA is down). HA provides visibility, override and alerts.

Setpoints

Parameter Value
Base aeration fan 40 % for 5 min every 30 min
Odour/CO2 vent trigger gas ratio R/R0 (#1) < 0.60 or CO2 > 2500 ppm
Vent exit R/R0 > 0.75 and CO2 < 1500 ppm, min 5 min
Vent duty limit max 20 min continuous at 100 %, then 10 min at 40 %; max 6 h at 100 % per day. If RH < 75 %, vent capped at 60 %
Humidify trigger SCD41 RH < 82 % and soil A < 70 % (calibrated); not during a test
Humidify action mister on + fan 25 % (draws fog), max 90 s per burst, min 10 min between bursts, max 6 bursts per hour
Humidify stop RH ≥ 90 % or burst timer
Too dry / too wet alerts (HA notification) soil A or B < 55 %: "add 200 mL water by hand, evenly". > 80 %: "stop misting, add 1 L dry cardboard"
Core temperature alert < 10 °C or > 30 °C
Respiration test daily 02:00, 30 min, abort at CO2 > 4500 ppm or R/R0 < 0.4; hard timeout 35 min → intake opens
Fail-safe SCD41 missing > 5 min: fan fixed 60 %, 10 min on / 20 min off; mister disabled; tests disabled. BME680 #1 missing: VOC trigger off, CO2 trigger remains. Soil A missing: mister uses RH only, max 3 bursts per hour. On boot: intake opens, mister off, fan 40 % for 2 min
stateDiagram-v2
  [*] --> Boot
  Boot --> Base: intake open, mister off, fan 40 pct 2 min
  Base --> Vent: gas ratio below 0.60 or CO2 above 2500
  Vent --> Base: ratio above 0.75 and CO2 below 1500
  Vent --> VentRest: 20 min at full speed
  VentRest --> Vent: after 10 min at 40 pct
  Base --> Humidify: RH below 82 and soil A below 70
  Humidify --> Base: RH at least 90 or 90 s elapsed
  Base --> RespTest: 02.00 schedule or HA button
  RespTest --> Base: 30 min done, slope published
  RespTest --> Vent: CO2 above 4500 or timeout 35 min
  Base --> FailSafe: SCD41 missing 5 min
  Vent --> FailSafe: SCD41 missing 5 min
  Humidify --> FailSafe: sensor missing
  FailSafe --> Base: sensor back for 5 min
  Base --> Manual: HA override
  Manual --> Base: Auto selected or 2 h timeout

ESPHome implementation outline (students fill in the full YAML)

Operations

Daily (school days, ≤ 10 min, task rota on the tank)

Weekly

Lab notebook (paper, numbered pages, plus the shared sheet)

Maintenance

End-of-term plan (14–18 Dec)

Safety & risks

The general rules still apply: no 230 V anywhere inside or near the tank. The fan and servo are 12/5 V. The mister is 24 V DC with its own certified adapter. All bricks sit on the shelf above, on the RCD strip, with drip loops. The node box is outside the tank, above the rim, with cables entering through glands. Students never open or modify mains devices.

Risk Specific cause here Mitigation
Mould spores / allergens bread and peel bags, surface mould bread only in buried bags; lid open ≤ 10 min; FFP2 + window open for harvest/sieving; asthma/allergy students excluded from harvest; no shaking; springtails graze mould
Fungus gnats / fruit flies soft food, wet surface freeze food 48 h, bury it, 0.5 mm mesh on all vents, inside and outside sticky cards, BTI if needed
Odour in the classroom VOCs, H2S if anaerobic carbon filter + VOC-triggered fan, feeding limits, sniff panel, alerts
Anaerobic bed overfeeding, > 80 % moisture, compaction aeration tubes, base fan schedule, CO2 alert, soil > 80 % alert, add dry cardboard, turn the feeding zone only
Leachate over-watering, wet food 3 cm LECA sump, weekly check, siphon via tube with a syringe (no mouth siphoning), dispose diluted on plants
Mister water hygiene warm standing water, biofilm, aerosol weekly empty/clean/dry; tap water changed weekly; mister off during lid-open; fog goes only into the closed tank
Electrical / water condensation on the lid, refilling the reservoir node box above the rim with glands; reservoir lid kept closed; refill with the MIST adapter unplugged at the strip (teacher) or the mister switched off in HA; MIST checked for a built-in low-water cut-off (if absent, add a FLOAT on GPIO13 as a student mod)
Sharp tools / acrylic build phase teacher operates drill/hole saw; safety glasses; deburr edges
Pathogens soil, compost gloves, handwashing, no food or drink, no meat/dairy/pet waste in the system
Organism welfare drying, overheating, escape RH/soil loop, core T alerts, gasket + mesh, divider holes only 10 mm, release only to the school compost (never to the wild: E. fetida is non-native to soils)
Glass tank knock or drop (≈ 30 kg filled) on a stable bench, front 5 cm from the bench edge, never moved full

Educational outcomes & assessment

# Outcome Track Evidence produced
1 Formulate testable hypotheses and identify independent/dependent/controlled variables for decomposition Science written experimental plan with a variables table and randomised bag map (assessed before burial)
2 Run a replicated, controlled field method (litter bags, travel bags, PE control) and quantify uncertainty Science bag mass table (M0, Mt, handling correction), mean ± SD, k values, error bars
3 Convert sensor data into a physical rate (CO2 production in mg/h) and relate it to conditions (feeding, temperature, Q10) Science respiration test sheets, Grafana screenshots with annotations, slope calculation, Q10 graph (Feb)
4 Explain what a sensor does and does not measure (BME680 vs SCD41) and validate it against human observation Science + Engineering short report: R/R0 vs sniff-panel scatter plot, discussion of limits
5 Define requirements, compare candidate solutions and iterate with data (odour, moisture, aeration) Engineering requirements table, A/B test results (continuous vs triggered fan), filter efficiency E, decision log v1→v3
6 Operate a living system responsibly and safely over months Both logbook completeness, maintenance checklist sign-offs, end-of-term poster and 5-min presentation

Sub-BOM

Cost-cut 2026-10-20: BTI granules removed (buy only if fungus gnats appear). PPE, pens and calibration solutions are shared project items.
Price basis: Romanian retail incl. VAT, Oct 2026 estimates. Electronics: optimusdigital.ro / sigmanortec.ro / cleste.ro (SCD41 modules are listed at sigmanortec.ro). Hardware: dedeman.ro / leroymerlin.ro. Organisms: OLX / vermiculture and terrarium sellers. Fallback: AliExpress.

ID / item Qty Unit RON Line RON Basis
ESP32 1 45 45 Optimus/Sigmanortec DevKitC 38-pin
TERMBOARD 1 35 35 screw-terminal expansion board
OLED 1 22 22 SSD1306 0.96" I2C
BME680 2 85 170 breakout, Sigmanortec/Optimus
SCD41 1 250 250 Sensirion SCD41 module (≈ 49 EUR)
DS18B20 1 15 15 waterproof 1 m
SOIL 2 12 24 capacitive v2.0 (TL555 version)
FAN 1 30 30 80 mm 12 V quiet PC fan
MIST 1 75 75 24 V ultrasonic mist maker + adapter
MOSFET 1 10 10 D4184 module
RELAY 1 8 8 1-ch 5 V relay (switches 24 V DC)
SERVO 1 12 12 SG90
PSU12 1 60 60 12 V 5 A certified brick + DC jack
BUCK 1 12 12 LM2596
BOX 1 40 40 IP65 150×110×70
GLAND 14 1.5 21 PG7 (10 box + 4 lid)
TANK45 1 180 180 glass aquarium 50×30×30, pet shop
ACRYLIC 0.6 120 72 0.6 of a 50×100 3 mm sheet (lid, divider, plates)
MESH 0.25 30 8 m²; separator + vents + fine bags
SILICONE 1 35 35 aquarium-safe tube
TUBING 1 5 5 m, leachate siphon
RESERVOIR 1 30 30 10 L food-grade with lid
BIO: Eisenia fetida 150 g 1 65 65 incl. courier
BIO: isopod cultures (P. scaber, A. vulgare) 2 35 70 buy; 0 RON if collected locally
BIO: Folsomia candida culture 1 35 35 terrarium seller
BIO: Pleurotus ostreatus grain spawn 500 g 1 30 30 mushroom supplier/eMAG
SUB: coco coir brick 650 g 1 15 15 Dedeman
SUB: organic compost 20 L, no fertiliser 1 25 25 Dedeman/Hornbach
SUB: LECA 10 L 1 25 25 Dedeman
SUB: cork bark pieces 1 20 20 pet/terrarium shop
CONS: activated carbon pellets 1 kg 1 45 45 aquarium carbon (≈ 13 refills of 75 g)
HW: PVC pipe 50 mm 1 m + 2 end caps 1 20 20 Dedeman
HW: PVC conduit 20 mm 2 m + caps 1 12 12 Dedeman
HW: hose 16 mm ID, 1.5 m (fog duct) 1 18 18 Dedeman
HW: EPDM foam gasket 9×6 mm, 5 m 1 25 25 Dedeman
HW: 2 hinges + M3 stainless bolts/nylocks + knob 1 20 20 Dedeman
CONS: garden netting 5 mm, 1 m² 1 15 15 coarse bags
CONS: fishing line + 50 plant labels + marker 1 25 25 bag tethers/tags
TOOL: pocket scale 0.01 g / 200 g + 100 g weight 1 50 50 eMAG
CONS: yellow sticky traps, 20 1 20 20 garden shop
CONS: nitrile gloves, 100 1 40 40 pharmacy/eMAG
CONS: FFP2 masks, 10 1 25 25 pharmacy
TOOL: stainless sieve 2 mm, 20 cm 1 30 30 kitchen/lab
CONS: distilled water 5 L 2 7.5 15 supermarket
CONS: 4-core shielded cable 5 m, Qwiic/JST leads, ferrules, heat-shrink 1 35 35 Optimus
CONS: conformal coating (share of 1 can) 0.25 40 10 shared with other teams
TOOL: 2 L food box (choice arena) 1 15 15 supermarket
CONS: spray bottle 500 mL 1 10 10 supermarket
Subtotal 1 874 RON (≈ 367 EUR) electronics + enclosure 1 159; bio/consumables 715

PHPEN, CALSOL, the hub (PI5, ROUTER) and the RCD power strip are project-wide shared items and are not counted here.

8-week timeline (Oct 26 – Dec 18, 2026)

Check the 2026/27 school calendar. If a holiday falls in this window, shift by one week; Dec 1 (Romania's national day) is a public holiday.

gantt
  title Orchestra of Rot - build and Run 1
  dateFormat YYYY-MM-DD
  axisFormat %d %b
  section Prepare
  Order parts and organisms          :p1, 2026-10-26, 5d
  Collect leaves and isopods         :p2, 2026-10-27, 8d
  Lid and vent design review         :p3, 2026-10-29, 2d
  section Build
  Cut and drill lid and vent tube    :b1, 2026-11-02, 4d
  Node box wiring and ESPHome        :b2, 2026-11-03, 4d
  BME680 burn-in and calibrations    :b3, 2026-11-06, 4d
  Sew and weigh litter bags          :b4, 2026-11-04, 6d
  section Establish
  Layer substrate and settle         :e1, 2026-11-09, 3d
  Pleurotus cardboard colonisation   :e2, 2026-11-09, 21d
  Add worms springtails and isopods  :e3, 2026-11-12, 2d
  section Run 1
  Bury Run 1 bags and start feeding  :milestone, r0, 2026-11-16, 0d
  v1 passive vent baseline           :r1, 2026-11-16, 7d
  v2 carbon fan AB test              :r2, 2026-11-23, 10d
  Isopod choice arena trials         :r3, 2026-11-24, 8d
  v3 mister loop and auto resp test  :r4, 2026-12-03, 9d
  Harvest Run 1 bags                 :milestone, r5, 2026-12-14, 0d
  Dry weigh analyse and poster       :r6, 2026-12-14, 5d
  Insert Run 2 bags                  :milestone, r7, 2026-12-15, 0d
  Winter break preparation           :r8, 2026-12-17, 2d

2. The Domino Effect — EcoColumn

Node: mc-02-ecocolumn · Team of 3–4 · Footprint 90×40 cm, 180 cm tall rack · Water on board ≤ 35 L, all 12 V DC.

Concept (refined)

A four-level column on a boltless metal rack: a tilting "field" of two removable soil cassettes (lanes A/B) receives metered artificial rain; runoff carrying sediment and fertiliser drops through swappable filter cartridges into a 25 L "pond" with plants, snails and algae. Rain comes from a separate clean reservoir, so the only nutrient input to the pond is what washes off the field (closed nutrient accounting). The A/B lanes and interchangeable cassettes give every erosion experiment its own side-by-side control. An array of twelve 0.5 L jars beside the pond runs a fast fertiliser-dose bioassay, so eutrophication results exist by mid-December, while the pond itself is the slow, whole-system experiment that runs to June 2027.

Science track

Driving question: How much soil and fertiliser leaves a field during a storm, and what does it do to the pond downstream?

Hypotheses (testable by the team)

# Hypothesis Comparison Primary measure
H1 A vegetated slope (≥ 80 % cover ryegrass/wheat) loses ≥ 70 % less sediment per storm than a bare slope at the same angle. Sub-question H1b: sediment from bare soil rises steeply with angle (5 → 20°). Vegetated vs bare cassette, side by side; bare cassettes at 5/10/15/20° Sediment yield, g/m² per event
H2 Algal growth rises with nutrient dose: jars at 0 / 1 / 4 / 16 mg N/L (NPK 20-20-20) turn green in dose order within 14 days. 4 doses × 3 replicate jars Bench turbidity, photo green index, Secchi-card depth
H3 A grass buffer strip on the bottom 20 % (8 cm) of a bare slope cuts sediment ≥ 50 % but cuts dissolved nitrate much less (dissolved N passes through, particle-bound P is trapped). Bare vs bare + buffer strip Sediment g/m²; NO3 and PO4 in runoff

Variables

H1 H2 H3
Independent Cover (bare / vegetated); angle (H1b) NPK dose Buffer strip present / absent
Dependent Runoff volume (mL), sediment mass (g), turbidity Turbidity (bench TURB), green index, Secchi depth, pH Sediment mass, NO3/PO4 (mg/L) in runoff
Controlled Rain volume 10 mm and intensity 60 mm/h (FLOW metered), angle 10°, soil mix and depth 5 cm, antecedent soil moisture (SOIL within ±3 % of target before every event), surface raked to 1 cm on bare cassettes, room temp Jar size 500 mL, inoculum 50 mL, light (same LED strip, positions randomised and rotated), temperature, start date As H1, plus fertiliser 2 g NPK 15-15-15 per cassette applied 24 h before event

Replication strategy

  1. Bare-vs-bare calibration first (3 events, both lanes bare): measures the natural lane-to-lane difference. A later treatment effect only counts if it is ≥ 2× this calibration difference.
  2. Four interchangeable cassettes (2 vegetated, 2 bare): every comparison is run once, then the cassettes are swapped left↔right and run again, cancelling position bias (rain bar uneven, light gradient).
  3. Repeat rain events: ≥ 3 events per condition (2 per week, ≥ 48 h apart).
  4. Before/after on the pond: 2-week baseline with unfertilised runoff, then fertilised runoff; compare weekly means.
  5. Jars: 3 replicates per dose, positions assigned by dice, rotated one place every 2 days.

Sampling schedule

What When Who/how
All automated sensors Every 60 s (FLOW every 5 s during events) Node → Home Assistant → InfluxDB
Rain events Tue + Thu at start of lab session (button in HA), weeks 4–8; later 1/week Students present to collect runoff
Runoff volume, sediment, bench turbidity Every event, each lane Graduated jug, filter/dry/weigh
NO3, PO4 in runoff (filter in / out) 1 event per week Test strips + drop tests
Pond: Secchi card, photo green index, NO3, PO4, pH pen check, duckweed fronds Weekly (Monday) Manual log
Jars: photo, bench turbidity, pH pen Mon / Wed / Fri for 21 days Manual log

Manual measurements (methods)

Analysis

Mid-December vs. spring

By mid-December (observable) Spring 2027 (needs weeks of light + nutrients)
H1, H1b, H3 sediment results (≥ 3 events each) Pond bloom trajectory after repeated fertilised runoff (weeks 7 → 20)
H2 jar bioassay: high-dose jars visibly green in 7–14 days at 20 °C, 14 h light Diurnal pH swing growing as biomass rises; Secchi depth falling
Filter v1/v2 removal efficiencies Filter clogging and lifetime (efficiency vs number of events)
Pond baseline + first 1–2 weeks of fertilised inflow; duckweed growth rate Duckweed vs submerged plants competition; snail population counts; light (window, day length) as a seasonal factor; clover vs ryegrass cover

Design consequence: the pond is started in week 2 (not week 6) so it is biologically stable before the first nutrients arrive, and the jars carry the eutrophication result for the December presentation.

Engineering track

Problem statement: Design a field-edge system that keeps soil and fertiliser on the field and out of the pond, using only cheap natural materials, without flooding during a 20 mm storm, and that a farmer (a student) can service in under 2 minutes.

Requirements

ID Requirement Verification
R1 Rain simulator delivers a set volume ±5 % and mean intensity 30–120 mm/h, repeatable between events FLOW pulses vs graduated jug, 3 repeats
R2 Rain uniformity across each lane: Christiansen CU ≥ 80 % 8 catch cups per lane, 5 min
R3 Slope angle adjustable 5/10/15/20° ±1°, repeatable Prop blocks + phone inclinometer
R4 Filter cartridge swappable in < 2 min, no tools, identical outer size Stopwatch test
R5 Filter passes 0.25 L/min without overflowing; detention ≥ 0.6 L 20 mm storm test, no water in catch tray
R6 Filter removes ≥ 80 % of turbidity/TSS; report NO3/PO4 change In/out samples
R7 No water can reach the pond above 21 cm; pump cannot run dry or overfill Interlock tests (see Automation)
R8 Cost per filter cartridge ≤ 30 RON, materials non-toxic BOM

Candidate solutions

Test criteria: sediment removal (%), turbidity removal (%), NO3/PO4 change, overflow (yes/no, volume in catch tray), clogging (outflow rate at event 1 vs event 5), swap time, cost.

Iteration plan

  1. v0 (week 3): rain bar (a), measure CU; if < 80 %, build (b) and retest.
  2. v1 filters (week 5): build 3 cartridges (gravel, sand, layered); run inline on bare-lane runoff; rank with the criteria above.
  3. v2 (week 7): redesign the best one (e.g. thicker sand, plant mat on top, coarser layer against clogging); retest; compare v1 vs v2 on the same event type.
  4. Spring: lifetime test (10 events), cleaning method, combine best on-field measure + best filter ("whole-catchment solution") and measure pond impact.
    Every iteration is logged in the design notebook: requirement → change → test result → decision.

Enclosure & build

Layout (boltless metal rack 180×90×40 cm, 5 shelves, anchored to the wall with an anti-tip strap; shelves lined with PP sheet)

Level Height (shelf top) Contents
L4 Field 125 cm 12 mm plywood tilt platform 60×40 cm, hinged at the front edge, prop blocks at the back (h = 40 cm × sin θ: 3.5 / 6.9 / 10.4 / 13.7 cm for 5 / 10 / 15 / 20°). Two cassettes side by side in rail stops. Rain bars + slope LED profiles on two PVC 16 mm uprights screwed to the platform, 25 cm above the soil, so drop height stays constant when tilting. Two 12 cm kitchen funnels on brackets under the open front ends.
L3 Filter 95 cm Catch tray (spare BOXPLASTIC lid or 40×30 cm PP tray) holding 2 filter cartridges A/B. Each cartridge outlet → 16 mm clear hose → pond. Catch tray drain (overflow only) → separate hose → pond. JSN on a bracket under this shelf, on top of the stilling tube.
L2 Pond 40 cm BOXPLASTIC low box 60×40×15 cm (≈ 36 L, holds the whole pond if the glass fails) containing TANK25 (40×25×25 cm, water at 18 cm = 18 L) on 1 cm foam, plus 12 × 0.5 L jars. Pond/jar LED profiles hang from L3 on chains, 15 cm above water (adjustable 10–30 cm). Hose ends clipped 3 cm above the water surface (air gap = sampling point).
L1 Supply 5 cm Second BOXPLASTIC spill box containing RESERVOIR 15 L (lid drilled for pump cable, tubing, float) and a 5 L drawdown jug.
Node 110 cm on the rack's side upright, outside the shelf footprint BOX with ESP32 + TERMBOARD + OLED + BUCK + 3 MOSFET + PH-4502C board; glands pointing down; every cable with a drip loop below the box.
Mains Wall shelf ≥ 40 cm to the side of the rack, ≥ 150 cm high RCD (30 mA) power strip + PSU12 brick only. Only the 12 V DC lead crosses to the node box, with a drip loop.

Soil cassettes (×4): 3 mm ACRYLIC, inner 40 × 12 × 6 cm; base, two sides, back wall; front end open with a 1 cm sill and a 2 cm strip of MESH below the sill so seepage also exits. Fill 5 cm soil mix (2 parts garden topsoil : 1 part washed sand, sieved 5 mm) = 2.4 L per cassette. Lane area 0.048 m² → 1 mm of rain = 48 mL per lane.

Rain rate (computed): pump flow is trimmed (PWM + bypass valve) to Q = 0.40 L/min, split equally to both lanes (servo valve "both") = 0.20 L/min per lane = 4.2 mm/min instantaneous. Rain is pulsed (like oscillating-nozzle field simulators): each 15 s pulse = 100 mL total = ~1 mm per lane.

Storm preset Pulses Pulse/pause Depth Duration Mean intensity Total water
S10 standard 10 15 s / 45 s 10 mm 10 min 60 mm/h 1.0 L
S20 extreme 20 15 s / 15 s 20 mm 10 min 120 mm/h 2.0 L
D2 drizzle (irrigation) 2 15 s / 105 s 2 mm 4 min 30 mm/h 0.2 L

Pulsing keeps the FLOW sensor inside its accurate range (≥ 0.3 L/min). Limitation to discuss with students: 25 cm drops have far less impact energy than real rain, so absolute erosion is underestimated; comparisons remain valid.

Water path

flowchart TD
  R["RESERVOIR 15 L dechlorinated water"] --> P["PUMP 12 V via MOSFET PWM3"]
  P --> BV["Bypass ball valve back to reservoir"]
  BV --> R
  P --> F["FLOW YF-S401"]
  F --> NRV["Non-return valve"]
  NRV --> V["3-way valve on SERVO, A / both / B"]
  V --> RA["Rain bar A"]
  V --> RB["Rain bar B"]
  RA --> CA["Cassette A on tilt platform"]
  RB --> CB["Cassette B on tilt platform"]
  CA --> GA["Funnel A, hose"]
  CB --> GB["Funnel B, hose"]
  GA --> JA["Optional 1 L sample jug A"]
  GB --> JB["Optional 1 L sample jug B"]
  GA --> FA["Filter cartridge A"]
  GB --> FB["Filter cartridge B"]
  FA --> PD["Pond TANK25, 18 L"]
  FB --> PD
  FA --> CT["Catch tray overflow"]
  FB --> CT
  CT --> PD
  PD --> DD["Weekly drawdown to 5 L jug, max level 21 cm"]
  S1(["FLOAT reservoir low"]) -.-> R
  S2(["SOIL A and SOIL B"]) -.-> CA
  S2 -.-> CB
  S3(["BH1750 at water surface"]) -.-> PD
  S4(["JSN in stilling tube"]) -.-> PD
  S5(["FLOAT pond high"]) -.-> PD
  S6(["TURB, PHKIT, DS18B20"]) -.-> PD

Overflow policy: no siphon overflow on the glass tank (siphons can fail and drain or flood). Instead: 7 cm freeboard (18 → 25 cm = 7 L spare), FLOAT high at 21 cm blocks all events, JSN level > 20 cm blocks events, weekly manual drawdown to 18 cm (this is also the pond sample), spill box under the tank holds > 25 L. One S20 storm adds ≤ 2 L (≈ 2 cm).

Build steps

# Step Time Tools
1 Assemble rack, set shelf heights, anchor to wall, line shelves with PP sheet 1.5 h Rubber mallet, drill, wall plugs
2 Cut acrylic for 4 cassettes (score-and-snap), glue with aquarium silicone, cure 24 h, test-fill with water for leaks 3 h + cure Acrylic scoring knife, steel rule, clamps, silicone gun
3 Tilt platform: cut plywood 60×40, varnish 2 coats, 2 hinges (approved lot), rail stops, prop blocks cut to 3.5/6.9/10.4/13.7 cm 2 h Saw, drill, sandpaper, brush
4 Rain bars: 2 × 40 cm PVC 16 mm, end caps, drill holes Ø 0.8 mm at 5 cm pitch, T-pieces, uprights and pipe clips 2 h Pin vice, hacksaw, PVC glue
5 Supply line: pump in reservoir, 6 mm tubing, bypass ball valve, FLOW (arrow = flow direction, mounted horizontal), non-return valve, 3-way aquarium valve on SERVO with acrylic coupler 2 h Scissors, cable ties, hot glue
6 Filter cartridges: drill 6 PP boxes for 16 mm barbed bulkhead, silicone, mesh over outlet; build catch tray drain 2 h Step drill, silicone
7 Pond: TANK25 in spill box on foam; stilling tube (PVC 75 mm × 50 cm, 6 slots 5 mm near bottom) vertical in a back corner; float, pH and TURB holders on acrylic hang-over clips 1.5 h Hacksaw, file
8 Node box: TERMBOARD, BUCK set to 5.0 V before connecting ESP32, MOSFETs, dividers, PH-4502C; glands; label every wire 3 h Screwdriver, multimeter, crimper, heat-shrink
9 LED strips in profiles (slope 3 × 45 cm, pond 3 × 60 cm), JST leads, chains 1.5 h Soldering iron (teacher) or solderless clips
10 Flash ESPHome, adopt in HA, dashboard + rain-event script; run calibration and interlock tests 3 h Laptop

Total ≈ 22 student-hours + cure times.

Biology

Pond (TANK25, 18 L)

Item Species Qty Source (Romania)
Water Bucharest tap water + dechlorinator (e.g. Tetra AquaSafe), or stood 48 h 18 L —
Substrate 3 cm washed sand + 1 cm garden soil under it (nutrient-poor start) ~2 L Dedeman / garden
Submerged plant Ceratophyllum demersum (hornwort, native) 2 bunches Aquarium shops (Aquaristica, Zoomania, local "acvaristică"), OLX hobbyists
Submerged plant Egeria densa (Brazilian waterweed) or Elodea canadensis 2 bunches Aquarium shops
Floating plant Lemna minor (common duckweed, native) ~100 fronds Aquarium shops / hobbyists
Grazer Planorbarius corneus (great ramshorn snail, native), fixed at 5 individuals 5 Aquarium shops
Inoculum 0.5 L pond water from a garden pond or a lake edge (Herăstrău/Văcărești, with teacher, gloves), sieved through 0.5 mm mesh to exclude larger animals 0.5 L Field

Do not buy Elodea nuttallii or Lagarosiphon major (EU invasive species of Union concern). Prefer Planorbarius over Physa acuta (invasive). No organism or water from this system is ever released outdoors: plant waste is dried and binned, water goes down the sink.

Field (cassettes): 2 vegetated cassettes sown densely with Lolium perenne (perennial ryegrass, 5 g per cassette) + 2 g wheat (Triticum aestivum, germinates in 3–5 days, fast cover) — one cassette may be ryegrass + white clover (Trifolium repens, 1 g) for spring comparison. 2 bare cassettes = control. Buffer strip: a 8 × 12 cm sod of ryegrass grown in a separate small tray, cut and inserted at the low end of a bare cassette for H3. Seeds from agricultural/garden shops (Dedeman, Agroland, eMAG).

Establishment timeline: sow week 1 (Oct 26–30) under the slope LED (or a windowsill), keep moist with a spray bottle; ≥ 80 % cover at day 18–21 (by Nov 16–20). Pond filled week 2, plants week 2, snails and inoculum week 3 (after 7 days of plant settling). Jars started Nov 18.

Fertiliser (measured doses)

Avoid: fish or any vertebrate (brief rule; also adds nutrients); mosquito risk — check weekly for larvae, cover the pond with a MESH frame lid if seen; peat-based potting compost on the slope (floats, unrealistic erosion); copper-containing products; pesticides.

Instrumentation

Catalog ID Qty Placement Interval Purpose / entity
DS18B20 1 Pond, mid-depth, clipped to stilling tube 60 s Water temperature; pH temperature context. mc_02_water_temp_pond
SOIL 2 One per cassette, vertical, 8 cm from the high end, top edge sealed 60 s (mean of 10) Antecedent moisture control + infiltration response during events. mc_02_soil_moisture_a/_b
BH1750 1 Pond/jar level facing up, in a clear sealed sandwich box 5 cm above water 60 s Light dose for algae (lux, not PAR — relative comparisons only). mc_02_illuminance_pond
JSN 1 On top of PVC 75 mm stilling tube, face 52 cm above tank bottom (outside 25 cm blind zone at max level 21 cm) 60 s (median of 12 pings at 5 s) Pond level → inflow volume per event (1 cm ≈ 1.0 L). mc_02_water_level_pond
FLOAT 2 (1) Reservoir, switch point at 3 L; (2) pond, switch point at 21 cm On change + 60 s Interlocks (fail-safe wiring, see below). mc_02_float_reservoir_low, mc_02_float_pond_high
FLOW 1 Rain line after pump, horizontal 5 s during events, else 60 s Event volume and rate. mc_02_rain_flow, mc_02_rain_volume_event
TURB 2 (1) Pond: in an opaque PVC sleeve clipped to the glass, head 3 cm under water, top of probe body dry; (2) bench cup: black 250 mL cup with lid holding the probe 60 s (pond); 5 s on demand (bench) Pond turbidity trend; sample turbidity for runoff, filter in/out, jars. mc_02_turbidity_pond, mc_02_turbidity_bench
PHKIT 1 Pond, probe in a hang-over holder, tip 5 cm below surface, ≥ 3 cm from glass 60 s (mean of 20) pH and diurnal swing (photosynthesis proxy). mc_02_ph_pond
SERVO 1 Coupled to 3-way aquarium valve on rain line Event-driven Route rain to A / both / B
PUMP 1 In RESERVOIR Event-driven Rain
LEDSTRIP + LEDPROFILE 3.2 m, 5 profiles Slope: 3 × 45 cm on uprights; pond/jars: 3 × 60 cm on chains Schedule Grass growth; algae light treatment

TURB notes: SEN0189-type sensors measure light transmitted across a 1 cm gap (IR LED → phototransistor); output 0–4.5 V, falls as turbidity rises. The "NTU" formula in the datasheet is approximate — we calibrate in g/L kaolin-equivalent instead. Limitations: sensitive to ambient light (hence the opaque sleeve and black cup), bubbles and algal film on the window (wipe weekly with soft cloth), not accurate below ~0.05 g/L, and the probe top is not waterproof (keep top 2 cm dry; seal cable entry with heat-shrink).

PHKIT notes: the glass probe must never dry out; out of water store it in its cap with 3 M KCl storage solution (never distilled water). Drift ~0.05–0.1 pH/week: check weekly in pH 7, recalibrate 2-point monthly or when drift > 0.1. Algal film on the bulb: rinse with tap water, soak 10 min in vinegar if fouled. Probe lifetime in continuous immersion 6–12 months: budget a replacement probe in spring. Ground-loop check: read pH with pump/LEDs on and off; if the reading jumps > 0.05, add an analog signal isolator.

Pin assignment (standard pin map only)

GPIO Standard function Connected here
21 / 22 I2C OLED 0x3C, BH1750 0x23
4 1-Wire DS18B20 pond (4.7 kΩ pull-up)
32 Analog A SOIL A
33 Analog B SOIL B
34 Analog C TURB bench (10 k / 20 k divider, 0–4.5 V → 0–3.0 V)
35 Analog D free
36 (VP) Analog E PHKIT Po output (10 k / 20 k divider)
39 (VN) Analog F TURB pond (10 k / 20 k divider)
16 PWM 1 MOSFET → slope LED strip
17 PWM 2 ("fan" slot, no fan on this node) MOSFET → pond/jar LED strip
18 PWM 3 (pump) MOSFET → rain PUMP (PWM 1 kHz)
19 PWM 4 free
23 / 25 Relay 1–2 free
26 Servo 1 SG90 rain valve (5 V from BUCK, 470 µF across supply)
27 Servo 2 free
13 Digital in 1 FLOAT reservoir low
14 Digital in 2 FLOAT pond high
5 Pulse counter FLOW signal (10 k / 20 k divider from 5 V)
15 / 12 Ultrasonic TRIG / ECHO JSN (ECHO via 1 k / 2 k divider; the 2 k to GND also keeps strapping pin GPIO12 low at boot)

Power: PSU12 → MOSFET loads (LEDs ≤ 10 W/m × 3.2 m ≈ 32 W, pump ~4 W) and BUCK 5.0 V → ESP32 VIN, JSN, FLOW, TURB ×2, PHKIT, SERVO. Worst case ≈ 39 W = 3.3 A of 5 A. All ADC pins on ADC1, attenuation 11 dB (attenuation: 12db in current ESPHome).

Fail-safe float wiring: both floats are mounted so the contact is closed (to GND) in the safe state — reservoir float closed while water is above 3 L; pond float closed while level is below 21 cm. Open circuit (triggered or broken wire) = unsafe → pump blocked.

ESPHome flow excerpt (YF-S401 ≈ 5880 pulses/L; replace with your calibrated value):

sensor:
  - platform: pulse_counter
    pin: GPIO5
    name: "mc_02_rain_flow"
    unit_of_measurement: "L/min"
    update_interval: 5s
    filters:
      - multiply: 0.00017007   # 1/5880 L per pulse
    total:
      name: "mc_02_rain_total"
      unit_of_measurement: "L"
      filters:
        - multiply: 0.00017007

Calibration procedures

Sensor Procedure Frequency
FLOW Pump into a 1 L graduated jug for 60 s, 3 repeats at the event PWM; pulses/L = pulses ÷ litres; update the factor At commissioning, after tubing changes
Rain uniformity 8 catch cups per lane on a flat platform, 5 min, weigh; CU = 100 × (1 − Σ|x − mean| / (n × mean)) Each rain-bar version
JSN Ruler in the stilling tube at 3 water levels (12, 18, 21 cm); level = mount height − distance; fit offset Commissioning, monthly check
PHKIT Probe in pH 7.00 → record voltage V7; rinse; pH 4.01 → V4; slope = (V7 − V4)/2.99; pH = 7 − (V − V7)/slope (ESPHome calibrate_linear with the two points). Use solutions at room temperature; check against PHPEN 2-point monthly; pH 7 check weekly
TURB (both) Kaolin standards in dechlorinated water: 0, 0.05, 0.1, 0.2, 0.5, 1.0 g/L (stirred, read within 10 s); fit voltage → g/L (calibrate_linear or polynomial); daily zero check with clear water in the bench cup Commissioning, then monthly
SOIL Each probe in its cassette mix: air reading, oven-dry soil, saturated soil; map to 0–100 %; check twice with gravimetric water content (weigh 20 g soil, dry, reweigh) Per probe per substrate
DS18B20 Ice-water bath (0 °C) and room vs a reference thermometer; offset Commissioning
BH1750 Compare with a phone lux app at 3 positions; record only as relative Commissioning
Slope angle Phone inclinometer on platform for each prop block Each angle change

Automation

Rain-event controller runs inside the ESP32 (ESPHome script), so an event always finishes or aborts even if Wi-Fi or Home Assistant is down. HA only triggers it (dashboard button with preset S10/S20/D2 and valve position) or schedules D2 drizzle when both SOIL values fall below the target band.

stateDiagram-v2
  [*] --> Idle
  Idle --> Precheck : HA button or schedule
  Precheck --> Fault : interlock open
  Precheck --> SetValve : all checks pass
  SetValve --> Raining : servo settled 2 s
  Raining --> Pausing : pulse time elapsed
  Pausing --> Raining : pulses remaining
  Pausing --> Draining : all pulses delivered
  Raining --> Fault : float open or no flow or volume cap
  Pausing --> Fault : float open
  Draining --> Logging : 15 min runoff window
  Logging --> Idle : event record written
  Fault --> Idle : manual reset in HA

LED schedule

Light Default Experiment use
Slope (PWM 1) 06:00–20:00 (14 h), 70 %, 15 min ramp Constant; off during rain events not needed
Pond/jars (PWM 2) 07:00–21:00 (14 h), set PWM so BH1750 reads ~8,000 lux at the water surface Fixed during H2; spring option: 10 h vs 14 h photoperiod or 50 % vs 100 % (move half the jars under shade mesh)

Winter break (Dec 21 – Jan 7): lights continue on schedule, rain events disabled, reservoir and pond topped up on the last school day, HA alerts sent to the teacher's phone.

Safety interlocks (summary)

  1. Pump runs only while both floats are in the safe (closed) state and JSN < 20 cm.
  2. Hard caps per event: ≤ 2.0 L (11,760 pulses) and ≤ 300 s cumulative pump time.
  3. Flow fault: no pulses within 10 s of pump ON → abort (dry pump, kink or sensor failure).
  4. restore_mode: ALWAYS_OFF on pump and MOSFET outputs; after any reboot the pump is off.
  5. Minimum 2 h between events; maximum 4 events per day.
  6. All loads are 12 V DC; the only mains items (PSU12 brick, RCD strip) are on the wall shelf beside the rack.

Operations

Per-event checklist (≈ 40 min)

  1. HA dashboard: no faults; reservoir float OK; pond level < 20 cm; note SOIL A/B.
  2. Set angle (prop block, check inclinometer); rake bare cassettes 1 cm; photo of both cassettes from the fixed point.
  3. Place clean 1 L jugs under hoses A and B (erosion mode) or leave hoses in cartridges (filter mode).
  4. Start preset in HA; enter event ID, angle, cassette IDs, treatment.
  5. After the 15 min runoff window: read jug volumes; take 100 mL TSS subsamples and bench-turbidity samples; label (date_event_lane).
  6. Filter mode: grab 100 mL at hose inlet and at pond-end outlet at minutes 2, 5, 10.
  7. Pour remaining jug runoff slowly through its cartridge into the pond (keeps nutrient accounting closed).
  8. Photo after; write the event log line.

Weekly (Monday, ≈ 30 min): pond Secchi, photo green index, Lemna count, NO3/PO4, pH pen vs PHKIT; drawdown pond to 18 cm into the 5 L jug (this is the weekly pond sample); top up reservoir to 15 L with dechlorinated water; wipe TURB window; check pH probe in pH 7; check for mosquito larvae; inspect tubing and drip loops; refill catch tray dry.

Manual logs (printed sheet + shared spreadsheet): event log (ID, date, preset, angle, cassettes, rain L, runoff A/B mL, TSS A/B, turbidity A/B, notes); pond log; jar log; maintenance log (calibrations, cleaning, faults).

Filter cleaning: after every 5 events or when outflow time doubles: tip the top 1 cm of sediment-laden sand into a labelled bag (keep as sample), backwash gravel/sand in a bucket, re-pack to the marked height. Charcoal is replaced, not washed, every 10 events.

Water changes: no routine pond water changes (they would remove the nutrients being studied); only weekly drawdown and evaporation top-up with dechlorinated water. Emergency only: if snails die or water smells of rotten eggs, replace 30 % and log it.

Sample storage: nutrient samples tested the same day, or stored ≤ 48 h at 4 °C in a labelled screw-cap bottle in a dedicated (non-food) fridge or cool box; dried sediment filters in labelled zip bags in a dry box (archive for the year); photos named mc02_YYYYMMDD_subject.jpg in the shared folder.

Safety & risks

Educational outcomes & assessment

Students will be able to:

  1. Formulate a testable hypothesis on erosion/eutrophication and name independent, dependent and controlled variables.
  2. Explain why a calibration (bare vs bare) run and a position swap are needed before claiming an effect.
  3. Measure sediment yield (TSS × volume), turbidity, pH, NO3/PO4, and convert rain to mm and mm/h.
  4. Interpret a dose–response and a time series (diurnal pH swing) from the dashboard.
  5. Write requirements, build and test a filter against them, and justify a v2 from data.
  6. Explain the chain field → runoff → nutrients → algae → light/oxygen in the pond, and link it to real Romanian cases (Danube Delta and agricultural lakes eutrophication, EU Nitrates Directive buffer strips).

Assessment artefacts: lab notebook (individual), event/pond/jar logs (team), engineering design log with requirements table and test results (team), 5-minute December presentation with one graph per hypothesis (team), short individual reflection.

Criterion Developing (1) Secure (2) Strong (3)
Question & hypothesis Vague Testable, variables named Testable, variables + controls + replication justified
Data quality Gaps, no units Complete logs with units Complete, calibrated, uncertainty discussed
Analysis Raw numbers Correct graphs and means Effect vs calibration difference, limitations stated
Engineering Built one filter Tested against requirements Iterated with data, trade-offs explained
Teamwork & safety Needs reminders Follows checklists Leads checklists, improves procedures

Roles rotate every 2 weeks: hydrologist (rain, slope), chemist (water tests), engineer (filters, hardware), data lead (HA/Grafana, spreadsheet).

Sub-BOM

Cost-cut 2026-10-20: lighter shelving, strips plus one PO4 test instead of two drop tests, shared precision scale, electrical consumables moved to the project electronics lot.

Prices: estimates incl. VAT, RON (1 EUR ≈ 5.1 RON), October 2026, basis given per line.

ID / item Qty Unit RON Line RON Basis
ESP32 1 35 35 optimusdigital.ro / cleste.ro
TERMBOARD 1 35 35 optimusdigital.ro
OLED 1 22 22 optimusdigital.ro
BOX 1 40 40 IP65 ABS, emag.ro / dedeman.ro
GLAND (PG7/PG9 ×9, PG13.5 ×1 for BNC) 10 3 30 emag.ro
PSU12 1 60 60 certified 12 V 5 A brick, emag.ro
BUCK 1 12 12 optimusdigital.ro
MOSFET 3 8 24 D4184 module, optimusdigital.ro
DS18B20 1 15 15 waterproof 1 m, cleste.ro
SOIL 2 12 24 v2.0 TL555 version, optimusdigital.ro
BH1750 1 12 12 optimusdigital.ro
JSN 1 50 50 JSN-SR04T, optimusdigital.ro / ardushop.ro
FLOAT 2 12 24 vertical PP float, emag.ro
FLOW 1 35 35 YF-S401, optimusdigital.ro / AliExpress
TURB 2 55 110 SEN0189-type, robofun.ro / AliExpress
PHKIT 1 140 140 BNC probe + PH-4502C, optimusdigital.ro
SERVO 1 12 12 SG90, optimusdigital.ro
PUMP 1 45 45 12 V DC 240 L/h, emag.ro
LEDSTRIP 1 120 120 5 m reel, 3.2 m used, rest to shared pool; emag.ro
LEDPROFILE 5 25 125 1 m alu + diffuser, dedeman.ro
TANK25 1 160 160 40×25×25 rimless, aquarium shop / emag.ro
RESERVOIR 1 45 45 15 L food-grade with lid, dedeman.ro
BOXPLASTIC 2 55 110 low under-bed box ~60×40×15, spill boxes, dedeman.ro
ACRYLIC 1 190 190 3 mm 50×100 (cassettes); 1 of 3 approved sheets — lead to reconcile
MESH 0.25 m² 60 15 fibreglass mesh, dedeman.ro
SILICONE 1 35 35 aquarium-safe, aquarium shop
TUBING 5 m 6 30 silicone 6 mm ID, emag.ro
CALSOL 1 60 60 pH 4/7 + storage KCl (shared with Hydro possible)
FRAME: 3-tier wire shelving 90×45 cm, ≥ 50 kg per shelf (or existing bench plus wall brackets) 1 130 130 emag.ro / dedeman.ro
FRAME: anti-tip strap, PP shelf liner 1 40 40 dedeman.ro
Tilt platform: plywood 12 mm 60×40, varnish, prop blocks (hinges from approved lot) 1 50 50 dedeman.ro
Rain bars: PVC 16 mm 2 m, end caps, T-pieces, clips 1 40 40 dedeman.ro
23G blunt dispensing needles set 1 25 25 emag.ro
Valves: 3-way aquarium valve, ball valve, non-return valve, 6 mm barbs 1 45 45 aquarium shop / emag.ro
Drain hose 16 mm clear 3 m + 6 barbed bulkheads 1 80 80 dedeman.ro
Kitchen funnels 12 cm 2 5 10 any household shop
Filter cartridge boxes PP 2.5 L 6 10 60 household shop / dedeman.ro
Stilling tube PVC 75 mm × 0.5 m + bracket 1 25 25 dedeman.ro
Filter media: pea gravel 5 kg, pool filter sand 25 kg, activated carbon 500 g 1 110 110 dedeman.ro, aquarium shop
Soil: topsoil 20 L + washed sand 10 kg 1 30 30 dedeman.ro
Seeds: Lolium perenne 0.5 kg, wheat 1 kg, Trifolium repens 100 g 1 45 45 Agroland / dedeman.ro
BIO: Ceratophyllum ×2, Egeria ×2, Lemna, Planorbarius ×5, dechlorinator 1 110 110 aquarium shops
Fertiliser: NPK 15-15-15 granular 1 kg + soluble NPK 20-20-20 1 kg 1 55 55 dedeman.ro / garden centre
Water tests: 6-in-1 strips (50) + PO4 drop test 1 154 154 JBL, emag.ro
Lab: coffee filters, 1 L jugs ×4, 100 mL cylinders ×2, 0.5 L jars ×12, kaolin 500 g, catch cups, Secchi/colour cards (0.01 g scale shared with team 1) 1 150 150
Subtotal 2 774 RON (≈ 544 EUR)

Not included (shared pool): PHPEN, TDSPEN, syringes, labels, sample bags, small tools, hub/router. Spring item to budget: spare pH probe ≈ 70 RON.

Changes vs. draft allocation: SOIL 1 → 2 (one per lane, needed for antecedent-moisture control and A/B replication); TURB 1 → 2 (second as bench probe for runoff, filter in/out and jar samples — replaces buying a turbidimeter).

8-week timeline

Check the 2026–27 school calendar: if the autumn break falls in week 1, the teacher sows the cassettes. Nov 30 and Dec 1 are public holidays.

gantt
  title EcoColumn build and first experiments
  dateFormat YYYY-MM-DD
  axisFormat %d %b
  section Build
  Collect parts, soil mix, sow cassettes      :b1, 2026-10-26, 5d
  Rack, cassettes, platform, rain bars        :b2, 2026-11-02, 5d
  Node wiring, ESPHome, HA dashboard          :b3, 2026-11-04, 6d
  Supply line, filters, pond hardware         :b4, 2026-11-09, 5d
  Calibrations and interlock tests            :b5, 2026-11-12, 6d
  Commissioning sign-off                      :milestone, m1, 2026-12-15, 0d
  section Biology
  Grass establishment                         :g1, 2026-10-27, 21d
  Pond fill and plants                        :g2, 2026-11-03, 7d
  Snails and inoculum, pond baseline          :g3, 2026-11-10, 28d
  Jar dose bioassay                           :g4, 2026-11-18, 21d
  Fertilised runoff into pond                 :g5, 2026-12-07, 12d
  section Experiments
  Bare vs bare calibration events             :e1, 2026-11-17, 4d
  H1 vegetated vs bare with swap              :e2, 2026-11-23, 5d
  H1b angle series                            :e3, 2026-12-02, 3d
  H3 buffer strip with fertiliser             :e4, 2026-12-07, 5d
  section Engineering
  Rain bar uniformity v0 to v1                :n1, 2026-11-12, 5d
  Filter v1 build and tests                   :n2, 2026-11-23, 9d
  Filter v2 iteration                         :n3, 2026-12-07, 5d
  section Report
  Analysis and presentation                   :r1, 2026-12-14, 5d
Week Dates Deliverable
1 Oct 26–30 Parts collected, cassettes sown, soil mix sieved
2 Nov 2–6 Rack + cassettes + platform built; pond filled and planted; node flashed
3 Nov 9–13 Supply line + filters; FLOW, JSN, pH, TURB, SOIL calibrated; snails + inoculum in
4 Nov 16–20 Interlocks tested; rain CU ≥ 80 %; 3 calibration events; jars started Nov 18
5 Nov 23–27 H1 events with position swap; filter v1 built
6 Nov 30–Dec 4 (holidays Mon–Tue) angle series; filter v1 tests; jar day-14 readings
7 Dec 7–11 H3 with fertiliser; filter v2; fertilised runoff starts entering pond
8 Dec 14–18 Final events, analysis, presentation; sign-off Dec 15; winter-break mode set

3. Toxic Ground — Brownfield

Node: mc-03-brownfield · Team: 3–4 students · Enclosure: TANK63 (60×30×35 cm) used as a 5-zone landscape + a cup "assay bench" for fast, truly replicated tests.

Safety baseline (repeat of HARD SAFETY RULES 1–5): contamination is simulated only — table salt (NaCl), household vinegar (acetic acid), baking soda / garden lime, compaction, a concrete tile and a 12 V heat pad. No heavy metals, no motor oil, no fuel, no fertiliser "spikes", no soil dug from roadsides or old industrial sites, ever. Everything inside or under the tank is ≤ 12 V DC; the only mains item is the certified PSU12 brick on the shelf above, on the RCD strip.

Concept (refined)

A 60 × 30 cm "city block" in a glass tank, divided by siliconed acrylic walls into five isolated soil cells, each one a typical urban damage type:

Zone Name Damage simulated Real-world analogue
A Paved + heat 10×10 cm concrete tile in the middle band, 12 V heat pad under the glass floor sealed soil, urban heat island
B Compacted soil tamped in 3 layers, +20–30 % bulk density car parks, construction sites, trampled verges
C Saline 3 g NaCl per kg dry soil de-icing salt along Bucharest roads and pavements
D Acidified pH lowered ~1.5 units with diluted vinegar acid-affected soil (concept only)
E Control loose, untreated mix reference "healthy" soil

The tank is the system-scale demonstration (one plot per treatment). The assay bench (48 × 400 mL clear cups) is where the real dose-response science and fast engineering screening happen, because cups can be truly replicated and cress gives a result in 7 days. Phase 1 (Nov–Dec): degrade, measure, understand. Phase 2 (Jan–May): restore zones A–D with the interventions that won on the bench, and track recovery against E.

Science track

Driving question: How do salt, pH change, heat and compaction — the typical damage of city soil — affect whether plants can germinate and grow, and which damage is worst?

Hypotheses (students write their own; these are the defaults):

ID Hypothesis Prediction Where tested
H1 Germination and growth fall as salinity rises cress germination at day 7: 0 g ≈ 90 %, 1 g/kg slightly lower, 3 g/kg clearly lower, 6 g/kg < 20 %; EC1:5 rises roughly linearly with dose bench S1 + tank C
H2 Compaction reduces root growth and infiltration more than germination germination in B ≈ E, but radish root length/mass and infiltration speed clearly lower in B tank B, bench C1
H3 Heated soil under pavement is warmer and drier and gives poorer growth at the pavement edge ΔT(A − E) at 2 cm ≈ +6 °C during the photoperiod; SOIL A dries faster; cress taller early, then wilts / lower final biomass tank A
H4 Shifting pH ±1.5 from the baseline reduces growth; raising pH with baking soda hurts more than with lime because it also adds sodium growth at pH −1.5 and +1.5 (lime) moderately lower; +1.5 (baking soda) lowest and EC1:5 highest bench P1 + tank D
H5 Salt-tolerant species (barley, orache) germinate where cress fails at 3 g/kg barley germination > 70 %, cress < 50 % bench S2

Variables

Type Variable How
Independent NaCl dose (0 / 1 / 3 / 6 g per kg dry soil); compaction (loose / tamped); heat (pad on / off); pH shift (−1.5 / 0 / +1.5 lime / +1.5 baking soda); species set at mixing, weighed to 0.1 g
Dependent germination % (day 3, 5, 7), shoot height (mm), leaf count, fresh/dry shoot mass (g), radish root length (mm), EC1:5 (µS/cm), pH1:5, infiltration time (s), penetration depth (mm), soil moisture (%), soil temperature (°C) manual + sensors
Controlled same soil mix batch, same seed lot, sowing depth 5 mm, seed count, water type (distilled), water volume by mass, light 14 h, room temperature, position in tank/bench (rotate bench cups every 2 days) protocol
Confounders to discuss heat dries soil (A); baking soda adds Na; vinegar is broken down by microbes so pH drifts back; potting soil already contains fertiliser salts (baseline EC); light is not perfectly even under the strip measure, don't ignore

Plot layout and replication

Every tank zone (11 × 28.8 cm inside) has the same three bands, front to back:

Pseudo-replication warning (teach it explicitly): the 3 rows inside one zone are sub-samples of one treated plot, not independent replicates. Tank results show patterns; the bench (3 independent cups per level) is what supports a statistical claim.

Assay bench (true replication). Clear PP cups 400 mL, no drainage holes, 250 g dry soil mix each, brought to 60 % of water-holding capacity by weight, 10 seeds per cup, cups covered with cling film until germination, labelled with code (not treatment) so counting is blind.

Run Factor levels Reps Species Cups Start
S1 NaCl 0 / 1 / 3 / 6 g·kg⁻¹ 3 cress 12 29 Oct
S2 NaCl 0 / 3 / 6 g·kg⁻¹ × cress / barley / orache 3 3 species 27 16 Nov
P1 pH −1.5 (vinegar) / 0 / +1.5 (lime) / +1.5 (baking soda) 3 cress 12 9 Nov
C1 loose / compacted (radish root length) 3 radish 6 9 Nov
R1–R3 engineering screening (see Engineering) 3 cress 12–18 from 16 Nov

Dosing calculations (students do these): salt dose per cup = 250 g × 3 g/kg = 0.75 g NaCl, dissolved in the water used to wet the cup. Tank zone: weigh the dry mix for that zone (≈ 3.2 L ≈ 2.2–2.6 kg), dose = mass × 3 g/kg (≈ 7 g). Expected EC1:5 increase: 1 g NaCl per L ≈ 2 000 µS/cm, and 1 g/kg in a 1:5 extract is 0.2 g/L → ≈ +400 µS/cm per g/kg (so 1 / 3 / 6 g/kg ≈ +400 / +1 200 / +2 400 µS/cm above the baseline). Students predict this before measuring, then compare.

pH shift: titrate a 100 g sample first — add 9 % vinegar diluted 1:10 in 5 mL steps, measure pH1:5 after each step, plot the curve, then scale to the zone mass. For +1.5 use garden lime (CaCO₃, slow, days) or baking soda (NaHCO₃, fast) the same way. Re-check pH weekly and re-dose zone D if it drifts back more than 0.5 units (record every dose).

Sampling schedule

What Tank Bench Who / tool
Sensors (moisture, T, RH, lux) every 60 s, automatic – node → HA/InfluxDB
Germination count day 2, 3, 5, 7, 10 after sowing same ruler, tweezers
Height (5 tallest per row) + leaf count 2× per week (Mon, Thu) day 7, 10, 14 ruler 1 mm
Photo on fixed grid every Monday + each count day day 7, 14 phone on tripod
EC1:5 + pH1:5 at setup, then every 2 weeks (middle band core) at setup + at end TDSPEN, PHPEN
Infiltration test at setup, week 4, week 8 (it disturbs soil — same spot) – 50 mm ring, 50 mL water
Penetrometer at setup, week 4, week 8 – pencil + 1 kg
Harvest biomass (fresh, then dry) cress day 14; radish day 28 day 14 kitchen scale 0.1 g
Leachate EC (sump tube) weekly if water present – syringe + TDSPEN

Manual measurement protocols

  1. Germination % = seeds with visible radicle ≥ 2 mm / seeds sown × 100, per row (tank) or per cup (bench).
  2. Height: soil surface to tip of the highest leaf, 5 tallest plants per row; leaf count = true leaves only (cotyledons separately).
  3. Soil EC and pH, 1:5 extract: take a core from the middle band with a cut-off 60 mL syringe (top 5 cm); air-dry 48 h on paper; crush, sieve 2 mm; weigh 10.0 g into a 100 mL screw-top jar; add 50 mL distilled water; shake 1 min, stand 30 min, shake again 30 s, let settle 30 min; dip TDSPEN (EC mode, auto-temperature-compensated to 25 °C) into the clear liquid, read when stable (30 s); rinse in distilled water; then PHPEN in the same extract. Record water temperature. Blank: distilled water alone must read < 10 µS/cm.
    • EC notes: report µS/cm, not "ppm". If a pen only shows TDS, convert with the pen's factor (NaCl scale: EC ≈ TDS × 2; "442" scale: EC ≈ TDS × 1.4 — check the manual). EC1:5 is a relative index: to estimate the saturated-paste ECe used in agronomy multiply by ≈ 8–14 for sandy mixes (texture-dependent; our peat-sand mix is uncertain, so we compare zones, not absolute agronomic classes). Rule of thumb: ECe > 4 dS/m = saline for most crops.
    • Calibrate TDSPEN with CALSOL EC 1413 µS/cm and PHPEN at pH 7 then 4 before every session; log the calibration.
  4. Infiltration: push a 5 cm long ring of 50 mm PVC pipe 2 cm into the soil; pour 50 mL distilled water in one go; stopwatch from pouring until no water glistens on the surface. Report seconds; repeat once 10 min later (second value = near-saturated rate).
  5. Penetrometer (static pencil test): an unsharpened HB pencil (flat 7 mm end) held vertically in a 20 mm PVC tube guide; place a 1.0 kg load (1 L water bottle) on top for 10 s; measure sinking depth in mm with a ruler. 3 readings per zone in the middle band, ≥ 3 cm apart. Calibrate the idea first on loose vs. tamped cups.
  6. Bulk density: 60 mL syringe core (volume known), oven-dry at 105 °C (teacher, kitchen oven) or air-dry 72 h, weigh: ρ = dry mass / volume (g/cm³).

Analysis

What shows by mid-December vs. spring

By ~15 Dec 2026 Spring 2027 (Feb–May)
Bench S1 and P1 complete (cress 7–10 days), S2 and C1 done; 2–3 rounds of engineering screening Restoration of zones A–D with the winning interventions; EC trend after leaching/phytoremediation
Tank: cress germination and 14-day biomass per zone; radish ~4 weeks (sown 19 Nov) — leaf size, first root swelling Radish to maturity; clover cover (%) and barley/orache biomass; repeat salinity test after 2 months of restoration
4+ weeks of sensor data: ΔT heat island, drying curves per zone Seasonal light change irrelevant (LED), but room temperature changes — compare winter vs. spring ΔT
Baseline + week-4 infiltration and penetrometer data Earthworm avoidance tests (optional), final report and poster

Engineering track

Problem statement: Our city block has four damaged plots (sealed + hot, compacted, salty, acidified). Design, build and test low-cost interventions that restore each plot so that plants grow at least 80 % as well as in the control soil, using only materials a school or a city could afford.

Requirements

# Requirement Measure Target
R1 Growth recovery cress shoot mass at day 14 as % of control ≥ 80 %
R2 Salt reduction (C) EC1:5 drop vs. untreated salty cups ≥ 50 % lower
R3 Infiltration (A, B) infiltration time ≤ 2 × control
R4 De-compaction (B) pencil penetration depth ≥ 75 % of control
R5 Heat (A) ΔT(A − E) at 2 cm with pad running the same program reduced by ≥ 2 °C
R6 Cost and safety materials per m² of real city soil; non-toxic < 50 RON/m² scaled, no hazardous materials
R7 No salt export leachate collected, measured and disposed of in the bin (never on garden beds) 100 % of leachate logged

Candidate interventions

Damage Intervention Mechanism (what students should explain) Test on bench / tank
Salt Leaching with distilled water (1, 2, 3 pore volumes) dissolves and moves NaCl down; salt moves, it does not disappear → leachate in sump bench cups with drain hole over a saucer; tank C via sump tube
Salt Agricultural gypsum 5 g/kg + leaching Ca²⁺ replaces Na⁺ on soil particles, keeps structure open while leaching; gypsum alone does not lower EC (it is itself a salt) bench R1
Salt Compost 20 % v/v / biochar 5 % v/v more organic matter and water holding; dilution; biochar can adsorb a little; note compost has its own EC — measure it bench R1
Salt Phytoremediation with Atriplex hortensis (orache), Hordeum vulgare (barley), Beta vulgaris (beet); optional Salicornia europaea tolerant plants grow and take up some Na; harvest and measure leaf-extract EC → students compute how little salt a crop removes (critical thinking) tank C Phase 2, bench S2
Compaction De-compaction (fork to 6 cm with a chopstick grid), compost + mulch, clover / radish "bio-drilling" pores reopened mechanically vs. by roots and organisms tank B, bench C1
Paving Pavement removal vs. permeable paving (pebbles / gravel-filled grid students design) water enters soil, evaporation cools tank A, infiltration test
Heat Mulch 2 cm bark, vegetation cover, shade canopy (paper/acrylic "tree" under the LED), evaporative watering less absorbed light, more evaporation; note our heat comes mainly from below (pad) — shade only reduces the LED share; use the IR thermometer on tile vs. mulch vs. soil tank A
pH Lime (for acid) / compost buffering; for alkaline, do not use more baking soda neutralisation, buffering bench P1 follow-up

Test criteria: each intervention is compared against (a) untreated damaged cups/zone and (b) control, with 3 cups per treatment; pass = meets R1 + its specific requirement. Cost is computed per m² from the actual grams used.

Iteration plan

  1. R1 (16–23 Nov): screen 5 treatments on 3 g/kg salty soil: untreated, leach 2 PV, gypsum + leach, compost 20 %, biochar 5 % (15 cups, cress, 7 days + EC).
  2. R2 (23–30 Nov): keep the best 2, vary dose (e.g. leach 1 vs. 3 PV; compost 10 vs. 30 %) and combine (gypsum + compost + leach).
  3. R3 (30 Nov–7 Dec): test the final recipe on 6 g/kg soil and on compacted soil.
  4. Tank (Jan–Mar): apply final recipes to zones A–D (one at a time, logged), re-sow, compare with E; second paved-zone design (permeable paving prototype v2) after first infiltration results.
  5. Each iteration: design sheet (sketch, prediction, cost), build, test, one-paragraph "what we change and why".

Enclosure & build

Recommendation: TANK63 (60×30×35 cm glass, ~5 mm walls, inside ≈ 58.8×28.8 cm) used upright as a landscape: wide footprint, shallow 12 cm substrate, 23 cm of air above for plants, lighting and fan. Glass gives a side view of soil layers and roots. (The 60×40 BOXPLASTIC tray alternative is cheaper but opaque sides hide the soil profile and the walls flex when dividers are siliconed; use it only if TANK63 is unavailable.)

Internal layout (left → right, viewed from the front)

Element Width (cm) Detail
Zone A — Paved + heat 11 tile 10×10×2 cm on 1 cm sand in middle band; HEATPAD under the glass floor below this zone
Thermal buffer 2 two acrylic dividers with a 20 mm XPS strip between (stops heat leaking into B)
Zone B — Compacted 11
Zone C — Saline 11
Zone D — Acidified 11
Zone E — Control 11
Dividers 5 × 0.3 3 mm acrylic, 28.6 × 16 cm, siliconed to floor and both long walls

Profile of each zone (bottom → top): 2 cm LECA drainage → geotextile → 10 cm soil mix → (zone A: 1 cm sand + tile). Each zone has a sump tube (16 mm PVC, 15 cm long, slotted bottom 2 cm, in the back-left corner down to the LECA) — a 60 mL syringe with silicone tubing pulls out excess water / leachate for measurement. Dividers stand 4 cm above the soil so watering cannot splash salt across zones.

Lid & light: two LEDPROFILE bars (cut to 58 cm, each with 55 cm of LEDSTRIP) screwed to two acrylic cross-bars (5 × 30 cm) resting on the top rim → LEDs 23 cm above the soil, at y ≈ 9 and y ≈ 20 cm. Rear half of the top covered by a 60 × 15 cm acrylic strip with a FAN cut-out (Ø 76 mm) above zone A and MESH-covered intake slots above zone E; front half open for access.

Under the tank: whole tank stands on a 20 mm XPS board (cushion + insulation); a 10×20 cm pocket is cut in the XPS under zone A for the HEATPAD, adhesive side up against the glass; KSD301 45 °C NC thermostat and 72 °C one-shot thermal fuse taped (aluminium tape) to the pad, wired in series in the pad's + lead. A filled tank weighs ≈ 45–50 kg: build it in its final place on a sturdy table.

Node box mounting: BOX on the wall/shelf bracket at the right end, box bottom above the tank rim; all cables enter from below via GLANDs with drip loops. PSU12 on the shelf above, on the RCD strip.

flowchart LR
  subgraph TANK["TANK63 top view - front at bottom - LEDs 23 cm above soil"]
    direction LR
    A["Zone A Paved plus heat - tile 10x10 cm, HEATPAD under glass"]
    X["XPS buffer 2 cm"]
    B["Zone B Compacted"]
    C["Zone C Saline 3 g NaCl per kg"]
    D["Zone D Acidified pH minus 1.5"]
    E["Zone E Control"]
    A --- X --- B --- C --- D --- E
  end
  S1(["SOIL A plus DS18B20 paved at 2 cm under tile"]) -.-> A
  S2(["SOIL B"]) -.-> B
  S3(["SOIL C plus SHT31 on back glass plus BH1750 at canopy"]) -.-> C
  S5(["DS18B20 ref plus SOIL D in control"]) -.-> E
  F(["FAN 80 mm in lid above A"]) -.-> A
  N["Node box mc-03-brownfield outside right end"]
  E --- N

Soil probe allocation: SOIL A (paved), B (compacted), C (saline), D-channel probe placed in zone E (control). Zone D (acidified) has no continuous probe (only 4 ADC1 soil channels in the pin map): it is loose like E, so it is watered with the same volume as E, and its variable is pH, checked by extract. (Entity names follow the zone: mc_03_soil_moisture_paved, _compacted, _saline, _control.)

Build steps

# Step Who Time
1 Clean tank, mark zone lines on outside of glass with tape students 0.5 h
2 Cut acrylic: 6 dividers 28.6 × 16 cm, 2 cross-bars, rear lid strip, fan hole (teacher at saw/drill; deburr) teacher + students 2 h
3 Silicone dividers (glue A/buffer pair with XPS between), tape-hold vertical; cure 48 h students 1 h + 48 h
4 Water-test each cell: fill 2 cm in one cell, check neighbours after 2 h students 0.5 h
5 Cut XPS base, pocket for HEATPAD; fit pad, KSD301, fuse; strain-relief lead Alacrity/teacher 1 h
6 Node box: ESP32 on TERMBOARD, BUCK set to 5.0 V before connecting, 3 MOSFET modules, terminal wiring, glands; flash ESPHome Alacrity + students 3 h
7 Seal SOIL probe top edges (conformal coat + heat-shrink); label all cables students 1 h
8 LED strips into profiles, cross-bars, fan in lid students 1.5 h
9 Mix soil batch, fill sumps + LECA + fabric, fill zones; treat C (salt), D (vinegar), compact B, lay tile in A students 3 h
10 Probe calibration per zone, sensor commissioning, heat-loop test with pad (observe 2 h) students + Alacrity 2 h
11 Sow; photo grid set-up students 1 h

Total ≈ 17 h of hands-on time + curing.

Biology

Indicator plants (all non-toxic, fast):

Species Common (RO) Role Germination / first data
Lepidium sativum garden cress (creson) main bioassay, salt-sensitive 2–3 days; data at 7–10 days
Raphanus sativus radish (ridiche de lună) root/compaction indicator 3–5 days; 3–4 weeks to swelling
Trifolium repens white clover (trifoi alb) ground cover, N-fixing, restoration 5–10 days; cover in 6–8 weeks
Hordeum vulgare barley (orz) moderately salt-tolerant cereal 2–4 days
Atriplex hortensis garden orache (lobodă de grădină) halophyte, phytoremediation 5–10 days
Beta vulgaris beet (sfeclă roșie) salt-tolerant crop 5–10 days
Salicornia europaea (optional) glasswort (brâncă) true halophyte, native to Romanian saline soils slow, 10–20 days; seeds only online

Seed sourcing (Bucharest): cress, radish, beet and orache seed packets (Agrosem, Florian, Opal, Agrosel brands, 3–7 RON/packet) at Dedeman, Hornbach, Leroy Merlin and agro shops (e.g. Piața Obor seed stalls); white clover in 100 g–1 kg lawn-seed bags (Dedeman/agro shops); barley as untreated feed grain from agro shops / pet shops ("orz", check it is not fungicide-treated seed — no coloured coating); Salicornia from online seed sellers (eMAG marketplace / EU shops). Use untreated seed only (no coloured fungicide coating).

Soil mix (one batch for everything, ~35 L): universal potting soil ("pământ universal", peat-based) : washed fine quartz sand = 1 : 1 by volume, mixed dry in a tub, sieved through 1 cm mesh. Measure baseline EC1:5 and pH1:5 of the batch (commercial potting soil often has 200–800 µS/cm of fertiliser salts and pH 5.5–6.5 — this is the "0" level). Do not use schoolyard or roadside soil (unknown contaminants).

Inoculants: optional mycorrhizal inoculant (garden-shop "micorize" product) dusted into the radish/clover rows in Phase 2 as an extra factor; clover nodules (pink = active) are a bonus indicator — if seed is not pre-inoculated, expect few nodules and record that.

Earthworms (optional bio-indicator, invertebrate): Eisenia fetida (red wigglers, "râme roșii", fishing shops, ~15 RON/cup). Use only in a separate avoidance test: a 1 L box split in half, control soil vs. test soil (salty / acid / restored), 10 worms placed on the line, cover dark, count on each side after 48 h; worms then return to the Orchestra of Rot compost. Never put worms in the salty tank zones.

Establishment steps

  1. Mix and moisten batch to ~60 % of water-holding capacity (squeeze test: holds shape, no dripping).
  2. Fill zones; apply treatments (salt dissolved in the wetting water, mixed in a bucket per zone before filling — homogeneous; vinegar the same way).
  3. Let zones equilibrate 3 days, then measure baseline EC/pH/infiltration/penetrometer.
  4. Sow with a template (cardboard strip with holes at 2 cm / 4 cm), 5 mm deep, mist with distilled water, cover the tank front half with cling film until day 3.
  5. Remove film when > 50 % of control seeds are up; begin height counts.

Instrumentation

Catalog ID Qty Placement Interval Purpose / entity
SOIL 4 vertical in middle band of zones A, B, C and E, inserted to the line (sensing 0–6 cm), 3 cm from the tile edge in A 60 s, mean of 10 samples moisture per zone; mc_03_soil_moisture_paved / _compacted / _saline / _control
DS18B20 2 (1) zone A, 2 cm deep directly under the tile; (2) zone E, 2 cm deep, middle band 60 s heat island ΔT and heater control; mc_03_soil_temp_paved, mc_03_soil_temp_ref
SHT31 1 back glass, 15 cm above soil, zone C, in its case, shielded from direct LED 60 s air T/RH, fan control; mc_03_air_temp, mc_03_air_humidity
BH1750 1 on a stake at canopy height (5 cm, raise as plants grow), zone C middle band, facing up 60 s photoperiod check, LED ageing; mc_03_light. Lux ≠ PAR — relative only
OLED 1 node box lid live values + Wi-Fi + heater state
PHPEN shared lab per protocol pH1:5
TDSPEN shared lab per protocol EC1:5, leachate EC
CALSOL shared lab before every session pH 4/7 + EC 1413 µS/cm
TOOL: IR thermometer 1 handheld each measurement day surface T of tile / mulch / soil / leaves

Pin assignment (standard pin map only)

Function GPIO Connected
I2C SDA / SCL 21 / 22 SHT31 (0x44), BH1750 (0x23), OLED (0x3C)
1-Wire 4 DS18B20 ×2, 4.7 kΩ pull-up to 3.3 V
Analog A / B / C / D 32 / 33 / 34 / 35 SOIL paved / compacted / saline / control
PWM 1 (light) 16 MOSFET → LEDSTRIP (2 × 55 cm)
PWM 2 (fan) 17 MOSFET → FAN
PWM 3 (pump) 18 unused (irrigation manual)
PWM 4 (heater) 19 MOSFET → KSD301 → fuse → HEATPAD
Not used 36, 39, 23, 25, 26, 27, 13, 14, 5, 15, 12 free for student extensions (e.g. analog E for a later continuous probe)

MOSFET modules: use logic-level D4184 type (IRF520 boards do not fully switch at 3.3 V gate drive). Soil probes powered from 3.3 V so their output stays inside the ADC range; ADC attenuation 11 dB (written 12db in current ESPHome).

Power budget (PSU12 12 V 5 A = 60 W): LEDs 1.1 m × 14.4 W/m ≈ 16 W, HEATPAD 20 W, FAN 1.5 W, ESP32 + sensors via BUCK ≈ 2 W → ≈ 40 W peak (67 % of rating).

Soil probe calibration (per probe, per zone, in that zone's own soil):

  1. Take ~400 mL of the zone's treated mix (salty mix for C, compacted core for B) in a cup.
  2. Air reading (probe in air) and dry reading (air-dry mix) → 0 %.
  3. Saturated reading (add distilled water until free water appears, wait 30 min) → 100 % of saturation.
  4. A gravimetric mid-point: weigh cup, compute water content, record raw ADC → check linearity.
  5. Enter dry/wet raw voltages in ESPHome calibrate_linear for that channel; re-check in week 6.

Why per zone, including salty soil: a resistive fork probe measures the electrical current through the soil, which depends on dissolved ions as much as on water — adding salt makes the soil read "wet" even when it is dry, and the DC current corrodes the forks. A capacitive probe measures the soil's dielectric permittivity (water ≈ 80, mineral/organic matter ≈ 3–5, air = 1), which depends mostly on water content, so salt affects it much less. But the v2.0 probe works at a relatively low frequency (~1.5 MHz), where high ionic conductivity still raises the reading somewhat, and peat vs. compacted sand changes the dry/wet endpoints. So zone C may read a few % "wetter" than reality, and B differs from E — without per-zone calibration a moisture difference could be a salt or density artefact. Students can test this directly: same water content, 0 vs. 6 g/kg cup, compare raw readings.

ESPHome excerpt (heater loop; full YAML in the repo):

one_wire:
  - platform: gpio
    pin: GPIO4
sensor:
  - platform: dallas_temp
    id: t_paved
    name: "mc_03_soil_temp_paved"
    address: 0x0000000000000000   # fill in from log
  - platform: dallas_temp
    id: t_ref
    name: "mc_03_soil_temp_ref"
    address: 0x0000000000000000
output:
  - platform: slow_pwm
    id: heat_out
    pin: GPIO19
    period: 10s
globals:
  - id: heat_lockout
    type: bool
    restore_value: true
    initial_value: "false"
number:
  - platform: template
    id: delta_t
    name: "mc_03_heat_delta_setpoint"
    min_value: 0
    max_value: 8
    step: 0.5
    initial_value: 6
    optimistic: true
    restore_value: true
switch:
  - platform: template
    id: heat_enable
    name: "mc_03_heat_enable"
    optimistic: true
    restore_mode: RESTORE_DEFAULT_OFF
button:
  - platform: template
    name: "mc_03_heat_reset"
    on_press:
      - lambda: 'if (id(t_paved).state < 35) id(heat_lockout) = false;'
interval:
  - interval: 30s
    then:
      - lambda: |-
          float tp = id(t_paved).state, tr = id(t_ref).state;
          bool bad = isnan(tp) || isnan(tr) || tp < -50 || tp > 84;
          if (!bad && tp >= 42.0f) id(heat_lockout) = true;
          if (bad || id(heat_lockout) || !id(heat_enable).state) { id(heat_out).set_level(0); return; }
          float target = std::min(tr + (float) id(delta_t).state, 38.0f);
          float duty = (target - tp) * 0.25f;          // 25 % per degC error
          duty = std::max(0.0f, std::min(duty, 0.70f)); // duty limit 70 %
          id(heat_out).set_level(duty);

Automation

Heat-island control (zone A). Goal: soil under the tile at 2 cm = reference (zone E) + 6 °C during the photoperiod. Layers of protection: (1) software target capped at 38 °C, P-control with duty limit 70 %; (2) software lockout at 42 °C paved-soil temperature or any sensor fault (needs a manual reset in HA, only accepted below 35 °C); (3) KSD301 45 °C NC bimetal thermostat on the pad (hardware, self-resetting) — the pad/glass never exceeds ~45 °C; (4) 72 °C one-shot thermal fuse in series as last resort. HA automation turns mc_03_heat_enable on at 07:30 and off at 21:00, and sends an alert on lockout. The heater is off during school holidays.

stateDiagram-v2
  [*] --> Off
  Off --> Regulating: heat_enable on and both probes valid
  Regulating --> Regulating: every 30 s duty = 0.25 x error, max 0.70
  Regulating --> Off: heat_enable off at 21.00
  Regulating --> Lockout: paved temp 42 or more, or probe fault
  Off --> Lockout: probe reads 42 or more
  Lockout --> Off: manual reset in HA and paved temp below 35
  note right of Regulating
    target = ref + 6, capped at 38
    KSD301 opens at 45 on the pad
  end note

Fan (GPIO17): air exchange 5 min every hour during the photoperiod; additionally ON at 100 % if mc_03_air_humidity > 85 % or mc_03_air_temp > 30 °C, OFF when < 80 % and < 28 °C (prevents mould on the cling-film days and condensation above the warm zone). PWM 25 kHz, minimum 40 % (below that 80 mm fans stall).

LED (GPIO16): 14 h/day, 07:00–21:00, ESPHome light with 15 min sunrise/sunset ramps, 80 % brightness default (adjust so BH1750 reads the same lux in every run; log the setting).

Irrigation stays manual, with measured volumes — why:

Operations

Watering protocol: distilled water only (Bucharest tap water adds ~300–500 µS/cm of salts). Water a zone when its calibrated moisture < 40 % of saturation; add water with a 60 mL syringe / 100 mL cylinder to bring it to ~60 % (volume from the calibration: mL = (target − current) × zone pore volume; start with 50 mL steps); water the cress and radish bands, never the tile (zone A: pour 1/3 of the dose on the tile edge to simulate runoff). Log zone, date, mL, reason. Same volume rules on the bench, by weight (cup to target mass).

Weekly checklist (Monday, 20 min)

Manual logs (shared spreadsheet, one tab each): sowing & counts; heights & leaves; EC/pH extracts (incl. calibration line); infiltration & penetrometer; watering & leachate; interventions (what, grams, cost); incidents.

End of term (by 18 Dec): harvest cress, dry biomass; radish measured (leave in); disable heater (heat_enable off, HA automation paused); LED 12 h; water all zones to 60 %, cover front with cling film (with 2 cm gap); teacher check once a week in the holiday (HA moisture alert at < 30 %); export data snapshot CSV.

Disposal: salty and vinegar-treated soil goes into a sealed bag in the general waste — never onto school garden beds or lawn (it would really salinise them). Control-zone soil can go to compost.

Safety & risks

Hazard Control
Salt (NaCl) non-toxic in these amounts but irritates eyes and cuts; goggles when mixing brine, gloves, wash hands; never taste anything; label all containers "NOT FOOD"
Vinegar 9 % eye/skin irritant: goggles + gloves, dilute 1:10 before use (adult handles concentrate), never mix with bleach or other cleaners; baking soda + vinegar fizz (CO₂) is harmless but done in an open cup
Baking soda / lime dust: scoop, do not pour from height; garden lime with gloves
Heat pad 12 V only, through MOSFET; software cap 38 °C, lockout 42 °C, KSD301 45 °C NC + 72 °C one-shot fuse on the pad; pad on XPS (not on wood/paper), no wet contact; never run it with the tank removed; off during holidays
Glass edges / weight rimless tank edges: gloves when moving; two people; fill in final position (≈ 50 kg filled); sturdy table
Acrylic cutting teacher at the saw/drill; students deburr with file; goggles
Electrical SELV ≤ 12 V inside/under the tank; PSU12 certified brick on shelf above on 30 mA RCD strip with drip loop; node box outside, glands from below; BUCK pre-set to 5.0 V before connecting the ESP32
Soil/biology gloves for soil and compost work; potting soil dust → moisten before mixing; wash hands; no schoolyard/roadside soil; only non-toxic plants; worms handled gently and returned to compost
Mould / fungus gnats fan schedule, don't overwater, mesh on intake

Educational outcomes & assessment

Outcome Evidence Assessed by
Formulate testable hypotheses with predictions hypothesis sheet with numeric predictions (e.g. EC per g/kg) teacher rubric 0–3
Design controlled, replicated experiments; recognise pseudo-replication bench plan + written explanation of tank vs. bench rubric
Precise measurement and calibration calibration log, EC/pH protocol carried out independently (observed) practical check
Quantitative reasoning dose calculations, % of control, dose-response graph, EC halving point worksheet
Systems thinking: salt moves, doesn't vanish; trade-offs (heat vs. moisture) leachate mass balance, discussion of confounders short written argument
Engineering design cycle requirements table, 3 iteration sheets, cost per m², final recipe design portfolio
Use of sensors/data Grafana ΔT chart interpreted, sensor limits stated (lux ≠ PAR, capacitive vs. resistive) presentation
Communication & civic link 5-min presentation "Which damage is worst for Bucharest soil and what would you do?" peer + teacher

Sub-BOM

Cost-cut 2026-10-20: the three optional biology lines (Salicornia, inoculant, worms) are removed; add in spring if the restoration round needs them.

Price basis: Romanian retail estimates incl. VAT, Oct 2026 — electronics optimusdigital.ro / cleste.ro / ardushop.ro; tank & aquaristics emag.ro / pet shops; building and garden items dedeman.ro / hornbach.ro; heat pad & thermal parts AliExpress fallback. Shared items (PHPEN, TDSPEN, CALSOL, Pi hub, router) are in the common BOM and shown here at 0.

ID / item Qty Unit RON Line RON Basis / note
ESP32 1 45 45 optimusdigital
TERMBOARD 1 30 30 optimusdigital/AliExpress
OLED 1 20 20 optimusdigital
SHT31 1 55 55 cased/PTFE version
DS18B20 2 15 30 waterproof 1 m
SOIL 4 10 40 v2.0 TL555 version; spares from common pool
BH1750 1 12 12
MOSFET 3 12 36 D4184 logic-level (light, fan, heater)
PSU12 1 60 60 certified 12 V 5 A brick + DC jack
BUCK 1 10 10 LM2596
BOX 1 35 35 IP65 ABS
GLAND 6 2.5 15 PG9; sensor cables grouped
FAN 1 25 25 12 V 80 mm
HEATPAD 1 45 45 12 V 20 W silicone 10×20 cm
PART: KSD301 45 °C NC thermostat 2 6 12 1 spare
PART: thermal fuse 72 °C 10 A one-shot 2 3 6 1 spare
LEDSTRIP 0.25 reel 110 28 1.1 m of a shared 5 m reel
LEDPROFILE 2 25 50 cut to 58 cm
PART: 4-core cable 0.25 mm², 5 m 1 15 15 sensor runs; ferrules from common lot
TANK63 1 260 260 60×30×35 glass, emag/pet shop
ACRYLIC 1 90 90 dividers, lid strip, cross-bars
SILICONE 1 30 30 aquarium-safe
MESH 0.1 m² 50/m² 5 intake slots
PART: XPS board 20 mm 1 20 20 Dedeman, base + buffer strip
PART: screws, brackets, standoffs 1 lot 15 15
BIO: universal potting soil 50 L 1 30 30 Dedeman
BIO: washed quartz sand 25 kg 1 20 20 Dedeman/Hornbach
BIO: LECA expanded clay 10 L 1 25 25 drainage layer
BIO: geotextile 1 m² 1 10 10
BIO: NaCl table salt 1 kg 1 3 3 supermarket
BIO: vinegar 9 % 1 L 1 5 5 supermarket
BIO: baking soda 500 g 1 6 6 supermarket
BIO: garden lime 2 kg 1 15 15 Dedeman
BIO: agricultural gypsum (CaSO₄·2H₂O) 2 kg 1 30 30 emag/agro shop — NOT construction plaster
BIO: vermicompost / compost 10 L 1 25 25 Dedeman
BIO: biochar 5 L 1 45 45 emag
BIO: pine bark mulch 10 L 1 15 15
BIO: distilled water 5 L 6 6 36 auto/supermarket
BIO: concrete tile/paver 10×10–10×20 cm 3 6 18 1 in use + prototypes
BIO: pebbles/gravel 5 kg 1 15 15 permeable paving prototypes
BIO: seeds cress (Lepidium sativum) 3 pkt 5 15 Agrosem/Florian
BIO: seeds radish (Raphanus sativus) 2 pkt 4 8
BIO: seeds white clover (Trifolium repens) 100 g 1 15 15
BIO: barley grain untreated (Hordeum vulgare) 1 kg 1 12 12 agro/pet shop
BIO: seeds orache (Atriplex hortensis) 1 pkt 7 7
BIO: seeds beet (Beta vulgaris) 1 pkt 4 4
TOOL: clear PP cups 400 mL 50 0.4 20 bench
TOOL: kitchen scale 0.1 g / 500 g 1 40 40 emag
TOOL: graduated cylinder 100 mL 1 15 15
TOOL: syringes 60 mL 4 3 12 cores + sump extraction
TOOL: PVC pipe 50 mm 0.5 m + 16 mm 1 m + 20 mm 0.3 m 1 13 13 infiltration rings, sumps, penetrometer guide
TOOL: screw-top sample jars 100 mL 12 1.5 18 1:5 extracts
TOOL: IR thermometer 1 60 60 emag
TOOL: 2 mm soil sieve 1 15 15
TOOL: nitrile gloves box 100 1 30 30
TOOL: safety goggles 2 12 24
TOOL: phone clamp + mini tripod 1 40 40 fixed photo grid
PHPEN, TDSPEN, CALSOL shared – 0 common pool
Subtotal 1 635 RON (≈ 321 EUR) of which electronics ≈ 584 RON; optional biology removed in the cost-cut pass

8-week timeline (26 Oct – 18 Dec 2026)

Week Dates Science Engineering / build Milestone
1 26–30 Oct driving question, hypotheses; soil batch mixed; baseline EC/pH; bench S1 sown 29 Oct order parts; design sketches of tank zones parts ordered, S1 running
2 2–6 Nov S1 counts day 2–7 (read 5 Nov); dose calculations for tank cut acrylic, silicone dividers (cure), water test first dose-response graph
3 9–13 Nov P1 (pH) and C1 (compaction) sown 9 Nov; vinegar titration curve node box built and flashed; LED/fan lid; heat-pad install node online in HA
4 16–20 Nov fill & treat zones, equilibrate 3 days, baseline infiltration/penetrometer; probe calibration; tank sown 19 Nov (cress + radish); S2 sown heat loop commissioned (2 h supervised test); R1 screening sown tank running, ΔT logged
5 23–27 Nov tank cress germination day 2–7; P1/C1 harvest R1 read → choose best 2; R2 sown iteration 1 report
6 30 Nov–4 Dec tank cress height + day-14 biomass (3 Dec); S2 read R2 read; R3 (6 g/kg + compacted) sown iteration 2 report
7 7–11 Dec week-4 infiltration/penetrometer; data analysis in spreadsheet + Grafana; radish ~3 weeks R3 read; final restoration recipe + cost/m²; Phase-2 plan commissioning complete by 15 Dec
8 14–18 Dec radish ~4 weeks measured; poster/presentation holiday mode (heater off, LED 12 h, cover, alerts) presentation; CSV snapshot

Phase 2 (Jan–May 2027): apply recipes to zones A–D, re-sow clover/barley/orache, monthly EC/pH/infiltration, spring repeat of S1 on restored soil, earthworm avoidance tests, final report.

4–5. The Future Is Not What It Used to Be (2026 vs 2056)

Concept (refined)

Two identical 45 L glass tanks get the same substrate batch, seed lot, pot layout, LED strip and lid. They differ only in a climate treatment package written in software:

Both tanks carry the full hardware set: heat pad, CO2 inlet, servo vent flap, pump and rain bars. The two ESPHome YAMLs differ only in substitutions:. Because of this, the treatments can be swapped between tanks in spring (crossover design) to separate the climate effect from any "tank effect".

This is a scenario experiment: heat, rainfall pattern and CO2 change together. Run 1 cannot attribute an effect to any single factor, and students must say so in their reports. A single-factor decomposition run is planned for spring (Run 3, CO2 dosing off).

Climate scenario definition

Parameter 2026 setpoint (mc-04) 2056 setpoint (mc-05) Source / justification
Air temperature Room-following. Heater floor 19 °C (pad only switches on if the tank drops below 19 °C at night or on weekends). Expected 20–25 °C with lights on. T_2026 (10-min mean) + 3.5 °C, clamped 22.5–30.5 °C. Fallback fixed 24.5 °C if T_2026 is unavailable > 10 min. Bucharest May–June mean ≈ 17–21 °C, so a classroom at 20–22 °C stands in for the growing season. Projections for SE Romania by 2041–2060 (ANM / Copernicus CORDEX, RCP8.5) give +1.5–2.5 °C annual mean and up to ~+3 °C in summer. +3.5 °C is a deliberately amplified high-emission summer plus urban-heat-island value, chosen so the effect exceeds sensor error and day-to-day noise.
Substrate temperature Response, logged (cap 30 °C) Response, logged (hard cap 30 °C; heater off above it) Heat comes from below (pad), as in a warming soil. Logged so students can see the soil–air gradient.
Establishment watering, days 0–6 after sowing 20 mL/pot/day at 10h00 Identical: 20 mL/pot/day Germination must not be killed by drought. During this week heat and CO2 are the only differences, which isolates the germination hypothesis.
Rain, amount (from day 7) 200 mL/pot per 14 days (≈ 22 mm on a 9.5 cm pot; ≈ 11 mm/week) Same 200 mL/pot per 14 days Bucharest normal ≈ 590–620 mm/yr (ANM 1991–2020) ≈ 11.5 mm/week. Pot area 90 cm²: 50 mL = 5.5 mm.
Rain, pattern 4 × 50 mL/pot: every Mon and Thu at 10h00 Every other Mon at 10h00: 150 mL/pot "cloudburst", delivered at full pump speed. The following Fri: 50 mL/pot. Then 10-day drought (Fri → Mon). IPCC AR6 WGI (Ch. 11–12, Mediterranean/SE Europe): heavier short extreme events and longer dry spells. Total volume is held equal, so only the distribution changes.
Rain, per tank per event (15 pots) 750 mL 2 250 mL (cloudburst) / 750 mL Pump time = volume ÷ calibrated mL/s.
Substrate moisture Response. Expected 35–65 % of calibrated scale (0 = air-dry mix, 100 = saturated). Response. Expected swings from ≈ 95 % (after the cloudburst) to < 15 % (end of drought). Moisture is the response, not a controlled setpoint. Controlling it would cancel the treatment.
Drought rescue n/a If a pot shows wilting score 3 for 24 h, the teacher may give 30 mL by syringe. Logged as a data point. Lets the run continue after a mis-specified drought. Every rescue becomes a result ("the 2056 drought kills radish seedlings at day X").
CO2 Room air, refreshed by scheduled "breaths". Expected 420–550 ppm nights/weekends, 800–1500 ppm in occupied lesson hours. 700–800 ppm during the light period (dose below 700, stop at 780). Night: no dosing, cap 1 000 ppm. Global mean ≈ 425 ppm in 2025 (NOAA). Urban Bucharest air ≈ 430–470. SSP2-4.5 gives ≈ 530–550 ppm by 2056, SSP5-8.5 ≈ 600 ppm. 700–800 ppm is amplified (late-century SSP3-7.0/5-8.5), chosen so the contrast stays > 200 ppm. SCD41 accuracy is ±(50 ppm + 5 %).
Air exchange Identical in both tanks: lid slider set to a 5 mm gap. A "breath" every 30 min opens the flap and runs the fan at 60 % for 60 s. Extra breath if RH > 92 % for 30 min. 2026 only: also an extra breath if CO2 < 430 ppm (photosynthetic depletion). Same breaths and same RH rule. A CO2 dose follows each breath. Matched ventilation keeps RH and evaporation comparable. Without it, a sealed 2056 tank would also be a "humid tank".
Relative humidity Response, logged Response, logged. Mister disabled in Run 1 (enabled only in the spring "tropical night" variant). Avoids adding an extra variable. Warmer air in the 2056 tank should lower RH slightly, which is realistic.
Light 3 × 46 cm 12 V full-spectrum strips, PWM 80 % (trimmed so BH1750 at canopy matches the other tank ± 5 %) Identical Light is a controlled variable. BH1750 measures lux, not PAR, which is fine for checking equality.
Photoperiod 14 h, 06h00–20h00 Identical Adequate for fast crops; the same in both.

Honest limits of the CO2 treatment (state this in student reports).

  1. Classroom air is not "2026 outdoor air". Occupied classrooms regularly reach 1 000–2 000 ppm (Fisk 2017, Indoor Air 27:1039, review of school ventilation; EN 16798-1 Cat. II wants < 800 ppm above outdoor). During lessons the 2026 tank can therefore sit at 1 200 ppm, above the 2056 target. Mitigations:
    • Put the pair in the least-occupied room (lab, not homeroom).
    • Ventilate windows at every break.
    • Report a treatment-fidelity metric: the share of light-period hours with CO2_2056 − CO2_2026 ≥ 200 ppm.
    • Expected fidelity is ≈ 75–80 %, because about 130 of the 168 hours in a week are unoccupied.
  2. The 2056 tank is semi-sealed. Plants deplete CO2 in light, so it is a dosing controller, not a "set and forget". The yeast generator overproduces by ≈ 10–40×, so the servo pinch valve meters it.
  3. A single SCD41 per tank samples one point. Mixing relies on heat-pad and LED convection. Check homogeneity during commissioning by moving the sensor to 3 heights.
  4. The SCD41 automatic self-calibration (ASC) assumes the sensor sees ~400 ppm weekly. The 2056 tank never does, so ASC is disabled on both sensors. Calibration is manual (see Instrumentation).

Science track

Driving question. If Bucharest's climate in 2056 is hotter, has its rain in fewer and heavier events, and has more CO2, how will common crop plants germinate, grow and use water compared with today?

Hypotheses (directional, testable by mid-December or in spring):

# Hypothesis Prediction Measured by
H1 Germination Warmer air and elevated CO2 speed up germination of cress and radish. Wheat changes less (cool-season crop). T50 (days to 50 % emergence) in 2056 ≤ 0.75 × T50 in 2026 for cress and radish. Final germination % the same (± 10 points). Daily emergence counts, days 1–7
H2 Growth/biomass Under the 2056 package, early shoot growth is faster while water is available (warmth + CO2 fertilisation of C3 plants). Final radish storage-root dry mass is lower (≥ 20 %) because of drought cycles and heat. Height RGR higher in 2056 days 7–14. Hypocotyl dry mass lower at harvest (day 31). Height, leaf count, fresh/dry mass, hypocotyl diameter
H3 Water use 2056 pots lose more water per day (higher VPD). During the cloudburst a larger share of the rain drains through unused. Daily mass loss per pot ≥ 1.3× the 2026 value. Drainage fraction of the cloudburst ≥ 30 % vs ≤ 10 % for 50 mL events. Pot weighing, drainage volume siphoned from the tank floor, SOIL curves
H4 Stress signs Visible drought stress (wilting, leaf rolling, chlorosis, tip burn) appears in 2056 from about day 6 of each drought window, and only rarely in 2026. ≥ 3 wilting-score-≥ 2 days per pot per drought window in 2056 vs 0 in 2026 Daily stress score 0–3, weekly photo

Variables.

Replication.

Sampling schedule.

What When Who
Automatic: SHT31, SCD41, DS18B20, SOIL, BH1750 every 60 s (SOIL = mean of 10 reads) node → InfluxDB
Emergence count (per pot, per species) daily, days 1–7 (incl. Fri; weekend counts back-filled from photos) student pair
Pot mass (5 kg / 1 g scale) Mon and Thu before 10h00. Also 30 min after every rain event. student pair
Height (tallest plant, ruler from substrate surface), leaf count Mon and Thu student pair
Stress score 0–3 (0 turgid, 1 slight droop, 2 wilted leaves, 3 collapsed) + chlorosis Y/N every school day student pair
Top-down photo from a fixed acrylic jig (phone, flash off, LEDs on) Mon student
Drainage on tank floor (syringe + tube into a measuring cylinder) 24 h after every event, then Mon student
Destructive harvest: thinned seedlings (day 7); cress (day 10 of each cycle); wheat clip at 3 cm (day 21); radish science pots (day 31) per timeline whole team
Dry mass: paper bags, oven 70 °C 48 h (teacher) or radiator shelf 7 days, then 0.01 g scale after each harvest teacher + student

Analysis.

What shows by mid-December vs spring.

Engineering track

Problem statement. "The 2056 climate stresses plants through heat, a cloudburst that drains away, and a 10-day drought. Using only low-cost, low-maintenance interventions a Bucharest gardener could copy, make radish plants in the 2056 tank produce at least 80 % of the 2026 radish dry mass, using no extra water."

Requirements.

  1. Water budget unchanged: 200 mL/pot per 14 days.
  2. No extra electricity per pot.
  3. Cost ≤ 2 RON per pot.
  4. Materials non-toxic and available from Dedeman/garden shops.
  5. Must not change light at canopy by > 10 % (shade cloth tested separately).
  6. Measurable effect on at least one of: pot moisture at end of drought, drainage fraction, dry mass, stress days.

Candidate solutions (students pick and justify).

Intervention Mechanism Run 1 (Nov–Jan) Spring
Mulch: 1 cm coco chips or chopped straw lower soil evaporation, cooler surface 2 pots per tank iterate thickness 0.5 / 1 / 2 cm
Hydrogel (potassium polyacrylate), 2 g dry per L of mix stores cloudburst water, releases it in drought 2 pots per tank dose 1 / 2 / 4 g/L
Living mulch: white clover Trifolium repens sown around radish shading of soil, competition trade-off – 2–3 pots
Drip stake per pot vs rain bar slower delivery, less runoff in the cloudburst – swap delivery on one row (5 pots)
Shade cloth 30 % over the drought row lower leaf temperature and VPD – only with lux logged; competes with light control
Drought-tolerant variety or species (e.g. wheat vs radish, or a "drought" radish cultivar) biology instead of engineering compare species in science pots if a cultivar is found

Test criteria.

Iteration plan.

  1. Nov: build the baseline (mulch, hydrogel), log, harvest radish Jan 11.
  2. Jan: design review. Each team presents its data, rejects one intervention and refines one (dose or thickness).
  3. Feb–Mar: iteration 2 in the crossover run with 3 levels of the kept intervention.
  4. Apr–May: iteration 3 combines the best intervention with drip stakes or living mulch.
  5. June: final "resilience recipe" card for the Time Capsule team.

Enclosure & build

Tanks.

Lids (identical on both; students design and cut).

Inside layout (bottom → top).

  1. Tank floor = drainage sump; drainage is siphoned out by syringe.
  2. Four 10 mm rigid PVC rails across the floor, siliconed, so pots stand 1.2 cm above the water.
  3. 15 square pots, 9.5 cm, in a 5 × 3 grid.
  4. Sensor mast: an acrylic strip siliconed to the back glass, centre, carrying:
    • BH1750 facing up at 14 cm above floor (canopy height);
    • SCD41 at 16 cm and SHT31 at 18 cm, each inside a white PP radiation shield (a small cup with holes, not in direct LED light).
  5. Rain bars: 3 rigid PVC tubes (8–10 mm, one per row of 5 pots), end-capped, with 2 × 1.2 mm holes above each pot. They are fed by a cross/tee from the 6 mm supply and clipped 4 cm above the pot rims.
  6. CO2 outlet: tube end at canopy height, back centre, opposite the exhaust fan.

Heat pad (both tanks; only treatment-active on 2056).

Water.

Mister (mc-05 only, Run 1 disabled).

CO2 generator (mc-05; moves with the 2056 treatment).

Node boxes.

flowchart TD
  PSU["PSU12 12 V 5 A brick on shelf, RCD strip"] --> NODE["Node box BOX, ESP32 + TERMBOARD + BUCK + 4 MOSFET + RELAY + OLED"]
  NODE -->|"PWM1 GPIO16"| LED["3 x LEDSTRIP in LEDPROFILE under lid"]
  NODE -->|"PWM2 GPIO17"| FAN["FAN 80 mm exhaust on lid"]
  NODE -->|"Servo2 GPIO27"| FLAP["Vent flap over fan"]
  NODE -->|"PWM3 GPIO18"| PUMP["PUMP 12 V in RESERVOIR 10 L, below tank"]
  PUMP --> NRV["Non-return valve"] --> BARS["3 rain bars over 5 x 3 pots"]
  NODE -->|"PWM4 GPIO19"| FUSE["KSD301 45 C fuse"] --> PAD["HEATPAD 20 W on alu spreader in XPS pocket"]
  NODE -->|"Servo1 GPIO26"| PINCH["Pinch valve on CO2 line"]
  YEAST["PET yeast-sugar bottle, loose push-fit tube"] --> TEE["Tee"]
  TEE --> BUB["Open bubbler jar, 2 cm water relief"]
  TEE --> PINCH --> OUT["CO2 outlet at canopy height"]
  NODE -->|"Relay1 GPIO23"| MIST["MIST 24 V, mc-05 only, own adapter"]
  MAST["Sensor mast: SHT31 + SCD41 + BH1750 on I2C 21/22"] --> NODE
  PROBES["DS18B20 substrate + pad on GPIO4, SOIL A/B on GPIO32/33"] --> NODE
  FLOATS["FLOAT reservoir-low GPIO13, floor-flood GPIO14"] --> NODE
  NODE -.->|"Wi-Fi MICROCOSM"| HA["Home Assistant on PI5"]
flowchart LR
  LOT["One seed lot + one substrate batch, pots filled to equal mass"] --> A["Tank A mc-04"]
  LOT --> B["Tank B mc-05"]
  A --> R1A["Run 1 Nov-Jan, 2026 climate"]
  B --> R1B["Run 1 Nov-Jan, 2056 climate"]
  R1A --> R2A["Run 2 Feb-Mar, 2056 climate"]
  R1B --> R2B["Run 2 Feb-Mar, 2026 climate"]
  R1A --> CMP["Paired comparison by pot position"]
  R1B --> CMP
  R2A --> X["Crossover analysis: climate effect vs tank effect"]
  R2B --> X
  CMP --> X

Build steps (team of 4, teacher supervises tools).

# Step Time
1 Unpack and inspect tanks, label A/B, water-test 24 h on the bench for leaks 0.5 h + 24 h
2 Draw lid layout on paper at 1:1 (ports, glands, profiles) and get it reviewed 1.5 h
3 Cut 2 lids + flaps + slider + mast + sowing jig from ACRYLIC (score-and-snap; holes with step drill, teacher) 3 h
4 Fit gasket, fans, glands, mesh, slider, servo + flap, LED profiles. Solder or connect the LED strip leads with pre-crimped JST. 3 h
5 Cut XPS pockets, bond heat pad to spreader, fit KSD301, tape the pad DS18B20 1.5 h
6 Glue PVC rails + sensor mast inside the tanks with SILICONE, cure 24 h 1 h + 24 h
7 Build rain bars (drill holes, end caps, tees), plumb reservoir → pump → valve → bars 2 h
8 Wire both node boxes identically from one wiring sheet, glands + labels 4 h
9 Flash ESPHome (shared future_common.yaml + 2 substitution files), check entities in HA 2 h
10 Calibrations (sensors, pump mL/s, rain-bar cup test, lux matching) 3 h
11 Build the CO2 generator, bubbler and pinch valve; test valve closure by bubble-count (bubbles divert to bubbler when closed) 1.5 h
12 Commissioning: uniformity run + CO2 decay test + 2056 controller trial 5 days, 1 h/day

Biology

Species (same in both tanks, all C3, non-toxic, fast).

Species Role Pots per tank Seeds per pot → thinned to Depth Harvest
Raphanus sativus radish 'Roșu de Saxa' / 'Saxa 2' dicot, storage root, drought-sensitive 3 science + 6 engineering 10 → 2 at day 7 1 cm day 31 (science), day 56 (engineering)
Lepidium sativum garden cress (creson) very fast germination/biomass bioassay 3 30 (no thinning) surface + 2 mm sieved mix day 10, re-sown ×3
Triticum aestivum wheat (grâu pentru germinat, untreated) monocot, cool-season comparison 3 10 → 5 at day 7 2 cm clip at 3 cm on day 21 (regrowth measured to day 31)
Trifolium repens white clover ground cover / living mulch (engineering, spring) – – surface –

Seeds.

Substrate recipe (one batch for both tanks plus refills, ≈ 35 L).

Planting protocol (identical starting conditions).

  1. Fill each pot to the same moist mass (e.g. 420 g ± 5 g on the kitchen scale), tap 3× on the bench, label the pot ID (A01–A15, B01–B15) on its side.
  2. Place pots in both tanks according to the one random layout map.
  3. Size-sort radish seeds by sieve (keep 2.5–3.5 mm). Count seeds into labelled paper envelopes the day before.
  4. Sow with the acrylic dibber jig (10 pins at fixed depth). Use the same jig and the same person for both tanks, alternating A01, B01, A02, B02… so time of sowing is balanced.
  5. Water every pot with 30 mL by syringe right after sowing. Close lids. Start the treatments at the same minute on both nodes (HA script future_start_run).
  6. Day 7: thin (radish to 2, wheat to 5) by cutting at the soil surface. Bag the thinned seedlings for fresh/dry mass, which is the first biomass sample.
  7. Cress re-sowing: into fresh pots prepared at the same time from the same substrate bag, same mass.

Instrumentation

Per tank (identical on mc-04 and mc-05).

Catalog ID Qty per tank Placement Interval Purpose
SHT31 1 mast, 18 cm, in radiation shield 60 s air T (control variable for the heater loop) and RH
SCD41 1 mast, 16 cm, in radiation shield, ASC off 60 s (periodic mode 5 s, averaged) CO2 (2056 dosing loop; 2026 room tracking); T/RH cross-check
DS18B20 2 (a) substrate 5 cm deep in radish control pot (moves with pot); (b) taped to heat-pad spreader 60 s substrate T (cap 30 °C); pad safety (42 °C)
SOIL 2 A: radish control pot; B: radish hydrogel pot; inserted to the line, top sealed 60 s, mean of 10 moisture curves, drought timing, engineering comparison
BH1750 1 mast top, facing up, canopy height 14 cm 60 s light equality between tanks, photoperiod check
FLOAT 2 reservoir low; tank floor flood (2 cm) event pump inhibits
OLED 1 node box 2 s refresh live T, ΔT, CO2, SOIL, Wi-Fi

Pin assignment (standard pin map; same on both nodes).

Function GPIO Device / entity
I2C SDA/SCL 21 / 22 SHT31 0x44 (mc_0X_air_temp, _air_rh), SCD41 0x62 (mc_0X_co2), BH1750 0x23 (mc_0X_lux), OLED 0x3C. Bus 50 kHz, cable to mast ≤ 1 m
1-Wire 4 DS18B20 mc_0X_substrate_temp, mc_0X_pad_temp (by address)
Analog A / B 32 / 33 SOIL mc_0X_soil_moisture_a (control), _b (hydrogel)
PWM 1 16 MOSFET → LED strips
PWM 2 17 MOSFET → FAN
PWM 3 18 MOSFET → PUMP
PWM 4 19 MOSFET → KSD301 → HEATPAD (max_power: 0.6)
Relay 1 23 RELAY → MIST 24 V (mc-05; unused on mc-04)
Servo 1 / 2 26 / 27 CO2 pinch valve / vent flap
Digital in 1 / 2 13 / 14 FLOAT reservoir low / FLOAT floor flood
Unused 34, 35, 36, 39, 5, 15, 12, 25 spare (add SOIL C/D on 34/35 in spring if needed)

YAML difference between nodes (only substitutions):

# mc-05-future2056.yaml          # mc-04-future2026.yaml uses:
substitutions:
  node: mc-05-future2056          # mc-04-future2026
  heat_offset: "3.5"              # "0.0"
  t_floor: "22.5"                 # "19.0"
  co2_dose_below: "700"           # "0"  (dosing disabled)
  co2_stop_above: "780"           # "0"
  co2_extra_breath_below: "0"     # "430"
  rain_calendar: calendar.future_2056_rain   # calendar.future_2026_rain
  pump_ml_per_s: "14.2"           # each tank's own calibration
packages:
  common: !include future_common.yaml

Calibration.

Automation

Split of responsibilities.

stateDiagram-v2
  state Heater2056 {
    [*] --> H_IDLE
    H_IDLE --> H_ON : T_air below target minus 0.3 C
    H_ON --> H_IDLE : T_air above target plus 0.3 C
    H_ON --> H_FAULT : NaN or pad above 42 C or air above 31 C or substrate above 30 C
    H_IDLE --> H_FAULT : any temperature sensor NaN
    H_FAULT --> H_IDLE : sensors valid 10 min and teacher reset in HA
    H_ON : duty up to 60 pct, target is T_2026 plus 3.5, clamp 22.5 to 30.5
    H_FAULT : pad OFF, alert teacher
  }
  state Rain2056 {
    [*] --> R_WAIT
    R_WAIT --> R_PUMP : calendar event and reservoir OK and floor dry
    R_PUMP --> R_WAIT : volume delivered or 240 s cap
    R_PUMP --> R_LOCK : reservoir low or floor flood
    R_WAIT --> R_LOCK : reservoir low or floor flood
    R_LOCK --> R_WAIT : refilled and acknowledged
    R_WAIT : cloudburst Mon 150 mL per pot, shower Fri 50, then 10-day drought
  }
  state Air2056 {
    [*] --> A_SEALED
    A_SEALED --> A_BREATH : every 30 min or RH above 92 for 30 min
    A_BREATH --> A_DOSE : 60 s elapsed and lights on and CO2 below 700
    A_BREATH --> A_SEALED : 60 s elapsed otherwise
    A_SEALED --> A_DOSE : lights on and CO2 below 700
    A_DOSE --> A_SEALED : CO2 above 780 or 120 s dose
    A_SEALED --> A_PURGE : CO2 above 1500 or air above 32 C or SCD41 NaN
    A_DOSE --> A_PURGE : CO2 above 1500 or SCD41 NaN
    A_PURGE --> A_SEALED : CO2 below 1000 and air below 30 C and sensor valid
    A_SEALED : flap closed, fan off, valve closed
    A_BREATH : flap open, fan 60 pct, valve closed
    A_DOSE : flap closed, pinch valve open
    A_PURGE : flap open, fan 100 pct, valve closed, alert
  }
stateDiagram-v2
  state Air2026 {
    [*] --> S_SEALED
    S_SEALED --> S_BREATH : every 30 min, or CO2 below 430, or RH above 92 for 30 min
    S_BREATH --> S_SEALED : 60 s elapsed
    S_SEALED --> S_PURGE : air above 32 C or sensor NaN
    S_PURGE --> S_SEALED : air below 30 C and sensors valid
  }
  state Rain2026 {
    [*] --> W_WAIT
    W_WAIT --> W_PUMP : Mon and Thu 10h00, reservoir OK, floor dry
    W_PUMP --> W_WAIT : 750 mL delivered or 240 s cap
    W_PUMP --> W_LOCK : reservoir low or floor flood
    W_LOCK --> W_WAIT : refilled and acknowledged
  }
  state Floor2026 {
    [*] --> F_OFF
    F_OFF --> F_ON : T_air below 18.7 C
    F_ON --> F_OFF : T_air above 19.3 C or pad above 42 C or NaN
  }

Fail-safes (both nodes, implemented in ESPHome).

Home Assistant automations (in words).

  1. Rain calendars. Two HA Local Calendars, future_2026_rain and future_2056_rain, hold events titled RAIN 750 / RAIN 2250 (mL per tank). At event start, an automation calls esphome.mc_0X_rain with the volume, and the ESP converts it to pump seconds. Students see and edit the calendar, which counts as a protocol change and needs teacher approval. The 2056 calendar is pre-filled with the 14-day cycle up to June.
  2. Establishment week. Script future_start_run sets both nodes to "establishment" (20 mL/pot/day = 300 mL per tank at 10h00) for 7 days, then switches both to their calendars automatically.
  3. T link. sensor.mc_04_air_temp is imported on mc-05 via the ESPHome homeassistant sensor platform and filtered by a 10-min moving average.
  4. Breath sync. Both nodes schedule breaths at :00 and :30 from SNTP time, so they are simultaneous.
  5. Alerts (mobile app/Telegram to teacher):
    • reservoir low;
    • floor flood;
    • heater fault;
    • |ΔT − 3.5| > 0.7 °C for 2 h;
    • CO2 generator exhausted;
    • any sensor unavailable > 15 min;
    • node offline > 10 min.
  6. Fidelity dashboard (Grafana): ΔT, ΔCO2, lux ratio, SOIL A/B both tanks, rain events as annotations, plus a daily "fidelity score" sensor.
  7. Nightly CSV export (project-wide).

Operations

Daily (school days, 5 min, rotating pair).

Monday (30 min).

Thursday (15 min). Weigh pots before 10h00 (2026 rain day); height and leaf count.

Monthly. SCD41 FRC outdoors (both sensors); lux equality check; SOIL probe visual check for corrosion; clean the fan dust and mesh.

Manual logs (one printed sheet per tank per week plus a shared Google Sheet with the same columns): date, time, student initials, pot ID, mass g, height mm, leaves, stress score, notes, rescue mL, drainage mL, bubbler count, refills, anomalies. Every intervention on a tank (lid opened > 5 min, spill, rescue) goes in the log, because it explains spikes in the data.

Reservoir refills. 2026 uses ≈ 1.5 L/week; 2056 averages the same. A 10 L reservoir lasts 5–6 weeks. Before the winter break (Dec 18), fill both to 10 L, which covers 3 weeks.

CO2 generator refresh.

Safety & risks

Educational outcomes & assessment

Outcome Evidence Assessment
Formulate hypotheses with variables and controls Written H1–H4 with IV/DV/controls, before sowing Rubric 0–3: directional, measurable, justified
Understand controlled experiments and their limits Explanation of pseudo-replication, confounded package, CO2 room limit, crossover Short oral defence (5 min/team)
Measure carefully and reproducibly Log sheets, calibration records, inter-observer check (2 students score the same 5 pots) Completeness % plus agreement within 1 stress point
Analyse data Growth curves, T50, paired differences, fidelity metric, from InfluxDB/CSV in a spreadsheet Graph quality checklist (axes, units, n, error bars or points)
Engineering design Requirements, intervention choice, test results, iteration log, cost per pot Design-review presentation in January plus final recipe card
Systems/automation literacy Explain the 2056 state diagram, change one calendar event, read alerts Practical: trace an alert to its cause
Climate literacy Link setpoints to Bucharest normals and IPCC projections, and explain why they are amplified Poster section "What 2056 really means for Bucharest"

Sub-BOM

Cost-cut 2026-10-20: the 0.01 g pocket scale is shared with team 1; tanks are the 45 L MARINA size. (pair: mc-04 + mc-05)

Price basis: RON incl. VAT, Romanian web shops Oct 2026 (optimusdigital.ro, robofun.ro, ardushop.ro, emag.ro, dedeman.ro). AliExpress fallback noted where much cheaper.

ID / item Qty Unit RON Line RON Basis / note
ESP32 2 40 80 optimusdigital; 1 per node
TERMBOARD 2 35 70 emag/AliExpress
OLED 2 20 40 optimusdigital
SHT31 2 55 110 cased probe with cable, robofun/AliExpress
SCD41 2 240 480 robofun/ardushop; AliExpress ≈ 130
DS18B20 4 12 48 2 per tank (substrate + pad); +2 vs draft allocation
SOIL 4 12 48 v2.0 with TL555, sealed
BH1750 2 12 24 optimusdigital
FLOAT 4 10 40 reservoir low + floor flood per tank
FAN 2 25 50 80 mm 12 V
PUMP 2 25 50 12 V 3–5 W; uses the 2 approved submersible pumps
HEATPAD 2 45 90 12 V 20 W silicone; both tanks (crossover)
MIST 1 60 60 with 24 V adapter; mc-05
LEDSTRIP 1 110 110 one 5 m reel for both; 2.76 m used, rest spare
LEDPROFILE 3 25 75 each 1 m cut 2 × 46 cm
SERVO 4 12 48 pinch valve + flap per tank; uses all 4 approved
MOSFET 8 8 64 4 per node (light, fan, pump, heat)
RELAY 2 8 16 mister; second ready for crossover
PSU12 2 55 110 12 V 5 A per node (peak load ≈ 47 W)
BUCK 2 10 20 12 → 5 V, ESP32 + servos
BOX 2 35 70 IP65 150 × 110 × 70
GLAND 22 2 44 8 per box + 3 per lid
TANK45 2 220 440 50 × 30 × 30 rimless; same order
ACRYLIC 1 120 120 3 mm 50 × 100: 2 lids + parts
MESH 0.25 m² 40 10 intake slots
SILICONE 1 30 30 rails, mast
TUBING 8 m 5 40 pump lines, CO2 lines (soft silicone at pinch)
RESERVOIR 2 35 70 10 L food-grade with lid
MISC: KSD301 45 °C NC thermal cut-off 2 5 10 AliExpress/emag
MISC: aluminium sheet 0.5 mm 30 × 20 cm 2 15 30 dedeman
MISC: XPS board 20 mm 1 35 35 dedeman, cut to 2 × 50 × 30
MISC: EPDM foam gasket tape 2 15 30 dedeman
MISC: rigid PVC tube 8–10 mm (rain bars, rails) 3 m 5 15 dedeman; from approved "rigid tubes" lot
MISC: tees, crosses, end caps, 2 non-return valves 1 lot 35 35 approved "nozzles/valves" lots
MISC: radiation shields (PP cups), labels 1 lot 10 10 –
BIO: square pots 9.5 cm 60 1 60 30 in use + cress re-sowing + Run 2
BIO: universal potting soil 50 L 2 30 60 one batch through Run 3
BIO: perlite 10 L 1 20 20 –
BIO: washed sand 0–2 mm 5 kg 1 10 10 –
BIO: hydrogel (K-polyacrylate) 250 g 1 30 30 emag
BIO: coco chips 5 L 1 20 20 mulch
BIO: Raphanus sativus 'Saxa' seeds, same lot 3 5 15 Agrosel/Prosem
BIO: Lepidium sativum seeds, same lot 3 5 15 –
BIO: Triticum aestivum germination wheat 1 kg 1 15 15 –
BIO: Trifolium repens seeds 1 10 10 spring
BIO: dry yeast 11 g sachets 10 2 20 through Feb; restock later
BIO: white sugar 5 kg 5 25 –
TOOL: kitchen scale 5 kg / 1 g 1 50 50 pot weighing
TOOL: digital caliper 1 40 40 hypocotyl diameter
BIO: paper bags + permanent labels 1 lot 35 35 harvest
Subtotal 3 047 RON (≈ 597 EUR) hardware IDs 2 457 + misc/bio/tools 590

Changes vs the approved list:

8-week timeline (Oct 26 – Dec 18, 2026)

gantt
  title Future 2026 vs 2056 - build and Run 1
  dateFormat YYYY-MM-DD
  axisFormat %d %b
  section Plan and order
  Hypotheses, lid design, order parts and seeds :p1, 2026-10-26, 5d
  Substrate mix, seed pre-test               :p2, 2026-10-29, 4d
  section Build
  Tank leak test, lids, flaps, LED profiles  :b1, 2026-11-02, 5d
  Heat pad assembly, rails, mast, rain bars  :b2, 2026-11-03, 4d
  Node boxes wiring, ESPHome flashing        :b3, 2026-11-02, 6d
  CO2 generator and pinch valve              :b4, 2026-11-06, 2d
  section Commission
  Calibrations sensors pump lux              :c1, 2026-11-09, 2d
  Uniformity run both in 2026 mode           :c2, 2026-11-10, 3d
  CO2 decay test and 2056 controller trial   :c3, 2026-11-12, 4d
  section Run 1
  Sow all pots, treatments start             :milestone, m1, 2026-11-16, 0d
  Establishment week, germination counts     :r1, 2026-11-16, 7d
  Rain regimes start, 2056 cloudburst 1      :milestone, m2, 2026-11-23, 0d
  Drought cycle 1                            :r2, 2026-11-27, 10d
  Cloudburst 2 and drought cycle 2           :r3, 2026-12-07, 14d
  Cress cycles 1-3                           :r4, 2026-11-16, 31d
  Wheat clip day 21                          :milestone, m3, 2026-12-07, 0d
  Radish science harvest day 31              :milestone, m4, 2026-12-17, 0d
  section Report
  Mid-term data analysis and poster          :a1, 2026-12-10, 7d
  Winter-break prep, refill, 2 L CO2 bottle  :a2, 2026-12-18, 1d

Notes:

6. Forests in Space

Node: mc-06-regolith · Enclosure: TANK63 (60×30×35 cm) used as a pot "greenhouse" · Team: 3–4 students · Round 1 (cress) runs Nov 16 – Dec 7, 2026. Round 2 (peas/wheat) runs Jan–Mar 2027.

Concept (refined)

Students make a classroom regolith analogue (a mineral powder with no organic matter or nitrogen, alkaline and poor at holding water). They test whether plants can establish in it and which Earth-supplied amendment, at the smallest import mass, makes it a working growing medium. The experiment is 15 individually potted replicates in one lit, humidity-controlled glass tank, with gravimetric (by-weight) watering and destructive harvest. The node logs only the environment the pots share, plus the moisture/temperature of three marker pots. The plant data is collected by hand, and that is deliberate.

Real context (for the students' introduction, 1 page):

Why we do not buy certified simulant: LHS-1 (Space Resource Technologies, US) lists at $45/kg (≈ 210 RON/kg) plus US→RO shipping and customs, with lead times of several weeks. EAC-1A (ESA/EAC, Cologne) goes to ESA-supported research only and is not sold to schools. JSC-1A is discontinued in its original form. The ~15 kg this ecosystem needs would cost > 3 000 RON and might not arrive before December. Optional stretch: buy 1 kg LHS-1 (≈ 650 RON delivered) as a reference standard in Round 2 to benchmark our analogue against a real simulant (3 extra pots). It is not in the subtotal.

Classroom regolith analogue "MR-1" (Mare-type Regolith, recipe 1), by dry mass:

Component Mass % Role / lunar counterpart Source (Romania first)
Basalt rock dust (Gesteinsmehl/Urgesteinsmehl, garden remineraliser, mostly < 0.2 mm) 65 Mare basalt: pyroxene, plagioclase, Fe-Ti oxides eMAG marketplace / Amazon.de (Oscorna, Steinkraft "Bodenkraft" 5–7 kg bags). Alternative: basalt quarry fines 0–4 mm (Racoș basalt, Brașov county, via aggregate depots), sieved < 1 mm
Fine quartz sand 0.1–0.5 mm, washed, dry 25 Bulk mineral grains; lowers water retention Dedeman / Hornbach "nisip cuarțos" (filter or decorative sand, 25 kg)
Potassium feldspar powder 5 Stand-in for plagioclase/anorthosite (highland component) Ceramics/pottery suppliers (Bucharest), "feldspat" 1 kg. Optional: replace with more basalt if not found
Perlite, crushed and sieved < 1 mm 5 (≈ 10 % by volume) Stand-in for porous glass/agglutinates; low density Dedeman / garden centres, 5 L bag

Target grain size: 100 % < 1 mm and ≥ 50 % < 0.1 mm by mass (real lunar regolith: median ≈ 60–80 µm). Check by sieving 100 g through 1 mm and 0.5 mm kitchen sieves and weighing each fraction. Expected pH of the 1:5 water extract is 8–9 (fresh-crushed basalt is alkaline). Record the measured value. If the extract is < 7.5, add 1 % ground dolomitic lime and re-measure, and log this as a recipe change (MR-1b).

What MR-1 reproduces and what it does not

Lunar regolith property Why it matters to plants MR-1 reproduces?
No organic matter, no microbes No nutrient cycling, no aggregation, no water-holding humus Yes (baking optional, to kill bag contaminants)
No nitrogen (no NO₃⁻/NH₄⁺) N is the first limiting nutrient Yes
Alkaline, pH ≈ 8–9 in extract Locks up Fe, Mn, P, Zn Mostly (basalt dust is alkaline; measure)
Poor water retention, fast drainage, crusting Drought stress between waterings Yes (quartz + rock flour)
Nutrients present but locked in minerals (P, K, Ca, Mg, Fe) Plants starve despite "rich" chemistry Yes (basalt is the same rock type)
Very fine, cohesive dust Packing, compaction, root penetration, inhalation hazard Partly (fine, but less fine than real dust)
Sharp, jagged, unweathered grains and impact glass (agglutinates) Root abrasion, odd packing Partly (crushed rock is angular. No agglutinates or glass, perlite is a weak stand-in)
Nanophase metallic iron, solar-wind implants, highly reduced chemistry Probably the source of the 2022 stress-gene response No
Highlands anorthosite composition Different Ca/Al ratio No (MR-1 is "mare-type". Feldspar is only a gesture)
Low gravity, radiation, vacuum – No (out of scope)

Science track

Driving question: Can plants establish in a lunar-like mineral substrate, and which single Earth-supplied amendment gives the most plant growth per kg of imported material?

Treatments (codes used everywhere: labels, data sheets, entity ids):

Code Substrate (by volume) Tests
R0 100 % MR-1 analogue Baseline "raw regolith"
RC 80 % MR-1 + 20 % mature compost (sieved < 5 mm) Organic matter: water + nutrients + microbes together
RB 90 % MR-1 + 10 % biochar + slow-release fertiliser 3 g/L (Osmocote-type, ~15-9-11) Mineral nutrition + structure without organic matter decomposition
RM 95 % MR-1 + 5 % live soil from ecosystem 8 (Living Earth) + mycorrhizal powder (label dose, under the seed) Biology alone ("inoculate, don't fertilise")
P 100 % commercial universal potting soil Terrestrial control

Hypotheses (Round 1, cress):

Variables

Design: 5 treatments × 3 replicate pots = 15 pots. The pot is the experimental unit (n = 3). The 10 seedlings in a pot are sub-samples and are averaged first. Plus 1 extra R0 pot and 1 extra P pot outside the grid ("sacrificial" pots for root checks at day 10. They are not part of the statistics).

Sampling and manual measurements

Measurement When How Tool
Germination count Days 1–7, daily (school days) Cotyledons visible = germinated Eye, data sheet
Height Days 7, 14, 21 Soil surface to cotyledon/leaf tip, all seedlings Steel ruler 0.5 mm
Leaf colour score Days 14, 21 1–5 printed colour chart Chart
Green cover % Weekly photo Top-down photo → Canopeo app (free) or Fiji colour threshold Phone on fixed mount
Root length Day 21 (harvest), day 10 sacrificial pots Wash root ball over sieve, longest root of 5 seedlings Ruler
Shoot fresh mass Day 21 Cut at soil level, weigh per pot immediately Jewellery scale 0.001 g
Shoot dry mass Day 23–24 Paper envelope, 60 °C for 48 h (oven/dehydrator) → weigh 0.001 g scale
Substrate pH / EC Before sowing and after harvest 10 g substrate + 50 mL distilled water, shake 1 min, stand 30 min, measure supernatant PHPEN, TDSPEN (shared pool), CALSOL
WHC (drain-and-weigh) Week 3, each substrate × 3 See protocol below Kitchen scale 1 g
Water used Every watering Mass before/after (g = mL) Kitchen scale 1 g
Biological activity Harvest (a) catalase foam test, (b) CO₂ respiration (borrowed), (c) tea-bag index (long run) See below

Water-retention test (drain-and-weigh), per substrate, 3 replicates:

  1. Line a 7 cm pot (drain holes) with one layer of fine mesh. Weigh the empty pot (m_pot).
  2. Fill with dry substrate to 1 cm below the rim, tap 5× on the table, weigh (m_dry).
  3. Stand in a bowl of water up to 1 cm below the substrate surface for 60 min (saturation from below).
  4. Remove the pot, cover the top with cling film, let it drain on a rack for 120 min, weigh (m_fc).
  5. WHC (g water per g dry substrate) = (m_fc − m_dry) / (m_dry − m_pot). Volumetric WHC = (m_fc − m_dry) / 220 mL.
  6. Drying curve: leave uncovered in the running tank and weigh daily for 5 days → % of retained water lost per day.
  7. The 70 % watering target mass for each substrate = m_dry + 0.7 × (m_fc − m_dry).

Biological activity (no CO₂ sensor on this node):

Analysis (spreadsheet, template provided by the teacher):

What you can show by mid-December vs spring

Engineering track

Problem statement: design a growing medium made mostly of local regolith (MR-1) that supports a crop through a full cycle, while minimising material that must be shipped from Earth. Real lunar payload delivery costs on the order of $1 million per kg.

Requirements (measurable):

# Requirement Target Test
R1 Import mass fraction ≤ 20 % of dry mass from Earth (compost, biochar, fertiliser, soil) Recipe mass balance
R2 Water retention Gravimetric WHC ≥ 0.35 g/g (or ≥ 2× R0) Drain-and-weigh
R3 Drying rate Loses ≤ 25 % of retained water per day in the tank Daily weighing
R4 pH buffering 1:5 extract pH 6.0–7.5 after 3 weeks of watering PHPEN
R5 Salinity safe Extract EC 0.2–1.5 mS/cm (no fertiliser burn) TDSPEN (EC mode)
R6 Nutrient supply Dry mass ≥ 60 % of P at day 21 (cress), leaf colour ≥ 3 Harvest
R7 Structure No surface crust after 3 waterings. Seedlings emerge ≥ 80 % Visual, germination %
R8 Cost and availability ≤ 10 RON per litre of medium, all components buyable in Bucharest BOM

Candidate solutions (students brainstorm, then pick 4 for Round 1. The table lists the realistic set):

Test criteria → weighted decision matrix (filled in week 8): dry mass as % of P (35 %), WHC (20 %), pH/EC within range (15 %), import mass fraction (15 %), cost/availability (10 %), handling (dust, crusting) (5 %). Score each 0–5 from the measured data, not from opinion.

Iteration plan, Round 2 (sow Jan 11, harvest by mid-March, peas):

  1. Keep R0 and P as anchors.
  2. Take the best Round 1 amendment and run a dose series at 5 %, 10 % and 20 % → find the minimum import fraction that meets R6.
  3. Add one combination recipe designed by the students (e.g. 10 % compost + 5 % biochar + inoculum) = "MR-1 Optimised".
  4. Add a baked-inoculum control (RM soil heated at 120 °C for 1 h) to separate the effect of biology from that of the nutrients in the soil. This fixes the Round 1 confound.
  5. 5 treatments × 3 pots × 9 cm pots fit the same tank (grid 47.5 × 28.5 cm with saucers).
  6. Round 3 (spring, optional): scale the winning recipe to a 10 L "forest" pot. Engineering focus: long-term pH drift and WHC after 3 months.

Enclosure & build

Enclosure: TANK63 glass aquarium 60×30×35 cm (inner ≈ 59 × 29 cm). It is a clear humidity greenhouse that photographs well. A BOXPLASTIC (opaque) would block side light and photos, so it is not used.

flowchart LR
  subgraph TANK["TANK63 glass tank 60x30x35 cm"]
    subgraph ROW1["Row 1 (block 1, back)"]
      A1["RC"] --- A2["R0"] --- A3["P (SOIL C)"] --- A4["RM"] --- A5["RB"]
    end
    subgraph ROW2["Row 2 (block 2)"]
      B1["RM"] --- B2["RB"] --- B3["R0 (SOIL A)"] --- B4["P"] --- B5["RC (SOIL B)"]
    end
    subgraph ROW3["Row 3 (block 3, front)"]
      C1["P"] --- C2["RM"] --- C3["RB"] --- C4["RC"] --- C5["R0 (DS18B20)"]
    end
    STAND["Sensor stand: SHT31 at canopy height, BH1750 facing up"]
    SAC["Sacrificial pots R0-x and P-x"]
  end
  LED["Light bridge: 3 x 50 cm LEDSTRIP in LEDPROFILE above acrylic lid"]
  FAN["FAN 80 mm in lid, exhaust"]
  NODE["Node box mc-06-regolith (ESP32, OLED, 2 MOSFET, BUCK)"]
  PSU["PSU12 brick on shelf, RCD strip"]
  LED --> TANK
  FAN --> TANK
  NODE -->|"PWM 12 V"| LED
  NODE -->|"PWM 12 V"| FAN
  NODE ---|"I2C, 1-Wire, 3 analog"| TANK
  PSU -->|"12 V DC"| NODE

(The layout shown is one dice randomisation. Students re-roll their own and record it on the tank label.)

Build steps (team of 3–4, with time estimates):

# Step Time
1 Inspect TANK63 for chips. Place it on a foam mat on a sturdy table away from the radiator and direct sun. Two people carry it, empty 20 min
2 Cut the acrylic lid panels (teacher, fine-tooth saw or scoring knife), sand the edges, drill the 80 mm fan hole (hole saw, teacher) and cut the inlet slot. Glue mesh over the slot 90 min
3 Cut the aluminium angles to 65 cm. Cut the LEDPROFILE to 3 × 50 cm, and the LEDSTRIP to 3 × 50 cm at the marked cut points. Stick the strips in, solder or clip leads (teacher solders), fit the diffusers, screw the profiles to the angles (M3) 120 min
4 Node: ESP32 on TERMBOARD in BOX, BUCK set to 5.0 V before connecting the ESP32, 2 × MOSFET (LED, fan), OLED in the lid window, 6 GLANDs 120 min
5 Flash ESPHome mc-06-regolith.yaml, join the MICROCOSM SSID, adopt in Home Assistant, check entities 45 min
6 Sensor stand: acrylic offcut L-bracket. SHT31 at 10 cm height (canopy), BH1750 at pot-rim height facing up. Route cables through the lid gap edge (flat 4-core, under a bumper) 45 min
7 Seal the SOIL probes: conformal coat or nail varnish on the PCB edges, heat-shrink over the electronics, mark the insertion line at 6 cm 30 min
8 Light map: BH1750 on its cable at all 15 pot positions with LED at 80 % → map table. Adjust the riser if the min/max ratio is < 0.7 30 min
9 Calibration sessions (SOIL per substrate, SHT31 salt test, DS18B20 ice bath) 2 × 45 min

Regolith analogue preparation (teacher + 2 students, outdoors or by an open window, FFP2 + goggles + gloves):

  1. Weigh the components for a 10 kg batch: 6.5 kg basalt dust, 2.5 kg quartz sand, 0.5 kg feldspar, 0.5 kg perlite.
  2. Crush the perlite in a closed bag with a rolling pin. Sieve each component separately through a 1 mm kitchen sieve inside a large lidded bucket or bag (sieve low, no shaking in open air). Discard the > 1 mm fraction (or keep it for the crust-mulch experiment).
  3. Do not wash. The analogue stays dry and purely mineral. Washing would remove fines and soluble salts and change the pH.
  4. Optional sterilisation: spread 2 cm deep on oven trays, bake at 120 °C for 1 h (teacher, school kitchen/home oven), cool covered. Do this for all MR-1 so that R0 is "sterile like the Moon" and the RM inoculum is the only biology.
  5. Mix in a lidded 10 L bucket: close it, roll and tumble for 2 min, wait 5 min for the dust to settle, then open.
  6. Grain-size check: 100 g through 0.5 mm, weigh both fractions, record. Baseline pH/EC (1:5) and WHC.
  7. Store dry in the labelled lidded bucket ("MR-1 batch 1, date, mass").
  8. To suppress dust when filling pots, moisten the mix to ≈ 5 % water by mass (50 mL per kg, sprayed and stirred in the bucket). Do amendments by volume with a measuring jug: e.g. RC = 800 mL MR-1 + 200 mL compost, mixed in a bag.

Biology

Species

Species Use Why Source / RON
Lepidium sativum (garden cress, "creson") Round 1 Germinates in 1–2 days, harvestable at 14–21 days, sensitive to nutrient stress, uniform Any garden centre/Dedeman, ≈ 5 RON/packet
Raphanus sativus (radish, e.g. 'Saxa' / microgreen radish) Backup for Round 1, or pilot Bigger seed, visible hypocotyl, 3–4 weeks ≈ 5 RON
Pisum sativum (pea, e.g. 'Kelvedon Wonder') Round 2 Mycorrhizal host + root nodules (rhizobia) → tests the biology treatments ≈ 8 RON / 250 g
Triticum aestivum (wheat, wheatgrass grain) Round 2 optional Grass (Wageningen-style crop), mycorrhizal host ≈ 12 RON / 500 g (bio shop)
Pavement moss (Bryum argenteum or local cushion moss) Optional pioneer pot Pioneer on bare mineral substrate, no cost Collected from a school courtyard
Arabidopsis thaliana Not used Tiny, 6–8 week cycle, seed only via stock centres (NASC), hard to measure by hand. Cite it, don't grow it –

Lichens: not practical (growth is mm per year). Do not collect them.

Inoculants and amendments

Sowing protocol (Round 1, Monday Nov 16, 2026 = day 0)

  1. Seed viability test the week before: 2 × 20 seeds on wet paper towel in a closed box, count at 72 h. Expect ≥ 90 %. Use one packet and one lot for all pots.
  2. Fill the pots to 1 cm below the rim with the pre-moistened substrate, tap 5×, weigh and record m_dry_equiv (correct for the 5 % moisture).
  3. Bring each pot to its 70 % WHC target mass with a syringe, from below the surface (no splashing).
  4. Place 10 seeds per pot in a 3 × 3 + 1 pattern with tweezers (template card with 10 holes).
  5. Cover with 2–3 mm of the same substrate (dry, sprinkled through a tea sieve). Mist 5 sprays.
  6. Label each pot on two sides (code + block, e.g. "RC-1"), place according to the randomisation sheet, insert the probes in the marker pots at the 6 cm line, 1 cm from the wall, before the seeds go in.
  7. Lid closed, inlet taped, LED on schedule from the same day.
  8. Days 1–7: mist only (5 sprays per pot per school day). Weigh-watering starts on day 7.

Instrumentation

Catalog ID Qty Placement Interval Purpose
SOIL 3 A: pot R0 row 2 (B3). B: pot RC row 2 (B5). C: pot P row 1 (A3). Inserted to the 6 cm line 60 s (median of 10 samples) Drying curves after watering, analogue vs amended vs soil. Checks watering timing
DS18B20 1 Pot R0 row 3 (C5), probe tip at 3 cm depth 60 s Root-zone temperature. Dark basalt mineral vs air temperature under the LED
SHT31 1 Sensor stand, 10 cm above the floor (canopy height), shaded from direct LED 60 s Air T/RH. Humidity dome control (fan), damping-off risk
BH1750 1 Sensor stand at pot-rim height, facing up. Also used on a cable for the light map 60 s Light level at the canopy. Confirms LED schedule/PWM. Lux, not PAR
OLED 1 Node box lid window 5 s refresh Live values + Wi-Fi/HA status for students at the tank
PHPEN / TDSPEN / CALSOL shared pool Bench Before sowing, after harvest 1:5 substrate extracts

Why each SOIL probe is calibrated separately in its own substrate: a capacitive probe measures the bulk dielectric permittivity around it, not water directly. Water has ε ≈ 80, air 1, organic matter ≈ 2–5 and silicate minerals ≈ 4–9. Basalt with Fe-Ti oxides sits at the high end. MR-1 packs at ≈ 1.5 g/cm³, potting soil at ≈ 0.3–0.5 g/cm³, so the same raw reading means a different water content in each. The v2.0 probe works at ~1 MHz, where dissolved salts (fertiliser in RB, compost in RC) also raise the reading. So a single "soil" curve would make R0 look wetter or drier than it is. Every probe gets its own curve in the substrate of its marker pot, and graphs are reported in θv (mL water per 100 mL substrate) and in % of that substrate's WHC.

Pin assignment (standard pin map only):

Function GPIO Device / entity id
I2C SDA / SCL 21 / 22 SHT31 0x44 → mc_06_air_temp, mc_06_air_rh. BH1750 0x23 → mc_06_lux. OLED 0x3C
1-Wire 4 (4.7 kΩ to 3.3 V, on TERMBOARD) DS18B20 → mc_06_substrate_temp_r0
Analog A 32 SOIL A → mc_06_soil_moisture_r0
Analog B 33 SOIL B → mc_06_soil_moisture_rc
Analog C 34 SOIL C → mc_06_soil_moisture_p
PWM out 1 (light) 16 → MOSFET 1 → LED bridge mc_06_led (brightness logged as mc_06_led_pwm)
PWM out 2 (fan) 17 → MOSFET 2 → FAN mc_06_fan
Unused 18, 19, 23, 25, 26, 27, 13, 14, 5, 15, 12, 35, 36, 39 Free for Round 2 extensions (e.g. a 4th SOIL on GPIO35)

SOIL probes are powered from 3.3 V (the output then stays within the 0–3.1 V ADC range at 11 dB attenuation). I2C cable to the stand ≤ 1 m, 4-core twisted, at 100 kHz.

ESPHome core (excerpt):

substitutions: { node: mc-06-regolith }
i2c: { sda: 21, scl: 22, frequency: 100kHz }
one_wire: [{ platform: gpio, pin: 4 }]
sensor:
  - platform: sht3xd
    address: 0x44
    temperature: { name: mc_06_air_temp }
    humidity: { name: mc_06_air_rh, id: rh }
    update_interval: 60s
  - platform: bh1750
    name: mc_06_lux
    update_interval: 60s
  - platform: dallas_temp
    name: mc_06_substrate_temp_r0
    update_interval: 60s
  - platform: adc
    pin: GPIO32
    name: mc_06_soil_moisture_r0
    attenuation: 12db        # "11 dB" in older ESPHome
    update_interval: 6s
    unit_of_measurement: "%"   # theta_v, mL per 100 mL
    filters:
      - median: { window_size: 10, send_every: 10 }
      - calibrate_linear:   # MR-1 curve, replace with measured points
          - 2.60 -> 0.0
          - 1.45 -> 32.0
  # GPIO33 (rc) and GPIO34 (p) identical, each with its own curve
output:
  - { platform: ledc, pin: 16, id: pwm_led, frequency: 1000Hz }
  - { platform: ledc, pin: 17, id: pwm_fan, frequency: 25000Hz }
light:
  - { platform: monochromatic, output: pwm_led, name: mc_06_led, default_transition_length: 10min }
fan:
  - { platform: speed, output: pwm_fan, name: mc_06_fan }

Calibration

Automation

Minimal on purpose. The experiment's precision comes from hand-weighed watering.

stateDiagram-v2
  state "LED control" as LEDC {
    [*] --> Night
    Night --> Day : clock 0600, fade in 10 min
    Day --> Dimmed : air temp above 30 C
    Dimmed --> Day : air temp below 28 C
    Day --> Night : clock 2200, fade out 10 min
    Dimmed --> Night : clock 2200
  }
  state "Fan control" as FANC {
    [*] --> Off
    Off --> Venting : every 30 min in light period, or RH above 90
    Venting --> Off : after 5 min and RH below 85
    Off --> Locked : germination days 0 to 4
    Locked --> Off : day 5 flag set in HA
  }

Implementation: HA automations (the time triggers) + an ESPHome on_value rule for the temperature dim. If Wi-Fi/HA is down, the node keeps its last LED state, and an ESPHome time component with an SNTP fallback schedule (same 06–22) is included in the YAML, so the photoperiod survives a hub outage.

Operations

Daily (school days, 3 min, rota of 1 student):

Mon / Wed / Fri watering (15 min, from day 7):

Weekly photos (Friday 12:00, LED at 100 % for the photo then back to 80 %):

Harvest protocol (day 21 = Mon Dec 7, 2026; one double lesson):

  1. Final count, height of all seedlings, colour score. Photos.
  2. Cut the shoots at the substrate surface with scissors, one pot at a time. Weigh fresh mass per pot immediately (0.001 g scale, tared envelope) → record.
  3. Labelled paper envelope (code, date) → dry at 60 °C for 48 h → weigh dry mass. (If no oven/dehydrator: air-dry on a radiator for 7 days, weigh twice 24 h apart until constant, and note the method.)
  4. Roots: tip the pot onto a sieve over a bowl of water, soak 10 min, rinse gently, measure the longest root of 5 seedlings. Photograph the roots on a black card with a ruler.
  5. Substrate: take 20 g from each pot (1:5 extract for pH/EC + 2 g catalase test). Pool 100 g per treatment for the respiration run in ecosystem 8.
  6. Keep the R0 and RC substrates in labelled bags for Round 2 "conditioned regolith".
  7. Nothing from this experiment is eaten. Plant material goes to the compost (ecosystem 1).

Safety & risks

Educational outcomes & assessment

Students will be able to:

  1. Explain why germination is not establishment, using their own R0 vs P data and the 2022 Apollo-soil result.
  2. Design a controlled pot experiment with replication, randomised blocks and a terrestrial control, and say what their n = 3 can and cannot show.
  3. Measure water-holding capacity, pH and EC with standard methods, and explain why a capacitive sensor needs a separate calibration for each substrate.
  4. Translate an engineering goal (minimum import mass) into measurable requirements and a weighted decision matrix, and use the data to choose the Round 2 recipe.
  5. Combine manual data (biomass, counts) with logged sensor data (moisture curves, light, temperature) in one analysis.

Assessment (per team, 100 points):

Item Points Evidence
Research plan: question, hypotheses H1–H5 in their own words, variables table, randomisation sheet 15 Plan document, week 2
Analogue lab sheet: recipe mass balance, grain-size, pH/EC, WHC (with replicates) 15 Lab sheet, week 3
Data quality: complete germination/watering/harvest logs, photo series, calibration records 20 Shared spreadsheet + folder
Analysis: charts with all replicates, % of control, honest statement of uncertainty 20 Analysis sheet, week 8
Engineering: requirements table, decision matrix, justified Round 2 design 20 Design review, Dec 16
Communication: 5 min presentation / poster at the MICROCOSM showcase 10 Dec 17–18

Individual: each student keeps a lab notebook (dated entries). Roles rotate weekly (lead, measurer, recorder, safety/dust officer).

Sub-BOM

Cost-cut 2026-10-20: feldspar omitted from the analogue recipe (basalt + quartz + perlite only); kitchen scale shared with teams 4–5.

Price basis: Romanian retail estimates incl. VAT, October 2026 (optimusdigital.ro / cleste.ro for electronics, eMAG, Dedeman/Hornbach, garden centres; basalt rock dust via eMAG marketplace or Amazon.de incl. a shipping share). 1 EUR ≈ 5.1 RON. Shared pool items (PHPEN, TDSPEN, CALSOL, safety goggles, hand tools, Pi/router) are not counted here.

ID / item Qty Unit RON Line RON Basis / note
ESP32 1 40 40 DevKitC 38-pin
TERMBOARD 1 35 35 Screw-terminal breakout
OLED 1 20 20 SSD1306 0.96"
SHT31 1 55 55 Cased/PTFE membrane
SOIL 3 12 36 v2.0 TL555 version
DS18B20 1 15 15 Waterproof, 1 m
BH1750 1 15 15 Lux breakout
LEDSTRIP 1 140 140 1.5 m used (3 × 50 cm). 3.5 m returns to the pool
LEDPROFILE 2 30 60 Cut to 3 × 50 cm + 1 spare 50 cm
MOSFET 2 10 20 LED, fan
FAN 1 25 25 12 V 80 mm, lid exhaust
PSU12 1 60 60 12 V 5 A brick (load ≈ 1.6 A)
BUCK 1 10 10 12 → 5 V for ESP32 VIN
BOX 1 35 35 IP65 150×110×70
GLAND 6 2 12 3 SOIL, DS18B20, I2C, 12 V out
TANK63 1 260 260 Rimless glass 60×30×35
ACRYLIC 1 120 120 2 lid panels + sensor stand + photo bridge
MESH 0.1 m² 25 2.5 Inlet vent, pot bottoms in WHC test
BIO: basalt rock dust (Urgesteinsmehl), ≈ 6–7 kg bag 2 60 120 ≈ 12 kg → 15 kg MR-1 (2 rounds + tests)
BIO: fine quartz sand 0.1–0.5 mm, 25 kg 1 40 40 Dedeman/Hornbach
BIO: perlite 5 L 1 15 15 Dedeman
BIO: universal potting soil 20 L 1 25 25 Control P
BIO: mature compost 20 L 1 25 25 Or from ecosystem 1 (then 0)
BIO: horticultural biochar 3 L 1 50 50 eMAG
BIO: slow-release fertiliser (Osmocote-type) 300 g 1 40 40 Garden centre
BIO: mycorrhizal inoculant powder 1 45 45 eMAG/garden centre
BIO: seeds (cress ×2, radish, pea 250 g, wheat 500 g) 1 lot 35 35 Garden centre / bio shop
Consumable: square pots 7 cm 20 0.5 10 15 + 2 sacrificial + 3 WHC test
Consumable: square pots 9 cm 20 0.8 16 Round 2 + tea-bag pots
Consumable: saucers 8.5–10 cm 20 1 20 One per pot, no shared tray
Tool: jewellery scale 0.001 g / 50 g 1 70 70 Cress biomass is ≈ 20–60 mg dry per pot
Tool: stainless kitchen sieves (1 mm, 0.5 mm, tea sieve) 1 set 40 40 Analogue prep
Safety: FFP2 masks 10 2 20 Dust steps
Safety: nitrile gloves box 100 1 35 35 Shared with ecosystem 8 if needed
Consumable: lidded 10 L buckets 2 15 30 Mixing + storage
Consumable: distilled water 5 L 2 5 10 1:5 extracts
Hardware: aluminium angle 20×20 mm, 1 m 2 20 40 Light bridge
Hardware: M3 screws, silicone bumpers, 4-core cable 3 m 1 lot 20 20 –
Consumable: labels, paper envelopes, colour chart print 1 lot 15 15 –
BIO: tea bags green + rooibos (Tea Bag Index) 2 boxes 15 30 Pyramid bags
Consumable: H₂O₂ 3 % 100 mL 2 3 6 Catalase test
Subtotal 1 718 RON (≈ 337 EUR)
Optional (not in subtotal): LHS-1 certified simulant 1 kg 1 ≈ 337 EUR (650) $45/kg list + US shipping/customs, lead time several weeks

8-week timeline (Oct 26 – Dec 18, 2026)

gantt
  title Forests in Space - Round 1
  dateFormat YYYY-MM-DD
  axisFormat %d %b
  section Plan and order
  Team roles, question, read 2022 and Wageningen summaries :a1, 2026-10-26, 5d
  Order basalt dust, biochar, scales, myco online          :a2, 2026-10-26, 3d
  Dedeman and garden centre run                           :a3, 2026-10-29, 2d
  section Build
  Node assembly and ESPHome flash                         :b1, 2026-11-02, 4d
  Lid, light bridge, sensor stand                         :b2, 2026-11-02, 5d
  Seed viability test                                     :b3, 2026-11-03, 3d
  section Substrate
  Sieve, bake, mix MR-1, grain size                       :c1, 2026-11-09, 2d
  Baseline pH EC and WHC of all 5 substrates              :c2, 2026-11-10, 3d
  SOIL, SHT31, DS18B20 calibration and light map          :c3, 2026-11-11, 3d
  section Experiment
  Sow round 1 day 0                                       :milestone, d0, 2026-11-16, 0d
  Germination counts days 1 to 7                          :d1, 2026-11-17, 7d
  Growth, weigh-watering, weekly photos                   :d2, 2026-11-23, 14d
  Harvest day 21                                          :milestone, d3, 2026-12-07, 0d
  Drying, dry mass, extracts, catalase, respiration       :d4, 2026-12-07, 5d
  section Analyse and present
  Analysis and decision matrix                            :e1, 2026-12-09, 5d
  Commissioning sign-off                                  :milestone, e2, 2026-12-15, 0d
  Design review, Round 2 recipe                           :e3, 2026-12-16, 1d
  Showcase presentation                                   :e4, 2026-12-17, 2d
Week Dates Deliverable
1 Oct 26–30 Roles, research plan draft, all orders placed (online by Oct 28)
2 Nov 2–6 Node live in HA, lid + light bridge built, seed viability ≥ 90 %
3 Nov 9–13 MR-1 batch 1 (10 kg), baseline pH/EC/WHC table, 3 SOIL curves, light map, randomisation sheet
4 Nov 16–20 Sown Nov 16, germination curves
5 Nov 23–27 Day 7/14 heights, weigh-watering log, photo week 1–2. Pre-holiday watering Nov 27
6 Nov 30 – Dec 4 (Nov 30 – Dec 1 no school) Day 14–18 data, sacrificial-pot root check
7 Dec 7–11 Harvest Dec 7, dry mass Dec 9, extracts + biological activity tests
8 Dec 14–18 Analysis, decision matrix, sign-off Dec 15, Round 2 design Dec 16, showcase Dec 17–18. Tank reset for Round 2 (sow Jan 11, 2027)

Sources used for prices and context: Space Resource Technologies LHS-1 product page (spaceresourcetech.com, $45/kg list); Hornbach.ro crushed basalt listing (basalt aggregate availability in RO); Steinkraft "Bodenkraft" basalt powder (fromaustria.com) as an example of garden basalt rock dust; Paul et al., Commun. Biol. 5, 382 (2022); Wamelink et al., PLoS ONE 9(8): e103138 (2014).

7. The Hydroponic Jungle

Node: mc-07-hydro · Team: 3–4 students · Location: classroom bench, 60 × 85 cm growing footprint, a wall shelf ≥ 40 cm above the water line, and a hanging frame for the light.

Concept (refined)

This is a soil-free growing system with two parts:

  1. Main DWC unit (deep water culture), the "engineering" unit. An opaque 45 L food-grade PP box holds 25 L of nutrient solution and 8 net pots (50 mm). It is aerated by a COTS air pump. A 12 V pump circulates the solution. The node controls pH, EC and level automatically.
  2. Jar array, the "science" unit. A 3 × 3 grid of 9 × 2 L opaque glass jars, one plant per jar. These are cheap, independent replicates for the treatments (aeration, EC, light). Still (non-aerated) jars are Kratky jars. One jar has no plant and serves as the evaporation blank.

The node's probes stay in the DWC box. Students measure the jars by hand with the pens. This is deliberate: the jars teach measurement, and the DWC box teaches control.

Two pieces of 230 V equipment are allowed, and no others. The COTS LED panel hangs ≥ 30 cm above the open top of the unit, on its own cord. The COTS aquarium air pump sits on the shelf, and only its air line goes down into the water. Both plug into SMARTPLUGs on an RCD power strip. Everything that touches water or sits beside it runs on 12 V DC or less.

Science track

Driving question: What does a lettuce plant actually need from the water: oxygen, nutrients, or light? How much of each gives the most biomass?

Hypotheses (one per round)

Round When Hypothesis Treatment / control
R1 Aeration 9 Nov – 14 Dec 2026 H1: Aerated roots produce more root mass and shoot mass than still (Kratky) roots at the same EC (1.2 mS/cm). The difference grows once the roots fill the jar. 4 aerated jars vs 4 still jars + 1 blank. The DWC box (aerated, n = 8) is a descriptive reference, not a statistical treatment, because its container differs.
R2 Nutrients Jan – Feb 2027 H2: Shoot mass rises from EC 0.8 to 1.2 mS/cm and then levels off (or drops) at 1.6. Tip-burn appears first at 1.6. 3 × EC 0.8, 3 × EC 1.2, 3 × EC 1.6, all aerated. The blank moves to a corner of the tray.
R3 Light Mar – Apr 2027 H3: Biomass scales with daily light integral (DLI). Option A: distance to the panel (jars on risers at 30 / 45 / 60 cm under the panel). Option B: photoperiod 12 h vs 16 h, which needs a light-tight divider and a second LEDPANEL on its own SMARTPLUG (+≈ 260 RON). 3 distances × 3 jars (A, recommended, no extra cost)

Variables (R1)

Design rules for students

Sampling and manual measurements

What Who / tool When
pH, EC and water temperature of the DWC box with PHPEN / TDSPEN, entered into HA "pen check" fields duty student every school day at 10:00
pH and EC of each jar (pen; rinse in distilled water between jars) duty student Mon / Wed / Fri
Water consumption: jar level marks (mL scale on tape) and top-up reservoir level (L) duty student Mon / Wed / Fri
Leaf count (leaves > 1 cm) and height (rim to tallest leaf tip, cm) for every plant 2 students Mon and Thu
Photo of each plant from a fixed top view (phone on a jig) and of roots (lift the net pot, 10 s, back) 1 student Thu
Lux at each of 9 + 8 positions at canopy height (BH1750 on a stick) 1 student Monday after re-randomisation
Harvest: shoot fresh mass (0.1 g), root fresh mass (blotted), root dry mass (2 days on a radiator in a paper bag, then 0.01 g scale) whole team harvest day

Analysis

What shows by mid-December vs spring

Engineering track

Problem statement: Keep the solution in the DWC box within the plants' range automatically, with no manual dosing for 7 days. Targets: pH 5.8–6.2, EC 1.2 ± 0.1 mS/cm, level ± 1 cm. Plants change pH, nutrient concentration and volume every hour. The system must never overdose and must stop safely when something is wrong.

Requirements

ID Requirement Verified by
R1 pH held at 6.0 ± 0.3 for 7 days with no manual intervention InfluxDB: 100 % of 10-min medians inside 5.7–6.3
R2 EC held at 1.2 ± 0.1 mS/cm (25 °C-compensated) for 7 days same, 1.1–1.3
R3 Level held within ± 1 cm of setpoint; top-up reservoir lasts ≥ 4 days JSN log, top-up count
R4 No single dose > 10 s pump run; daily caps A/B ≤ 20 mL each, pH-down ≤ 10 mL ESPHome hard limits, dose log
R5 Dosing locks out on low level, empty top-up tank, implausible probe values, failed or stale pen cross-check, or air pump without power fault-injection tests (see below)
R6 Probe vs pen agreement ≤ 0.2 pH and ≤ 0.1 mS/cm at the daily check HA pen-check log
R7 All safety limits work with Wi-Fi or HA down test with the router unplugged
R8 Every component that touches water is ≤ 12 V DC; all 230 V on the shelf through a SMARTPLUG and RCD teacher checklist sign-off
R9 A student can recalibrate pH in ≤ 15 min using the printed card timed trial

Candidate solutions (students compare them and justify the choice)

Function Option A Option B Option C Recommended start
Top-up Mechanical mini float valve (aquarium/livestock type, ≈ 25 RON). Gravity-fed from a top-up tank raised ≥ 20 cm. No electronics, not logged, can stick open. 12 V PUMP in the top-up RESERVOIR, controlled by the JSN level. Overflow cut-off by FLOAT high; dry-run cut-off by FLOAT low. Logged, capped. Manual daily top-up B, with A built as a comparison in week 7. A frees one PUMP if the project is short on pumps.
Dosing Timed fixed doses every X h (open loop) Closed loop: measure → small dose → 15 min mix → re-measure, with caps and lockouts Proportional dose (volume ∝ error) B. C is a liceu iteration once dose-response is measured (titration).
Dose pumps 3 × PERI (A, B, pH-down) 2 × PERI with a one-part nutrient (e.g. GHE FloraNova Grow) Manual syringe A. Two-part A and B concentrates must never be mixed, so they need two pumps.
Mixing Air stone + circulation PUMP 5 min / 30 min, continuous during MIX Air stone only — A. Students test B in week 7: time until EC is uniform after a dose.
Phase 2 NFT gutter extension: 1 m square PVC NFT channel (100 × 50 mm) with 6 × 50 mm holes, slope 1:40, fed by the circulation PUMP, gravity return into the DWC box. The pump then runs continuously. Vertical tower — spring 2027

Test criteria (pass/fail, run 30 Nov – 6 Dec and again after each iteration)

  1. 7-day stability: pH 5.7–6.3 and EC 1.1–1.3 for 100 % of the time, with no human dosing. Refilling the top-up tank and dosing bottles is allowed and logged.
  2. Step response: add a defined disturbance of 2 L of plain dechlorinated water. The controller restores EC to within ± 0.1 in ≤ 3 dose cycles without overshooting by more than 0.15.
  3. Fault injection (each must lock out dosing and raise an HA alert within 2 min): lift the JSN probe and fake a low level by covering the stilling tube with a hand; lift FLOAT low in the top-up tank; unplug the air pump plug; enter a pen value 0.5 pH off the probe; force the pH probe out of the water (reading out of band).
  4. Watchdog: force a PERI on from the ESPHome web UI. It must stop by itself after ≤ 10 s.

Iteration plan

Enclosure & build

Main DWC box (BOXPLASTIC)

flowchart LR
    TAP["Tap water, dechlorinated 24 h"] --> TOP["Top-up RESERVOIR 20 L"]
    TOP -->|"PUMP top-up (12 V)"| DWC["DWC box 25 L, 8 net pots"]
    FLO["FLOAT low (dry-run)"] -.-> TOP
    FHI["FLOAT high (overflow)"] -.-> DWC
    NA["Bottle nutrient A"] -->|"PERI A"| DWC
    NB["Bottle nutrient B"] -->|"PERI B"| DWC
    ND["Bottle pH-down 5 percent"] -->|"PERI pH"| DWC
    AIR["AIRPUMP 230 V on shelf via SMARTPLUG"] -->|"air line + check valve"| DWC
    AIR -->|"gang valve"| JAR["Jar array 9 x 2 L"]
    DWC -->|"circulation PUMP loop"| DWC
    DWC --> PRB["Probes pH, TDS, DS18B20"]
    DWC --> JSNT["JSN in stilling tube"]
    PRB --> NODE["mc-07-hydro node box"]
    JSNT --> NODE
    NODE --> HA["Home Assistant on Pi 5"]
    LED["LEDPANEL 230 V via SMARTPLUG, 40 cm above"] -.->|"light"| DWC
    LED -.->|"light"| JAR
    DWC -->|"every 2 weeks, drain"| OUT["Spent solution to school plants"]

Build steps (student hours; teacher does all drilling of metal and the 48 mm hole saw work)

# Step Time
1 Lay out the lid on paper at 1:1, mark the holes, drill with the 48 mm hole saw, drill the 75/32/16 mm holes, deburr, test-fit pots 2 h
2 Light-proof the box and jars (film, foil, tape), make the jar lids 1.5 h
3 Build the PVC frame and reflectors; hang the panel; route the cord to the shelf with a drip loop (teacher checks) 2 h
4 Mount the shelf items: RCD strip, smart plugs, node box, PERI board, dosing tray 1 h
5 Flash the ESPHome base YAML; wire sensors on the screw terminals; bench-test all readings in a bucket of tap water 3 h
6 Make the stilling tube and probe holder; install JSN, floats, pumps, air stones, check valves, gang valve 2 h
7 Calibrate pH and TDS, calibrate the JSN level table, calibrate PERI flow (mL/s) and top-up pump flow (L/min) 2 h
8 Leak test: 24 h with plain water, pumps cycling, paper towel under every joint 1 h + 24 h
9 Fault-injection dry run (test criteria #3, #4) before the first plant goes in 1 h

Biology

Species

Species Use Start In DWC / jars
Lactuca sativa 'Lollo Rossa' (loose-leaf) and 'Grand Rapids' main experimental plant, fast (5 weeks after transplant), cut-and-come-again seed 27 Oct in rockwool 4 DWC + all 9 jars ('Lollo Rossa' only in jars)
Ocimum basilicum 'Genovese' (basil) slower; shows nutrient and temperature effects; pinch the tips seed 27 Oct, plus 1 supermarket pot divided into 3 plugs with the soil washed off 2 DWC
Mentha spicata / Mentha × piperita (mint) roots from cuttings in 7–10 days; vigorous; tests the controller under load 10 cm cuttings in water, 2 Nov 2 DWC
Fragaria × ananassa (strawberry, day-neutral 'Albion') spring 2027 NFT extension runners/plants Mar 2027 NFT

Seed starting: Soak Grodan 36/40 rockwool plugs (or coco plugs) for 1 h in tap water adjusted to pH 5.5. Squeeze lightly and sow 2 seeds per plug. Lettuce seed needs light: press it on the surface, do not cover. Put the tray under a humidity dome at 18–22 °C, 5 cm under the edge of the panel's light. On day 7, thin to 1 seedling. From day 7, feed the plugs with quarter-strength solution (EC 0.4).

Transplant: at day 12–14 (9–10 Nov), when 2–3 true leaves show and roots come out of the plug bottom. Place each plug in a net pot and fill around it with rinsed clay pebbles. In the DWC box the water touches the net pot bottom for the first 7 days. After that, lower the setpoint by 2 cm to create a root air zone.

Nutrients (available in Romania)

pH-down

Water

Target ranges: pH 5.8–6.2 (setpoint 6.0) · EC 1.0–1.4 mS/cm (lettuce 1.2; basil and mint tolerate 1.4) · water 18–22 °C (alert < 16 or > 24 °C; above 24 °C dissolved O₂ falls and Pythium root rot risk rises) · air 18–26 °C, 40–70 % RH · PPFD 200–300 µmol/m²/s at the canopy, DLI 12–17 mol/m²/day at 16 h.

Instrumentation

Catalog ID Qty Placement Interval Purpose
DS18B20 1 probe holder, 8 cm deep in the DWC box 60 s water temperature, temperature compensation for EC, root-rot alert
SHT31 1 on the frame at canopy height + 20 cm, shaded from the panel 60 s air T/RH, VPD (template sensor)
BH1750 1 at canopy height on a movable stick (1.5 m cable); fixed position = centre of the DWC lid 60 s lux, panel-on check, position mapping
JSN 1 top of the stilling tube 60 s (median of 5) continuous level, top-up control, consumption
FLOAT 2 #1 high, in the DWC box at 16.5 cm; #2 low, in the top-up reservoir event + 60 s overflow and dry-run hard stops
PHKIT 1 probe holder 10-min measurement window pH control
TDS 1 probe holder, ≥ 5 cm from pH 10-min measurement window EC control
PHPEN, TDSPEN shared pool handheld daily 10:00 cross-check, jar measurements
SMARTPLUG 2 shelf 60 s power (W) panel and air pump state, power-fail alert

pH and EC are not sampled every 60 s like the other sensors. They use a 10-minute measurement window: pump off → pH powered → 30 s settle → median of 10 → TDS powered → 10 s → median of 10 → back to pH power. The window avoids the ground-loop error and the bubble noise.

Pin assignment (standard pin map only)

Function GPIO Connected to
I2C SDA / SCL 21 / 22 SHT31 0x44, BH1750 0x23, OLED 0x3C
1-Wire 4 DS18B20 water (4.7 kΩ pull-up)
Analog E 36 (VP) PH-4502C Po, through a 10 k / 20 k divider (protects the ADC from > 3.3 V); attenuation 11 dB (12db in current ESPHome)
Analog F 39 (VN) Gravity TDS analog out (0–2.3 V)
PWM 1 (light slot: unused, the panel is on a SMARTPLUG) 16 MOSFET → PERI pH-down
PWM 2 (fan slot: no fan in this ecosystem) 17 MOSFET → PERI nutrient A
PWM 3 (pump) 18 MOSFET → circulation PUMP
PWM 4 (heater/mister slot: unused) 19 MOSFET → top-up PUMP
Relay 1 23 RELAY → PERI nutrient B (12 V, low-voltage load)
Relay 2 25 RELAY changeover: COM = 5 V, NC → PH-4502C VCC, NO → TDS VCC (probe power selector)
Digital in 1 / 2 13 / 14 FLOAT high (DWC) / FLOAT low (top-up), internal pull-up, switch to GND
Ultrasonic TRIG / ECHO 15 / 12 JSN-SR04T; ECHO through a 1 k / 2 k divider. GPIO12 is a strapping pin: the JSN echo idles low, so boot is safe; do not add a pull-up.
Reserved 0, 2 boot, onboard LED (blinks during dosing)
Unused 5, 26, 27, 32–35 free for phase 2 (e.g. FLOW on 5 for the NFT return)

Use relay modules with a 3.3 V-compatible input (jumper for high/low trigger). Power the MOSFET and relay modules from 12 V and 5 V respectively, with a common GND.

ESPHome hard limits (illustrative excerpt for students to complete; these run on the node even if HA is down)

switch:
  - platform: gpio
    pin: GPIO16
    id: peri_ph
    name: "mc_07_peri_ph_down"
    restore_mode: ALWAYS_OFF
    on_turn_on:
      - if:
          condition:
            or:
              - binary_sensor.is_on: dosing_lockout
              - lambda: 'return id(ph_dose_today_ml) >= 10.0;'
          then:
            - switch.turn_off: peri_ph
          else:
            - delay: !lambda 'return (uint32_t)(id(ph_dose_ml) / id(peri_ph_ml_per_s) * 1000);'
            - switch.turn_off: peri_ph
    on_turn_off:
      - lambda: 'id(ph_dose_today_ml) += id(ph_dose_ml);'
  # same pattern for peri_a (GPIO17), peri_b (GPIO23), topup_pump (GPIO19, max 60 s)
script:
  - id: watchdog
    then:
      - delay: 10s            # independent max-on for any PERI
      - switch.turn_off: peri_ph
      - switch.turn_off: peri_a
      - switch.turn_off: peri_b

(Students complete the analogous blocks; the daily counters reset at 00:00 via time → on_time. The ESPHome script runs with mode: restart and is executed on every PERI turn-on.)

Calibration procedures

Probe maintenance

Automation

Architecture: reflexes on the node, brain in HA.

Dosing controller

Setpoints: pH 6.0, dose when > 6.2. EC 1.2, dose when < 1.10. Dose sizes: pH-down 1.0 mL of 5 %; A + B 3.0 mL each. In 25 L this is ≈ +0.08 mS/cm per step. Students measure and replace this in v0.

stateDiagram-v2
    [*] --> Idle
    Idle --> Measure: every 30 min, 07h to 21h
    Measure --> Check: medians of pH and EC ready
    Check --> Locked: any lockout true
    Check --> DoseEC: EC below 1.10
    Check --> DosePH: EC ok and pH above 6.2
    Check --> Idle: all in band
    Check --> AlertHigh: EC above 1.40 or pH below 5.6
    DoseEC --> Mix: A 3 mL then wait 60 s then B 3 mL
    DosePH --> Mix: pH-down 1 mL
    Mix --> Measure: 15 min with circulation pump and air on
    AlertHigh --> Idle: notify team, no automatic action
    Locked --> Idle: lockout cleared by student acknowledge

The controller fixes EC first and pH second, because adding nutrient shifts pH. It makes at most one dose per Measure → Mix loop, and at most 6 dose loops per day.

Lockouts (any one blocks all dosing and sends an HA alert):

Air pump: always on (SMARTPLUG #2 on; HA turns it back on if it is ever off). Alert "Air pump no power" if the plug reports < 1 W for 5 min while on, or if the plug is unavailable for 5 min. Dosing locks out in either case.

Light (SMARTPLUG #1): 16 h on / 8 h off, 06:00–22:00. HA runs the automation, and a Tasmota/ESPHome timer on the plug itself is the fallback if the hub is down.

Circulation pump (GPIO18): 70 % PWM, 5 min on / 25 min off, continuous during Mix, and forced off during every Measure window and during top-up. Mid-shift, students compare EC uniformity with the pump off (air only).

Top-up (GPIO19):

Alerts to Home Assistant (mobile app notification to the team phone/tablet plus a dashboard banner): pH or EC out of band for > 2 h · dosing lockout (with reason) · daily cap reached · top-up tank low · overflow float · leak suspicion (top-up > 5 L/day) · water temperature out of range · air pump no power · panel failure / night light · node offline > 10 min · pen check overdue · calibration overdue (> 14 days).

Operations

Daily (school days, ≈ 10 min, duty student)

  1. Check the dashboard: any alerts and lockouts? Read the reason, fix it, acknowledge.
  2. Do the pen check at 10:00 in the DWC box: pH, EC, water temperature. Enter the values in HA and compare with the probes.
  3. Look: are the plants wilting or yellowing? Are the roots white? Is there algae (green film on the lid, at the holes)? Any leaks under the joints (paper towel)?
  4. Check the top-up tank level. Refill with dechlorinated water from the standing bucket. Re-fill the standing bucket for tomorrow.
  5. Jars (Mon/Wed/Fri): level, pH and EC, refill per the rule, log.

Weekly (Monday, ≈ 40 min)

Reservoir change every 2 weeks (23 Nov, 7 Dec, then every second Monday; ≈ 45 min)

  1. Switch the maintenance mode on (all dosing and top-up locked; circulation off).
  2. Siphon the solution into buckets. Use it on school plants, diluted 1:1. Do not pour it into the sink concentrated.
  3. Lift the lid with the plants onto a support (2 bricks/blocks), keeping the roots in a tub of solution.
  4. Wipe the box with 3 % H₂O₂ on a cloth and rinse.
  5. Refill with 25 L dechlorinated water. Add 50 mL A, mix, add 50 mL B, mix 10 min. Measure EC and adjust to 1.2. Adjust pH to 6.0 with diluted pH-down.
  6. Replace the lid, maintenance off, log it.
  7. Clean the probes (see maintenance) and recalibrate.

Harvest

Safety & risks

HARD RULES applied here

Risks and controls

Risk Control
pH-down (phosphoric acid) splash on skin or eyes The teacher dilutes the concentrate. Students use only the diluted 5 % solution, always wearing nitrile gloves and goggles. Keep an eyewash bottle and a sink nearby. Rinse a splash for 15 min. The concentrate is stored locked and labelled, outside the classroom.
Nutrient concentrates (irritant, oxidiser in A) Gloves. A and B are never mixed undiluted. Bottles are labelled with pictograms; store them away from food.
Water + 12 V SELV only. Fused at 3 A. Glands and drip loops. If water reaches the node box, pull the 12 V plug at the shelf (not the strip) and dry the box.
Leak or flood Drip tray under the box and jars; paper-towel leak check; top-up caps (5 L/day); FLOAT high; reservoir change only in maintenance mode.
Overdosing Hard 10 s max-on watchdog, daily caps, lockouts, and a dose log. Small diluted doses. Students test these in fault injection.
Algae Opaque box and jars, every hole covered, panda film, no clear tubing in the light path (use black tubing or tape it).
Mould / root rot (Pythium) on rockwool and roots Keep the plug tops dry. Clay pebble top-dress. Water ≤ 22 °C. Aeration always on. Reservoir change every 2 weeks. Remove any slimy, brown, smelly plant at once.
Rockwool fibres and dust Wet it before handling; gloves; no cutting dry.
Panel heat, eye glare Do not look into the panel. Keep it ≥ 30 cm away. Teacher only for any panel adjustment, with the plug off.
Lettuce bolting / tip-burn Keep air ≤ 24 °C and EC ≤ 1.4. Use loose-leaf varieties.
Weekend / holiday failure Alerts reach the teacher's phone. The 25 L DWC + 20 L top-up gives ≥ 4 days of autonomy. Before the 2-week winter break (from 19 Dec), harvest the jars, cut the DWC plants back, and set the panel to 12 h.

Educational outcomes & assessment

Outcome Evidence Assessment
Formulate a testable hypothesis with variables R1 plan sheet: IV, DV, controls, n, randomisation Rubric 1–4: clear IV/DV, valid control, replication
Measure carefully and estimate uncertainty Pen vs probe log; jar measurements Quantify the disagreement (mean difference, spread); explain one source of error
Analyse data Growth curves, dot plots, effect size (t-test for liceu) Report: claim–evidence–reasoning with figures
Engineering design Requirements table, options matrix, v0 → v3 log Test reports for the 7-day stability test and the fault injection, pass/fail per requirement
Systems thinking Explain why pH drifts up and why EC rises when plants drink more water than nutrients Oral explanation at the December presentation
Safe working Chemical handling, electrical rules Checklist sign-off before access to dosing bottles
Agency Students choose the R2/R3 variable levels and propose the iteration Team decision log; teacher notes

Sub-BOM

Cost-cut 2026-10-20: panel hangs from the shelf above instead of a PVC frame; foil reflectors; hole saw and scale from the shared tools.

Price basis: estimates incl. VAT from Romanian shops (optimusdigital.ro, emag.ro, dedeman.ro). Nutrient price estimated from a UK listing at ≈ £16.50 (≈ 100 RON) for Canna Aqua Vega A+B 1 L; Romanian grow shops typically charge 90–120 RON, so verify before ordering. PHPEN/TDSPEN come from the shared pool and are not counted here.

Item Qty Unit RON Line RON Basis / note
ESP32 1 40 40 optimusdigital.ro
TERMBOARD 1 35 35 optimus / AliExpress
OLED 1 20 20 optimus
SHT31 1 45 45 cased/membrane version
DS18B20 1 15 15 waterproof 1 m
BH1750 1 15 15 on 1.5 m 4-core cable
JSN 1 45 45 JSN-SR04T v3
FLOAT 2 10 20 high (DWC) + low (top-up)
PHKIT 1 120 120 BNC probe + PH-4502C
TDS 1 75 75 Gravity analog TDS
CALSOL 1 60 60 dedicated set for this node (weekly calibrations)
PERI 3 45 135 A, B, pH-down. +1 vs the 2 approved project-wide. Fallback: 2 PERI with a one-part nutrient.
PUMP 2 35 70 circulation + top-up. Option A (float valve) needs only 1.
MOSFET 4 8 32 GPIO16–19
RELAY 2 8 16 PERI B, probe power selector (low-voltage only)
PSU12 1 60 60 12 V 5 A certified
BUCK 1 12 12 12 → 5 V
SMARTPLUG 2 60 120 with power metering (Tasmota, e.g. Nous A1T class), emag
LEDPANEL 1 200 200 45 W full spectrum. Replaces 1 of the approved "grow lights 5–10 W".
AIRPUMP 1 90 90 2-outlet ≈ 3–4 W, with 2 cylinder stones + air tubing
BOX 1 35 35 IP65
GLAND 12 2 24 1 × PG11 + PG7/PG9 mix
BOXPLASTIC 1 70 70 45 L opaque PP, food-safe (DWC box). Counts against the approved "water reservoirs".
RESERVOIR 1 45 45 20 L food-grade canister (top-up)
TUBING 6 5 30 6 mm silicone, top-up + dosing
BIO: net pots 50 mm, pack of 50 1 35 35 emag/AliExpress
BIO: Grodan rockwool plugs 36/40, 1 tray 1 60 60 grow shop
BIO: clay pebbles 10 L 1 55 55 grow shop / garden centre
BIO: Canna Aqua Vega A+B 1 L 1 100 100 see basis
BIO: phosphoric pH-down 250 mL 1 35 35 grow shop
BIO: citric acid 100 g (food grade) 1 5 5 supermarket
BIO: dosing bottles 3 × 500 mL HDPE + drip tray 1 30 30
BIO: seeds (lettuce ×2, basil) + mint plant + basil pot 1 35 35 Agrosel/Florian packets, supermarket
BIO: 2 L glass jars 9 8 72 Dedeman/hypermarket
BIO: black tape + aluminium foil + panda film strip 1 15 15
BIO: 6-way air gang valve, 6 check valves, 4 small stones 1 35 35 pet shop
BIO: pH probe KCl storage solution 250 mL 1 30 30
BIO: 2 ratchet hangers + hooks to hang the panel from the shelf above (no PVC frame) 1 30 30 grow shop / dedeman.ro
BIO: PVC 75 mm × 0.5 m + end cap, 32 mm sleeve, acrylic offcut 1 25 25 stilling tube + probe holder
BIO: aluminium foil reflectors on cardboard 1 10 10
BIO: 100 mL graduated cylinder + measuring jug 1 25 25 syringes from the approved lot
BIO: nitrile gloves box + 2 goggles + eyewash bottle 1 50 50
BIO: 3 % H₂O₂ 1 L 1 15 15 pharmacy
BIO: seedling tray + humidity dome 1 25 25
BIO: 3 A inline fuse holder + fuses 1 15 15
Subtotal 2 131 RON (≈ 418 EUR) hardware 1 429 + consumables/BIO 702

Changes vs the approved list: PERI 3 (approved 2 for the whole project), PUMP 2 of the approved 2 (the lead must reconcile with EcoColumn and Future 2026/2056; option A float valve reduces this to 1), LEDPANEL instead of one small grow light, 2 SMARTPLUG and 1 AIRPUMP (new lines, covered by "aeration" in the items to discuss). Optional spring additions: 2nd LEDPANEL + SMARTPLUG for the photoperiod round (≈ 260 RON); DFR0504 isolator (≈ 100 RON); NFT channel 1 m + end caps (≈ 80 RON); spare pH probe (≈ 60 RON).

8-week timeline

gantt
    title mc-07-hydro 26 Oct to 18 Dec 2026
    dateFormat YYYY-MM-DD
    axisFormat %d %b
    section Plants
    Order parts, baseline tap water         :a1, 2026-10-26, 4d
    Sow lettuce and basil in rockwool       :a2, 2026-10-27, 13d
    Mint cuttings rooting                   :a3, 2026-11-02, 9d
    Transplant to DWC and jars              :milestone, a4, 2026-11-09, 0d
    R1 aeration experiment                  :a5, 2026-11-09, 35d
    Reservoir change 1                      :milestone, 2026-11-23, 0d
    Reservoir change 2                      :milestone, 2026-12-07, 0d
    Harvest R1 jars, weigh, dry roots       :a6, 2026-12-14, 3d
    section Build and control
    Lid, light-proofing, frame, shelf       :b1, 2026-11-02, 5d
    Node wiring, ESPHome, leak test         :b2, 2026-11-04, 5d
    v0 manual controller, titration         :b3, 2026-11-09, 5d
    Calibration and ground-loop test        :b4, 2026-11-16, 3d
    v1 auto pH, hard limits                 :b5, 2026-11-18, 5d
    v2 auto EC and top-up                   :b6, 2026-11-23, 7d
    7-day stability test                    :b7, 2026-11-30, 7d
    v3 iterate, float valve vs pump         :b8, 2026-12-07, 5d
    Fault injection, commissioning          :milestone, b9, 2026-12-11, 0d
    section Reporting
    Analysis and presentation               :c1, 2026-12-14, 4d
    Winter-break setup, 12 h light          :c2, 2026-12-18, 1d

8. The Living Earth

Node: mc-08-soil · Enclosure: TANK63 split rhizotron · Team: 3–4 students · Alternative: 8b (mc-08b-bog)

Concept (refined)

One 60×30×35 cm glass tank is divided by a sealed acrylic wall into two 29×29 cm soil columns, both filled from the same batch of base soil:

The front glass is a root window (rhizotron) under a removable black panel. Each half has one perforated clear observation tube (mini-rhizotron) at 45°, read with a USB/phone endoscope. A removable acrylic respiration lid with a gasket covers one half at a time. The lid carries the SCD41 and a small mixing fan, so students measure soil CO2 efflux directly (mg CO2 kg⁻¹ h⁻¹ and mg CO2 m⁻² h⁻¹). In January the team applies its best restoration recipe (from the engineering track) to Half D. It then becomes a before/after restoration experiment, with Half R as the reference, running until June 2027.

Science track

Driving question: How does degradation (compaction + organic-matter loss + bare surface) change how alive a soil is, and how fast can restoration bring that life back?

Hypotheses (directional, measurable):

# Hypothesis Metric Expected direction (R vs D)
H1 Restored soil respires more CO2 efflux, chamber test, dark R ≥ 2× D
H2 Restored soil takes in water faster and holds more infiltration time (s); VWC after 48 h; drying-curve half-life R faster infiltration, higher VWC at 48 h, slower drying
H3 Restored soil has more invertebrates Berlese counts per 100 cm³ (springtails, mites, other) R > D by ≥ 3×
H4 Roots grow deeper and longer in restored soil root length on window grid (Tennant) and tube depth reached R deeper/longer
H5 Decomposition is faster in restored soil Tea Bag Index k (higher) and S (lower); mass loss at 35 d R k > D k
H6 Aggregates in restored soil are more stable slake-test class 1–6 R ≥ D + 2 classes by spring

Variables:

Design and replication (honest about limits):

Sampling schedule (2026; continues monthly to June 2027):

Measure Frequency Dates (2026)
Sensors (VWC, T, RH, lux, CO2 ambient) every 60 s, automatic from Nov 9
Respiration test D and R 2× per week (Tue + Thu) from Nov 17
Root window photo + grid count weekly (Mon) Nov 16, 23, 30; Dec 7, 14
Tube endoscope photos weekly (Mon) same as above
Infiltration every 2 weeks Nov 12 (baseline), Nov 26, Dec 10
Slake test monthly Nov 6 (base soil, before split), Dec 10
Berlese extraction baseline + monthly Nov 9 (base soil), Dec 7–10, then Jan 11, Feb 8…
Tea bags bury Nov 10 35-day set retrieved Dec 15; 90-day set Feb 8, 2027
Cover crop height/biomass weekly height; clipped biomass monthly from Nov 23
pH / EC (handheld PHPEN/TDSPEN, 1:5 soil:water extract) monthly Nov 6, Dec 10

Analysis:

What shows by mid-December vs spring:

By Dec 15, 2026 By spring (Mar–Jun 2027)
Respiration R ≫ D (compost effect is immediate) Whether the R/D ratio persists after compost carbon is spent
Infiltration and drying-curve differences (compaction effect is immediate) Slake-class change: real aggregate building by roots, fungi, worms
First roots on window/tubes; depth reached in 4–5 weeks Full root architecture; worm burrows on the window
Berlese counts #2 (introduced springtails established in R?) Colonisation of D after its restoration in January
35-day tea mass loss (green tea already differs) Full TBI k and S (Feb 8) plus a second TBI round in D after restoration (Feb → May)

Engineering track

Problem statement: A compacted, organic-poor, bare urban soil (Half D) barely respires, sheds water and has few animals. Design a restoration method that a school or city could apply. It must be cheap, scalable, use local materials, and work within one season.

Requirements (measurable):

ID Requirement Target
R1 Infiltration 200 mL disappears in < 60 s (D baseline expected > 5 min)
R2 Water held 48 h after watering VWC ≥ 1.3× untreated control
R3 Biological activity CO2 efflux ≥ 2× control at the same soil T, 4 weeks after treatment
R4 Structure slake class ≥ 4 by 8 weeks
R5 Plant establishment cress germination ≥ 80 % and shoot dry mass ≥ 1.5× control at 14 d
R6 Cost and sourcing ≤ 5 RON per 10 L of treated soil, materials available in Bucharest
R7 No harm no added synthetic fertiliser; only organic/mineral inputs listed in Biology

Candidate solutions (screened first in pots, then the winner goes into Half D):

Code Treatment (per 0.5 L cup of degraded soil) Mechanism tested
C0 Control: degraded soil only —
A1 Compost 20 % v/v mixed into top 5 cm food for microbes, porosity
A2 Biochar 5 % v/v (pre-soaked 48 h in compost tea) + compost 10 % stable carbon, water holding
M1 1 cm chopped-leaf mulch on surface evaporation, food for surface fauna
P1 Cover crop: 10 Secale + pinch Trifolium sown living roots, root exudates
X1 Aeration: 6 holes Ø 5 mm × 5 cm with a skewer, refilled with compost breaking compaction

Test criteria:

Iteration plan:

  1. v1 (Nov 16 – Dec 18): screen 6 single treatments in cups; pick the top 2.
  2. v2 (Jan 11 – Feb 7): combine the top 2 (e.g. A2 + P1) and test 3 doses in cups (n = 3).
  3. v3 (Feb 8): apply the best v2 recipe to Half D after retrieving its 90-day tea bags. Bury a new TBI set in both halves. Track D's recovery against R until June.
  4. Document every iteration on a one-page "design card": change, reason, result, next step.
  5. Optional phase 2 automation: a servo-closed respiration port, so tests run unattended overnight.

Enclosure & build

Tank: TANK63 (60×30×35 cm, ≈ 63 L, rimless glass, ≈ 14 kg empty).

Layers, bottom to top (each half):

  1. 3 cm LECA (expanded clay) drainage.
  2. Geotextile fleece.
  3. 20 cm soil, filled in 4 lifts of 5 cm:
    • D lifts tamped with a 2 kg rammer (brick in a bag, 10 drops per lift, target dry bulk density 1.4 kg/L).
    • R lifts lightly firmed by hand (≈ 1.0 kg/L).
  4. R only: 1 cm leaf mulch.
  5. Headspace ≈ 12 cm to the rim.

Fittings:

flowchart TD
    PSU["PSU12 brick on shelf (RCD strip)"] --> BOX["Node box mc-08-soil (ESP32 + TERMBOARD + BUCK + 2 MOSFET + OLED)"]
    BOX -->|"PWM1 GPIO16"| LED["LED bridge 1.1 m strip (12 V)"]
    BOX -->|"I2C + PWM2 GPIO17 + GPIO13"| LID["Respiration lid (SCD41 + FAN + reed magnet)"]
    BOX -->|"I2C"| SHT["SHT31 on light bridge"]
    BOX -->|"I2C"| LUX["BH1750 on divider top, back"]
    BOX -->|"1-Wire GPIO4"| T["DS18B20 x2 at 10 cm (D and R)"]
    BOX -->|"ADC 32/33/34"| SM["SOIL A (D 5 cm), B (R 5 cm), C (D 15 cm)"]
    subgraph TANK["TANK63 split rhizotron"]
        D["Half D degraded (compacted, bare)"]
        R["Half R restored (compost, biochar, cover crop, worms)"]
        W["Front root window (black panel, 2 cm grid)"]
        TU["Observation tubes 45 deg, one per half"]
    end
    LID -.->|"placed on D or R"| TANK
    LED --> TANK

Build steps (student hours, team of 3–4):

# Step Time
1 Check tank for leaks (fill 5 cm water, 24 h, empty, dry) 0.5 h + 24 h wait
2 Cut acrylic: divider 29×35, lid 32×32, mesh-cover frame 32×32 (score-and-snap or teacher with jigsaw; deburr) 2 h
3 Silicone divider in place; cure 24 h 1 h + 24 h
4 Black panels for back/sides (fixed, double-sided tape) and front (velcro); draw 2 cm grid on front glass 1.5 h
5 Prepare tubes: cap bottoms with mesh, black tape on exposed part, depth marks; drainage wells 1 h
6 Collect and sieve soil (5 mm), mix the batch, take baseline samples (moisture, pH/EC, slake, Berlese) 3 h
7 Fill D: LECA, fleece, 4 compacted lifts, set tube at 45° and SOIL/DS18B20 probes during filling; weigh all soil added 2 h
8 Fill R: mix compost + biochar into the soil, 4 loose lifts, tube and probes, weigh all soil 2 h
9 Lid: gasket, SCD41 holder, fan spacers, magnet, cable + JST; reed switch on rim 2.5 h
10 Light bridge and LED strip (solder pads with pre-tinned wires by teacher, or use clip connectors) 2 h
11 Node box: TERMBOARD, BUCK set to 5.0 V (measure before connecting ESP32), MOSFETs, glands, labels 3 h
12 Flash ESPHome, adopt in Home Assistant, calibrate sensors 3 h
13 Leak test of lid (see Instrumentation) 1 h
14 Biology: sow cover crop, add worms/springtails/isopods, mulch, bury tea bags 1.5 h
Total ≈ 27 h + cure/wait times

Biology

Soil source:

Amendments (Half R and cups):

Fauna (Half R only at start):

Organism Role Qty in R Source (Romania)
Aporrectodea caliginosa / Allolobophora chlorotica (endogeic garden worms) burrow in mineral soil, mix 6 dig from school garden when collecting soil (free)
Lumbricus terrestris (anecic nightcrawler) vertical burrows, pull litter down; visible on window 2 fishing shops sell them as "râme canadiene" (≈ 25–35 RON per box of 20–25); keep the rest in a cool box of damp soil and release in the garden
Eisenia fetida (epigeic red worm, "râmă californiană / roșie") lives in mulch/compost layer only, not deep mineral soil 5 vermicompost farms via OLX/eMAG ("râme californiene"), or fishing shops; ≈ 30–40 RON per small culture
Folsomia candida (springtails, "colembole") fungal grazers, Berlese indicator ½ culture (≈ 100+) terrarium/exotic pet shops and OLX ("colembole cultură"); ≈ 25–40 RON
Porcellio scaber / Armadillidium vulgare (isopods) shred litter on surface 6 collect under stones/wood in the school yard (native, free)

Cover crop (Half R):

Establishment:

  1. Fill both halves and water each to ≈ 60 % of the field capacity measured on base-soil cups.
  2. Wait 3 days.
  3. Add fauna in the evening with the LED off. Worms are placed on the surface and must burrow within 30 min; remove and replace any that do not.
  4. Apply mulch, sow, and bury the tea bags (Nov 10).

Invertebrate welfare:

Instrumentation

Catalog ID Qty Placement Interval Purpose
SOIL 3 A: Half D at 5 cm; B: Half R at 5 cm; C: Half D at 15 cm (deep/compacted layer, shows perched water) 60 s (mean of 10 samples) VWC, drying curves, watering trigger
DS18B20 2 10 cm depth, centre of D and centre of R 60 s soil T for respiration normalisation, welfare
SCD41 1 under the respiration lid (3 cm below plate); when the lid is parked on its shelf hook beside the tank: ambient room CO2 60 s (normal), 60 s during tests (25–55 points per test) chamber CO2 slope, plus T/RH inside chamber
SHT31 1 on the light bridge, 15 cm above the rim, shielded from the strip by the profile 60 s room air T/RH beside the tank
BH1750 1 top of divider at the back, facing up, at the rim level 60 s LED on/off verification, light dose (lux; not PAR, relative only)
FAN 1 under the respiration lid on only during tests, 30 % PWM mix headspace
Reed switch (free-text) 1 rim of tank; magnet on lid event lid-on detection
OLED 1 node box window 2 s page cycle live values, test countdown
SERVO 1 (phase 2) respiration-port flap event unattended tests later

Pin assignment (standard pin map only):

Function GPIO Device
I2C SDA / SCL 21 / 22 SCD41 0x62, SHT31 0x44, BH1750 0x23, OLED 0x3C (bus at 50 kHz because of the 1.5 m lid cable)
1-Wire 4 DS18B20 D and R (4.7 kΩ to 3.3 V)
Analog A / B / C 32 / 33 / 34 SOIL A (D 5 cm), B (R 5 cm), C (D 15 cm)
PWM out 1 16 MOSFET to LED strip
PWM out 2 17 MOSFET to lid FAN
Digital in 1 13 lid reed switch (pull-up, closed to GND = lid on)
Servo 1 26 phase 2 port flap
Free 35, 36, 39, 18, 19, 23, 25, 27, 14, 5, 15, 12 spare (e.g. SOIL D for R 15 cm if a 4th probe is added)

Calibration:

Respiration test protocol (one half, ≈ 45 min):

  1. Check the last watering was ≥ 24 h ago. Watering pulses CO2 out of the pores; log hours since watering.
  2. On the HA dashboard: select chamber position D or R, check that the V and m numbers are current, and press Start respiration test.
  3. Place the lid on that half within 2 min: gasket on rim and divider, 2 clamps or bottles on top. The reed switch must show "lid on", or the test will not start measuring.
  4. Firmware automatically:
    • switches the LED off (dark test, to exclude photosynthesis);
    • runs the fan at 30 %;
    • discards 5 min (mixing/equilibration);
    • collects 30 min of CO2 readings, extended to 60 min for Half D if the rise is < 150 ppm after 30 min;
    • fits a linear regression;
    • publishes slope (ppm/h), R², R_kg and F;
    • restores the LED according to the schedule;
    • sends a "done" notification.
  5. Remove the lid, ventilate 5 min (or wait until ambient CO2 is back to within 50 ppm of the pre-test value), then test the other half.
  6. Alternate which half goes first on each test day.

Formula:

ρCO2 (mg/L) = P × M / (R × T) = 101325 × 44.01 / (8.314 × TK) (≈ 1830 mg/L at 20 °C; use the chamber T from SCD41)

Mass rate (mg CO2/h) = slopeppm/h × 10⁻⁶ × VL × ρCO2

Sample calculation (Half R):

Automation

ESPHome core (excerpt; full file mc-08-soil.yaml):

esphome: { name: mc-08-soil }
i2c: { sda: 21, scl: 22, frequency: 50kHz }
one_wire: [{ platform: gpio, pin: 4 }]
globals:
  - { id: resp_state, type: int, initial_value: '0' }   # 0 idle, 1 mixing, 2 measuring
  - { id: t0, type: uint32_t, initial_value: '0' }
  - { id: sn, type: double, initial_value: '0' }
  - { id: st, type: double, initial_value: '0' }
  - { id: sc, type: double, initial_value: '0' }
  - { id: stt, type: double, initial_value: '0' }
  - { id: stc, type: double, initial_value: '0' }
  - { id: scc, type: double, initial_value: '0' }
sensor:
  - platform: scd4x
    automatic_self_calibration: false
    update_interval: 60s
    co2:
      id: co2
      name: "mc_08_co2_chamber"
      on_value:
        then:
          - lambda: |-
              if (id(resp_state) == 2) {
                double t = (millis() - id(t0)) / 3600000.0;  // hours
                id(sn) += 1; id(st) += t; id(sc) += x;
                id(stt) += t*t; id(stc) += t*x; id(scc) += x*x;
              }
              if (id(resp_state) == 2 && x > 5000) id(resp_finish).execute();
    temperature: { id: ch_t, name: "mc_08_air_temp_chamber" }
    humidity: { name: "mc_08_air_humidity_chamber" }
  - { platform: template, id: slope, name: "mc_08_resp_slope", unit_of_measurement: "ppm/h" }
  - { platform: template, id: r2, name: "mc_08_resp_r2" }
  - { platform: template, id: rkg, name: "mc_08_resp_rate_kg", unit_of_measurement: "mg/kg/h" }
  - { platform: template, id: fm2, name: "mc_08_resp_flux_m2", unit_of_measurement: "mg/m2/h" }
number:
  - { platform: template, id: vol_l, name: "mc_08_headspace_l", min_value: 2, max_value: 20, step: 0.1, optimistic: true, restore_value: true, initial_value: 10 }
  - { platform: template, id: m_kg, name: "mc_08_dry_soil_kg", min_value: 1, max_value: 40, step: 0.1, optimistic: true, restore_value: true, initial_value: 16 }
binary_sensor:
  - platform: gpio
    id: lid_on
    name: "mc_08_lid_on"
    pin: { number: 13, mode: INPUT_PULLUP, inverted: true }
    on_release:   # lid lifted
      - if:
          condition: { lambda: 'return id(resp_state) > 0;' }
          then: [ script.stop: resp_test, lambda: 'id(resp_state) = 0;', text_sensor.template.publish: { id: status, state: "ABORTED lid open" } ]
button:
  - { platform: template, name: "mc_08_resp_start", on_press: [ script.execute: resp_test ] }
script:
  - id: resp_test
    mode: single
    then:
      - wait_until: { condition: { binary_sensor.is_on: lid_on }, timeout: 120s }
      - if: { condition: { binary_sensor.is_off: lid_on }, then: [ text_sensor.template.publish: { id: status, state: "ABORTED no lid" }, script.stop: resp_test ] }
      - light.turn_off: grow
      - output.set_level: { id: fan_out, level: 30% }
      - lambda: 'id(resp_state) = 1; id(sn)=id(st)=id(sc)=id(stt)=id(stc)=id(scc)=0;'
      - text_sensor.template.publish: { id: status, state: "MIXING" }
      - delay: 5min
      - lambda: 'id(t0) = millis(); id(resp_state) = 2;'
      - text_sensor.template.publish: { id: status, state: "MEASURING" }
      - delay: 30min
      - script.execute: resp_finish
  - id: resp_finish
    then:
      - lambda: |-
          id(resp_state) = 0;
          double n=id(sn), d = n*id(stt) - id(st)*id(st);
          if (n < 10 || d <= 0) { id(status).publish_state("FAILED too few points"); return; }
          double b = (n*id(stc) - id(st)*id(sc)) / d;
          double rnum = n*id(stc) - id(st)*id(sc);
          double rden = sqrt(d * (n*id(scc) - id(sc)*id(sc)));
          double rho = 101325.0*44.01/(8.314*(id(ch_t).state + 273.15));   // mg/L
          double mg_h = b * 1e-6 * id(vol_l).state * rho;
          id(slope).publish_state(b); id(r2).publish_state(rden > 0 ? (rnum/rden)*(rnum/rden) : 0);
          id(rkg).publish_state(mg_h / id(m_kg).state); id(fm2).publish_state(mg_h / 0.0841);
          id(status).publish_state("DONE");
      - output.set_level: { id: fan_out, level: 0% }
      - script.execute: led_restore   # turns grow light on if inside 0600-2000 window
stateDiagram-v2
    [*] --> Night
    Night --> Day : 0600 schedule
    Day --> Night : 2000 schedule
    Day --> TestArmed : start button pressed
    Night --> TestArmed : start button pressed
    TestArmed --> Mixing : lid switch closed within 2 min
    TestArmed --> Aborted : no lid after 2 min
    Mixing --> Measuring : 5 min elapsed, LED off, fan 30 pct
    Measuring --> Computing : 30 or 60 min elapsed
    Measuring --> Computing : CO2 above 5000 ppm
    Mixing --> Aborted : lid opened
    Measuring --> Aborted : lid opened
    Computing --> Done : slope, R2, rates published
    Done --> Day : LED restore inside photoperiod
    Done --> Night : LED restore outside photoperiod
    Aborted --> Night : notify and restore

Operations

Daily (2 min, any team member):

Twice weekly (Tue/Thu, 25 min):

Weekly (Mon, 30 min):

Tea bags:

Event Date Bags
Weigh, number, bury at 8 cm Tue Nov 10, 2026 per half: 2 green + 2 rooibos (35-day set), 2 green + 2 rooibos (90-day set) = 16 bags total
Retrieve 35-day set Tue Dec 15, 2026 8 bags
Retrieve 90-day set Mon Feb 8, 2027 8 bags
New 90-day set after restoring D Feb 9 → May 10, 2027 8 bags

Berlese extraction:

Round Collect cores Lamp on 72 h Count and return
Baseline (base soil, 2 cores) Mon Nov 9 Nov 9–12 Nov 12
Round 2 (2 cores per half) Mon Dec 7 Dec 7–10 Dec 10
Then monthly 2nd Monday +72 h Thursday

Holidays (Dec 19 – Jan 10):

Safety & risks

Educational outcomes & assessment

Outcome Evidence Assessment
Formulate testable hypotheses with variables and controls hypothesis table (H1–H6) in the team notebook rubric 0–3: testable, directional, metric named, control named
Understand replication and pseudo-replication written paragraph: why n = 1 tank ≠ proof; how cups give true replicates teacher check
Measure and compute a physical rate 2 hand-calculated respiration rates matching firmware within 5 % correct units and formula
Use a standard scientific protocol TBI data sheet submitted to teatime4science.org (optional) complete data sheet
Quantitative image analysis weekly root-length series (Tennant) and depth-vs-time graph consistency between 2 students counting the same photo (≤ 15 % difference)
Engineering design cycle decision matrix, 3 design cards (v1–v3), final restoration recipe rubric: requirements met, evidence-based choice, iteration documented
Systems/IoT literacy explain the state diagram; modify one YAML parameter (e.g. mixing time) and test working change on a spare board
Communication Dec 17 poster/3-min pitch; June final report peer + teacher rubric
Ethics and welfare welfare checklist kept; release plan executed checklist completion

Sub-BOM

Cost-cut 2026-10-20: Berlese funnel uses a school desk lamp.

Prices are estimates incl. VAT. Basis: optimusdigital.ro / robofun.ro / sigmanortec.ro for electronics, emag.ro for the endoscope/scale, dedeman.ro / hornbach.ro for materials, fishing/pet shops and OLX for animals, Amazon.de where noted. 1 EUR ≈ 5.1 RON.

ID / item Qty Unit RON Line RON Basis / note
ESP32 1 35 35 optimusdigital/sigmanortec
TERMBOARD 1 30 30 sigmanortec/AliExpress
OLED 1 20 20 optimusdigital
SHT31 1 45 45 cased/membrane breakout
SCD41 1 230 230 robofun/Adafruit-class breakout
DS18B20 2 15 30 waterproof 1 m
SOIL 3 12 36 v2.0, TL555 version
BH1750 1 15 15 GY-302
FAN 1 25 25 80 mm 12 V, lid mixing (one from the approved 4)
LEDSTRIP 0.25 reel 150 38 1.1 m used from a pooled 5 m reel
LEDPROFILE 2 30 60 2 × 55 cm cut from 1 m profiles
MOSFET 2 10 20 LED, fan
SERVO 1 15 15 phase 2 (optional)
PSU12 1 60 60 certified 12 V 5 A brick
BUCK 1 12 12 LM2596
BOX 1 35 35 IP65 150×110×70
GLAND 6 3 18 PG7/PG9
TANK63 1 320 320 60×30×35 rimless glass, local aquarium shop/eMAG
ACRYLIC 1 120 120 divider, lid, mesh-cover frame
MESH 0.25 m² 40 10 cover + tube bottoms
SILICONE 1 30 30 aquarium-safe
Catalog subtotal 1 204
APPROVED: transparent perforated observation tube 2 35 70 approved line item; Ø ≈ 40–50 mm × 40 cm
Black corrugated PP panels A2 ×2 + velcro 1 set 45 45 dedeman/office supplies
EPDM self-adhesive foam gasket 9×4 mm, 5 m 1 20 20 dedeman (window seal)
Spring clamps (small) 4 5 20 dedeman
Wired reed switch + magnet (MC-38) 1 12 12 optimusdigital/AliExpress
USB-C/Android endoscope, 5.5 mm, LED, 2 m semi-rigid 1 70 70 emag.ro
BIO: Lipton green tea (EAN 8722700055525) + Lipton rooibos (EAN 8722700188438), 20 bags each 2 boxes 25 50 supermarket / Amazon.de for rooibos
Precision scale 0.01 g / 200 g 1 45 45 emag.ro
Berlese: school desk lamp + 28 W eco-halogen bulb 1 10 10 bulb only
Berlese: 2 mm hardware mesh 0.25 m², plaster of Paris 1 kg, 4 jars, 4 PET 2 L bottles (reused) 1 set 50 50 dedeman
10× loupes ×2, white trays ×2, soft brush, DIY aspirator 1 set 40 40 emag
Infiltration ring (PVC Ø 110 offcut) + 500 mL measuring jug 1 25 25 dedeman
Slake: tea strainers ×2 + clear jars ×2 1 set 20 20 household shop
Soil corer PVC Ø 50 mm, drainage wells PVC Ø 20 mm — 0 0 from approved "rigid tubes and fittings" lot
BIO: compost/biohumus 20 L 1 35 35 dedeman/hornbach
BIO: biochar 5 L (or untreated lump charcoal 3 kg) 1 50 50 eMAG/garden shops
LECA expanded clay 10 L 1 25 25 dedeman
Geotextile fleece 1 m² 1 10 10 dedeman
BIO: topsoil 60 L — 0 0 collected with permission
BIO: backup garden soil 50 L 1 30 30 dedeman ("pământ de grădină"), also for cups
BIO: seeds Secale cereale 1 kg, Trifolium repens 100 g, Lolium perenne 500 g, Lepidium sativum (cress) 1 set 55 55 agri/garden shops, eMAG
BIO: Lumbricus terrestris ("râme canadiene") box of ~25 1 30 30 fishing shop
BIO: Eisenia fetida starter culture 1 35 35 vermicompost farm (OLX/eMAG)
BIO: Folsomia candida springtail culture 1 35 35 terrarium shop/OLX
BIO: endogeic worms, isopods — 0 0 collected in school garden
Screening cups 0.5 L clear ×18 + 2 trays 1 set 30 30 household/eMAG
Nitrile gloves box of 100 1 35 35 pharmacy/dedeman
Yellow sticky traps ×10 1 15 15 garden shop
Free-text subtotal 862
Ecosystem 8 total 2 066 RON (≈ 405 EUR)

Delta vs the approved list:

8-week timeline

gantt
    title Living Earth build and first experiments (2026)
    dateFormat YYYY-MM-DD
    axisFormat %d %b
    section Plan and source
    Questions, hypotheses, order parts         :a1, 2026-10-26, 7d
    Collect soil, worms, seeds                  :a2, 2026-10-30, 7d
    section Build
    Tank leak test, divider, panels             :b1, 2026-11-02, 4d
    Node box, flash ESPHome, LED bridge         :b2, 2026-11-02, 7d
    Baseline soil tests and fill both halves    :b3, 2026-11-06, 3d
    Fauna, sowing, tea bags buried              :milestone, b4, 2026-11-10, 0d
    Sensor calibration and SCD41 FRC            :b5, 2026-11-11, 3d
    Lid gasket and leak test                    :b6, 2026-11-16, 4d
    section Science
    Respiration tests twice weekly              :c1, 2026-11-17, 30d
    Weekly rhizotron and tube photos            :c2, 2026-11-16, 30d
    Infiltration rounds                         :c3, 2026-11-12, 29d
    Berlese round 2                             :c4, 2026-12-07, 4d
    Retrieve 35 day tea bags                    :milestone, c5, 2026-12-15, 0d
    section Engineering
    Screening cups v1 set up and run            :d1, 2026-11-16, 30d
    Decision matrix and design card v1          :d2, 2026-12-14, 4d
    section Wrap up
    Commissioning sign-off                      :milestone, e1, 2026-12-15, 0d
    Poster and pitch, holiday autopilot         :e2, 2026-12-15, 4d
Week Dates Deliverable
1 Oct 26 – Nov 1 hypothesis table, BOM ordered, soil site permission (check autumn-break dates)
2 Nov 2 – 8 tank divided and paneled, node box built, base-soil baseline (pH/EC, slake, moisture), halves filled
3 Nov 9 – 15 Berlese baseline, fauna added, cover crop sown, tea bags in (Nov 10), sensors live and calibrated, SCD41 FRC
4 Nov 16 – 22 lid finished and leak-tested, first respiration tests, screening cups started, first root photos
5 Nov 23 – 29 routine tests; infiltration round 2; cress sown in cups (day 21 ≈ Dec 7 if cups set Nov 16)
6 Nov 30 – Dec 6 mid-point data review; firmware result check (hand calc vs firmware)
7 Dec 7 – 13 Berlese round 2, infiltration round 3, slake + pH/EC round 2, cup measurements
8 Dec 14 – 18 35-day tea bags out (Dec 15), commissioning sign-off (Dec 15), decision matrix, poster/pitch (Dec 17), holiday setup (Dec 18)

8b. Alternative: The Carnivorous Bog

Node: mc-08b-bog · Enclosure: TANK25 · Use instead of #8 if the team prefers.

Concept: A nutrient-poor acid bog where sundews get nitrogen from insects instead of soil. Students test how carnivorous plants detect and respond to prey, and engineer a stable constant-water-level, high-humidity habitat that uses only mineral-free water.

Science:

Engineering: Design a self-watering tray that holds a constant water level (±5 mm) using only distilled or RO water (TDS < 50 ppm, checked with TDSPEN), and keeps humidity at 60–80 % without mould. Requirements:

Iterate on float positions, pulse length, mister duty and vent gap.

Enclosure: TANK25 (40×25×25 cm).

Biology:

Species Qty Notes Source (Romania)
Drosera capensis (Cape sundew, "roua cerului") 9 no winter dormancy, fast, forgiving, flowers indoors Hornbach (FloraSelf, 9 cm pot ≈ 30 RON), secretgarden.ro (≈ 29–49 RON)
Drosera aliciae (Alice sundew) 2 rosette, no dormancy, good comparison species secretgarden.ro / Romanian carnivorous-plant sellers on OLX
Pinguicula (Mexican hybrid, e.g. 'Tina' or P. moranensis) 2 butterwort, sticky leaves; has a dry "succulent" winter phase: keep on the 3 cm spacer and drier Dec–Feb same sellers
D. capensis seed 1 packet sow on peat in Week 2 for a seedling series same sellers / plants' own seed
Flightless Drosophila culture 1 prey terrarium shops

Instrumentation and pins (standard map):

Catalog ID Qty Placement Interval Purpose GPIO
SHT31 1 back wall, 10 cm above pots 60 s RH/T control I2C 21/22 (0x44)
BH1750 1 at rosette height, centre (moved to ends on calibration day) 60 s light dose I2C 21/22 (0x23)
OLED 1 node box — live values I2C 21/22 (0x3C)
DS18B20 1 in the water tray 60 s water/root-zone T 1-Wire 4
SOIL 1 in one "medium" pot, calibrated in peat:perlite 60 s substrate moisture vs level ADC 32
FLOAT 2 low 1.5 cm, high 2.5 cm event level control DI 13 (low), DI 14 (high)
LEDSTRIP + MOSFET 1 lid schedule light PWM1 16
PUMP + MOSFET 1 in external reservoir event top-up PWM3 18
MIST 1 outside container, ducted RH loop humidity Relay 1 23 (switches 24 V DC)

Automation:

Safety: 12 V/24 V DC only at the tank (HARD RULES 1–4), adapters on the RCD strip on the shelf, drip loops. The mister and its electronics are outside the tank, and the reservoir sits below the node box. Peat dust: moisten before handling, gloves, wash hands. Plants are non-toxic. Fruit flies are kept in a closed culture, and the tank lid has a mesh vent.

Sub-BOM 8b:

ID / item Qty Unit RON Line RON Basis
ESP32 1 35 35 optimusdigital
TERMBOARD 1 30 30 sigmanortec
OLED 1 20 20 optimusdigital
SHT31 1 45 45 cased
DS18B20 1 15 15 waterproof
SOIL 1 12 12 v2.0
BH1750 1 15 15 GY-302
FLOAT 2 10 20 vertical plastic
PUMP 1 35 35 12 V 3 W
TUBING 2 m 4 8 6 mm ID
RESERVOIR 1 35 35 10 L food-grade
MIST 1 60 60 incl. 24 V adapter
RELAY 1 8 8 24 V mister line
LEDSTRIP 0.25 reel 150 38 0.8 m used, pooled reel
LEDPROFILE 1 30 30 cut 2 × 40 cm
MOSFET 2 10 20 LED, pump
PSU12 1 60 60 certified
BUCK 1 12 12 LM2596
BOX 1 35 35 IP65
GLAND 5 3 15 PG7/PG9
TANK25 1 150 150 40×25×25 glass
ACRYLIC 0.5 sheet 120 60 lid with vent slot
SILICONE 1 30 30 aquarium-safe
Catalog subtotal 788
BIO: Drosera capensis 9 30 270 Hornbach FloraSelf / secretgarden.ro
BIO: Drosera aliciae 2 35 70 secretgarden.ro / OLX sellers
BIO: Pinguicula Mexican hybrid 2 35 70 same
BIO: D. capensis seed 1 20 20 same
Unfertilised sphagnum peat 20 L 1 35 35 dedeman/hornbach ("turbă" pH 3.5–4.5, no NPK)
Perlite 5 L 1 20 20 dedeman
Distilled water 5 L 4 5 20 dedeman/auto shops
9 cm pots ×12 + spacers 1 set 20 20 garden shop
BIO: flightless Drosophila culture 1 30 30 terrarium shop
Fish flakes 1 15 15 pet shop
Free-text subtotal 570
Ecosystem 8b total 1358 RON (≈ 266 EUR)

9. The Time Capsule

Node: mc-09-capsule · Team: all teams (core build team of 4 + one delegate from each of teams 1–8) · Built 1–12 Dec 2026 · Sealed mid-January 2027 · Capsule box opened in December 2036.

Concept (refined)

A closed bioactive terrarium in a 63 L glass tank. It is designed to run for 10+ years with almost no intervention, like David Latimer's bottle garden (sealed 1972, watered once in 1972). Plants recycle water through transpiration and condensation. Springtails, isopods, fungi and bacteria recycle dead matter into nutrients. The only external input is light.

Three rules shape the whole design:

  1. The living system never depends on the electronics. All sensors sit in one removable sensor pod that plugs into the lid. The light runs on a COTS timer plug with a hardware fail-safe, so it keeps working even if the ESP32, the Wi-Fi or Home Assistant are dead.
  2. Every intervention is possible without opening the lid. Water goes in and out through an external fill/drain standpipe. Air exchange goes through a screw-capped 20 mm vent port. Sensors are swapped through a 50 mm pod port.
  3. Everything is documented for strangers. The 2033 Keeper never met the 2026 builders. The manual, the labels and the data archive have to work without anyone remembering how things were done.

The capsule ritual. A lockable steel A4 document box is bolted inside the stand cabinet. It has two compartments:

Compartment Contents Opened
A — Founding capsule (sealed with a numbered tamper seal on Sealing Day, Jan 2027) One letter from each founding student "to the Keeper of 2036". A printed founding photo set (Day 0, Day 28, Sealing Day). The design document v1.0 on paper. The founding species list. Predictions for 2036, written down and signed (moss cover %, surviving species, CO2 amplitude). 2× USB 32 GB of different brands, holding identical founding data (CSV, JPG, PDF/A). December 2036, at a school event. Predictions are compared with reality.
B — Annual archive pocket (deposit slot cut in an inner folder, never sealed) Each June: one printed A4 "Year in the Capsule" summary page, and from 2028 the retired SD card (every 3 years) or a USB stick holding that year's ZIP. December 2036, together with A.

Science track

Driving question: Does a closed ecosystem reach a stable state, and how do its CO2, humidity and temperature cycles evolve over years?

Sub-questions for cohorts:

Hypotheses (each cohort may add its own; all are recorded in the manual):

ID Hypothesis Testable by
H1 Night-time CO2 is high in the first 3–6 months: fresh coir and bark decompose and soil respiration exceeds photosynthesis. The daily CO2 amplitude (night max − day min) then falls and stabilises within ±20 % month-to-month by the end of 2027. SCD41 daily summaries
H2 Night CO2 rise rate follows substrate temperature: roughly ×2 per +10 °C (Q10 ≈ 2). It is therefore higher in summer and in the heating season. SCD41 + DS18B20 regression
H3 Air RH stays ≥ 90 % while sealed. A sustained drop below 75 % means a seal leak, not a biological change. SHT31
H4 Vascular species richness falls from 8 to 3–5 by 2031 (competitive exclusion). Ficus pumila and Selaginella spread most. Yearly inventory
H5 Moss cover (% of substrate area seen from the front and top) increases for 2–3 years, then plateaus. Yearly fixed-jig photos
H6 Water is conserved. Sump level changes by < 5 mm per year when the lid is sealed and nobody adds water. Standpipe scale + SOIL B

Measured continuously (60 s to Home Assistant/InfluxDB; 10 min means to the local SD card):

Measured by people:

What When How
Fog score 0–4 (0 clear; 1 droplets on top quarter; 2 half of glass; 3 most; 4 fully fogged) Monthly glance, at 08:00 and 14:00 on the same day Paper logbook + HA input_number
Sump level (mm) Monthly Scale on the clear standpipe
Front + side photos Quarterly Fixed phone jig (see Engineering). LED at 100 %, room lights off, grey/colour card in frame.
Species inventory Yearly (June) Presence, estimated cover % per species on the printed 5 × 5 cm grid overlay, tallest height in cm
Moss cover % Yearly Fiji/ImageJ colour threshold (HSB) on the jig photo, fixed ROI; plus manual grid-cell count as a cross-check
Cleanup crew census Yearly, at 08:00 before lights on Count springtails and isopods visible against the front glass in a marked 10 × 10 cm window at substrate level. Three counts, 5 min apart.
Condensation pattern Yearly Photo series every 2 h for one day (08:00–18:00)
Pruned/removed biomass (g fresh, g dry) At each service opening Kitchen scale 0.1 g; dry 24 h at 60 °C. This is carbon exported from the system.

Analysis over years:

Role of the first 8 weeks (establishment baseline, Dec 2026 – Feb 2027). This is the founding cohort's own experiment. It is a natural before/after design:

Predictions to write down before sealing:

Students compute the effect size (weekly mean of the daily CO2 amplitude, open vs sealed) and report it in March 2027. These 8 weeks are also the reference baseline that every later year is compared against.

Engineering track

Design-for-longevity requirements (verify each one at commissioning; re-verify in the yearly checklist):

ID Requirement Design answer Verification
R1 The living system survives 30 days with all electronics and network dead Passive water cycle. Light runs on a COTS timer plug through a relay NC bypass. Unplug the node PSU5 for 48 h: LED still follows the 07:00–19:00 schedule
R2 Semi-sealed with controllable gas exchange Gasketed glass lid + 20 mm vent port with PVC screw cap and stainless mesh. Cap closed = sealed; cap off = passive vent. RH stays ≥ 90 % for 7 days with cap closed
R3 Water can be added and removed without opening 20 mm clear acrylic standpipe from the LECA sump to a ½" bulkhead in the lid. Syringe drain; optional 12 V peristaltic top-up. Add and remove 100 mL through the port; read the level on the standpipe scale
R4 Light independent of windows and school timetable 12 V LED strip in aluminium profiles above the lid, 12 h/day, weekends and holidays included BH1750 ≥ 3,000 lux at canopy
R5 Optical clarity and integrity for 10 years COTS glass tank + 6 mm float-glass lid. No acrylic walls: acrylic scratches, yellows and bows over 10 years. Yearly seam and scratch inspection
R6 No adhesive that can fail Mechanical fasteners only: clamp hinges, toggle clamps, threaded bulkheads, cable glands. Aquarium silicone only where the tank already uses it. No hot glue, foam tape, cyanoacrylate, epoxy or PVA in the wet zone. Neutral-cure (not acetoxy) silicone on electronics. Visual
R7 Sensors are replaceable without opening the lid Sensor pod: acrylic mast hung from a DN50 screw cap carrying ONE PG9 gland + one blanked spare PG9 Full pod swap in < 15 min (rehearsed at commissioning)
R8 Data survives hub failure DS3231 RTC + local microSD CSV log on the node, independent of Wi-Fi/HA Stop HA for 24 h; SD file has no gaps
R9 Understandable by strangers Versioned manual (paper + PDF + repository), printed information panel, every cable labelled at both ends A student outside the project performs the monthly check using only the manual
R10 Survives a room move Stand + tank + node move as one unit. All couplings unpluggable (DC jacks, standpipe sleeve). Move procedure written and rehearsed once (empty-tank dry run)
R11 Safe SELV 12 V only on the stand. Mains bricks on a wall shelf above and away, on an RCD strip. Teacher sign-off

Sealed vs. semi-sealed. Fully sealed (Latimer style) gives the best science, because it is a truly closed system. The risk is an unrecoverable mould or anaerobic crash in year 1, when nobody has experience with this tank. Decision: semi-sealed by design, sealed in operation. The vent cap is normally closed. The cap is opened only by rule (fog score 4 all day for 3 consecutive days, or mould bloom), and every opening is logged as an event.

Data archive strategy. Data is kept in four independent places:

  1. InfluxDB on the hub (retention forever).
  2. Nightly CSV export to the school Google Drive. The account is owned by the school, not a person.
  3. A local monthly CSV on the node's SD card.
  4. A yearly ZIP: open formats only (CSV, JPG, PDF/A, TXT, MD), plus a README.txt describing columns, units, sensor versions, calibration and events. It goes to the school drive, a USB stick, and a printed summary page in capsule compartment B.

USB flash and SD cards can lose data after years without power. Paper is the guaranteed format, and the drive copy is refreshed yearly.

Failure modes & recovery:

Failure Detection Recovery
Mould bloom: white fuzz on wood or leaf litter. Normal in weeks 1–8. Visual; fog score 4 for days Weeks 1–8: do nothing; springtails graze it. If it covers > 10 cm² on a plant, or is still spreading after week 8: open the vent cap for 1–3 days. Remove affected material with long tweezers during a service opening. Log mass removed.
Plant die-off (rotting mass) Visual; CO2 night peak +50 % over the 30-day median Remove rotting tissue > 5 cm² at a service opening (log g). Replant only with a species already in the inventory, or document the new one.
Pest outbreak: fungus gnats (Bradysia), mites, snails/slugs from wild moss Yellow sticky trap during settling; visual Prevention: freeze substrate bags and moss 48 h at −18 °C, and quarantine moss for 2 weeks. Gnats: lower the sump level, leave the vent open 1 week, yellow trap. Slugs: remove by hand at night.
Overwatering: sump > 30 mm, waterlogged substrate Standpipe scale; SOIL B saturated > 7 days Drain via standpipe with a 60 mL syringe and 6 mm tube. Log mL.
Drying or seal leak RH < 75 % for 6 h; SOIL A dry; no condensation for 3 days Check gasket and clamps, vent cap and glands. Add 50 mL distilled water via the standpipe.
Algae on glass Green film; BH1750 falls > 20 % vs baseline Reduce LED to 50 % or 10 h. Wipe the inside at the yearly opening with a magnetic glass cleaner (no chemicals).
Sensor failure NaN/stuck values; HA alert Swap the whole pod with the spare pod or rebuilt pod (15 min). Repair the old pod at the bench.
Node failure "No data 24 h" alert; OLED dark LED continues via relay NC bypass on the timer plug. Swap in a spare ESP32 + TERMBOARD and flash the archived .bin from the repo.
Hub failure No dashboard Node keeps logging to SD. Restore the HA backup on a new Pi. Back-fill InfluxDB from the SD CSVs.
Long power cut events.csv boot record; RTC time stays correct Nothing to do. The digital timer plug has battery backup; check its clock afterwards.
School renovation or room move Planned Follow the move procedure (Operations). Move the stand as one unit with 4 people. Max 2 h without light. Never move it while the sump is > 10 mm.
Summer heat (room > 30 °C in July–August) T > 30 °C alert Automatic summer mode (Jun 15–Sep 10): 10 h photoperiod at 50 %. The teacher checks the dashboard weekly in the holiday.

Enclosure & build

Tank.

Layers (bottom → top; volumes for 60 × 30 cm internal ≈ 58 × 28 cm):

Layer Depth Volume Notes
LECA drainage + sump 4 cm 6.5 L Rinse, soak 24 h in distilled water. 1 cm of sump water ≈ 0.65 L (porosity ~40 %). Normal sump: 10–20 mm; MAX line 30 mm, marked on the front glass with a small label.
MESH separator — 58 × 28 cm + 2 cm upturned edges Fibreglass or stainless. Stops substrate falling into the sump.
Activated charcoal 1 cm 1.6 L Horticultural or aquarium grade, rinsed. Adsorbs organic acids and odour.
ABG-style substrate 8 cm at the front → 11 cm at the rear (slope) ~15 L Mix by volume: 2 coco coir : 2 orchid bark (fine) : 1 chopped sphagnum : 1 charcoal : 1 peat or tree-fern fibre. Pre-moisten with distilled water to "squeeze → a few drops".
Hardscape — — 2 pieces of natural cork bark (≈ 30 × 15 cm and 20 × 10 cm), one leaned on the rear glass as a climbing face for Ficus. Optionally 2–3 boiled river stones. No treated or painted wood.
Leaf litter 1–2 cm ~2 L loose Dried oak/beech leaves (bake 30 min at 90 °C) + 3–5 Terminalia catappa leaves. This is the food for the cleanup crew for years.

Water. Only distilled or demineralised water, ever. Bucharest tap water is hard (Ca/Mg). In a closed system, the salts accumulate on glass and in substrate over 10 years.

Fill/drain standpipe.

Lid.

Opening the lid (rare; procedure in the manual):

  1. Unplug the LED bar's DC jack and lift off the light bridge.
  2. Unscrew the pod cap and lift the pod out.
  3. Release the toggle clamps.
  4. Tilt the lid up on its hinges. The standpipe sleeve slides off.

Light.

Stand and mains.

Sensor pass-through.

flowchart TD
  WS["Wall shelf above and away - RCD strip, timer plug, PSU12, PSU5 (230 V COTS only)"]
  LB["Light bridge - 2x LED profile 58 cm (12 V), 5 cm above lid"]
  LID["Glass lid 6 mm + silicone gasket, 2 clamp hinges, 2 toggle clamps"]
  PORTS["Lid ports - standpipe bulkhead, vent cap with mesh, DN50 pod port"]
  POD["Sensor pod - acrylic mast with SHT31, SCD41, BH1750, DS18B20, SOIL A and B"]
  AIR["Air space about 20 cm - condensation cycle"]
  LIT["Leaf litter 1-2 cm"]
  SUB["ABG-style substrate 8-11 cm"]
  CH["Activated charcoal 1 cm"]
  ME["Mesh separator"]
  LE["LECA 4 cm with sump water 10-30 mm"]
  SP["Clear standpipe 20 mm, rear-left, fill and drain"]
  BOXN["Node box mc-09-capsule on rear board - ESP32, RTC, SD, MOSFET, relay"]
  CAB["Cabinet - capsule document box, spare pod, manual"]
  WS -->|"12 V and 5 V DC, drip loops"| BOXN
  BOXN -->|"12 V PWM"| LB
  LB --> LID
  LID --- PORTS
  PORTS --> POD
  PORTS --> SP
  POD -->|"8-core cable via 1 PG9"| BOXN
  LID --> AIR --> LIT --> SUB --> CH --> ME --> LE
  SP --> LE
  LE --> CAB

Build steps (core team of 4 plus delegates):

# Step Time
1 Assemble and level the cabinet (spirit level, shims under the feet). Bolt on the rear board. Fit the wall shelf. Fit the lid hinges' wood leaves and the clamp posts. 3 h
2 Leak test: TANK63 with 5 cm water for 24 h on the cabinet, paper towel underneath. Then empty and dry. 0.5 h + 24 h
3 Lid (pre-ordered from the glazier): fit bulkheads, vent cap, pod connector and gasket. Dry-fit the hinges and toggle clamps. 1.5 h
4 Substrate prep: soak LECA 24 h; hydrate 2 coir bricks; freeze moss and bagged substrate 48 h; bake leaves. Mix the ABG-style substrate in a 60 L box with gloves. 2 h + soaking
5 Install standpipe → LECA 4 cm (level) → MESH (upturned edges) → charcoal 1 cm → substrate, sloped 8 → 11 cm 1.5 h
6 Hardscape: cork pieces, stones. Mark the 6 × 6 cm "pod patch" at rear-right, left unplanted and covered with litter only. 1 h
7 Insert the pod mast through the open top, pushing the probes into the substrate first. Route the cable. Fit the cap on the lid later. 1 h
8 Planting (largest first: ferns, Asplenium, Peperomia, Pilea, Fittonia, Ficus at the cork, Selaginella), then mosses, then leaf litter. Mist with 200–400 mL distilled water. 3 h
9 Add the cleanup crew: 1 springtail culture tipped over the litter; 30+ isopods under the cork. Keep the 2nd springtail culture as a backup. 0.5 h
10 Electronics: node box on the rear board, LED bridge, timer plug programme, 12 V wiring, relay bypass, pod cable into the box. Label every cable at both ends. 3 h
11 Commissioning: ESPHome flash, HA entities, alert tests (cold spray on DS18B20, unplug pod cable), SD file check, fail-safe test (unplug PSU5 → LED keeps the timer schedule) 2 h
12 Day-0 baseline: jig photos, species inventory, calibration sheet into the manual 1 h
13 Fit the information panel. Put the logbook and manual v1.0 in the cabinet. 0.5 h

Information panel (approved "printed durable ecosystem labels / information panels"):

Biology

Plants. All are non-toxic for handling with gloves, robust in closed terrariums, and available at Dedeman/Hornbach/Leroy Merlin garden sections, florists, or Romanian terrarium shops/OLX:

Species (common) Qty Position 10-year note
Fittonia albivenis 'Mini' (nerve plant) 2 Front-middle Classic closed-terrarium plant; prune at service openings
Ficus pumila 'Minima' (creeping fig) 1 At the rear cork Most vigorous; prune yearly. Latex is a mild skin irritant, so wear gloves. Alternative: Pellionia repens.
Peperomia rotundifolia or P. caperata mini 1 Mid-left Slow, very tolerant
Pilea glauca or P. depressa 1 Front-right ground cover Fast ground cover
Nephrolepis cordifolia 'Duffii' (lemon-button fern) 1 Rear-left Dwarf form only. Standard N. exaltata outgrows 60 L.
Asplenium nidus juvenile (bird's-nest fern) 1 Rear-centre Slow; may reach 25–30 cm by 2032
Selaginella kraussiana (spike moss) 1 Low, humid front Needs 90 %+ RH; indicator of humidity health
Mosses: Leucobryum glaucum (cushion moss), Hypnum cupressiforme (sheet moss) 3 portions (≈ 0.05 m² total) Front slope, on stones and cork See sourcing note below

Moss sourcing. Buy from terrarium shops where possible. If collecting: take small amounts only, with the forest administrator's permission (Romsilva / owner), never in protected areas. Leucobryum glaucum is listed in Annex V of the EU Habitats Directive. Quarantine moss 2 weeks in a tray and freeze it for 48 h to kill slugs and mites.

Cleanup crew. No animals that need feeding; no vertebrates.

Establishment and settling (4 weeks, ~12 Dec 2026 – ~11 Jan 2027).

Expected condensation cycle (sealed, LED 07:00–19:00):

Tuning rules:

Observation Action
Fully fogged (score 4) all day Open the vent cap 10 min. Repeat daily up to 3 days, then reassess.
No condensation at all for 3 days Add 50 mL distilled water via the standpipe
Water above 30 mm in the standpipe Drain to 15 mm with the syringe
Pale, stretched plants Raise LED duty +10 % (max 90 %)
Algae on glass or scorched moss Lower LED duty −10 % or shorten to 10 h

Every action is logged in events.csv and the paper logbook.

Instrumentation

Catalog ID Qty Placement Interval Purpose
SHT31 1 Inside, on the pod mast 4 cm below the lid, in a cased PTFE-membrane probe housing, membrane facing down 60 s Air T/RH, seal integrity (RH < 75 % = leak), dew point
SCD41 1 (strongly recommended) Inside, on the pod mast 6 cm below the lid (warmest, least-condensing point under the LED), membrane-covered cased board 60 s Day/night CO2 cycle: the most informative long-term signal of a sealed ecosystem (respiration vs photosynthesis). Also a secondary T/RH.
BH1750 1 Pod mast at canopy height (~10 cm above the substrate), facing up, conformal-coated, clear cover 60 s Canopy lux. Relative trend from LED aging, lid fog and algae. Not PAR.
DS18B20 2 #1 in the substrate at 5 cm depth (pod mast); #2 outside on the rear board, shaded (room reference) 60 s Substrate T for the Q10 analysis; room T separates internal from classroom dynamics
SOIL 2 A: shallow, sensing zone 0–5 cm; B: deep, tip 1 cm above the mesh near the sump. Both on the pod mast. 60 s (mean of 10) Water distribution; B detects waterlogging
RTC 1 Node box (I2C 0x68) — Timestamps for SD logging; light schedule without NTP
SDMOD + SD64 1 + 2 Node box (SPI) 10 min Local CSV log independent of hub and Wi-Fi
OLED 1 Node box lid window 5 s page cycle Live values, Wi-Fi/SD status, "last top-up" date

Why not a BME680 here:

SCD41 notes:

SD logging and card lifetime:

Pin assignment (standard pin map; unused standard slots reused for SPI and documented):

Function GPIO Standard-map slot
I2C SDA / SCL: SHT31 0x44, SCD41 0x62, BH1750 0x23, OLED 0x3C, RTC 0x68 (+ EEPROM 0x57) 21 / 22 I2C; bus at 50 kHz because of the ~1.2 m pod cable; 2.2 kΩ pull-ups
1-Wire: DS18B20 #1 substrate, #2 room 4 1-Wire, 4.7 kΩ to 3.3 V
SOIL A (shallow) / SOIL B (deep) 32 / 33 Analog A / B (ADC1, 11 dB)
12 V LED-supply sense (47 k / 10 k divider → 2.1 V) 36 Analog E
LED PWM (MOSFET 1, 2 kHz) 16 PWM 1 — light
PERI top-up (MOSFET 2, on/off) 18 PWM 3 — pump
Relay 1: LED fail-safe bypass (energised = MOSFET control; de-energised = NC bypass) 23 Relay 1 (12 V DC load only)
SD SPI SCK / MOSI 26 / 27 Servo 1 / 2 slots (no servos on this node)
SD SPI MISO 19 PWM 4 slot (unused here)
SD SPI CS 5 Pulse-counter slot (unused here; high at boot = card deselected)
Status LED heartbeat 2 Reserved onboard LED

Power:

Calibration (results go on the calibration sheet in the manual and in the CSV header):

The sensor pod (swappable in 2029/2030 without opening the lid):

Automation

Everything is passive except light. The pump top-up is optional and human-confirmed.

Fail-safe:

Alerts (HA automations → HA mobile app + e-mail to the teacher sponsor and both Keepers; also shown on the OLED and in events.csv):

Alert Condition
Too hot Air or substrate T > 30 °C for 15 min
Too cold Air T < 12 °C for 30 min (heating failure in winter)
Seal leak / drying RH < 75 % for 6 h
Soil dry SOIL A < 25 % of saturation for 24 h
Waterlogged SOIL B ≥ 98 % for 7 days
No data Any mc_09_* entity unchanged for 24 h (HA side)
SD error Write failure or card missing (node side, on boot or write)
Light supply 12 V absent between 07:30 and 18:30, or present between 19:30 and 06:30 (timer plug fault)
CO2 info Night peak > 2× the 30-day median (possible die-off; inspect)

Optional top-up:

stateDiagram-v2
  [*] --> Boot
  Boot --> Bypass : relay off during boot
  Bypass --> Night : time valid from RTC or NTP
  Night --> Dawn : 0700 and 12 V present
  Dawn --> Day : ramp done 70 pct
  Day --> Dusk : 1830
  Dusk --> Night : 1900 duty 0
  Day --> TopUp : Keeper presses Add 50 mL
  TopUp --> Day : run time done or interlock
  Night --> Alert : threshold breached
  Day --> Alert : threshold breached
  Alert --> Night : cleared at night
  Alert --> Day : cleared at day
  Day --> Bypass : node crash or power loss
  Night --> Bypass : node crash or power loss
  Bypass --> Bypass : LED follows timer plug at 100 pct

Operations

10-year maintenance calendar:

Frequency Who Tasks Time
Weekly (school weeks) Keepers Glance at the dashboard; read the OLED 2 min
Monthly Keepers Fog score (08:00 and 14:00), standpipe level, visual check (mould, pests, dead plants), confirm the timer-plug clock, fill in the logbook, tick the panel box 15 min
Quarterly (Sep, Dec, Mar, Jun) Keepers Jig photos (front + side, grey card), upload to the drive 20 min
Yearly (June, before summer) Keepers + teacher See the yearly checklist below 2–3 h
Every 3 years (2029/30, 2032/33, 2035/36) Keepers + an electronics-capable student Build, calibrate and swap a new sensor pod (SHT31, SCD41, BH1750, DS18B20, 2× SOIL, 8-core cable). Retire the SD card to capsule compartment B and insert a new SD64. 1 day bench + 15 min swap
Every 5 years (2031, 2036) Teacher + Alacrity/IT volunteer Hub refresh: new Pi or successor + storage; restore the HA backup; export the full InfluxDB to CSV; replace the gasket, RTC cell and timer plug; replace the LED strip from the spare reel if Day-0 lux has dropped below 70 % 1 day
December 2036 Whole school Capsule opening; compare the 2026 predictions with the data; decide on the next decade Event

Yearly checklist (June):

  1. Species inventory, moss cover, crew census, condensation photo day.
  2. Copy the SD card and verify it against InfluxDB (row counts per month).
  3. Build the yearly ZIP: CSV of 10 min and daily data, photos, inventory, events, manual PDF, README.
  4. Upload the ZIP to the school drive. Put a USB copy and the printed A4 summary page in compartment B.
  5. Inspect the tank silicone seams, gasket, clamps and glands.
  6. Optional service opening (≤ 60 min, only if needed): prune Ficus and ferns, remove rot, clean the inside glass. Weigh removed biomass (fresh and dry) and log the event.
  7. Check the summer-mode schedule.
  8. Write the manual change log and bump the version.
  9. Hand over the Keeper role (below).

The Keeper role:

Maintenance manual outline ("MC-09 Keeper Manual vX.Y"; paper binder in the cabinet + PDF + Markdown in the project repository; every page dated and versioned; change log at the front):

§ Content
0 Change log, Keeper list, contacts
1 What this is: concept, layers, species, why it is sealed
2 Monthly / quarterly / yearly checklists (one page each, tick-box)
3 Tuning rules (condensation table), water rules (distilled only, 50 mL max per action)
4 Vent, standpipe, pod swap and lid opening procedures, with photos
5 Electronics: wiring diagram, pin table, cable labels, ESPHome version and YAML, .bin location, flashing steps, relay bypass explanation
6 Calibration procedures and the calibration history table
7 Alerts: what each one means and what to do
8 Failure modes & recovery (table above)
9 Data: where it lives, file formats, column dictionary, how to build the yearly ZIP
10 Move procedure for renovation (see Safety)
11 Safety rules (the hard rules, verbatim)
12 Parts list with suppliers and 2026 prices, plus "equivalent part" guidance for when parts are discontinued

Data archive:

Safety & risks

Hard rules that apply here.

Weight.

Sealing and mould.

Vandalism and knocks.

School renovation / move.

Other risks.

Educational outcomes & assessment

Outcomes. Students can:

Collaborative design: one lesson learned from each team. Each team presents its lesson in a 5-minute "design review" on 30 Nov 2026. The capsule team turns each into a written requirement or design change.

Team Example lesson (to be confirmed with real results) Becomes
1 Orchestra of Rot Which decomposers persisted; mould dynamics; charcoal against odour Crew choice, charcoal layer, mould tuning rule
2 EcoColumn Drainage, water-level reading, sediment clogging mesh Sump + standpipe scale, mesh with upturned edges
3 Brownfield Salt accumulation and compaction harm roots Distilled water only; open, bark-rich substrate
4 Future 2026 Real classroom T/RH swings and heating-season effect Room DS18B20, cold alert
5 Future 2056 Heat stress thresholds 30 °C alert, summer mode
6 Forests in Space Substrate recipes and water retention ABG mix ratios, SOIL calibration in the actual mix
7 Hydroponic Jungle LED intensity/photoperiod vs growth; PWM dimming 70 % duty, 12 h, ramp, LED spare reel
8 Living Earth Soil respiration CO2 vs temperature SCD41 inclusion, Q10 analysis, ASC off
9 Capsule prototype jars 4 × 4 L sealed jar prototypes (built ~9 Nov), 4 weeks of observation: condensation and mould behaviour of the mix Final mix, water dose, settling duration

Assessment (team grade 60 % + individual 40 %):

Component Evidence
Requirements & verification R1–R11 table with test results
Build quality Checklist: labels, gland seals, no loose wires, level, leak test log
Baseline experiment Pre-registered predictions, 8-week open/sealed report with plots and effect size
Manual v1.0 A non-team student completes a monthly check using only the manual (pass/fail + feedback)
Individual Letter to the 2036 Keeper (in the capsule), plus a short reflection: one design decision and its trade-off

Sub-BOM

Cost-cut 2026-10-20: MARINA 54 L tank, SCD41 deferred to 2027, top-up by 60 mL syringe through the fill tube instead of a peristaltic pump, existing furniture instead of a new cabinet, one timer plug, laminated panel, plastic archive box, fewer jars, prints, cork, moss and cultures. The sensor pod keeps a reserved slot for the SCD41.

Price basis: Romanian web shops Oct 2026, incl. VAT. Electronics from optimusdigital.ro, ardushop.ro, robofun.ro and emag.ro (AliExpress fallback for the cased SHT31). Hardware from dedeman.ro and hornbach.ro. Tank and cabinet from Romanian aquarium shops. Live animals from OLX.ro hobbyists or EU breeders. 1 EUR ≈ 5.1 RON.

Item Qty Unit RON Line RON Basis / note
TANK63 1 139 139 Hornbach MARINA 60×30×30 (54 L). Ultraclear 60×30×36 at ≈ 362 if the extra height is wanted.
ESP32 1 35 35 Optimus/emag
TERMBOARD 1 30 30 Screw-terminal breakout
OLED 1 25 25
SHT31 1 75 75 Cased probe with PTFE membrane
Optional (not in subtotal): SCD41 CO2 sensor, deferred to the 2027 budget 1 230 (230) The sealed-tank CO2 cycle is the best long-term signal; the gland and pod have a reserved slot for it
DS18B20 2 15 30 Substrate + room reference
SOIL 2 12 24 v2.0 TL555, top edge sealed
BH1750 1 15 15
RTC 1 20 20 DS3231; charging diode removed or LIR2032
SDMOD 1 10 10 SPI microSD breakout
SD64 1 70 70 High Endurance; rotation card bought at year 3
MOSFET 2 10 20 LED dimming + PERI
RELAY 1 10 10 LED fail-safe bypass (12 V DC only), active-high jumper
PSU12 1 60 60 On the timer plug
PSU5 1 30 30 Node, always on
BOX 1 40 40 IP65, on the rear board
GLAND 6 3 18 2 in the pod cap (1 blanked) + 4 on the node box
LEDSTRIP 1 90 90 1.2 m used; 3.8 m kept as the 2031 spare
LEDPROFILE 2 25 50 Cut to 58 cm
TUBING 2 m 8 16 PERI line + drain tube
SILICONE 1 35 35 Aquarium-safe, no fungicide (gasket dots, standpipe sleeve seat)
MESH 0.25 m² 10 (lot) 10 Separator + standpipe wrap + vent disc
ACRYLIC 0.25 sheet 30 (share) 30 Pod mast L-profiles (2, incl. spare pod)
8-core shielded cable LiYCY 8×0.25 3 m 6 18 Pod cable (×2 pods)
Neutral-cure electronics silicone / potting 1 30 30 Splice block (not acetoxy)
Fuse holder 2 A, adhesive heat-shrink, terminal blocks, 47 k/10 k resistors 1 lot 30 30 From the consumables lot
PVC ½" tank connector (bulkhead) 2 15 30 Standpipe + vent
PVC ½" screw cap 1 5 5 Vent cap
PVC DN50 (2") tank connector + DN50 screw cap 1 60 60 Pod port
Clear acrylic tube 20 mm OD × 40 cm 1 20 20 Standpipe (rigid tubes lot)
Glass lid 6 mm 60×30, polished, 3 holes 1 180 180 Bucharest glazier, order by 20 Nov
Silicone sponge gasket cord 6×4 mm 3 m 35 (roll) 35 Replace 2031
Clamp-type glass hinges 4–8 mm 2 25 50 From the approved hinges lot
Toggle hold-down clamps GH-101 2 20 40 Latches
Existing school cabinet or bench rated ≥ 100 kg, plus wall-anchor kit and 18 mm plinth board 1 100 100 confirm the furniture rating before filling the tank
Rear board 18 mm plywood 60×100 + 2 brackets + aluminium light bridge 1 120 120 Dedeman
Wall shelf for mains bricks 1 40 40
Digital timer plug with battery backup 1 50 50 LED fail-safe schedule
Information panel A3 laminated print + cable/port labels 1 25 25
BIO: LECA 10 L 1 25 25
BIO: activated charcoal 3 L 1 70 70 Layer + mix
BIO: coco coir brick 650 g 2 15 30
BIO: orchid bark fine 5 L 1 30 30
BIO: dried sphagnum 150 g 1 35 35
BIO: peat or tree-fern fibre 5–20 L 1 25 25
BIO: natural cork bark piece + collected hardwood branch (baked) 1 50 50
BIO: Terminalia catappa leaves (10) + collected oak/beech litter 1 20 20 Litter collected free
BIO: Fittonia albivenis mini 2 15 30
BIO: Ficus pumila 'Minima' 1 15 15
BIO: Peperomia rotundifolia / caperata mini 1 20 20
BIO: Pilea glauca / depressa 1 20 20
BIO: Nephrolepis cordifolia 'Duffii' 1 25 25
BIO: Asplenium nidus juvenile 1 25 25
BIO: Selaginella kraussiana 1 25 25
BIO: mosses (Leucobryum, Hypnum) portions, plus moss collected with permission 2 30 60
BIO: springtails Folsomia candida culture (split from the team 1 and 8 cultures) 1 40 40
BIO: dwarf white isopods Trichorhina tomentosa 30+ 1 60 60 Incl. shipping share
Distilled water 5 L 2 8 16
Yellow sticky traps 1 pack 15 15 Settling census
Prototype jars 4 L with clamp lid 2 20 40
Lockable plastic archive box A4 (capsule) 1 45 45
Acid-free sleeves/folders + slot pocket 1 25 25
Silica gel packs 1 20 20
USB 32 GB (two brands) 2 30 60 Founding data
Numbered tamper seals 1 pack 20 20
Photo prints (founding set) 1 20 20
Photo jig (aluminium arm + phone clamp) 1 40 40 Slots into the cabinet top
Grey/colour reference card, laminated 1 15 15
60 mL syringes 2 5 10 Approved syringes lot
Subtotal 2 646 RON (≈ 519 EUR) catalog hardware 882 · lid, plinth, pod and operations 928 · biology 836 (after the cost-cut pass)

Without the optional SCD41 + PERI: 3,832 RON. Not recommended to drop the SCD41.

Shared items, not counted here: the RCD power strip, hub, router and handheld pens.

Allocation from the approved list:

Timeline

Dates Milestone
26 Oct – 6 Nov 2026 Requirements R1–R11 agreed; order the tank, cabinet, electronics and live crew (book for an early-December pickup)
9 Nov – 4 Dec 4 prototype jars sealed and observed. Pod bench build and calibration (salt test, ice bath, SOIL 3-point, SCD41 FRC). ESPHome YAML + SD component tested.
by 20 Nov Glass lid ordered from the glazier (holes checked against the actual bulkheads)
30 Nov Design review: 9 lessons learned → final design v1.0
1–12 Dec Build steps 1–13; commissioning and fail-safe test; Day-0 baseline
12 Dec – ~11 Jan 2027 Settling: lid cracked, vent open; dashboard checks over the winter break
11–15 Jan 2027 Sealing Day: tank sealed, capsule compartment A sealed
Jan – Mar 2027 Weeks 5–8 sealed baseline; March report (open vs sealed)
June 2027 First yearly checklist; first Keeper handover
gantt
  title MC-09 Time Capsule - build and 10-year calendar
  dateFormat YYYY-MM-DD
  axisFormat %Y
  section Build 2026
  Prototype jars and pod bench build :a1, 2026-11-09, 2026-12-04
  Build and commissioning :a2, 2026-12-01, 2026-12-12
  Settling with lid cracked :a3, 2026-12-12, 2027-01-11
  Sealing Day and capsule A sealed :milestone, m0, 2027-01-13, 0d
  Sealed baseline weeks 5-8 :a4, 2027-01-13, 2027-03-10
  section Yearly
  Yearly checklist 2027 :milestone, y27, 2027-06-15, 0d
  Yearly checklist 2028 :milestone, y28, 2028-06-15, 0d
  Yearly checklist 2029 :milestone, y29, 2029-06-15, 0d
  Yearly checklist 2030 :milestone, y30, 2030-06-15, 0d
  Yearly checklist 2031 :milestone, y31, 2031-06-15, 0d
  Yearly checklist 2032 :milestone, y32, 2032-06-15, 0d
  Yearly checklist 2033 :milestone, y33, 2033-06-15, 0d
  Yearly checklist 2034 :milestone, y34, 2034-06-15, 0d
  Yearly checklist 2035 :milestone, y35, 2035-06-15, 0d
  Yearly checklist 2036 :milestone, y36, 2036-06-15, 0d
  section Pod and hub
  Sensor pod v2 swap :milestone, p2, 2029-11-15, 0d
  Hub refresh and gasket and LED check :milestone, h1, 2031-06-20, 0d
  Sensor pod v3 swap :milestone, p3, 2032-11-15, 0d
  Sensor pod v4 swap :milestone, p4, 2035-11-15, 0d
  section Capsule
  Capsule opening and next decade decision :milestone, c1, 2036-12-10, 0d

6. Procurement and budget

6.1 Method and assumptions

6.2 Budget tables

A. Controllers and sensors

ID Item Approved qty Recommended qty Unit (RON) Line (RON) Source / basis Note
ESP32 ESP32-WROOM-32 DevKitC 38-pin 12 12 48 576 emag.ro ESP32 38-pin CP2102 USB-C buy all 12 from one listing so pinout and row spacing match
TERMBOARD ESP32 DevKitC screw-terminal breakout – 10 18 180 sigmanortec.ro 38P screw-terminal board CHECK row spacing against the DevKitC (a review reports a 25 mm pitch mismatch); eMAG sells ESP32 + terminal board as a matched pair at 92
OLED SSD1306 0.96 in I2C OLED 12 12 19 228 sigmanortec.ro SSD1306 0.96 in I2C expect 1–2 dead on arrival; spares cover it
SHT31 SHT31-D T/RH breakout with PTFE membrane – 8 50 400 emag.ro SHT31 I2C (2-pack 99) probe-style cased SHT31 with cable (AliExpress ≈ 31–60) is better in 90 % RH tanks: order 8 on day one as the primary, eMAG as fallback
BME680 BME680 T/RH/P/gas breakout 9 2 60 120 optimusdigital.ro BME680 module (in stock) purple 3.3 V I2C board
SCD41 Sensirion SCD41 NDIR CO2 breakout 3 4 230 920 sigmanortec.ro SCD41 module 201 (out of stock on 2026-10-20) / Pimoroni EU 260 genuine Sensirion SCD41, not SCD40 or MH-Z19; order day one
DS18B20 DS18B20 waterproof probe 1 m 9 15 16 240 emag.ro stainless 1 m, 3-pack 47 test every probe in ice water; 2–3 m cable for hydroponics
SOIL Capacitive soil moisture v2.0 (TL555 version) 12 22 7 154 sigmanortec.ro capacitive v2.0 (5) / known-good TLC555 batch (9) reject NE555 boards; conformal-coat the top edge
BH1750 BH1750 lux breakout 9 9 14 126 optimusdigital.ro GY-302 (in stock) mount behind a clear window
FLOAT Float switch vertical 3* 10 26 260 emag.ro vertical PP float, side mount AliExpress ≈ 6 but 2–4 weeks; floats are needed at commissioning, so buy local
JSN JSN-SR04T waterproof ultrasonic – 2 50 100 emag.ro JSN-SR04T buy v3.0; 25 cm blind zone
FLOW YF-S401 flow sensor 2 2 24 48 emag.ro YF-S401 calibrate pulses per litre with a jug
PHKIT Analog pH kit (BNC probe + PH-4502C) – 2 140 280 sigmanortec.ro pH probe + PH-4502C kit output 0–5 V: divider to ESP32 ADC; store tip in KCl; probe life 6–12 months
TDS Gravity analog TDS module – 1 28 28 sigmanortec.ro Gravity-style TDS module 3.3 V compatible
TURB Analog turbidity module – 2 59 118 emag.ro turbidity module probe top not waterproof: mount through a lid; relative readings only
PHPEN Handheld pH pen – 2 42 84 emag.ro pH pen with ATC + calibration powders
TDSPEN Handheld TDS/EC pen – 1 25 25 emag.ro TDS/EC pen must show EC in µS/cm
CALSOL pH 4/7/10 + EC 1413 calibration set 1 lot 2 55 110 emag.ro pH sachet set 30 + EC 1413 sachets ≈ 25 (est.) sachets stay uncontaminated; add KCl 3 M storage bottle
RTC DS3231 RTC module 2 2 22 44 sigmanortec.ro DS3231 module remove the LIR2032 charging diode if a CR2032 is fitted
SDMOD microSD breakout module 9 2 4 8 sigmanortec.ro microSD SPI module 3.3 V-native version
SDCARD microSD 32 GB (node logging) 9 2 50 100 emag.ro ADATA 32 GB UHS-I brand-name only; FAT32
ELECCONS Electronics consumables: 9 node cable kits (pre-crimped JST-XH leads, 22 AWG wire, ferrules, heat-shrink) 270 + 12 inline fuse holders with 5 A fuses 96 + backplates, standoffs, flyback diodes, labels 100 1 lot 1 466 466 optimusdigital.ro / emag.ro (platform chapter estimate) replaces the 4 approved "lots"
Subtotal A. Controllers and sensors 4 615

B. Automation and power

ID Item Approved qty Recommended qty Unit (RON) Line (RON) Source / basis Note
FAN 12 V 80 mm fan 4 6 10 60 optimusdigital.ro CMP-FAN23 12 V 80 mm only ~21 in stock; Sunon ball-bearing alt. ~25
PUMP 12 V DC submersible pump 3–5 W 2 5 45 225 cleste.ro 12 V brushless 240 L/h (32, snippet) / bitmi.ro JT-500 (60) budgeted mid-way; confirm stock
PERI 12 V peristaltic dosing pump 2 3 135 405 emag.ro G528 12 V peristaltic set Amazon.de Kamoer ≈ 77; buy 1 m spare pump tubing
HEATPAD 12 V silicone heat pad 10–25 W – 4 35 140 AliExpress 12 V 20 W silicone pad not in approved list; 2056 scenario needs it; NOT sold in RO as 12 V; order first, 2–3 weeks; RO 230 V mats are not allowed
THERMO KSD301 45 °C thermostat + 72 °C one-shot thermal fuse (set) – 4 10 40 optimusdigital.ro / emag.ro KSD301 + thermal fuse one set per heat pad; one set per heat pad
MIST Ultrasonic mister + 24 V adapter 2 2 83 166 emag.ro MY-20 fogger with 24 V PSU in stock
AIRPUMP COTS 230 V aquarium air pump + stone + tubing – 1 102 102 maxi-pet.ro Tetra APS 50 + stone + 3 m tube COTS 230 V on the shelf
LEDSTRIP 12 V full-spectrum LED strip 5 m reel 4* 4 70 280 emag.ro ZenLED 12 V COB 4000 K 12 W/m 5 m approved: grow lights 5–10 W ×4; full-spectrum 12 V strips out of stock in RO; AliExpress option ≈ 60
LEDPROFILE Aluminium LED profile 1 m + diffuser – 16 31 496 emag.ro profile 1 m + opal diffuser + caps
LEDPANEL COTS 230 V full-spectrum LED panel 45 W – 1 136 136 emag.ro EVI Tech Slim 36 W grow panel hydroponics only; verify real draw; hanging kit
SERVO SG90 micro servo 4 8 12 96 optimusdigital.ro SG90 180° (in stock) power from the 5 V buck
MOSFET MOSFET PWM module (D4184) 6 27 11 297 emag.ro dual-D4184 15 A PWM module 23 (9 for the critical path) + AliExpress D4184 ≈ 5 (18) never IRF520; blended price
RELAY 1-ch 5 V relay module (low-voltage loads only) 4 6 9 54 sigmanortec.ro 1-ch 5 V optocoupler relay low-voltage loads only
PSU12 12 V 5 A certified brick + DC jack adapter 4* 9 70 630 emag.ro CE-marked brand 12 V 5 A desktop adapter (LED/CCTV type, ≈ 50–90); Mean Well GST60A12 at AVmall 173 is the premium option certified brand only; it sits on the mains side
PSU5 5 V 2 A USB adapter + cable – 2 16 32 emag.ro OptimStar 5 V 2 A USB-A CE-marked brand only
BUCK LM2596 buck module – 10 10 100 emag.ro LM2596 set 5.0 V before connecting; lock the trimmer
SMARTPLUG COTS Wi-Fi smart plug with power metering – 2 61 122 Domadoo NOUS A1T (Tasmota pre-flashed, metering) / emag.ro Sonoff S60TPF 53 no cloud; power metering doubles as an air-pump sensor
RCDSTRIP RCD-protected (30 mA) power strip – 2 147 294 emag.ro Tracon TFGA-1 30 mA RCD adapter one per shelf; test button monthly
STRIP Standard 6-socket power strip 3 m – 4 44 176 dedeman.ro Lohuis 6-socket 3 m strip mounted on wall/top shelf
AUTOCONS Automation consumables lot (valves, non-return valves, barbs, spray bar PVC, cabling, fuses) 1 lot 1 213 213 emag.ro aquarium connector kit 120 + 6 non-return valves 48 + PPR spray bar 45 approved as sprayers/valves/cabling/spares lots
Subtotal B. Automation and power 4 064

C. Enclosures and construction

ID Item Approved qty Recommended qty Unit (RON) Line (RON) Source / basis Note
TANK25 Glass aquarium ~25 L – 1 109 109 hornbach.ro MARINA 40×25×24 EcoColumn pond
TANK45 Glass aquarium ~45 L – 3 129 387 hornbach.ro MARINA 50×30×30 Rot, 2026, 2056
TANK63 Glass aquarium ~63 L 9* 4 139 556 hornbach.ro MARINA 60×30×30 (54 L) approved: glass-panel construction packs ×9; Brownfield, Regolith, Living Earth, Capsule; 60×30×35 not sold bare in RO; ultraclear 60×30×36 at 362 if height matters
ACRYLIC Polycarbonate 3 mm, 205×125 cm sheet (= 4 panels 50×100) 0.75 1 419 419 dedeman.ro polycarbonate 3 mm 205×125 cm sheet 419 = 4 panels 50×100 1 full sheet = 4 panels; 2 more panels below
ACRYLIC2 Acrylic panel 3 mm 50×100 cm from a local plastics shop – 2 100 200 local plastics shop (estimate) designs use 5.85 panels in total
MESH Fine mesh per m² 1 lot 2 19 38 hornbach.ro fibreglass mesh 120 cm, per m
SILICONE Aquarium-safe silicone tube 4 6 43 258 hornbach.ro Soudal aquarium silicone 280 mL
TUBING Tubing lot: 5 m silicone 6 mm ID + 50 m PVC Cristal 8×10 mm 1 lot 1 229 229 emag.ro silicone 25/m + dedeman.ro Cristal roll 104 approved 20 m; silicone only where needed
RESERVOIR Food-grade container 10–20 L with lid 4 5 48 240 dedeman.ro 20 L HDPE food-grade canister with lid wrap in black foil for hydroponics
BOXPLASTIC Opaque storage box 30–60 L – 3 40 120 leroymerlin.ro 45 L storage box with lid buy opaque colour for hydroponics
BOX IP65 junction box 6 9 31 279 hornbach.ro Pawbol 150×110 IP65 transparent lid (snippet) transparent lid shows the OLED
GLAND PG7/PG9 cable gland 20 80 2 160 emag.ro Pawbol PG7 10-pack 17 70 % PG7, 30 % PG9, plus blanking plugs
HINGES Small hinges + clamp latches + handles/fasteners lot 1 lot 1 124 124 dedeman.ro hinges 12×3 + latches 4×12 + fasteners est. 40
OBSTUBE Transparent perforated observation tube 2 2 0 0 costed in Section 5.8 sub-BOM (PVC 32/40 mm drilled)
MOUNT Mounting lot (shelf brackets, aluminium angle, rigid PVC tubes and fittings) 1 lot 1 222 222 hornbach.ro aluminium angle ×6 + brackets + PVC/PPR tube lot
TOOLS Small tools lot: 2 UNI-T multimeters 124, hole saw 51 mm 33, step drill 30, glue gun 41, auto stripper 26, side cutters 25, caulking gun 15 (pliers and screwdrivers from the school) 1 lot 1 300 300 dedeman.ro / leroymerlin.ro / hornbach.ro: 2 cutters, 2 strippers, 2 pliers, hole saw 51, step drill, 2 glue guns, caulking gun, 2 UNI-T multimeters
LABCONS Syringes, sample containers and bags, labels, markers (lot) 1 lot 1 165 165 pharmacy / emag.ro / office: syringes 45 + containers & bags 60 + markers & labels 60
PANELS Printed information panels: 10× A3 laminated prints (foamboard upgrade later) 1 lot 1 100 100 school printer + laminating get 2–3 quotes
METROLOGY Metrology kit: reference thermometer 60, salt-test calibration jars and salts 40, cable trunking and drip-loop clips 80 (crimp tool dropped: pre-crimped leads) – 1 180 180 optimusdigital.ro / dedeman.ro (platform chapter estimate)
Subtotal C. Enclosures and construction 4 086

D. Hub and network

ID Item Approved qty Recommended qty Unit (RON) Line (RON) Source / basis Note
PI5 Raspberry Pi 5 4 GB + 27 W PSU + active cooler case – 1 557 557 ardushop.ro Pi 5 4 GB 463 + optimusdigital.ro official 27 W PSU 67 + Argon active cooler 27 authorised reseller only; eMAG marketplace is over 1 000
SD64 64 GB A2 microSD 1 2 132 264 emag.ro SanDisk Ultra 64 GB A1 prefer Extreme A2 or High Endurance for 24/7 writes
USBSTICK USB stick 64 GB for backups – 1 90 90 emag.ro SanDisk 64 GB backup rotation
NETCONS Ethernet patch cable + USB/HDMI cables for the Pi (lot) – 1 20 20 emag.ro patch cable + USB/HDMI cables
PIRTC Pi 5 RTC battery – 1 30 30 estimate
Subtotal D. Hub and network 961

E. Biology and consumables per ecosystem

ID Item Approved qty Recommended qty Unit (RON) Line (RON) Source / basis Note
E01 1 Rot: organisms + substrate + consumables + tools (from Section 5.1 sub-BOM) – 1 715 715 Section 5.1
E02 2 EcoColumn: rack + water tests + biology + lab consumables (Section 5.2) – 1 1 159 1 159 Section 5.2 includes 130 RON shelving
E03 3 Brownfield: soils + seeds + amendments + tools (Section 5.3) – 1 714 714 Section 5.3
E0405 4–5 Future pair: seeds + substrate + CO2 generator + tools (Section 5.4) – 1 590 590 Section 5.4
E06 6 Regolith: basalt dust + sand + amendments + pots + scales (Section 5.6) – 1 757 757 Section 5.6
E07 7 Hydroponics: nutrients + media + frame + jars + PPE (Section 5.7) – 1 702 702 Section 5.7
E08 8 Living Earth: tubes + endoscope + tea bags + Berlese + biology (Section 5.8) – 1 862 862 Section 5.8
E09 9 Time Capsule: glazier lid, plinth hardware, substrate, plants, capsule box (Section 5.9) – 1 1 764 1 764 Section 5.9 SCD41 deferred to 2027
Subtotal E. Biology and consumables per ecosystem 7 263

Summary by group

Group Approved list priced as-is (RON) Recommended plan (RON) Recommended (EUR)
A. Controllers and sensors 3 565 4 615 905
B. Automation and power 1 489 4 064 797
C. Enclosures and construction 3 314 4 086 801
D. Hub and network 132 961 188
E. Biology and consumables per ecosystem – 7 263 1 424
Total 8 500 20 989 4 115

Contingency 15 %: 3 148 RON. Total with contingency: 24 137 RON (4 733 EUR).

6.3 Per-ecosystem cost (as designed in Chapter 5)

These are the subtotals each ecosystem section declares, including its share of node electronics, enclosure, biology and tools. They overlap with the tables above (the catalog items are the same parts) and are shown so the school can see where the money goes.

Ecosystem Sub-BOM total (RON) Of which biology, consumables, tools (RON) Notes
1 Orchestra of Rot 1 874 715 two BME680, one SCD41, mister, carbon filter
2 EcoColumn 2 774 1 159 includes 130 RON shelving, water tests, pH kit, two turbidity probes
3 Brownfield 1 635 714 63 L tank, heat pad, 48-cup replication bench
4–5 Future 2026 / 2056 3 047 590 two full nodes, two SCD41, two heat pads, four servos
6 Forests in Space 1 718 757 basalt dust, 0.001 g scale; optional 1 kg LHS-1 simulant (≈ 650) not included
7 Hydroponic Jungle 2 131 702 LED panel, air pump, three peristaltic pumps, nutrients
8 Living Earth 2 066 862 SCD41, endoscope, observation tubes, tea bags, Berlese kit
9 Time Capsule 2 646 1 764 glazier lid, plinth hardware, RTC and SD logging, plants, capsule box; SCD41 deferred to 2027
Sum of ecosystem sub-BOMs 17 891 7 263 catalog parts inside these sums are the same parts as groups A–C above
8b Carnivorous Bog (alternative to 8) 1 358 570 only if chosen instead of Living Earth

6.4 Reconciliation with the approved ARCUB list

Every approved line, what this plan buys against it, and why. "Lot" lines in the proposal had no quantity; they are mapped to the consumables lines above.

Approved line (Annex 2) Approved qty This plan Change and reason
ESP32 development boards 12 12 ESP32 + 12 screw-terminal breakouts same count; breakouts added so final builds have no loose wires
BME680 T/RH/VOC sensors 9 2 BME680 + 8 SHT31 BME680 only where VOC is the science (Rot); SHT31 survives wet air
DS18B20 waterproof probes 9 15 two per tank where thermostat feedback or paired zones need them, plus spares
BH1750 light sensors 9 9 unchanged
Capacitive soil moisture v2 12 22 replicated plots and known batch defects
CO2 sensor breakouts (real CO2) 3 4 SCD41 Rot, Living Earth, 2026, 2056 (paired); Time Capsule deferred to 2027
Water-level sensors 3 10 floats + 2 ultrasonic floats are the interlocks, ultrasonic gives continuous level
Water-flow sensors 2 2 YF-S401 type fixed (YF-S201 cannot read these flows)
OLED displays 12 12 unchanged
microSD modules + cards 9 + 9 2 + 2 hub logging is primary; local logging only where independence matters
RTC modules 2 2 one per SD logger
Breadboards, jumpers, connectors, consumables (4 lots) 4 lots 1 electronics consumables line (466) prototyping kit kept; final builds use JST and screw terminals
Peristaltic dosing pumps 2 3 hydroponics A, B, pH-down
Submersible water pumps 2 5 EcoColumn rain, 2026 and 2056 irrigation, hydroponics circulation and top-up
Ultrasonic misting modules 2 2 unchanged; each with its own 24 V adapter
5 V / 12 V fans 4 6 six enclosures need ventilation control
SG90 microservos 4 8 Rot flap, EcoColumn valve, 2026/2056 gates, Living Earth lid, spare
MOSFET switching modules 6 27 25 PWM loads across nine ecosystems plus two spares; D4184 type only
Relay modules 4 6 low-voltage loads only
Grow lights (5–10 W) 4 4 reels of 12 V LED strip + 16 profiles + 1 LED panel eight enclosures need light; 5–10 W is not enough for any of them
Water reservoirs 4 5 + 3 opaque boxes one per automated water system
Silicone / PVC tubing 20 m 5 m silicone + 50 m PVC roll silicone only where needed
Sprayers, nozzles, connectors; valves (2 lots) 2 lots automation consumables line (213) mapped
Power supplies / adapters 4 9 × 12 V bricks + 2 × 5 V + 10 bucks nine nodes with 12 V loads
Automation cabling; automation spares (2 lots) 2 lots in electronics consumables and spare pool mapped
Glass-panel construction packs 9 packs 8 COTS glass tanks (1×25 L, 3×45 L, 4×54 L) + 1 opaque hydroponics box leak-tested tanks; the engineering is in lids and internals
Transparent acrylic / polycarbonate sheets 3 1 polycarbonate sheet (4 panels of 50×100) + 2 acrylic panels designs use about 6 panels
Fine insect / ventilation mesh 1 lot 2 m mapped
Small hinges 12 12 + 4 latches mapped
Handles / fasteners 1 lot in hinges line mapped
Cable glands 20 80 about 9 per node
Waterproof electrical connectors 1 lot in electronics consumables mapped
Aquarium-safe silicone 4 tubes 6 ten tanks, lids and dividers
Rigid acrylic / PVC tubes and fittings; mounting supports (2 lots) 2 lots mounting lot (222) mapped
Electronics project cases / junction boxes 6 9 one per node
Transparent perforated observation tubes 2 2 made from drilled PVC, costed in Section 5.8
Small tools 1 lot tools lot (300) + metrology kit (180) multimeters, drills, reference thermometer; pliers and screwdrivers from the school
pH / EC calibration and storage solutions 1 lot 2 sets + 2 pH kits + 1 TDS + 2 pH pens + 1 TDS pen + 2 turbidity probes were missing
Syringes; sample containers; labels (3 lots) 3 lots lab consumables line (165) mapped
Printed durable labels / information panels 1 lot 10 A3 laminated prints (100) mapped
microSD card for Raspberry Pi 1 Raspberry Pi 5 kit + 2 SD cards the computer was missing; nodes use the school Wi-Fi
(not listed) – heat pads, thermostats, air pump, smart plugs, RCD adapters, power strips, biology for nine ecosystems the living and the safety parts of the project

6.5 Procurement plan

When What Where Why
Tue 2026-10-21 Heat pads ×4, full-spectrum LED strip option, Kamoer peristaltic alternative AliExpress / Amazon.de 2–3 week lead time; nothing else may wait for China
Tue–Wed 2026-10-21/22 All electronics (group A), MOSFETs, bucks, bricks, boxes, glands optimusdigital.ro, cleste.ro, sigmanortec.ro, emag.ro Romanian stock, 2–5 day delivery; order from two shops for critical items
Wed 2026-10-22 Raspberry Pi 5 kit, SD cards, smart plugs, RCD adapters emag.ro, pcgarage.ro hub must be up by 2026-10-30
Thu 2026-10-23 Tanks, polycarbonate, silicone, mesh, hinges, tools, substrates hornbach.ro, dedeman.ro, leroymerlin.ro (store pickup) bulky; one van trip
Fri 2026-10-23 noon "China fallback" check: anything not confirmed in a Romanian shop is ordered abroad the same day with a local substitute – see Chapter 7
2026-11-03 to 11-10 Live organisms (worms, springtails, isopods, snails, aquarium plants), hydroponic nutrients, seeds OLX breeders, secretgarden.ro, hornbach.ro, grow shops ship live animals before mid-November cold; substrates must be ready first
2026-11-20 Glazier order for the Time Capsule lid local glazier needed by 2026-12-01

Invoices: keep a mapping from each approved line to the actual invoice line (table 6.4 is that mapping). Confirm with ARCUB whether foreign marketplace invoices (AliExpress, Amazon.de) are eligible before placing them; if not, the heat pads are the only item at risk, and the fallback is a 12 V PTC heater module from optimusdigital.ro when it is back in stock.

6.6 Cost reductions applied (2026-10-20)

Requested cuts and the further trims made in the same pass. Savings are against the first full costing; electronics prices are the provisional ones used in that costing.

Cut Saving (RON) What it costs the project
No NVMe drive or M.2 HAT for the Pi 200 SD-card wear risk; mitigated by nightly backups and a spare imaged card
No project router (school Wi-Fi used) 180 Depends on school IT providing a 2.4 GHz PSK SSID; fallback router stays on the list as optional
Time Capsule CO2 sensor deferred to 2027; no spare SCD41 440 The sealed-tank CO2 cycle is not recorded in year one; pod slot reserved
No spare BME680 75 –
RCD adapters 4 → 2; power strips 6 → 4; smart plugs 4 → 2; no separate timer plugs (Capsule keeps one) 574 Two shelf power groups instead of four; capsule light fail-safe unchanged
Spares trimmed: bricks 10 → 9, 5 V adapters 3 → 2, bucks 12 → 10, breakouts 12 → 10, MOSFET 30 → 27, relays 8 → 6, pumps 6 → 5, fans 7 → 6, DS18B20 16 → 15, soil 24 → 22, SD/RTC sets 3 → 2, TDS pen 2 → 1, calibration sets 3 → 2 596 Failures in these parts become a same-week purchase
Peristaltic pumps 4 → 3 (Capsule top-up by syringe) 135 Manual, which the ten-year design prefers anyway
Air pumps 2 → 1 102 EcoColumn pond is not aerated (its science does not need it)
LED strip 5 → 4 reels, profiles 18 → 16 132 None; 14 m are actually cut
No new shelving (existing school furniture, rated) 260 Must verify the furniture can carry 50 kg per tank
Time Capsule: existing cabinet instead of a new one, MARINA tank, one timer plug, laminated panel, plastic archive box, fewer jars, prints, cork, moss, cultures 1 466 Capsule total 4 112 → 2 646
EcoColumn: lighter shelving, strips plus one PO4 test, shared scale, consumables moved to the project lot 341 –
Hydroponics: panel hung from the shelf (no PVC frame), foil reflectors, shared scale and hole saw 215 –
Polycarbonate 2 sheets → 1 sheet + 2 acrylic panels 219 6 panels instead of 8
Tools and metrology: no crimp tool (pre-crimped leads), school pliers and screwdrivers 326 –
Electronics consumables lot trimmed 180 –
Printed panels: laminated A3 instead of foamboard 250 Upgrade later from the school budget
Glands 100 → 80, boxes 10 → 9, no spare 12 L tank, Brownfield optional biology, Rot BTI granules, Regolith feldspar, Living Earth desk lamp, Future pair spare scale 362 –
Total reduction ≈ 5 350 (25 625 → 20 269 at the provisional electronics prices; the final total with researched electronics prices is 20 989 RON) –

7. Programme: schedule, people, pedagogy, risks

Planning assumptions (confirm by Fri 2026-10-23)

# Assumption Confirm with If wrong
A1 Autumn break (vacanța de toamnă) for gimnaziu: Sat 2026-10-31 – Sun 2026-11-08. No sessions in that week. School secretariat / MEC structure order If liceu students are in school during that week, run one optional catch-up session (node soldering is not needed, so only kit sorting and planning)
A2 Winter break starts Sat 2026-12-19 and runs to about Sun 2027-01-10. Secretariat Showcase stays in the week of Dec 14–18 regardless
A3 Project sessions Tue and Thu, 14:00–15:30 (2 × 90 min per week) in the lab room. Both teachers Shift the day labels; the sequence stays the same
A4 Three Saturday build days, 09:30–15:30, with 2 Alacrity engineers present: Sat Nov 14, Sat Nov 21, Sat Dec 5. Head teacher (building access, caretaker) Move to the following Saturday. Nov 21 has no slack
A5 Mon Nov 30 (Sf. Andrei) and Tue Dec 1 (Ziua Națională) are public holidays. The Tue Dec 1 session moves to Wed Dec 2. Automated treatments can still start on Dec 1 through Home Assistant schedules. – –
A6 9 teams × 3–4 students (27–36 students), 2 teachers (T1 = project coordinator, biology/science; T2 = physics/ICT/technology), Alacrity engineers E1 + E2 at ~4 h/week each, plus the 3 build days. ARCUB contract / Alacrity With only one engineer, E1 covers sessions and the build days lose one adult. Keep the 1:8 ratio for tool work by adding T2
A7 ARCUB deliverables due Fri 2026-12-18. Public showcase Tue Dec 15 – Thu Dec 17. ARCUB contract (check the visibility clauses and the budget-line transfer threshold) –

Adult time budget, Oct 26 – Dec 18: E1 + E2 ≈ 2 × 4 h × 8 weeks = 64 h plus 3 build days × 2 × 6 h = 36 h. Total ≈ 100 h. The schedule below uses about 90 h, which leaves ~10 h as contingency.

Master schedule

gantt
    title MICROCOSM programme Oct 2026 - Jun 2027
    dateFormat YYYY-MM-DD
    axisFormat %d %b
    section School calendar
    Autumn break (assumed)            :done, cal1, 2026-10-31, 2026-11-09
    Winter break (assumed)            :done, cal2, 2026-12-19, 2027-01-11
    section Procurement
    Order electronics                 :crit, pr1, 2026-10-21, 3d
    Order tanks and materials         :crit, pr2, 2026-10-21, 3d
    Deliveries RO shops               :crit, pr3, 2026-10-26, 2026-11-07
    China fallback window             :pr4, 2026-10-23, 2026-11-20
    China fallback latest arrival     :milestone, pr5, 2026-11-20, 0d
    section Platform
    Hub setup                         :pl1, 2026-10-26, 2026-10-31
    Node v1 reference build and firmware :pl2, 2026-10-27, 2026-11-07
    Node kits handed to teams         :milestone, crit, pl3, 2026-11-09, 0d
    section Workshops
    W1 Kickoff and safety             :milestone, ws1, 2026-10-27, 0d
    W2 Ecosystem science design       :milestone, ws2, 2026-10-29, 0d
    W3 Node assembly                  :milestone, crit, ws3, 2026-11-10, 0d
    W4 ESPHome and dashboards         :milestone, crit, ws4, 2026-11-12, 0d
    W5 Design sprint (build day 1)    :milestone, ws5, 2026-11-14, 0d
    W6 Calibration lab                :milestone, ws6, 2026-11-17, 0d
    W7 Data analysis                  :milestone, ws7, 2026-12-03, 0d
    W8 Presentation skills            :milestone, ws8, 2026-12-08, 0d
    section Ecosystem builds
    Enclosures and substrates         :crit, eb1, 2026-11-09, 2026-11-21
    Instrumentation and commissioning :crit, eb2, 2026-11-16, 2026-11-28
    Biology established               :eb3, 2026-11-20, 2026-12-05
    section Experiments
    Baseline                          :ex1, 2026-11-23, 2026-12-05
    Treatments                        :ex2, 2026-12-01, 2026-12-19
    Data review                       :crit, ex3, 2026-12-07, 2026-12-12
    section Time Capsule
    Capsule design                    :tc1, 2026-11-23, 2026-11-28
    Capsule build                     :tc2, 2026-12-01, 2026-12-12
    Capsule sealed                    :milestone, tc3, 2026-12-14, 0d
    section Showcase and reporting
    Rehearsal                         :milestone, sh1, 2026-12-11, 0d
    Public showcase                   :crit, sh2, 2026-12-15, 2026-12-18
    ARCUB report submitted            :milestone, crit, sh3, 2026-12-18, 0d
    section Continuation
    Round 2 experiments               :co1, 2027-01-11, 2027-06-19
    Monthly data reviews              :co2, 2027-01-14, 2027-06-19

Week-by-week

Week Dates What happens Who Outputs Risks
W0 Tue Oct 20 – Fri Oct 23 Final BOM reconciliation against the ARCUB list. All RO orders placed Oct 21–23. Anything not in stock at an RO shop on Oct 23 goes to AliExpress the same day and a RO substitute is named. Teams formed. Parental consent and photo forms sent home. Room layout agreed: tank tables, mains shelf above, RCD strips. T1 (orders, forms), E1 (BOM, substitutes), head teacher (room) Purchase orders and pro-forma invoices; substitution log; team list; consent forms out Stock-outs (SCD41, cased SHT31, TL555 soil probes); slow invoice approval by the school bursar
W1 Oct 26 – Oct 30 Deliveries start. E1 obtains the 2.4 GHz WPA2-PSK SSID and reservations from school IT, sets up the Pi 5 with HA OS and add-ons, and a test dashboard. E2 builds one reference node (mc-00-ref) plus the ESPHome YAML templates. Tue Oct 27 W1 kickoff and safety. Thu Oct 29 W2 science design: each team drafts its question, hypothesis and variables. E1, E2, T1, T2, all students Hub online; mc-00-ref on the dashboard; signed safety pledge per student; draft experiment plan per team (1 page) School IT objects to the router; late tank delivery
W2 Nov 2 – Nov 6 (break) No student sessions. Remaining deliveries arrive. T1/T2 receive and check goods against invoices (proces-verbal de recepție). E1/E2 sort node kits into 9 labelled bags and bench-test every sensor on mc-00-ref; DOA parts go back for replacement. T1 (reception), E1/E2 (kit test, ~6 h) Goods-received log; 9 tested node kits plus spares; DOA list DOA sensors with no time to replace; capacitive probe batch defects
W3 Nov 9 – Nov 13 Mon Nov 9 kits issued. Tue Nov 10 W3 node assembly: students build their own node in an IP65 box on a screw-terminal board. Thu Nov 12 W4 ESPHome and HA: each team flashes its node and sees its own sensors. Teams clean tanks, cut and fit substrate layers and draw lid/vent designs. Tanks are placed on tables and never moved again. Students (build), E1 + E2 (mentor), T2 9 nodes reporting to HA (OLED shows IP + values); lid sketches; tanks in final position Wi-Fi or flash problems eat W4; absent students
W4 Nov 14 – Nov 20 Sat Nov 14 Build Day 1 (W5 design sprint): lids, vents and mounts from acrylic, mesh and hinges; substrates layered; glands drilled in the node boxes. Tue Nov 17 W6 calibration lab (soil probes per substrate, pH/EC pens, DS18B20 ice and room cross-check). Thu Nov 19 sensors installed in enclosures. Biology goes in from Nov 20: plants, decomposers, inocula. Students, E1 + E2 (Sat), T1 (biology sourcing) Lids and vents fitted; calibration table per probe in the Data folder; first plantings Glass breakage while drilling or fitting (no student glass cutting); plants not sourced
W5 Nov 21 – Nov 27 Sat Nov 21 Build Day 2: actuators (12 V pumps, fans, LED strips in profiles, heat pads with thermal fuse) wired SELV-side only. E1 places the mains-side COTS devices (bricks, smart plugs, LED panel, air pump) on the shelf with drip loops. Automations created in HA. Commissioning checklist signed per ecosystem by Fri Nov 27. Baseline logging starts Nov 23. Capsule Council designs the Time Capsule (Nov 23–27). Students, E1 + E2, T1/T2 Commissioning certificate × 9; HA automations; baseline running; Capsule design brief v1 Critical: any ecosystem not commissioned by Nov 27 cannot reach 2 weeks of data by Dec 11
W6 Nov 30 – Dec 4 Holidays Mon/Tue. Treatments switch on from Dec 1 (scheduled in HA, e.g. 2056 heat and drought profile, Brownfield salt dose) once a team has ≥ 7 days of clean baseline. Wed Dec 2 session (moved from Tue): role rotation 2, treatment checks. Thu Dec 3 W7 data analysis in Google Sheets on real CSV. Capsule build starts. Sat Dec 5 Build Day 3: Capsule build, fixes, panel drafts. Students, T1/T2, E1 + E2 (Sat) Treatment logs started; first chart per team; Capsule hardscape plus node Plant die-off from low light; gnats; heat-pad faults
W7 Dec 7 – Dec 11 Tue Dec 8 W8 presentation skills. Data review: each team picks one chart and writes its claim and evidence. Information panels sent to print Wed Dec 9 (latest). Capsule build finished. Fri Dec 11 rehearsal (full run, timed). Evidence folder checked against the ARCUB list. Students, T1 (print order), T2 (rehearsal), E1 (dashboard kiosk view, 2 h) 9 charts; 9 panels at the printer; showcase run-sheet; evidence folder ≥ 90 % complete Printer turnaround; missing consent forms block photos
W8 Dec 14 – Dec 18 Mon Dec 14 Time Capsule sealed (ceremony, logbook entry #1). Tue Dec 15 – Thu Dec 17 public showcase (2 h slots, teams present in rotation). Fri Dec 18 ARCUB final report and evidence pack submitted. Winter care rota and alerts tested. All; T1 (report), E1 (data annex, remote alerts) Showcase held; attendance list; final report; data export; winter rota Visitor accidents; report missing invoices
W9 Sat Dec 19 – ~Jan 10 (break) Winter care: automated light and irrigation; T1/T2 or the caretaker visit Mon + Thu (15 min checklist); HA alerts go to T1 and E1 by push or email. Restart Jan 11 with round 2 planning. T1/T2 (visits), E1 (remote monitoring) Visit log; no losses Power cut or Pi down over the break; dry-out

Critical path & slack

flowchart LR
    A["Orders placed Oct 21-23"] --> B["Electronics delivered by Nov 6"]
    B --> C["Kits tested and issued Nov 9"]
    H["Hub Oct 26-30"] --> D
    C --> D["W3 node assembly + W4 ESPHome Nov 10-12"]
    A --> E["Tanks and materials by Nov 6"]
    E --> F["Enclosures and substrates Nov 9-20"]
    D --> G["Instrumentation and commissioning by Nov 27"]
    F --> G
    F --> I["Biology in from Nov 20"]
    G --> J["2 weeks of data Nov 28 - Dec 11"]
    I --> J
    J --> K["Data review and one chart per team Dec 7-11"]
    K --> L["Showcase Dec 15-17"]
    L --> M["ARCUB report Dec 18"]

Gates and slack

Gate Gated by Gates Slack If it slips
G1 Orders placed BOM sign-off Oct 21 All of it 0 days Every day lost here comes straight off the data window
G2 Electronics delivered (ESP32, terminal boards, OLED, SHT31, DS18B20, BH1750, soil probes, boxes, glands, bricks, buck, MOSFET) G1 Kit test (Nov 2–6), W3 Nov 10 ~3 days (kits can be tested Mon Nov 9 morning) Teams assemble with whatever has arrived; missing sensors are added as plug-in screw-terminal connections later
G3 Hub online Pi 5, SD64, Wi-Fi credentials from IT W4 Nov 12 ~9 days Fallback is W4 on a laptop running the ESPHome dashboard with the router only, then migrate to the Pi
G4 Tanks + acrylic + mesh + silicone G1 Enclosures Nov 9 ~5 days (substrate prep and lid design can start without tanks) Start substrates in buckets; silicone needs 24–48 h cure before water or substrate goes in
G5 Commissioning ×9 G2, G3, G4, W6 calibration Data window ~2 days (latest Sun Nov 29 for 14 full days to Dec 12) Drop that team's actuators. Commission sensors only (minimum viable)
G6 Biology alive Plant/organism sourcing (order by Nov 13), enclosures Treatments, panels ~5 days for the MVS (only "alive") Use garden-centre plugs (Dedeman/Hornbach) instead of seeds; cress and radish give a visible result within 5–7 days
G7 Panels printed Chart + text by Dec 9 Showcase ~2 days Print A3 on the school laser printer, laminate
G8 Report Evidence folder kept live from Oct 21 ARCUB ~1 day Do not leave the evidence collection for Dec 18

China fallback rule (binding)

  1. On Fri Oct 23 at 12:00, E1 checks every BOM line. Any item not orderable in stock from a RO shop (optimusdigital, cleste, ardushop, robofun, sigmanortec, emag) is ordered on AliExpress the same day, choosing "Choice" or EU-warehouse offers where they exist.
  2. At the same time a RO substitute is named and bought, so that the build never waits for China. Typical pairs:
Missing item RO substitute used meanwhile Swap-in
SCD41 Run respiration ecosystems without CO2. BME680 gas resistance as a qualitative indicator (labelled "not CO2") When it arrives; 1 week of re-baseline
Cased SHT31 Bare SHT31-D breakout behind a PTFE vent plug or in a perforated tube, mounted high January
Capacitive v2.0 with TL555 Any v1.2/v2.0 probe in stock, each one tested on mc-00-ref (dry/wet reading spread > 800 counts) January (re-calibrate)
JSN-SR04T 2 float switches only (low/high) January
YF-S401 Pump runtime × flow measured by a bucket test (L/min) January
TERMBOARD DevKitC on a perfboard with screw terminal blocks (E-supervised) When it arrives, before final mounting
PERI Manual dosing with a syringe, logged in HA via an input button January
  1. Latest useful arrival is Fri Nov 20. Anything arriving later is installed in January. The substitute stays for the showcase.
  2. AliExpress orders: keep each order < 150 EUR (IOSS, VAT charged at checkout, no customs hold). Download the invoice PDF straight away. Check with ARCUB whether foreign marketplace invoices are eligible. If they are not, the fallback is paid from Alacrity's own contribution or bought from Amazon.de with an invoice on the school's fiscal code (CIF).

Minimum viable showcase (MVS)

The ARCUB deliverable is met if, on Dec 15:

# MVS criterion Evidence
1 All 9 ecosystems built, alive and instrumented (≥ 1 T/RH or DS18B20 + 1 soil or water sensor reporting) Photos; HA "all nodes online" screenshot
2 Hub dashboard live (Grafana or HA kiosk on a screen) Live demo + screenshot
3 ≥ 14 days of continuous data per ecosystem (Nov 28 – Dec 11) CSV export in Drive
4 Each team presents one chart with a claim Panel + slide
5 Safety documentation complete Signed pledges, incident log, commissioning checklists

Can slip to January without hurting the deliverable: SCD41-based respiration experiments, peristaltic dosing automation, EcoColumn flow and turbidity, servo vents/gates, the Time Capsule's long-term alerting beyond the basics, Arduino/PlatformIO work on spare boards, statistical replication (round 2), full treatment phases (a treatment that started Dec 1–7 with partial data still counts), and any AliExpress-dependent sensor.

Cannot slip: G1, G5, the panels, the evidence folder, the Capsule sealing (it is the showcase's public moment). If the Capsule is late it is sealed "planted but unsealed" with a lid ceremony in January. That is acceptable, but avoid it.

Team structure & roles

Per-team roles (each team of 3–4; rotate monthly)

Role Does Weekly time Rotation
Lead Scientist Owns the question, hypothesis, variables and controls; keeps the experiment plan current; writes the claim for the chart In sessions Rotation 1: Oct 27 – Nov 27. Rotation 2: Dec 2 – Jan 29 (stable through the showcase). Then monthly
Lead Engineer Owns node, wiring (SELV only), ESPHome YAML, lids/vents/mounts; runs the commissioning checklist In sessions + build days Same
Data Steward Checks the dashboard every session, flags gaps, exports CSV, keeps the calibration table and the data dictionary 10 min per session Same
Biology Keeper Watering/feeding schedule, plant/organism health log, pest checks, photo of the ecosystem every session from a fixed spot (same angle) 10 min per session Same. In 3-person teams the Lead Scientist also acts as Biology Keeper

Rule: every student must hold the Lead Engineer and the Lead Scientist role at least once by June. The rotation handover is a 10-minute "role card" briefing, and the outgoing holder signs the handover in the lab notebook.

Cross-team roles

Role Who Does Doesn't
Hub Admins ×2 2 students (1 liceu + 1 gimnaziu ideally), mentored by E1 Add nodes to HA, manage dashboards, check the nightly CSV export, keep the IP/lease table, run the weekly backup check Touch the router admin password or remote access (E1 only); edit another team's YAML without the team present
Safety Officers ×2 2 students, mentored by T2 Run the 2-minute safety check at the start of every session (drip loops, RCD test button monthly, no water near the mains shelf, PPE out), keep the incident log, may stop any activity Fix electrical faults (they report to an adult)
Capsule Council 1 delegate per team (9) + T1 as chair Design brief, species choice, longevity rules, Capsule Charter, logbook, sealing ceremony, Jan handover to the younger cohort Decide alone; decisions go by majority vote, recorded in minutes

Adult roles

Adult Does Doesn't
T1 Teacher-coach (coordinator) Programme lead; procurement and invoices; consent; biology sourcing; assessment; ARCUB report; asks questions ("what would convince you?") Write students' hypotheses or conclusions
T2 Teacher-coach (technology) Supervision of tools and SELV wiring; safety lead; rehearsal; second marker Wire or assemble nodes for teams
E1 Alacrity engineer-mentor (platform) Wi-Fi access with school IT, Pi/HA setup, reference node, YAML templates, all mains-side placement (COTS bricks, smart plugs, LED panel, air pump on the shelf, RCD strips), remote alerts, data annex Build team nodes; debug by taking the keyboard (the rule is hands behind the back: explain, point, let the student do it)
E2 Alacrity engineer-mentor (sensors/actuators) Kit testing, calibration lab, actuator/MOSFET review, heat-pad safety sign-off, design sprint coaching Same as E1
Any adult Glass cutting or drilling glass (if needed at all), mains-side setup, final sign-off of the commissioning checklist Anything else students can do safely themselves

RACI for main deliverables

R = does the work, A = accountable (one per row), C = consulted, I = informed.

Deliverable Team (students) Hub Admins Safety Officers Capsule Council T1 T2 E1 E2
Procurement & substitution log I I – – A/R C R C
Pi + HA platform + Wi-Fi access I R – – I I A/R C
Reference node + YAML templates I C – – I I R A/R
Team node (assembled, flashed) R C C – I A C C
Enclosure, lid, vents, substrate R – C – C A I C
Mains-side installation I I C – I C A/R C
Calibration tables R C – – I C C A
Commissioning checklist ×9 R C C – I A C R
Experiment plan + lab notebook R – – – A C I I
Data export + charts R R – – A C C I
Time Capsule C C C R A C C C
Safety pledge, incident log C – R – I A I I
Information panels ×9 R – – C A C C I
Showcase R R R R A R C C
ARCUB report + evidence pack C C C C A/R R R C

Workshop sequence

Workshops W1–W4 and W6–W8 take a full 90-min session unless stated. W5 runs inside Build Day 1.

# Date Title Duration Objectives Materials Activities Output
W1 Tue Oct 27 Kickoff, safety & electricity basics 90 min Know the 10 wall rules; tell SELV from mains; know why water + mains is the hazard; know the stop word Wall-rules poster (A2), RCD strip, 12 V brick, multimeter, 9 V battery + LED, PPE samples, safety pledge form 15' project tour and the 9 ecosystems; 20' "voltage ladder" demo (3.3 / 5 / 12 V measured with a multimeter by students; 230 V shown only as a sealed COTS brick); 20' hazard hunt in the room (find 5 planted hazards); 20' teams formed, roles assigned; 15' pledge signed Signed pledge per student; team + role list
W2 Thu Oct 29 Scientific method applied + ecosystem science design 90 min Write a testable hypothesis; name IV, DV and controlled variables; plan a control and replicates Driving-question cards, lab notebook template, variable worksheet, example dataset 15' "good vs bad hypothesis" sort; 30' each team turns its driving question into a hypothesis plus an IV/DV/controls table; 20' peer critique (2 teams pair up); 25' first draft of the experiment plan (1 page) and first notebook entry Experiment plan v1; notebook started
W3 Tue Nov 10 Node assembly 90 min Assemble an ESP32 node on a screw-terminal board in an IP65 box; route cables through glands; check polarity with a multimeter Team kit bag (ESP32, TERMBOARD, OLED, SHT31/BH1750, DS18B20, SOIL, BOX, GLAND, pre-crimped JST/Dupont leads, BUCK pre-set to 5.0 V by E2), screwdrivers, wire strippers, labels 10' tour of the reference node; 50' assembly following the pin-map card (GPIO 21/22 I2C, 4 1-Wire, 32–35 soil); 15' multimeter checks (3.3 V, 5 V, no shorts); 15' label every cable at both ends 9 assembled nodes, labelled
W4 Thu Nov 12 ESPHome & Home Assistant basics 90 min Flash a node; read YAML; add a sensor; see it on the dashboard Laptops/Chromebooks with Chrome (ESPHome Web), USB cables, YAML template per node (mc-0X-*), HA user per team 15' what YAML is; 25' flash the base template (Wi-Fi + OLED + one sensor); 25' add a second sensor by editing YAML (e.g. BH1750), reflash OTA; 15' build the team's dashboard card in HA; 10' Data Steward exports the first CSV Each node online with ≥ 2 sensors; team dashboard card
W5 Sat Nov 14 (Build Day 1) Engineering design sprint (lids, vents, mounts, cable routing) 2 × 90 min within the build day Requirements → sketch → prototype → test → iterate Acrylic 3 mm, scoring knife, mesh, hinges, silicone, cardboard for mock-ups, cut-resistant gloves, requirements card 20' write 5 requirements (e.g. "RH > 80 %", "lid opens with 1 hand", "no water on node box"); 20' 3 sketches each, pick 1; 60' cardboard prototype; 30' test against the requirements (mist test, open/close 20×); 40' acrylic version Design sheet (requirements, sketches, test results); fitted lid/vent
W6 Tue Nov 17 Calibration lab 90 min Understand that a sensor gives a number, not the truth; do a 2-point calibration; record uncertainty Substrate samples in cups (dry / field-wet / saturated), ice water + room water, pH 4/7/10 and EC 1413 solutions, PHPEN, TDSPEN, reference thermometer Station rotation, 20' each: (1) soil probe raw value in air / dry / saturated per team substrate → map to 0–100 %; (2) DS18B20 vs reference in ice water and room water → offset; (3) pH/EC pen calibration + 1:5 soil extract; 30' enter calibrations in YAML (calibrate_linear) Calibration table per probe (date, raw, reference, offset); YAML updated
W7 Thu Dec 3 Data analysis in Google Sheets 90 min Import CSV; plot a time series; compare treatment vs control; mean, SD, paired comparison; what "significant" means at school level Team CSV (≥ 10 days), Sheets template with formulas, worked example 15' import + clean (timestamps, units); 20' line chart; 20' daily means, AVERAGE, STDEV; 20' compare two conditions: difference in means vs SD; paired differences day by day (e.g. 2026 vs 2056 same day) and how many days out of N go the same way; 15' school-level rule: "a difference is convincing if it is bigger than about 2 × SD of the day-to-day noise and shows up in most replicates or days. Otherwise we say 'no clear difference yet'" One chart + one sentence claim per team
W8 Tue Dec 8 Presentation skills for the showcase 90 min Tell a 3-minute story: question → what we built → what we saw → what we would do next Panel draft, timer, chart printout 15' structure (Claim–Evidence–Reasoning); 30' each team drafts its 3-minute talk with everyone speaking; 30' practice in pairs of teams with feedback (2 stars + 1 wish); 15' visitor Q&A practice ("what went wrong?") Talk script; speaker order

The 10 wall rules (A2 poster at the door, read aloud at W1 and on every build day):

  1. Only adults touch anything that plugs into the wall. Students work only on the 12 V side.
  2. Every mains device lives on the shelf above, never on or under a tank table.
  3. Every cable has a drip loop. If you see a cable without one, stop and tell an adult.
  4. No water within 1 m of the mains shelf. Fill and drain at the sink, using a jug.
  5. Unplug the 12 V brick before you touch wiring. Plug it back in only after a partner checks.
  6. Hands dry before electronics, gloves on before soil, compost or solutions.
  7. Goggles for cutting, drilling, solutions and anything that can splash.
  8. Nobody cuts glass. Broken glass: step back, call an adult, use the dustpan, not hands.
  9. Anyone can say "STOP", and everyone stops.
  10. Every incident, spill or near miss is logged the same day, with no blame.

Pedagogy & assessment

Learning outcomes and observable indicators

Outcome Observable indicator (what an adult can see or tick) Evidence
Agency Student proposes a change unprompted; takes and hands over a role; fixes or escalates a problem without waiting; asks for help with a specific question ("I measured 0 V at GPIO 32; is the probe dead?") Notebook entries, role handover sign-off, adult observation sheet (weekly, 1 line per team)
Scientific thinking Writes a hypothesis with a direction and a reason; names IV, DV and ≥ 3 controls; uses a control or a paired comparison; distinguishes noise from effect; reports a null result honestly Experiment plan, chart + claim, data review
Engineering design Writes measurable requirements; produces ≥ 2 alternatives; tests a prototype against requirements; documents an iteration with a reason Design sheet, commissioning checklist, photos of v1/v2
Collaboration & communication Every member can explain the system; talk is shared; feedback given and used Rehearsal checklist, showcase

Lab notebook template (one Google Doc per team + paper notebook at the tank)

Field Example
Date / time / session # 2026-11-24 14:05, S10
Who was present / roles today Ana (LS), Mihai (LE), Ioana (DS), Radu (BK)
Observation (what we saw, not what we think) "Fungus gnats ×4 on yellow trap; condensation on lid 3/4 of area"
Measurements (sensor + manual) Dashboard: RH 94 %, soil A 62 %; PHPEN 6.8
Photo ID (fixed-angle photo) IMG_mc04_20261124.jpg
Actions / interventions (time-stamped) 14:20 watered 50 mL, recorded via HA input button
Changes to setup (hardware/software) YAML v1.3: soil A calibration updated
Problems & how we handled them "Node offline 03:00–07:00, power strip switched off by cleaner. Added label."
Question / idea for next time "Is RH above 90 % causing mould on the cress?"
Next steps + owner Mihai: vent test Thu
Signature of note-taker –

Experiment-plan header (front page, updated when it changes): driving question, hypothesis ("If … then … because …"), IV / DV / controlled variables, control or comparison, replicates (n), measurement schedule, safety notes, version + date.

Team project rubric (4 criteria × 4 levels)

Criterion 1 Beginning 2 Developing 3 Secure 4 Excellent
Scientific process Question unclear; no variables named Hypothesis present; variables partly named; no control Testable hypothesis; IV/DV/controls; control or comparison used As 3, plus replication or paired design, limitations stated, next experiment proposed from the result
Engineering design Built as told; no requirements Some requirements; one design; informal testing Measurable requirements; tested against them; ≥ 1 documented iteration As 3, plus trade-offs explained, reliability or safety improvement evidenced by a test
Data & evidence No data used Chart shown, no claim, or claim not supported Clean chart with units; claim matches data; noise acknowledged As 3, plus mean/SD or paired comparison, a correct "no clear difference yet" call where needed, calibration referenced
Documentation & communication Sparse notebook Notebook irregular; talk read from notes Notebook every session; clear 3-minute talk, everyone speaks As 3, plus failures documented with causes and fixes; answers visitor questions with evidence

Scoring rule: results don't score; process does. A treatment that killed every plant, or a sensor that failed, scores 4 on "Data & evidence" if the team detected it, explained it with evidence and proposed a fix. A team that "proves" its hypothesis with an uncontrolled comparison scores at most 2. Assessment is formative until January (feedback only). The first graded checkpoint is the showcase, the second is the June review.

Driving questions (one per ecosystem)

# Ecosystem Driving question
1 The Orchestra of Rot Which organic materials do our decomposers recycle fastest, and what conditions make the system most efficient?
2 The Domino Effect, EcoColumn How does rain on bare vs protected soil move sediment and fertiliser into the water, and can a natural filter stop the algal bloom?
3 Toxic Ground, Brownfield How do salt, pH change, heat and compaction damage a soil, and which restoration helps life come back?
4 Future 2026 How does today's ecosystem respond under current Bucharest-like conditions (our control)?
5 Future 2056 What happens to the same ecosystem under 2056-style heat, drought, extreme rain and elevated CO2, and which intervention makes it more resilient?
6 Forests in Space Can plants establish in a lunar-like mineral substrate, and what is the least we must add to make it a viable growing medium?
7 The Hydroponic Jungle How do nutrients, aeration and light affect plant growth without soil, and can we automate a stable system?
8 The Living Earth How much life (respiration, invertebrates, roots, water retention) is in healthy vs degraded soil, and which method restores it fastest?
8b The Carnivorous Bog (alt.) How do sundews catch prey and survive in nutrient-poor water?
9 The Time Capsule How do we design an ecosystem that stays alive and observable for 10 years, and what will change in it?

Keeping educational outcomes ahead of scientific results

Younger cohorts from January and the Time Capsule handover

When What
Jan 12 – Feb 5 Each team adopts 2–3 "apprentices" (grade 5–6). Apprentices shadow the Biology Keeper and Data Steward roles and are trained with the role cards.
Feb Apprentices run the weekly Capsule check under supervision; first entry in the Capsule logbook in their own handwriting.
Mar – Apr Mixed teams for round 2: apprentices take Biology Keeper, current students take Lead roles.
May Capsule handover ceremony: the outgoing Capsule Council briefs the incoming one (apprentice delegates); signs the Capsule Charter; hands over the logbook, maintenance card, spares box and HA access for 2 new Hub Admins.
Every December (2027–2036) "Capsule Day": annual photo from the fixed angle, data export, logbook entry, maintenance (spare node swap if needed).

Capsule handover kit: Capsule Charter (rules: what may never be added or removed), species list with Latin names, maintenance card (weekly / monthly / yearly tasks), spare node pre-flashed (mc-09-capsule-spare), spare SD card, printed YAML + wiring diagram, logbook, password envelope sealed with the head teacher.

Risk register

L = likelihood, I = impact, each rated H / M / L.

ID Risk L I Mitigation Owner Trigger
R01 Delivery delays from RO shops (stock "in 5–7 days" turns into 3 weeks) M H Order Oct 21–23; prefer "în stoc" items; split across 2 shops for critical parts (ESP32, SHT31, DS18B20); call the shop on day 3 if not shipped T1 + E1 Item not shipped by Oct 28
R02 Customs/VAT and invoice eligibility for China orders M M Orders < 150 EUR (IOSS); download invoices; confirm ARCUB eligibility; RO substitute in parallel (China fallback rule) T1 Parcel held by customs; ARCUB rejects invoice
R03 School IT cannot provide a 2.4 GHz WPA2-PSK SSID for the nodes (enterprise-only Wi-Fi, captive portal, MAC filtering) M M Ask IT in writing by Oct 23 for a 2.4 GHz WPA2-PSK SSID, 12 DHCP reservations and the Pi reachable from student devices. If refused, buy the fallback router (≈ 160 RON) the same day and run an isolated project network as the platform chapter describes. E1 IT objection or WAN port blocked
R04 Power cuts or someone switches off the strip M M Nodes reconnect automatically; heat pad/pump restore_mode: ALWAYS_OFF; HA backup nightly; label "DO NOT SWITCH OFF" on the strips; optional small UPS (~400 RON, ~80 EUR, emag.ro) for Pi + router E1 Node offline > 30 min (HA alert)
R05 Water damage (leak, overflow, spill on electronics) M H Rules 2–4; node boxes above the water line; glands; trays under tanks; float-switch high cut-off on pump-fed systems; leak test 24 h with water before electronics are fitted T2 Water on table or floor; float high alarm
R06 Mould/odour complaints (Rot, Living Earth) M M No meat/dairy/cooked food; charcoal-filter vent fan; lid closed; weekly sniff test; BME680 gas trend alert; remove mouldy items in a sealed bag Team 1 Biology Keeper + T1 Complaint from staff; visible fuzzy mould outside the intended substrate
R07 Pests: fungus gnats, mites, fruit flies H L Yellow sticky traps in every enclosure; 1 cm sand top-dressing; let the surface dry between waterings; Bti (mosquito dunks) in the watering water; mesh on vents; quarantine new soil for 3 days Biology Keepers > 5 gnats per trap per week
R08 Plant die-off in winter light (Bucharest ~9 h daylight in December) H M 12 V LED strips 12–14 h photoperiod via HA schedule; shade-tolerant species; spare seedlings; never rely on window light; BH1750 check that lux > 5 000 at the canopy T1 + teams Lux < 2 000 at the canopy or wilting > 20 % of plants
R09 Sensor failures or drift M M Bench test in W2; spares (3 nodes, extra probes); calibration log; monthly cross-check against handheld pens and the reference thermometer; HA "unavailable" alert E2 + Data Stewards Flatline > 2 h or step change > 3 SD
R10 Capacitive probe batch defects (no TL555, wrong regulator, top-edge corrosion) H M Buy "v2.0 TL555" version; test every probe dry/wet before issue; reject spread < 800 counts; seal the top edge with heat-shrink + conformal coat; 24 bought for 18 used E2 > 3 probes fail the bench test
R11 SCD41 auto-self-calibration (ASC) drifts in closed tanks (ASC assumes weekly fresh-air ~420 ppm) H M automatic_self_calibration: false in ESPHome; forced recalibration at an open window (420 ppm) at commissioning and monthly; record in the calibration log E2 CO2 baseline < 400 ppm or slow downward creep
R12 Student absence (autumn break, illness, other commitments) M M Break falls before biology; role cards and notebooks allow handover; teams of 4 where possible; every task has a named backup T1 < 50 % of a team present twice in a row
R13 Teacher time overload (T1 carries procurement + report + teaching) H H E1 drafts BOM/orders and the data annex; Hub Admins and Data Stewards do routine work; ARCUB evidence collected weekly (15 min Fridays) rather than at the end Head teacher T1 misses 2 weekly status reports
R14 Alacrity time (4 h/week insufficient in W3–W5) M H Front-load: hub and reference node before break; templates for all 9 YAMLs ready Nov 9; the 3 build days carry the peak; contingency ~10 h Alacrity lead E1/E2 hours > 120 % of plan by Nov 20
R15 ARCUB reporting evidence incomplete (missing attendance, invoices, photos, visibility) M H Evidence folder from day 1; attendance sheet every session; ARCUB logo on panels, posters, posts; weekly evidence check against the list T1 Folder < 70 % complete on Dec 4
R16 Data loss (Pi SD corruption, Drive sync failure) M H A2 SD; HA backup nightly to Drive; nightly CSV export via rclone; weekly test restore of one CSV; spare SD64 pre-imaged; Time Capsule node logs locally to microSD Hub Admins + E1 Backup or export missing 2 nights in a row
R17 Vandalism / accidents (bumped tanks, curious visitors, cleaning staff) L H Locked room outside sessions; tanks on stable tables, back against the wall; showcase with a rope line and student guides; brief the cleaning staff Head teacher + T2 Any damage incident
R18 Glass breakage (tank dropped, lid fitting, drilling) L H COTS tanks; no student glass cutting/drilling; carry tanks with 2 people; foam mat under tanks; cut-resistant gloves for handling; broken-glass kit (dustpan, thick bag) T2 Crack or chip noticed
R19 Heat-pad overheating L H 12 V pads only; DS18B20 thermostat loop on the ESP32 (not via HA); max PWM 60 %; hardware thermal fuse (~72 °C) in series; pad off if the sensor is unavailable > 60 s; pad never under substrate without an air gap E2 Pad surface > 40 °C or substrate > setpoint + 5 °C
R20 pH-down / chemical handling (hydroponics, Brownfield) L M Use citric acid solution (pre-diluted by T1, labelled) instead of concentrated phosphoric acid; small dropper bottles; goggles + nitrile gloves; nutrient concentrate stored in a locked cabinet; SDS kept in the folder T1 Spill or skin contact
R21 Scope creep (too much automation, every sensor at once) H M Feature freeze for the MVS on Fri Nov 13: only the sensors and actuators in the commissioning checklist; everything else goes on a "January list" E1 + T1 New feature requested after Nov 13
R22 "ChatGPT plan" ambiguity (approved items without specs, e.g. "glass-panel construction packs", "grow lights 5–10 W") H M Reconciliation table: each approved line → concrete spec + catalog ID + reason for change; T1 confirms with ARCUB in writing before invoices; keep a change log T1 + E1 ARCUB queries a line, or an invoice does not match a line name
R23 Budget overrun ±20 % M M 10 % contingency line; price basis recorded per item; cheaper RO alternatives listed; reallocation between lines within the contract threshold (confirm %); scope cuts from the "January list" first T1 Committed spend > 90 % of a line
R24 Photo/consent gaps block showcase documentation M M Consent forms out in W0; tracker; non-consented students wear a coloured lanyard and are photographed from behind / hands only T1 Form missing on Dec 7
R25 Holiday-period failure (Dec 19 – Jan 10) M H Visit rota Mon + Thu; remote alerts; automated light/water; 3-week water reservoirs; no new treatments after Dec 14 T1 + E1 Alert unacknowledged > 24 h

Safety & compliance

Safety protocol summary

Domain Rules (binding)
Electrical Students work only on SELV ≤ 12 V DC (24 V DC for the mister, behind its own adapter). All 230 V exists only inside certified COTS products with their own cord and plug. Mains devices go on the shelf above and away from water, with a drip loop on every cable, on a 30 mA RCD-protected strip. Mains is switched only through certified COTS smart plugs, never bare relays. Nothing mains-powered inside an enclosure, in water or in substrate. Every 12 V brick is a certified adapter. Unplug before rewiring; buddy check before re-power. RCD test button pressed monthly (logged).
Water Node boxes outside enclosures, above the water line, cables through glands. Fill and drain at the sink with a jug. Trays under tanks. 24 h leak test before electronics. Spills mopped immediately; floor sign if wet.
Biological Gloves for compost, soil and organism work; hand-washing after every session; no toxic plants; no vertebrates; no wild-collected soil from contaminated sites; mould removed in sealed bags; anyone with allergies or asthma informs T1 and is excused from Rot/compost handling.
Chemical Brownfield "contamination" = table salt, vinegar/baking soda, compaction, heat only. No heavy metals, no real pollutants. pH-down = pre-diluted citric acid. Calibration solutions and nutrients in labelled bottles, locked cabinet, SDS on file. Goggles + gloves for all solutions.
Glass & tools No student glass cutting or glass drilling (adults only, if at all). Acrylic scoring with a steel rule and cut-resistant gloves; goggles for cutting and drilling. Hand tools signed out and back in; hot-glue at a fixed station; no soldering by students in the build phase (pre-crimped and screw terminals), except optional supervised soldering in January on spare boards with a fume extractor.

Supervision ratios

Activity Ratio (adult : students) Notes
Normal session (observation, data, planning) 1 : 18 2 teachers for the whole group
Tool work (acrylic, drilling plastic boxes, screwdrivers) 1 : 8 Build days: T1, T2, E1, E2 = 4 adults for ≤ 32 students
Node power-up / first 12 V connection 1 adult per active bench Buddy check + adult nod before plugging in
Solutions / chemicals 1 : 6 At the designated wet bench only
Mains-side placement Adult only Students out of the shelf zone
Showcase 1 adult per 3 ecosystems + student guides Rope line; no touching tanks

PPE list (quantities for 36 students + 4 adults)

Item Qty Use
Safety goggles (EN 166) 20 Cutting, drilling, solutions
Nitrile gloves, M/L boxes of 100 4 boxes Soil, compost, solutions
Cut-resistant gloves (EN 388, level C) 8 pairs Acrylic scoring, tank handling
Lab aprons 12 Wet bench, substrates
Dust masks FFP2 1 box of 20 Dry substrate mixing (regolith simulant, perlite, vermiculite)
First-aid kit + eye-wash bottle 1 + 2 Lab
Broken-glass kit (dustpan, brush, thick bag, label) 1 Lab
Fire blanket + CO2 extinguisher (school-provided, check date) 1 + 1 Lab

Incident log (Google Sheet + paper copy on the wall)

Fields: ID · date/time · location/ecosystem · who was involved (initials) · what happened · type (injury / near miss / spill / electrical / glass / biological / equipment damage) · immediate action · adult informed (name) · root cause · corrective action + owner + date · parents informed (Y/N, by whom) · closed (date). Reviewed every Friday by the Safety Officers + T2. Any injury: head teacher and parents informed the same day.

ARCUB evidence (likely required; confirm against the financing contract)

Evidence Source When collected
Fiscal invoices + payment proof (OP / card statement) for every item T1 At purchase
Goods-received records (proces-verbal de recepție) + reconciliation table (approved line → purchased item) T1 + E1 On delivery
Attendance lists per session (date, names, signatures) Teachers Every session
Dated photos: before / during / after per ecosystem, workshops, build days, showcase Biology Keepers + T2 Weekly + events
Outputs: experiment plans, notebooks (scans), design sheets, calibration tables, CSV data export, dashboard screenshots, panels (PDF) Teams + Hub Admins Weekly
Visibility proof: ARCUB logo on panels, invitations, posts; screenshots of posts T1 When published
Showcase: invitation, visitor count / sign-in sheet, programme, photos T1/T2 Dec 15–17
Narrative + financial report T1 + E1 Dec 18

Evidence folder structure (inside the shared Drive, 06_ARCUB_Evidence/)

06_ARCUB_Evidence/
  01_Contract_and_budget/        contract, annexes, approved budget, change requests
  02_Procurement/
    2026-10-21_optimusdigital_INV-xxxx.pdf   (one file per invoice, prefixed by date)
    payments/                    OP / statements
    receipts_PVR/                proces-verbal de recepție, signed
    reconciliation.xlsx          approved line → item → invoice → RON
  03_Attendance/                 YYYY-MM-DD_session-NN.pdf
  04_Photos/
    by_ecosystem/mc-01 ... mc-09/  YYYYMMDD_mcXX_fixed.jpg
    events/W1_kickoff/ ... showcase/
  05_Outputs/                    plans, notebooks, design sheets, calibration, panels, data exports
  06_Visibility/                 logo usage, posts, invitations
  07_Showcase/                   programme, sign-in sheets, feedback forms
  08_Safety/                     pledges, incident log, commissioning checklists, RCD tests
  09_Consent/                    consent forms (restricted access: T1 + head teacher only)
  10_Final_report/               narrative report, financial report, annexes

Communication & documentation

Shared drive structure (school Google Workspace, owner T1, Alacrity as editors)

MICROCOSM/
  00_Admin/                  contacts, calendar, weekly status reports, minutes
  01_Plan/                   this plan, BOM, pin map, substitution log, change log
  02_Platform/               network table (IPs, leases), HA backups, YAML (one folder per node), wiring diagrams
  03_Teams/
    mc-01-rot/ ... mc-09-capsule/
      plan/                  experiment plan (versioned), design sheets
      notebook/              lab notebook doc + scans
      data/                  calibration table, team charts
      photos/                fixed-angle series
  04_Data/
    csv_nightly/             YYYY-MM-DD_all-nodes.csv (rclone export)
    data_dictionary.xlsx     entity id, unit, calibration, valid range
  05_Workshops/              slides, worksheets, role cards, rubric, wall rules
  06_ARCUB_Evidence/         (see above)
  07_Showcase/               panels (source + PDF), talk scripts, run-sheet
  08_TimeCapsule/            charter, species list, maintenance card, logbook scans, council minutes

Naming rule: YYYY-MM-DD_<node>_<what>_v<N> (e.g. 2026-11-17_mc-04_soilcal_v1.xlsx). No spaces, no diacritics in file names.

Weekly status (10 lines, T1 posts every Friday by 16:00 in 00_Admin/status/, sent to E1, E2, head teacher)

1. Week / dates:
2. Overall: GREEN / AMBER / RED (one reason)
3. Done this week (max 3 bullets):
4. Next week (max 3 bullets, with owner):
5. Ecosystems online: X/9 · alive: X/9 · days of data: X
6. Procurement: items outstanding (IDs) · China orders pending · expected dates
7. Top risk this week (ID) + action:
8. Safety: incidents/near misses (IDs) · open actions:
9. Evidence folder: % complete · missing items:
10. Decisions needed / from whom / by when:

Final report outline for ARCUB (submit Fri Dec 18)

  1. Summary (1 page): what was built, how many students, key numbers (9 ecosystems, N sessions, N student-hours, days of data, visitors).
  2. Objectives vs achieved: table per approved objective → evidence reference.
  3. Activities: timeline (the gantt above, as-run), workshops held with dates and attendance.
  4. The nine ecosystems: one page each: driving question, setup photo, sensors, one chart, what students learned, what comes next.
  5. Educational outcomes: indicators observed, rubric summary (anonymised), sample student reflections.
  6. Technical platform: architecture diagram, sensors per node, data volume, uptime %.
  7. Safety: protocol, incidents (count and type), commissioning certificates.
  8. Public showcase: dates, programme, visitors, photos, feedback.
  9. Procurement & budget: reconciliation of approved lines vs purchased items with reasons for each change; spend per line; remaining commitments.
  10. Visibility: logo usage, posts, press.
  11. Continuation plan (Jan–Jun 2027) and Time Capsule 10-year plan.
  12. Annexes: evidence index (file list referencing 06_ARCUB_Evidence/), data export, panels PDF.

Public one-pager per ecosystem (the "printed durable information panels")

Format: A3 portrait, printed on 3 mm PVC foam board (forex) or 5 mm, UV-laminated, one per ecosystem plus one project overview panel (10 panels), mounted on the table edge or the wall beside each tank. Basis: ~40–60 RON per A3 forex panel at a Bucharest print shop (≈ 8–12 EUR); 10 panels ≈ 500 RON. Send to print by Wed Dec 9. Time Capsule panel printed on aluminium composite (dibond) for a 10-year life (~120 RON).

Block Content Who writes
Header Ecosystem name + number, team first names, ARCUB + school + Alacrity logos T1 template
Driving question One line (table above) Lead Scientist
What's inside Species (Latin + common), substrate layers, 1 labelled photo or drawing Biology Keeper
What we measure Icons: temperature, humidity, soil moisture, light, CO2, water; sampling every 60 s Data Steward
What we built Node + actuators, 1 diagram; "everything inside the tank runs at 12 V or less" Lead Engineer
Our experiment Hypothesis, what we change, what we keep the same, control Lead Scientist
What we've seen so far One chart + one-sentence claim (updatable sticker area or QR) Team
What went wrong and what we changed 2–3 bullets Team
QR code Link to a public read-only Drive folder with the latest chart PDF (refreshed monthly by Hub Admins). The HA dashboard itself is not public Hub Admins
Footer "Please don't touch the tanks or the cables." Date + version T1

8. Answers to the proposal's "Items to discuss"

The proposal closes with six open questions for Alacrity. Short answers, with pointers to the chapters that justify them.

Question from the proposal Answer
Common ESP32 architecture across ecosystems Yes. One node design ("MICROCOSM node v1"): ESP32 DevKitC on a screw-terminal breakout in an IP65 box, one pin map, one ESPHome base YAML, one 12 V rail, one hub. A team configures a node; it never designs one. Chapter 3.
Useful vs unnecessary sensors Keep DS18B20, BH1750, OLED, capacitive soil (with mitigation), NDIR CO2. Replace 7 of 9 BME680 with SHT31. Add floats, ultrasonic level, pH, TDS, turbidity and handheld pens where the science needs them. Drop SD cards and RTCs from 6 of 9 nodes. Skip dissolved oxygen. Chapter 4.
Automation for hydroponics Light and air pump through smart plugs, circulation pump on a duty cycle, peristaltic dosing of nutrient and pH-down with daily caps, mixing waits and lockouts, level top-up with float interlocks, pen cross-checks daily. Chapter 5.7.
Automation for climate simulations 2056: heating loop with hysteresis and a hardware thermal fuse, drought and extreme-rain calendar, CO2 from a yeast generator with SCD41 feedback and vent/seal logic, humidity fan. 2026: steady irrigation and ventilation. Same hardware on both tanks, only setpoints differ. Chapter 5.4–5.
Automation for long-term monitoring Time Capsule: light on a schedule with a timer-plug fallback that works without the hub, alerts for temperature, humidity, dryness, data gaps and SD errors, local CSV logging with RTC, a replaceable external sensor pod, a ten-year maintenance calendar. Chapter 5.9.
Spare capacity 3 ESP32 boards (approved), one spare SHT31, BH1750 and DS18B20, two spare soil probes, floats, MOSFETs and bucks, one spare heat pad and 5 V adapter. No spare CO2 sensor, pump or brick after the cost cut; a failure there is a same-week purchase. Chapter 4.4.
Extra equipment for pH, EC, turbidity and aeration Yes to all four: 2 analog pH kits, 1 TDS module, 2 turbidity modules, 2 handheld pH pens, 1 TDS pen, 2 calibration sets, 1 COTS aquarium air pump with air stones. Chapter 6.
Note: calibration solutions listed, no probes Confirmed and fixed: probes and pens added.
Note: Raspberry Pi SD card listed, no Pi Confirmed and fixed: Raspberry Pi 5 (4 GB), official PSU, active cooler; the nodes use the school's existing Wi-Fi.

Appendix A. Glossary

Term Meaning
ARCUB Centrul Cultural al Municipiului București, the funding body for this project
COTS Commercial off-the-shelf: a finished product bought as-is, not built from parts
SELV Safety extra-low voltage: circuits at 12 V DC or below in this project, safe to touch and to run in water
RCD Residual-current device (differential protection), trips at 30 mA leakage; required on every power strip here
ESP32 The Wi-Fi microcontroller used in every node
ESPHome Firmware framework configured in YAML, integrates natively with Home Assistant
Home Assistant (HA) Open-source home-automation hub software running on the Raspberry Pi; dashboards, automations, alerts
InfluxDB / Grafana Time-series database and charting tool, run as Home Assistant add-ons for long-term data and CSV export
MQTT Lightweight messaging protocol; available on the hub for the advanced track
OTA Over-the-air firmware update over Wi-Fi
I2C, 1-Wire Two-wire digital sensor buses; I2C for SHT31/SCD41/BH1750/OLED, 1-Wire for DS18B20
ADC1 The ESP32 analog inputs that still work while Wi-Fi is on (GPIO 32–39)
PWM Pulse-width modulation: dimming lights, fans and heaters by switching fast
MOSFET module A transistor switch board that lets a 3.3 V pin control a 12 V load
Buck module A step-down converter, here 12 V to 5 V for the ESP32
NDIR Non-dispersive infrared, the measuring principle of a real CO2 sensor (SCD41)
VOC Volatile organic compounds; the BME680 reports a gas resistance that falls as VOCs rise
ASC / FRC Automatic self-calibration / forced recalibration of the SCD41; ASC must be off in sealed tanks
EC / TDS Electrical conductivity / total dissolved solids: a measure of dissolved salts in water or a soil extract
DWC / Kratky Deep water culture (aerated) and passive (non-aerated) hydroponic methods
Rhizotron A clear-walled container for observing roots in soil
Tea Bag Index (TBI) A standard citizen-science method for decomposition rate using buried tea bags
Berlese funnel A lamp-and-funnel device that drives soil invertebrates into a collecting jar for counting
Litter bag A mesh bag with a known mass of material, buried and reweighed to measure decomposition
Regolith Loose surface material of the Moon; here a basalt-based classroom analogue
Node One ESP32 box serving one ecosystem
Hub The Raspberry Pi running Home Assistant

Appendix B. ESPHome firmware listing

These files are the firmware referred to in Chapter 3. Copy the common/ folder to /config/esphome/common/ on the hub; each node YAML then needs only substitutions and the list of packages it uses.

common/mc-base.yaml

# common/mc-base.yaml — MICROCOSM node v1 base package (ESPHome 2025.x/2026.x)
# Every node YAML includes this file first and overrides the substitutions below.
substitutions:
  node_name: mc-00-test            # hostname, = ESPHome device name
  friendly_name: "MC 00"           # HA device name -> entity ids start with mc_00_
  area: "Lab"
  api_key: !secret mc00_api_key    # one key per node (secrets.yaml)
  ntp_server: "0.ro.pool.ntp.org"  # fallback only; primary time = HA over the API
  user1_src: wifi_rssi_s           # id of any sensor shown on OLED line 4
  user1_label: "RSSI dBm"          # no percent sign in labels (printf)
  user2_src: uptime_s              # id of any sensor shown on OLED line 5
  user2_label: "Uptime s"

esphome:
  name: ${node_name}
  friendly_name: ${friendly_name}
  area: ${area}
  on_boot:
    priority: 600
    then:
      - logger.log: "MICROCOSM ${node_name} booting"

esp32:
  board: esp32dev
  framework:
    type: esp-idf

logger:
  level: INFO

api:
  encryption:
    key: ${api_key}
  reboot_timeout: 0s               # do NOT reboot when HA is down: local logic keeps running

ota:
  - platform: esphome
    password: !secret ota_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  power_save_mode: none
  reboot_timeout: 0s               # keep running local automations without Wi-Fi
  ap:
    ssid: "${node_name}-fb"
    password: !secret fallback_ap_password

captive_portal:

time:
  # Both sources set the same ESP32 system clock; ha_time works without Internet
  # (HA over the native API), sntp is the fallback when HA is down.
  - platform: homeassistant
    id: ha_time
    timezone: Europe/Bucharest
  - platform: sntp
    id: sntp_time
    timezone: Europe/Bucharest
    servers:
      - ${ntp_server}
      - 1.ro.pool.ntp.org
      - 2.ro.pool.ntp.org

i2c:
  id: bus_a
  sda: GPIO21
  scl: GPIO22
  frequency: 100kHz                # 50kHz if total bus cable > 50 cm
  scan: true

one_wire:
  - platform: gpio
    id: ow_bus
    pin: GPIO4                     # 4.7 k pull-up to 3.3 V on the bus

globals:
  - id: g_air_t                    # written by sens-sht31 / sens-bme680, read by OLED
    type: float
    restore_value: false
    initial_value: "NAN"
  - id: g_air_rh
    type: float
    restore_value: false
    initial_value: "NAN"

sensor:
  - platform: wifi_signal
    id: wifi_rssi_s
    name: "WiFi RSSI"
    update_interval: 60s
    entity_category: diagnostic
  - platform: uptime
    id: uptime_s
    name: "Uptime"
    update_interval: 60s
    entity_category: diagnostic

binary_sensor:
  - platform: status
    id: api_status
    name: "Status"

button:
  - platform: restart
    name: "Restart"
    entity_category: config
  - platform: safe_mode
    name: "Safe mode boot"
    entity_category: config

font:
  - file: "gfonts://Roboto Mono"   # offline: put a .ttf in /config/esphome/fonts/
    id: f_small
    size: 10

display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    i2c_id: bus_a
    address: 0x3C
    update_interval: 5s
    lambda: |-
      it.printf(0, 0, id(f_small), "%s", "${node_name}");
      if (id(api_status).state) {
        it.printf(0, 12, id(f_small), "WiFi %.0f dBm  HA ok", id(wifi_rssi_s).state);
      } else if (wifi::global_wifi_component->is_connected()) {
        it.printf(0, 12, id(f_small), "WiFi %.0f dBm  no HA", id(wifi_rssi_s).state);
      } else {
        it.print(0, 12, id(f_small), "WiFi DOWN - local");
      }
      if (std::isnan(id(g_air_t))) {
        it.print(0, 26, id(f_small), "T --  RH --");
      } else {
        it.printf(0, 26, id(f_small), "T %.1f C  RH %.0f %%", id(g_air_t), id(g_air_rh));
      }
      it.printf(0, 40, id(f_small), "${user1_label}: %.1f", id(${user1_src}).state);
      it.printf(0, 52, id(f_small), "${user2_label}: %.1f", id(${user2_src}).state);

Sensor packages

# ---------- common/sens-sht31.yaml ----------
# SHT31-D on I2C 0x44 -> mc_XX_air_temp, mc_XX_air_rh
sensor:
  - platform: sht3xd
    i2c_id: bus_a
    address: 0x44
    update_interval: 60s
    heater_enabled: false
    temperature:
      id: air_t
      name: "Air temp"
      accuracy_decimals: 1
      on_value:
        - lambda: "id(g_air_t) = x;"
    humidity:
      id: air_rh
      name: "Air RH"
      accuracy_decimals: 0
      on_value:
        - lambda: "id(g_air_rh) = x;"
# ---------- common/sens-bme680.yaml (Orchestra of Rot only) ----------
# BME680 on I2C 0x77 (0x76 if SDO to GND) -> air temp/RH/pressure + gas resistance (VOC proxy)
sensor:
  - platform: bme680
    i2c_id: bus_a
    address: 0x77
    update_interval: 60s
    temperature:
      id: air_t
      name: "Air temp"
      oversampling: 2x
      on_value:
        - lambda: "id(g_air_t) = x;"
    humidity:
      id: air_rh
      name: "Air RH"
      oversampling: 2x
      on_value:
        - lambda: "id(g_air_rh) = x;"
    pressure:
      id: air_p
      name: "Air pressure"
    gas_resistance:
      id: gas_r
      name: "Gas resistance"
    heater:
      temperature: 320
      duration: 150ms
# ---------- common/sens-scd41.yaml ----------
# Sensirion SCD41 on I2C 0x62 -> mc_XX_co2 (+ diagnostic T/RH)
# ASC is OFF: sealed/biological enclosures never see fresh air (see Calibration).
sensor:
  - platform: scd4x
    id: scd41
    i2c_id: bus_a
    update_interval: 60s
    measurement_mode: periodic
    automatic_self_calibration: false
    altitude_compensation: 80m     # Bucharest
    co2:
      id: co2
      name: "CO2"
      accuracy_decimals: 0
    temperature:
      id: co2_t
      name: "CO2 sensor temp"
      entity_category: diagnostic
    humidity:
      id: co2_rh
      name: "CO2 sensor RH"
      entity_category: diagnostic

button:
  - platform: template
    name: "CO2 FRC 425 ppm"        # press ONLY outdoors after >= 5 min stable readings
    entity_category: config
    on_press:
      - scd4x.perform_forced_calibration:
          id: scd41
          value: 425
# ---------- common/sens-bh1750.yaml ----------
# BH1750 on I2C 0x23 -> mc_XX_illuminance (lux, not PAR)
sensor:
  - platform: bh1750
    i2c_id: bus_a
    id: lux
    name: "Illuminance"
    address: 0x23
    update_interval: 60s
# ---------- common/sens-ds18b20.yaml ----------
# One DS18B20 probe on the 1-Wire bus (GPIO4). vars: sid, label, addr, offset
sensor:
  - platform: dallas_temp
    one_wire_id: ow_bus
    id: ${sid}
    name: "${label}"
    address: ${addr}
    resolution: 12
    update_interval: 60s
    filters:
      - offset: ${offset}          # from the ice-water check (record sheet M3)

Finding a probe address: connect one probe, boot, read the 64-bit address (0x....) that the ESPHome log lists for the 1-Wire bus at boot, write the last 4 hex digits on the probe's label, add the include, then add the next probe.

# ---------- common/sens-soil.yaml ----------
# Capacitive soil probe v2.0 on an ADC1 pin. vars: pos (a..d), pin, dry_v, wet_v
# 10 samples x 6 s -> one averaged value per 60 s. Raw volts kept for re-calibration.
sensor:
  - platform: adc
    id: soil_${pos}_v
    name: "Soil raw ${pos}"
    pin: ${pin}
    attenuation: 12db              # = the old "11db" setting (renamed in ESPHome)
    update_interval: 6s
    accuracy_decimals: 3
    unit_of_measurement: "V"
    entity_category: diagnostic
    filters:
      - sliding_window_moving_average:
          window_size: 10
          send_every: 10
  - platform: copy
    source_id: soil_${pos}_v
    id: soil_${pos}
    name: "Soil moisture ${pos}"
    unit_of_measurement: "%"
    device_class: moisture
    accuracy_decimals: 0
    filters:
      - calibrate_linear:
          - ${dry_v} -> 0.0        # dry substrate (volts go DOWN when wetter)
          - ${wet_v} -> 100.0      # saturated substrate
      - clamp:
          min_value: 0
          max_value: 100
# ---------- common/sens-analog.yaml (pH on GPIO36, TDS on GPIO39) ----------
# Generic analog probe (pH board on GPIO36, TDS board on GPIO39). vars: aid, pin, label, unit, v1, y1, v2, y2
sensor:
  - platform: adc
    id: ${aid}_v
    name: "${label} raw"
    pin: ${pin}
    attenuation: 12db
    update_interval: 6s
    accuracy_decimals: 3
    unit_of_measurement: "V"
    entity_category: diagnostic
    filters:
      - median:
          window_size: 10
          send_every: 10
  - platform: copy
    source_id: ${aid}_v
    id: ${aid}
    name: "${label}"
    unit_of_measurement: "${unit}"
    accuracy_decimals: 2
    filters:
      - calibrate_linear:
          - ${v1} -> ${y1}
          - ${v2} -> ${y2}
# ---------- common/in-floats.yaml ----------
# Float switches on GPIO13 / GPIO14, switch to GND, internal pull-up.
# Fail-safe wiring: ON = alarm, and an open circuit (broken wire) also reads ON.
#  low float : mount so the contact is CLOSED when the float is UP (water above low mark)
#  high float: mount so the contact is CLOSED when the float is DOWN (water below high mark)
binary_sensor:
  - platform: gpio
    id: level_low
    name: "Level low alarm"
    device_class: problem
    pin:
      number: GPIO13
      mode:
        input: true
        pullup: true
    filters:
      - delayed_on: 2s
      - delayed_off: 2s
  - platform: gpio
    id: level_high
    name: "Level high alarm"
    device_class: problem
    pin:
      number: GPIO14
      mode:
        input: true
        pullup: true
    filters:
      - delayed_on: 2s
      - delayed_off: 2s
# ---------- common/in-flow.yaml ----------
# YF-S401 on GPIO5 via 10k/20k divider (sensor powered from 5 V).
# Nominal K = 5880 pulses/L (F[Hz] = 98 x Q[L/min]); replace with your bucket test value.
substitutions:
  flow_k: "0.00017007"             # = 1 / 5880 L per pulse
sensor:
  - platform: pulse_counter
    id: flow_rate
    name: "Flow rate"
    pin:
      number: GPIO5
      mode:
        input: true
    unit_of_measurement: "L/min"
    accuracy_decimals: 2
    update_interval: 10s           # exception to 60 s: rain events last 1-3 min
    internal_filter: 13us
    count_mode:
      rising_edge: INCREMENT
      falling_edge: DISABLE
    filters:
      - multiply: ${flow_k}        # pulses/min -> L/min
    total:
      id: flow_total
      name: "Flow total"
      unit_of_measurement: "L"
      device_class: water
      state_class: total_increasing
      accuracy_decimals: 3
      filters:
        - multiply: ${flow_k}      # pulses -> L

YF-S401: nominal F = 98 × Q (Hz, L/min) → 5 880 pulses/L, ±10 % between units. Calibrate each sensor once: pump exactly 1.000 L into a measuring jug, read Flow total, and set flow_k = 1 / pulses_counted.

# ---------- common/in-level.yaml ----------
# JSN-SR04T: TRIG GPIO15, ECHO GPIO12 through 1k (series) / 2k (to GND) divider.
# GPIO12 is a strapping pin: it MUST be low at boot - the 2k to GND guarantees that.
substitutions:
  tank_depth_m: "0.30"             # distance sensor face -> tank bottom, measured
sensor:
  - platform: ultrasonic
    id: us_dist
    name: "Water distance"
    trigger_pin: GPIO15
    echo_pin: GPIO12
    update_interval: 10s
    timeout: 4m
    pulse_time: 20us
    accuracy_decimals: 3
    entity_category: diagnostic
    filters:
      - filter_out: nan            # timeouts
      - lambda: |-
          if (x < 0.22 || x > 4.0) return {};   // blind zone / out of range -> drop
          return x;
      - median:
          window_size: 6
          send_every: 6            # 1 value per 60 s
  - platform: copy
    source_id: us_dist
    id: water_level
    name: "Water level"
    unit_of_measurement: "m"
    accuracy_decimals: 3
    filters:
      - lambda: "return ${tank_depth_m} - x;"

Mount the JSN-SR04T ≥ 25 cm above the maximum water level (its blind zone is ≈ 20–22 cm), pointing straight down, away from the walls.

Actuator packages

# ---------- common/act-light.yaml ----------
# PWM1 / GPIO16 -> MOSFET -> 12 V LED strip. Local photoperiod runs even without HA.
substitutions:
  light_on_min: "420"              # minutes after midnight (07:00)
  light_off_min: "1260"            # 21:00
  light_level: "0.8"               # 0..1 duty when the schedule switches on

output:
  - platform: ledc
    id: out_pwm1
    pin: GPIO16
    frequency: 1000Hz

light:
  - platform: monochromatic
    id: grow_light
    name: "Grow light"
    output: out_pwm1
    gamma_correct: 1.0             # linear: duty = light, easier to report
    default_transition_length: 2s
    restore_mode: RESTORE_DEFAULT_OFF

switch:
  - platform: template
    id: light_auto
    name: "Grow light schedule"
    optimistic: true
    restore_mode: RESTORE_DEFAULT_ON

interval:
  - interval: 60s
    then:
      - if:
          condition:
            switch.is_on: light_auto
          then:
            - lambda: |-
                auto now = id(ha_time).now();
                if (!now.is_valid()) return;
                int m = now.hour * 60 + now.minute;
                bool want = (m >= ${light_on_min}) && (m < ${light_off_min});
                bool is_on = id(grow_light).current_values.is_on();
                if (want && !is_on) {
                  auto call = id(grow_light).turn_on();
                  call.set_brightness(${light_level});
                  call.perform();
                } else if (!want && is_on) {
                  id(grow_light).turn_off().perform();
                }
# ---------- common/act-fan.yaml ----------
# PWM2 / GPIO17 -> MOSFET -> 12 V 80 mm fan
output:
  - platform: ledc
    id: out_pwm2
    pin: GPIO17
    frequency: 500Hz
    min_power: 0.30                # below ~30 % duty the fan stalls
    zero_means_zero: true

fan:
  - platform: speed
    id: fan1
    name: "Fan"
    output: out_pwm2
    speed_count: 10
    restore_mode: ALWAYS_OFF
# ---------- common/act-pump.yaml ----------
# 12 V DC pump on a PWM/MOSFET channel (default PWM3 / GPIO18). vars: pid, pin, label, max_s
# Firmware max-run timer: the pump can never run longer than max_s per start.
output:
  - platform: ledc
    id: ${pid}_out
    pin: ${pin}
    frequency: 500Hz
    min_power: 0.40
    zero_means_zero: true

fan:
  - platform: speed
    id: ${pid}
    name: "${label}"
    output: ${pid}_out
    speed_count: 10
    restore_mode: ALWAYS_OFF
    on_turn_on:
      - script.execute: ${pid}_timeout
    on_turn_off:
      - script.stop: ${pid}_timeout

script:
  - id: ${pid}_timeout
    mode: restart
    then:
      - delay: ${max_s}s
      - fan.turn_off: ${pid}
      - logger.log:
          level: WARN
          format: "${label}: max run time reached -> OFF"
# ---------- common/guard-dryrun.yaml ----------
# Needs in-floats.yaml and act-pump.yaml. vars: pid. Pump off while the low-level alarm is on.
interval:
  - interval: 1s
    then:
      - if:
          condition:
            and:
              - binary_sensor.is_on: level_low
              - fan.is_on: ${pid}
          then:
            - fan.turn_off: ${pid}
            - logger.log:
                level: WARN
                format: "Dry-run guard: ${pid} OFF (level low)"
# ---------- common/act-relay.yaml ----------
# Relay 1/2 (GPIO23 / GPIO25) for an isolated LOW-VOLTAGE load (e.g. 24 V mister). vars: rid, pin, label, max_s
output:
  - platform: gpio
    id: ${rid}_out
    pin:
      number: ${pin}
      inverted: false              # set true for active-low relay boards

switch:
  - platform: output
    id: ${rid}
    name: "${label}"
    output: ${rid}_out
    restore_mode: ALWAYS_OFF
    on_turn_on:
      - script.execute: ${rid}_timeout
    on_turn_off:
      - script.stop: ${rid}_timeout

script:
  - id: ${rid}_timeout
    mode: restart
    then:
      - delay: ${max_s}s
      - switch.turn_off: ${rid}
# ---------- common/act-servo.yaml ----------
# SG90 servo on GPIO26 / GPIO27 (5 V from the buck, signal 3.3 V). vars: sid, pin, label
output:
  - platform: ledc
    id: ${sid}_pwm
    pin: ${pin}
    frequency: 50Hz

servo:
  - id: ${sid}
    output: ${sid}_pwm
    auto_detach_time: 2s           # no buzzing/heat when idle
    transition_length: 1s

number:
  - platform: template
    id: ${sid}_pos
    name: "${label}"
    min_value: -100
    max_value: 100
    step: 5
    initial_value: 0
    optimistic: true
    restore_value: true
    set_action:
      - servo.write:
          id: ${sid}
          level: !lambda "return x / 100.0;"

Safety interlock: common/act-heater.yaml

The heat pad is driven only by a script in the node. The script runs every 5 s, needs no Wi-Fi or HA, and latches OFF when the controlling DS18B20 reads NaN (probe unplugged or broken) or more than 45 °C. Reset is deliberate: switch Heater enable off and on again (and if the fault persists, it trips again within 5 s). Hardware back-up: a 72 °C thermal cut-off fuse in series with the pad, taped to the pad surface.

# PWM4 / GPIO19 -> MOSFET -> 12 V heat pad (10-25 W) + 72 C thermal fuse in series (hardware).
# Local thermostat with LATCHED safety interlock. Runs in the node, works without HA/Wi-Fi.
substitutions:
  heat_probe: t_sub_a              # id of the DS18B20 taped to the pad / in the heated substrate
  heat_max: "45.0"                 # C, firmware hard limit
  heat_hyst: "0.5"                 # C, thermostat hysteresis

globals:
  - id: heat_tripped
    type: bool
    restore_value: false
    initial_value: "false"

output:
  - platform: gpio
    id: out_heat
    pin: GPIO19

switch:
  - platform: output
    id: heater_raw                 # internal: only the guard script may drive it
    output: out_heat
    restore_mode: ALWAYS_OFF
    internal: true
  - platform: template
    id: heater_enable
    name: "Heater enable"
    optimistic: true
    restore_mode: ALWAYS_OFF
    on_turn_off:
      - switch.turn_off: heater_raw
      - lambda: "id(heat_tripped) = false;"   # manual reset = toggle enable off/on

number:
  - platform: template
    id: heat_sp
    name: "Heater setpoint"
    unit_of_measurement: "°C"
    min_value: 15
    max_value: 40
    step: 0.5
    initial_value: 25
    optimistic: true
    restore_value: true

binary_sensor:
  - platform: template
    id: heat_trip_bs
    name: "Heater interlock"
    device_class: problem
    lambda: "return id(heat_tripped);"
  - platform: template
    id: heat_on_bs
    name: "Heater on"
    device_class: heat
    lambda: "return id(heater_raw).state;"

script:
  - id: heater_guard
    mode: single
    then:
      - lambda: |-
          const float t = id(${heat_probe}).state;
          if (!id(heater_enable).state) {
            if (id(heater_raw).state) id(heater_raw).turn_off();
            return;
          }
          if (std::isnan(t) || t > ${heat_max}) {
            if (id(heater_raw).state) id(heater_raw).turn_off();
            if (!id(heat_tripped)) {
              ESP_LOGW("safety", "Heater interlock TRIPPED (t=%.1f). Toggle Heater enable to reset.", t);
            }
            id(heat_tripped) = true;
            return;
          }
          if (id(heat_tripped)) return;            // latched until manual reset
          const float sp = id(heat_sp).state;
          if (t < sp - ${heat_hyst} && !id(heater_raw).state) id(heater_raw).turn_on();
          if (t > sp + ${heat_hyst} && id(heater_raw).state) id(heater_raw).turn_off();

interval:
  - interval: 5s
    then:
      - script.execute: heater_guard