Models¶
All response models inherit from a base class with extra="allow" for forward-compatible parsing.
ATX¶
ATXState
¶
ATX subsystem state.
enabled is False when the ATX plugin is disabled, in which case
every action answers HTTP 400.
Source code in src/aiopikvm/models/atx.py
ATXActs
¶
Which ATX action is running right now.
kvmd guards the power and reset lines separately, so a reset can be
pending while the power line is free. ATXState.busy is the two of
them combined.
Source code in src/aiopikvm/models/atx.py
ATXLeds
¶
HID¶
HIDState
¶
HID subsystem state.
Mirrors the shape returned by GET /api/hid. connected reports
whether the target host has the HID plugged in, and only the MCU-based
backends can tell — otg, ch9329 and bt report None. The
MCU backends are also the only ones that implement
HIDResource.set_connected(),
so a bool here says that call does something. A None does not say
the reverse: an MCU backend reports it too until its microcontroller has
sent a status word carrying the flag.
Source code in src/aiopikvm/models/hid.py
HIDKeyboard
¶
HIDKeyboardLeds
¶
HIDMouse
¶
HIDOutputs
¶
Selectable HID output modes for one device.
available is empty and active is an empty string on backends that
cannot switch modes at runtime — the OTG keyboard, for instance.
Source code in src/aiopikvm/models/hid.py
HIDJiggler
¶
Mouse jiggler — the anti-idle mover built into kvmd.
Two flags that read alike and are not the same.
HIDResource.set_params()
with jiggler writes active, which is whether it is running now.
enabled says the device was configured with a jiggler at all and no
API call moves it, so a caller who checks enabled after a write sees
it unchanged and concludes the write was ignored.
interval is the idle time in seconds before it starts nudging the
pointer, and is likewise read-only over the API.
Source code in src/aiopikvm/models/hid.py
HIDKeymaps
¶
Keyboard layouts installed on the device.
Returned by GET /api/hid/keymaps; the names are what
HIDResource.type_text()
accepts as its keymap argument.
Source code in src/aiopikvm/models/hid.py
MSD¶
MSDState
¶
MSD subsystem state.
drive and storage are both None while the subsystem is
offline — the MSD is disabled in the OTG profile, or kvmd has not
finished setting it up. Neither is available without the other.
Source code in src/aiopikvm/models/msd.py
MSDDrive
¶
MSDStorage
¶
MSD storage: what is on it and what is moving in or out of it.
Source code in src/aiopikvm/models/msd.py
MSDImage
¶
An image stored in MSD storage.
complete is False for an image whose upload was interrupted; kvmd
keeps it in the listing so it can be resumed or removed.
Source code in src/aiopikvm/models/msd.py
MSDDriveImage
¶
The image currently in the virtual drive.
kvmd reports two fields here that the storage listing leaves out, because the drive can also hold an image that is not in storage at all.
Source code in src/aiopikvm/models/msd.py
MSDPart
¶
MSDUpload
¶
Progress of an image being written to storage.
kvmd reports the same three fields in two places: under
storage.uploading while a write is in flight, and as the body of the
write endpoints themselves — once from /api/msd/write, once per line
of the stream /api/msd/write_remote answers with.
name is the name kvmd stored the image under, which is not
necessarily the one that was asked for: a prefix is joined on and the
whole thing goes through kvmd's file-name validator. size is the
total the write was opened for — the request's Content-Length, or the
remote's — and written how much of it has landed.
Source code in src/aiopikvm/models/msd.py
MSDDownload
¶
Progress of a stored image being read back.
readed is spelled the way kvmd spells it on the wire.
Source code in src/aiopikvm/models/msd.py
GPIO¶
GPIOState
¶
GPIO subsystem state.
Mirrors GET /api/gpio: model describes the channels and the web
UI layout, state holds their readings. inputs and outputs are
shortcuts to the readings, which is what callers almost always want.
This is the shape of the REST response. The gpio WebSocket events
carry partial updates and do not validate against it.
Source code in src/aiopikvm/models/gpio.py
GPIOIOState
¶
GPIOChannel
¶
GPIO output channel state.
busy is True while a switch or pulse is still running, and it is
the field to read first: kvmd does not touch the pin for a busy channel,
so state is False and online is True for the duration
whatever the hardware is doing. That covers a switch to the state the
channel already has, which still runs the action and still reads back as
off while it does.
GPIOResource.switch()
and pulse() answer as
the action starts unless they are given wait=True, so a read taken
straight after one of them lands inside that window by default.
Source code in src/aiopikvm/models/gpio.py
GPIOInput
¶
GPIOModel
¶
GPIOScheme
¶
GPIOOutputScheme
¶
GPIOInputScheme
¶
Configuration of an input channel.
No capture covers this: the fixture device has no input channels. The
shape comes from kvmd's ugpio.py, which builds it two lines away from
the output scheme below.
Source code in src/aiopikvm/models/gpio.py
GPIOPulse
¶
Pulse limits of an output channel.
A delay of 0 means the channel does not support pulsing at all —
kvmd answers GpioPulseNotSupported.
Source code in src/aiopikvm/models/gpio.py
GPIOHardware
¶
GPIOView
¶
Layout hints for the GPIO widget in the PiKVM web UI.
The items are deliberately left as dictionaries. kvmd emits three shapes
here — label, input and output, told apart by type — and
the captured device has an empty table, so a typed union would rest on
kvmd's source alone and no test could hold it honest. This is layout
metadata for the web UI; nothing in this client reads it. A None row
is a separator.
Source code in src/aiopikvm/models/gpio.py
GPIOViewHeader
¶
Streamer¶
StreamerState
¶
Streamer subsystem state.
Mirrors the shape returned by GET /api/streamer. The streamer
field is None when no stream clients are connected — kvmd stops the
streamer process to save resources.
Source code in src/aiopikvm/models/streamer.py
Streamer
¶
Running streamer process state.
Present only when the streamer is active. StreamerState.streamer is
None when no clients are subscribed and kvmd has shut the streamer
process down. h264 is absent unless ustreamer was built and configured
with H.264 support.
Source code in src/aiopikvm/models/streamer.py
StreamerSource
¶
Resolution
¶
StreamerParams
¶
Streamer parameters.
Mirrors what the device supports: quality is absent when the capture
path has no adjustable JPEG quality, resolution only exists on
resolution-capable hardware, and the H.264 pair only when H.264 is
configured. Used for both the requested parameters and the applied ones.
Source code in src/aiopikvm/models/streamer.py
StreamerLimits
¶
Limits for the tunable streamer parameters.
Only desired_fps is always present. kvmd adds the H.264 ranges only
when H.264 is configured, and available_resolutions only on a device
whose capture hardware can switch resolution.
Source code in src/aiopikvm/models/streamer.py
StreamerLimitRange
¶
StreamerFeatures
¶
SnapshotImage
¶
A JPEG taken from the video stream, with what ustreamer said about it.
online is False when the frame is the "NO LIVE VIDEO" placeholder
rather than a picture of the host, which is the only way to tell the two
apart. A saved snapshot returned with load=True carries the same
metadata it had when it was taken.
Everything but data is optional: these come from response headers
that no capture in this repository pins down, so a header that is absent
or unreadable leaves its field unset rather than failing the call. With
preview=True the size still describes the source frame, not the
scaled-down data.
Source code in src/aiopikvm/models/streamer.py
StreamerSnapshot
¶
The snapshot stored on the device, if any.
saved is None until something calls
StreamerResource.snapshot()
with save=True.
Source code in src/aiopikvm/models/streamer.py
SavedSnapshot
¶
Metadata of the snapshot stored on the device.
kvmd keeps the image itself out of the state and reports only what it was: whether the source was live and how big the frame is.
Source code in src/aiopikvm/models/streamer.py
StreamerEncoder
¶
StreamerH264
¶
StreamerSinks
¶
StreamerSinkInfo
¶
StreamerStream
¶
StreamerClientStat
¶
One MJPEG client of the streamer, as ustreamer accounts for it.
Every field but fps echoes the query the client connected with, so a
caller that passed a key to
StreamerResource.mjpeg()
can find its own row: the id these are keyed by is ustreamer's, assigned
at connect and not known to the client that owns it.
Attributes:
| Name | Type | Description |
|---|---|---|
fps |
int
|
Frames per second ustreamer is sending this client. |
key |
str
|
The |
extra_headers |
bool
|
Whether it asked for the |
advance_headers |
bool
|
Whether it asked for the Chromium workaround. |
dual_final_frames |
bool
|
Whether it asked for the Safari workaround. |
zero_data |
bool
|
Whether it asked for part headers without the JPEG data. |
Source code in src/aiopikvm/models/streamer.py
MJPEGFrame
¶
One frame of the MJPEG stream, with what its part headers said.
data is a complete JPEG; the rest comes from the part headers, so a
field is set only when the header was there and could be read. Without
extra_headers=True only timestamp arrives — everything else is a
X-UStreamer-* header ustreamer sends on request. headers keeps the
raw part headers, including the timing ones this model does not name.
Attributes:
| Name | Type | Description |
|---|---|---|
data |
bytes
|
The JPEG bytes, empty when the stream was opened with
|
timestamp |
float | None
|
|
online |
bool | None
|
Whether the frame is a picture of the host rather than the "NO LIVE VIDEO" placeholder. |
width |
int | None
|
Frame width in pixels. |
height |
int | None
|
Frame height in pixels. |
dropped |
int | None
|
How many frames ustreamer dropped for this client so far. |
client_fps |
int | None
|
The rate ustreamer is sending this client. |
latency |
float | None
|
Seconds between grabbing the frame and sending it. |
headers |
dict[str, str]
|
Every part header, as received. |
Source code in src/aiopikvm/models/streamer.py
OCRInfo
¶
OCRLangs
¶
Media¶
MediaState
¶
What the kvmd-media daemon offers, as GET /api/media returns it.
The same object arrives as the first frame of a
MediaWebSocket opened without a format, where
it is on MediaWebSocket.media.
Attributes:
| Name | Type | Description |
|---|---|---|
video |
MediaVideoFormats
|
The video formats the daemon can send. |
Source code in src/aiopikvm/models/media.py
MediaVideoFormats
¶
The video formats the daemon is configured with.
A format the daemon does not serve is simply absent, which is what makes
both fields optional: a PiKVM v3 with H.264 offloaded to the hardware
encoder publishes h264 and nothing else, and asking a
MediaWebSocket for a format that is not here
is refused with HTTP 400 before the socket exists.
Attributes:
| Name | Type | Description |
|---|---|---|
h264 |
MediaH264 | None
|
H.264 metadata, |
jpeg |
MediaJPEG | None
|
MJPEG metadata, |
Source code in src/aiopikvm/models/media.py
MediaH264
¶
What the daemon says about its H.264 source.
Attributes:
| Name | Type | Description |
|---|---|---|
profile_level_id |
str
|
The SDP |
Source code in src/aiopikvm/models/media.py
MediaJPEG
¶
What the daemon says about its JPEG source.
Nothing, on every kvmd this release was checked against: the daemon has no metadata to publish for MJPEG the way it does for H.264. The model exists so that the format shows up as present rather than as an unnamed extra when a device serves it.
Source code in src/aiopikvm/models/media.py
MediaFrame
¶
One frame off the media socket.
Attributes:
| Name | Type | Description |
|---|---|---|
data |
bytes
|
The frame as the daemon sent it. For H.264 that is Annex B —
a |
key |
bool | None
|
Whether this frame is a keyframe. |
Source code in src/aiopikvm/models/media.py
WebRTC¶
WebRTCFeatures
¶
What this build of the ustreamer plugin can do.
Attributes:
| Name | Type | Description |
|---|---|---|
audio |
bool
|
Whether the device has a capture audio device, i.e. whether the host's sound can be streamed to the client. |
mic |
bool
|
Whether the device has a playback audio device, i.e. whether the client's microphone can be sent to the host. |
ice |
WebRTCICE
|
The ICE server the plugin suggests. |
Source code in src/aiopikvm/models/webrtc.py
WebRTCICE
¶
The ICE server the plugin suggests.
Attributes:
| Name | Type | Description |
|---|---|---|
url |
str | None
|
A STUN or TURN URL, e.g. |
Source code in src/aiopikvm/models/webrtc.py
WebRTCEvent
¶
One message Janus sent that answers nothing this client asked for.
These arrive whenever Janus has something to say: the peer connection came
up, the link is congested, the peer connection ended, the session timed
out. The plugin's own pushes arrive the same way, since it answers a
request by pushing an event rather than by replying to it, which is why
plugindata can be set on one of these.
An answer to something this client did send never arrives here — it is
consumed where the request was made — so the transaction such an
answer carries, and the error block a refusal carries, have no field
here. A Janus-level refusal reaches a caller as
WebRTCError instead.
Attributes:
| Name | Type | Description |
|---|---|---|
janus |
str
|
The kind — |
sender |
int | None
|
The handle the message concerns. |
session_id |
int | None
|
The session the message concerns. |
plugindata |
WebRTCPluginData | None
|
The plugin's payload on an |
jsep |
WebRTCJSEP | None
|
The SDP beside a plugin push, which is how the offer arrives. |
type |
str | None
|
On |
mid |
str | None
|
On |
receiving |
bool | None
|
On |
uplink |
bool | None
|
On |
lost |
int | None
|
On |
reason |
str | None
|
On |
Source code in src/aiopikvm/models/webrtc.py
WebRTCJSEP
¶
An SDP, as Janus carries one.
Only one message in a session has it: the plugin's answer to watch,
which is the offer this client owes an answer to.
Attributes:
| Name | Type | Description |
|---|---|---|
type |
str
|
|
sdp |
str
|
The session description itself. |
Source code in src/aiopikvm/models/webrtc.py
WebRTCPluginData
¶
One plugin payload, as Janus wraps it.
Attributes:
| Name | Type | Description |
|---|---|---|
plugin |
str
|
The plugin package, |
data |
WebRTCPluginEvent
|
What the plugin itself said. |
Source code in src/aiopikvm/models/webrtc.py
WebRTCPluginEvent
¶
What the ustreamer plugin itself said.
Either a result or an error, never both. An error here is a plugin error and rides inside a message Janus considers successful — Janus's own errors are a different shape, at the top level of the message.
Attributes:
| Name | Type | Description |
|---|---|---|
ustreamer |
str
|
Always |
result |
WebRTCResult | None
|
The answer, when the request succeeded. |
error_code |
int | None
|
The plugin's own code — 400 for a body with no |
error |
str | None
|
The text beside that code, e.g. |
Source code in src/aiopikvm/models/webrtc.py
WebRTCResult
¶
The plugin's answer to a request that succeeded.
The plugin names the status and then repeats it as the key its payload
hangs off, so a features answer is {"status": "features",
"features": {...}} and a started answer is {"status": "started"}
with nothing beside it.
Attributes:
| Name | Type | Description |
|---|---|---|
status |
str
|
|
features |
WebRTCFeatures | None
|
The payload of a |
Source code in src/aiopikvm/models/webrtc.py
Switch¶
SwitchState
¶
KVM switch state.
Mirrors GET /api/switch. Every list is indexed by port number, and all
of them are empty on a PiKVM without a switch — which is also the only
configuration the fixtures cover.
Source code in src/aiopikvm/models/switch.py
SwitchSummary
¶
Which port is currently selected.
active_port is -1 when nothing is selected, and active_id is
then an empty string. synced is False while the units are still
catching up with the state kvmd wants them in.
Source code in src/aiopikvm/models/switch.py
SwitchModel
¶
The static half of the switch state.
units and ports are empty until the units have reported in, and
stay empty on a PiKVM with no switch attached.
Source code in src/aiopikvm/models/switch.py
SwitchPort
¶
A port of the switch chain.
id is what the web UI shows: "3" on a single unit, "2.3" once
more than one unit is chained. Ports are addressed by their numeric index
everywhere in the API, not by this string.
Source code in src/aiopikvm/models/switch.py
SwitchPortAtx
¶
SwitchPortVideo
¶
SwitchAtxClickDelays
¶
SwitchUnit
¶
SwitchUnitFirmware
¶
SwitchFirmware
¶
Protocol version the switch subsystem speaks.
A constant of the kvmd build, unrelated to the firmware running on the
units — that one is SwitchUnitFirmware.
Source code in src/aiopikvm/models/switch.py
SwitchLimits
¶
SwitchAtxLimits
¶
SwitchAtxClickDelayLimits
¶
Allowed ranges for the three ATX click delays.
Source code in src/aiopikvm/models/switch.py
SwitchAtxClickDelayLimit
¶
SwitchEdids
¶
The EDID catalogue.
all is keyed by EDID id — "default" always exists — and used
lists the id in effect on each port, in port order.
Source code in src/aiopikvm/models/switch.py
EDID
¶
An EDID the switch can present to a port.
parsed is None when kvmd could not decode the blob.
Source code in src/aiopikvm/models/switch.py
EDIDInfo
¶
The fields kvmd decodes out of an EDID blob.
monitor_name and monitor_serial are None when the blob has no
descriptor block for them.
Source code in src/aiopikvm/models/switch.py
SwitchColors
¶
SwitchColor
¶
One indicator colour.
blink_ms of 0 means a steady light.
Source code in src/aiopikvm/models/switch.py
SwitchLinks
¶
SwitchBeacons
¶
SwitchAtx
¶
SwitchAtxLeds
¶
Info¶
InfoState
¶
Device information, one attribute per kvmd submanager.
Every field is optional, for two reasons that look the same from here:
get_info() can ask
for a subset, and the WebSocket sends one submanager per event, so a
snapshot taken early has only what has arrived. meta and extras
are also nullable at the source — kvmd returns None for either when
it cannot parse the files behind them — and that is indistinguishable
here from not having been asked for.
meta is left untyped on purpose. It is a YAML file the device's owner
writes, and kvmd reads exactly one thing out of it: it replaces
server.host when that is set to @auto. Nothing else about its
shape is kvmd's to promise.
Source code in src/aiopikvm/models/info.py
InfoAuth
¶
InfoNode
¶
InfoUptime
¶
InfoUptimeParts
¶
InfoHealth
¶
Load, temperature and throttling.
throttling is None wherever vcgencmd cannot be run — kvmd
reads it from the Raspberry Pi firmware and has no other source.
Source code in src/aiopikvm/models/info.py
InfoTemp
¶
InfoCPU
¶
InfoMem
¶
InfoThrottling
¶
InfoThrottlingFlags
¶
InfoThrottlingFlag
¶
One throttling condition, now and since boot.
past stays True once it has happened, which is why kvmd has an
ignore_past setting for it.
Source code in src/aiopikvm/models/info.py
InfoFan
¶
Fan controller state.
state is whatever the kvmd-fan daemon answers on its own socket,
so it is left untyped: it belongs to another program, and a device
without that daemon reports monitored false and state None.
The same None also means kvmd asked and got no answer.
Source code in src/aiopikvm/models/info.py
InfoSystem
¶
InfoKvmd
¶
InfoKernel
¶
InfoStreamer
¶
The streamer binary kvmd is configured to run.
version is an empty string and features an empty mapping when
kvmd could not run it — not None, which is why neither is nullable.
Source code in src/aiopikvm/models/info.py
InfoPlatform
¶
What the device is.
base and serial come from the device tree and model,
video and board from kvmd's platform file; any of the five is
None when the file behind it could not be read. type is a
constant in kvmd's source, not a reading.
Source code in src/aiopikvm/models/info.py
InfoExtra
¶
One entry of the extras catalogue.
An extra is a manifest.yaml shipped beside kvmd, so its contents are
whatever its author wrote and every field here is optional. kvmd itself
only writes two pairs into it: enabled and started when the
manifest names a daemon, and port resolved to an integer when the
manifest names one as a config path. Anything else the manifest carries
is kept as an extra attribute.