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 hidapi          # the only runtime dependency
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
reboot() / enter_bootloader() danger zone
send(cmd, payload) / request(cmd, expect, payload) / read_frame() raw access for PDO / programmable / OTA commands not yet wrapped

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.

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.1.0.tar.gz (14.2 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.1.0-py3-none-any.whl (11.6 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for pymp305-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8625b36bb6a01ec472ab52273fdb0a214f5c85584130922d327441017318ec73
MD5 50c64e97df6bb35a063c63b038f1b4f6
BLAKE2b-256 e1e54e34d192d510897cf5f9d132ca605f458bdfcf0aac56bf9e82f10464e08f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pymp305-0.1.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.1.0-py3-none-any.whl.

File metadata

  • Download URL: pymp305-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 11.6 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.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 65c605f00267b617f48bf2f9b809a85d8840dcfe403b5459f143bb08b02d0f2b
MD5 11127f6036baf9aa418b4b70f1ad2bfa
BLAKE2b-256 4e7311a0320042d7167c860b68836d9d082bfd06cd47d53313572195dc6479be

See more details on using hashes here.

Provenance

The following attestation bundles were made for pymp305-0.1.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