diff --git a/Cargo.lock b/Cargo.lock index 266126f..da474f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2567,7 +2567,7 @@ dependencies = [ [[package]] name = "tesla-charge-controller" -version = "1.0.10" +version = "1.0.11" dependencies = [ "async-channel", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 9e1b207..2a8000c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tesla-charge-controller" -version = "1.0.10" +version = "1.0.11" edition = "2021" license = "MITNFA" description = "Controls Tesla charge rate based on solar charge data" diff --git a/src/charge_controllers/pl.rs b/src/charge_controllers/pl.rs index 4c7b485..4dc159a 100644 --- a/src/charge_controllers/pl.rs +++ b/src/charge_controllers/pl.rs @@ -4,6 +4,7 @@ use std::{ time::Duration, }; +use chrono::Timelike; use metrics::{gauge, Gauge, Label}; use serde::{Deserialize, Serialize}; use serialport::SerialPort; @@ -140,6 +141,7 @@ impl RegulatorGauges { pub enum PliRequest { ReadRam(u8), ReadEeprom(u8), + SyncTime, } impl Pli { @@ -210,6 +212,22 @@ impl Pli { log::warn!("Read EEPROM at {address}: data {data}"); } } + PliRequest::SyncTime => { + let now = chrono::Local::now(); + let timestamp = (((now.hour() * 10) + (now.minute() / 6)) & 0xFF) as u8; + let min = (now.minute() % 6) as u8; + log::warn!("Setting time: {now} corresponds to {timestamp} + minutes {min}"); + if self + .write_ram(PlRamAddress::Hour, timestamp) + .some_or_print_with("Setting time") + .is_none() + { + return; + } + let _ = self + .write_ram(PlRamAddress::Min, min) + .some_or_print_with("Setting time (minutes)"); + } } } @@ -262,6 +280,14 @@ impl Pli { } } + fn write_ram(&mut self, address: T, data: u8) -> Result<(), PliError> + where + T: Into, + { + self.send_command(command(152, address.into(), data))?; + Ok(()) + } + fn read_eeprom(&mut self, address: T) -> Result where T: Into, @@ -278,6 +304,8 @@ impl Pli { enum PlRamAddress { Dutycyc, + Min, + Hour, Batv, Battemp, Rstate, @@ -290,6 +318,8 @@ impl From for u8 { fn from(value: PlRamAddress) -> Self { match value { PlRamAddress::Dutycyc => 39, + PlRamAddress::Min => 47, + PlRamAddress::Hour => 48, PlRamAddress::Batv => 50, PlRamAddress::Battemp => 52, PlRamAddress::Rstate => 101, diff --git a/src/server/mod.rs b/src/server/mod.rs index 23b894e..797bf84 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -62,6 +62,7 @@ fn rocket(state: ServerState) -> rocket::Rocket { disable_control, enable_control, metrics, + sync_time, read_ram, read_eeprom ], @@ -137,6 +138,12 @@ fn metrics() -> Result { ) } +#[get("/sync-time")] +async fn sync_time(state: &State) -> String { + let _ = state.pli_requests.send(PliRequest::SyncTime).await; + String::from("syncing time...") +} + #[get("/read-ram/
")] async fn read_ram(address: u8, state: &State) -> String { let _ = state.pli_requests.send(PliRequest::ReadRam(address)).await;