Add parsing of values

This commit is contained in:
2023-11-19 12:22:35 +01:00
parent 3ef70b0a7b
commit 56ee85b677
4 changed files with 207 additions and 39 deletions

29
Cargo.lock generated
View File

@@ -175,6 +175,7 @@ dependencies = [
"base64", "base64",
"log", "log",
"serialport", "serialport",
"strum",
"tokio", "tokio",
] ]
@@ -232,6 +233,12 @@ version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.3.3" version = "0.3.3"
@@ -688,6 +695,28 @@ dependencies = [
"windows-sys", "windows-sys",
] ]
[[package]]
name = "strum"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125"
dependencies = [
"strum_macros",
]
[[package]]
name = "strum_macros"
version = "0.25.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0"
dependencies = [
"heck",
"proc-macro2",
"quote",
"rustversion",
"syn",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.39" version = "2.0.39"

View File

@@ -11,4 +11,5 @@ axum = "0.6.20"
base64 = "0.21.5" base64 = "0.21.5"
log = "0.4.20" log = "0.4.20"
serialport = "4.2.2" serialport = "4.2.2"
strum = { version = "0.25.0", features = ["derive"] }
tokio = { version = "1.34.0", features = ["full"] } tokio = { version = "1.34.0", features = ["full"] }

43
src/index.html Normal file
View File

@@ -0,0 +1,43 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/purecss@3.0.0/build/pure-min.css" integrity="sha384-X38yfunGUhNzHpBaEBsWLO+A0HDYOQi8ufWDkZ0k9e0eXz/tH3II7uKZ9msv++Ls" crossorigin="anonymous">
<title>ELWA DC Heizstab</title>
</head>
<body>
<h2>Wasser</h2>
<p>Temperatur: {0} °C</p>
<p>Temperatur Min: {1} °C</p>
<p>Temperatur Max: {2} °C</p>
<p>Solltemperatur Solar: {3} °C</p>
<p>Solltemperatur Netz: {4} °C</p>
<h2>Solar aktuell</h2>
<p>Spannung: {5} V</p>
<p>Strom: {6} A</p>
<p>Leistung: {7} kW</p>
<h2>Historie</h2>
<p>Solarenergie Heute: {8} kWh</p>
<p>Solarenergie Gesamt: {9} kWh</p>
<p>Netzenergie Heute: {10} kWh</p>
<h2>Zustand</h2>
<p>Isolationsmessung: {11}</p>
<p>Gerätetemperatur: {12}</p>
<p>Status: {13}</p>
<p>DC Trenner: {14}</p>
<p>DC Relais: {15}</p>
<p>AC Relais: {16}</p>
<h2>Misc</h2>
<p>Betriebstag: {17}</p>
<p>Firmware: {18}</p>
<p>Seriennummer: {19}</p>
</body>
</html>

View File

@@ -1,60 +1,155 @@
use axum::{routing::get, Router}; use axum::{response::Html, routing::get, Router};
use strum::{EnumIter, IntoEnumIterator};
const STATUS_KEYS: &'static [&str] = &[ #[derive(EnumIter, Debug)]
"dummy0", enum StatusTag {
"firmware", Dummy0,
"Betriebstag", Firmware,
"Status", Betriebstag,
"DcTrenner", Status,
"DcRelais", DcTrenner,
"AcRelais", DcRelais,
"Wassertemp", AcRelais,
"WassertempMin", Wassertemp,
"WassertempMax", WassertempMin,
"SolltempSolar", WassertempMax,
"SolltempNetz", SolltempSolar,
"GeraeteTemp", SolltempNetz,
"IsoMessung", GeraeteTemp,
"Solarspannung", IsoMessung,
"dummy5", Solarspannung,
"Solarstrom", Dummy5,
"Solarleistung", Solarstrom,
"SolarenergieHeute", Solarleistung,
"SolarenergieGesammt", SolarenergieHeute,
"Netzernergie", SolarenergieGesamt,
"dummy6", NetzenergieHeute,
"dummy7", Dummy6,
"dummy8", Dummy7,
"dummy9", Dummy8,
"dummy10", Dummy9,
"dummy11", Dummy10,
"dummy12", Dummy11,
"Seriennummer", Dummy12,
"dummy13", Seriennummer,
]; Dummy13,
}
#[derive(Default, Debug)]
struct Status<'a> {
// Wasser
wassertemp: f32,
wassertemp_min: f32,
wassertemp_max: f32,
solltemp_solar: f32,
solltemp_netz: f32,
// Solar aktuell
solarspannung: f32,
solarstrom: f32,
solarleistung: f32,
// Historie
solarenergie_heute: f32,
solarenergie_gesamt: f32,
netzenergie_heute: f32,
// Zustand
iso_messung: u32,
geraetetemp: u32,
status: u32,
dc_trenner: bool,
dc_relais: bool,
ac_relais: bool,
// Misc
betriebstag: u32,
firmware: &'a str,
seriennummer: &'a str,
}
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
let app = Router::new().route("/", get(handler)); let app = Router::new().route("/", get(handler));
axum::Server::bind(&"0.0.0.0:3001".parse().unwrap()) axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service()) .serve(app.into_make_service())
.await .await
.unwrap(); .unwrap();
} }
async fn handler() -> String { async fn handler() -> Html<String> {
log::info!("Fetch new data"); log::info!("Fetch new data");
let data = read_device(); let data = read_device();
let data_string = std::str::from_utf8(&data).unwrap(); let data_string = std::str::from_utf8(&data).unwrap();
let mut current_status = String::new(); let mut status = Status::default();
for (value, &key) in data_string.split('\t').zip(STATUS_KEYS.iter()) { for (value, tag) in data_string.split('\t').zip(StatusTag::iter()) {
current_status.push_str(&format!("{key}: {value}\n")); match tag {
StatusTag::Firmware => status.firmware = value,
StatusTag::Betriebstag => status.betriebstag = str::parse(value).unwrap(),
StatusTag::Status => status.status = str::parse(value).unwrap(),
StatusTag::DcTrenner => status.dc_trenner = str::parse::<u8>(value).unwrap() != 0,
StatusTag::DcRelais => status.dc_relais = str::parse::<u8>(value).unwrap() != 0,
StatusTag::AcRelais => status.ac_relais = str::parse::<u8>(value).unwrap() != 0,
StatusTag::Wassertemp => status.wassertemp = str::parse::<f32>(value).unwrap() / 10.0,
StatusTag::WassertempMin => {
status.wassertemp_min = str::parse::<f32>(value).unwrap() / 10.0
}
StatusTag::WassertempMax => {
status.wassertemp_max = str::parse::<f32>(value).unwrap() / 10.0
}
StatusTag::SolltempSolar => {
status.solltemp_solar = str::parse::<f32>(value).unwrap() / 10.0
}
StatusTag::SolltempNetz => {
status.solltemp_netz = str::parse::<f32>(value).unwrap() / 10.0
}
StatusTag::GeraeteTemp => status.geraetetemp = str::parse(value).unwrap(),
StatusTag::IsoMessung => status.iso_messung = str::parse(value).unwrap(),
StatusTag::Solarspannung => status.solarspannung = str::parse::<f32>(value).unwrap(),
StatusTag::Solarstrom => status.solarstrom = str::parse::<f32>(value).unwrap(),
StatusTag::Solarleistung => {
status.solarleistung = str::parse::<f32>(value).unwrap() / 1000.0
}
StatusTag::SolarenergieHeute => {
status.solarenergie_heute = str::parse::<f32>(value).unwrap() / 1000.0
}
StatusTag::SolarenergieGesamt => {
status.solarenergie_gesamt = str::parse::<f32>(value).unwrap() / 1000.0
}
StatusTag::NetzenergieHeute => {
status.netzenergie_heute = str::parse::<f32>(value).unwrap() / 1000.0
}
StatusTag::Seriennummer => status.seriennummer = value,
_ => (),
}
} }
current_status Html(format!(
include_str!("index.html"),
status.wassertemp,
status.wassertemp_min,
status.wassertemp_max,
status.solltemp_solar,
status.solltemp_netz,
status.solarspannung,
status.solarstrom,
status.solarleistung,
status.solarenergie_heute,
status.solarenergie_gesamt,
status.netzenergie_heute,
status.iso_messung,
status.geraetetemp,
status.status,
status.dc_trenner,
status.dc_relais,
status.ac_relais,
status.betriebstag,
status.firmware,
status.seriennummer,
))
} }
#[cfg(not(feature = "dummy"))] #[cfg(not(feature = "dummy"))]