1use crate::traits::{NodeId, ParameterId, PortId};
4use std::fmt;
5use std::time::{SystemTime, UNIX_EPOCH};
6
7pub const CLOCK_TICK: &str = "clock_tick";
9pub const CLOCK_TEMPO: &str = "clock_tempo";
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
14pub enum TelemetryKind {
15 Parameter,
17 Signal,
19 Peak,
21 Event,
23 Violation,
25}
26
27impl fmt::Display for TelemetryKind {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 match self {
30 TelemetryKind::Parameter => write!(f, "parameter"),
31 TelemetryKind::Signal => write!(f, "signal"),
32 TelemetryKind::Peak => write!(f, "peak"),
33 TelemetryKind::Event => write!(f, "event"),
34 TelemetryKind::Violation => write!(f, "violation"),
35 }
36 }
37}
38
39#[derive(Debug, Clone)]
41pub enum Telemetry {
42 ParameterValue {
44 port: PortId,
46 parameter: ParameterId,
48 value: f32,
50 timestamp: u64,
52 },
53 SignalData {
55 node_id: NodeId,
57 channel: usize,
59 data: Vec<f32>,
61 timestamp: u64,
63 sample_rate: f32,
65 },
66 Peak {
68 port: PortId,
70 value: f32,
72 timestamp: u64,
74 hold_time_ms: Option<u32>,
76 },
77 Event {
79 source: String,
81 kind: String,
83 data: Vec<f32>,
85 timestamp: u64,
87 description: Option<String>,
89 },
90 Violation {
92 component: String,
94 expected_ns: u64,
96 actual_ns: u64,
98 value: Option<f32>,
100 timestamp: u64,
102 },
103}
104
105impl Telemetry {
106 pub fn now() -> u64 {
108 SystemTime::now()
109 .duration_since(UNIX_EPOCH)
110 .unwrap_or_default()
111 .as_micros() as u64
112 }
113
114 pub fn parameter(port: PortId, parameter: ParameterId, value: f32) -> Self {
116 Telemetry::ParameterValue {
117 port,
118 parameter,
119 value,
120 timestamp: Self::now(),
121 }
122 }
123
124 pub fn event(source: impl Into<String>, kind: impl Into<String>, data: Vec<f32>) -> Self {
126 Telemetry::Event {
127 source: source.into(),
128 kind: kind.into(),
129 data,
130 timestamp: Self::now(),
131 description: None,
132 }
133 }
134
135 pub fn event_with_description(
137 source: impl Into<String>,
138 kind: impl Into<String>,
139 data: Vec<f32>,
140 description: impl Into<String>,
141 ) -> Self {
142 Telemetry::Event {
143 source: source.into(),
144 kind: kind.into(),
145 data,
146 timestamp: Self::now(),
147 description: Some(description.into()),
148 }
149 }
150
151 pub fn violation(
153 component: impl Into<String>,
154 expected_ns: u64,
155 actual_ns: u64,
156 value: Option<f32>,
157 ) -> Self {
158 Telemetry::Violation {
159 component: component.into(),
160 expected_ns,
161 actual_ns,
162 value,
163 timestamp: Self::now(),
164 }
165 }
166
167 pub fn kind(&self) -> TelemetryKind {
169 match self {
170 Telemetry::ParameterValue { .. } => TelemetryKind::Parameter,
171 Telemetry::SignalData { .. } => TelemetryKind::Signal,
172 Telemetry::Peak { .. } => TelemetryKind::Peak,
173 Telemetry::Event { .. } => TelemetryKind::Event,
174 Telemetry::Violation { .. } => TelemetryKind::Violation,
175 }
176 }
177}