lpf2

LEGO Powered-Up LPF2 protocol bindings.

Provides the core LPF2 primitives: ports (local, remote and virtual), typed device wrappers, hub descriptors and a hub-emulation server. Submodules expose the LPF2 enumerations (color, device_type, port_num …).

Submodules

Classes

battery

Battery voltage tracking + optional ADC divider reader.

device_descriptor

Static descriptor for a device (modes + firmware/hardware versions).

hub

BLE client for a remote LEGO PoweredUp / Control+ hub.

hub_emulation

BLE server that impersonates a LEGO hub so LEGO apps can connect.

mode

Description of one LPF2 device mode (parsed from Port Mode Info).

motor_setting

Preset _motor_settings instances for known LPF2 motors.

port

Base LPF2 port.

version

LEGO Wireless Protocol version tuple: Build/Major/Minor/Bugfix.

Package Contents

class lpf2.battery[source]

Battery voltage tracking + optional ADC divider reader.

All methods are static. Defaults: max 9000 mV, min 6000 mV, current voltage equal to max. Percent = linear interpolation between min and max with a cutoff at min.

static getCurrentVoltage() int[source]

Get the last-known current battery voltage in mV.

static getMaxVoltage() int[source]

Get the full-charge voltage in mV.

static getMinVoltage() int[source]

Get the cut-off (0%) voltage in mV.

static getPercent() int[source]

Compute percentage from current voltage using the mapping installed via setPercentFunc() (default: linear).

static readBatteryVoltage() int[source]

Read the divider, average samples shots, store via setCurrentVoltage(). Returns the reading in mV, or 0 if the ADC is not configured.

static setCurrentVoltage(mv: int) None[source]

Manually update the current battery voltage (mV).

Use this if you have your own voltage source (not the built-in ADC divider).

static setMaxVoltage(mv: int) None[source]

Set the full-charge voltage in mV.

static setMinVoltage(mv: int) None[source]

Set the cut-off (0%) voltage in mV.

static setPercentFunc(fn: Callable[[int, int, int], int] | None) None[source]

Install a custom voltage->percent mapping fn(mV, vmin, vmax).

Pass None to restore the default linear mapping.

static setupAdcDivider(adc_channel: int, adc_unit: int, r_top_ohms: float, r_bottom_ohms: float, vref_mv: int = 3300, samples: int = 8) bool[source]

Configure the ESP-IDF ADC + calibration for a resistive divider.

adc_channel/adc_unit are ESP-IDF adc_channel_t / adc_unit_t values. r_top_ohms/r_bottom_ohms describe the divider (battery -> tap -> GND). Returns True on success.

class lpf2.device_descriptor[source]

Static descriptor for a device (modes + firmware/hardware versions).

Used to build virtual devices without a live LPF2 handshake.

fwVersion: version[source]

Firmware version reported by the device.

hwVersion: version[source]

Hardware version reported by the device.

modes: list[mode][source]

List of mode descriptors, indexed by mode number.

class lpf2.hub[source]

BLE client for a remote LEGO PoweredUp / Control+ hub.

Manages the NimBLE scan/connect state, mirrors the remote hub’s ports as port objects, and exposes hub properties. Registers itself with the firmware’s update registry at construction, so update() runs each tick automatically — scripts just wait on isConnected() / infoReady().

connectHub() bool[source]

Attempt to connect to the discovered hub. Returns True on success.

getAllInfoStr() str[source]

Formatted dump of hub properties + port descriptions.

getBatteryType() int[source]

Battery type reported by the hub (see lpf2.battery_type).

getHubAddress() str[source]

BLE MAC address of the hub.

getHubPropStr(prop_id: int) str[source]

String rendering of one hub property (see lpf2.hub_property).

getHubType() int[source]

Hub type reported over BLE (see lpf2.hub_type).

getName() str[source]

Advertised name of the connected hub.

getPort(port_num: int) port | None[source]

Return the remote port at port_num (see lpf2.port_num), or None if not attached.

infoReady() bool[source]

True once all initial info requests (hub props, port modes) have been answered or timed out.

init(addr_or_scan: str | int | None = None, scan_duration: int = 10) None[source]

Prepare BLE stack and set connect target.

addr_or_scan may be: - a MAC-address string to target a specific hub, - an int scan duration (seconds), or - None to use scan_duration.

isConnected() bool[source]

True while the BLE link is up.

isConnecting() bool[source]

True while a connection attempt is in progress.

isScanning() bool[source]

True while BLE is actively scanning.

setName(name: str) None[source]

Change the hub’s advertising name (persisted on the hub).

setPortMode(port_num: int, mode: int, delta: int, notify: bool = True) int[source]

Configure input-format on one remote port. Returns 0 on success.

setPortModeCombo(port_num: int, combo_idx: int, nibble_pairs: Sequence[int], deltas_per_mode: Sequence[int]) int[source]

Configure a combined-mode input-format on one remote port.

nibble_pairs is a list of bytes with mode/dataset nibbles (high = mode, low = dataset); deltas_per_mode lists the thresholds in the same order.

shutDownHub() None[source]

Send the LWP hub-shutdown action to the remote hub.

update() None[source]

Pump BLE state (scan/connect/message handling).

Auto-called each tick from the firmware update registry, so user code does not need to call it. Calling it manually just runs an extra pump early.

class lpf2.hub_emulation[source]

BLE server that impersonates a LEGO hub so LEGO apps can connect.

Advertises the LWP service, handles hub-property/port-info requests and forwards port I/O to attached port objects. Configure it first (name, versions, battery), attach ports, then start().

attachPort(port_num: int, p: port) None[source]

Attach a port object to a port number on the emulated hub.

The port’s lifetime must exceed the hub_emulation instance; this class does not take ownership.

getName() str[source]

Current advertised hub name.

setAlert(alert: int, on: bool) None[source]

Assert or clear a hub alert (see lpf2.alerts).

setBatteryLevel(level: int) None[source]

Reported battery percentage (0..100).

setBatteryType(type: int) None[source]

Reported battery type (see lpf2.battery_type).

setButtonState(state: int) None[source]

Push a button-state update (see lpf2.button_state).

setFirmwareVersion(v: version) None[source]

Firmware version reported to the app.

setHardwareVersion(v: version) None[source]

Hardware version reported to the app.

setName(name: str) None[source]

Advertised hub name.

setUseBuiltInDevices(use: bool) None[source]

If True, initialise the default built-in devices on start. Must be called before start().

start() None[source]

Begin BLE advertising and start the message-handling task.

stop() None[source]

Stop advertising / disconnect / delete the message task.

class lpf2.mode[source]

Description of one LPF2 device mode (parsed from Port Mode Info).

Combines the mode’s name, value range (raw/PCT/SI), I/O mapping flags, dataset layout and the latest raw payload received on the mode.

PCTmax: float[source]

Percent-scale maximum.

PCTmin: float[source]

Percent-scale minimum.

SImax: float[source]

SI-scale maximum.

SImin: float[source]

SI-scale minimum.

dataSets: int[source]

Number of datasets per sample.

decimals: int[source]

Decimals shown for display.

figures: int[source]

Total display figures (integer + decimals).

flags: int[source]

Capability/flags bitmask.

format: int[source]

Sample element format (0=int8, 1=int16, 2=int32, 3=float).

inMapping: int[source]

Input-mapping bitmask (see LWP spec).

max: float[source]

Raw value maximum.

min: float[source]

Raw value minimum.

motorBias: int[source]

Motor bias, per LWP.

name: str[source]

Mode name (from the device).

outMapping: int[source]

Output-mapping bitmask (see LWP spec).

rawData: bytes[source]

Latest raw payload for this mode.

class lpf2.motor_setting[source]

Preset _motor_settings instances for known LPF2 motors.

medium_linear: _motor_settings[source]

Medium linear motor.

technic_large_angular: _motor_settings[source]

Technic Large Angular motor.

technic_large_angular_grey: _motor_settings[source]

Technic Large Angular motor (grey Control+ variant).

technic_large_linear: _motor_settings[source]

Technic Large linear motor.

technic_medium_angular: _motor_settings[source]

Technic Medium Angular motor.

technic_medium_angular_grey: _motor_settings[source]

Technic Medium Angular motor (grey Control+ variant).

technic_xlarge_linear: _motor_settings[source]

Technic XL linear motor.

class lpf2.port[source]

Base LPF2 port.

Base class for lpf2.local.port, lpf2.virtual.port and remote ports. Wraps the C++ Lpf2::Port. Every port registers itself with the firmware’s update registry at construction, so update() is polled automatically each tick — callers just read state via isDeviceConnected() / device() / getValue().

device() devices.basic_motor | devices.encoder_motor | devices.color_sensor | devices.distance_sensor | devices.port_expander | devices.hub_led | devices.accelerometer | devices.gyroscope | None[source]

Return the typed device wrapper for whatever is currently attached, or None if nothing is connected.

disable(disable: bool = True) None[source]

Enable/disable port polling.

When disabled, update() returns immediately without polling the transport or forwarding to the attached device. Use to pause a port temporarily (e.g. while another task drives the same hardware) without tearing down the device wrapper. Call disable(False) to resume.

Subclasses may release/reacquire transport resources on the transition via the C++ _onDisable hook (e.g. deinit UART).

getCapabilities() int[source]

Capability bitmask (bit 0x04 = combinable, if the device has combos).

getDeviceType() int[source]

Reported LPF2 device type (see lpf2.device_type).

getInfoStr() str[source]

Diagnostic dump of port state (device type, modes, versions).

getInputModes() int[source]

Bitmask of modes that produce values.

getMode(num: int) mode | None[source]

mode descriptor for mode num or None.

getModeCombo(combo: int) int[source]

Mode-combo bitmask at index combo. Bit N = mode N.

getModeComboCount() int[source]

Number of active mode-combo entries.

getModeCount() int[source]

Total number of modes exposed by the device.

getOutputModes() int[source]

Bitmask of modes that accept values.

getValue(mode: int, dataSet: int) float[source]

Parsed value of dataset dataSet of mode. Format (int8/16/32/float) is taken from the mode descriptor.

getValueStr(mode: int) str[source]

Human-readable value of mode formatted per the mode’s figures/decimals.

getViewCount() int[source]

Number of modes the device would show in the LEGO app.

gotoAbsPosition(absPos: int, speed: int = 100, maxPower: int = 100, endState: int = 0, useProfile: int = 0) None[source]

Move the motor to absolute encoder position absPos at speed (0..100) then apply endState.

init() None[source]

Optional one-shot setup hook. Default: no-op.

isDeviceConnected() bool[source]

True if a device has been detected on this port.

isDisabled() bool[source]

True if the port is currently disabled.

presetEncoder(pos: int) None[source]

Reset the motor encoder to pos. Also stops the motor.

rawToSpeed(raw: int) int[source]

Convert an LPF2 raw byte to a signed -100..100 speed.

setAccTime(time: int, profile: int) None[source]

Set acceleration time (ms) and profile for the motor.

setDecTime(time: int, profile: int) None[source]

Set deceleration time (ms) and profile for the motor.

setMode(mode: int, delta: float = 1.0) int[source]

Select the device’s active input mode.

delta is the minimum change (in raw units) that triggers a value-change callback. 0 = every update. Returns 0 on success.

setModeCombo(idx: int, deltas: Sequence[float] = ()) int[source]

Activate one of the device’s mode combinations.

deltas are per-mode change thresholds in the order defined by the combo bitmask; empty = default of 1. Returns 0 on success.

setRgbColor(r: int, g: int, b: int) None[source]

Set an RGB LED by explicit RGB (0..255, uses mode 1).

setRgbColorIdx(idx: int) None[source]

Set an RGB LED by lpf2.color index (uses mode 0).

speedToRaw(speed: int) int[source]

Convert a signed -100..100 speed to the LPF2 raw byte (0..255).

startPower(pw: int) None[source]

Set motor power. pw in [-100..100]: negative = CCW, positive = CW.

startSpeed(speed: int = 100, maxPower: int = 100, useProfile: int = 0) None[source]

Run the motor at speed (-100..100). maxPower caps commanded power (0..100). useProfile selects the acc/dec profiles (low nibble = acc, next nibble = dec).

startSpeedForDegrees(degrees: int, speed: int = 100, maxPower: int = 100, endState: int = 0, useProfile: int = 0) None[source]

Move the motor by degrees (positive; use speed sign for direction) then apply endState.

startSpeedForTime(time: int, speed: int = 100, maxPower: int = 100, endState: int = 0, useProfile: int = 0) None[source]

Run the motor at speed for time ms then apply endState (see lpf2.button_state / BrakingStyle).

update() None[source]

Poll the port: run one tick of the underlying transport, then resolve the attached device via the device factory.

The C firmware calls this every tick for every port, so user code does not need to call it. Calling it manually just runs an extra poll early. No-op while the port is disabled (see disable()).

writeData(mode: int, buf: bytes) int[source]

Send a raw payload to the device on the given mode. Returns an error code (0 = ok).

class lpf2.version[source]

LEGO Wireless Protocol version tuple: Build/Major/Minor/Bugfix.

Bugfix: int[source]

Bugfix version.

Build: int[source]

Build number.

Major: int[source]

Major version.

Minor: int[source]

Minor version.