# Creating interface to the instruments and quantum device

**URL:** <https://community.orangeqs.com/t/creating-interface-to-the-instruments-and-quantum-device/36>\
**Category:** Community Support\
**Created:** [March 12, 2026, 9:28am UTC](https://community.orangeqs.com/t/creating-interface-to-the-instruments-and-quantum-device/36 "2026-03-12T09:28:34Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![eendebakpt](https://avatars.discourse-cdn.com/v4/letter/e/3d9bf3/32.png) [@eendebakpt](https://community.orangeqs.com/u/eendebakpt)\
**Post date:** [March 12, 2026, 9:28am UTC](https://community.orangeqs.com/t/creating-interface-to-the-instruments-and-quantum-device/36/1 "2026-03-12T09:28:34Z")

</div>

Hi!

We are evaluating what OQS Juice could do for our labs. One critical element for our setups is how multi users with interact with a single physical set of instruments with a quantum device.

From the architecture page ([Architecture — OrangeQS Juice documentation](https://docs.orangeqs.com/juice/core/v26.11.1/concepts/architecture.html)) I gather this is to be done via a Quantum Device Manager that is itself a Task. Is that correct?

Is there any documentation on the Quantum Device Manger? Or even better: an example of how to create a device manger for a set of QCoDeS instruments?

Kind regards,

Pieter Eendebak

---

<div class="post-metadata">

**Author:** ![kel85uk](https://avatars.discourse-cdn.com/v4/letter/k/9fc29f/32.png) [@kel85uk](https://community.orangeqs.com/u/kel85uk)\
**Post date:** [March 12, 2026, 10:02am UTC](https://community.orangeqs.com/t/creating-interface-to-the-instruments-and-quantum-device/36/2 "2026-03-12T10:02:26Z")

</div>

Hi Pieter,

Thanks for checking out the OQS Juice OS. The Quantum Device Manager shown in the figure is a Service which spawns Tasks within itself ( [Architecture — OrangeQS Juice documentation](https://docs.orangeqs.com/juice/core/v26.11.1/concepts/architecture.html#services) ). The service by itself is an empty jupyterlab IPython kernel, so, it would run the same way with python scripts/console commands as how you would instantiate a set of QCoDeS instruments. As for an example on how to create a Service within OQS Juice, one of which is for the System Monitor service ([System Monitor — OrangeQS Juice documentation](https://docs.orangeqs.com/juice/core/v26.11.1/concepts/system-monitor.html)).

Hope that helps and let us know if you got further questions.

Kind regards,

Kelvin

---

<div class="post-metadata">

**Author:** ![eendebakpt](https://avatars.discourse-cdn.com/v4/letter/e/3d9bf3/32.png) [@eendebakpt](https://community.orangeqs.com/u/eendebakpt)\
**Post date:** [March 13, 2026, 8:50am UTC](https://community.orangeqs.com/t/creating-interface-to-the-instruments-and-quantum-device/36/3 "2026-03-13T08:50:29Z")

</div>

Hi Kelvin,

What I am looking for is instructions how to setup juice OS for a set of real instruments and perform measurements with these instruments.

In the documentation I have not found examples, or a structure for this. For example:

- How to specify which instruments to connect to (driver, IP address, COM port, etc.)
- What an interface could look like from the user side (since this is multi-user, there needs to be some way to interface and schedule measurement tasks).

I could not find the Quantum Device Manager in the codebase, Do you have some more information on this? In particular: if the QDM starts an empty ipython kernel where a user can connect to the instruments using QCoDeS, how will a second user be able to connect to the same set of instruments?

With kind regards,

Pieter Eendebak

---

<div class="post-metadata">

**Author:** ![kel85uk](https://avatars.discourse-cdn.com/v4/letter/k/9fc29f/32.png) [@kel85uk](https://community.orangeqs.com/u/kel85uk)\
**Post date:** [March 16, 2026, 2:19pm UTC](https://community.orangeqs.com/t/creating-interface-to-the-instruments-and-quantum-device/36/4 "2026-03-16T14:19:07Z")

</div>

Hi Pieter,

I will send over a quick-er start guide (likely later tomorrow) especially for this use-case as it is obviously representative for the typical applications we expect from JuiceOS users.

As for the connectivity, as long as the hostOS (e.g. AlmaLinux) can ping/connect to the instruments, then it is simply configuring the orchestration.toml file within `/etc/juice/config` to forward the correct ports (only necessary for serial devices) to the respective service (which I will cover in the document, or in more detail: [orchestration.toml: Orchestration Settings — OrangeQS Juice documentation](https://docs.orangeqs.com/juice/core/v26.11.1/reference/configuration/schemas/orchestration.html)).

The default Services that are out-of-the-box configured in a barebones installation are the Task Manager, System Monitor, and influxdb database service. The Quantum Device Manager is an example Service for which you can create yourself ([First steps after installation — OrangeQS Juice documentation](https://docs.orangeqs.com/juice/core/v26.11.1/tutorials/getting-started/first-steps.html#adding-services)) using the example of the System Monitor (which always come preconfigured). Naturally, we always set it all up for our FLEX line products, the same way as shown in the system architecture diagram.

All user kernels serve as proxy kernels when connecting to a Service kernel ([Accessing services — OrangeQS Juice documentation](https://docs.orangeqs.com/juice/core/v26.11.1/tutorials/basics/accessing-services.html#through-a-proxy-kernel)). This allows then multiple user proxy kernels to interact with the Service kernel (also note the “Connecting to a busy kernel” section for the case of the second user to connect to the same set of instruments (because only the Service kernel is connected to the instrument). If you want to schedule tasks/measurements to run on these services, then sending Tasks from the personal kernels to the Services is the easiest way, allowing you to run your own measurement code on the service (See [Tasks — OrangeQS Juice documentation](https://docs.orangeqs.com/juice/core/dev/concepts/tasks.html#defining-tasks))

Hope this helps for now and until tomorrow.

Kind regards,

Kelvin

---

<div class="post-metadata">

**Author:** ![kel85uk](https://avatars.discourse-cdn.com/v4/letter/k/9fc29f/32.png) [@kel85uk](https://community.orangeqs.com/u/kel85uk)\
**Post date:** [March 17, 2026, 6:14pm UTC](https://community.orangeqs.com/t/creating-interface-to-the-instruments-and-quantum-device/36/5 "2026-03-17T18:14:47Z")

</div>

# Quicker user guide

## Introduction

This is a very condensed user guide meant to provide a quick start for you to create a Quantum Device Manager “device” service within the Juice OS.

It should create the blank “device” service first. After that, you will be introduced to an example of creating a lab initialization script to be run automatically whenever the service starts. Then it moves on to modifying the default `orchestration.toml` file to set up the database bucket for this service and configuring the device service to run the initialization script.

## Housekeeping

These sequential set of instructions assume you have root access to the AlmaLinux distro, and have a basic linux admin ability (i.e. file copy and creation, terminal navigation).

## The guide itself

1. Follow all the instructions for installation here ( [Installation — OrangeQS Juice documentation](https://docs.orangeqs.com/juice/core/v26.11.1/tutorials/getting-started/installation.html) )

2. Verify that you are able to connect to the default juice environment by navigating with a browser to “localhost:8888”. You should see a login page as shown below:

 ![image](https://canada1.discourse-cdn.com/flex029/uploads/orangeqs/original/1X/d30b8492c8f6ec801d79debf18816b57789ec118.png)

2a. Enter the login details for your AlmaLinux account.

2b. Once logged in, you should be seeing a similar starting page:

 ![image](https://canada1.discourse-cdn.com/flex029/uploads/orangeqs/original/1X/23752759ed1e3185e12fb71e5639c55fc2d5aa26.jpeg)

2c. Enter the Jupyterlab environment

 ![image](https://canada1.discourse-cdn.com/flex029/uploads/orangeqs/original/1X/8eb0b0c8b7ff9076afc0edfeb77542601ec86cb3.jpeg)

2d. Edit the default `pyproject.toml` file within the `shared/lib/lab/` directory as shown below to reflect the contents also shown within the image which installs the qcodes, quantify, pyvisa-py and pyserial dependencies on top of the orangeqs-juice-core packages. Save the changes.

 ![image](https://canada1.discourse-cdn.com/flex029/uploads/orangeqs/original/1X/f539d8e398513e47bd091b7d8b7413a96b0ef803.jpeg)

2e. After that, create an `init_device_service.py` file within the `shared/lib/lab/src/lab` directory with the following content:

```python
from __future__ import annotations

# ---------------
# basic imports
# ---------------
import time

# for benchmarking purposes
t0 = time.time()

import os
import sys
from pathlib import Path
from importlib import reload
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import display, SVG
import warnings
from typing import Optional, Any, Tuple
from qcodes import validators
from qcodes.instrument.base import Instrument
from qcodes.instrument.parameter import ManualParameter

warnings.filterwarnings("ignore")

t1 = time.time()
print(f"Finished basic imports {t1-t0:.2f} s")

class DummyFluxCurrent(Instrument):
    """A Dummy QCoDeS instrument for a current source."""

    def __init__ (self, name: str, channel_list: list[str]):
        super(). __init__ (name)

        for channel in channel_list:
            self.add_parameter(
                channel,
                unit="A",
                initial_value=0,
                vals=validators.Numbers(),
                parameter_class=ManualParameter,
            )

class DummyVNA(Instrument):
    """A dummy VNA driver"""

    def __init__ (self, name: str):
        super(). __init__ (name)

        self.MAX_NPTS = 1001

# -------------------------------------------------------------------------------------------------
# Connect VNA
# -------------------------------------------------------------------------------------------------
try:
    vna = DummyVNA(
        name="vna",
    )
    print("Connected to VNA")
except Exception as e:
    print("Something went wrong connecting to the vna:", e)

# -------------------------------------------------------------------------------------------------
# Connect FLUX
# -------------------------------------------------------------------------------------------------
try:
    flux = DummyFluxCurrent(
        name="flux",
        channel_list=["output_1", "output_2", "output_3"]
    )
    print("Connected to current source")
except Exception as e:
    print("Something went wrong connecting to the current source:", e)

t3 = time.time()
print(f"\nFinished loading settings {t3-t0:.2f} s")

```

This file will be used later in the construction of the `orchestration.toml` file.

1. Open the AlmaLinux terminal. Turn on `root` access by `sudo -i` and enter the credentials.

4a. Edit the default `/etc/juice/config/orchestration.toml` file to duplicate these entries:

```auto
# Add the lab extension to the default environment.
# This environment will be used by all services and singleuser containers unless overridden.
# See below for some examples.
[environments.default]
type = "uv"
dependencies = ["lab"]
sources = { lab = { editable = true, path = "~/shared/lib/lab" }}

# This entry creates a device service kernel
[services.device]
entrypoint = "orangeqs.juice.service:IPythonService"

# This entry tells the device service to run a python script called init_device_service.py within the shared/lab repo.
[services.device.init_kwargs]
init_module = "lab.init_device_service"

# This entry creates a service-device data bucket within the influxdb2 database service
[influxdb2.buckets.service-device]
name = "service-device"

## This entry sets any necessary environments for the device service container (e.g.) device port forwarding or volume mounts from hostOS to the service container.

[environments.device.envinronment]
type = "uv"
dependencies = ["lab"]
sources = { lab = { editable = true, path = "~/shared/lib/lab" }}

[services.device.environment.container]
volumes = [
        "/etc/machine-id:/etc/machine-id:ro"
]
# Forward the device /dev/tty1 from AlmaLinux to the device service container device /dev/custom_6
devices = ["/dev/tty1:/dev/custom_6"]
group_add = ["dialout"]

```

The comments within the file should help explain the reasons why they’re there, especially about the device forwarding from AlmaLinux to the service container.

4b. As for the instruments to connect to, as long as the host OS (AlmaLinux) can ping to the device (this is assuming an ethernet connection with the instrument), then any service spawned will be able to connect to it.

1. After you’re done editing, run `juice install --rebuild --restart --no-parallel-build`. You should be able to see the output from the terminal after it has finished rebuilding and restarted.  

2. Go to a web browser and navigate back to `localhost:8888` to spawn the Jupyterlab environment. You should now be able to see an extra `Service: device` button within the Notebook and Console. These will spawn proxy kernels to send instructions directly to the device service kernel. For example, open up the Console for the device service.  

3. You should be taken to a familiar ipython console which is behind the scenes has a proxy kernel which communicates with the device service. The user experience however does not change from your point of view. A simple `dir()` should tell you what objects are available in the device service kernel. If the init script was executed properly, you should be able to see the `vna` and `flux` qcodes instruments and are also able to print their respective snapshots from this same console as shown here:  

4. And to further check that COM devices are forwarded correctly, do an `!ls /dev/` within the same console. In the example `orchestration.toml` we deliberately forwarded the `/dev/tty1` instrument from AlmaLinux to `/dev/custom_6` instrument in the device service container. You should verify that the output is as shown below:  

You now have a very basic Quantum Device Manager “device” service running within your JuiceOS installation.
