Skip to content

Commit 5285b83

Browse files
more
1 parent db710e9 commit 5285b83

File tree

11 files changed

+140
-22
lines changed

11 files changed

+140
-22
lines changed

developer-guide/03-Background jobs/02-writing-background-jobs.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class IntroJob(BackgroundJob):
8383

8484
def set_intensity(self, intensity):
8585
self.intensity = intensity
86-
led_intensity(channels=self.LED_channel, intensities=self.intensity)
86+
led_intensity({self.LED_channel: self.intensity})
8787
```
8888

8989
Next, we create the "on exit" behaviour (turn off LED) by overwriting the `on_disconnected` function.
@@ -107,7 +107,7 @@ class IntroJob(BackgroundJob):
107107

108108
def set_intensity(self, intensity):
109109
self.intensity = intensity
110-
led_intensity(channels=self.LED_channel, intensities=self.intensity)
110+
led_intensity({self.LED_channel: self.intensity})
111111

112112
def on_disconnected(self):
113113
self.set_intensity(0)
@@ -133,7 +133,7 @@ class IntroJob(BackgroundJob):
133133

134134
def set_intensity(self, intensity):
135135
self.intensity = intensity
136-
led_intensity(channels=self.LED_channel, intensities=self.intensity)
136+
led_intensity({self.LED_channel: self.intensity})
137137

138138
def on_disconnected(self):
139139
self.set_intensity(0)
@@ -143,7 +143,7 @@ if __name__ == "__main__":
143143
from pioreactor.whoami import get_assigned_experiment_name
144144

145145
unit = get_unit_name()
146-
experiment = get_unit_name(unit)
146+
experiment = get_assigned_experiment_name(unit)
147147

148148
job = IntroJob(unit=unit, experiment=experiment)
149149

@@ -210,7 +210,7 @@ We see that the `__init__` requires the two parameters for PWM: `hz` and an `ini
210210
We next initialize the PWM code (this is still in the `__init__`) that controls the PWM outputs on the HAT, and add more imports:
211211

212212
```python
213-
from pioreactor.hardware_mappings import PWM_TO_PIN
213+
from pioreactor.hardware import PWM_TO_PIN
214214
from pioreactor.utils.pwm import PWM
215215
from pioreactor.config import config
216216

@@ -220,7 +220,7 @@ from pioreactor.config import config
220220
def __init__(...)
221221
...
222222

223-
pwm_pin = PWM_TO_PIN[config["PWM_reverse", "motor_driver"]]
223+
pwm_pin = PWM_TO_PIN[config.get("PWM_reverse", "motor_driver")]
224224
self.pwm = PWM(pwm_pin, self.hz)
225225
self.pwm.lock()
226226

@@ -318,7 +318,7 @@ import json
318318

319319
from pioreactor.config import config
320320
from pioreactor.background_jobs.base import BackgroundJob
321-
from pioreactor.hardware_mappings import PWM_TO_PIN
321+
from pioreactor.hardware import PWM_TO_PIN
322322
from pioreactor.utils.pwm import PWM
323323
from pioreactor.utils import clamp
324324

@@ -337,7 +337,7 @@ class MotorDriver(BackgroundJob):
337337
self._initial_duty_cycle = initial_duty_cycle
338338
self.duty_cycle = initial_duty_cycle
339339

340-
self.pwm_pin = PWM_TO_PIN[config["PWM_reverse", "motor_driver"]]
340+
self.pwm_pin = PWM_TO_PIN[config.get("PWM_reverse", "motor_driver")]
341341

342342
self.pwm = PWM(self.pwm_pin, self.hz)
343343
self.pwm.lock()

developer-guide/03-Background jobs/03-avoiding-od.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class JustPause(BackgroundJobWithDodgingContrib):
2222
class JustPause(BackgroundJobWithDodgingContrib):
2323

2424
def __init__(self, ...):
25-
super().__init__(..., enable_dodging_od=True or False) # set to True if you want the dodging behaviour right away.
25+
super().__init__(..., enable_dodging_od=False, plugin_name="just-pause") # set to True if you want the dodging behaviour right away.
2626

2727

2828
def action_to_do_before_od_reading(self):
@@ -45,15 +45,15 @@ You can handle the "dodging" case and "continuous" with the `initialize_*` metho
4545
class JustPause(BackgroundJobWithDodgingContrib):
4646

4747
def __init__(self, ...):
48-
super().__init__(..., enable_dodging_od=True or False) # set to True if you want the dodging behaviour right away.
48+
super().__init__(..., enable_dodging_od=False, plugin_name="just-pause") # set to True if you want the dodging behaviour right away.
4949

5050
...
5151

5252
def initialize_dodging_operation(self):
53-
self.logger("OD reading is ON and I'm enabled for dodging, so set up what I need...")
53+
self.logger.debug("OD reading is ON and I'm enabled for dodging, so set up what I need...")
5454

5555
def initialize_continuous_operation(self):
56-
self.logger("OD reading is off, or being ignored, so set up what I need for that...")
56+
self.logger.debug("OD reading is off, or being ignored, so set up what I need for that...")
5757

5858
def action_to_do_before_od_reading(self):
5959
# example
@@ -69,7 +69,7 @@ class JustPause(BackgroundJobWithDodgingContrib):
6969
4. We also want some "buffer" time before and after an OD reading. For example, if using a bubbler, we want the bubbles to dissipate completely before taking an OD reading. We should stop bubbling early then. To set these times, add the following to your config.ini:
7070

7171
```
72-
[<job_name>]
72+
[<job_name>.config]
7373
pre_delay_duration=<float>
7474
post_delay_duration=<float>
7575
enable_dodging_od=1

developer-guide/04-Automations/02-writing-automations-1.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class NaiveTurbidostat(DosingAutomationJobContrib):
104104

105105
```
106106

107-
Run the script with `pio run dosing_atomation --automation-name naive_turbidostat --target-od 0.5`. This will start the job. After a moment, you may notice that warnings are thrown - that's because there's no optical density measurements being produced! You can use crtl-c to stop the job.
107+
Run the script with `pio run dosing_automation --automation-name naive_turbidostat --target-od 0.5`. This will start the job. After a moment, you may notice that warnings are thrown - that's because there's no optical density measurements being produced! You can use crtl-c to stop the job.
108108

109109
#### Editing attributes over MQTT (optional)
110110

developer-guide/07-Plugins/01-intro-plugins.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,15 +152,15 @@ Here's an example of adding a custom automation: place the following code into t
152152

153153
```python title="/home/pioreactor/.pioreactor/plugins/demo_automation.py"
154154
# -*- coding: utf-8 -*-
155-
from pioreactor.automations.dosing.base import DosingAutomationContrib
155+
from pioreactor.automations.dosing.base import DosingAutomationJobContrib
156156

157157
__plugin_summary__ = "A demo dosing automation"
158158
__plugin_version__ = "0.0.1"
159159
__plugin_name__ = "Demo Dosing Automation"
160160
__plugin_author__ = "Cam Davidson-Pilon"
161161
__plugin_homepage__ = "https://docs.pioreactor.com"
162162

163-
class DemoAutomation(DosingAutomationContrib):
163+
class DemoAutomation(DosingAutomationJobContrib):
164164

165165
automation_name = "demo"
166166

@@ -169,7 +169,7 @@ class DemoAutomation(DosingAutomationContrib):
169169
self.volume = volume
170170

171171
def execute(self):
172-
self.logger("Here I would execute...")
172+
self.logger.debug("Here I would execute...")
173173

174174
```
175175

developer-guide/07-Plugins/03-plugin-as-python-package.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ Here's a general directory outline of how your files should be organized for a j
4343
├─ 📝 setup.py
4444
```
4545

46-
The directory outline is very similar for an **automation plugin** &#151 the only difference is the location of the `.yaml` file.
46+
The directory outline is very similar for an **automation plugin**, the only difference is the location of the `.yaml` file.
4747

4848
```
4949
📁 <DISTRIBUTION-NAME with dashes>
287 KB
Loading
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
---
2+
id: change-model
3+
title: Change your Pioreactor model
4+
sidebar_label: Change Pioreactor model
5+
description: Adjust the Pioreactor model in the Inventory page and register custom models that appear in the UI.
6+
---
7+
8+
9+
## Update a Pioreactor's model from the UI
10+
11+
You can update the model that the software uses for each unit from the **Inventory** page.
12+
13+
1. Navigate to **Inventory** in the sidebar.
14+
2. Locate the Pioreactor you want to configure and open the **Model** dropdown.
15+
3. Pick the correct entry. The change is saved immediately.
16+
17+
![The Inventory page with the Model dropdown highlighted.](/img/user-guide/inventory-model-overview.png)
18+
19+
Changes to the model update any UI text, configuration safety limits, and workflows that depend on vessel geometry.
20+
21+
## Add a custom model
22+
23+
The UI lists every YAML definition stored in `.pioreactor/models/`. Each file represents a single model.
24+
25+
1. Create the directory if it does not already exist:
26+
27+
```bash
28+
mkdir -p ~/.pioreactor/models
29+
```
30+
31+
2. Add a new YAML file. Use a descriptive file name such as `my_custom_model.yaml`.
32+
33+
```yaml
34+
model_name: custom_100ml
35+
model_version: "1.0"
36+
display_name: "Custom 100 mL, v1.0"
37+
reactor_capacity_ml: 100.0
38+
reactor_max_fill_volume_ml: 95.0
39+
reactor_diameter_mm: 50.0
40+
max_temp_to_reduce_heating: 80.0
41+
max_temp_to_disable_heating: 85.0
42+
max_temp_to_shutdown: 90.0
43+
```
44+
45+
### Required fields
46+
47+
| Field | Description |
48+
| --- | --- |
49+
| `model_name` | A unique identifier. Use lowercase letters, numbers, and underscores. Example `pioreactor_20ml` |
50+
| `model_version` | Semantic version string that differentiates variants of the same model. Example: `1.1` |
51+
| `display_name` | What appears in the UI dropdown. Example: `Pioreactor 20ml, v1.1`|
52+
| Capacity and geometry fields | Used by dosing and safety calculations. Provide real measurements in millilitres and millimetres. |
53+
| Temperature limits | Guardrails for the heater. Adjust them to match your hardware. |
54+
55+
If any field fails validation, the Pioreactor logs an error in `pioreactor.log` and skips the file. Double-check spelling and numeric values if your model does not appear.
56+
57+
### Reload the web UI
58+
59+
After adding or editing model files, restart the web UI service so it picks up the new definitions:
60+
61+
```bash
62+
sudo systemctl restart pioreactor-web.target
63+
```
64+
65+
Return to the Inventory page and reopen the **Model** dropdown. Your custom entry should now be available alongside the built-in models.
66+
67+
## Troubleshooting
68+
69+
- **No new dropdown entries:** confirm the YAML file lives in `/home/pioreactor/.pioreactor/models/` on the leader and that the file extension is `.yaml` or `.yml`. Restart the `pioreactor-web.target` service once more.
70+
- **Validation errors in the logs:** open `pioreactor.log` or run `journalctl -u pioreactor-web.target` to view the message, then update the YAML file accordingly.
71+
- **Distribute to workers**: workers need these files to, so if you've added it to your leader, you can run `pios cp ~/.pioreactor/models/my_custom_model.yaml` to distribute it to workers.

user-guide/03-Extending your Pioreactor/04-Experiment Profiles/03-start-stop-profiles.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pio run experiment_profile execute /home/pioreactor/.pioreactor/experiment_profi
5252
Stop all running profiles from the CLI with:
5353

5454
```bash
55-
pio kill --job-name experiment_profiles
55+
pio kill --job-name experiment_profile
5656
```
5757

5858
Or target a specific profile by its job ID:

user-guide/03-Extending your Pioreactor/11-using-stemma-qt.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ To run the script, you'll first need to install the Python library:
2727

2828

2929
```python
30-
import sleep
30+
import time
3131
import board
3232
import adafruit_scd4x
3333

user-guide/29-Automations/02-dosing-automations.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ The chemostat automation is the second simplest dosing automation. Every `durati
4646
* one labelled "media"
4747

4848

49-
A turbidostat ("turbidity-static") tries to keep the turbidity (the optical density, or OD), constant over time. This is usually accomplished by taking frequent measurements of the turbidity (every 30 seconds), and performing a set media/waste pump cycle if the optical density (or normalized optical density) exceeds a `target OD` (or `target nOD`). The amount exchanged is the `volume` parameter (mL). For very fast growing cultures, we recommend a `volume` between 1.0 ml and 2.0 ml.
49+
A turbidostat ("turbidity-static") tries to keep the turbidity (the optical density, or OD), constant over time. This is usually accomplished by taking frequent measurements of the turbidity (every 15 seconds), and performing a set media/waste pump cycle if the optical density (or normalized optical density) exceeds a `target OD` (or `target nOD`). The amount exchanged is the `volume` parameter (mL). For very fast growing cultures, we recommend a `volume` between 1.0 ml and 2.0 ml.
5050

5151
This automation will always dose the `volume` parameter, even if it's not enough for the OD to drop below the `target OD`. If that happens, then `OD > target OD`, and so the automation will trigger after the next check (30 seconds).
5252

@@ -104,7 +104,7 @@ To further avoid overflow, we limit how much liquid is added in a single pump cy
104104
You can edit these parameters in your config.ini files.
105105

106106

107-
#### Section `[dosing_auomation.config]`
107+
#### Section `[dosing_automation.config]`
108108

109109
- `pause_between_subdoses_seconds`: time to wait between doses - this is useful if you want to be sure the newly added liquid is sufficiently mixed before running the waste pump.
110110
- `waste_removal_multiplier`: the amount of additional time to run the waste pump after the influx pump has run. This is to ensure that the volume of liquid in the vial never exceeds the end of the efflux tube. Ex: if media ran for `0.75` seconds, then the waste will run for `waste_removal_multiplier * 0.75 seconds`

0 commit comments

Comments
 (0)