Skip to main content

Python driver for the ISDT MP305 (MP305A/MP305B) smart bench power supply over USB-HID

Project description

pymp305

A pure-Python driver for the ISDT MP305 smart bench power supplies (MP305A and MP305B), talking to it over USB-HID — the same transport the official WebLink web app uses. Reverse-engineered from WebLink's public source-maps; the full protocol is documented in ../PROTOCOL.md. (The recovered upstream JS used during RE is ISDT's copyright and is kept locally under reversing/, which is git-ignored and not published.)

Status: written from the recovered firmware protocol but not yet validated against real hardware (the device hasn't arrived). The framing layer is covered by golden-vector tests (tests/test_protocol.py, all passing). See Bring-up below for first-run checks.

Install

pip install pymp305          # USB-HID (pulls in hidapi)
pip install pymp305[ble]     # + Bluetooth transport (bleak)

From source (development): pip install -e . from this directory.

On Linux you'll need permission to access the hidraw node. Either run as root for a quick test, or add a udev rule (recommended):

# /etc/udev/rules.d/99-pymp305.rules
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="28e9", MODE="0660", TAG+="uaccess"

then sudo udevadm control --reload && sudo udevadm trigger and replug.

Quick start

from pymp305 import MP305

with MP305.open() as psu:
    print(psu.hardware_info())            # name, hw/boot/app versions

    psu.set_output(voltage=5.0, current=1.0, on=True)   # takes remote control + enables output

    st = psu.read_state()
    print(f"{st.voltage:.2f} V  {st.current:.3f} A  {st.power:.2f} W  {st.temperature} C")

    psu.output_off()
    psu.release_remote()                  # hand control back to the front panel

See examples/basic.py for a live-streaming example.

API surface

Method Does
MP305.list_devices() enumerate VID 0x28E9 HID interfaces
MP305.open(path=None) open (auto-picks usage_page 0x01 / usage 0x04)
hardware_info() 0xE00xE1 device id, firmware versions
read_state(realtime=True) 0xBD/0xC20xC3 live V/I/W/Wh/temp/output (State)
read_system_settings() 0xC40xC5 (SystemSettings)
set_output(voltage, current, on, model=0) take control + apply, returns fresh State
output_on() / output_off() toggle output
release_remote() remoteCon=0 — return control to the panel
control(ControlCommand) low-level 0xC8
set_system_settings(SystemSetCommand) 0xC6
charge(ChargeCommand) 0xEE battery-charge mode
set_language(i) 0xA2
read_charge_state() / read_charge_settings() 0xEC0xED / 0xEA0xEB (ChargeState / ChargeInfo)
charge(ChargeCommand) 0xEE start/stop a charge
read_pdo(id) / pdo_connect(PDOConnect) 0xD00xD1 read PD profile / 0xE80xE9 select it
read_program_list() / read_program_steps(id, n) 0xD40xD5 / 0xD80xD9
read_program_state() / program_connect(ProgramConnect) 0xDE0xDF / 0xE20xE3 run a sequence
flash(Firmware, confirm=True) experimental OTA (see warnings)
reboot() / enter_bootloader() danger zone
send(cmd, payload) / request(cmd, expect, payload) / read_frame() raw access for any other command

Units are converted for you: voltage/set_voltage in V, current/set_current in A, power in W, energy in Wh, temperature in °C, working_time in s.

Transports

  • MP305 — synchronous, USB-HID (this table).
  • MP305BLE — the same API but async over Bluetooth (bleak); methods are coroutines and connection is await MP305BLE.open(). See examples/ble.py.

Firmware (pymp305.ota)

  • Firmware.parse(bytes) — decrypt + verify an official .bin (key is in the header).
  • IntelHexFirmware.parse(...) — the BLE FEE1 firmware format.
  • tools/fetch_firmware.py downloads + decrypts official images into git-ignored reversing/.
  • OTA writing is experimental and untested on hardware — see the repo banner.

Bring-up checklist (first run with hardware)

  1. python -c "from pymp305 import MP305; print(MP305.list_devices())" — confirm the device shows up under VID 0x28E9 and note its usage_page/usage.
  2. psu.hardware_info() — if the de-stuffed name/version look right, framing is correct.
  3. If reads time out: the device may not use a fixed 64-byte report. Try MP305(dev, report_size=N) with other sizes, or pass an explicit interface path.
  4. read_state() polls with the realtime command (0xBD) like the app; if that yields nothing, try read_state(realtime=False) (0xC2).

Tests

python tests/test_protocol.py        # or: pytest

These validate the framing/checksum/stuffing and unit decoding without hardware.

BLE (not implemented here)

The MP305 also speaks the same command set over BLE (used by the PolyLink phone app): GATT service 0000af00-…, characteristic af01 for command/notify, af02 for the binding handshake and chunked writes, plus fee0/fee1 for OTA. BLE frames drop the length/0xAA/checksum wrapper and are just [0x12, cmd, …payload]. Wrapping that with bleak would reuse responses.py directly — left as a future addition.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pymp305-0.2.0.tar.gz (28.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pymp305-0.2.0-py3-none-any.whl (25.1 kB view details)

Uploaded Python 3

File details

Details for the file pymp305-0.2.0.tar.gz.

File metadata

  • Download URL: pymp305-0.2.0.tar.gz
  • Upload date:
  • Size: 28.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pymp305-0.2.0.tar.gz
Algorithm Hash digest
SHA256 e187ec68be01a150037cb7024754db0cffce6602fa66be74595365f6324db000
MD5 f50e098d59f447941769a3212c792f3a
BLAKE2b-256 922c1709ef96387ec2268fdcd52ffad12b1486337f1a7398e5ab498f044a31d7

See more details on using hashes here.

Provenance

The following attestation bundles were made for pymp305-0.2.0.tar.gz:

Publisher: publish.yml on nemanjan00/pymp305

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pymp305-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: pymp305-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 25.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pymp305-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c1e63e669cf88c81a67176f06401ea2e16ae898bc40f9752947104690f1607be
MD5 d366db1e2374307a75ba32d170e2380f
BLAKE2b-256 40801808497a730aa2beb59bd71966aabea9d9133166e4efd3570e6b85ac3655

See more details on using hashes here.

Provenance

The following attestation bundles were made for pymp305-0.2.0-py3-none-any.whl:

Publisher: publish.yml on nemanjan00/pymp305

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page