emberviewer

June 9, 2026 · View on GitHub

A cross-platform desktop viewer for the Ember+ control protocol (Lawo) - an open alternative to Lawo's Windows-only EmberPlusView.exe, from one Rust codebase for Windows, macOS and Linux.

Keep an address book of providers, browse a provider's tree, view & set parameters with live subscriptions, route matrices, invoke functions, and watch streamed meters - plus a server mode to operate the running desktop app from any phone or laptop browser on your network.

Status: usable. Tested against real broadcast gear - Lawo (Power Core, mc²36, VSM, Virtual Patch Bay, vPro8, Gadget Server, DMS), Riedel MicroN, Arkona AT300, DirectOut Maven, 2wcom RF10e, Tieline Gateway - and the node-emberplus stack.

Why

EmberPlusView.exe has been the de-facto Ember+ tool for years and does the job well. emberviewer offers an open, cross-platform alternative: the same browsing, get/set, matrices, functions and streams, rebuilt from the protocol up, with a few quality-of-life additions.

Features

  • Address book - providers in folders, drag-and-drop, JSON persistence; optional auto-connect on startup.
  • Browse - lazy getDirectory tree walking, filter by identifier, sort, copy path/identifier.
  • View & set - type-aware editors (int, real, string, bool, trigger, enum); sliders honour min/max, factor and printf format; read-only vs read-write badged.
  • Live updates - visible parameters auto-subscribe and reflect pushed changes; collapsing unsubscribes.
  • Matrices - crosspoint grid with device-resolved source/target labels, click to route, configurable orientation, and a signal-parameters popup.
  • Functions - argument form, invoke, rendered result.
  • Streams / meters - StreamFormat-aware decode; a vertical meter for the selected parameter, plus pop-out windows.
  • Server mode - serve the UI to phones/laptops on your LAN; token-protected, with read-only and open-LAN modes (see below).
  • Discovery - find providers via mDNS (_ember._tcp).
  • More - per-parameter change logging (window or file), dark/light theme, an opt-in safety lock against accidental edits, a TX/RX traffic counter, and robust transport (keep-alive, reconnect with backoff, multi-package S101 reassembly).

Update check

On launch emberviewer checks GitHub once a day for a newer release and shows an "Update available" note if there is one. This is the only thing it contacts besides your Ember+ devices: it's a normal HTTPS request to GitHub's API (so GitHub sees your IP), and it sends nothing about your devices. Turn it off in Options -> "Check for updates on startup".

Server mode

Ember+ gear usually sits behind a firewall only the engineering PC can reach, and embedded devices cap how many consumers may connect. Server mode makes the desktop app the single gateway: it holds one connection per provider and fans the live tree out to every viewer - the local window and any number of browsers.

Ember+ devices ──TCP──► emberviewer (engineering PC) ──HTTP/WebSocket──► 📱💻 browsers
                        one connection per device      shared live tree

Browsers run the same egui UI compiled to WebAssembly and never touch the devices directly; documents cross the WebSocket as the device's original Glow/BER bytes. A shared token is required by default (toggle open on LAN or read-only as needed), and a copyable URL + QR code make joining one-tap.

Enable it: Options → Server modeEnable, pick a port (default 8080) and interface, then open the URL on another device. Published release binaries already embed the web bundle; building it yourself needs one extra step (see Building).

Install

Grab a build from Releases (Windows .zip, macOS/Linux .tar.gz). On first launch Windows may warn about an unsigned binary - More info → Run anyway. Or build from source.

Building

Requires a Rust toolchain.

cargo build --release --workspace
cargo test  --workspace      # unit + interop tests against captured real frames
cargo run   -p emberviewer

On Debian/Ubuntu the GUI needs:

sudo apt install libgtk-3-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev \
                 libxkbcommon-dev libgl1-mesa-dev

Web bundle (for server mode): a plain build serves a placeholder; to embed the real browser UI, build the wasm bundle first:

rustup target add wasm32-unknown-unknown
cargo install wasm-bindgen-cli --version <wasm-bindgen crate version>   # versions must match
./scripts/build-web.sh          # → crates/emberviewer/web-dist/ (gitignored)
cargo build --release -p emberviewer

CI does this automatically, so published release binaries already ship the web UI.

Architecture

A cargo workspace with the protocol cleanly separated from the UI:

CrateRole
ember-protoPure protocol, no I/O: S101 framing and the Glow schema as BER via rasn. Compiles to wasm unchanged.
ember-netAsync tokio TCP transport. Native, server-side only.
ember-web-protoThe WebSocket wire vocabulary for server mode (JSON control + binary document framing).
emberviewerThe app (egui/eframe): a native desktop binary (with an embedded axum server) and a wasm browser client, from one source.

The wire format is three nested layers over TCP (default port 9000):

TCP → S101 frames → BER (TLV) → Glow tree (nodes, parameters, matrices, functions, streams)

Implemented from scratch (no mature Ember+ library exists in Rust); a few non-obvious details - ASN.1 REAL following libember's IEEE-exponent convention, RELATIVE-OID paths, the outer [APPLICATION 0] Root wrapper - are handled in ember-proto/src/glow.rs and covered by tests.

Test provider

A small node-emberplus provider lives in testprovider/ (one parameter of each type, matrices, a function, streamed meters):

cd testprovider && npm install && node server.js     # listens on 0.0.0.0:9000

Point the app at 127.0.0.1:9000, or walk the tree headlessly:

cargo run -p ember-net --example walk -- 127.0.0.1:9000

Contributing

Issues and PRs welcome. CI runs cargo fmt --check, clippy -D warnings, and the test suite across Linux/macOS/Windows; please keep those green.

License

MIT.