Skip to main content

hidock-python

A Python library and command line tool to list and download recordings directly from a HiDock P1 over USB. No HiNotes account or cloud service is needed.

Hardware verified on a P1 (10d6:b00e), firmware 1.4.7, using macOS on Apple Silicon. H1, H1E, and P1 Mini are not enabled or tested. The library supports device information, battery/storage status, clock, recording status/quality, settings, listing, downloads, and individual recording deletion. Writes and deletion occur only through explicit API calls or CLI options.

Install

Python 3.10 or newer and a native libusb installation are required.

# macOS
brew install libusb

python3 -m venv .venv
source .venv/bin/activate
python -m pip install hidock-python

The PyPI distribution is hidock-python; Python imports remain hidock and the command line executable is hidock. To work from a source checkout, use python -m pip install -e . instead.

On Debian/Ubuntu, install libusb-1.0-0 and grant your user access to the P1 with an appropriate udev rule. Windows requires libusb and a compatible USB driver for the vendor interface. These platforms have not been hardware tested.

Disconnect the recorder in HiNotes or close the browser tab using it before connecting through Python. One application can claim its USB interface at a time. Use the USB data connection on the recorder.

Command line

hidock info
hidock battery
hidock battery --json
hidock storage
hidock storage --json
hidock clock
hidock clock --sync
hidock recording-status
hidock recording-status --json
hidock quality
hidock settings
hidock list
hidock list --json
hidock download '2026Jan01-120000-Rec00.hda' recordings/sample.hda
hidock download-all recordings/

python -m hidock accepts the same arguments. --serial USB_SERIAL before the subcommand selects a device by its USB serial descriptor (which can differ from the serial returned by info).

download takes an exact device filename and an output file path. download-all takes an output directory, preserves device filenames, and skips existing files with the same byte count. A same-size skip does not verify file contents. If an existing file has a different size, the command stops to avoid overwriting it. Use --overwrite explicitly to replace local files.

Python

from pathlib import Path
from hidock import HiDock

with HiDock() as dock:
    print(dock.info())
    recordings = dock.list_recordings()
    for recording in recordings:
        print(recording.name, recording.size)

    if recordings:
        recording = recordings[0]
        dock.download(recording, Path('recordings') / recording.name)

You can also pass an exact filename to download. Its optional progress(bytes_saved, total_bytes) callback runs synchronously during transfer. Set timeout=20 on HiDock to allow a longer idle wait per response frame. Keep one device session for sequential operations; operations on an instance are serialized. A failed download closes the connection so queued data cannot contaminate a retry; open a new context before retrying.

Each Recording has name, size, version, and the device's opaque signature metadata. The signature is not treated as a content checksum.

Battery status

from hidock import HiDock

with HiDock() as dock:
    battery = dock.battery_status()
    print(battery.percent, battery.status, battery.voltage_volts)

battery_status() returns a BatteryStatus with percent (0–100), status (idle, charging, full, or unknown), voltage_microvolts, and the raw status_code. The voltage_volts property converts microvolts to volts. Unrecognized state codes are preserved and labeled unknown; malformed responses and percentages above 100 raise ProtocolError.

The read-only battery command (0x1004) was verified on the connected P1 with firmware 1.4.7. hidock battery prints a short status line; hidock battery --json outputs the four stored fields for scripts.

Storage information

from hidock import HiDock

with HiDock() as dock:
    storage = dock.storage_info()
    print(storage.total_bytes, storage.free_bytes, storage.used_bytes)
    print(storage.used_percent)

storage_info() returns a StorageInfo with total_bytes, free_bytes, used_bytes, and the raw card status_code. Its used_percent property gives the percentage of capacity used. hidock storage displays sizes in GiB; hidock storage --json outputs the four stored fields, with sizes in bytes.

The read-only card-information command (0x0010) was verified on the P1 with firmware 1.4.7. The device reports free and total capacity in whole MiB; byte values therefore have MiB precision. Used space is total minus free, so it includes filesystem overhead and can differ from the sum of recording sizes. Usable capacity can be smaller than the advertised storage size. The raw status code is preserved without interpreting it as a health assessment.

Truncated replies, capacities outside the supported 100 MiB–256 GiB range, and free space greater than capacity raise ProtocolError. Extra firmware metadata following the first 12 payload bytes is ignored.

Device clock and recording status

from datetime import datetime
from hidock import HiDock

with HiDock() as dock:
    print(dock.get_time())         # datetime, or None if uninitialized
    print(dock.recording_status())
    # Explicitly change the clock, if desired:
    dock.set_time()               # synchronize to the computer's local time
    # dock.set_time(datetime(2026, 11, 6, 12, 30))

hidock clock reads the clock. hidock clock --sync synchronizes it with the computer's current local time; hidock clock --set 2026-11-06T12:30:00 supplies a specific time. Both read and write commands accept --json and output {"time": "2026-11-06T12:30:00"} (or null for an uninitialized clock). Clock reads do not modify the device. The clock stores wall time with one-second precision and no timezone. Timezone-aware Python values or ISO inputs retain their supplied wall-clock components without conversion. A successful set returns the requested time after checking the device acknowledgement; call get_time() separately for readback. Malformed clock data and rejected clock updates raise ProtocolError.

recording_status() returns RecordingStatus with is_recording, recording (the active filename or None), duration_seconds, type (recording, whisper, unknown, or None), type_code, and samples (raw sample values). An empty response indicates idle. Unknown recording type codes are preserved. The CLI command hidock recording-status displays the current snapshot; --json includes all fields. It never starts or stops recording. Duration is the device's 16-bit field, and the library does not infer longer elapsed times.

Clock reading (0x0002) and an idle status reply (0x001d) were verified on the P1 with firmware 1.4.7. Clock writing (0x0003) and active recording payloads follow the public HiNotes parser and are covered by simulated-device tests; they have not been exercised against a live recording on this device.

Recording quality, settings, and file management

hidock quality
hidock quality --set high
hidock quality --set normal
hidock settings --json
hidock settings --auto-record off --auto-play on
hidock settings --notification off --bluetooth-tone on --record-on-vibe on
hidock delete 'exact-recording-name.hda' --dry-run
hidock delete 'exact-recording-name.hda'

quality and settings read the current values when no write options are provided. Both support --json. Supported settings are auto_record, auto_play, notification (notification sounds), bluetooth_tone (Bluetooth prompt sounds), and record_on_vibe (record during Vibe Mic use).

from hidock import HiDock

with HiDock() as dock:
    quality = dock.get_recording_quality()  # RecordingQuality(quality, raw_code)
    settings = dock.get_settings()         # DeviceSettings
    # Explicit writes, when desired:
    # dock.set_recording_quality("high")
    # dock.set_settings(auto_play=True, notification=False)
    # dock.delete_recording("exact-recording-name.hda")

Recording quality is normal, high, or unknown with the raw numeric code preserved. For normal quality writes, the P1's firmware-dependent encoding is selected automatically: code 2 before 1.4.6, code 0 from 1.4.6 onward. High uses code 1. The setting affects future captures, not previously saved audio. Changing quality does not convert existing downloads.

get_settings() returns a DeviceSettings object containing five optional boolean fields and raw_values (the original uint32 fields). Missing or unrecognized setting values are None. set_settings() changes only supplied boolean fields; None means leave unchanged. Unsupported fields and invalid values are rejected before sending a write. Omitted fields use the protocol's zero/unchanged sentinel, including for Bluetooth tones, whose on/off encoding is inverted. Quality and settings writes check the acknowledgement, then read back the result. A mismatch raises ProtocolError; it does not automatically roll back an acknowledged change. After a timeout, re-read the current state before deciding to retry.

File management includes the existing list, download, and download-all commands plus delete for permanent deletion of a single exact device filename. There is no wildcard expansion inside the library. delete --dry-run checks the file exists and displays the intended deletion without sending a delete command. Actual deletion rechecks the file list and current recording status, refuses an active recording, and checks the device acknowledgement. It leaves local downloaded audio and transcripts untouched. The device can change state between the status check and deletion; the library cannot make those commands atomic with physical button presses or other device activity.

delete_recording(name_or_recording) returns True after a successful deletion. Missing files raise FileNotFoundError; use missing_ok=True to return False instead. Failed or malformed write acknowledgements raise ProtocolError.

Quality and settings reads were verified on the P1 with firmware 1.4.7. Write payloads follow the public HiNotes implementation. Writes and deletion are covered by simulated-device tests; no recordings were deleted or device settings changed during hardware verification. Storage formatting, firmware updates, file renaming, and file uploads are not implemented.

Local transcription

Install the optional transcription dependencies:

python -m pip install 'hidock-python[transcription]'

From a source checkout, use python -m pip install -e '.[transcription]'.

Add --transcribe to either download command to save a UTF-8 .txt transcript beside each audio file (sample.hda produces sample.txt):

hidock download '2026Jan01-120000-Rec00.hda' recordings/sample.hda --transcribe
hidock download-all recordings/ --transcribe --language en
hidock transcribe recordings/sample.hda --model base --language en

The standalone transcribe command works on local audio without a USB connection. Use --output transcript.txt to choose a different transcript path. The --model, --language, --model-cache, and --offline options are supported by both download commands and by transcribe.

Speech recognition runs locally using faster-whisper, on the CPU with int8 computation. Audio is never uploaded. The default multilingual base model downloads from Hugging Face on first transcription and is reused across files. Set --model tiny for a smaller model or --model small for a larger one. Language is detected automatically unless supplied with --language en (or another language code). Model accuracy varies with speech and recording quality. Silence detection is enabled; recordings without detected speech produce an empty transcript. There is no speaker identification.

Use --model-cache .models to keep model downloads in a chosen directory. After downloading once, --offline restricts loading to cached files; --model can also name a local converted Whisper model directory. No external FFmpeg installation is needed: faster-whisper uses PyAV to decode the audio, including the P1's MP3 content in .hda files.

download-all --transcribe also transcribes existing same-size audio files whose transcripts are missing. Existing transcripts are skipped unless --overwrite is set. --overwrite on download commands replaces both local audio and transcripts. A transcription error stops the command with a nonzero exit code and retains completed audio and previous transcripts. Retry with hidock transcribe, or rerun the batch to fill missing transcripts.

The Python API supports the same flow, with one reusable model:

from hidock import HiDock, WhisperTranscriber

transcriber = WhisperTranscriber(model="base", language="en")
with HiDock() as dock:
    recordings = dock.list_recordings()
    if recordings:
        dock.download(recordings[0], "recordings/sample.hda", transcriber=transcriber)

# Or transcribe previously downloaded audio without opening the device:
transcriber.transcribe("recordings/other.hda")

WhisperTranscriber.transcribe returns the transcript path, and refuses to replace an existing transcript unless overwrite=True. HiDock.download continues to return the audio path. You may implement the Transcriber protocol to plug in another engine. Base USB functionality does not import or require faster-whisper when transcription is unused.

File handling and validation

Downloads stream to a temporary file beside the requested destination and are published only when their byte count matches the device's file-list metadata. An interrupted or short transfer raises an error and removes its temporary file. Existing files are preserved by default, including when another process creates the destination during a download.

USB protocol frames are decoded by declared payload length, independent of USB read boundaries. Every frame header and padding is removed without searching audio bytes for header-like patterns. Memory use during transfer is bounded by USB/frame buffers rather than recording length.

Original recording bytes are preserved. The small .hda sample downloaded from the tested P1 is MP3 audio (48 kHz mono, 96 kbps). You may choose an .mp3 destination for compatible recordings; changing the extension does not convert audio. The library does not assume every firmware or recording mode uses MP3.

Tests

python -m unittest discover -s tests -v

Tests exercise fragmented and coalesced frames, padding, embedded header-like audio bytes, multi-frame file lists and downloads, malformed responses, timeouts, atomic publication, and overwrite protection without hardware.

Protocol references

MIT licensed; see LICENSE. Maintainers can follow the release guide to build and publish packages.

The implementation was independently written using the public hidock-mcp protocol implementation and HiDock Local P1 protocol notes, then checked against the connected P1. Some historical P1 notes use hard-coded sequence numbers and approximate download sizes; this implementation uses incrementing big-endian sequence numbers, response frame lengths, and exact file-list byte counts, as observed on the tested device.

Metadata

Release files for hidock-python 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hidock-python 0.1.0
File Size Uploaded Provenance Actions
hidock_python-0.1.0.tar.gz 35.2 kB With provenance Details for hidock_python-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for hidock-python 0.1.0
File Interpreter ABI Platform Actions
hidock_python-0.1.0-py3-none-any.whl Python 3 none any Details for hidock_python-0.1.0-py3-none-any.whl

Total release size: 57.7 kB

Release files / hidock_python-0.1.0.tar.gz

Download URL hidock_python-0.1.0.tar.gz
Size 35.2 kB
Tags Source
SHA-256 checksum
How to use checksums
fe4e9ffd60bd1eef6c1c7edd3eb4bb09227b16fd0b066bb54cb4fca4c62eea56
BLAKE2b-256 checksum
How to use checksums
d72c3c03a2d86aea99cf4eea7fa13c702992dbc5ebfc9f8604c60580df31078b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / hidock_python-0.1.0-py3-none-any.whl

Download URL hidock_python-0.1.0-py3-none-any.whl
Size 22.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f9294b23c64b1fc584b7af4cabb73ded5d977f42b22f916105b214d962ecf6e0
BLAKE2b-256 checksum
How to use checksums
05a46d1991e77636b28f90e16b1474496efd413debd28ea7edcc13fccf90a21c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Security for hidock-python 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for hidock_python-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page