diff --git a/Cargo.lock b/Cargo.lock index e954e7a..249b11e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,6 +67,15 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bindgen" version = "0.31.3" @@ -376,8 +385,10 @@ dependencies = [ name = "modbus-test" version = "0.1.0" dependencies = [ + "bincode", "clap 3.2.20", "libmodbus-rs", + "serde", ] [[package]] @@ -535,6 +546,26 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +[[package]] +name = "serde" +version = "1.0.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" +dependencies = [ + "proc-macro2", + "quote 1.0.21", + "syn", +] + [[package]] name = "strsim" version = "0.8.0" diff --git a/Cargo.toml b/Cargo.toml index 71db642..b3d0f66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,6 @@ edition = "2021" [dependencies] libmodbus-rs = "0.8.3" -clap = { version = "3.1", features = ["derive"] } \ No newline at end of file +clap = { version = "3.1", features = ["derive"] } +bincode = "1.3" +serde = { version = "1.0", features = ["derive"] } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 0d2af92..722057f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,81 +1,117 @@ use clap::Parser; use libmodbus_rs::{Modbus, ModbusClient, ModbusRTU}; +use serde::{Deserialize, Serialize}; + +mod offsets; +use crate::offsets::{OffsetsEeprom, OffsetsRam}; const DEVICE_ID: u8 = 0x01; +const RAM_DATA_SIZE: u16 = 0x005B; +const EEPROM_BEGIN: u16 = 0xE000; +const EEPROM_DATA_SIZE: u16 = 0xE021 - EEPROM_BEGIN; +// const EEPROM_DATA_SIZE: u16 = 0xE0CD - EEPROM_BEGIN; -struct Offsets {} - -impl Offsets { +#[derive(Serialize, Deserialize, Debug)] +struct MpptRam { // scaling values - const V_PU_HI: u16 = 0x0000; - const V_PU_LO: u16 = 0x0001; - const I_PU_HI: u16 = 0x0002; - const I_PU_LO: u16 = 0x0003; - const VER_SW: u16 = 0x0004; + V_PU: f32, + I_PU: f32, + VER_SW: u16, // filtered ADC - const ADC_VB_F_MED: u16 = 0x0018; - const ADC_VBTERM_F: u16 = 0x0019; - const ADC_VBS_F: u16 = 0x001A; - const ADC_VA_F: u16 = 0x001B; - const ADC_IB_F_SHADOW: u16 = 0x001C; - const ADC_IA_F_SHADOW: u16 = 0x001D; - const ADC_P12_F: u16 = 0x001E; - const ADC_P3_F: u16 = 0x001F; - const ADC_PMETER_F: u16 = 0x0020; - const ADC_P18_F: u16 = 0x0021; - const ADC_V_REF: u16 = 0x0022; + ADC_VB_F_MED: f32, + ADC_VBTERM_F: f32, + ADC_VBS_F: f32, + ADC_VA_F: f32, + ADC_IB_F_SHADOW: f32, + ADC_IA_F_SHADOW: f32, + ADC_P12_F: f32, + ADC_P3_F: f32, + ADC_PMETER_F: f32, + ADC_P18_F: f32, + ADC_V_REF: f32, // temperatures - const T_HS: u16 = 0x0023; - const T_RTS: u16 = 0x0024; - const T_BATT: u16 = 0x0025; + T_HS: u16, + T_RTS: u16, + T_BATT: u16, // status - const ADC_VB_F_1M: u16 = 0x0026; - const ADC_IB_F_1M: u16 = 0x0027; - const VB_MIN: u16 = 0x0028; - const VB_MAX: u16 = 0x0029; - const HOURMETER_HI: u16 = 0x002A; - const HOURMETER_LO: u16 = 0x002B; - const FAULT_ALL: u16 = 0x002C; - const ALARM_HI: u16 = 0x002E; - const ALARM_LO: u16 = 0x002F; - const DIP_ALL: u16 = 0x0030; - const LED_STATE: u16 = 0x0031; + ADC_VB_F_1M: f32, + ADC_IB_F_1M: f32, + VB_MIN: f32, + VB_MAX: f32, + HOURMETER_HI: u16, + HOURMETER_LO: u16, + FAULT_ALL: u16, + ALARM_HI: u16, + ALARM_LO: u16, + DIP_ALL: u16, + LED_STATE: u16, // charger - const CHARGE_STATE: u16 = 0x0032; - const VB_REF: u16 = 0x0033; - const AHC_R_HI: u16 = 0x0034; - const AHC_R_LO: u16 = 0x0035; - const AHC_T_HI: u16 = 0x0036; - const AHC_T_LO: u16 = 0x0037; - const KWHC_R: u16 = 0x0038; - const KWHC_T: u16 = 0x0039; - // MPPT - const POWER_OUT_SHADOW: u16 = 0x003A; - const POWER_IN_SHADOW: u16 = 0x003B; - const SWEEP_PIN_MAX: u16 = 0x003C; - const SWEEP_VMP: u16 = 0x003D; - const SWEEP_VOC: u16 = 0x003E; + CHARGE_STATE: u16, + VB_REF: f32, + AHC_R_HI: u16, + AHC_R_LO: u16, + AHC_T_HI: u16, + AHC_T_LO: u16, + KWHC_R: u16, + KWHC_T: u16, + // MpptRam + POWER_OUT_SHADOW: f32, + POWER_IN_SHADOW: f32, + SWEEP_PIN_MAX: f32, + SWEEP_VMP: f32, + SWEEP_VOC: f32, // logger - today's values - const VB_MIN_DAILY: u16 = 0x0040; - const VB_MAX_DAILY: u16 = 0x0041; - const VA_MAX_DAILY: u16 = 0x0042; - const AHC_DAILY: u16 = 0x0043; - const WHC_DAILY: u16 = 0x0044; - const FLAGS_DAILY: u16 = 0x0045; - const POUT_MAX_DAILY: u16 = 0x0046; - const TB_MIN_DAILY: u16 = 0x0047; - const TB_MAX_DAILY: u16 = 0x0048; - const FAULT_DAILY: u16 = 0x0049; - const ALARM_DAILY_HI: u16 = 0x004B; - const ALARM_DAILY_LO: u16 = 0x004C; - const TIME_AB_DAILY: u16 = 0x004D; - const TIME_EQ_DAILY: u16 = 0x004E; - const FIME_FL_DAILY: u16 = 0x004F; + VB_MIN_DAILY: f32, + VB_MAX_DAILY: f32, + VA_MAX_DAILY: f32, + AHC_DAILY: f32, + WHC_DAILY: u16, + FLAGS_DAILY: u16, + POUT_MAX_DAILY: f32, + TB_MIN_DAILY: u16, + TB_MAX_DAILY: u16, + FAULT_DAILY: u16, + ALARM_DAILY_HI: u16, + ALARM_DAILY_LO: u16, + TIME_AB_DAILY: u16, + TIME_EQ_DAILY: u16, + TIME_FL_DAILY: u16, // manual control - const IB_REF_SLAVE: u16 = 0x0058; - const VB_REF_SLAVE: u16 = 0x0059; - const VA_REF_FIXED: u16 = 0x005A; - const VA_REF_FIXED_PCT: u16 = 0x005B; + IB_REF_SLAVE: f32, + VB_REF_SLAVE: f32, + VA_REF_FIXED: f32, + VA_REF_FIXED_PCT: f32, +} + +#[derive(Serialize, Deserialize, Debug)] +struct MpptEeprom { + EV_absorp: f32, + EV_float: f32, + Et_absorp: u16, + Et_absorp_ext: u16, + EV_absorp_ext: f32, + EV_float_cancel: f32, + Et_float_exit_cum: u16, + EV_eq: f32, + Et_eqcalendar: u16, + Et_eq_above: u16, + Et_eq_reg: u16, + Et_batt_service: u16, + EV_tempcomp: f32, + EV_hvd: f32, + EV_hvr: f32, + Evb_ref_lim: f32, + ETb_max: u16, + ETb_min: u16, + EV_soc_g_gy: f32, + EV_soc_gy_g: f32, + EV_soc_y_yr: f32, + EV_soc_yr_r: f32, + Emodbus_id: u16, + Emeterbus_id: u16, + EIb_lim: f32, + EVa_ref_fixed_init: f32, + EVa_ref_fixed_pct_init: f32, } #[derive(Parser, Debug)] @@ -85,6 +121,34 @@ struct Args { serial_port: String, } +struct Info { + v_scale: f32, + i_scale: f32, +} +impl Info { + pub fn from(data: &[u16]) -> Self { + Self { + v_scale: data[0] as f32 + (data[1] as f32 / f32::powf(2., 16.)), + i_scale: data[2] as f32 + (data[3] as f32 / f32::powf(2., 16.)), + } + } + pub fn scale_power(&self, p: &u16) -> f32 { + *p as f32 * self.v_scale * self.i_scale * f32::powf(2., -17.) + } + pub fn scale_voltage(&self, v: &u16) -> f32 { + *v as f32 * self.v_scale * f32::powf(2., -15.) + } + pub fn scale_current(&self, i: &u16) -> f32 { + *i as f32 * self.i_scale * f32::powf(2., -15.) + } + pub fn scale_voltage_f(&self, v: f32) -> f32 { + v * self.v_scale * f32::powf(2., -15.) + } + pub fn scale_current_f(&self, i: f32) -> f32 { + i * self.i_scale * f32::powf(2., -15.) + } +} + fn main() { let args = Args::parse(); let baud = 9600; @@ -100,53 +164,119 @@ fn main() { modbus .connect() .expect("Could not connect to client device"); - let mut scaling_data: [u16; 4] = [0; 4]; + let mut data_in: [u16; RAM_DATA_SIZE as usize + 1] = [0; RAM_DATA_SIZE as usize + 1]; modbus - .read_registers(0x0000, 4, &mut scaling_data) + .read_registers(0x0000, RAM_DATA_SIZE + 1, &mut data_in) .expect("couldnt"); - let v_scale = scaling_data[0] as f32 + (scaling_data[1] as f32 / f32::powf(2., 16.)); - let i_scale = scaling_data[2] as f32 + (scaling_data[3] as f32 / f32::powf(2., 16.)); - let mut data: [u16; 1] = [0; 1]; - modbus - .read_registers(Offsets::T_BATT, 1, &mut data) - .expect("couldnt"); - // println!("d: {}", (data[0] as f32 * v_scale) / 32768.); - println!("battery temp: {}", data[0]); - modbus - .read_registers(Offsets::CHARGE_STATE, 1, &mut data) - .expect("couldnt"); - println!("charge state: {}", data[0]); - modbus - .read_registers(Offsets::ADC_IB_F_1M, 1, &mut data) - .expect("couldnt"); - println!( - "current (1 min avg): {}", - data[0] as f32 * i_scale * f32::powf(2., -15.) - ); - modbus - .read_registers(Offsets::ADC_VB_F_1M, 1, &mut data) - .expect("couldnt"); - println!( - "voltage (1 min avg): {}", - data[0] as f32 * v_scale * f32::powf(2., -15.) - ); - // let mut data: [u16; 5] = [0; 5]; - // modbus - // .read_registers(0x0000, 5, &mut data) - // .expect("Could not read registers"); - // println!("voltage scaling (whole term): {}", get_floating(data[0])); - // println!( - // "voltage scaling (fractional term): {}", - // get_floating(data[1]) - // ); - // println!("current scaling (whole term): {}", get_floating(data[2])); - // println!( - // "current scaling (fractional term): {}", - // get_floating(data[3]) - // ); - // println!("software version: {}", data[4]); -} + let info = Info::from(&data_in); + let ram_data = MpptRam { + V_PU: info.scale_voltage_f( + data_in[OffsetsRam::V_PU_HI] as f32 + + (data_in[OffsetsRam::V_PU_LO] as f32 / f32::powf(2., 16.)), + ), + I_PU: info.scale_current_f( + data_in[OffsetsRam::I_PU_HI] as f32 + + (data_in[OffsetsRam::I_PU_LO] as f32 / f32::powf(2., 16.)), + ), + VER_SW: data_in[OffsetsRam::VER_SW], + ADC_VB_F_MED: info.scale_voltage(&data_in[OffsetsRam::ADC_VB_F_MED]), + ADC_VBTERM_F: info.scale_voltage(&data_in[OffsetsRam::ADC_VBTERM_F]), + ADC_VBS_F: info.scale_voltage(&data_in[OffsetsRam::ADC_VBS_F]), + ADC_VA_F: info.scale_voltage(&data_in[OffsetsRam::ADC_VA_F]), + ADC_IB_F_SHADOW: info.scale_current(&data_in[OffsetsRam::ADC_IB_F_SHADOW]), + ADC_IA_F_SHADOW: info.scale_current(&data_in[OffsetsRam::ADC_IA_F_SHADOW]), + ADC_P12_F: data_in[OffsetsRam::ADC_P12_F] as f32 * 18.618 * f32::powf(2., -15.), + ADC_P3_F: data_in[OffsetsRam::ADC_P3_F] as f32 * 6.6 * f32::powf(2., -15.), + ADC_PMETER_F: data_in[OffsetsRam::ADC_PMETER_F] as f32 * 18.618 * f32::powf(2., -15.), + ADC_P18_F: data_in[OffsetsRam::ADC_P18_F] as f32 * 3. * f32::powf(2., -15.), + ADC_V_REF: data_in[OffsetsRam::ADC_V_REF] as f32 * 3. * f32::powf(2., -15.), + T_HS: data_in[OffsetsRam::T_HS], + T_RTS: data_in[OffsetsRam::T_RTS], + T_BATT: data_in[OffsetsRam::T_BATT], + ADC_VB_F_1M: info.scale_voltage(&data_in[OffsetsRam::ADC_VB_F_1M]), + ADC_IB_F_1M: info.scale_current(&data_in[OffsetsRam::ADC_IB_F_1M]), + VB_MIN: info.scale_voltage(&data_in[OffsetsRam::VB_MIN]), + VB_MAX: info.scale_voltage(&data_in[OffsetsRam::VB_MAX]), + HOURMETER_HI: data_in[OffsetsRam::HOURMETER_HI], + HOURMETER_LO: data_in[OffsetsRam::HOURMETER_LO], + FAULT_ALL: data_in[OffsetsRam::FAULT_ALL], + ALARM_HI: data_in[OffsetsRam::ALARM_HI], + ALARM_LO: data_in[OffsetsRam::ALARM_LO], + DIP_ALL: data_in[OffsetsRam::DIP_ALL], + LED_STATE: data_in[OffsetsRam::LED_STATE], + CHARGE_STATE: data_in[OffsetsRam::CHARGE_STATE], + VB_REF: info.scale_voltage(&data_in[OffsetsRam::VB_REF]), + AHC_R_HI: data_in[OffsetsRam::AHC_R_HI], + AHC_R_LO: data_in[OffsetsRam::AHC_R_LO], + AHC_T_HI: data_in[OffsetsRam::AHC_T_HI], + AHC_T_LO: data_in[OffsetsRam::AHC_T_LO], + KWHC_R: data_in[OffsetsRam::KWHC_R], + KWHC_T: data_in[OffsetsRam::KWHC_T], + POWER_OUT_SHADOW: info.scale_power(&data_in[OffsetsRam::AHC_R_HI]), + POWER_IN_SHADOW: info.scale_power(&data_in[OffsetsRam::POWER_IN_SHADOW]), + SWEEP_PIN_MAX: info.scale_power(&data_in[OffsetsRam::SWEEP_PIN_MAX]), + SWEEP_VMP: info.scale_voltage(&data_in[OffsetsRam::SWEEP_VMP]), + SWEEP_VOC: info.scale_voltage(&data_in[OffsetsRam::SWEEP_VOC]), + VB_MIN_DAILY: info.scale_voltage(&data_in[OffsetsRam::VB_MIN_DAILY]), + VB_MAX_DAILY: info.scale_voltage(&data_in[OffsetsRam::VB_MAX_DAILY]), + VA_MAX_DAILY: info.scale_voltage(&data_in[OffsetsRam::VA_MAX_DAILY]), + AHC_DAILY: data_in[OffsetsRam::AHC_DAILY] as f32 * 0.1, + WHC_DAILY: data_in[OffsetsRam::WHC_DAILY], + FLAGS_DAILY: data_in[OffsetsRam::FLAGS_DAILY], + POUT_MAX_DAILY: info.scale_power(&data_in[OffsetsRam::POUT_MAX_DAILY]), + TB_MIN_DAILY: data_in[OffsetsRam::TB_MIN_DAILY], + TB_MAX_DAILY: data_in[OffsetsRam::TB_MAX_DAILY], + FAULT_DAILY: data_in[OffsetsRam::FAULT_DAILY], + ALARM_DAILY_HI: data_in[OffsetsRam::ALARM_DAILY_HI], + ALARM_DAILY_LO: data_in[OffsetsRam::ALARM_DAILY_LO], + TIME_AB_DAILY: data_in[OffsetsRam::TIME_AB_DAILY], + TIME_EQ_DAILY: data_in[OffsetsRam::TIME_EQ_DAILY], + TIME_FL_DAILY: data_in[OffsetsRam::TIME_FL_DAILY], + IB_REF_SLAVE: data_in[OffsetsRam::IB_REF_SLAVE] as f32 * 80. * f32::powf(2., -15.), + VB_REF_SLAVE: info.scale_voltage(&data_in[OffsetsRam::VB_REF_SLAVE]), + VA_REF_FIXED: info.scale_voltage(&data_in[OffsetsRam::VA_REF_FIXED]), + VA_REF_FIXED_PCT: data_in[OffsetsRam::VA_REF_FIXED_PCT] as f32 * 100. * f32::powf(2., -16.), + }; + println!("ram: {:#?}", ram_data); -fn get_floating(num: u16) -> f32 { - num as f32 * 16.92 / 65536.0 + let mut data_in: [u16; EEPROM_DATA_SIZE as usize + 1] = [0; EEPROM_DATA_SIZE as usize + 1]; + modbus + .read_registers(EEPROM_BEGIN, EEPROM_DATA_SIZE + 1, &mut data_in) + .expect("could not get eeprom data"); + + let eeprom_data = MpptEeprom { + EV_absorp: info.scale_voltage(&data_in[OffsetsEeprom::EV_absorp]), + EV_float: info.scale_voltage(&data_in[OffsetsEeprom::EV_float]), + Et_absorp: data_in[OffsetsEeprom::Et_absorp], + Et_absorp_ext: data_in[OffsetsEeprom::Et_absorp_ext], + EV_absorp_ext: info.scale_voltage(&data_in[OffsetsEeprom::EV_absorp_ext]), + EV_float_cancel: info.scale_voltage(&data_in[OffsetsEeprom::EV_float_cancel]), + Et_float_exit_cum: data_in[OffsetsEeprom::Et_float_exit_cum], + EV_eq: info.scale_voltage(&data_in[OffsetsEeprom::EV_eq]), + Et_eqcalendar: data_in[OffsetsEeprom::Et_eqcalendar], + Et_eq_above: data_in[OffsetsEeprom::Et_eq_above], + Et_eq_reg: data_in[OffsetsEeprom::Et_eq_reg], + Et_batt_service: data_in[OffsetsEeprom::Et_batt_service], + EV_tempcomp: data_in[OffsetsEeprom::EV_tempcomp] as f32 + * info.v_scale + * f32::powf(2., -16.), + EV_hvd: info.scale_voltage(&data_in[OffsetsEeprom::EV_hvd]), + EV_hvr: info.scale_voltage(&data_in[OffsetsEeprom::EV_hvr]), + Evb_ref_lim: info.scale_voltage(&data_in[OffsetsEeprom::Evb_ref_lim]), + ETb_max: data_in[OffsetsEeprom::ETb_max], + ETb_min: data_in[OffsetsEeprom::ETb_min], + EV_soc_g_gy: info.scale_voltage(&data_in[OffsetsEeprom::EV_soc_g_gy]), + EV_soc_gy_g: info.scale_voltage(&data_in[OffsetsEeprom::EV_soc_gy_g]), + EV_soc_y_yr: info.scale_voltage(&data_in[OffsetsEeprom::EV_soc_y_yr]), + EV_soc_yr_r: info.scale_voltage(&data_in[OffsetsEeprom::EV_soc_yr_r]), + Emodbus_id: data_in[OffsetsEeprom::Emodbus_id], + Emeterbus_id: data_in[OffsetsEeprom::Emeterbus_id], + EIb_lim: info.scale_current(&data_in[OffsetsEeprom::EIb_lim]), + 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 + * 100. + * f32::powf(2., -16.), + }; + + println!("eeprom: {:#?}", eeprom_data); } diff --git a/src/offsets.rs b/src/offsets.rs new file mode 100644 index 0000000..1af8201 --- /dev/null +++ b/src/offsets.rs @@ -0,0 +1,106 @@ +pub struct OffsetsRam {} + +impl OffsetsRam { + // scaling values + pub const V_PU_HI: usize = 0x0000; + pub const V_PU_LO: usize = 0x0001; + pub const I_PU_HI: usize = 0x0002; + pub const I_PU_LO: usize = 0x0003; + pub const VER_SW: usize = 0x0004; + // filtered ADC + pub const ADC_VB_F_MED: usize = 0x0018; + pub const ADC_VBTERM_F: usize = 0x0019; + pub const ADC_VBS_F: usize = 0x001A; + pub const ADC_VA_F: usize = 0x001B; + pub const ADC_IB_F_SHADOW: usize = 0x001C; + pub const ADC_IA_F_SHADOW: usize = 0x001D; + pub const ADC_P12_F: usize = 0x001E; + pub const ADC_P3_F: usize = 0x001F; + pub const ADC_PMETER_F: usize = 0x0020; + pub const ADC_P18_F: usize = 0x0021; + pub const ADC_V_REF: usize = 0x0022; + // temperatures + pub const T_HS: usize = 0x0023; + pub const T_RTS: usize = 0x0024; + pub const T_BATT: usize = 0x0025; + // status + pub const ADC_VB_F_1M: usize = 0x0026; + pub const ADC_IB_F_1M: usize = 0x0027; + pub const VB_MIN: usize = 0x0028; + pub const VB_MAX: usize = 0x0029; + pub const HOURMETER_HI: usize = 0x002A; + pub const HOURMETER_LO: usize = 0x002B; + pub const FAULT_ALL: usize = 0x002C; + pub const ALARM_HI: usize = 0x002E; + pub const ALARM_LO: usize = 0x002F; + pub const DIP_ALL: usize = 0x0030; + pub const LED_STATE: usize = 0x0031; + // charger + pub const CHARGE_STATE: usize = 0x0032; + pub const VB_REF: usize = 0x0033; + pub const AHC_R_HI: usize = 0x0034; + pub const AHC_R_LO: usize = 0x0035; + pub const AHC_T_HI: usize = 0x0036; + pub const AHC_T_LO: usize = 0x0037; + pub const KWHC_R: usize = 0x0038; + pub const KWHC_T: usize = 0x0039; + // MPPT + pub const POWER_OUT_SHADOW: usize = 0x003A; + pub const POWER_IN_SHADOW: usize = 0x003B; + pub const SWEEP_PIN_MAX: usize = 0x003C; + pub const SWEEP_VMP: usize = 0x003D; + pub const SWEEP_VOC: usize = 0x003E; + // logger - today's values + pub const VB_MIN_DAILY: usize = 0x0040; + pub const VB_MAX_DAILY: usize = 0x0041; + pub const VA_MAX_DAILY: usize = 0x0042; + pub const AHC_DAILY: usize = 0x0043; + pub const WHC_DAILY: usize = 0x0044; + pub const FLAGS_DAILY: usize = 0x0045; + pub const POUT_MAX_DAILY: usize = 0x0046; + pub const TB_MIN_DAILY: usize = 0x0047; + pub const TB_MAX_DAILY: usize = 0x0048; + pub const FAULT_DAILY: usize = 0x0049; + pub const ALARM_DAILY_HI: usize = 0x004B; + pub const ALARM_DAILY_LO: usize = 0x004C; + pub const TIME_AB_DAILY: usize = 0x004D; + pub const TIME_EQ_DAILY: usize = 0x004E; + pub const TIME_FL_DAILY: usize = 0x004F; + // manual control + pub const IB_REF_SLAVE: usize = 0x0058; + pub const VB_REF_SLAVE: usize = 0x0059; + pub const VA_REF_FIXED: usize = 0x005A; + pub const VA_REF_FIXED_PCT: usize = 0x005B; +} + +pub struct OffsetsEeprom {} + +impl OffsetsEeprom { + pub const EV_absorp: usize = 0xE000; + pub const EV_float: usize = 0xE001; + pub const Et_absorp: usize = 0xE002; + pub const Et_absorp_ext: usize = 0xE003; + pub const EV_absorp_ext: usize = 0xE004; + pub const EV_float_cancel: usize = 0xE005; + pub const Et_float_exit_cum: usize = 0xE006; + pub const EV_eq: usize = 0xE007; + pub const Et_eqcalendar: usize = 0xE008; + pub const Et_eq_above: usize = 0xE009; + pub const Et_eq_reg: usize = 0xE00A; + pub const Et_batt_service: usize = 0xE00B; + pub const EV_tempcomp: usize = 0xE00D; + pub const EV_hvd: usize = 0xE00E; + pub const EV_hvr: usize = 0xE00F; + pub const Evb_ref_lim: usize = 0xE010; + pub const ETb_max: usize = 0xE011; + pub const ETb_min: usize = 0xE012; + pub const EV_soc_g_gy: usize = 0xE015; + pub const EV_soc_gy_g: usize = 0xE016; + pub const EV_soc_y_yr: usize = 0xE017; + pub const EV_soc_yr_r: usize = 0xE018; + pub const Emodbus_id: usize = 0xE019; + pub const Emeterbus_id: usize = 0xE01A; + pub const EIb_lim: usize = 0xE01D; + pub const EVa_ref_fixed_init: usize = 0xE020; + pub const EVa_ref_fixed_pct_init: usize = 0xE021; +}