Skip to main content

ados_protocol/
node_info.rs

1//! The `node.info` plugin method: the node facts a plugin may read without
2//! reaching into the agent's sidecars, which its sandbox hides.
3//!
4//! The host answers from the same sources the agent's own services decide on
5//! (the node profile, the HAL board sidecar, the ground-station role sentinel,
6//! the camera-state sidecar and the video config). A source that is absent maps
7//! to `null` on the wire and `None` here; the host never fills a gap with a
8//! guess. The types are the wire shape: the host serializes them and the SDK
9//! deserializes them, so the two cannot drift.
10
11use serde::{Deserialize, Serialize};
12
13/// The wire method name.
14pub const METHOD: &str = "node.info";
15
16/// The capability `node.info` is gated on.
17pub const CAPABILITY: &str = "node.info.read";
18
19/// Everything `node.info` answers.
20#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
21pub struct NodeInfo {
22    /// The node profile in wire form: `drone`, `ground-station`, `workstation`
23    /// or `compute`.
24    pub profile: String,
25    /// The board, or `None` when the board sidecar is absent or unreadable (a
26    /// node that has not probed yet).
27    pub board: Option<BoardInfo>,
28    /// The ground-station facts. `role` is `None` on every profile other than
29    /// `ground-station`.
30    pub ground_station: GroundStationInfo,
31    /// The camera facts.
32    pub camera: CameraInfo,
33}
34
35/// The board the node runs on.
36#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
37pub struct BoardInfo {
38    /// The board identity manifests' `compatibility.supported_boards` match
39    /// against (the board sidecar's `name`).
40    pub id: String,
41    /// The hardware model string the board reports (the sidecar's `model`).
42    pub name: String,
43    /// The board declares a neural accelerator (`npu_tops > 0`). The same rule
44    /// the offload decision and the status surfaces' `hasAccelerator` key on.
45    pub has_npu: bool,
46    /// The inference accelerators the board declares: `npu` when it has one,
47    /// and `cpu-<runtime>` (e.g. `cpu-onnx`) when it declares CPU inference.
48    /// Empty when it declares neither.
49    pub accelerators: Vec<String>,
50}
51
52/// The ground-station facts.
53#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
54pub struct GroundStationInfo {
55    /// `direct`, `relay` or `receiver` on a ground station (a ground station
56    /// with no role sentinel runs the direct plane, so reads `direct`); `None`
57    /// on any other profile.
58    pub role: Option<String>,
59}
60
61/// The camera facts.
62#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
63pub struct CameraInfo {
64    /// The video pipeline is publishing the `main` stream: its camera-state
65    /// report says `streaming` (stamped only once mediamtx holds the encoder's
66    /// publisher on `main`) and was re-stamped within the live window. `false`
67    /// while the encoder is still starting, when the pipeline is stopped or
68    /// failed, and when the report is absent or stale, whatever the camera
69    /// source (a local camera or a network stream).
70    pub ready: bool,
71    /// The geometry the primary encoder (the `main` stream) runs at, or `None`
72    /// when the node has no config file or is a ground station (no onboard
73    /// camera).
74    pub main: Option<StreamGeometry>,
75}
76
77/// One stream's geometry.
78#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
79pub struct StreamGeometry {
80    pub width: u32,
81    pub height: u32,
82    pub fps: u32,
83}