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