From 79611339645f47957cdcf4cbb7e067daf5e063ab Mon Sep 17 00:00:00 2001 From: Maxime Augier Date: Sat, 10 Aug 2024 17:40:14 +0200 Subject: [PATCH] Add mattermost module, decode observations --- src/main.rs | 27 +++++++++++++++++++-------- src/mattermost.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 src/mattermost.rs diff --git a/src/main.rs b/src/main.rs index 45ac927..6324b1f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,11 +4,12 @@ use anyhow::{Context as AnyhowContext, Result}; use clap::ValueEnum; use clap::{Parser, Subcommand}; use easee::api::{ApiError, Charger, ChargerState, ChargingSession, Context}; -use easee::stream; +use easee::{observation, stream}; use tracing::info; mod prom; +mod mattermost; #[derive(Debug, Clone, Copy, ValueEnum)] enum Command { @@ -72,17 +73,23 @@ fn login() -> Result<()> { let username = username.trim(); let password = password.trim(); - let ctx = easee::api::Context::from_login(&username, &password)?; - eprintln!("Login successful."); + let mut ctx = easee::api::Context::from_login(&username, &password)?; + info!("Login successful."); - std::fs::write(SAVED_TOKEN_PATH, ctx.save().as_bytes())?; + save_context(&mut ctx); return Ok(()); } fn load_context() -> Result { let saved = std::fs::read_to_string(SAVED_TOKEN_PATH) .context("Cannot read saved token (did you log in ?)")?; - Ok(easee::api::Context::from_saved(&saved)?) + let ctx = easee::api::Context::from_saved(&saved)? + .on_refresh(save_context); + Ok(ctx) +} + +fn save_context(ctx: &mut Context) { + std::fs::write(SAVED_TOKEN_PATH, ctx.save().as_bytes()).unwrap(); } fn load_chargers(ctx: &mut Context, names: &[String]) -> Result> { @@ -101,13 +108,13 @@ fn load_chargers(ctx: &mut Context, names: &[String]) -> Result> { fn stream(names: &[String]) -> Result<()> { let mut ctx = load_context()?; - let mut stream = stream::Stream::open(&mut ctx)?; + + let mut stream = observation::Stream::from_context(&mut ctx)?; let chargers = load_chargers(&mut ctx, names)?; for c in &chargers { stream.subscribe(&c.id)?; } - let mut stream = easee::signalr::Stream::from_ws(stream); loop { println!("{:?}", stream.recv()?); } @@ -141,6 +148,11 @@ fn main() -> Result<()> { .expect("Tracing subscriber failed"); } + // We need to do this before loading the context + if let Mode::Login = args.mode { + login()?; return Ok(()) + } + let mut ctx = load_context()?; match args.mode { @@ -171,7 +183,6 @@ fn main() -> Result<()> { } }; - std::fs::write(SAVED_TOKEN_PATH, ctx.save().as_bytes())?; Ok(()) } diff --git a/src/mattermost.rs b/src/mattermost.rs new file mode 100644 index 0000000..003fd6f --- /dev/null +++ b/src/mattermost.rs @@ -0,0 +1,43 @@ +use easee::api::ChargerOpMode; +use ureq::json; +use anyhow::Result; + +pub struct Context { + pub base: String, + pub token: String, +} + +pub struct Channel { + channel_id: String, +} + +impl Context { + + fn path(&self, rel: &str) -> String { + format!("{}/api/v4/{}", self.base, rel) + } + + pub fn set_custom_status(&self, text: &str, emoji: &str) -> Result<()> { + let path = &self.path("users/me/status/custom"); + ureq::put(path) + .send_json(json!( { "emoji": emoji, "text": text } ))?; + Ok(()) + } + + pub fn set_status(&self, mode: ChargerOpMode) -> Result<()> { + use ChargerOpMode::*; + let (text, emoji) = match mode { + Unknown => ("Unknown", "interrobang"), + Disconnected => ("Disconnected", "zzz"), + Paused => ("Paused", "double_vertical_bar"), + Charging => ("Charging", "zap"), + Finished => ("Finished", "white_check_mark"), + Error => ("Error", "no_entry_sign"), + Ready => ("Ready", "electric_plug"), + }; + self.set_custom_status(text, emoji) + } + + pub fn send_to_channel(&self, channel: &Channel, ) + +}