diff --git a/prostar_mppt.preset.toml b/prostar_mppt.preset.toml new file mode 100644 index 0000000..0f22cd7 --- /dev/null +++ b/prostar_mppt.preset.toml @@ -0,0 +1,182 @@ +# Preset for Morningstar ProStar MPPT Solar Charge Controller +# Register values use IEEE 754 half-precision float (Float16) unless noted. +# Reference: ProStar MPPT MODBUS Specification v05 (MS-001723), 2 March 2021 + +config_version = 1 +# Name of this device preset, used for lookup +name = "prostar_mppt" +# Type of this preset +type = "device" +# Dependencies required by all inputs in this device preset +_dependencies = [ "pymodbus", "pyserial" ] + +# Preset-level metadata; format follows that specified in the top-level +[metadata] + name_full = "Morningstar ProStar MPPT charge controller" + author = "C.A.M. Gerlach and the UAH HAMMA group" + description = "Device preset for the Morningstar ProStar MPPT solar charge controller" + homepage = "https://hamma.dev/" + repo = "https://github.com/hamma-dev/mjolnir-presets" + preset_version = "0.1.0" + brokkr_version_min = "0.3.0" + +# Data type presets to use for the data types that follow +# Float16 registers decode directly via struct format "e" (no scale/base/power) +[type_presets] + float16_v = { input_type = "e", unit = "V", uncertainty = true, digits = 3 } + float16_a = { input_type = "e", unit = "A", uncertainty = true, digits = 3 } + float16_w = { input_type = "e", unit = "W", uncertainty = true, digits = 1 } + float16_c = { input_type = "e", unit = "C", uncertainty = true, digits = 1 } + float16_ah = { input_type = "e", unit = "Ah", uncertainty = true, digits = 1 } + amp_hours = { input_type = "I", conversion = "custom", unit = "Ah", uncertainty = true, scale = 0.1, digits = 1 } + kilowatt_hours = { conversion = "custom", unit = "kWh", uncertainty = true, scale = 0.1, digits = 1 } + bitfield = { conversion = "bitfield", unit = false, uncertainty = false } + bitfield_32 = { input_type = "I", conversion = "bitfield", unit = false, uncertainty = false } + +# Data types referenced in individual presets +[data_types] + # Filtered ADC measurements (registers 0x0010-0x0019) + adc_ic = { full_name = "Charge Current", type_presets = "float16_a" } + adc_ia = { full_name = "Array Current", type_presets = "float16_a" } + adc_vbterm = { full_name = "Batt Terminal Voltage", type_presets = "float16_v" } + adc_va = { full_name = "Array Voltage", type_presets = "float16_v" } + adc_vl = { full_name = "Load Voltage", type_presets = "float16_v" } + adc_ib = { full_name = "Battery Current (Net)", type_presets = "float16_a" } + adc_il = { full_name = "Load Current", type_presets = "float16_a" } + adc_vbsense = { full_name = "Batt Sense Voltage", type_presets = "float16_v" } + adc_vb_f_1m = { full_name = "Batt Voltage (60s Filter)", type_presets = "float16_v" } + adc_ib_f_1m = { full_name = "Batt Current (60s Filter)", type_presets = "float16_a" } + + # Temperatures (registers 0x001A-0x0020) + t_hs = { full_name = "Heatsink Temp", type_presets = "float16_c" } + t_batt = { full_name = "Battery Temp", type_presets = "float16_c" } + t_amb = { full_name = "Ambient Temp", type_presets = "float16_c" } + t_rts = { full_name = "Remote Temp", type_presets = "float16_c" } + t_ind_u = { full_name = "Phase U Inductor Temp", type_presets = "float16_c" } + t_ind_v = { full_name = "Phase V Inductor Temp", type_presets = "float16_c" } + t_ind_w = { full_name = "Phase W Inductor Temp", type_presets = "float16_c" } + + # Charger status (registers 0x0021-0x0025) + charge_state = { unit = false, uncertainty = false } + array_fault = { type_presets = "bitfield" } + vb_f = { full_name = "Batt Voltage (25s Filter)", type_presets = "float16_v" } + vb_ref = { full_name = "Ref Voltage", type_presets = "float16_v" } + vb_ref_charge_slave = { full_name = "Ref Voltage Slave", type_presets = "float16_v" } + + # Charge accumulation (registers 0x0026-0x002B) + ahc_r = { full_name = "Ah Charge (rst)", type_presets = "amp_hours" } + ahc_t = { full_name = "Ah Charge (tot)", type_presets = "amp_hours" } + kwhc_r = { full_name = "kWh Charge (rst)", type_presets = "kilowatt_hours" } + kwhc_t = { full_name = "kWh Charge (tot)", type_presets = "kilowatt_hours" } + + # Temperature foldback limits (registers 0x002C-0x002D) + tb_lo_limit_100 = { full_name = "Batt Temp Foldback 100%", type_presets = "float16_c" } + tb_lo_limit_0 = { full_name = "Batt Temp Foldback 0%", type_presets = "float16_c" } + + # Load status (registers 0x002E-0x0035) + load_state = { unit = false, uncertainty = false } + load_fault = { type_presets = "bitfield" } + v_lvd = { full_name = "LVD Voltage", type_presets = "float16_v" } + v_lhvd = { full_name = "Load HVD Voltage", type_presets = "float16_v" } + ahl_r = { full_name = "Ah Load (rst)", type_presets = "amp_hours" } + ahl_t = { full_name = "Ah Load (tot)", type_presets = "amp_hours" } + + # Miscellaneous (registers 0x0036-0x003B) + hourmeter = { input_type = "I", unit = "h", uncertainty = false } + alarm = { type_presets = "bitfield_32" } + dip_switch = { type_presets = "bitfield" } + led_state = { full_name = "SOC LED State", unit = false, uncertainty = false } + + # MPPT (registers 0x003C-0x0040) + power_out = { full_name = "Charger Output Power", type_presets = "float16_w" } + sweep_vmp = { full_name = "Array Vmp (Sweep)", type_presets = "float16_v" } + sweep_pmax = { full_name = "Array Max Power (Sweep)", type_presets = "float16_w" } + sweep_voc = { full_name = "Array Voc (Sweep)", type_presets = "float16_v" } + va_ref = { full_name = "Array Target Voltage", type_presets = "float16_v" } + + # Daily logger (registers 0x0041-0x004C) + vb_min_daily = { full_name = "Batt Voltage Min (Daily)", type_presets = "float16_v" } + vb_max_daily = { full_name = "Batt Voltage Max (Daily)", type_presets = "float16_v" } + ahc_daily = { full_name = "Ah Charge (Daily)", type_presets = "float16_ah" } + ahl_daily = { full_name = "Ah Load (Daily)", type_presets = "float16_ah" } + array_fault_daily = { type_presets = "bitfield" } + load_fault_daily = { type_presets = "bitfield" } + alarm_daily = { type_presets = "bitfield_32" } + time_ab_daily = { full_name = "Time in Absorption (Daily)", unit = "s", uncertainty = false } + time_eq_daily = { full_name = "Time in Equalization (Daily)", unit = "s", uncertainty = false } + time_fl_daily = { full_name = "Time in Float (Daily)", unit = "s", uncertainty = false } + va_max_daily = { full_name = "Array Voltage Max (Daily)", type_presets = "float16_v" } + +[inputs] + # Input to read the RAM status data (holding registers) of the ProStar MPPT + # Reads 61 contiguous registers from 0x0010 to 0x004C + [inputs.ram] + _module_path = "brokkr.inputs.modbus" + _class_name = "ModbusSerialInput" + _dependencies = [] + name = "ProStar MPPT RAM Status Data" + unit = 1 + start_address = 0x0010 + serial_port = "" + serial_pids = [ 24597 ] + try_usb_reset = true + modbus_kwargs.baudrate = 9600 + modbus_kwargs.parity = "N" + modbus_kwargs.stopbits = 2 + modbus_kwargs.strict = false + data_types = [ + "adc_ic", + "adc_ia", + "adc_vbterm", + "adc_va", + "adc_vl", + "adc_ib", + "adc_il", + "adc_vbsense", + "adc_vb_f_1m", + "adc_ib_f_1m", + "t_hs", + "t_batt", + "t_amb", + "t_rts", + "t_ind_u", + "t_ind_v", + "t_ind_w", + "charge_state", + "array_fault", + "vb_f", + "vb_ref", + "vb_ref_charge_slave", + "ahc_r", + "ahc_t", + "kwhc_r", + "kwhc_t", + "tb_lo_limit_100", + "tb_lo_limit_0", + "load_state", + "load_fault", + "v_lvd", + "v_lhvd", + "ahl_r", + "ahl_t", + "hourmeter", + "alarm", + "dip_switch", + "led_state", + "power_out", + "sweep_vmp", + "sweep_pmax", + "sweep_voc", + "va_ref", + "vb_min_daily", + "vb_max_daily", + "ahc_daily", + "ahl_daily", + "array_fault_daily", + "load_fault_daily", + "alarm_daily", + "time_ab_daily", + "time_eq_daily", + "time_fl_daily", + "va_max_daily", + ]