In development · pre-release · APIs and behaviour will change
A Fuzue research project

A modular
bioreactor
operating system.

ChiBio Next is a from-scratch rewrite of the Chi.Bio control software, built behind a hexagonal hardware boundary so the same controllers run on a BeagleBone Black with real I²C peripherals or on a laptop against a Python physics simulator.

In development Python 3.10+ Flask + Alpine.js Hexagonal · ports & adapters Open source · MIT-style
Source on GitHub Try the simulator

Same hardware.
Different bones.

The upstream Chi.Bio device is brilliant; the controller code is a single ~100 KB Flask file with hardware I/O, control loops, and view logic interleaved. ChiBio Next preserves the device behaviour but reorganises the software so each layer can be reasoned about, tested, and replaced on its own.

01 / Hardware boundary
Ports & adapters
All controllers depend on the BioreactorUnitPort protocol — never on a concrete I²C class. Swap in a simulator, a recorded trace, or a different instrument without touching the algorithms.
02 / Runs offline
Physics in Python
A pure-Python SimulatedBioreactorFleet models logistic culture growth (Beer–Lambert transmittance) and Newton’s-law thermal response, so the whole stack — Flask app, UI, control loops — runs on any laptop.
03 / No global state
Per-unit state objects
The old sysData[M][…] global dict is gone. Each unit owns a UnitExperimentState dataclass; routes are thin and never call I²C directly.
04 / Tested in CI
Real-data regression
Unit, integration, Playwright UI, and a regression suite that replays a real M1 experiment through the new controllers to confirm behaviour matches before any device is switched over.

Five layers,
one boundary.

Each layer depends only on the one below it. The ports layer is the contract — everything above it is logic, everything below it is I/O.

app_new.py
Flask routes Thin handlers; validate inputs, mutate state, return JSON.
chibio.experiment
ExperimentRunner · State · DataRecorder · PumpScheduler One threaded loop per unit; CSV/JSON snapshots; pump timing.
chibio.domain
ODController · ThermostatController · types Turbidostat / chemostat / custom pump modes; no I/O.
chibio.ports
BioreactorUnitPort · BioreactorFleetPort Protocol definitions — the contract between logic and hardware.
chibio.adapters
SimulatedBioreactorFleet · I2CBioreactorFleet Physics-based fake for dev/CI; TCA9548A multiplexer for real hardware.

Two ways
to bring it up.

The same Flask app boots in both modes. bootstrap.build_fleet() picks the adapter based on a single environment variable.

Default · any laptop
Simulation

Eight simulated units come up populated with the physics model. Start a turbidostat, watch the OD trace evolve in real time, hit the Playwright UI tests.

# install
git clone https://github.com/fuzue/chibio-next
cd chibio-next
pip install -e . flask

# run
python app_new.py
# → http://localhost:5000
BeagleBone Black
Hardware

On the real Chi.Bio device, the bootstrap probes each of M0–M7 over the TCA9548A multiplexer and skips any unit that doesn’t respond, so partially-populated devices work.

# require Adafruit_BBIO, smbus2, Adafruit_I2C
BEAGLEBONE_I2C=1 python app_new.py

# or, equivalently:
CHIBIO_MODE=hardware python app_new.py

Pre-release.
Honest about it.

The simulator path is usable today; the hardware path has been wired but not yet end-to-end validated on a live device. Treat anything here as a work-in-progress until this section says otherwise.

Landed

  • Hexagonal layout (ports / adapters / domain / experiment)
  • Simulated fleet with growth + thermal physics models
  • OD controller — turbidostat, chemostat, custom pump modes
  • Thermostat controller on its own 30 s loop
  • ExperimentRunner replacing runExperiment()
  • Alpine.js + Chart.js UI (vendored, no CDN)
  • Regression test against real M1 experiment data
  • Playwright browser tests of the live UI