refactor for more generic charge controller driver

This commit is contained in:
Alex Janka 2024-01-13 17:06:48 +11:00
parent d4a11b8a98
commit aab1a7f2a7
7 changed files with 76 additions and 22 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
/target /target
/test-config /test-config
.trigger .trigger
~*.xlsx

Binary file not shown.

View file

@ -0,0 +1,10 @@
pub const CHARGE_CONTROLLER_LABEL: &str = "charge_controller";
pub const PL_LABEL: &str = "pl_device";
pub const BATTERY_VOLTAGE: &str = "pl_battery_voltage";
pub const TARGET_VOLTAGE: &str = "pl_target_voltage";
pub const INPUT_CURRENT: &str = "pl_internal_charge_current";
pub const CHARGE_STATE: &str = "pl_regulator";
pub const PL_DUTY_CYCLE: &str = "pl_duty_cycle";
pub const PL_LOAD_CURRENT: &str = "pl_internal_load_current";

View file

@ -0,0 +1,17 @@
use metrics::describe_gauge;
mod gauge_names;
pub mod pl;
pub fn register_metrics() {
describe_gauge!(gauge_names::BATTERY_VOLTAGE, "Battery voltage");
describe_gauge!(gauge_names::TARGET_VOLTAGE, "Target voltage");
describe_gauge!(gauge_names::INPUT_CURRENT, "Internal charge current");
describe_gauge!(gauge_names::CHARGE_STATE, "Regulator state");
register_pl_metrics();
}
fn register_pl_metrics() {
describe_gauge!(gauge_names::PL_DUTY_CYCLE, "Duty cycle");
describe_gauge!(gauge_names::PL_LOAD_CURRENT, "Internal load current");
}

View file

@ -4,13 +4,15 @@ use std::{
time::Duration, time::Duration,
}; };
use metrics::{describe_gauge, gauge, Gauge}; use metrics::{gauge, Gauge, Label};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serialport::SerialPort; use serialport::SerialPort;
use termcolor::WriteColor; use termcolor::WriteColor;
use crate::errors::{PliError, PrintErrors}; use crate::errors::{PliError, PrintErrors};
use super::gauge_names;
pub struct Pli { pub struct Pli {
pub state: Arc<RwLock<PlState>>, pub state: Arc<RwLock<PlState>>,
port: Box<dyn SerialPort>, port: Box<dyn SerialPort>,
@ -73,12 +75,35 @@ struct RegulatorGauges {
} }
impl RegulatorGauges { impl RegulatorGauges {
fn new() -> Self { fn new(labels: Vec<Label>) -> Self {
describe_gauge!("pl_regulator", "Regulator state"); let boost = gauge!(
let boost = gauge!("pl_regulator", "state" => "boost"); gauge_names::CHARGE_STATE,
let equalise = gauge!("pl_regulator", "state" => "equalise"); [
let absorption = gauge!("pl_regulator", "state" => "absorption"); labels.clone(),
let float = gauge!("pl_regulator", "state" => "float"); vec![Label::new("state", String::from("boost"))]
]
.concat()
);
let equalise = gauge!(
gauge_names::CHARGE_STATE,
[
labels.clone(),
vec![Label::new("state", String::from("equalise"))]
]
.concat()
);
let absorption = gauge!(
gauge_names::CHARGE_STATE,
[
labels.clone(),
vec![Label::new("state", String::from("absorption"))]
]
.concat()
);
let float = gauge!(
gauge_names::CHARGE_STATE,
[labels, vec![Label::new("state", String::from("float"))]].concat()
);
Self { Self {
boost, boost,
equalise, equalise,
@ -128,20 +153,20 @@ impl Pli {
baud_rate: u32, baud_rate: u32,
timeout: u64, timeout: u64,
) -> Result<Self, serialport::Error> { ) -> Result<Self, serialport::Error> {
let port = serialport::new(serial_port, baud_rate) let port = serialport::new(serial_port.clone(), baud_rate)
.timeout(Duration::from_millis(timeout)) .timeout(Duration::from_millis(timeout))
.open()?; .open()?;
describe_gauge!("pl_battery_voltage", "Battery voltage"); let device_labels = vec![
let voltage_gauge = gauge!("pl_battery_voltage"); Label::new(gauge_names::CHARGE_CONTROLLER_LABEL, serial_port.clone()),
describe_gauge!("pl_target_voltage", "Target voltage"); Label::new(gauge_names::PL_LABEL, serial_port),
let target_voltage_gauge = gauge!("pl_target_voltage"); ];
describe_gauge!("pl_duty_cycle", "Duty cycle");
let duty_cycle = gauge!("pl_duty_cycle"); let voltage_gauge = gauge!(gauge_names::BATTERY_VOLTAGE, device_labels.clone());
describe_gauge!("pl_internal_charge_current", "Internal charge current"); let target_voltage_gauge = gauge!(gauge_names::TARGET_VOLTAGE, device_labels.clone());
let internal_charge_current = gauge!("pl_internal_charge_current"); let duty_cycle = gauge!(gauge_names::PL_DUTY_CYCLE, device_labels.clone());
describe_gauge!("pl_internal_load_current", "Internal load current"); let internal_charge_current = gauge!(gauge_names::INPUT_CURRENT, device_labels.clone());
let internal_load_current = gauge!("pl_internal_load_current"); let internal_load_current = gauge!(gauge_names::PL_LOAD_CURRENT, device_labels.clone());
Ok(Self { Ok(Self {
state: Arc::new(RwLock::new(Default::default())), state: Arc::new(RwLock::new(Default::default())),
@ -151,7 +176,7 @@ impl Pli {
duty_cycle, duty_cycle,
internal_charge_current, internal_charge_current,
internal_load_current, internal_load_current,
regulator_gauges: RegulatorGauges::new(), regulator_gauges: RegulatorGauges::new(device_labels),
}) })
} }

View file

@ -4,17 +4,17 @@
extern crate rocket; extern crate rocket;
use api_interface::TeslaInterface; use api_interface::TeslaInterface;
use charge_controllers::pl::Pli;
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use errors::PrintErrors; use errors::PrintErrors;
use pl_interface::Pli;
use std::path::PathBuf; use std::path::PathBuf;
use crate::config::Config; use crate::config::Config;
mod api_interface; mod api_interface;
mod charge_controllers;
mod config; mod config;
mod errors; mod errors;
mod pl_interface;
mod server; mod server;
mod types; mod types;
@ -61,6 +61,7 @@ async fn main() {
let (api_requests, api_receiver) = async_channel::unbounded(); let (api_requests, api_receiver) = async_channel::unbounded();
// and to the pli thread // and to the pli thread
let (pli_requests, pli_receiver) = async_channel::unbounded(); let (pli_requests, pli_receiver) = async_channel::unbounded();
charge_controllers::register_metrics();
// try to spawn the pli loop // try to spawn the pli loop
let pl_state = match Pli::new( let pl_state = match Pli::new(

View file

@ -10,9 +10,9 @@ use rocket::{
use crate::{ use crate::{
api_interface::InterfaceRequest, api_interface::InterfaceRequest,
charge_controllers::pl::{PlState, PliRequest},
config::Config, config::Config,
errors::ServerError, errors::ServerError,
pl_interface::{PlState, PliRequest},
types::{CarState, ChargeState, ClimateState}, types::{CarState, ChargeState, ClimateState},
}; };