program initial commit

This commit is contained in:
Aaska Black Wolf
2026-06-28 23:07:27 +02:00
parent 45378275b2
commit d11daea836
4 changed files with 140 additions and 0 deletions
+10
View File
@@ -36,9 +36,11 @@ fp-info-cache
# will have compiled files and executables # will have compiled files and executables
debug/ debug/
target/ target/
Cargo.lock
# These are backup files generated by rustfmt # These are backup files generated by rustfmt
**/*.rs.bk **/*.rs.bk
**/*.rs.save
# MSVC Windows builds of rustc generate these, which store debugging information # MSVC Windows builds of rustc generate these, which store debugging information
*.pdb *.pdb
@@ -49,3 +51,11 @@ target/
# and can be added to the global gitignore or merged into this file. For a more nuclear # and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder. # option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/ #.idea/
# Added by cargo
/target
# ---> Syncthing
.stfolder/
+10
View File
@@ -0,0 +1,10 @@
[package]
name = "isolated-switches"
version = "0.1.0"
edition = "2024"
[dependencies]
rppal = "0.22.1"
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.150"
sqlite = "0.37.0"
+6
View File
@@ -0,0 +1,6 @@
{
"database": "./VEDirect.db",
"device_name_voltage": "0xA10C-HQ2535PVZGE",
"voltage_off": 23.0,
"voltage_recover": 24.0
}
+114
View File
@@ -0,0 +1,114 @@
use rppal::gpio::{Gpio, OutputPin};
use serde::{Deserialize};
use serde_json;
use sqlite;
use std::error::Error;
use std::env;
use std::fs::File;
use std::path::Path;
use std::thread;
use std::time::Duration;
// Gpio uses BCM pin numbering. BCM GPIO 23 is tied to physical pin 16.
const GPIO_SWITCH: u8 = 24;
// set duration of pin switching test
const TEST_DURATION: u64 = 1000;
#[derive(Deserialize)]
#[derive(Debug)]
struct Config{
database: String,
device_name_voltage: String,
voltage_off: f32,
voltage_recover: f32,
}
#[derive(Deserialize)]
struct DbData{
V: String,
}
//fn main() {
fn main () {
// read and parse configuration file
let config_file = File::open("config.json")
.expect("file should open read only");
let config: Config = serde_json::from_reader(config_file)
.expect("file should be proper JSON");
// read and parse command line parameters
let args: Vec<String> = env::args().collect();
if args.len() >= 2 {
let action: &str = args[1].as_str();
match action {
"on" => pin_switch_on(),
"off" => pin_switch_off(),
"test" => pin_test(),
&_ => todo!("So far only the parameters 'on', 'off' and 'test' are supported.")
}
}
else { // no command line parameter set; check for voltages and switch the inverter accordingly
pin_status();
let voltage = get_current_voltage(&config);
if voltage < config.voltage_off && pin_status() > 0 {
println!("Siwtching off inverter due to low voltage!");
pin_switch_off();
}
else if voltage >= config.voltage_recover && pin_status() == 0 {
println!("Voltage recovered! Switching inverter back on.");
pin_switch_on();
}
else {
}
}
//end program with OK status
}
fn pin_status () -> u8 {
let mut pin_level: u8 = Gpio::new().unwrap().get(GPIO_SWITCH).unwrap().read() as u8;
return pin_level;
}
fn pin_switch_on () {
let mut pin: OutputPin = Gpio::new().unwrap().get(GPIO_SWITCH).unwrap().into_output();
pin.set_reset_on_drop(false);
pin.set_high();
}
fn pin_switch_off () {
let mut pin: OutputPin = Gpio::new().unwrap().get(GPIO_SWITCH).unwrap().into_output();
pin.set_reset_on_drop(false);
pin.set_low();
}
fn pin_test () {
pin_switch_on();
thread::sleep(Duration::from_millis(TEST_DURATION));
pin_switch_off();
}
fn get_current_voltage (config: &Config) -> f32 {
let mut voltage: f32 = 0.0;
if !Path::new(&config.database).exists() {
return voltage;
}
let db_connection = sqlite::open(&config.database).unwrap();
let query = format!("SELECT data FROM '{device}' ORDER BY date DESC, time DESC LIMIT 1;", device = &config.device_name_voltage);
let _ = db_connection.iterate(query, |pairs | {
let data = pairs.get(0).unwrap().1.unwrap();
let test_parse: DbData = serde_json::from_str(data).expect("no proper JSON data found on database");
let raw_value = match test_parse.V.parse::<i32>() {
Ok(v) => v,
Err(_) => return true
};
voltage = raw_value as f32 / 1000.0;
true
});
return voltage;
}