Skip to content

Commit

Permalink
remove old automations, and adding a test that checks automation yaml…
Browse files Browse the repository at this point in the history
… against the Python code
  • Loading branch information
CamDavidsonPilon committed Nov 28, 2023
1 parent 4dcf43b commit 3b9d134
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 83 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
- Previously, if the LED channel was locked (most common when OD reading was running), then any changes to the LED intensity (via the UI) would be silently rejected. This is changed: we have added retry logic that will attempt to keep changing it a few more times (hopefully to avoid the lock)
- Fixed a race condition between starting an automation and not getting OD data in time.
- Added some light form validation in the automations dialog in the UI.
- New environment variable to skip loading plugins, `SKIP_PLUGINS`. Useful for debugging. Ex:
```
SKIP_PLUGINS=1 pio run stirring
```
- The automation form in the UI for pid_morbidostat was missing `volume`, that's been added now.
- Removed `morbidostat` dosing automation, users should try to use pid_morbidostat. The morbidostat code is still available to be added as a custom plugin here: https://github.com/Pioreactor/automation-examples/blob/main/dosing/morbidostat.py
- Removed `constant_duty_cycle` temperature automation. Again, the code is available here: https://github.com/Pioreactor/automation-examples/blob/main/temperature/constant_duty_cycle.py

### 23.11.18
- No more waiting around for growth-rate-calculating to get to "Ready" state
Expand Down
1 change: 0 additions & 1 deletion pioreactor/automations/dosing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

from .chemostat import Chemostat
from .fed_batch import FedBatch
from .morbidostat import Morbidostat
from .pid_morbidostat import PIDMorbidostat
from .silent import Silent
from .turbidostat import Turbidostat
54 changes: 0 additions & 54 deletions pioreactor/automations/dosing/morbidostat.py

This file was deleted.

1 change: 1 addition & 0 deletions pioreactor/automations/led/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

class Silent(LEDAutomationJob):
automation_name = "silent"
published_settings = {"duration": {"datatype": "float", "settable": True, "unit": "min"}}

def __init__(self, **kwargs) -> None:
super(Silent, self).__init__(**kwargs)
Expand Down
1 change: 0 additions & 1 deletion pioreactor/automations/temperature/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
from __future__ import annotations

from .constant_duty_cycle import ConstantDutyCycle
from .only_record_temperature import OnlyRecordTemperature
from .thermostat import Thermostat
20 changes: 0 additions & 20 deletions pioreactor/automations/temperature/constant_duty_cycle.py

This file was deleted.

4 changes: 4 additions & 0 deletions pioreactor/plugin_management/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ def get_plugins() -> dict[str, Plugin]:

plugins: dict[str, Plugin] = {}

if os.environ.get("SKIP_PLUGINS"):
# short circuit out
return plugins

# get entry point plugins
# Users can use Python's entry point system to create rich plugins, see
# example here: https://github.com/Pioreactor/pioreactor-air-bubbler
Expand Down
55 changes: 55 additions & 0 deletions pioreactor/tests/test_automation_yamls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
# test automation_yamls
from __future__ import annotations

from yaml import load # type: ignore
from yaml import Loader # type: ignore

from pioreactor.automations import * # noqa: F403, F401
from pioreactor.background_jobs.dosing_control import DosingController
from pioreactor.background_jobs.led_control import LEDController
from pioreactor.background_jobs.temperature_control import TemperatureController
from pioreactor.mureq import get


def get_specific_yaml(path):
data = get(f"https://raw.githubusercontent.com/Pioreactor/pioreactorui/master/{path}")
return load(data.content, Loader=Loader)


def test_automations_and_their_yamls_have_the_same_data():
for automation_name, klass in LEDController.available_automations.items():
data = get_specific_yaml(f"contrib/automations/led/{automation_name}.yaml")
assert data["automation_name"] == automation_name

for field in data["fields"]:
key = field["key"]
assert field["unit"] == klass.published_settings[key]["unit"]

for setting in klass.published_settings:
assert any([f["key"] == setting for f in data["fields"]])

for automation_name, klass in DosingController.available_automations.items():
data = get_specific_yaml(f"contrib/automations/dosing/{automation_name}.yaml")
assert data["automation_name"] == automation_name

for field in data["fields"]:
key = field["key"]
assert field["unit"] == klass.published_settings[key]["unit"]

for setting in klass.published_settings:
assert any([f["key"] == setting for f in data["fields"]])

for automation_name, klass in TemperatureController.available_automations.items():
data = get_specific_yaml(f"contrib/automations/temperature/{automation_name}.yaml")
assert data["automation_name"] == automation_name

for field in data["fields"]:
key = field["key"]
assert field["unit"] == klass.published_settings[key]["unit"]

for setting in klass.published_settings:
assert any([f["key"] == setting for f in data["fields"]])


# TODO: turn off plugin loading with a env variable.
15 changes: 8 additions & 7 deletions pioreactor/tests/test_temperature_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

from pioreactor import pubsub
from pioreactor import structs
from pioreactor.automations.temperature import ConstantDutyCycle
from pioreactor.automations.temperature import OnlyRecordTemperature
from pioreactor.automations.temperature import Thermostat
from pioreactor.background_jobs import temperature_control
Expand Down Expand Up @@ -96,18 +95,20 @@ def test_changing_temperature_algo_over_mqtt_and_then_update_params() -> None:
f"pioreactor/{unit}/{experiment}/temperature_control/automation/set",
encode(
structs.TemperatureAutomation(
automation_name="constant_duty_cycle", args={"duty_cycle": 25}
automation_name="thermostat", args={"target_temperature": 25}
)
),
)
time.sleep(15)
assert algo.automation_name == "constant_duty_cycle"
assert isinstance(algo.automation_job, ConstantDutyCycle)
assert algo.automation_job.duty_cycle == 25
assert algo.automation_name == "thermostat"
assert isinstance(algo.automation_job, Thermostat)
assert algo.automation_job.target_temperature == 25

pubsub.publish(f"pioreactor/{unit}/{experiment}/temperature_automation/duty_cycle/set", 30)
pubsub.publish(
f"pioreactor/{unit}/{experiment}/temperature_automation/target_temperature/set", 30
)
pause()
assert algo.automation_job.duty_cycle == 30
assert algo.automation_job.target_temperature == 30


def test_heating_is_reduced_when_set_temp_is_exceeded() -> None:
Expand Down

0 comments on commit 3b9d134

Please sign in to comment.