Skip to main content
Control the power state of USB devices and ports on your testbed using USB hubs with per-port power control.

Import

Methods

Exception Classes

Method Reference

Net.get(name, type=NetType.Usb)

Get a USB net by name.
Parameters: Returns: USB Net instance

enable()

Enable (power on) the USB port.

disable()

Disable (power off) the USB port.

toggle()

Toggle the power state of the USB port. Returns the resulting state (True if now enabled, False if now disabled).

state()

Read the current power state of the USB port without changing it. Returns True if the port is currently enabled (powered on), False if disabled. The value is read live from the hub, so it always reflects the real port state.

cycle(off_time=None)

Power-cycle the port: off, wait, on. The return value tells you what the hub saw:
  • True — the device re-enumerated.
  • False — the device did not come back in time.
  • None — the hub reports nothing attached, or the driver cannot observe re-enumeration.
None does not mean the port is unused. A hub only sees a device that pulls up its data lines. A charge-only cable carries power on the other end but no data. Such a cable is therefore indistinguishable from an empty socket. Power is cut and restored either way; there is simply nothing on the bus to watch come back. Confirm a DUT on such a port by its own behavior instead: its UART output, or a current measurement.
off_time is how long the port stays unpowered, defaulting to 1 second and limited to 0.5-10 seconds. Too short an off time is the failure that matters. The device’s rails do not fully discharge, so the device warm-starts and only appears to reset. Raise it for a device with large bulk capacitance.
Prefer this over a hand-rolled disable/sleep/enable. It gives two guarantees that the hand-rolled form does not:
  • It holds the hub for the whole sequence, so nothing else can switch the port while it is dark.
  • It restores power on every failure path, so an exception partway through cannot leave a port stranded.
cycle returns on the hub’s reconnect signal, a few hundred milliseconds after power returns — not on Linux finishing enumeration. So /dev/ttyUSB* can be absent when it returns, and a /sys read taken immediately still shows the pre-cycle device number. Poll for what you need rather than reading once.
A powered-off port still appears in lsusb and keeps its /dev/ttyUSB*. Hubs raise no change notification while a port is unpowered, so the kernel does not process the disconnect until power returns. Never check for a device’s absence to decide whether a port is off — use state(), which reads the hub’s own power bit.

recover()

Restore power after an interrupted operation left a port unpowered. On hubs where lager can identify the whole physical device, this re-powers every port on it.

Examples

Basic Power Control

Power Cycle Device

Error Handling

Automated Test Setup

USB Device Reset

Toggle for Quick State Change

Supported Hardware

Backend classes

Net.get(name, type=NetType.Usb) returns a wrapper that dispatches to the backend for whichever hub the net names. Use that wrapper in most scripts. The per-backend classes are also importable directly, for code that needs to name one:
They are exported from lager.automation and from lager.automation.usb_hub.
Prefer Net.get. If you construct a backend class directly, you tie the script to one model of hub. To move that test to a bench with a different hub, you must then edit code rather than the net record.

Notes

  • USB nets must be configured on the Lager Box with hub serial number and port mapping
  • Power state changes take effect immediately
  • Allow time for USB enumeration after powering on (~1-3 seconds). cycle() does this waiting for you and tells you whether the device returned
  • Power cycling can be useful for device reset/recovery; prefer cycle() over a hand-rolled disable/sleep/enable so a failure cannot leave a port off
  • A port that is powered off still appears in lsusb and keeps its device nodes. Never use device presence to test whether a port is off
  • The toggle() function is useful for quick state changes
  • Use exception handling for robust error recovery