Skip to main content

Crate lager

Crate lager 

Source
Expand description

First-class Rust access to Lager nets, so embedded developers can write their entire hardware-in-the-loop test suite in Rust and run it with cargo test — no Python required.

The crate is a pure HTTP/JSON client of the Lager box’s API on port 9000: power supplies, battery simulators, e-loads, solar simulators, GPIO, ADC, DAC, thermocouples, watt meters, energy analyzers, SPI, I2C, USB hub ports, robot arms, webcams, routers, and (behind the uart feature) streaming UART. Box-level capabilities — the box’s own BLE adapter (LagerBox::ble), WiFi interface (LagerBox::wifi), and BluFi ESP32 provisioning (LagerBox::blufi) — are exposed the same way. Debug-probe nets (nets::debug::DebugNet) talk to the box’s debug service on port 8765 for flash/erase/reset/memory-read and RTT log streaming.

§Quickstart

[dev-dependencies]
lager = { package = "lager-net", version = "0.2" }
use lager::{LagerBox, Level};

#[test]
fn dut_boots_at_3v3() -> lager::Result<()> {
    let lager = LagerBox::from_env()?; // reads LAGER_BOX_HOST
    let supply = lager.supply("supply1");
    let boot_ok = lager.gpio("boot_ok");

    supply.set_voltage(3.3)?;
    supply.enable()?;
    // Hardware-timed wait on the box; returns elapsed seconds.
    let t = boot_ok.wait_for_level(Level::High, 5.0)?;
    println!("booted in {t:.3}s");
    supply.disable()
}

§Concurrency

The box serializes access per physical instrument (a single-owner hardware service with per-device locks), so parallel cargo tests can never interleave I/O on one instrument. Tests sharing a net still observe each other’s state changes — partition nets across tests or run cargo test -- --test-threads=1 when that matters.

§Boxes behind an authenticating gateway

Boxes fronted by an authenticating reverse proxy (gateway) reject unauthenticated traffic with 401 + an X-Gateway-Auth-Url header. The crate handles this transparently: it reuses the session created by lager login <auth_url> (the Lager CLI’s token store in ~/.lager_gateway_auth), attaches Authorization: Bearer to every request — including debug-service and UART Socket.IO traffic — and refreshes expired access tokens automatically. For CI or machines without a CLI login, pin a token with LagerBoxBuilder::bearer_token or the LAGER_GATEWAY_TOKEN environment variable. Plain (ungated) boxes are unaffected: no header is sent and no code path runs. When no usable credential exists, calls fail with Error::AuthRequired naming the auth server to log into.

§Features

  • blocking (default): the LagerBox client on ureq — no tokio in the dependency tree.
  • async: the AsyncLagerBox client on reqwest/tokio. Both clients share one wire layer (wire) so they cannot drift.
  • uart: streaming UART sessions over Socket.IO (nets::uart::Uart).

§Not yet on the HTTP API

Oscilloscope workflows are not yet exposed on any box HTTP API; nets::scope::Scope ships as a documented stub returning Error::NotSupportedByBox. See MISSING_ENDPOINTS.md in the crate repository.

Re-exports§

pub use nets::battery::BatteryMode;
pub use nets::debug::ConnectOptions;
pub use nets::debug::FirmwareKind;
pub use nets::debug::RttOptions;
pub use nets::eload::EloadMode;
pub use nets::gpio::Level;
pub use nets::gpio::WaitForLevelOptions;
pub use nets::scope::Scope;
pub use nets::spi::BitOrder;
pub use nets::spi::CsActive;
pub use nets::spi::CsMode;
pub use nets::spi::SpiConfig;
pub use nets::spi::SpiOptions;
pub use nets::spi::SpiTransfer;
pub use wire::DebugConnection;
pub use wire::DebugInfo;
pub use wire::DebugStatus;
pub use wire::GdbServer;
pub use nets::adc::Adc;
pub use nets::arm::Arm;
pub use nets::battery::Battery;
pub use nets::ble::Ble;
pub use nets::blufi::Blufi;
pub use nets::dac::Dac;
pub use nets::debug::DebugNet;
pub use nets::debug::RttStream;
pub use nets::eload::Eload;
pub use nets::energy::EnergyAnalyzer;
pub use nets::gpio::Gpio;
pub use nets::i2c::I2c;
pub use nets::router::Router;
pub use nets::solar::Solar;
pub use nets::spi::Spi;
pub use nets::supply::Supply;
pub use nets::thermocouple::Thermocouple;
pub use nets::usb::UsbPort;
pub use nets::watt::WattMeter;
pub use nets::webcam::Webcam;
pub use nets::wifi::Wifi;
pub use nets::adc::AsyncAdc;
pub use nets::arm::AsyncArm;
pub use nets::battery::AsyncBattery;
pub use nets::ble::AsyncBle;
pub use nets::blufi::AsyncBlufi;
pub use nets::dac::AsyncDac;
pub use nets::debug::AsyncDebugNet;
pub use nets::eload::AsyncEload;
pub use nets::energy::AsyncEnergyAnalyzer;
pub use nets::gpio::AsyncGpio;
pub use nets::i2c::AsyncI2c;
pub use nets::router::AsyncRouter;
pub use nets::solar::AsyncSolar;
pub use nets::spi::AsyncSpi;
pub use nets::supply::AsyncSupply;
pub use nets::thermocouple::AsyncThermocouple;
pub use nets::usb::AsyncUsbPort;
pub use nets::watt::AsyncWattMeter;
pub use nets::webcam::AsyncWebcam;
pub use nets::wifi::AsyncWifi;
pub use nets::uart::Uart;
pub use wire::ArmPosition;
pub use wire::BatteryState;
pub use wire::BleCharacteristic;
pub use wire::BleDevice;
pub use wire::BleDeviceInfo;
pub use wire::BleService;
pub use wire::BlufiDeviceInfo;
pub use wire::BlufiNetwork;
pub use wire::BlufiProvisionResult;
pub use wire::BlufiStatus;
pub use wire::BoxCapabilities;
pub use wire::BoxStatus;
pub use wire::EloadState;
pub use wire::EnergyReading;
pub use wire::EnergyStats;
pub use wire::Health;
pub use wire::NetRecord;
pub use wire::NetSummary;
pub use wire::RouterSystemInfo;
pub use wire::StatSummary;
pub use wire::SupplyState;
pub use wire::WattReading;
pub use wire::WebcamStatus;
pub use wire::WebcamStream;
pub use wire::WifiAccessPoint;
pub use wire::WifiConnection;
pub use wire::WifiInterface;
pub use nets::i2c::I2cEffectiveConfig;
pub use nets::spi::SpiEffectiveConfig;

Modules§

nets
Typed handles for each Lager net type.
wire
Sans-io wire layer: request builders and response parsers for the Lager box HTTP API on port 9000.

Structs§

AsyncLagerBox
A connection to one Lager box, over async HTTP (reqwest/tokio).
AsyncLagerBoxBuilder
Builder for AsyncLagerBox, for overriding the default timeout, the debug-service URL, and gateway auth.
LagerBox
A connection to one Lager box, over blocking HTTP.
LagerBoxBuilder
Builder for LagerBox, for overriding the default timeout, the debug-service URL, and gateway auth.

Enums§

Error
All the ways a Lager box interaction can fail.

Constants§

BOX_HOST_ENV
Environment variable read by from_env constructors (LAGER_BOX_HOST).
DEBUG_SERVICE_URL_ENV
Environment variable that overrides the debug-service base URL (LAGER_DEBUG_SERVICE_URL), e.g. http://127.0.0.1:8765 when tunneling.
GATEWAY_AUTH_FILE_ENV
Environment variable that overrides the path of the Lager CLI’s gateway token store (LAGER_GATEWAY_AUTH_FILE; default ~/.lager_gateway_auth). The crate reads sessions created by lager login from this file, so the same name/semantics as the CLI are honored.
GATEWAY_TOKEN_ENV
Environment variable holding a bearer token for boxes behind an authenticating gateway (LAGER_GATEWAY_TOKEN). When set, every request carries Authorization: Bearer <token>. Equivalent to LagerBoxBuilder::bearer_token.

Type Aliases§

Result
Convenience alias used by every fallible API in this crate.