Skip to content

Remote devices

deckerjulian edited this page Oct 6, 2026 · 1 revision

Remote devices

A script on another computer – a Raspberry Pi with sensors, a PC with a measuring card, a laptop with a sound card – becomes a device of openSciLab. This page shows how to switch remote devices on, how to try them with a demo device or a simulator, how to write such a script with the package openscilab_device, and how openSciLab keeps the time of their values right. The full reference, including the protocol, is docs/remote.md.

How it works

The script describes its inputs, outputs, commands and sync signals and connects to openSciLab over TCP (port 24050). openSciLab uses it like any other instrument: in the device list, in flows, panels and data views.

Every value is stamped on the device with the device's own clock when it is measured. The network only delays it. openSciLab measures the device's clock all the time and converts the times, so the values line up with those of the other instruments.

The package openscilab_device needs Python 3.8 or newer and nothing but the standard library (numpy is used when it is there). It is the folder openscilab_device of the repository; it is also installed with openSciLab from source.

Getting started

  1. In openSciLab: Settings → Remote devices (or the entry Remote devices (off): settings... in the device list). Tick Accept remote devices (scripts with openscilab_device). The page shows the Port (24050), the Token a device needs (New makes another one, Copy copies it) and, under Try it, a command that starts a demo device. With Tell devices in the local network where openSciLab is devices find openSciLab by themselves.

  2. On the other computer: copy the folder openscilab_device there and start a demo device:

    python -m openscilab_device.demo climate --server 192.168.1.20 --token <token>

    Without --server the device looks for openSciLab's beacon in the local network.

  3. Back in openSciLab: the device appears in the device list under Available as climate (remote, ...), with its address and how well its clock is known. Double-click it. Its device card opens on the Remote tab. In a flow, a device node with the address remote:climate uses it.

The demo devices are climate (temperature, humidity, a door contact, a heater and a fan to switch, a calibration command, a sync output), audio (a microphone sending 8 kHz samples in blocks, a 440 Hz tone), echo (sends back every value it is given, to look at latencies) and daq (a measuring box behind USB with a drifting sample clock, a line that records openSciLab's sync signal and a loopback for the latency).

The Remote tab

The device card of a remote device opens on the Remote tab:

  • Clock of the device – Method (measured over the network, sync signal, or not measured yet), Accuracy, Round trip, Jitter, Drift and the number of Measurements.
  • Inputs – the latest value of every input.
  • Outputs – a check box for a truth value, a field for the others (Enter sends the value).
  • Commands – a button per command; the answer shows below.

gpio.write, gpio.read and device.monitor work with the bool and scalar channels of a remote device, so its truth values also appear as pins.

Without a second computer

The simulators run the same demo devices inside openSciLab, each with a clock of its own (minutes apart, with a drift) and an emulated network in between. They are in the Simulators group of the device list:

Entry Address
Simulation: remote climate station remote-sim:climate
Simulation: remote microphone remote-sim:audio
Simulation: remote echo remote-sim:echo
Simulation: remote DAQ (drifting clock, USB, sync line) remote-sim:daq
Simulation: remote DAQ, clock follows UTC (PTP) remote-sim:daq?timescale=utc
Simulation: remote DAQ, shared sample clock remote-sim:daq?shared_clock=1

The Remote tab of a simulated device has a box Simulation: timing: Network latency, Network jitter (milliseconds, one way) and Clock drift (ppm) change at once with Apply; the Clock (its own, following UTC or TAI) and, for the DAQ, a sample clock shared with openSciLab's instruments are chosen when the device starts (Start it again with this clock). The address keeps the settings, e.g. remote-sim:daq?latency=20&jitter=2&drift=200.

The template category Remote devices (Templates menu or the start page) has a climate station, a remote control panel, a remote microphone and a sync signal; Time has the remote DAQ. Start a project → Remote measuring device is a project with the script for the other computer (device/my_device.py) – a simulated remote DAQ stands in until it runs.

Writing a device

from openscilab_device import Device

dev = Device("climate-pi", server="192.168.1.20", token="...")
temperature = dev.input("temperature", kind="scalar", unit="°C")
microphone = dev.input("mic", kind="analog", rate=48000, unit="V")
relay = dev.output("relay", kind="bool", default=False)
heater = dev.output("heater", kind="scalar", unit="W", range=(0, 100))
dev.sync_output("SYNC", lambda level: gpio.output(22, level))

@relay.on_set
def switch(value, at):           # called at the time openSciLab asked for ('at': this device's clock)
    gpio.output(17, value)

@dev.command()
def calibrate(reference=21.0):   # keyword arguments from the flow, the result goes back
    return sensor.calibrate(reference)

dev.start()                      # threads: connect (again), answer the clock measurements, send
while True:
    temperature.send(read_sensor())              # stamped with this computer's clock when called
    microphone.send_block(samples, t0=adc_time)  # samples at the rate, t0: time of the first one
Input kind (dev.input) Arrives in openSciLab as
scalar (with unit) numbers with their time
bool truth values, also a pin for gpio.read
analog, digital (with rate) blocks of samples with their time base
event, text events with data

Outputs (dev.output) are scalar, bool (also a pin for gpio.write) or text. Values sent while the connection is down are kept (up to buffer messages) and follow with their original times. Blocks of analog and digital inputs are only sent while a flow listens to them.

Two templates are in the repository: examples/remote/raspberry_pi.py for a Raspberry Pi (a button, an LED, the CPU temperature, a sync output; it runs without a Pi as well) and examples/remote/ni_daq.py for a NI DAQ.

Blocks from hardware behind USB. send_block(samples) without t0 stamps a block from when it arrived, corrected by a latency – measured with input.calibrate(...) over a loopback or given with latency=. Give t0 when the hardware stamps its samples itself. See docs/remote.md and Time and synchronization.

In flows

Node What it does
remote.receive every value of an input, with the time it was measured on the device
remote.set sets an output at a time a little ahead (lead), so the device applies it on time
remote.call calls a command; result is the answer
remote.sync aligns the device's clock with a sync signal recorded by another instrument

A flow addresses the device as remote:<name>; in the application, remote devices have to be switched on in the settings for that. The inspector offers the inputs, outputs, commands and sync signals the device describes. Remote devices run in real time, not with Fast (virtual time). remote.receive waits a moment and hands values on in the order of their time, so values of two devices meet in the right order. More on the nodes: Nodes.

Time of the values

  • Over the network – always, without doing anything. openSciLab pings the device (16 times right after it connected, then once a second) and fits offset and drift of its clock. On a wired network the error is a fraction of a millisecond, over WiFi a few milliseconds. The Remote tab shows the accuracy.
  • With a sync signal – microseconds. The device drives a sync output that toggles at irregular intervals and reports the time of every edge. Wire it to a channel of a logic analyzer as well, stream that channel and give it to remote.sync. It also works the other way round: a sync input of the device for a pulse openSciLab or a GPS receiver makes.
  • With a time scale (PTP, GPS). A device whose clock follows UTC or TAI says so; when this computer's clock follows it too (Settings → Time), its times are converted without measuring.

Details: Time and synchronization.

Security and the command line

The server listens only while remote devices are switched on. A device needs the token: openSciLab sends a random challenge and the device answers with an HMAC of it, so the token itself never travels. The beacon (UDP port 24051) tells devices in the local network where openSciLab is; switch it off if they all know the address. The connection is not encrypted – use it in your own network, or through a VPN or an SSH tunnel.

openscilab run on the command line starts the server by itself when a flow uses remote: devices, with the port and token of the settings (Scripting).

Devices in other languages (MicroPython, C++) can speak the protocol too; it is described in docs/remote.md, with openscilab_device/protocol.py as the reference.

Clone this wiki locally