diff --git a/Cargo.lock b/Cargo.lock index 0e2e413..13e21d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1014,7 +1014,7 @@ dependencies = [ [[package]] name = "kon" -version = "0.3.4" +version = "0.3.5" dependencies = [ "bb8", "bb8-postgres", @@ -1912,11 +1912,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.120" +version = "1.0.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -2242,9 +2243,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokenservice-client" -version = "0.3.2" +version = "0.3.3" source = "sparse+https://git.toast-server.net/api/packages/toast/cargo/" -checksum = "afce7633f840504c54b2d2dfee881e183543ad8945bedbd86ea8fbaeb498bfb8" +checksum = "af9294666d8fc39de691f9dd8e919630622af40279dc6c17716359b318edcbb2" dependencies = [ "reqwest 0.12.5", "serde", diff --git a/Cargo.toml b/Cargo.toml index 925a831..025ac4b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kon" -version = "0.3.4" +version = "0.3.5" edition = "2021" [dependencies] @@ -17,7 +17,7 @@ reqwest = { version = "0.12.5", features = ["json"] } serde = "1.0.204" serde_json = "1.0.120" sysinfo = "0.30.13" -tokenservice-client = { version = "0.3.2", registry = "gitea" } +tokenservice-client = { version = "0.3.3", registry = "gitea" } tokio = { version = "1.39.2", features = ["macros", "signal", "rt-multi-thread"] } tokio-postgres = "0.7.11" uptime_lib = "0.3.1" diff --git a/src/commands.rs b/src/commands.rs index ce603c7..67aabcb 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -1,3 +1,4 @@ +pub mod ilo; pub mod midi; pub mod ping; pub mod status; diff --git a/src/commands/ilo.rs b/src/commands/ilo.rs new file mode 100644 index 0000000..e623037 --- /dev/null +++ b/src/commands/ilo.rs @@ -0,0 +1,144 @@ +use crate::{ + Error, + internals::{ + config::BINARY_PROPERTIES, + utils::token_path + } +}; + +use reqwest::{ + ClientBuilder, + Error as ReqError +}; +use serde::{ + Serialize, + Deserialize +}; +use poise::{ + CreateReply, + serenity_prelude::{ + CreateEmbed, + Timestamp + } +}; + +#[derive(Serialize, Deserialize)] +struct Chassis { + #[serde(rename = "Fans")] + fans: Vec, + #[serde(rename = "Temperatures")] + temperatures: Vec +} + +#[derive(Serialize, Deserialize)] +struct Fan { + #[serde(rename = "CurrentReading")] + current_reading: i32, + #[serde(rename = "FanName")] + fan_name: String, + #[serde(rename = "Status")] + status: Status, +} + +#[derive(Serialize, Deserialize)] +struct Temperature { + #[serde(rename = "CurrentReading")] + current_reading: i32, + #[serde(rename = "Name")] + name: String, + #[serde(rename = "ReadingCelsius")] + reading_celsius: i32, + #[serde(rename = "Status")] + status: Status, + #[serde(rename = "Units")] + units: String, + #[serde(rename = "UpperThresholdCritical")] + upper_threshold_critical: i32, + #[serde(rename = "UpperThresholdFatal")] + upper_threshold_fatal: i32 +} + +#[derive(Serialize, Deserialize)] +struct Status { + #[serde(rename = "Health")] + health: Option, + #[serde(rename = "State")] + state: String +} + +async fn ilo_data() -> Result { + let client = ClientBuilder::new() + .danger_accept_invalid_certs(true) + .build() + .unwrap(); + let res = client + .get(format!("https://{}/redfish/v1/chassis/1/thermal", token_path().await.ilo_ip)) + .basic_auth(token_path().await.ilo_user, Some(token_path().await.ilo_pw)) + .send() + .await + .unwrap(); + + let body = res.json().await.unwrap(); + Ok(body) +} + +/// Retrieve data from the HP iLO4 interface +#[poise::command( + slash_command, + subcommands("temperature") +)] +pub async fn ilo(_: poise::Context<'_, (), Error>) -> Result<(), Error> { + Ok(()) +} + +/// Retrieve data from the HP iLO4 interface +#[poise::command(slash_command)] +pub async fn temperature(ctx: poise::Context<'_, (), Error>) -> Result<(), Error> { + let data = ilo_data().await.unwrap(); + + let mut tempdata = String::new(); + let mut fandata = String::new(); + + let allowed_sensors = [ + "01-Inlet Ambient", + "04-P1 DIMM 1-6", + "13-Chipset", + "14-Chipset Zone" + ]; + + for temp in data.temperatures { + if temp.reading_celsius == 0 || !allowed_sensors.contains(&temp.name.as_str()) { + continue; + } + + let name = match temp.name.as_str() { + "01-Inlet Ambient" => "Inlet Ambient", + "04-P1 DIMM 1-6" => "P1 DIMM 1-6", + "13-Chipset" => "Chipset", + "14-Chipset Zone" => "Chipset Zone", + _ => "Unknown Sensor" + }; + + tempdata.push_str(&format!("**{}:** `{}°C`\n", name, temp.reading_celsius)); + } + for fan in data.fans { + if fan.current_reading == 0 { + continue; + } + + fandata.push_str(&format!("**{}:** `{}%`\n", fan.fan_name, fan.current_reading)); + } + + ctx.send(CreateReply::default().embed( + CreateEmbed::new() + .color(BINARY_PROPERTIES.embed_color) + .timestamp(Timestamp::now()) + .title("POMNI - HP iLO4 Temperatures") + .fields(vec![ + ("Temperatures", tempdata, false), + ("Fans", fandata, false) + ]) + )).await?; + + Ok(()) +} diff --git a/src/commands/status.rs b/src/commands/status.rs index 73c86d1..206de6a 100644 --- a/src/commands/status.rs +++ b/src/commands/status.rs @@ -69,8 +69,7 @@ fn process_pms_statuses(servers: Vec<(String, Vec)>) -> Vec<(String, Stri /// Query the server statuses #[poise::command( slash_command, - subcommands("wg"), - subcommand_required + subcommands("wg") )] pub async fn status(_: poise::Context<'_, (), Error>) -> Result<(), Error> { Ok(()) diff --git a/src/main.rs b/src/main.rs index bf793d6..df5e6f5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -120,6 +120,7 @@ async fn main() { let framework = poise::Framework::builder() .options(poise::FrameworkOptions { commands: vec![ + commands::ilo::ilo(), commands::ping::ping(), commands::status::status(), commands::midi::midi_to_wav(),