From 20a2a304e344e2481ee76a2961c3a0db27fb5384 Mon Sep 17 00:00:00 2001 From: SCHAUAUS GmbH Date: Thu, 3 Sep 2026 09:58:10 +0200 Subject: [PATCH] add time based control on top of voltage --- Cargo.toml | 1 + config.json | 8 +++-- src/main.rs | 93 +++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 83 insertions(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3fc1e35..0bbd647 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" edition = "2024" [dependencies] +chrono = "0.4.45" rppal = "0.22.1" serde = { version = "1.0.228", features = ["derive"] } serde_json = "1.0.150" diff --git a/config.json b/config.json index 7a36e61..89e5d5f 100644 --- a/config.json +++ b/config.json @@ -1,7 +1,11 @@ { "database": "./VEDirect.db", "device_name_voltage": "0xA10C-HQ2535PVZGE", + "mode": "auto", "test_duration_seconds": 1, + "time_off": "23:30", + "time_on": "7:30", + "time_use": true, "voltage_off": 23.0, - "voltage_recover": 24.0 -} \ No newline at end of file + "voltage_recover": 25.0 +} diff --git a/src/main.rs b/src/main.rs index f3ed327..7f01404 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ use std::fs::File; use std::path::Path; use std::thread; use std::time::Duration; +use chrono; // Gpio uses BCM pin numbering. BCM GPIO 23 is tied to physical pin 16. const GPIO_SWITCH: u8 = 24; @@ -17,7 +18,11 @@ const GPIO_SWITCH: u8 = 24; struct Config{ database: String, device_name_voltage: String, + mode: String, test_duration_seconds: u64, + time_on: String, + time_off: String, + time_use: bool, voltage_off: f32, voltage_recover: f32, } @@ -45,8 +50,14 @@ fn main () { pin_switch_off(); return; }, - "status" => { println!("Inverter status: {}" , if pin_status() == 0 { "off" } else { "on" }); std::process::exit(0); }, - "test" => pin_test(config_file_path), + "status" => { + println!("Inverter status: {}" , if pin_status() == 0 { "off" } else { "on" }); + return; + }, + "test" => { + pin_test(config_file_path); + return; + }, "config" => { if args.len() > n + 1 { config_file_path = args[n + 1].as_str(); } }, @@ -54,23 +65,71 @@ fn main () { } } + // read and parse configuration file let config: Config = read_config(&config_file_path); - let pin_status_cur = pin_status(); - let voltage = get_current_voltage(&config); - if voltage < config.voltage_off && pin_status_cur > 0 { - println!("Low voltage!"); - pin_switch_off(); - } - else if voltage >= config.voltage_recover && pin_status_cur == 0 { - println!("Voltage recovered!"); - pin_switch_on(); - } - else { - // no change in status needed - let pin_status_text = if pin_status_cur == 0 { "off" } else { "on" }; - println!("No change in inverter status. Current status: {}", pin_status_text); - } + match config.mode.as_str() { + "auto" => { + println!("Running in automatic mode"); + let pin_status_cur = pin_status(); + let voltage = get_current_voltage(&config); + + // turn inverter off based on time of day settings + if config.time_use { + let time_off = chrono::NaiveTime::parse_from_str(&config.time_off, "%H:%M").unwrap(); + let time_on = chrono::NaiveTime::parse_from_str(&config.time_on, "%H:%M").unwrap(); + let time_now = chrono::Local::now().time(); + + if time_off > time_on { // switch off at the same day + if time_now < time_on || time_now > time_off { + if pin_status() > 0 { + println!("Off-time!"); + pin_switch_off(); + } + return; + } + } + else if time_off < time_on { // switch off the next day + if time_now < time_on && time_now > time_off { + if pin_status() > 0 { + println!("Off-time!"); + pin_switch_off(); + } + return; + } + } + } + + if voltage < config.voltage_off && pin_status_cur > 0 { + println!("Low voltage!"); + pin_switch_off(); + } + else if voltage >= config.voltage_recover && pin_status_cur == 0 { + println!("Voltage recovered!"); + pin_switch_on(); + } + else { + // no change in status needed + let pin_status_text = if pin_status_cur == 0 { "off" } else { "on" }; + println!("No change in inverter status. Current status: {}", pin_status_text); + } + }, + "on" => { + println!("Running in manual mode ON"); + if pin_status() == 0 { + pin_switch_on(); + } + return; + }, + "off" => { + println!("Running in manual mode OFF"); + if pin_status() > 0 { + pin_switch_off(); + } + return; + }, + _ => () + } //end program with OK status }