Skip to content
 
 

Latest commit

 

History

129 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ChiBio

The Chi.Bio operating system: a Flask web app that controls Chi.Bio bioreactors over an I2C bus. It runs on the device (a BeagleBone Black), not on a dev machine — see https://chi.bio/software/.

This is a fork of HarrisonSteel/ChiBio, refactored and hardened. The original single-file app.py (~2300 lines) was split into the modules below and retired; it remains in git history if ever needed.

What's different in this fork

  • Modular layout. The monolith is split into app.py (Flask routes + output control) plus focused chibio_*.py modules (state, hardware/I2C, optics, measurements, experiment loops, control helpers). See CLAUDE.md for the full architecture map.

  • Robustness fixes. Long-running control loops are persistent threads instead of being re-spawned every iteration; the I2C/CSV lock is released via try/finally; a pre-existing CharacteriseDevice crash is fixed.

  • Token auth for remote access (see below), with zero-touch USB access preserved.

  • I2C on smbus2. The device layer was migrated off Adafruit_GPIO to a small smbus2 wrapper in chibio_hardware.py. GPIO/PWM still use Adafruit_BBIO.

  • Pinned dependencies (requirements.txt) and an EOL-safe provisioning path.

  • UI: self-hosted uPlot charts (no CDNs), a dark-mode toggle, a per-chart ln y-axis toggle (true base e — exponential growth reads as a straight line, slope = μ; on the OD/FP/growth charts), legends that show the latest value at rest and the cursor value on hover, and a fluorescence-assist panel (scan → recommended excite/emit bands → apply to an FP slot).

  • Data integrity. Sensor-read failures set a valid flag and log NaN only in the CSV (never a raw NaN in the live state); OD/FP take a 3× median + spread; a per-experiment metadata sidecar (<start>_<M>_meta.json) plus a mid-run events log (<start>_<M>_events.json) make each dataset self-describing when FP bands or the OD blank change during a run. A near-saturation guard flags fluorescence reads whose CLEAR base rides the ADC ceiling.

  • Simulation mode. CHIBIO_SIM=1 fakes the I2C bus and runs the real initialisation and control code on top of it, so the whole UI — charts, controls, running experiments — works with no reactors attached, and on an ordinary laptop. See Running without hardware.

By default you cannot run this on a macOS/Linux dev machine. Importing app.py triggers initialiseAll(), which talks to GPIO/I2C hardware and spawns the watchdog. Edit on your machine; run on the device — or set CHIBIO_SIM=1 to run the interface anywhere (see below). The device remains the reference you design against; the simulator is not a substitute for it.

Layout

  • app.py — Flask routes and the core output-control functions.
  • chibio_state.py — the shared global dicts (sysData, sysDevices, sysItems) and the global lock.
  • chibio_hardware.pyI2CCom, the single chokepoint for all I2C traffic; PWM; watchdog.
  • chibio_optics.py / chibio_measurements.py — AS7341 spectrometer reads; OD/FP/temperature.
  • chibio_experiment.py — the long-running control threads (main loop, thermostat, pumps, turbidostat, zigzag).
  • chibio_control_helpers.py — user-editable optogenetic programs, CSV logging, metadata/events sidecars, downsampling.
  • chibio_fluorescence.py — the fluorescence configuration assist (excitation scan → recommended FP settings).
  • chibio_auth.py — token/cookie auth and the trusted-subnet rules.
  • chibio_sim.py — the CHIBIO_SIM=1 simulator: a fake I2C bus plus substituted optics, with a culture and thermal model behind them.
  • templates/ + static/ — the browser UI (polls /getSysdata/ over AJAX).

Install (on the BeagleBone)

Runs on the Chi.Bio Debian 10.5 / Linux 4.19 image with Python 3.7. Two paths:

  1. Golden image (preferred). Flash once, provision once, then snapshot the eMMC/SD and restore that image forever after. See make-golden-image.md. This removes the dependency on EOL apt at provisioning time.
  2. setup.sh (fresh provision). Repoints apt at archive.debian.org (Debian 10 "buster" is EOL and left the main mirrors), installs the pinned deps from requirements.txt, builds the bundled Adafruit_BBIO-1.2.0.tar.gz from source against the baked kernel, and copies app.py + the chibio_*.py modules, static/, and templates/ into ~/chibio. Run once on a fresh board.

Adafruit_BBIO is intentionally not in requirements.txt — it is kernel-matched and built from the tarball, not installed from PyPI.

Run

./cb.sh starts the server:

gunicorn -b 0.0.0.0:5000 app:application

Binding 0.0.0.0 serves the UI on both the USB point-to-point link and the LAN. To run detached, either uncomment the screen line in cb.sh, or start it under tmux (installed on the device) and leave cb.sh in the foreground:

tmux new-session -d -s chibio "bash -lc './cb.sh 2>&1 | tee /tmp/chibio.log'"
tmux attach -t chibio          # watch it
./cb-stop.sh stop 5000         # stop it — never hand-roll ss|kill

Access / auth

Set CHIBIO_TOKEN to require an X-Auth-Token header (or ?token=) on remote requests. cb.sh reads it from a gitignored .chibio_token file next to the script (root-only, 600); with no token set, all remote access is denied (fail closed).

  • USB point-to-point (192.168.7.x / 192.168.6.x) and loopback are trusted — no token needed.
  • Remote / LAN: open once with ?token=…. The device sets an HttpOnly chibio_token cookie (30-day), and the browser then sends it automatically on every request, including all control POSTs — no per-request token handling in the UI.

Caveat: HTTP-only (no TLS), so the token is visible to anyone sniffing the wire. This is LAN access control, not wire encryption. See chibio_auth.py.

Development / testing

The device run dir is a git checkout, but it is not updated via git pull — the board doesn't fetch from GitHub. Deploy by rsync from your machine:

rsync -az --delete \
  --exclude='.DS_Store' --exclude='.chibio_token' --exclude='.claude' \
  --exclude='selftest-*.json' --exclude='.c9' --exclude='__pycache__' \
  -e ssh ./ <device>:/root/chibio/

Always exclude .chibio_token (or --delete wipes the device's secret), the selftest-*.json artifacts, and the device's untracked .c9/ (Cloud9 IDE dir). .git is deliberately not excluded: syncing it keeps the run dir's git ref pointing at exactly what is deployed, which is where the metadata sidecar reads its commit hash from. Deploy to /root/chibio-staging first, verify there, then promote to /root/chibio.

device_selftest.py <label> exercises every I2C code path against a running server on the device and dumps a per-device snapshot to selftest-<label>.json, so a "before" run can be diffed against an "after" run. Use it to confirm sensor-path changes don't silently regress readings. It safely discovers connected reactors first (via /scanDevices/all + presentDevices) rather than measuring absent devices, which would trip the watchdog kill.

There is no linter and no build step. A suite of ten test_*.py files runs off-device, covering the logic that doesn't need hardware — CSV schema, metadata/events sidecars, read-validity, auto-ranging, replicate aggregation, the FP saturation guard, the fluorescence analysis, and the simulator itself:

python3 -m venv v && v/bin/pip install flask numpy smbus2 simplejson
CHIBIO_MOCK_HW=1 v/bin/python test_fluorescence.py   # (and the other test_*.py)

test_sim.py reaches furthest: because CHIBIO_SIM fakes only the bus, it exercises the real initialisation, presence-scan and measurement code end-to-end without a board (it sets its own env vars, so the invocation above still works).

Hardware paths still need the device (device_selftest.py, above). The device is otherwise the reference you design against — CHIBIO_MOCK_HW is only an import shim, not a development target.

Running without hardware (CHIBIO_SIM=1)

Two situations where the server won't otherwise start: a controller with no reactors plugged in (nothing on the bus answers, so the I2C multiplexer never ACKs, the watchdog kills the process, and gunicorn reports App failed to load with exit code 4 — that is the watchdog working, not a bug), and an ordinary laptop with no BeagleBone at all. CHIBIO_SIM=1 handles both:

CHIBIO_SIM=1 ./cb.sh                                  # on the device
CHIBIO_SIM=1 python3 -c "import app; app.application.run(port=5000)"   # on a laptop

It fakes the bus — a stand-in smbus2.SMBus for the multiplexer, both MCP9808 thermometers, the IR thermometer, the DAC and the two PWM chips, plus substituted AS7341 optics — and then runs the real initialiseAll() on top. So the presence scan, LED V1/V2 detection (and the FP3 excitation remap that follows from it), OD calibration and dark correction, the FP ratio and its near-saturation guard, the thermostat, the turbidostat, CSV logging and the fluorescence assist are all the actual product code. Behind the fake optics sits a logistic culture model — diluted by whatever the input pump is really doing — and a first-order heater model driven by the real heat output, so experiments genuinely run and the control loops close.

Variable Default Meaning
CHIBIO_SIM_LED_VERSION 2 LED board version to present (V1 and V2 expose different excitation panels)
CHIBIO_SIM_REACTORS M0,M1,M2,M3,M4 Which reactors answer; the rest scan absent through the real failure path
CHIBIO_SIM_HOURS 12 Hours of synthetic history pre-loaded so charts open with data; pressing Start resumes into it
CHIBIO_SIM_SEED 1 Otherwise deterministic

Simulated reactors carry a SIM- device ID and a SIMULATION MODE - no hardware attached terminal line, so a screenshot can't be mistaken for real hardware.

This is not a substitute for the device. It is a fake bus with a plausible culture behind it: it cannot tell you what real readings look like, which LEDs are actually fitted, or how the optics behave. Use it to work on the interface when the rig is unavailable — not to design against.

About

ChiBio primary operating system.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages