diff --git a/src/uccm.rs b/src/uccm.rs index 9ee4e76..abee4ef 100644 --- a/src/uccm.rs +++ b/src/uccm.rs @@ -1,4 +1,7 @@ -use crate::{ChimemonMessage, ChimemonSource, ChimemonSourceChannel, Config, TimeReport}; +use crate::{ + ChimemonMessage, ChimemonSource, ChimemonSourceChannel, Config, SourceMetric, + SourceReportDetails, TimeReport, +}; use async_trait::async_trait; use bitflags::bitflags; use byteorder::{BigEndian, ReadBytesExt}; @@ -43,6 +46,77 @@ pub struct UCCMTODReport { pub flags: UCCMFlags, } +impl SourceReportDetails for UCCMTODReport { + fn is_healthy(&self) -> bool { + self.flags.contains(UCCMFlags::OSC_LOCK) + && self.flags.contains(UCCMFlags::HAVE_GPS_TIME) + && !self.flags.contains(UCCMFlags::INIT_UNLOCK) + && !self.flags.contains(UCCMFlags::INIT_NO_SATS) + && !self.flags.contains(UCCMFlags::POWER_FAIL) + && !self.flags.contains(UCCMFlags::NO_GPS_SYNC) + && !self.flags.contains(UCCMFlags::NO_GPS_SYNC2) + && !self.flags.contains(UCCMFlags::NO_ANT) + && !self.flags.contains(UCCMFlags::GPS_LOS) + } + + fn to_metrics(&self) -> Vec { + let no_tags = Arc::new(vec![]); + vec![ + SourceMetric::new_int("leaps", self.leaps as i64, no_tags.clone()), + SourceMetric::new_bool( + "osc_lock", + self.flags.contains(UCCMFlags::OSC_LOCK), + no_tags.clone(), + ), + SourceMetric::new_bool( + "leap_flag", + self.flags.contains(UCCMFlags::LEAP_FLAG), + no_tags.clone(), + ), + SourceMetric::new_bool( + "init_unlock", + self.flags.contains(UCCMFlags::INIT_UNLOCK), + no_tags.clone(), + ), + SourceMetric::new_bool( + "init_no_sats", + self.flags.contains(UCCMFlags::INIT_NO_SATS), + no_tags.clone(), + ), + SourceMetric::new_bool( + "have_gps_time", + self.flags.contains(UCCMFlags::HAVE_GPS_TIME), + no_tags.clone(), + ), + SourceMetric::new_bool( + "power_fail", + self.flags.contains(UCCMFlags::POWER_FAIL), + no_tags.clone(), + ), + SourceMetric::new_bool( + "no_gps_sync", + self.flags.contains(UCCMFlags::NO_GPS_SYNC), + no_tags.clone(), + ), + SourceMetric::new_bool( + "no_gps_sync2", + self.flags.contains(UCCMFlags::NO_GPS_SYNC2), + no_tags.clone(), + ), + SourceMetric::new_bool( + "ant_fault", + self.flags.contains(UCCMFlags::NO_ANT), + no_tags.clone(), + ), + SourceMetric::new_bool( + "gps_los", + self.flags.contains(UCCMFlags::GPS_LOS), + no_tags.clone(), + ), + ] + } +} + impl UCCMTODReport { pub fn as_builder(&self, measurement: &String, tags: &Map) -> DataPointBuilder { let mut builder = @@ -194,6 +268,27 @@ pub struct UCCMStatusReport { pub freq_error: f32, } +impl SourceReportDetails for UCCMStatusReport { + fn is_healthy(&self) -> bool { + self.gps_pps_valid + } + fn to_metrics(&self) -> Vec { + let no_tags = Arc::new(vec![]); + vec![ + SourceMetric::new_int("tfom", self.tfom as i64, no_tags.clone()), + SourceMetric::new_int("ffom", self.ffom as i64, no_tags.clone()), + SourceMetric::new_float("gps_phase", self.gps_phase as f64, no_tags.clone()), + // TODO: sv info + // TOOD: timestamp + SourceMetric::new_float("ant_voltage", self.ant_voltage as f64, no_tags.clone()), + SourceMetric::new_float("ant_current", self.ant_current as f64, no_tags.clone()), + SourceMetric::new_float("temp", self.temp as f64, no_tags.clone()), + SourceMetric::new_int("efc_dac", self.efc_dac as i64, no_tags.clone()), + SourceMetric::new_float("freq_error", self.freq_error as f64, no_tags.clone()), + ] + } +} + pub struct UCCMInfo { pub vendor: String, pub model: String,