diff --git a/Cargo.lock b/Cargo.lock index a334111..afeab09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -239,7 +239,7 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "charge-controller-supervisor" -version = "1.9.9-pre-4" +version = "1.9.9-pre-5" dependencies = [ "chrono", "clap", @@ -2201,7 +2201,7 @@ dependencies = [ [[package]] name = "tesla-charge-controller" -version = "1.9.9-pre-4" +version = "1.9.9-pre-5" dependencies = [ "chrono", "clap", diff --git a/Cargo.toml b/Cargo.toml index 5995459..fa4416d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ default-members = ["charge-controller-supervisor"] resolver = "2" [workspace.package] -version = "1.9.9-pre-4" +version = "1.9.9-pre-5" [workspace.lints.clippy] pedantic = "warn" diff --git a/charge-controller-supervisor/src/main.rs b/charge-controller-supervisor/src/main.rs index 10f8e06..1444cd6 100644 --- a/charge-controller-supervisor/src/main.rs +++ b/charge-controller-supervisor/src/main.rs @@ -82,7 +82,7 @@ async fn watch(args: Args) -> eyre::Result<()> { } } - let server = web::rocket(web::ServerState::new(map)); + let server = web::rocket(web::ServerState::new(config.primary_charge_controller, map)); let server_task = tokio::task::spawn(server.launch()); tokio::select! { diff --git a/charge-controller-supervisor/src/web.rs b/charge-controller-supervisor/src/web.rs index d603f0d..c80ab7b 100644 --- a/charge-controller-supervisor/src/web.rs +++ b/charge-controller-supervisor/src/web.rs @@ -1,6 +1,7 @@ use rocket::{get, routes, serde::json::Json, State}; pub struct ServerState { + primary_name: String, map: std::collections::HashMap< String, std::sync::Arc>, @@ -9,19 +10,27 @@ pub struct ServerState { impl ServerState { pub fn new( + primary_name: String, map: std::collections::HashMap< String, std::sync::Arc>, >, ) -> Self { - Self { map } + Self { primary_name, map } } } pub fn rocket(state: ServerState) -> rocket::Rocket { - rocket::build() - .manage(state) - .mount("/", routes![metrics, interfaces, all_interfaces, interface]) + rocket::build().manage(state).mount( + "/", + routes![ + metrics, + interfaces, + all_interfaces, + primary_interface, + interface + ], + ) } #[get("/interfaces")] @@ -29,6 +38,21 @@ fn interfaces(state: &State) -> Json> { Json(state.map.keys().cloned().collect()) } +#[get("/interfaces/primary")] +async fn primary_interface( + state: &State, +) -> Result, ServerError> { + let s = state + .map + .get(&state.primary_name) + .ok_or(ServerError::InvalidPrimaryName)? + .read() + .await + .clone(); + + Ok(Json(s)) +} + #[get("/interfaces/data")] async fn all_interfaces( state: &State, @@ -68,6 +92,7 @@ fn metrics() -> Result { enum ServerError { Prometheus, NotFound, + InvalidPrimaryName, } impl From for ServerError { @@ -79,8 +104,9 @@ impl From for ServerError { impl<'a> rocket::response::Responder<'a, 'a> for ServerError { fn respond_to(self, _: &'a rocket::Request<'_>) -> rocket::response::Result<'a> { Err(match self { + Self::Prometheus => rocket::http::Status::InternalServerError, Self::NotFound => rocket::http::Status::NotFound, - ServerError::Prometheus => rocket::http::Status::InternalServerError, + Self::InvalidPrimaryName => rocket::http::Status::ServiceUnavailable, }) } }