1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5use std::net::IpAddr;
6
7use super::common::{Bandwidth, DataSource, EntityOrigin};
8use super::entity_id::{EntityId, MacAddress};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
12#[non_exhaustive]
13pub enum DeviceType {
14 Gateway,
15 Switch,
16 AccessPoint,
17 Other,
18}
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
22#[non_exhaustive]
23pub enum DeviceState {
24 Online,
25 Offline,
26 PendingAdoption,
27 Updating,
28 GettingReady,
29 Adopting,
30 Deleting,
31 ConnectionInterrupted,
32 Isolated,
33 Unknown,
34}
35
36impl DeviceState {
37 pub fn is_online(&self) -> bool {
38 matches!(self, Self::Online)
39 }
40
41 pub fn is_transitional(&self) -> bool {
42 matches!(
43 self,
44 Self::Updating | Self::GettingReady | Self::Adopting | Self::PendingAdoption
45 )
46 }
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct Port {
52 pub index: u32,
53 pub name: Option<String>,
54 pub state: PortState,
55 pub speed_mbps: Option<u32>,
56 pub max_speed_mbps: Option<u32>,
57 pub connector: Option<PortConnector>,
58 pub poe: Option<PoeInfo>,
59}
60
61#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
62pub enum PortState {
63 Up,
64 Down,
65 Unknown,
66}
67
68#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
69pub enum PortConnector {
70 Rj45,
71 Sfp,
72 SfpPlus,
73 Sfp28,
74 Qsfp28,
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize)]
78pub struct PoeInfo {
79 pub standard: Option<String>,
80 pub enabled: bool,
81 pub state: PortState,
82}
83
84#[derive(Debug, Clone, Serialize, Deserialize)]
86pub struct Radio {
87 pub frequency_ghz: f32,
88 pub channel: Option<u32>,
89 pub channel_width_mhz: Option<u32>,
90 pub wlan_standard: Option<String>,
91 pub tx_retries_pct: Option<f64>,
92 pub channel_utilization_pct: Option<f64>,
93}
94
95#[derive(Debug, Clone, Default, Serialize, Deserialize)]
97pub struct DeviceStats {
98 pub uptime_secs: Option<u64>,
99 pub cpu_utilization_pct: Option<f64>,
100 pub memory_utilization_pct: Option<f64>,
101 pub load_average_1m: Option<f64>,
102 pub load_average_5m: Option<f64>,
103 pub load_average_15m: Option<f64>,
104 pub uplink_bandwidth: Option<Bandwidth>,
105 pub last_heartbeat: Option<DateTime<Utc>>,
106 pub next_heartbeat: Option<DateTime<Utc>>,
107}
108
109#[derive(Debug, Clone, Serialize, Deserialize)]
111#[allow(clippy::struct_excessive_bools)]
112pub struct Device {
113 pub id: EntityId,
114 pub mac: MacAddress,
115 pub ip: Option<IpAddr>,
116 pub wan_ipv6: Option<String>,
117 pub name: Option<String>,
118 pub model: Option<String>,
119 pub device_type: DeviceType,
120 pub state: DeviceState,
121
122 pub firmware_version: Option<String>,
124 pub firmware_updatable: bool,
125
126 pub adopted_at: Option<DateTime<Utc>>,
128 pub provisioned_at: Option<DateTime<Utc>>,
129 pub last_seen: Option<DateTime<Utc>>,
130
131 pub serial: Option<String>,
133 pub supported: bool,
134
135 pub ports: Vec<Port>,
137 pub radios: Vec<Radio>,
138
139 pub uplink_device_id: Option<EntityId>,
141 pub uplink_device_mac: Option<MacAddress>,
142
143 pub has_switching: bool,
145 pub has_access_point: bool,
146
147 pub stats: DeviceStats,
149
150 pub client_count: Option<u32>,
152
153 pub origin: Option<EntityOrigin>,
155
156 #[serde(skip)]
157 #[allow(dead_code)]
158 pub(crate) source: DataSource,
159 #[serde(skip)]
160 #[allow(dead_code)]
161 pub(crate) updated_at: DateTime<Utc>,
162}