This commit is contained in:
Alex Janka 2022-09-05 15:05:36 +10:00
parent 130611aee6
commit b014c17d52
3 changed files with 175 additions and 59 deletions

7
Cargo.lock generated
View file

@ -389,6 +389,7 @@ dependencies = [
"clap 3.2.20", "clap 3.2.20",
"libmodbus-rs", "libmodbus-rs",
"serde", "serde",
"sum_type",
] ]
[[package]] [[package]]
@ -578,6 +579,12 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "sum_type"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da5b4a0c9f3c7c8e891e445a7c776627e208e8bba23ab680798066dd283e6a15"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.99" version = "1.0.99"

View file

@ -10,3 +10,4 @@ libmodbus-rs = "0.8.3"
clap = { version = "3.2.20", features = ["derive"] } clap = { version = "3.2.20", features = ["derive"] }
bincode = "1.3" bincode = "1.3"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
sum_type = "0.2"

View file

@ -3,6 +3,7 @@ use std::{path::Path, process::Command};
use clap::{AppSettings, Parser, Subcommand}; use clap::{AppSettings, Parser, Subcommand};
use libmodbus_rs::{Modbus, ModbusClient, ModbusRTU}; use libmodbus_rs::{Modbus, ModbusClient, ModbusRTU};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sum_type::sum_type;
mod offsets; mod offsets;
use crate::offsets::{OffsetsEeprom, OffsetsRam}; use crate::offsets::{OffsetsEeprom, OffsetsRam};
@ -87,33 +88,112 @@ struct MpptRam {
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
struct MpptEeprom { struct MpptEeprom {
EV_absorp: f32, EV_absorp: UnitValues,
EV_float: f32, EV_float: UnitValues,
Et_absorp: u16, Et_absorp: UnitValues,
Et_absorp_ext: u16, Et_absorp_ext: UnitValues,
EV_absorp_ext: f32, EV_absorp_ext: UnitValues,
EV_float_cancel: f32, EV_float_cancel: UnitValues,
Et_float_exit_cum: u16, Et_float_exit_cum: UnitValues,
EV_eq: f32, EV_eq: UnitValues,
Et_eqcalendar: u16, Et_eqcalendar: UnitValues,
Et_eq_above: u16, Et_eq_above: UnitValues,
Et_eq_reg: u16, Et_eq_reg: UnitValues,
Et_batt_service: u16, Et_batt_service: UnitValues,
EV_tempcomp: f32, EV_tempcomp: UnitValues,
EV_hvd: f32, EV_hvd: UnitValues,
EV_hvr: f32, EV_hvr: UnitValues,
Evb_ref_lim: f32, Evb_ref_lim: UnitValues,
ETb_max: u16, ETb_max: UnitValues,
ETb_min: u16, ETb_min: UnitValues,
EV_soc_g_gy: f32, EV_soc_g_gy: UnitValues,
EV_soc_gy_y: f32, EV_soc_gy_y: UnitValues,
EV_soc_y_yr: f32, EV_soc_y_yr: UnitValues,
EV_soc_yr_r: f32, EV_soc_yr_r: UnitValues,
Emodbus_id: u16, Emodbus_id: UnitValues,
Emeterbus_id: u16, Emeterbus_id: UnitValues,
EIb_lim: f32, EIb_lim: UnitValues,
EVa_ref_fixed_init: f32, EVa_ref_fixed_init: UnitValues,
EVa_ref_fixed_pct_init: f32, EVa_ref_fixed_pct_init: UnitValues,
}
sum_type! {
#[derive(Serialize, Deserialize, Debug)]
enum UnitValues {
Raw(u16),
ScaledCurrent(ScaledCurrent),
ScaledVoltage(ScaledVoltage),
ScaledVoltagePercentage(ScaledVoltagePercentage),
ScaledTempcomp(ScaledTempcomp),
}
}
#[derive(Serialize, Deserialize, Debug)]
struct ScaledTempcomp {
data: u16,
}
impl ScaledTempcomp {
pub fn get(&self, info: &Info) -> f32 {
self.data as f32 * info.v_scale * f32::powf(2., -16.)
}
pub fn new(voltage: f32, info: &Info) -> Self {
Self {
data: ((voltage / f32::powf(2., -16.)) / info.v_scale) as u16,
}
}
}
#[derive(Serialize, Deserialize, Debug)]
struct ScaledVoltage {
data: u16,
}
impl ScaledVoltage {
pub fn get(&self, info: &Info) -> f32 {
self.data as f32 * info.v_scale * f32::powf(2., -15.)
}
pub fn new(voltage: f32, info: &Info) -> Self {
Self {
data: ((voltage / f32::powf(2., -15.)) / info.v_scale) as u16,
}
}
}
#[derive(Serialize, Deserialize, Debug)]
struct ScaledVoltagePercentage {
data: u16,
}
impl ScaledVoltagePercentage {
pub fn get(&self, info: &Info) -> f32 {
self.data as f32 * 100. * f32::powf(2., -16.)
}
pub fn new(voltage: f32, info: &Info) -> Self {
Self {
data: ((voltage / f32::powf(2., -16.)) / 100.) as u16,
}
}
}
#[derive(Serialize, Deserialize, Debug)]
struct ScaledCurrent {
data: u16,
}
impl ScaledCurrent {
pub fn get(&self, info: &Info) -> f32 {
self.data as f32 * info.i_scale * f32::powf(2., -15.)
}
pub fn new(voltage: f32, info: &Info) -> Self {
Self {
data: ((voltage / f32::powf(2., -15.)) / info.i_scale) as u16,
}
}
} }
#[derive(Parser)] #[derive(Parser)]
@ -300,37 +380,65 @@ fn main() {
.expect("could not get eeprom data"); .expect("could not get eeprom data");
let eeprom_data = MpptEeprom { let eeprom_data = MpptEeprom {
EV_absorp: info.scale_voltage(&data_in[OffsetsEeprom::EV_absorp]), EV_absorp: UnitValues::ScaledVoltage(ScaledVoltage {
EV_float: info.scale_voltage(&data_in[OffsetsEeprom::EV_float]), data: data_in[OffsetsEeprom::EV_absorp],
Et_absorp: data_in[OffsetsEeprom::Et_absorp], }),
Et_absorp_ext: data_in[OffsetsEeprom::Et_absorp_ext], EV_float: UnitValues::ScaledVoltage(ScaledVoltage {
EV_absorp_ext: info.scale_voltage(&data_in[OffsetsEeprom::EV_absorp_ext]), data: data_in[OffsetsEeprom::EV_float],
EV_float_cancel: info.scale_voltage(&data_in[OffsetsEeprom::EV_float_cancel]), }),
Et_float_exit_cum: data_in[OffsetsEeprom::Et_float_exit_cum], Et_absorp: UnitValues::Raw(data_in[OffsetsEeprom::Et_absorp]),
EV_eq: info.scale_voltage(&data_in[OffsetsEeprom::EV_eq]), Et_absorp_ext: UnitValues::Raw(data_in[OffsetsEeprom::Et_absorp_ext]),
Et_eqcalendar: data_in[OffsetsEeprom::Et_eqcalendar], EV_absorp_ext: UnitValues::ScaledVoltage(ScaledVoltage {
Et_eq_above: data_in[OffsetsEeprom::Et_eq_above], data: data_in[OffsetsEeprom::EV_absorp_ext],
Et_eq_reg: data_in[OffsetsEeprom::Et_eq_reg], }),
Et_batt_service: data_in[OffsetsEeprom::Et_batt_service], EV_float_cancel: UnitValues::ScaledVoltage(ScaledVoltage {
EV_tempcomp: data_in[OffsetsEeprom::EV_tempcomp] as f32 data: data_in[OffsetsEeprom::EV_float_cancel],
* info.v_scale }),
* f32::powf(2., -16.), Et_float_exit_cum: UnitValues::Raw(data_in[OffsetsEeprom::Et_float_exit_cum]),
EV_hvd: info.scale_voltage(&data_in[OffsetsEeprom::EV_hvd]), EV_eq: UnitValues::ScaledVoltage(ScaledVoltage {
EV_hvr: info.scale_voltage(&data_in[OffsetsEeprom::EV_hvr]), data: data_in[OffsetsEeprom::EV_eq],
Evb_ref_lim: info.scale_voltage(&data_in[OffsetsEeprom::Evb_ref_lim]), }),
ETb_max: data_in[OffsetsEeprom::ETb_max], Et_eqcalendar: UnitValues::Raw(data_in[OffsetsEeprom::Et_eqcalendar]),
ETb_min: data_in[OffsetsEeprom::ETb_min], Et_eq_above: UnitValues::Raw(data_in[OffsetsEeprom::Et_eq_above]),
EV_soc_g_gy: info.scale_voltage(&data_in[OffsetsEeprom::EV_soc_g_gy]), Et_eq_reg: UnitValues::Raw(data_in[OffsetsEeprom::Et_eq_reg]),
EV_soc_gy_y: info.scale_voltage(&data_in[OffsetsEeprom::EV_soc_gy_y]), Et_batt_service: UnitValues::Raw(data_in[OffsetsEeprom::Et_batt_service]),
EV_soc_y_yr: info.scale_voltage(&data_in[OffsetsEeprom::EV_soc_y_yr]), EV_tempcomp: UnitValues::ScaledTempcomp(ScaledTempcomp {
EV_soc_yr_r: info.scale_voltage(&data_in[OffsetsEeprom::EV_soc_yr_r]), data: data_in[OffsetsEeprom::EV_tempcomp],
Emodbus_id: data_in[OffsetsEeprom::Emodbus_id], }),
Emeterbus_id: data_in[OffsetsEeprom::Emeterbus_id], EV_hvd: UnitValues::ScaledVoltage(ScaledVoltage {
EIb_lim: info.scale_current(&data_in[OffsetsEeprom::EIb_lim]), data: data_in[OffsetsEeprom::EV_hvd],
EVa_ref_fixed_init: info.scale_voltage(&data_in[OffsetsEeprom::EVa_ref_fixed_init]), }),
EVa_ref_fixed_pct_init: data_in[OffsetsEeprom::EVa_ref_fixed_pct_init] as f32 EV_hvr: UnitValues::ScaledVoltage(ScaledVoltage {
* 100. data: data_in[OffsetsEeprom::EV_hvr],
* f32::powf(2., -16.), }),
Evb_ref_lim: UnitValues::ScaledVoltage(ScaledVoltage {
data: data_in[OffsetsEeprom::Evb_ref_lim],
}),
ETb_max: UnitValues::Raw(data_in[OffsetsEeprom::ETb_max]),
ETb_min: UnitValues::Raw(data_in[OffsetsEeprom::ETb_min]),
EV_soc_g_gy: UnitValues::ScaledVoltage(ScaledVoltage {
data: data_in[OffsetsEeprom::EV_soc_g_gy],
}),
EV_soc_gy_y: UnitValues::ScaledVoltage(ScaledVoltage {
data: data_in[OffsetsEeprom::EV_soc_gy_y],
}),
EV_soc_y_yr: UnitValues::ScaledVoltage(ScaledVoltage {
data: data_in[OffsetsEeprom::EV_soc_y_yr],
}),
EV_soc_yr_r: UnitValues::ScaledVoltage(ScaledVoltage {
data: data_in[OffsetsEeprom::EV_soc_yr_r],
}),
Emodbus_id: UnitValues::Raw(data_in[OffsetsEeprom::Emodbus_id]),
Emeterbus_id: UnitValues::Raw(data_in[OffsetsEeprom::Emeterbus_id]),
EIb_lim: UnitValues::ScaledCurrent(ScaledCurrent {
data: data_in[OffsetsEeprom::EIb_lim],
}),
EVa_ref_fixed_init: UnitValues::ScaledVoltage(ScaledVoltage {
data: data_in[OffsetsEeprom::EVa_ref_fixed_init],
}),
EVa_ref_fixed_pct_init: UnitValues::ScaledVoltagePercentage(ScaledVoltagePercentage {
data: data_in[OffsetsEeprom::EVa_ref_fixed_pct_init],
}),
}; };
println!("eeprom: {:#?}", eeprom_data); println!("eeprom: {:#?}", eeprom_data);