Skip to content

Commit

Permalink
support new od config; sync-configs should apply to leader-only piore…
Browse files Browse the repository at this point in the history
…actors too
  • Loading branch information
CamDavidsonPilon committed Aug 14, 2024
1 parent 2241fd3 commit 877932c
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 19 deletions.
32 changes: 31 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,39 @@
### Upcoming

#### Enhancements

- introduce a new od_reading config,`turn_off_leds_during_reading`, which enables / disables turning off the other LEDS during an OD snapshot. By default, it is set to 1 (enables).
- leader-only Pioreactors also have a `config_hostname.local` file now.
- a new top-level section in experiment profiles, `inputs`, allows you to define variables that can be used in expressions. This is useful if you are copy the same constant over an over again, and want a quick way to change it once. Example:

```
inputs:
growth_phase_temp: 37.0
stationary_phase_temp: 30.0
od_threshold: 1.6
common:
jobs:
temperature_automation:
actions:
...
- type: update
hours_elapsed: 12.0
if: ${{ ::od_reading:od1.od < od_threshold }}
options:
target_temperature: ${{ stationary_phase_temp }}
- type: update
hours_elapsed: 12.0
if: ${{ ::od_reading:od1.od >= od_threshold }}
options:
target_temperature: ${{ growth_phase_temp }}
```

#### Bug fixes

- more resilience to "UI state" diverging from "bioreactor state". Often, this occurred when two jobs stared almost immediately (often a networking issue), and the last job would halt since it couldn't get the required resources, however any MQTT data would be overwritten by the last job. Now, multiple places in the request pipeline will reduce duplication and prevent two jobs from starting too close to each other.
- Improved stirring clean up when stopped in quick succession after starting.
- improved stirring clean up when stopped in quick succession after starting.
- if a network isn't found, the `monitor` job will not stall, but warn and continue.

#### Breaking changes
Expand Down
11 changes: 7 additions & 4 deletions pioreactor/background_jobs/od_reading.py
Original file line number Diff line number Diff line change
Expand Up @@ -1018,10 +1018,13 @@ def add_post_read_callback(cls, function: Callable):

@property
def ir_led_on_and_rest_off_state(self) -> dict[pt.LedChannel, pt.LedIntensityValue]:
return {
channel: (self.ir_led_intensity if channel == self.ir_channel else 0.0)
for channel in led_utils.ALL_LED_CHANNELS
}
if config.getboolean("od_reading.config", "turn_off_leds_during_reading", fallback=True):
return {
channel: (self.ir_led_intensity if channel == self.ir_channel else 0.0)
for channel in led_utils.ALL_LED_CHANNELS
}
else:
return {self.ir_channel: self.ir_led_intensity}

def record_from_adc(self) -> structs.ODReadings:
"""
Expand Down
8 changes: 4 additions & 4 deletions pioreactor/cli/pios.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ def _thread_function(unit: str):
multiple=True,
default=(UNIVERSAL_IDENTIFIER,),
type=click.STRING,
help="specify a hostname, default is all active units",
help="specify a hostname, default is all units",
)
@click.option(
"--shared",
Expand All @@ -405,7 +405,7 @@ def _thread_function(unit: str):
@click.option(
"--specific",
is_flag=True,
help="sync the worker specific config.ini(s)",
help="sync the specific config.ini(s)",
)
@click.option(
"--skip-save",
Expand All @@ -415,14 +415,14 @@ def _thread_function(unit: str):
@click.option("-y", is_flag=True, help="(does nothing currently)")
def sync_configs(units: tuple[str, ...], shared: bool, specific: bool, skip_save: bool, y: bool) -> None:
"""
Deploys the shared config.ini and worker specific config.inis to the workers.
Deploys the shared config.ini and specific config.inis to the pioreactor units.
If neither `--shared` not `--specific` are specified, both are set to true.
"""
from sh import ErrorReturnCode_12 # type: ignore

logger = create_logger("sync_configs", unit=get_unit_name(), experiment=UNIVERSAL_EXPERIMENT)
units = universal_identifier_to_all_workers(units)
units = add_leader(universal_identifier_to_all_workers(units))

if not shared and not specific:
shared = specific = True
Expand Down
27 changes: 19 additions & 8 deletions pioreactor/tests/test_led_intensity.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,28 +46,39 @@ def test_change_leds_intensities_temporarily() -> None:
unit = get_unit_name()
exp = "test_change_leds_intensities_temporarily"

led_intensity({"A": 20, "B": 20}, unit=unit, experiment=exp)
original_settings: dict[LedChannel, float] = {"A": 20, "B": 20, "D": 1.0, "C": 0.0}
led_intensity(original_settings, unit=unit, experiment=exp)

with change_leds_intensities_temporarily({"A": 10}, unit=unit, experiment=exp):
with local_intermittent_storage("leds") as cache:
assert float(cache["A"]) == 10
assert float(cache["B"]) == 20
assert float(cache["B"]) == original_settings["B"]

with local_intermittent_storage("leds") as cache:
assert float(cache["A"]) == 20
assert float(cache["B"]) == 20
assert float(cache["A"]) == original_settings["A"]
assert float(cache["B"]) == original_settings["B"]
assert float(cache["C"]) == original_settings["C"]
assert float(cache["D"]) == original_settings["D"]

with change_leds_intensities_temporarily({"A": 10, "C": 10, "D": 0}, unit=unit, experiment=exp):
with local_intermittent_storage("leds") as cache:
assert float(cache["A"]) == 10
assert float(cache["B"]) == 20
assert float(cache["B"]) == original_settings["B"]
assert float(cache["C"]) == 10
assert float(cache["D"]) == 0

with local_intermittent_storage("leds") as cache:
assert float(cache["A"]) == 20
assert float(cache["C"]) == 0
assert float(cache["D"]) == 0
assert float(cache["A"]) == original_settings["A"]
assert float(cache["B"]) == original_settings["B"]
assert float(cache["C"]) == original_settings["C"]
assert float(cache["D"]) == original_settings["D"]

with change_leds_intensities_temporarily({}, unit=unit, experiment=exp):
with local_intermittent_storage("leds") as cache:
assert float(cache["A"]) == original_settings["A"]
assert float(cache["B"]) == original_settings["B"]
assert float(cache["C"]) == original_settings["C"]
assert float(cache["D"]) == original_settings["D"]


def test_local_cache_is_updated() -> None:
Expand Down
3 changes: 1 addition & 2 deletions update_scripts/upcoming/update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ export LC_ALL=C

PIO_DIR=/home/pioreactor/.pioreactor

# all pioreactors get a unit_config, include leader-only pioworekrs
touch $PIO_DIR/unit_config.ini


HOSTNAME=$(hostname)
Expand All @@ -18,6 +16,7 @@ HOSTNAME=$(hostname)
LEADER_HOSTNAME=$(crudini --get $PIO_DIR/config.ini cluster.topology leader_hostname)

if [ "$HOSTNAME" = "$LEADER_HOSTNAME" ]; then
touch "$PIO_DIR/config_$HOSTNAME.ini" # create if it doesn't exist.

# stirring -> stirring.config
# Iterate over each ini file in the directory
Expand Down

0 comments on commit 877932c

Please sign in to comment.