Writing a Custom Fridge Backend#

This tutorial walks you through writing a custom fridge backend for OrangeQS Juice.

Overview#

Juice supports pluggable fridge backends, allowing you to integrate any fridge hardware by writing:

  • Your own entrypoint script (to load configurations and launch the service)

  • An Application class (to manage your hardware and publish data)

You should copy the entire mock application code into your own project (for example, as my_package/application.py). Then, replace only the lines that initialize your hardware drivers (thermometers, heaters, compressors, etc.) with your real driver classes. This approach ensures you have a working template and can easily adapt it to your hardware.

What do I need to change?

After copying the mock application, you only need to change the lines that initialize the hardware drivers (MockThermometry, MockHeater, MockPTCompressor, MockGHS). Everything else can remain unchanged.

Prerequisites

You should first read the Fridge Monitor to understand how to configure and launch the system monitor service.

1. Create your own application class#

To create your application class, you can use the mock application class from Juice as a reference and only change the relevant sections.

Copy the full code of the mock application from src/orangeqs/juice/system_monitor/_mock_app.py into your own module (e.g. my_package/application.py).

Then, replace only the following lines with your real driver classes(These lines are highlighted with comments as):

    ##############################################
    ######## Initialize device drivers here ######
    ######## - Replace these for real hardware ###
    ##############################################
    logger.info("System Monitor Device Drivers initialized.")

    self.heaters: dict[str, MockHeater] = {}
    # Initialize cryogenic hardware abstractions here
    for heater_id, heater_settings in self.config.heaters.items():
        self.heaters[heater_id] = MockHeater(heater_id, heater_settings)

    self.thermometry = MockThermometry(self.config.thermometry)

    self.compressors: dict[str, MockPTCompressor] = {}
    for compressor_id, compressor_settings in self.config.compressors.items():
        self.compressors[compressor_id] = MockPTCompressor(
            compressor_id, compressor_settings
        )

    self.ghs = MockGHS(self.config.ghs)

    ##############################################
    ##############################################
    ##############################################
    ##############################################

Important

Your hardware drivers must all have the same API as the ones defined in the mock. This ensures that juice can interact with them through dashboards and retrieve data from them.

For example, you could write your custom thermometry class as:

class MyCustomThermometryUnit:
    def __init__(self, custom_hw_configuration):
        ### Custom code

    async def update(self) -> bool:
        """Update the temperatures from the device."""
        ### Custom Code

    @property
    def temperatures(self) -> list[TemperaturePoint]:
        """ Return data in Juice compatible format."""
        ### Custom Code

and replace the

self.thermometry = MockThermometry(self.config.thermometry)

with

self.thermometry = MyCustomThermometryUnit(self.config.thermometry)

2. Write Your Entrypoint Script#

Create a new entrypoint script (e.g. my_package/_fridge_entrypoint.py). This script should:

  • Instantiate your custom Application class

  • Start the report loop

Example:

import logging
import sys
from orangeqs.juice._util import spawn_thread
from my_package.application import MyFridgeApplication

logger = logging.getLogger(__name__)

try:
    system_monitor = MyFridgeApplication()
    REPORT_THREAD = spawn_thread(system_monitor.report_loop())
    logger.info("Started System Monitor REPORT_THREAD.")
except Exception:
    message = "Failed to start System Monitor. Exiting."
    logger.exception(message)
    sys.exit(message)

3. Start the service and the dashboard#

  1. Create a new service and point it to your fridge backend’s entrypoint. You can do this by adding the following snippet to your orchestration.toml, then running:

    juice install --restart --rebuild

    [services.system-monitor]
    entrypoint = "orangeqs.juice.system_monitor._service:SystemMonitorService"
    
    [services.system-monitor.init_kwargs]
    init_module = "<my_package._my_fridge_entrypoint>" # Your entrypoint
    
    [influxdb2.buckets.system_monitor]
    name = "system_monitor"
    
  2. Double‑check that your task manager shows a running system-monitor service.

  3. With the service running, you can now configure its dashboard. Create a configuration file system-monitor-dashboard.toml. Once saved, click the restart button on your dashboard to apply the changes.