Repository navigation
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.
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.
-
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.
-
On the other computer: copy the folder
openscilab_devicethere and start a demo device:python -m openscilab_device.demo climate --server 192.168.1.20 --token <token>
Without
--serverthe device looks for openSciLab's beacon in the local network. -
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:climateuses 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 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.
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.
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 oneInput 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.
| 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.
- 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.
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.
openSciLab · 0.1 beta
Instruments
Logic analyzer
The lab
More