Control a Xiaomi WalkingPad from Python using python-miio, with both:
- a command-line interface (CLI)
- a keyboard-driven terminal UI (TUI)
The codebase is split into reusable layers so future interfaces (for example a REST API) can reuse the same backend service.
- Async-ready application service on top of synchronous
python-miio - Device command support for start/stop, power, lock, speed, start speed, mode, and sensitivity
- Live status polling and event stream for interface consumers
- Keyboard-only TUI controls (no mouse required), focused on core walking-pad actions
- Built-in timing diagnostics for command latency analysis
Default model is ksmb.walkingpad.v1 (configured via .env).
python-miiomay reportksmb.walkingpad.v3in its internal model list depending on version/implementation. This project still allows explicit model configuration and wraps the available WalkingPad command surface.
python -m venv .venv
python -m pip install -e '.[dev]'Create a local environment file:
cp .env.example .envExample .env:
WALKINGPAD_IP=192.168.1.100
WALKINGPAD_TOKEN=YOUR_32_CHAR_TOKEN
WALKINGPAD_MODEL=ksmb.walkingpad.v1
WALKINGPAD_POLLING_INTERVAL=1.0
WALKINGPAD_REQUEST_TIMEOUT=5.0miwalkingpad status
miwalkingpad status --quick
miwalkingpad start
miwalkingpad stop
miwalkingpad power-on
miwalkingpad power-off
miwalkingpad lock
miwalkingpad unlock
miwalkingpad set-speed 3.0
miwalkingpad set-start-speed 2.0
miwalkingpad set-mode manual
miwalkingpad set-sensitivity medium
miwalkingpad discover --timeout 8miwalkingpad tuiCore shortcuts:
q,Esc,Ctrl+C— quitr— refresh statuss— startx— stop+/-— speed adjust in 0.5 km/h steps
TUI notes:
- Speed inputs can be submitted with
Enteror via set buttons. - TUI intentionally hides lock/unlock and sensitivity controls to keep the surface compact.
The TUI log prints timing entries:
timing op=<name> wait=<ms> run=<ms> total=<ms> ok=<bool>
Interpretation:
wait: time waiting for internal service IO lockrun: device call execution timetotal: end-to-end operation time
This helps separate app-side contention from device/network delay.
- Backend/core:
WalkingPadAdapter,AsyncWalkingPadService,AsyncEventBus - Shared types/events/errors:
types/ - Interface layer: CLI + TUI + interface-side composition/factory in
interface/factory.pyand config loading ininterface/config.py
AsyncWalkingPadService in service.py is the single backend API consumed by interfaces.
- Minimal top-level facade in
miwalkingpad/__init__.py:AsyncWalkingPadServiceWalkingPadAdapterAsyncEventBus
- Structured type exports in
miwalkingpad/types/__init__.pyfor models/events/errors.
Example:
from miwalkingpad import AsyncWalkingPadService, WalkingPadAdapter
from miwalkingpad.types import PadMode, PadStatus, ErrorEventpython -m pytest -qCurrent tests cover configuration, event bus fan-out, and service polling/snapshot behavior.
WalkingPad discovery (broadcast, not mDNS) is re-implemented, since python-miio's implementation is not working corrently.
Use:
miwalkingpad discover --timeout 8Output is JSON entries with:
ipdevice_idtokenauth_ok(whether token-based connect/info worked)info(device info payload if token auth succeeded)auth_error(error text if token auth failed)
If WALKINGPAD_TOKEN is set in env / .env, discovery will automatically try
token-auth and fetch extra device info for each discovered IP.
MIT. See LICENSE.