<!-- Source: https://medius.k4tech.net/bindings/python/types -->
# Types & errors

_Every enum, dataclass, and exception the package exposes_

Reference for the values the [API](/bindings/python/api.md) takes and returns. Field meanings live with each command, so this page links to the [Library types](/library/types.md) and [Native API](/native.md). Raw HID id meanings (keycodes, button slots, Consumer usages) are on [Usage IDs](/native/commands/usage.md).

> **Note**
>
> Every enum subclasses [`enum.IntEnum`](https://docs.python.org/3/library/enum.html), except [`CatchMask`](/bindings/python/types.md#catchmask), which is an [`enum.IntFlag`](https://docs.python.org/3/library/enum.html#enum.IntFlag). A member _is_ its [wire byte](/native/frame.md): `int(Button.LEFT) == 0`, and anywhere an enum is accepted you can pass a bare `int` instead (handy for a raw HID id with no named member). `CatchMask` members combine with `|`.

## Injection enums

_Button · Action_

See the [injection model](/native/injection.md) for what each `Action` means; button slots on [Usage IDs](/native/commands/usage.md#buttons).

#### Button

| Member | Value |
| --- | --- |
| `LEFT` | `0` |
| `RIGHT` | `1` |
| `MIDDLE` | `2` |
| `SIDE1` | `3` |
| `SIDE2` | `4` |

#### Action

| Member | Value | Meaning |
| --- | --- | --- |
| `SOFT_RELEASE` | `0` | release unless the user is physically holding it |
| `PRESS` | `1` | hold down |
| `FORCE_RELEASE` | `2` | release even against a physical hold |

## Lock & blanket enums

_LockDirection · LockTargetKind · Blanket_

See [Lock](/native/commands/lock.md) for what a direction and a blanket class mean.

#### LockDirection

| Member | Value | Blocks |
| --- | --- | --- |
| `BOTH` | `0` | either direction |
| `POSITIVE` | `1` | +x / +y / wheel-up only |
| `NEGATIVE` | `2` | \-x / -y / wheel-down only |

#### LockTargetKind

| Member | Value |
| --- | --- |
| `X` | `0` |
| `Y` | `1` |
| `WHEEL` | `2` |
| `USAGE` | `3` |

Built for you by [`LockTarget.x/y/wheel/usage`](/bindings/python/types.md#locktarget) (and the `button`/`key`/`media` shortcuts); you rarely name it directly.

#### Blanket

| Member | Value | Class |
| --- | --- | --- |
| `AIM` | `0` | the X and Y cursor axes |
| `WHEEL` | `1` | the wheel |
| `BUTTONS` | `2` | every mouse button |
| `KEYS` | `3` | every keyboard key and modifier |
| `MEDIA` | `4` | every media usage |

These are ABI-local ordinals (matching the crate's Blanket order), not the clip auto-lock scope bits.

## Keycode enums

_Key · MediaKey_

Named subsets of the [HID usage tables](https://www.usb.org/document-library/hid-usage-tables-14). The full list of ids and what they do is on [Usage IDs](/native/commands/usage.md#keycodes) (keys) and [Usage IDs](/native/commands/usage.md#consumer) (media). Any call that takes a `Key` or `MediaKey` also accepts a raw `int` usage.

#### Key

| Members | Values |
| --- | --- |
| `A` … `Z` | `4` to `29` |
| `N1` … `N9`, `N0` | `30` to `39` |
| `ENTER` `ESCAPE` `BACKSPACE` `TAB` `SPACE` | `40` to `44` |
| `CAPS_LOCK` | `57` |
| `F1` … `F12` | `58` to `69` |
| `INSERT` `HOME` `PAGE_UP` `DELETE` `END` `PAGE_DOWN` | `73` to `78` |
| `RIGHT` `LEFT` `DOWN` `UP` (arrows) | `79` to `82` |
| `LEFT_CTRL` `LEFT_SHIFT` `LEFT_ALT` `LEFT_GUI` | `224` to `227` |
| `RIGHT_CTRL` `RIGHT_SHIFT` `RIGHT_ALT` `RIGHT_GUI` | `228` to `231` |

#### MediaKey

| Member | Value |
| --- | --- |
| `PLAY` | `176` |
| `PAUSE` | `177` |
| `NEXT_TRACK` | `181` |
| `PREV_TRACK` | `182` |
| `STOP` | `183` |
| `PLAY_PAUSE` | `205` |
| `MUTE` | `226` |
| `VOLUME_UP` | `233` |
| `VOLUME_DOWN` | `234` |

## LED & admin enums

_LedTarget · LedMode · RebootTarget_

See [LED](/native/commands/led.md) and [Admin](/native/commands/admin.md).

#### LedTarget

| Member | Value |
| --- | --- |
| `DEVICE` | `0` |
| `HOST` | `1` |
| `BOTH` | `2` |

#### LedMode

| Member | Value |
| --- | --- |
| `AUTO` | `0` |
| `OFF` | `1` |
| `SOLID` | `2` |
| `BLINK` | `3` |

#### RebootTarget

| Member | Value |
| --- | --- |
| `DEVICE_DOWNLOAD` | `0` |
| `HOST_DOWNLOAD` | `1` |
| `DEVICE_RUN` | `2` |
| `HOST_RUN` | `3` |

## Emit pace

_EmitMode · EmitPace_

Passed to [`dev.set_emit_pace()`](/bindings/python/api.md#led-admin-options). See [Options](/library/options.md).

#### EmitMode

| Member | Value |
| --- | --- |
| `LEARNED` | `0` |
| `INTERVAL` | `1` |
| `FIXED` | `2` |

#### EmitPace

A frozen dataclass carrying `mode` and `hz`. Build it with `EmitPace.learned()`, `EmitPace.interval()`, or `EmitPace.fixed(hz)` (the rate snaps to `1000/n` and caps at 1 kHz).

## Clip

_ClipState · Edge · ClipAction · ClipTrigger · ClipSettings · ClipStatus_

The buffered-clip types. Concept on [Clip](/library/clip.md).

#### ClipState

| Member | Value | Meaning |
| --- | --- | --- |
| `IDLE` | `0` | No clip playing. |
| `PLAYING` | `1` | Draining the ring, one entry per native frame. |
| `PAUSED` | `2` | Halted mid-clip; the cursor and any held input are retained. |
| `FAULTED` | `3` | An append was dropped or the ring overflowed; `clear` to recover. |

#### Edge

| Member | Value | Fires on |
| --- | --- | --- |
| `BOTH` | `0` | either edge of the trigger usage |
| `PRESS` | `1` | the physical press edge |
| `RELEASE` | `2` | the physical release edge |

Which edge of a [`ClipTrigger`](/bindings/python/types.md#cliptrigger) runs its action.

#### ClipAction

| Member | Value | Runs |
| --- | --- | --- |
| `START` | `0` | rewind and play |
| `STOP` | `1` | stop and release |
| `PAUSE` | `2` | halt mid-clip |
| `RESUME` | `3` | continue from the pause |
| `RESTART` | `4` | force a rewind and play |
| `TOGGLE` | `5` | play if idle/paused, stop if playing |

The action a bound trigger runs on the box, matching the [`clip.start/stop/pause/resume/restart/toggle`](/bindings/python/api.md#clip) methods.

#### ClipTrigger

A dataclass binding a physical usage's edge to a clip action, passed to [`clip.bind()`](/bindings/python/api.md#clip). The box runs the action itself with no host round-trip.

| Field | Type | Meaning |
| --- | --- | --- |
| `on` | [`Usage`](/bindings/python/types.md#input) | the trigger usage (button, key, or media) |
| `edge` | [`Edge`](/bindings/python/types.md#edge) | which edge fires the action |
| `action` | [`ClipAction`](/bindings/python/types.md#clipaction) | what the box runs |
| `consume` | `bool` | swallow the physical edge so it doesn't pass through (default `False`) |

Construct it directly, e.g. `ClipTrigger(Usage.button(Button.SIDE1), Edge.PRESS, ClipAction.TOGGLE, consume=True)`.

#### ClipSettings (clip.query_config())

| Field | Type | Meaning |
| --- | --- | --- |
| `autolock` | `List[[Blanket](/bindings/python/types.md#blanket)]` | the input groups auto-locked while the clip plays |
| `loop` | `bool` | playback loops at the clip end (retained mode only) |
| `retain` | `bool` | the loaded clip is retained so it can rewind and replay |
| `finalized` | `bool` | a retained clip's end is fixed, ready to replay and loop |
| `triggers` | `List[[ClipTrigger](/bindings/python/types.md#cliptrigger)]` | the bound trigger set (up to 8) |

#### ClipStatus (clip.query_status())

| Field / method | Type | Meaning |
| --- | --- | --- |
| `state` | [`ClipState`](/bindings/python/types.md#clipstate) | the lifecycle state |
| `free` / `total` | `int` | ring bytes free (pace top-ups off this) / retained clip size in bytes (streaming: buffered-but-undrained) |
| `played` | `int` | bytes played from the clip start (retained progress; ~0 while streaming) |
| `ticks` | `int` | content frames emitted since the last start (gap runs excluded) |
| `underruns` / `overruns` / `seq_gaps` | `int` | empty-ring / ring-full / dropped-append counts |
| `held` | `List[Usage]` | the held-usage snapshot: the buttons, keys, and media the clip is holding down (one shape, like a [`UsageSnapshot`](/bindings/python/types.md#usagesnapshot)) |
| `is_held(usage)` | `bool` | test one [`Usage`](/bindings/python/types.md#input) in `held` |

## Stream enums

_CatchMask · CatchEventKind · LogLevel_

See [Catch](/native/commands/catch.md) and [Logs & counters](/library/diagnostics.md); consuming events is on [Streams](/bindings/python/streams.md).

#### CatchMask (IntFlag)

| Member | Value | Subscribes to |
| --- | --- | --- |
| `MOTION` | `1` | cursor motion |
| `WHEEL` | `2` | wheel |
| `BUTTONS` | `4` | mouse buttons |
| `KEYS` | `8` | keyboard keys |
| `MEDIA` | `16` | media keys |
| `ALL` | `31` | everything (default) |

Combine with `|`, e.g. `CatchMask.BUTTONS | CatchMask.KEYS`.

#### CatchEventKind

| Member | Value | [`CatchEvent.payload`](/bindings/python/types.md#catchevent) type |
| --- | --- | --- |
| `MOTION` | `0` | [`MotionEvent`](/bindings/python/types.md#motionevent) |
| `USAGES` | `1` | [`UsageSnapshot`](/bindings/python/types.md#usagesnapshot) |

#### LogLevel

| Member | Value |
| --- | --- |
| `ERROR` | `0` |
| `WARN` | `1` |
| `INFO` | `2` |
| `DEBUG` | `3` |
| `VERBOSE` | `4` |

## Wire enums

_MotionKind · Class · FrameType_

Mostly internal. `MotionKind` and `Class` tag the structs the [Usage](/bindings/python/types.md#input) and [Motion](/bindings/python/types.md#motion) builders produce; `FrameType` names a wire frame for [`MockBox.saw()`](/library/features/mock.md) and [`RecordedFrame.type`](/bindings/python/types.md#recordedframe). Frame semantics are on [Frames](/native/frame.md) and [Library frames](/library/types/frames.md).

#### MotionKind

| Member | Value |
| --- | --- |
| `CURSOR` | `0` |
| `WHEEL` | `1` |

#### Class

| Member | Value |
| --- | --- |
| `BUTTON` | `0` |
| `KEY` | `1` |
| `MEDIA` | `2` |

#### FrameType

| Member | Value | Member | Value |
| --- | --- | --- | --- |
| `MOVE` | `1` | `LOCK` | `10` |
| `INJECT` | `3` | `CATCH` | `11` |
| `RESET` | `4` | `MOTION_EVENT` | `12` |
| `QUERY` | `5` | `USAGE_EVENT` | `15` |
| `RESP` | `6` | `OPTION` | `17` |
| `REBOOT_DL` | `7` | `CLIP_APPEND` | `18` |
| `LOG` | `8` | `CLIP_CTRL` | `19` |
| `LED` | `9` | `CLIP_SET` | `20` |
|  |  | `CLIP_TRIGGER` | `21` |

## Parameter builders

_Usage · Motion · LockTarget_

Small classes that wrap a native struct. Build them with their class methods and pass the result to the matching call. Never construct one field by field.

#### Usage

```text
Usage.button(button) -> Usage
Usage.key(key)       -> Usage
Usage.media(media)   -> Usage
```

An injection target for [`dev.inject(input, action)`](/bindings/python/api.md#inject). See [Inject](/library/inject.md).

#### Motion

```text
Motion.cursor(dx, dy) -> Motion
Motion.wheel(delta)   -> Motion
```

A relative axis drive for [`dev.move_axis(motion)`](/bindings/python/api.md#move). See [Move](/library/move.md).

#### LockTarget

```text
LockTarget.x()            -> LockTarget
LockTarget.y()            -> LockTarget
LockTarget.wheel()        -> LockTarget
LockTarget.usage(usage)   -> LockTarget
LockTarget.button(button) -> LockTarget
LockTarget.key(key)       -> LockTarget
LockTarget.media(media)   -> LockTarget
```

An axis or usage to lock for [`dev.lock(target, direction)`](/bindings/python/api.md#lock); the `button`/`key`/`media` shortcuts wrap `usage()`. See [Lock](/library/lock.md).

## Device enums

_DeviceKind_

The cloned device's kind, on [`DeviceInfo.kind`](/bindings/python/types.md#deviceinfo), and what [`Device.find_mouse_box()`](/bindings/python/api.md#discovery) / `find_keyboard_box()` select on. See [DeviceKind](/library/types/enums.md#device-kind).

#### DeviceKind

| Member | Value |
| --- | --- |
| `UNKNOWN` | `0` |
| `KEYBOARD` | `1` |
| `MOUSE` | `2` |

## Identity & capability types

_Version · Health · DeviceInfo · Caps_

[Dataclasses](https://docs.python.org/3/library/dataclasses.html) returned by the [queries](/bindings/python/api.md). Canonical field docs: [Library structs](/library/types/structs.md).

#### Version (query_version())

| Field / property | Type | Meaning |
| --- | --- | --- |
| `proto_ver` | `int` | control-protocol version |
| `fw_major` | `int` | firmware major |
| `fw_minor` | `int` | firmware minor |
| `fw_patch` | `int` | firmware patch |
| `mac` | `bytes` | the device chip's base MAC (6 bytes), a stable per-box id |
| `mac_hex` | `str` | the MAC as 12 lowercase hex digits |
| `name` | `str` | the box's human-readable name (a synthesized default when unset), set with [`set_name`](/bindings/python/api.md#led-admin-options) |

#### Health (query_health())

| Field | Type |
| --- | --- |
| `link_up` | `bool` |
| `mouse_attached` | `bool` |
| `clone_configured` | `bool` |
| `injection_active` | `bool` |
| `rate_confident` | `bool` |
| `lock_on` | `bool` |
| `catch_on` | `bool` |
| `kbd_attached` | `bool` |

#### DeviceInfo (device_info())

| Field | Type | Meaning |
| --- | --- | --- |
| `vid` | `int` | USB vendor id |
| `pid` | `int` | USB product id |
| `bcd_device` | `int` | device release (BCD) |
| `bcd_usb` | `int` | USB spec (BCD) |
| `has_serial` | `bool` | exposes a serial string |
| `has_bos` | `bool` | exposes a BOS descriptor |
| `kind` | [`DeviceKind`](/bindings/python/types.md#devicekind) | the device's primary kind (Boot-interface protocol) |
| `product` | `str` | the product string (empty when none) |

#### Caps (caps())

| Field / method | Type | Meaning |
| --- | --- | --- |
| `mouse` | [`MouseCaps`](/bindings/python/types.md#mousecaps) | mouse capabilities |
| `keyboard` | [`KbdCaps`](/bindings/python/types.md#kbdcaps) | keyboard capabilities |
| `mouse_change_driven` | `bool` | mouse reports only on change |
| `kbd_change_driven` | `bool` | keyboard reports only on change |
| `has_mouse()` | `bool` | a mouse interface is present |
| `has_keyboard()` | `bool` | a keyboard interface is present |
| `is_composite()` | `bool` | the clone has more than one HID interface (`n_hid > 1`) |

#### MouseCaps

| Field | Type | Meaning |
| --- | --- | --- |
| `n_buttons` | `int` | button count |
| `has_x` | `bool` | X axis present |
| `has_y` | `bool` | Y axis present |
| `has_wheel` | `bool` | wheel present |
| `has_report_id` | `bool` | reports carry a report id |
| `n_hid` | `int` | HID interface count |

#### KbdCaps

| Field | Type | Meaning |
| --- | --- | --- |
| `n_keys` | `int` | rollover key count |
| `nkro` | `bool` | n-key rollover |
| `has_consumer` | `bool` | Consumer (media) page |
| `has_system` | `bool` | System-control page |
| `has_report_id` | `bool` | reports carry a report id |

## State & telemetry types

_Rate · Stats · Locks · CatchState · ImperfectStatus · Counters · PortInfo_

More query results, plus [`PortInfo`](/bindings/python/types.md#portinfo) from [`find_ports()`](/bindings/python/api.md#connect). Canonical field docs: [Library structs](/library/types/structs.md).

#### Rate (query_rate())

| Field / method | Type | Meaning |
| --- | --- | --- |
| `native_period_us` | `int` | mouse report period, µs |
| `poll_period_us` | `int` | poll period, µs |
| `confident` | `bool` | estimate is settled |
| `change_driven` | `bool` | reports only on change |
| `native_hz()` | `float \| None` | rate in Hz, or `None` if unknown |

#### Stats (query_stats())

| Field | Type | Meaning |
| --- | --- | --- |
| `inject_emits` | `int` | injected reports emitted |
| `tx_drops` | `int` | dropped TX frames |
| `tx_merges` | `int` | coalesced TX frames |
| `tx_maxdepth` | `int` | peak TX queue depth |
| `tx_wedges` | `int` | TX stalls |
| `wakeups` | `int` | scheduler wakeups |
| `reset_count` | `int` | resets seen |
| `config_count` | `int` | clone configures |

#### Locks (query_locks())

| Field / method | Type | Meaning |
| --- | --- | --- |
| `entries` | `List[LockEntry]` | one [`LockEntry`](/bindings/python/types.md#lockentry) per active lock |
| `is_locked(target, direction)` | `bool` | test one [`LockTarget`](/bindings/python/types.md#locktarget) + [`LockDirection`](/bindings/python/types.md#lockdirection); also true when a whole-class blanket covers it |

#### LockEntry

| Field | Type | Meaning |
| --- | --- | --- |
| `target` | [`LockTarget`](/bindings/python/types.md#locktarget) | what is locked (an axis or a usage) |
| `is_blanket` | `bool` | a whole-class lock, where `target` names only the class |
| `positive` | `bool` | the +x / +y / wheel-up / press edge is locked |
| `negative` | `bool` | the -x / -y / wheel-down / release edge is locked |

#### CatchState (query_catch())

| Field | Type | Meaning |
| --- | --- | --- |
| `mask` | `int` | active [`CatchMask`](/bindings/python/types.md#catchmask) bits |
| `dropped` | `int` | events dropped by [the box](/native/hardware.md) |

#### ImperfectStatus (query_imperfect())

| Field | Type | Meaning |
| --- | --- | --- |
| `allowed` | `bool` | imperfect clones opted in |
| `over_capacity` | `bool` | mouse exceeds clone capacity |
| `clone_imperfect` | `bool` | the live clone is imperfect |

See [Options](/library/options.md).

#### EmitPaceStatus (query_emit_pace())

| Field | Type | Meaning |
| --- | --- | --- |
| `mode` | [`EmitPace`](/bindings/python/types.md#emitpace) | the selected mode |
| `resolved_hz` | `int` | the ceiling in effect; 0 = learned/adaptive or no device yet |

See [Options](/library/options.md).

#### Counters (counters())

| Field | Type | Meaning |
| --- | --- | --- |
| `frames_tx` | `int` | host-side frames sent |
| `frames_rx` | `int` | host-side frames received |
| `crc_drops` | `int` | frames dropped on CRC |
| `reconnects` | `int` | link reconnects |

#### PortInfo (find_ports())

| Field | Type | Meaning |
| --- | --- | --- |
| `path` | `str` | serial path, e.g. `/dev/ttyACM0` or `COM3` |
| `vid` | `int` | USB vendor id |
| `pid` | `int` | USB product id |
| `serial` | `Optional[str]` | the CH343 adapter's serial, when it serves one |

Pass `path` to [`Device.open(path)`](/bindings/python/api.md#connect). Canonical: [PortInfo](/library/types/structs.md#port-info).

#### BoxInfo (list_boxes())

| Field / property | Type | Meaning |
| --- | --- | --- |
| `port` | [`PortInfo`](/bindings/python/types.md#portinfo) | the box's control port |
| `version` | [`Version`](/bindings/python/types.md#version) | its firmware version, with the box MAC and name |
| `device` | [`DeviceInfo`](/bindings/python/types.md#deviceinfo) | the device it clones |
| `id` | `str` | the box identity (the MAC hex) |
| `serial` | `Optional[str]` | the CH343 serial |

Pass `id` or `serial` to [`Device.open_by_id(id)`](/bindings/python/api.md#discovery). Canonical: [BoxInfo](/library/discovery.md#box-info).

## Event & log types

_Yielded by the streams_

Payloads from [streams](/bindings/python/streams.md). [`dev.catch_events()`](/bindings/python/api.md#streams) yields [`CatchEvent`](/bindings/python/types.md#catchevent) and [`dev.logs()`](/bindings/python/api.md#streams) yields [`LogLine`](/bindings/python/types.md#logline). What catch reports lives on [Catch](/library/catch.md).

#### CatchEvent

| Field / member | Type | Meaning |
| --- | --- | --- |
| `kind` | [`CatchEventKind`](/bindings/python/types.md#catcheventkind) | which payload is set |
| `payload` | `MotionEvent \| UsageSnapshot` | the decoded event |
| `motion` | [`MotionEvent`](/bindings/python/types.md#motionevent) `\| None` | payload when `kind == MOTION` |
| `usages` | [`UsageSnapshot`](/bindings/python/types.md#usagesnapshot) `\| None` | payload when `kind == USAGES` |

#### MotionEvent

| Field | Type | Meaning |
| --- | --- | --- |
| `dx` | `int` | X delta |
| `dy` | `int` | Y delta |
| `dz` | `int` | wheel delta |

#### UsageSnapshot

| Field / method | Type | Meaning |
| --- | --- | --- |
| `usages` | `List[Usage]` | every held [`Usage`](/bindings/python/types.md#input) (button, key, or media; modifiers are key usages `0xE0` to `0xE7`) |
| `is_held(usage)` | `bool` | test a [`Usage`](/bindings/python/types.md#input) in the snapshot |

#### LogLine

| Field | Type | Meaning |
| --- | --- | --- |
| `level` | [`LogLevel`](/bindings/python/types.md#loglevel) | severity |
| `text` | `str` | the log message |

#### RecordedFrame (MockBox.recorded_frame(idx))

| Field | Type | Meaning |
| --- | --- | --- |
| `type` | [`FrameType`](/bindings/python/types.md#frametype) `\| int` | frame type (raw `int` if unknown) |
| `seq` | `int` | frame sequence byte |
| `payload` | `bytes` | raw frame payload |

Only meaningful with the [mock](/library/features/mock.md) feature.

## Errors

_MediusError, its subclasses, and the Status codes_

Every _Blocks_ call (and any that fails on the wire) raises a `MediusError` or one of its subclasses. Catch the base class to catch them all. Canonical mapping: [Library errors](/library/types/errors.md).

#### MediusError (Exception)

| Attribute | Type | Meaning |
| --- | --- | --- |
| `status` | [`Status`](/bindings/python/types.md#status) | the failure code |
| `message` | `str` | the box's last error text |
| `proto_ver` | `int` | offending version byte (bad-proto-version only) |

```python
from medius import Device, MediusError, NotFoundError

try:
    dev = Device.find()
except NotFoundError:
    ...                      # no box plugged in
except MediusError as e:     # any other failure
    print(e.status, e.message)
```

#### Subclass per Status

| Exception | Raised on |
| --- | --- |
| `IoError` | `ERR_IO` |
| `NotFoundError` | `ERR_NOT_FOUND` |
| `NoReplyError` | `ERR_NO_REPLY` |
| `BadProtoVerError` | `ERR_BAD_PROTO_VER` |
| `QueryTimeoutError` | `ERR_QUERY_TIMEOUT` |
| `DisconnectedError` | `ERR_DISCONNECTED` |
| `FrameTooLongError` | `ERR_FRAME_TOO_LONG` |
| `FlashToolError` | `ERR_FLASH_TOOL` |
| `InvalidArgError` | `ERR_INVALID_ARG` |
| `PanicError` | `ERR_PANIC` |

> **Note**
>
> `DisconnectedError` ends a [stream](/bindings/python/streams.md) iteration cleanly rather than propagating. `OK` and `ERR_UNKNOWN` have no dedicated subclass; `ERR_UNKNOWN` raises the base `MediusError`.

#### Status

| Member | Value | Member | Value |
| --- | --- | --- | --- |
| `OK` | `0` | `ERR_DISCONNECTED` | `6` |
| `ERR_IO` | `1` | `ERR_FRAME_TOO_LONG` | `7` |
| `ERR_NOT_FOUND` | `2` | `ERR_FLASH_TOOL` | `8` |
| `ERR_NO_REPLY` | `3` | `ERR_INVALID_ARG` | `9` |
| `ERR_BAD_PROTO_VER` | `4` | `ERR_PANIC` | `10` |
| `ERR_QUERY_TIMEOUT` | `5` | `ERR_UNKNOWN` | `11` |
