launch server even with no cars

This commit is contained in:
Alex Janka 2024-02-13 09:03:35 +11:00
parent 942d3cc3cf
commit 1cde09ff58

View file

@ -64,108 +64,119 @@ async fn main() {
let config_path = args.config_dir.join("config.json"); let config_path = args.config_dir.join("config.json");
let (config, _config_watcher) = config::init_config(config_path); let (config, _config_watcher) = config::init_config(config_path);
config::CONFIG.get_or_init(|| RwLock::new(config)); config::CONFIG.get_or_init(|| RwLock::new(config));
if let Some(mut interface) = TeslaInterface::load(auth_path) let interface = TeslaInterface::load(auth_path)
.await .await
.some_or_print_with("loading tesla interface") .some_or_print_with("loading tesla interface");
{
// build the channel that takes messages from the webserver thread to the api thread // build the channel that takes messages from the webserver thread to the api thread
let (api_requests, mut api_receiver) = tokio::sync::mpsc::unbounded_channel(); let (api_requests, mut api_receiver) = tokio::sync::mpsc::unbounded_channel();
// and to the pli thread // and to the pli thread
let (pli_requests, mut pli_receiver) = tokio::sync::mpsc::unbounded_channel(); let (pli_requests, mut pli_receiver) = tokio::sync::mpsc::unbounded_channel();
// and to the charge rate controller thread // and to the charge rate controller thread
let (tcrc_requests, mut tcrc_receiver) = tokio::sync::mpsc::unbounded_channel(); let (tcrc_requests, mut tcrc_receiver) = tokio::sync::mpsc::unbounded_channel();
// try to spawn the pli loop // try to spawn the pli loop
let pli = { let pli = {
let config = access_config(); let config = access_config();
Pli::new( Pli::new(
config.serial_port.clone(), config.serial_port.clone(),
config.baud_rate, config.baud_rate,
config.pl_timeout_milliseconds, config.pl_timeout_milliseconds,
) )
}; };
let pl_state = match pli { let pl_state = match pli {
Ok(mut pli) => { Ok(mut pli) => {
let pl_state = pli.state.clone(); let pl_state = pli.state.clone();
tokio::task::spawn(async move { tokio::task::spawn(async move {
let mut interval = let mut interval = tokio::time::interval(std::time::Duration::from_secs(
tokio::time::interval(std::time::Duration::from_secs( access_config().pl_watch_interval_seconds,
access_config().pl_watch_interval_seconds, ));
)); loop {
loop { tokio::select! {
tokio::select! { _ = interval.tick() => pli.refresh(),
_ = interval.tick() => pli.refresh(), message = pli_receiver.recv() => match message {
message = pli_receiver.recv() => match message { Some(message) => pli.process_request(message),
Some(message) => pli.process_request(message), None => panic!("PLI send channel dropped")
None => panic!("PLI send channel dropped")
}
} }
} }
}); }
Some(pl_state) });
} Some(pl_state)
Err(e) => { }
log::error!("Error connecting to serial device for PLI: {e:?}"); Err(e) => {
None log::error!("Error connecting to serial device for PLI: {e:?}");
} None
}; }
let local = tokio::task::LocalSet::new(); };
// spawn a loop for each additional charge controller to log let local = tokio::task::LocalSet::new();
// failed connections will print an error but the program will continue // spawn a loop for each additional charge controller to log
let _additional_controllers: Vec<_> = access_config() // failed connections will print an error but the program will continue
.additional_charge_controllers let _additional_controllers: Vec<_> = access_config()
.clone() .additional_charge_controllers
.into_iter() .clone()
.filter_map(|v| match v { .into_iter()
ChargeControllerConfig::Pl { .filter_map(|v| match v {
serial_port, ChargeControllerConfig::Pl {
baud_rate, serial_port,
timeout_milliseconds, baud_rate,
watch_interval_seconds, timeout_milliseconds,
} => Pli::new(serial_port.clone(), baud_rate, timeout_milliseconds) watch_interval_seconds,
.some_or_print_with("Failed to connect to additional PLI") } => Pli::new(serial_port.clone(), baud_rate, timeout_milliseconds)
.map(|mut pli| { .some_or_print_with("Failed to connect to additional PLI")
tokio::task::spawn(async move { .map(|mut pli| {
let mut interval = tokio::time::interval( tokio::task::spawn(async move {
std::time::Duration::from_secs(watch_interval_seconds), let mut interval = tokio::time::interval(
); std::time::Duration::from_secs(watch_interval_seconds),
loop { );
interval.tick().await; loop {
pli.refresh(); interval.tick().await;
} pli.refresh();
}) }
}), })
ChargeControllerConfig::Tristar { }),
serial_port, ChargeControllerConfig::Tristar {
baud_rate, serial_port,
watch_interval_seconds, baud_rate,
} => Tristar::new(serial_port.clone(), baud_rate) watch_interval_seconds,
.some_or_print_with("Failed to connect to additional Tristar") } => Tristar::new(serial_port.clone(), baud_rate)
.map(|mut tristar| { .some_or_print_with("Failed to connect to additional Tristar")
local.spawn_local(async move { .map(|mut tristar| {
let mut interval = tokio::time::interval( local.spawn_local(async move {
std::time::Duration::from_secs(watch_interval_seconds), let mut interval = tokio::time::interval(
); std::time::Duration::from_secs(watch_interval_seconds),
loop { );
interval.tick().await; loop {
tristar.refresh(); interval.tick().await;
} tristar.refresh();
}) }
}), })
}) }),
.collect(); })
.collect();
let mut tesla_charge_rate_controller = let interface_and_tcrc = interface.map(|interface| {
let tcrc =
TeslaChargeRateController::new(interface.state.clone(), pl_state.clone()); TeslaChargeRateController::new(interface.state.clone(), pl_state.clone());
(interface, tcrc)
});
let car_state = interface_and_tcrc
.as_ref()
.map(|(interface, _)| interface.state.clone())
.unwrap_or_default();
let tcrc_state = interface_and_tcrc
.as_ref()
.map(|(_, tcrc)| tcrc.tcrc_state.clone())
.unwrap_or_default();
let server_handle = server::launch_server(server::ServerState { let server_handle = server::launch_server(server::ServerState {
car_state: interface.state.clone(), car_state,
pl_state, pl_state,
tcrc_state: tesla_charge_rate_controller.tcrc_state.clone(), tcrc_state,
api_requests, api_requests,
pli_requests, pli_requests,
tcrc_requests, tcrc_requests,
}); });
if let Some((mut interface, mut tesla_charge_rate_controller)) = interface_and_tcrc {
// spawn the api / charge rate control loop // spawn the api / charge rate control loop
tokio::task::spawn(async move { tokio::task::spawn(async move {
let mut normal_data_update_interval = let mut normal_data_update_interval =
@ -219,8 +230,8 @@ async fn main() {
} }
} }
}); });
tokio::join!(server_handle, local);
} }
tokio::join!(server_handle, local);
} }
} }
} }