Skip to content

fuzue/chibio-next

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ChiBio (modular rewrite)

A clean rewrite of the Chi.Bio open-source bioreactor control system. The original app.py was a single ~100 KB Flask file with hardware I/O, control loops, and view logic mixed throughout. This repo is a from-scratch reimplementation behind a hexagonal (ports & adapters) boundary so the same control algorithms can run unchanged on a BeagleBone Black with real hardware or on a laptop against a physics simulator.

Goals of the rewrite

  • Hardware abstraction. Control code depends only on the BioreactorUnitPort / BioreactorFleetPort protocols. The Flask app never imports an adapter class directly.
  • Run offline. A pure-Python SimulatedBioreactorFleet with logistic growth (Beer–Lambert transmittance) and Newton's-law-of-cooling thermal models lets the entire stack run on any platform.
  • No global state. Per-unit state lives in UnitExperimentState dataclasses; the old sysData[M][...] global dict is gone.
  • Tested. Unit, integration, regression (against real M1 experiment data), and Playwright UI tests — all runnable in CI without hardware.
  • Modern UI. Alpine.js + Chart.js (both vendored for offline use), replacing the jQuery + Google Charts frontend.

Architecture

┌──────────────────────────────────────────────────────────────┐
│  app_new.py        Flask routes — thin, no I/O               │
├──────────────────────────────────────────────────────────────┤
│  chibio.experiment  ExperimentRunner, UnitExperimentState,   │
│                     DataRecorder, PumpScheduler              │
├──────────────────────────────────────────────────────────────┤
│  chibio.domain      ODController (turbidostat / chemostat /  │
│                     custom), ThermostatController, types     │
├──────────────────────────────────────────────────────────────┤
│  chibio.ports       BioreactorUnitPort, BioreactorFleetPort  │  ← boundary
├──────────────────────────────────────────────────────────────┤
│  chibio.adapters    SimulatedBioreactorFleet (physics)       │
│                     I2CBioreactorFleet (TCA9548A + I2C)      │
└──────────────────────────────────────────────────────────────┘

chibio.bootstrap.build_fleet() is the only place that picks between the simulated and real-hardware adapter. It defaults to simulation unless BEAGLEBONE_I2C=1 is set (or CHIBIO_MODE=hardware).

Layout

chibio/
├── domain/          pure logic, no I/O
│   ├── types.py     UnitID, LED, Pump, SpectrumReading, …
│   ├── regulate_od.py   ODController (turbidostat/chemostat/custom)
│   └── thermostat.py    ThermostatController
├── ports/           Protocol definitions (the boundary)
│   └── hardware.py
├── adapters/
│   ├── simulated_adapter.py   physics-based fake for dev/CI
│   └── i2c_adapter.py         TCA9548A mux + I2C devices
├── experiment/
│   ├── state.py           UnitExperimentState (replaces sysData)
│   ├── runner.py          ExperimentRunner (threaded cycle loop)
│   ├── data_recorder.py   CSV/JSON snapshots
│   └── pump_scheduler.py
└── bootstrap.py     composition root

app_new.py          Flask app wiring everything together
static/             Alpine.js, Chart.js (vendored), chibio.js, chibio.css
templates/          index_new.html (Alpine + Jinja macros)
tests/              pytest suites + Playwright UI tests

Running

Requires Python ≥ 3.10.

git clone <this-repo> chibio
cd chibio
python -m venv .venv
source .venv/bin/activate
pip install -e .
pip install flask pytest

Simulation mode (any laptop)

python app_new.py

Open http://localhost:5000. All 8 simulated units (M0–M7) come up populated with the physics model. Start a turbidostat / chemostat experiment from the UI and watch the OD trace evolve in real time.

Hardware mode (BeagleBone Black)

On a real Chi.Bio device:

BEAGLEBONE_I2C=1 python app_new.py
# or:  CHIBIO_MODE=hardware python app_new.py

The bootstrap probes each of M0–M7 over the TCA9548A multiplexer and skips any unit that doesn't respond, so partially-populated devices work.

Tests

pytest                       # unit + integration + regression
pytest -k regression         # only the real-data regression suite
pytest tests/test_ui.py      # static-asset / route smoke tests

Browser tests (require Playwright + a running app) live in tests/playwright_ui_test.py:

pip install playwright
playwright install chromium
python tests/playwright_ui_test.py

Configuration

Env var Effect
CHIBIO_MODE simulation or hardware — overrides auto-detection
BEAGLEBONE_I2C=1 Force hardware mode (legacy alias)
CHIBIO_DATA_DIR Where experiment CSV / JSON snapshots are written (default .)

Status

This is an in-progress rewrite. The original app.py is the authority on what the device actually does on the bench; this repo's regression test (tests/test_regression.py) replays a real M1 dataset through the new controllers to make sure behaviour matches before any unit is switched over.

About

ChiBio bioreactor control system — modular rewrite with hardware abstraction layer

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors