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 voltage tracking + optional ADC divider reader. |
|
Static descriptor for a device (modes + firmware/hardware versions). |
|
BLE client for a remote LEGO PoweredUp / Control+ hub. |
|
BLE server that impersonates a LEGO hub so LEGO apps can connect. |
|
Description of one LPF2 device mode (parsed from Port Mode Info). |
|
Preset |
|
Base LPF2 port. |
|
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 getPercent() int[source]
Compute percentage from current voltage using the mapping installed via
setPercentFunc()(default: linear).
- static readBatteryVoltage() int[source]
Read the divider, average
samplesshots, store viasetCurrentVoltage(). 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 setPercentFunc(fn: Callable[[int, int, int], int] | None) None[source]
Install a custom voltage->percent mapping
fn(mV, vmin, vmax).Pass
Noneto 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_unitare ESP-IDFadc_channel_t/adc_unit_tvalues.r_top_ohms/r_bottom_ohmsdescribe 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.
- 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
portobjects, and exposes hub properties. Registers itself with the firmware’s update registry at construction, soupdate()runs each tick automatically — scripts just wait onisConnected()/infoReady().- getBatteryType() int[source]
Battery type reported by the hub (see
lpf2.battery_type).
- 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).
- getPort(port_num: int) port | None[source]
Return the remote
portatport_num(seelpf2.port_num), orNoneif 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_scanmay be: - a MAC-address string to target a specific hub, - an int scan duration (seconds), or -Noneto usescan_duration.
- 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_pairsis a list of bytes with mode/dataset nibbles (high = mode, low = dataset);deltas_per_modelists the thresholds in the same order.
- 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
portobjects. Configure it first (name, versions, battery), attach ports, thenstart().- 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_emulationinstance; this class does not take ownership.
- 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).
- 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.
- class lpf2.motor_setting[source]
Preset
_motor_settingsinstances for known LPF2 motors.- technic_large_angular_grey: _motor_settings[source]
Technic Large Angular motor (grey Control+ variant).
- class lpf2.port[source]
Base LPF2 port.
Base class for
lpf2.local.port,lpf2.virtual.portand remote ports. Wraps the C++Lpf2::Port. Every port registers itself with the firmware’s update registry at construction, soupdate()is polled automatically each tick — callers just read state viaisDeviceConnected()/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
Noneif 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. Calldisable(False)to resume.Subclasses may release/reacquire transport resources on the transition via the C++
_onDisablehook (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).
- getValue(mode: int, dataSet: int) float[source]
Parsed value of dataset
dataSetofmode. Format (int8/16/32/float) is taken from the mode descriptor.
- getValueStr(mode: int) str[source]
Human-readable value of
modeformatted per the mode’s figures/decimals.
- gotoAbsPosition(absPos: int, speed: int = 100, maxPower: int = 100, endState: int = 0, useProfile: int = 0) None[source]
Move the motor to absolute encoder position
absPosatspeed(0..100) then applyendState.
- 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.
deltais 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.
deltasare 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.colorindex (uses mode 0).
- startPower(pw: int) None[source]
Set motor power.
pwin [-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).maxPowercaps commanded power (0..100).useProfileselects 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; usespeedsign for direction) then applyendState.
- startSpeedForTime(time: int, speed: int = 100, maxPower: int = 100, endState: int = 0, useProfile: int = 0) None[source]
Run the motor at
speedfortimems then applyendState(seelpf2.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()).