New Pioreactor release: 26.3.0 and 26.3.3

:wave: Going forward, we are changing our versioning scheme from YY.M.D to YY.M.N, where N is a release counter within the month starting at 0.

We expect YY.M.0 releases to carry the larger changes, including system-level updates when needed. Subsequent releases in the same month, such as YY.M.1, YY.M.2, and so on, will typically be smaller bug-fix or incremental releases.

:arrow_down: Download the 26.3.0 update here


Enhancements

  • Redesigned the Experiments UI page into a management-focused table with search, status/tag filters, tag editing, and quick actions for exporting, ending, or deleting experiments.

  • Added experiment tags to the UI and API: tags can now be created when starting a new experiment, edited later from the Experiments and Overview page, and used to organize/filter experiments.

  • Calibration protocol sessions now persist a tab-scoped resume handle in the UI, so reloading the Protocols page in the same browser tab restores the existing Resume protocol action instead of losing the in-progress session.

  • Added persisted bioreactor state for each experiment, including current_volume_ml, max_working_volume_ml, and alt_media_fraction. These values are now exposed over MQTT plus new API endpoints:

    • GET /api/bioreactor/descriptors
    • GET|PATCH /api/workers/<unit>/experiments/<experiment>/bioreactor
    • GET /unit_api/bioreactor/experiments/<experiment>
  • Added live bioreactor controls to the Pioreactor UI so users can inspect and edit per-unit bioreactor values, with updated vessel diagrams for supported 20 mL and 40 mL models.

  • Added plugin hooks for custom self-tests. Plugins can now register additional checks that run with pio run self_test, for example:

    from pioreactor.actions.self_test import register_self_tests
    
    
    def test_air_bubble_is_running(managed_state, logger, unit, experiment):
        assert ...
    
    
    register_self_tests(test_air_bubble_is_running)
    

Breaking changes

  • Updated the leader UI’s dosing-related chart and job descriptors to read live bioreactor state from bioreactor/current_volume_ml and bioreactor/alt_media_fraction, and to stop exposing the hidden duplicate dosing-automation volume settings. The app update also refreshes the deployed YAML descriptors automatically on leaders.

  • Removed the legacy dosing-automation MQTT settings/topic surface for bioreactor values. current_volume_ml, max_working_volume_ml, and alt_media_fraction are no longer published as dosing_automation settings or exposed as dosing-automation capability flags. Use the retained bioreactor topics and APIs instead:

    pioreactor/<unit>/<experiment>/bioreactor/current_volume_ml
    pioreactor/<unit>/<experiment>/bioreactor/max_working_volume_ml
    pioreactor/<unit>/<experiment>/bioreactor/alt_media_fraction
    

Bug fixes

  • Fixed a UI crash when MQTT button_down events triggered tactile-button notifications.
  • Fix plugins not being loaded correctly in the background task worker. This affected mostly plugin-sourced calibrations.
  • Added a <System> experiment option in Export Data and mapped it to "$experiment" so users can export system logs from the UI.
  • Fixed calibration session resume so reopening a saved protocol session returns to the current step instead of accidentally starting the protocol from the beginning again.
  • Fix leaking of self-test logs into the experiment.

How to update

1 Like

26.3.1

Bug fixes

  • Fix temperature automation not recognizing Pioreactor 20ml v1.0 correctly
  • Fix bug that was causing /api/bioreactor/descriptors to fail on leader-only units.

release_26.3.1.zip

Hi @CamDavidsonPilon, in 26.3.0, turbidostat dosing automation is not registering the OD value entered. Can you reproduce this on your side as well? and if so, is this also handled in the latest update?

@sharknaro, let me investigate now. Sorry about this!

@sharknaro, it might be related to how we handle turbidostat and biomass signals now. See the docs here. Basically, the following logic is applied:

The current turbidostat fields in the UI are:

  • exchange volume: how much media and waste to move in each dilution cycle, in mL.
  • target biomass: the biomass threshold that triggers a dilution cycle.
  • biomass signal: which biomass estimate to monitor. The UI defaults this to auto.

When biomass signal is set to:

  • normalized_od: the automation compares against normalized OD.
  • od_fused: the automation compares against the fused OD estimator.
  • od: the automation compares against calibrated OD from the resolved OD channel.
  • auto: the automation chooses the most specific available signal automatically.

When biomass signal is auto, the selection order is:

  1. od_fused, when an active od_fused estimator is available.
  2. od, when an active OD calibration is available for the resolved photodiode angle.
  3. normalized_od, when neither of the above is available.

Aha… yes likely this is the cause… so what to do in case of raw OD use - e.g., running pios without OD calibration? which was the case and hence caused normalized_od to be selected.

Additional comment on the new feature on v26.3.0 and above. Assign Pioreactors section now allows to select assigned workers. I am not sure what was the incentive for this change, but I think it risks accidental removal of workers from already running experiments in big groups with multiple users. Is there an additional option added to lock the pios?

Ah, the incentive was that I felt it was more clear to users. But yes, I agree there is a risk. Maybe we need more cycles “states”.

Let me iterate on this interaction again.

Something like this: “Select all” is now “Select all available” (that’s more clear, and wont select existing Pioreactors), and users can manually reassign.

Maybe I keep the second confirmation, but thats feels like overkill

Yes, I think this is the best of both worlds! I do agree that second confirmation is an overkill as the user is already informed the cause of the action when they manually click on the worker.

It’s not clearly documented, but in this case, you should choose od. In your config.ini, find the section dosing_automation.turbidostat, and set:

[dosing_automation.turbidostat]
# one of {od,fused_od,normalized_od,auto}
biomass_signal=od

Save and restart and turbidostats running.

Okay, I understand it better now, thanks for the clarification @CamDavidsonPilon!

26.3.3

Download release_26.3.3.zip here

Breaking changes

  • Changed the leader API route for updating per-unit bioreactor values. PATCH /api/workers/<unit>/experiments/<experiment>/bioreactor has been removed; use PATCH /api/workers/<unit>/bioreactor/update/experiments/<experiment> instead.

Bug fixes

  • Fixed reassignment history tracking in the leader web app’s SQLite connection by enabling recursive triggers, preventing stale open rows from accumulating in experiment_worker_assignments_history.
  • Fixed worker reassignment so moving a Pioreactor from one experiment to another now stops jobs still running under the previous experiment.
  • Fixed pump dosing_events MQTT publishes for very small dosing volumes, where fast runs could finish before an event was emitted.
  • Fixed missed pump dosing_events observations by publishing them with MQTT QoS 2 (EXACTLY_ONCE), and updated pio mqtt to subscribe at the same QoS when tailing topics.
  • Fixed recent log tables in the UI so live MQTT log events stay sorted by timestamp even if they arrive slightly out of order, instead of appearing under older events until refresh.
  • Fixed experiment profile previews so inline YAML comments like # 1/h, # mL, and timing notes now appear in the human-readable display in the create, edit, and profile preview UIs.

26.3.2

Bug fixes

  • Adjusted the UI’s “Assign Pioreactors” dialog so Select all available no longer includes workers already assigned to another experiment, reducing accidental bulk reassignments while preserving individual reassignment.
  • fixed new images now having the experiment_tags table
  • fixed some UI bugs
1 Like