refactor metric tags & sources config

This commit is contained in:
2026-02-04 02:04:51 -08:00
parent d464cf8ee6
commit 156df9ae86
8 changed files with 326 additions and 302 deletions

View File

@@ -1,7 +1,7 @@
use crate::{
ChimemonMessage, ChimemonSource, ChimemonSourceChannel, Config, SourceMetric,
SourceReportDetails, TimeReport,
};
use std::io::{BufRead, Cursor};
use std::str;
use std::sync::Arc;
use async_trait::async_trait;
use bitflags::bitflags;
use byteorder::{BigEndian, ReadBytesExt};
@@ -11,9 +11,6 @@ use figment::value::Map;
use influxdb2::models::DataPoint;
use influxdb2::models::data_point::DataPointBuilder;
use itertools::Itertools;
use std::io::{BufRead, Cursor};
use std::str;
use std::sync::Arc;
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader, ReadHalf, WriteHalf};
use tokio::join;
use tokio::sync::Mutex;
@@ -21,6 +18,11 @@ use tokio::time::sleep;
use tokio_serial::{SerialPort, SerialStream};
use tracing::{debug, info, warn};
use crate::{
ChimemonMessage, ChimemonSource, ChimemonSourceChannel, SourceMetric, SourceReportDetails,
TimeReport, UCCMConfig,
};
pub const GPS_EPOCH: i64 = 315964800; // Doesn't seem possible to have a const DateTime object
pub type UccmEndian = BigEndian;
@@ -32,11 +34,11 @@ pub enum UCCMMonitorParseState {
}
pub struct UCCMMonitor {
// pub port: SerialStream,
pub name: String,
config: UCCMConfig,
rx: ReadHalf<SerialStream>,
tx: WriteHalf<SerialStream>,
pub info: Option<UCCMInfo>,
config: Config,
}
#[derive(Debug)]
@@ -399,30 +401,6 @@ impl TryFrom<&str> for UCCMGPSSatsReport {
}
impl UCCMMonitor {
pub fn new(config: Config) -> Self {
let builder = tokio_serial::new(&config.sources.uccm.port, config.sources.uccm.baud)
.timeout(config.sources.uccm.timeout)
.data_bits(tokio_serial::DataBits::Eight)
.parity(tokio_serial::Parity::None)
.stop_bits(tokio_serial::StopBits::One)
.flow_control(tokio_serial::FlowControl::None);
let mut port = SerialStream::open(&builder).expect("Must be able to open serial port");
port.set_exclusive(true).expect("Can't lock serial port");
info!(
"Opened serial port {}@{}",
port.name().unwrap(),
port.baud_rate().unwrap()
);
let (rx, tx) = tokio::io::split(port);
UCCMMonitor {
// port,
rx,
tx,
info: None,
config,
}
}
pub async fn send_cmd(&mut self, cmd: &[u8]) -> Result<String, std::io::Error> {
debug!("cmd: `{:?}`", String::from_utf8_lossy(cmd));
self.tx.write_all(cmd).await.unwrap();
@@ -481,7 +459,7 @@ impl UCCMMonitor {
let mut last_loop_diag: Option<UCCMLoopDiagReport> = None;
let mut last_gps_sats: Option<UCCMGPSSatsReport> = None;
let mut last_sent_report = Utc::now() - self.config.sources.uccm.status_interval;
let mut last_sent_report = Utc::now() - self.config.status_interval;
loop {
match tokio::io::AsyncReadExt::read_buf(&mut self.rx, &mut rdbuf).await {
@@ -525,37 +503,33 @@ impl UCCMMonitor {
}))
.expect("Unable to send to channel");
if sysnow - last_sent_report
>= Duration::from_std(self.config.sources.uccm.status_interval)
.unwrap()
>= Duration::from_std(self.config.status_interval).unwrap()
{
let mut points = vec![
tod.as_builder(
&self.config.sources.uccm.measurement,
&self.config.influxdb.tags,
)
.build()
.unwrap(),
];
if let Some(loop_diag) = &last_loop_diag {
points.push(
loop_diag
.as_builder(
&self.config.sources.uccm.measurement,
&self.config.influxdb.tags,
)
.build()
.unwrap(),
)
}
if let Some(gps_sats) = &last_gps_sats {
points.extend(gps_sats.build(
&self.config.sources.uccm.measurement,
&self.config.influxdb.tags,
));
}
// let mut points = vec![
// tod.as_builder(&self.config.measurement, &self.config.tags)
// .build()
// .unwrap(),
// ];
// if let Some(loop_diag) = &last_loop_diag {
// points.push(
// loop_diag
// .as_builder(
// &self.config.measurement,
// &self.config.influxdb.tags,
// )
// .build()
// .unwrap(),
// )
// }
// if let Some(gps_sats) = &last_gps_sats {
// points.extend(gps_sats.build(
// &self.config.sources.uccm.measurement,
// &self.config.influxdb.tags,
// ));
// }
chan.send(ChimemonMessage::DataPoints(points))
.expect("Unable to send to channel");
// chan.send(ChimemonMessage::DataPoints(points))
// .expect("Unable to send to channel");
last_sent_report = sysnow;
}
}
@@ -597,6 +571,31 @@ impl UCCMMonitor {
#[async_trait]
impl ChimemonSource for UCCMMonitor {
type Config = UCCMConfig;
fn new(name: &str, config: Self::Config) -> Self {
let builder = tokio_serial::new(&config.port, config.baud)
.timeout(config.timeout)
.data_bits(tokio_serial::DataBits::Eight)
.parity(tokio_serial::Parity::None)
.stop_bits(tokio_serial::StopBits::One)
.flow_control(tokio_serial::FlowControl::None);
let mut port = SerialStream::open(&builder).expect("Must be able to open serial port");
port.set_exclusive(true).expect("Can't lock serial port");
info!(
"Opened serial port {}@{}",
port.name().unwrap(),
port.baud_rate().unwrap()
);
let (rx, tx) = tokio::io::split(port);
UCCMMonitor {
name: name.to_owned(),
config,
rx,
tx,
info: None,
}
}
async fn run(mut self, chan: ChimemonSourceChannel) {
info!("UCCM task starting");
if self.get_info().await.is_err() {