This commit is contained in:
Alex Janka 2024-01-09 11:50:37 +11:00
parent 192731dcd3
commit 859326c132
3 changed files with 13 additions and 2 deletions

View file

@ -59,11 +59,12 @@ struct AuthInfo {
} }
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
// these are the messages that the webserver can send the api thread
pub enum InterfaceRequest { pub enum InterfaceRequest {
FlashLights, FlashLights,
} }
const REFRESH_INTERVAL: Duration = Duration::from_secs(12 * 60 * 60); const KEY_REFRESH_INTERVAL: Duration = Duration::from_secs(12 * 60 * 60);
impl TeslaInterface { impl TeslaInterface {
pub async fn load(auth_path: PathBuf) -> Result<Self, AuthLoadError> { pub async fn load(auth_path: PathBuf) -> Result<Self, AuthLoadError> {
@ -150,7 +151,8 @@ impl TeslaInterface {
} }
async fn refresh_keys(&mut self) { async fn refresh_keys(&mut self) {
if Instant::now().duration_since(self.last_refresh) >= REFRESH_INTERVAL { // refresh our Tesla (the company's web servers, not the car) access token
if Instant::now().duration_since(self.last_refresh) >= KEY_REFRESH_INTERVAL {
match self.api.refresh().await { match self.api.refresh().await {
Ok(_) => { Ok(_) => {
let now = Instant::now(); let now = Instant::now();
@ -166,6 +168,9 @@ impl TeslaInterface {
} }
async fn get_state(api: &FleetApi, vehicle_id: VehicleId) -> Result<CarState> { async fn get_state(api: &FleetApi, vehicle_id: VehicleId) -> Result<CarState> {
// Endpoint::VehicleDataCombo or multiple Endpoints in one request
// doesn't seem to reliably get them all,
// so for each endpoint we do a new request
let charge_state = api let charge_state = api
.vehicle_data(&GetVehicleData { .vehicle_data(&GetVehicleData {
vehicle_id, vehicle_id,

View file

@ -52,6 +52,7 @@ async fn main() {
let config: Config = let config: Config =
ron::from_str(&std::fs::read_to_string(&config_path).unwrap()).unwrap(); ron::from_str(&std::fs::read_to_string(&config_path).unwrap()).unwrap();
// build the channel that takes messages from the webserver thread to the api thread
let (api_requests, receiver) = async_channel::unbounded(); let (api_requests, receiver) = async_channel::unbounded();
let server_handle = server::launch_server(server::ServerState { let server_handle = server::launch_server(server::ServerState {
@ -60,9 +61,11 @@ async fn main() {
api_requests, api_requests,
}); });
// spawn the api loop
tokio::task::spawn(async move { tokio::task::spawn(async move {
let mut interval = tokio::time::interval(std::time::Duration::from_secs(120)); let mut interval = tokio::time::interval(std::time::Duration::from_secs(120));
loop { loop {
// await either the next interval OR a message from the other thread
tokio::select! { tokio::select! {
_ = interval.tick() => interface.refresh().await, _ = interval.tick() => interface.refresh().await,
message = receiver.recv() => match message { message = receiver.recv() => match message {

View file

@ -29,6 +29,9 @@ pub async fn launch_server(state: ServerState) {
} }
fn rocket(state: ServerState) -> rocket::Rocket<rocket::Build> { fn rocket(state: ServerState) -> rocket::Rocket<rocket::Build> {
// serve the html from disk if running in a debug build
// this allows editing the webpage without having to rebuild the executable
// but in release builds, bundle the entire webapp folder into the exe
let fileserver: Vec<rocket::Route> = if cfg!(debug_assertions) { let fileserver: Vec<rocket::Route> = if cfg!(debug_assertions) {
rocket::fs::FileServer::from(format!( rocket::fs::FileServer::from(format!(
"{}/webapp", "{}/webapp",