ORION Bridge
ORION Bridge connects lab equipment — xArm cobots, ABB robots, Siemens S7 PLCs, MuJoCo/Gazebo simulations, and local shell — to the ORION cloud platform. The bridge runs next to the hardware and opens a single outbound WebSocket to the ORION backend, so no inbound ports need to be exposed in the lab network. New device types plug in as handler packages via Python entry points; a cookiecutter template and a step-by-step guide are included.
Further reading: HANDLERS.md (handler plugin contract) and TUTORIAL_PLUGINS.md (write your first plugin).
Quick start
Option A — one line, no Python required
This installs uv, downloads Python 3.10 if
needed, and puts the orion command on your PATH. Nothing to preinstall.
Windows (PowerShell):
irm https://raw.githubusercontent.com/Starman26/orion-bridge-v2/main/install.ps1 | iex
Linux / macOS:
curl -LsSf https://raw.githubusercontent.com/Starman26/orion-bridge-v2/main/install.sh | sh
Then:
orion # sign in if needed, then add a device and Start Bridge
orion login # sign in from the terminal instead
orion --cli # terminal menu
To include optional hardware drivers (mujoco, plc, gazebo, http),
set ORION_EXTRAS before running the one-liner, e.g.
$env:ORION_EXTRAS = "mujoco,plc" (PowerShell) or ORION_EXTRAS="mujoco,plc"
(bash).
Option B — already have Python? Just pip install
pip install --upgrade "orion-bridge[all]" # core + GUI + all device drivers
orion # opens the GUI (use `orion --cli` for the terminal menu)
The base package already includes the GUI, the cloud/login stack, and the
xArm SDK, so a plain pip install orion-bridge gives a working bridge for
physical xArms. On Windows the first run registers the Python Scripts
directory in your user PATH automatically — if orion is not recognized
right after installing, open a new terminal. If another program named
orion shadows the command (e.g. Oracle's ORION disk benchmark), use the
orion-bridge alias or python -m orion_bridge.
For a lighter install pick only the device drivers you need:
pip install "orion-bridge[mujoco]" # MuJoCo simulation
pip install "orion-bridge[gazebo]" # Gazebo via rosbridge
pip install "orion-bridge[plc]" # Siemens S7 snap7
pip install "orion-bridge[http]" # PLC REST sidecar (Flask)
pip install "orion-bridge[sim-viewer]" # MuJoCo + in-process viewer (imgui)
Available extras: xarm, abb, plc, gazebo, mujoco, sim-viewer,
http, cloud, gui, all. (xarm, cloud, and gui now ship in the
base install; they remain as extras so existing install commands keep
resolving.)
Configuration
Profiles are stored in ~/.orion/connections.toml.
The wizard creates this file on first run. You can also edit it directly.
connections.toml format
# Which profile to use when no --connection flag is given
[default]
profile = "mezzanine"
# One [connections.<name>] section per lab
[connections.mezzanine]
server = "wss://your-server.example.com/ws/robot"
lab_id = "mezzanine"
bridge_id = "hostname-mezzanine" # unique per bridge process
token_env = "ORION_TOKEN_MEZZANINE" # real token read from this env-var
[[connections.mezzanine.devices]]
type = "xarm"
id = "xarm-lab1"
ip = "192.168.1.185"
[[connections.mezzanine.devices]]
type = "shell"
id = "shell-local"
# A second profile (e.g. local dev)
[connections.dev]
server = "ws://localhost:8000/ws/robot"
lab_id = "dev"
bridge_id = "localhost-dev"
token_env = "ORION_TOKEN_DEV"
[[connections.dev.devices]]
type = "xarm"
id = "xarm6-mujoco"
handler = "mujoco"
viewer = true
mjcf_path = "sim/models/xarm6/scene_xarm6.xml"
Token management
The token is never stored in the TOML file. Set the env-var named in
token_env before starting:
export ORION_TOKEN_MEZZANINE="your-secret-token"
orion --connection mezzanine
Or use a .env file with python-dotenv / direnv. If token_env is
left empty, the bridge authenticates with your orion login session
instead.
CLI flags
| Flag | Description |
|---|---|
orion |
Open the GUI (default) |
orion --cli |
Interactive terminal menu instead of the GUI |
orion --start |
Start the bridge directly, skip the menu (headless / service mode) |
orion --connection NAME |
Use a specific profile (-c NAME also works) |
orion --list |
Print all saved profiles and exit |
orion --local |
Run without a server (local dispatch only) |
orion --portable |
USB/portable mode: config and credentials in ./orion_data/ |
orion --config FILE |
Legacy: load a JSON config file and start |
orion --version |
Print version and exit |
Subcommands:
| Command | Description |
|---|---|
orion login |
Sign in via the ORION web platform (browser) |
orion login --otp |
Sign in with an email OTP code instead |
orion logout |
Clear stored credentials |
orion repl |
Interactive REPL (requires prior login) |
orion handlers |
List all registered device handlers (built-in + plugins) |
orion conformance |
Check whether handlers do what their capability cards declare |
orion create-plugin |
Wizard to scaffold a custom handler plugin |
Migrating from lab_config.json
If you have a legacy lab_config.json from an older installation, run orion
once — on first run (no connections.toml yet) the bridge detects the file
and migrates it to connections.toml. The JSON file is left untouched.
You can also migrate manually from Python:
from orion_bridge.connections import migrate_from_json
name = migrate_from_json("lab_config.json")
print(f"Migrated to profile '{name}'")
Supported devices
| Type | Handler | Notes |
|---|---|---|
xarm |
physical (default) |
UFACTORY SDK over IP (xArm 6/7, Lite 6) |
xarm |
mujoco |
MuJoCo simulation (pip install "orion-bridge[mujoco]") |
xarm |
gazebo |
Gazebo via rosbridge (pip install "orion-bridge[gazebo]") |
abb |
TCP socket | RAPID SocketServer |
plc |
snap7 | Siemens S7-1200 (pip install "orion-bridge[plc]") |
shell |
subprocess | Local commands (whitelisted) |
failure |
simulated | Fault injection module for training scenarios |
Additional device types (e.g. UR, Schneider Lexium, Cognex cameras) ship as
separate handler plugins. Run orion handlers to list everything registered
on your machine, and see HANDLERS.md to write your own.
Environment variables
| Variable | Required | Description |
|---|---|---|
ORION_TOKEN_<NAME> |
Per profile | Bridge token; exact name set by the profile's token_env. Optional when using an orion login session |
SUPABASE_URL |
No | Override the built-in Supabase project URL |
SUPABASE_ANON_KEY |
No | Override the built-in anon key — NOT service_role |
ORION_PLATFORM_URL |
No | Web platform URL used for browser login |
PLC_HTTP_PORT |
No | Port for the PLC REST sidecar (default 5000) |
PLC_HTTP_ENABLED |
No | Set to false to disable the PLC REST sidecar |
SHELL_WHITELIST |
No | Comma-separated commands the shell handler may run |
SHELL_TIMEOUT |
No | Shell command timeout in seconds (default 30) |
ORION_LOG_LEVEL |
No | Log level for the running bridge (default WARNING). Set to INFO to see connect / reconnect / registration lines — the record of how the bridge behaves across a dropped connection |
ORION_PORTABLE |
No | Same effect as --portable |
ORION_TEST_PLUGINS |
No | Pipe-separated plugin zips to hot-load at startup |
ORION_EXTRAS |
No | Extras installed by the one-line installer |
Authentication
Bridges have two authentication layers:
- User identity:
orion loginopens the ORION web platform in your browser (or useorion login --otpfor an email OTP code). The session is stored in~/.orion/credentials.jsonand is required for the GUI, the interactive menu, andorion repl. - Bridge identity: each profile carries a
bridge_idplus a token, read from the env-var named intoken_env— or taken from the login session whentoken_envis empty.
orion login # browser sign-in, stores JWT in ~/.orion/credentials.json
orion logout # removes stored credentials
orion repl # interactive REPL — requires prior login
Headless invocations (orion --start, orion --list, orion --config)
work without login, e.g. for lab PCs running the bridge as a service.
Architecture
The bridge has a written contract with each of its two consumers, plus decision records for the choices that are not recoverable from the code:
| docs/protocol.md | The bridge↔cloud wire protocol (v1.0) |
| HANDLERS.md | The bridge↔agent capability-card contract |
| docs/adr/ | Decision records — digest, card contract, conformance, comms-loss safe state |
| docs/README.md | Index, evidence, and stated limits |
Writing a device plugin
Third-party handlers live in their own pip package and register through the
orion_bridge.handlers entry-point group — no changes to the bridge core.
Scaffold one with orion create-plugin or from the cookiecutter template in
cookiecutter-orion-handler/, then verify it loads with orion handlers.
The full contract is documented in HANDLERS.md; a guided
walkthrough is in TUTORIAL_PLUGINS.md.
Development
pip install -e ".[all]" # editable install with all extras
Tests and CI
Every push and pull request runs the suite on Python 3.10–3.12 (Linux, plus one Windows leg), a clean-wheel install smoke test, and a package metadata check. The same checks run locally with:
pytest --cov=orion_bridge.dispatcher --cov=orion_bridge.capability_cards --cov=orion_bridge.card_schema --cov=orion_bridge.action_digest --cov=orion_bridge.conformance --cov=orion_bridge.handlers.base --cov=orion_bridge.protocol --cov-fail-under=85
The MuJoCo extra is the only one CI installs — the Gazebo and PLC drivers are
guarded by optional imports, so the suite runs without roslibpy or the native
snap7 library.
The frontend's xArm kinematic chain is a build artifact, not a hand-written
file. If tests/test_kinematics_export.py reports it stale, regenerate it:
python scripts/export_kinematics.py
Metadata
Release files for orion-bridge 3.12.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| orion_bridge-3.12.0.tar.gz | 5.4 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| orion_bridge-3.12.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 10.9 MB
Release files / orion_bridge-3.12.0.tar.gz
| Download URL | orion_bridge-3.12.0.tar.gz |
|---|---|
| Size | 5.4 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
05d3c6a72227513964e97a225197c6f4c02731d49453fc2c7ad4b5cbfa94bf67
|
|
BLAKE2b-256 checksum How to use checksums |
06cee21f9f5ce2f193de6dd0c96dce1a0d4d024fe5b1844637e5429ce5d27fde
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.8
|
Release files / orion_bridge-3.12.0-py3-none-any.whl
| Download URL | orion_bridge-3.12.0-py3-none-any.whl |
|---|---|
| Size | 5.4 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ca18e4373013a00bf06df35246cd11ccbe2e8fdffbe8f31b23fb0fcc3987e008
|
|
BLAKE2b-256 checksum How to use checksums |
c2823c6cb43c09ca4038f1fc68c851665d4fd77c393d9851588d9ddee213db80
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.8
|