We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hi everyone
I've created a set of tools for better MODBUS register analysis.
1.) Script for BLUETTI Modbus discovery-log parsing to ReadHoldingRegisters parameters. Discovers available ranges. https://gist.github.com/igor-podpalchenko/ee2f919881cc554db70026e803820df6
2.) BLUETTI raw data recorder, records data to text file. It should be run as systemd service. Its output will be used as data input for the next scripts. https://gist.github.com/igor-podpalchenko/010602542441ad35f351d2da98c5858d
3.) All registers change viewer (color codes the changed registers). https://gist.github.com/igor-podpalchenko/9fee7d3e82ed1b315f728d1dac40e188
4.) Specific registers change viewer (with register index offset finder). https://gist.github.com/igor-podpalchenko/35ed3c0c14da59d727b1dd65e79feb9a
The final output results look like:
And some small present, protocol version 2 discovery & analysis results. AC70P device config.
# Core (100) self.struct.add_uint_field('total_battery_percent', 102) self.struct.add_decimal_field('estimated_time_hr', 104,1) self.struct.add_swap_string_field('device_type', 110, 6) self.struct.add_sn_field('serial_number', 116) self.struct.add_decimal_field('power_generation', 154, 1) # Total power generated since last reset (kwh) self.struct.add_sn_field('serial_number', 1107) self.struct.add_uint_field('dc_output_power', 140) #y self.struct.add_uint_field('ac_output_power', 142) #y self.struct.add_uint_field('dc_input_power', 144) #y self.struct.add_uint_field('ac_input_power', 146) #y I keep forgetting to test this one. self.struct.add_decimal_field('power_generation', 1202, 1) # Total power generated since last reset (kwh) # Input Details (1100 - 1300) self.struct.add_swap_string_field('device_type', 1101, 6) self.struct.add_sn_field('serial_number', 1107) self.struct.add_uint_field('num_packs_connected', 1209) self.struct.add_bool_field('charging_from_internal_dc', 1210) self.struct.add_uint_field('internal_dc_input_power', 1212) self.struct.add_decimal_field('internal_dc_input_voltage', 1213, 1) self.struct.add_decimal_field('internal_dc_input_current', 1214, 1) self.struct.add_bool_field('charging_from_pack_dc', 1218) self.struct.add_uint_field('pack_dc_input_power', 1220) self.struct.add_decimal_field('pack_dc_input_voltage', 1221, 1) self.struct.add_decimal_field('pack_dc_input_current', 1222, 1) self.struct.add_decimal_field('ac_input_frequency', 1300, 1) self.struct.add_uint_field('internal_ac_input_power', 1313) self.struct.add_decimal_field('ac_input_voltage', 1314, 1) self.struct.add_decimal_field('ac_input_current', 1315, 1) # Output Details (1400 - 1500) self.struct.add_uint_field('total_dc_output_power', 1400) self.struct.add_uint_field('dc_usb_output_power', 1404) self.struct.add_uint_field('dc_12v_output_power', 1406) self.struct.add_uint_field('dc_output_uptime_minutes', 1410) self.struct.add_uint_field('ac_output_power', 1420) self.struct.add_uint_field('ac_output_uptime_minutes', 1424) self.struct.add_uint_field('ac_output_power', 1430) self.struct.add_decimal_field('ac_output_frequency', 1500, 1) #self.struct.add_bool_field('ac_output_on', 1509) self.struct.add_uint_field('battery_inputoutput_power', 1510) self.struct.add_decimal_field('ac_output_voltage', 1511, 1) self.struct.add_decimal_field('ac_output_amps', 1512, 1) # Controls (2000) self.struct.add_bool_field('ac_output_on', 2011) self.struct.add_bool_field('dc_output_on', 2012) self.struct.add_bool_field('dc_eco_on', 2014) self.struct.add_uint_field('dc_eco_hours', 2015) self.struct.add_uint_field('dc_eco_watts', 2016) self.struct.add_bool_field('ac_eco_on', 2017) self.struct.add_uint_field('ac_eco_hours', 2018) self.struct.add_uint_field('ac_eco_watts', 2019) self.struct.add_enum_field('charging_mode', 2020, ChargingMode) self.struct.add_bool_field('power_lifting_on', 2021) # More Controls (2200) self.struct.add_bool_field('grid_enhancement_mode_on', 2225) # Battery Data Register (6000) #self.struct.add_decimal_field('total_battery_voltage', 6003, 2) # Battery Data Register (6100) self.struct.add_swap_string_field('battery_type', 6101, 6) self.struct.add_sn_field('pack_serial_number', 6107) #self.struct.add_decimal_field('pack_voltage', 6111, 2) self.struct.add_decimal_field('bms_output_voltage', 6111, 2) self.struct.add_decimal_field('bms_charge_voltage', 6116, 2) self.struct.add_decimal_field('bms_current_1', 6112, 1) #self.struct.add_uint_field('pack_battery_percent', 6113) self.struct.add_uint_field('bms_temp_1', 6120) self.struct.add_uint_field('bms_temp_2', 6121) self.struct.add_version_field('bcu_version', 6175) # Controls (2000) #self.struct.add_bool_field('ac_output_on', 2011) #y #self.struct.add_bool_field('dc_output_on', 2012) #y @property def polling_commands(self) -> List[ReadHoldingRegisters]: return [ #ReadHoldingRegisters(10, 40), #ReadHoldingRegisters(70, 21), #ReadHoldingRegisters(100, 62), ReadHoldingRegisters(100, 50), ReadHoldingRegisters(1100, 51), ReadHoldingRegisters(1200, 90), ReadHoldingRegisters(1300, 31), ReadHoldingRegisters(1400, 48), ReadHoldingRegisters(1500, 30), ReadHoldingRegisters(2000, 67), ReadHoldingRegisters(2200, 29), ReadHoldingRegisters(6000, 31), ReadHoldingRegisters(6100, 100), ReadHoldingRegisters(6300, 52), ] @property def logging_commands(self) -> List[ReadHoldingRegisters]: return [ #ReadHoldingRegisters(70, 66), #ReadHoldingRegisters(136, 74), #ReadHoldingRegisters(100, 62), #ReadHoldingRegisters(1100, 51), #ReadHoldingRegisters(1200, 90), #ReadHoldingRegisters(2000, 67), #ReadHoldingRegisters(2200, 29), ReadHoldingRegisters(100, 50), ReadHoldingRegisters(1100, 51), ReadHoldingRegisters(1200, 90), ReadHoldingRegisters(1300, 31), ReadHoldingRegisters(1400, 48), ReadHoldingRegisters(1500, 30), ReadHoldingRegisters(2000, 67), ReadHoldingRegisters(2200, 29), ReadHoldingRegisters(6000, 31), ReadHoldingRegisters(6100, 100), ReadHoldingRegisters(6300, 52), ] @property def writable_ranges(self) -> List[range]: return [range(2000, 2225)]
It would be good if someone could integrate my findings into the repo.
The text was updated successfully, but these errors were encountered:
Would you be willing to contribute to my fork of this repo?
Sorry, something went wrong.
No branches or pull requests
Hi everyone
I've created a set of tools for better MODBUS register analysis.
1.) Script for BLUETTI Modbus discovery-log parsing to ReadHoldingRegisters parameters. Discovers available ranges.
https://gist.github.com/igor-podpalchenko/ee2f919881cc554db70026e803820df6
2.) BLUETTI raw data recorder, records data to text file. It should be run as systemd service. Its output will be used as data input for the next scripts.
https://gist.github.com/igor-podpalchenko/010602542441ad35f351d2da98c5858d
3.) All registers change viewer (color codes the changed registers).
https://gist.github.com/igor-podpalchenko/9fee7d3e82ed1b315f728d1dac40e188
4.) Specific registers change viewer (with register index offset finder).
https://gist.github.com/igor-podpalchenko/35ed3c0c14da59d727b1dd65e79feb9a
The final output results look like:
And some small present, protocol version 2 discovery & analysis results. AC70P device config.
It would be good if someone could integrate my findings into the repo.
The text was updated successfully, but these errors were encountered: