use crate::traits::{NodeId, ParameterId, PortId};
use std::fmt;
use std::time::{SystemTime, UNIX_EPOCH};
pub const CLOCK_TICK: &str = "clock_tick";
pub const CLOCK_TEMPO: &str = "clock_tempo";
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum TelemetryKind {
Parameter,
Signal,
Peak,
Event,
Violation,
}
impl fmt::Display for TelemetryKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TelemetryKind::Parameter => write!(f, "parameter"),
TelemetryKind::Signal => write!(f, "signal"),
TelemetryKind::Peak => write!(f, "peak"),
TelemetryKind::Event => write!(f, "event"),
TelemetryKind::Violation => write!(f, "violation"),
}
}
}
#[derive(Debug, Clone)]
pub enum Telemetry {
ParameterValue {
port: PortId,
parameter: ParameterId,
value: f32,
timestamp: u64,
},
SignalData {
node_id: NodeId,
channel: usize,
data: Vec<f32>,
timestamp: u64,
sample_rate: f32,
},
Peak {
port: PortId,
value: f32,
timestamp: u64,
hold_time_ms: Option<u32>,
},
Event {
source: String,
kind: String,
data: Vec<f32>,
timestamp: u64,
description: Option<String>,
},
Violation {
component: String,
expected_ns: u64,
actual_ns: u64,
value: Option<f32>,
timestamp: u64,
},
}
impl Telemetry {
pub fn now() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_micros() as u64
}
pub fn parameter(port: PortId, parameter: ParameterId, value: f32) -> Self {
Telemetry::ParameterValue {
port,
parameter,
value,
timestamp: Self::now(),
}
}
pub fn event(source: impl Into<String>, kind: impl Into<String>, data: Vec<f32>) -> Self {
Telemetry::Event {
source: source.into(),
kind: kind.into(),
data,
timestamp: Self::now(),
description: None,
}
}
pub fn event_with_description(
source: impl Into<String>,
kind: impl Into<String>,
data: Vec<f32>,
description: impl Into<String>,
) -> Self {
Telemetry::Event {
source: source.into(),
kind: kind.into(),
data,
timestamp: Self::now(),
description: Some(description.into()),
}
}
pub fn violation(
component: impl Into<String>,
expected_ns: u64,
actual_ns: u64,
value: Option<f32>,
) -> Self {
Telemetry::Violation {
component: component.into(),
expected_ns,
actual_ns,
value,
timestamp: Self::now(),
}
}
pub fn kind(&self) -> TelemetryKind {
match self {
Telemetry::ParameterValue { .. } => TelemetryKind::Parameter,
Telemetry::SignalData { .. } => TelemetryKind::Signal,
Telemetry::Peak { .. } => TelemetryKind::Peak,
Telemetry::Event { .. } => TelemetryKind::Event,
Telemetry::Violation { .. } => TelemetryKind::Violation,
}
}
}