Start | End | Block description |
---|---|---|
3972 | 3972 | Unknown |
4096 | 4111 | Brand and model name |
4112 | 4239 | Empty |
4320 | 4320 | Date and time |
4352 | 4415 | Same as 5120-5183 |
4416 | 4607 | Empty |
4608 | 4671 | Unknown, maybe settings (seems static) |
4672 | 4863 | Empty |
5120 | 5183 | BMS status |
5184 | 5199 | Empty |
5200 | 5215 | BMS SN |
5216 | 5231 | Pack 0-x - Module 0-x Voltage |
5232 | 5295 | Empty |
5296 | 5311 | Pack 0-x - Module 0-x Temperature |
5312 | 5375 | Empty |
5376 | 5503 | Pack 0 Module 0-4 Cell Voltage |
5504 | 6143 | ?? Pack 1-5 Module 0-4 Cell Voltage |
6144 | 6271 | Pack 0 Module 0-4 Cell Temperature |
6272 | 6911 | ?? Pack 1-5 Module 0-4 Cell Temperature |
-
-
Save nagisa/435bdf783e4b13b8e810106b0852081e to your computer and use it in GitHub Desktop.
Pylontech Force H2 - Solarman Modbus RTU registry map
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
requests: | |
# Brand, Device name, FW Version | |
- start: 4096 | |
end: 4106 | |
mb_functioncode: 0x03 | |
# Device Date and Time - TODO | |
#- start: 4320 | |
# end: 4325 | |
# mb_functioncode: 0x03 | |
# BMS Status | |
- start: 5120 | |
end: 5135 | |
mb_functioncode: 0x03 | |
# Cell/Module Max/Min Temperature and Voltage | |
- start: 5136 | |
end: 5151 | |
mb_functioncode: 0x03 | |
# Total Charge, Discharge | |
- start: 5152 | |
end: 5167 | |
mb_functioncode: 0x03 | |
# Pack, Module, Cell count | |
- start: 5174 | |
end: 5175 | |
mb_functioncode: 0x03 | |
# Device SN | |
- start: 5200 | |
end: 5207 | |
mb_functioncode: 0x03 | |
# Pack 0 Module 0-3 Voltage | |
- start: 5216 | |
end: 5219 | |
mb_functioncode: 0x03 | |
# Pack 0 Module 0-3 Temperature | |
- start: 5296 | |
end: 5299 | |
mb_functioncode: 0x03 | |
# Pack 0 Module 0-3 Cells Voltage | |
#- start: 5376 | |
# end: 5465 | |
# mb_functioncode: 0x03 | |
# Pack 0 Module 0-3 Cells Temperature | |
#- start: 6144 | |
# end: 6233 | |
# mb_functioncode: 0x03 | |
parameters: | |
- group: Basic information | |
items: | |
- name: "Device SN" | |
class: "" | |
state_class: "" | |
uom: "" | |
scale: 1 | |
rule: 5 | |
registers: [ 5200,5201,5202,5203,5204,5205,5206,5207 ] | |
isstr: true | |
#- name: "Device Time" # TODO - cant parse format is [y, m, d, h, m, s] | |
# class: "" | |
# state_class: "" | |
# uom: "" | |
# scale: 1 | |
# rule: 8 | |
# registers: [4320,4321,4322,4323,4324,4325] | |
# isstr: true | |
- name: "Brand" | |
class: "" | |
state_class: "" | |
uom: "" | |
scale: 1 | |
rule: 5 | |
registers: [ 4096,4097,4098 ] | |
isstr: true | |
- name: "Device Name" | |
class: "" | |
state_class: "" | |
uom: "" | |
scale: 1 | |
rule: 5 | |
registers: [ 4101,4102,4103,4104,4105 ] | |
isstr: true | |
- name: "FW Version" | |
class: "" | |
state_class: "" | |
uom: "" | |
scale: 1 | |
rule: 7 | |
registers: [ 4106 ] # 00000001 00000110 = V1.6 | |
isstr: true | |
# NOTE: buggy, counter jumps up by a couple MWh once in a while | |
- name: "Total Charge" | |
class: "energy" | |
state_class: "total_increasing" | |
uom: "kWh" | |
scale: 1 | |
rule: 1 | |
registers: [ 5164 ] | |
icon: 'mdi:battery-plus' | |
# NOTE: buggy, counter jumps up by a couple MWh once in a while | |
- name: "Total Discharge" | |
class: "energy" | |
state_class: "total_increasing" | |
uom: "kWh" | |
scale: 1 | |
rule: 1 | |
registers: [ 5166 ] | |
icon: 'mdi:battery-minus' | |
#- name: "Battery Pack (parallel)" # not tested | |
# class: "" | |
# state_class: "" | |
# uom: "" | |
# scale: 1 | |
# rule: 1 | |
# registers: [5173] | |
- name: "Battery Module (series)" | |
class: "" | |
state_class: "" | |
uom: "" | |
scale: 1 | |
rule: 1 | |
registers: [ 5174 ] | |
- name: "Battery Cell (series)" | |
class: "" | |
state_class: "" | |
uom: "" | |
scale: 1 | |
rule: 1 | |
registers: [ 5175 ] | |
- group: Battery | |
items: | |
- name: "Battery Voltage" | |
class: "voltage" | |
state_class: "measurement" | |
uom: "V" | |
scale: 0.1 | |
rule: 1 | |
registers: [ 5123 ] | |
icon: 'mdi:battery' | |
- name: "Battery Current" | |
class: "current" | |
state_class: "measurement" | |
uom: "A" | |
scale: 0.01 | |
rule: 2 | |
registers: [ 5125 ] | |
icon: 'mdi:current-dc' | |
- name: "Battery Temperature" | |
class: "temperature" | |
state_class: "measurement" | |
uom: "°C" | |
scale: 0.1 | |
rule: 2 | |
registers: [ 5126 ] | |
icon: 'mdi:thermometer' | |
- name: "Battery Charge" | |
class: "battery" | |
state_class: "measurement" | |
uom: "%" | |
scale: 1 | |
rule: 1 | |
registers: [ 5127 ] | |
icon: 'mdi:battery' | |
- name: "Battery Cycle Times" | |
class: "" | |
state_class: "" | |
uom: "" | |
scale: 1 | |
rule: 1 | |
registers: [ 5128 ] | |
icon: 'mdi:battery-heart' | |
- name: "Max Charging Voltage" | |
class: "voltage" | |
state_class: "measurement" | |
uom: "V" | |
scale: 0.1 | |
rule: 1 | |
registers: [ 5129 ] | |
- name: "Max Charging Current" | |
class: "current" | |
state_class: "measurement" | |
uom: "A" | |
scale: 0.01 | |
rule: 2 | |
registers: [ 5131 ] | |
icon: 'mdi:current-dc' | |
- name: "Min Discharging Voltage" | |
class: "voltage" | |
state_class: "measurement" | |
uom: "V" | |
scale: 0.1 | |
rule: 1 | |
registers: [ 5132 ] | |
- name: "Max Discharging Current" | |
class: "current" | |
state_class: "measurement" | |
uom: "A" | |
scale: 0.01 | |
rule: 2 | |
registers: [ 5134 ] | |
icon: 'mdi:current-dc' | |
- name: "Max Cell Voltage" | |
class: "voltage" | |
state_class: "measurement" | |
uom: "V" | |
scale: 0.001 | |
rule: 1 | |
registers: [ 5136 ] | |
icon: 'mdi:battery' | |
- name: "Min Cell Voltage" | |
class: "voltage" | |
state_class: "measurement" | |
uom: "V" | |
scale: 0.001 | |
rule: 1 | |
registers: [ 5137 ] | |
icon: 'mdi:battery' | |
- name: "Max Cell Voltage ID" | |
class: "" | |
state_class: "" | |
uom: "" | |
scale: 1 | |
rule: 1 | |
registers: [ 5138 ] | |
- name: "Min Cell Voltage ID" | |
class: "" | |
state_class: "" | |
uom: "" | |
scale: 1 | |
rule: 1 | |
registers: [ 5139 ] | |
- name: "Max Cell Temperature" | |
class: "temperature" | |
state_class: "measurement" | |
uom: "°C" | |
scale: 0.1 | |
rule: 2 | |
registers: [ 5140 ] | |
icon: 'mdi:thermometer' | |
- name: "Min Cell Temperature" | |
class: "temperature" | |
state_class: "measurement" | |
uom: "°C" | |
scale: 0.1 | |
rule: 2 | |
registers: [ 5141 ] | |
icon: 'mdi:thermometer' | |
- name: "Max Cell Temperature ID" | |
class: "" | |
state_class: "" | |
uom: "" | |
scale: 1 | |
rule: 1 | |
registers: [ 5142 ] | |
- name: "Min Cell Temperature ID" | |
class: "" | |
state_class: "" | |
uom: "" | |
scale: 1 | |
rule: 1 | |
registers: [ 5143 ] | |
- name: "Max Module Voltage" | |
class: "voltage" | |
state_class: "measurement" | |
uom: "V" | |
scale: 0.01 | |
rule: 1 | |
registers: [ 5144 ] | |
icon: 'mdi:battery' | |
- name: "Min Module Voltage" | |
class: "voltage" | |
state_class: "measurement" | |
uom: "V" | |
scale: 0.01 | |
rule: 1 | |
registers: [ 5145 ] | |
icon: 'mdi:battery' | |
- name: "Max Module Voltage ID" | |
class: "" | |
state_class: "" | |
uom: "" | |
scale: 1 | |
rule: 1 | |
registers: [ 5146 ] | |
- name: "Min Module Voltage ID" | |
class: "" | |
state_class: "" | |
uom: "" | |
scale: 1 | |
rule: 1 | |
registers: [ 5147 ] | |
- name: "Max Module Temperature" | |
class: "temperature" | |
state_class: "measurement" | |
uom: "°C" | |
scale: 0.1 | |
rule: 2 | |
registers: [ 5148 ] | |
icon: 'mdi:thermometer' | |
- name: "Min Module Temperature" | |
class: "temperature" | |
state_class: "measurement" | |
uom: "°C" | |
scale: 0.1 | |
rule: 2 | |
registers: [ 5149 ] | |
icon: 'mdi:thermometer' | |
- name: "Max Module Temperature ID" | |
class: "" | |
state_class: "" | |
uom: "" | |
scale: 1 | |
rule: 1 | |
registers: [ 5150 ] | |
- name: "Min Module Temperature ID" | |
class: "" | |
state_class: "" | |
uom: "" | |
scale: 1 | |
rule: 1 | |
registers: [ 5151 ] | |
- name: "Battery SOH" | |
class: "battery" | |
state_class: "measurement" | |
uom: "%" | |
scale: 1 | |
rule: 1 | |
registers: [ 5152 ] | |
icon: 'mdi:battery' | |
# NOTE: buggy, counter jumps up by a couple MWh once in a while | |
- name: "Today Charge" | |
class: "energy" | |
state_class: "total_increasing" | |
uom: "kWh" | |
scale: 0.001 | |
rule: 1 | |
registers: [ 5160 ] | |
# NOTE: buggy, counter jumps up by a couple MWh once in a while | |
- name: "Today Discharge" | |
class: "energy" | |
state_class: "total_increasing" | |
uom: "kWh" | |
scale: 0.001 | |
rule: 1 | |
registers: [ 5162 ] | |
- group: Battery Module 0 | |
items: | |
- name: "Battery Module 0 Voltage" | |
class: "voltage" | |
state_class: "measurement" | |
uom: "V" | |
scale: 0.01 | |
rule: 1 | |
registers: [ 5216 ] | |
icon: 'mdi:battery' | |
- name: "Battery Module 0 Temperature" | |
class: "temperature" | |
state_class: "measurement" | |
uom: "°C" | |
scale: 0.1 | |
rule: 2 | |
registers: [ 5296 ] | |
icon: 'mdi:thermometer' | |
- group: Battery Module 1 | |
items: | |
- name: "Battery Module 1 Voltage" | |
class: "voltage" | |
state_class: "measurement" | |
uom: "V" | |
scale: 0.01 | |
rule: 1 | |
registers: [ 5217 ] | |
icon: 'mdi:battery' | |
- name: "Battery Module 1 Temperature" | |
class: "temperature" | |
state_class: "measurement" | |
uom: "°C" | |
scale: 0.1 | |
rule: 2 | |
registers: [ 5297 ] | |
icon: 'mdi:thermometer' | |
- group: Battery Module 2 | |
items: | |
- name: "Battery Module 2 Voltage" | |
class: "voltage" | |
state_class: "measurement" | |
uom: "V" | |
scale: 0.01 | |
rule: 1 | |
registers: [ 5218 ] | |
icon: 'mdi:battery' | |
- name: "Battery Module 2 Temperature" | |
class: "temperature" | |
state_class: "measurement" | |
uom: "°C" | |
scale: 0.1 | |
rule: 2 | |
registers: [ 5298 ] | |
icon: 'mdi:thermometer' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" Scan Modbus registers to find valid registers""" | |
from pysolarmanv5 import PySolarmanV5, V5FrameError | |
import umodbus.exceptions | |
import argparse | |
# Docs: | |
# - https://pysolarmanv5.readthedocs.io/en/stable/solarmanv5_protocol.html | |
# - https://github.com/jmccrohan/pysolarmanv5 | |
# | |
# Usage: | |
# pip install pysolarmanv5 | |
# python solarmanPylontechScan.py 5120 5199 > scan_240224_10_10.csv | |
deviceIP="192.168.x.x" # string IP address | |
deviceSerialNumber=123456789 # int device serial number | |
def main(): | |
parser = argparse.ArgumentParser() | |
parser.add_argument("address", help="Address to start scanning from", type=int) | |
parser.add_argument("addressStop", help="Last address to scan", type=int) | |
args = parser.parse_args() | |
if args.address < 0: | |
print("Address must be greater than or equal to 0") | |
return | |
if args.addressStop < 0: | |
print("AddressStop must be greater than or equal to 0") | |
return | |
if args.addressStop < args.address: | |
print("AddressStop must be greater than or equal to address") | |
return | |
modbus = PySolarmanV5( | |
deviceIP, deviceSerialNumber, port=8899, mb_slave_id=1, verbose=False | |
) | |
# print as csv header | |
print("Register, Register Hex, Length, Value Int, Value Hex, Value Bin1, Value Bin2") | |
for x in range(args.address, args.addressStop): | |
try: | |
val = modbus.read_holding_registers(register_addr=x, quantity=1)[0] | |
binLeft = (val >> 8) & 0xff | |
binRight = val & 0xff | |
# csv row | |
print(f"{x}, {x:#06x}, 1, {val:05}, {val:#06x}, {binLeft:08b}, {binRight:08b}") | |
except (V5FrameError, umodbus.exceptions.IllegalDataAddressError): | |
print(f"{x}, {x:#06x}, 1") | |
continue | |
modbus.disconnect() | |
if __name__ == "__main__": | |
main() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I had to read all the registry values and compare them to the official Solarman Business app data. There were some predictions based on the layout for additional batteries, even though I have only three connected in parallel.