Skip to content

Commit 38de55d

Browse files
turbidostat now dynamically chooses the biomass signal; some UI updates
1 parent 835baad commit 38de55d

17 files changed

+158
-74
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22

33
#### Breaking changes
44

5+
- Turbidostat biomass signal behavior has changed in a user-visible way:
6+
- The setting key is now `biomass_signal` (renamed from `biomass_signal_override`).
7+
- The config moved from `[turbidostat.config]` to `[dosing_automation.turbidostat]`.
8+
- Default behavior is now `biomass_signal=auto`, with selection order:
9+
1. active `od_fused` estimator
10+
2. active OD calibration for the configured angle (`od`)
11+
3. normalized OD
12+
- Users can still explicitly override `biomass_signal` in config (including via profiles), but Turbidostat now defaults to `auto`.
13+
- Update scripts migrate existing values from the legacy section/key when present.
514
- Renamed `/api/is_local_access_point_active` to `/api/local_access_point` (now returns `{active: <bool>}`).
615
- Consolidated experiment profile routes under `/api/experiment_profiles` and `/api/experiments/<experiment>/experiment_profiles/*`. Removed `/api/contrib/experiment_profiles` and `/api/experiment_profiles/running/experiments/<experiment>`. `PATCH` now targets `/api/experiment_profiles/<filename>`.
716
- Consolidated config API routes under `/api/config/*`: `/api/units/<pioreactor_unit>/configuration` is now `/api/config/units/<pioreactor_unit>`, and `/api/configs` + `/api/configs/<filename>` + `/api/configs/<filename>/history` are now `/api/config/files` + `/api/config/files/<filename>` + `/api/config/files/<filename>/history`.
@@ -18,6 +27,8 @@
1827
- Added a new calibration coverage matrix page in the UI (linked from Calibrations) to show cluster-wide per-unit/per-device coverage and quick actions: open active calibration details, view available calibrations for a device, or create missing calibrations via `/protocols/<unit>/<device>`.
1928
- Added card-level quick controls to both `/pioreactors` and `/pioreactor/<unit>`: clicking an activity state now runs contextual actions (start, stop, pause, resume), and shows an in-place spinner until MQTT reports the expected state transition.
2029
- Added inline quick-edit popovers for card settings values.
30+
- Automation advanced config now discovers and displays both `[<x>_automation.config]` and per-automation sections like `[<x>_automation.<automation_name>]`, enabling section-specific overrides from the UI.
31+
2132

2233
#### Bug fixes
2334

@@ -28,6 +39,7 @@
2839
- Fixed Inventory model updates and active/inactive toggles to show success only after confirmed backend `2xx` responses, with explicit error feedback on failure.
2940

3041

42+
3143
### 26.2.3
3244

3345
#### Enhancements

config.dev.ini

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@ target_rpm_outside_od_reading=500
3838

3939

4040

41-
[turbidostat.config]
42-
signal_channel=2
43-
od_smoothing_ema=0.5
41+
[dosing_automation.turbidostat]
42+
biomass_signal=auto
4443

4544
[stirring.pid]
4645
Kp=0.007

core/pioreactor/automations/dosing/turbidostat.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def __init__(
3434
self,
3535
exchange_volume_ml: float | str,
3636
target_biomass: Optional[float | str] = None,
37-
biomass_signal: str = "auto",
37+
biomass_signal: str | None = None,
3838
**kwargs,
3939
) -> None:
4040
super().__init__(**kwargs)
@@ -48,6 +48,13 @@ def __init__(
4848
if target_biomass is None:
4949
raise ValueError("Provide a target biomass.")
5050

51+
if biomass_signal is None:
52+
biomass_signal = config.get(
53+
"dosing_automation.turbidostat",
54+
"biomass_signal",
55+
fallback="auto",
56+
)
57+
5158
self._set_biomass_signal(biomass_signal)
5259
self.target_biomass = float(target_biomass)
5360

core/pioreactor/web/static/asset-manifest.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"files": {
33
"main.css": "/static/static/css/main.9c7a48b7.css",
4-
"main.js": "/static/static/js/main.45157214.js",
4+
"main.js": "/static/static/js/main.c87c24a5.js",
55
"static/media/roboto-all-500-normal.woff": "/static/static/media/roboto-all-500-normal.0ab669b7a0d19b178f57.woff",
66
"static/media/roboto-all-700-normal.woff": "/static/static/media/roboto-all-700-normal.a457fde362a540fcadff.woff",
77
"static/media/roboto-all-400-normal.woff": "/static/static/media/roboto-all-400-normal.c5d001fa922fa66a147f.woff",
@@ -28,10 +28,10 @@
2828
"static/media/roboto-greek-ext-700-normal.woff2": "/static/static/media/roboto-greek-ext-700-normal.bd9854c751441ccc1a70.woff2",
2929
"index.html": "/static/index.html",
3030
"main.9c7a48b7.css.map": "/static/static/css/main.9c7a48b7.css.map",
31-
"main.45157214.js.map": "/static/static/js/main.45157214.js.map"
31+
"main.c87c24a5.js.map": "/static/static/js/main.c87c24a5.js.map"
3232
},
3333
"entrypoints": [
3434
"static/css/main.9c7a48b7.css",
35-
"static/js/main.45157214.js"
35+
"static/js/main.c87c24a5.js"
3636
]
3737
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/static/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Pioreactor"/><link rel="apple-touch-icon" href="/static/logo192.png"/><link rel="manifest" href="/static/manifest.json"/><script defer="defer" src="/static/static/js/main.45157214.js"></script><link href="/static/static/css/main.9c7a48b7.css" rel="stylesheet"></head><body><div id="root"></div></body></html>
1+
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/static/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Pioreactor"/><link rel="apple-touch-icon" href="/static/logo192.png"/><link rel="manifest" href="/static/manifest.json"/><script defer="defer" src="/static/static/js/main.c87c24a5.js"></script><link href="/static/static/css/main.9c7a48b7.css" rel="stylesheet"></head><body><div id="root"></div></body></html>

core/pioreactor/web/static/static/js/main.45157214.js renamed to core/pioreactor/web/static/static/js/main.c87c24a5.js

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/pioreactor/web/static/static/js/main.45157214.js.LICENSE.txt renamed to core/pioreactor/web/static/static/js/main.c87c24a5.js.LICENSE.txt

File renamed without changes.

core/pioreactor/web/static/static/js/main.45157214.js.map renamed to core/pioreactor/web/static/static/js/main.c87c24a5.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/tests/test_dosing_automation.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
from pioreactor.background_jobs.dosing_automation import DosingAutomationJob
2525
from pioreactor.background_jobs.dosing_automation import start_dosing_automation
2626
from pioreactor.background_jobs.dosing_automation import VolumeCalculator
27+
from pioreactor.config import config
28+
from pioreactor.config import temporary_config_change
2729
from pioreactor.structs import DosingEvent
2830
from pioreactor.utils import local_persistent_storage
2931
from pioreactor.utils import SummableDict
@@ -315,6 +317,20 @@ def test_rejects_invalid_biomass_signal_in_turbidostat() -> None:
315317
pass
316318

317319

320+
def test_turbidostat_uses_config_default_biomass_signal() -> None:
321+
experiment = "test_turbidostat_uses_config_default_biomass_signal"
322+
with temporary_config_change(config, "dosing_automation.turbidostat", "biomass_signal", "od"):
323+
with Turbidostat(
324+
target_biomass=0.5,
325+
duration=60,
326+
exchange_volume_ml=0.25,
327+
unit=unit,
328+
experiment=experiment,
329+
skip_first_run=True,
330+
) as algo:
331+
assert algo.biomass_signal == "od"
332+
333+
318334
def test_turbidostat_auto_prefers_active_od_fused_estimator(monkeypatch) -> None:
319335
experiment = "test_turbidostat_auto_prefers_active_od_fused_estimator"
320336

core/update_scripts/upcoming/update.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
1010
HOSTNAME=$(hostname)
1111
LEADER_HOSTNAME=$(/opt/pioreactor/venv/crudini --get "$CONFIG" cluster.topology leader_hostname)
1212

13+
# Migrate / seed turbidostat config namespace:
14+
# [turbidostat.config] -> [dosing_automation.turbidostat]
15+
biomass_signal=$(/opt/pioreactor/venv/crudini --get "$CONFIG" dosing_automation.turbidostat biomass_signal 2>/dev/null || true)
16+
if [ -z "$biomass_signal" ]; then
17+
biomass_signal=$(/opt/pioreactor/venv/crudini --get "$CONFIG" turbidostat.config biomass_signal 2>/dev/null || true)
18+
fi
19+
if [ -z "$biomass_signal" ]; then
20+
biomass_signal="auto"
21+
fi
22+
/opt/pioreactor/venv/crudini --set "$CONFIG" dosing_automation.turbidostat biomass_signal "$biomass_signal"
23+
1324
# UI automation definitions are leader-facing, so only install on the leader.
1425
if [ "$HOSTNAME" = "$LEADER_HOSTNAME" ]; then
1526
install -d -o pioreactor -g pioreactor -m 0755 "$DOT_PIOREACTOR/ui/automations/dosing"

0 commit comments

Comments
 (0)