Plugin/automation not appearing in UI

I had a bit of difficulty getting an automation to appear in the UI, but I finally managed it. I did have a couple errors pop along the way though. I had several issues/areas of difficulty that I wanted to provide feedback on.

I based my dosing automation off the chemostat automation and I was referring to the adding plugins to the UI webpage.

  1. Unclear where to place Python file.

I ended up getting the alt_media_chemostat.py to appear in the pioreactor1.local/plugins page by placing the file in ~/.pioreactor/plugins/ directory, but it wasn’t clear to me at first where to put it. On the linked “adding plugins to ui” page, it shows where to place the .yaml files but doesn’t mention the proper location to put the .py files.

  1. Where to place the .yaml files

The “adding plugins to ui” suggests that /var/www/pioreactorui/contrib/jobs/ is for “default” jobs and /user/pioreactor/.pioreactor/plugins/ui/jobs is the directory for custom plugins. I had a bit of confusion arising from several sources. First, I think the path should say /*home*/pioreactor/... and not /user/pioreactor/.... I tried looking around /usr/ but wasn’t finding anything pioreactor related (that I remember). Second, I didn’t (at first) realize there was a distinction between adding a background job/custom python script/custom automation. I think something that might be useful is having a section at the top of the page that shows the various directory paths in one location and says what types of .yamls go where.

Lastly, I haven’t been able to get my alt_chemostat.py automation to show up in the dosing automations when I placed them in the recommended directory (/home/pioreactor/.pioreactor/plugins/ui/automations/dosing/). I tried several times/locations and refreshed the web page, but was not able to get it to appear. I was only able to get my new automation to appear when I placed it in /var/www/pioreactorui/contrib/automations/.

  1. YAML errors with unknown fields.

I encountered several errors in the recent event log saying “Object contains unknown field [e.g., ‘description’]”. The reason for this error was that I structured my .yaml file after the .yaml example in “Adding a custom background job to the list of activities”. This example contains several fields (e.g., display, description, published_settings, type, etc…) that will give errors if you’re adding a custom automation. I didn’t see anything to indicate that the allowable objects for a custom automation are different from the allowable objects for a background job.

  1. General difficulty navigating file system.

I would find it helpful to have a reference page somewhere that lists most/all of the different directories with pioreactor files. This might be partially due to my inexperience with linux/Raspberry Pi, but I tend to have some difficulty remembering where things are or navigating through the Pi’s directories.

Automation File
File Location: /home/pioreactor/.pioreactor/plugins/alt_media_chemostat.py

# -*- coding: utf-8 -*-

from __future__ import annotations

from pioreactor.automations import events
from pioreactor.automations.dosing.base import DosingAutomationJobContrib
from pioreactor.exc import CalibrationError
from pioreactor.utils import local_persistant_storage

__plugin_summary__ = "An extension of the chemostat automation to allow a second media source."
__plugin_version__ = "0.0.1"
__plugin_name__ = "Alt Chemostat Automation"
__plugin_author__ = "realPeteDavidson"
__plugin_homepage__ = "https://docs.pioreactor.com"

class AltChemostat(DosingAutomationJobContrib):
    """
    Alternate Chemostat mode - try to keep [media] and [alt_media] constant.
    """

    automation_name = "alt_chemostat"
    published_settings = {
            "media_volume": {"datatype": "float", "settable": True, "unit": "mL"},
            "duration": {"datatype": "float", "settable": True, "unit": "min"},
            "alt_media_volume": {"datatype": "float", "settable": True, "unit": "mL"},
            }

    def __init__(self, media_volume: float | str, alt_media_volume: float | str, **kwargs) -> None:
        super().__init__(**kwargs)

        with local_persistant_storage("current_pump_calibration") as cache:
            if "media" not in cache:
                raise CalibrationError("Media pump calibration must be performed first.")
            elif "waste" not in cache:
                raise CalibrationError("Waste pump calibration must be performed first.")
            elif "alt_media" not in cache:
                raise CalibrationError("Alt_Media pump calibration must be performed first.")

        self.media = float(media_volume)
        self.alt_media = float(alt_media_volume)
        self.volume = self.media + self.alt_media

    def execute(self) -> events.DilutionEvent:
        volume_actually_cycled = self.execute_io_action(media_ml = self.media, alt_media_ml = self.alt_media, waste_ml = self.volume)
        return events.DilutionEvent(
                f"exchanged {volume_actually_cycled['waste_ml']}mL",
                data={"volume_actually_cycled": volume_actually_cycled["waste_ml"]},
                )

Working YAML
File Location: /var/www/pioreactorui/contrib/automations/dosing/alt_chemostat.yaml

---
display_name: Alternate Chemostat
automation_name: alt_chemostat
description: Testing for now.
fields:
  - key: media_volume
    unit: mL
    label: Added media volume
    default: 0.5
  - key: alt_media_volume
    unit: mL
    label: Added alt_media volume
    default: 0.1
  - key: duration
    unit: min
    label: Duration
    default: 20

Not-Working YAML
File Location: /home/pioreactor/.pioreactor/plugins/ui/automations/dosing/alt_chemostat.yaml

---
display_name: Alternate Chemostat
automation_name: alt_chemostat
display: True
source: Alt Chemostat Automation
description: Testing for now.
published_settings:
  - key: media_volume
    unit: mL
    label: Added media volume
    description: Media to be added each duration.
    type: numeric
    default: 0.5
    display: true
  - key: alt_media_volume
    unit: mL
    label: Added alt_media volume
    description: Alt media to be added each duration.
    type: numeric
    default: 0.1
    display: true
  - key: duration
    unit: min
    label: Duration
    description: Time between media and alt_media additions.
    type: numeric
    default: 20
    display: true

This is great, ty. You did point out some errors (and ambiguity) that I’ve now corrected in the docs.

I tried several times/locations and refreshed the web page, but was not able to get it to appear. I was only able to get my new automation to appear when I placed it in /var/www/pioreactorui/contrib/automations/.

This was a documentation error: the path was wrong. It’s fixed now, but since you have it in /var/www/... that works fine, too. The correct path should have been /home/pioreactor/plugins/ui/contrib/automations/dosing/

I would find it helpful to have a reference page somewhere that lists most/all of the different directories with pioreactor files. This might be partially due to my inexperience with linux/Raspberry Pi, but I tend to have some difficulty remembering where things are or navigating through the Pi’s directories.

This is a great idea for a page on the docs site. I’ll add it in the coming weeks.

I didn’t (at first) realize there was a distinction between adding a background job/custom python script/custom automation. I think something that might be useful is having a section at the top of the page that shows the various directory paths in one location and says what types of .yamls go where.

:+1: yup, agree. Thanks for the feedback.


Here’s a docs page on the filesystem locations: Important locations on the filesystem | Pioreactor Docs

Thanks. I think I figured out why I was initially having difficulty getting it to show up in the web UI.

Currently, the default file structure is missing the /contrib/ folder.

ls ~/.pioreactor/plugins/ui/ shows the following folders:
~/.pioreactor/plugins/ui/automations
~/.pioreactor/plugins/ui/charts
~/.pioreactor/plugins/ui/jobs

When I was placing my .yaml folders inside ~/.pioreactor/plugins/ui/automations/dosing/, it was not showing up. I managed to fix this by creating a new directory path:
~/.pioreactor/plugins/ui/contrib/automations/dosing/example.yaml

1 Like