diff --git a/modbus-sungrow-scanall.py b/modbus-sungrow-scanall.py new file mode 100644 index 0000000..b32022a --- /dev/null +++ b/modbus-sungrow-scanall.py @@ -0,0 +1,360 @@ +""" +A simple 'scan everything' register dump that I used when I +was scanning the SH10RS. This may be useful in the future as +new devices are released + +Copyright: Rob Thomas May 2024 + +Licenced under the MIT licence and any additional licence that +the solariot project may be released under. +""" + +read_register = { + "5000": "reg_5000_scan", + "5001": "reg_5001_scan", + "5002": "reg_5002_scan", + "5003": "reg_5003_scan", + "5004": "reg_5004_scan", + "5005": "reg_5005_scan", + "5006": "reg_5006_scan", + "5007": "reg_5007_scan", + "5008": "reg_5008_scan", + "5009": "reg_5009_scan", + "5010": "reg_5010_scan", + "5011": "reg_5011_scan", + "5012": "reg_5012_scan", + "5013": "reg_5013_scan", + "5014": "reg_5014_scan", + "5015": "reg_5015_scan", + "5016": "reg_5016_scan", + "5017": "reg_5017_scan", + "5018": "reg_5018_scan", + "5019": "reg_5019_scan", + "5020": "reg_5020_scan", + "5021": "reg_5021_scan", + "5022": "reg_5022_scan", + "5023": "reg_5023_scan", + "5024": "reg_5024_scan", + "5025": "reg_5025_scan", + "5026": "reg_5026_scan", + "5027": "reg_5027_scan", + "5028": "reg_5028_scan", + "5029": "reg_5029_scan", + "5030": "reg_5030_scan", + "5031": "reg_5031_scan", + "5032": "reg_5032_scan", + "5033": "reg_5033_scan", + "5034": "reg_5034_scan", + "5035": "reg_5035_scan", + "5036": "reg_5036_scan", + "5037": "reg_5037_scan", + "5038": "reg_5038_scan", + "5039": "reg_5039_scan", + "5040": "reg_5040_scan", + "5041": "reg_5041_scan", + "5042": "reg_5042_scan", + "5043": "reg_5043_scan", + "5044": "reg_5044_scan", + "5045": "reg_5045_scan", + "5046": "reg_5046_scan", + "5047": "reg_5047_scan", + "5048": "reg_5048_scan", + "5049": "reg_5049_scan", + "5050": "reg_5050_scan", + "5051": "reg_5051_scan", + "5052": "reg_5052_scan", + "5053": "reg_5053_scan", + "5054": "reg_5054_scan", + "5055": "reg_5055_scan", + "5056": "reg_5056_scan", + "5057": "reg_5057_scan", + "5058": "reg_5058_scan", + "5059": "reg_5059_scan", + "5060": "reg_5060_scan", + "5061": "reg_5061_scan", + "5062": "reg_5062_scan", + "5063": "reg_5063_scan", + "5064": "reg_5064_scan", + "5065": "reg_5065_scan", + "5066": "reg_5066_scan", + "5067": "reg_5067_scan", + "5068": "reg_5068_scan", + "5069": "reg_5069_scan", + "5070": "reg_5070_scan", + "5071": "reg_5071_scan", + "5072": "reg_5072_scan", + "5073": "reg_5073_scan", + "5074": "reg_5074_scan", + "5075": "reg_5075_scan", + "5076": "reg_5076_scan", + "5077": "reg_5077_scan", + "5078": "reg_5078_scan", + "5079": "reg_5079_scan", + "5080": "reg_5080_scan", + "5081": "reg_5081_scan", + "5082": "reg_5082_scan", + "5083": "reg_5083_scan", + "5084": "reg_5084_scan", + "5085": "reg_5085_scan", + "5086": "reg_5086_scan", + "5087": "reg_5087_scan", + "5088": "reg_5088_scan", + "5089": "reg_5089_scan", + "5090": "reg_5090_scan", + "5091": "reg_5091_scan", + "5092": "reg_5092_scan", + "5093": "reg_5093_scan", + "5094": "reg_5094_scan", + "5095": "reg_5095_scan", + "5096": "reg_5096_scan", + "5097": "reg_5097_scan", + "5098": "reg_5098_scan", + "5099": "reg_5099_scan", + "5100": "reg_5100_scan", + "5101": "reg_5101_scan", + "5102": "reg_5102_scan", + "5103": "reg_5103_scan", + "5104": "reg_5104_scan", + "5105": "reg_5105_scan", + "5106": "reg_5106_scan", + "5107": "reg_5107_scan", + "5108": "reg_5108_scan", + "5109": "reg_5109_scan", + "5110": "reg_5110_scan", + "5111": "reg_5111_scan", + "5112": "reg_5112_scan", + "5113": "reg_5113_scan", + "5114": "reg_5114_scan", + "5115": "reg_5115_scan", + "5116": "reg_5116_scan", + "5117": "reg_5117_scan", + "5118": "reg_5118_scan", + "5119": "reg_5119_scan", + "5120": "reg_5120_scan", + "5121": "reg_5121_scan", + "5122": "reg_5122_scan", + "5123": "reg_5123_scan", + "5124": "reg_5124_scan", + "5125": "reg_5125_scan", + "5126": "reg_5126_scan", + "5127": "reg_5127_scan", + "5128": "reg_5128_scan", + "5129": "reg_5129_scan", + "5130": "reg_5130_scan", + "5131": "reg_5131_scan", + "5132": "reg_5132_scan", + "5133": "reg_5133_scan", + "5134": "reg_5134_scan", + "5135": "reg_5135_scan", + "5136": "reg_5136_scan", + "5137": "reg_5137_scan", + "5138": "reg_5138_scan", + "5139": "reg_5139_scan", + "5140": "reg_5140_scan", + "5141": "reg_5141_scan", + "5142": "reg_5142_scan", + "5143": "reg_5143_scan", + "5144": "reg_5144_scan", + "5145": "reg_5145_scan", + "5146": "reg_5146_scan", + "5147": "reg_5147_scan", + "5148": "reg_5148_scan", + "5149": "reg_5149_scan", + "5150": "reg_5150_scan", + "5151": "reg_5151_scan", + "5152": "reg_5152_scan", + "5153": "reg_5153_scan", + "5154": "reg_5154_scan", + "5155": "reg_5155_scan", + "5156": "reg_5156_scan", + "5157": "reg_5157_scan", + "5158": "reg_5158_scan", + "5159": "reg_5159_scan", + "5160": "reg_5160_scan", + "5161": "reg_5161_scan", + "5162": "reg_5162_scan", + "5163": "reg_5163_scan", + "5164": "reg_5164_scan", + "5165": "reg_5165_scan", + "5166": "reg_5166_scan", + "5167": "reg_5167_scan", + "5168": "reg_5168_scan", + "5169": "reg_5169_scan", + "5170": "reg_5170_scan", + "5171": "reg_5171_scan", + "5172": "reg_5172_scan", + "5173": "reg_5173_scan", + "5174": "reg_5174_scan", + "5175": "reg_5175_scan", + "5176": "reg_5176_scan", + "5177": "reg_5177_scan", + "5178": "reg_5178_scan", + "5179": "reg_5179_scan", + "5180": "reg_5180_scan", + "5181": "reg_5181_scan", + "5182": "reg_5182_scan", + "5183": "reg_5183_scan", + "5184": "reg_5184_scan", + "5185": "reg_5185_scan", + "5186": "reg_5186_scan", + "5187": "reg_5187_scan", + "5188": "reg_5188_scan", + "5189": "reg_5189_scan", + "5190": "reg_5190_scan", + "5191": "reg_5191_scan", + "5192": "reg_5192_scan", + "5193": "reg_5193_scan", + "5194": "reg_5194_scan", + "5195": "reg_5195_scan", + "5196": "reg_5196_scan", + "5197": "reg_5197_scan", + "5198": "reg_5198_scan", + "5199": "reg_5199_scan", + "5200": "reg_5200_scan", + "5201": "reg_5201_scan", + "5202": "reg_5202_scan", + "5203": "reg_5203_scan", + "5204": "reg_5204_scan", + "5205": "reg_5205_scan", + "5206": "reg_5206_scan", + "5207": "reg_5207_scan", + "5208": "reg_5208_scan", + "5209": "reg_5209_scan", + "5210": "reg_5210_scan", + "5211": "reg_5211_scan", + "5212": "reg_5212_scan", + "5213": "reg_5213_scan", + "5214": "reg_5214_scan", + "5215": "reg_5215_scan", + "5216": "reg_5216_scan", + "5217": "reg_5217_scan", + "5218": "reg_5218_scan", + "5219": "reg_5219_scan", + "5220": "reg_5220_scan", + "5221": "reg_5221_scan", + "5222": "reg_5222_scan", + "5223": "reg_5223_scan", + "5224": "reg_5224_scan", + "5225": "reg_5225_scan", + "5226": "reg_5226_scan", + "5227": "reg_5227_scan", + "5228": "reg_5228_scan", + "5229": "reg_5229_scan", + "5230": "reg_5230_scan", + "5231": "reg_5231_scan", + "5232": "reg_5232_scan", + "5233": "reg_5233_scan", + "5234": "reg_5234_scan", + "5235": "reg_5235_scan", + "5236": "reg_5236_scan", + "5237": "reg_5237_scan", + "5238": "reg_5238_scan", + "5239": "reg_5239_scan", + "5240": "reg_5240_scan", + "5241": "reg_5241_scan", + "5242": "reg_5242_scan", + "5243": "reg_5243_scan", + "5244": "reg_5244_scan", + "5245": "reg_5245_scan", + "5246": "reg_5246_scan", + "5247": "reg_5247_scan", + "5248": "reg_5248_scan", + "5249": "reg_5249_scan", + "5250": "reg_5250_scan", + "5251": "reg_5251_scan", + "5252": "reg_5252_scan", + "5253": "reg_5253_scan", + "5254": "reg_5254_scan", + "5255": "reg_5255_scan", + "5256": "reg_5256_scan", + "5257": "reg_5257_scan", + "5258": "reg_5258_scan", + "5259": "reg_5259_scan", + "5260": "reg_5260_scan", + "5261": "reg_5261_scan", + "5262": "reg_5262_scan", + "5263": "reg_5263_scan", + "5264": "reg_5264_scan", + "5265": "reg_5265_scan", + "5266": "reg_5266_scan", + "5267": "reg_5267_scan", + "5268": "reg_5268_scan", + "5269": "reg_5269_scan", + "5270": "reg_5270_scan", + "5271": "reg_5271_scan", + "5272": "reg_5272_scan", + "5273": "reg_5273_scan", + "5274": "reg_5274_scan", + "5275": "reg_5275_scan", + "5276": "reg_5276_scan", + "5277": "reg_5277_scan", + "5278": "reg_5278_scan", + "5279": "reg_5279_scan", + "5280": "reg_5280_scan", + "5281": "reg_5281_scan", + "5282": "reg_5282_scan", + "5283": "reg_5283_scan", + "5284": "reg_5284_scan", + "5285": "reg_5285_scan", + "5286": "reg_5286_scan", + "5287": "reg_5287_scan", + "5288": "reg_5288_scan", + "5289": "reg_5289_scan", + "5290": "reg_5290_scan", + "5291": "reg_5291_scan", + "5292": "reg_5292_scan", + "5293": "reg_5293_scan", + "5294": "reg_5294_scan", + "5295": "reg_5295_scan", + "5296": "reg_5296_scan", + "5297": "reg_5297_scan", + "5298": "reg_5298_scan", + "5299": "reg_5299_scan", +} + +holding_register = { + "5000": "year", + "5001": "month", + "5002": "day", + "5003": "hour", + "5004": "minute", + "5005": "second" +} + +scan = """{ + "read": [ + { + "start": "4999", + "range": "100" + }, + { + "start": "5099", + "range": "100" + }, + { + "start": "5199", + "range": "100" + }, + { + "start": "13000", + "range": "100" + } + ], + "holding": [ + { + "start": "4999", + "range": "100" + } + ] +}""" + +# Match Modbus registers to pvoutput api fields +# Reference: https://pvoutput.org/help.html#api-addstatus +pvoutput = { + "Energy Generation": "daily_pv_energy", + "Power Generation": "total_pv_power", + "Energy Consumption": "daily_use_energy", + "Power Consumption": "load_power", + "Temperature": "internal_temp", + "Voltage": "grid_voltage" +} diff --git a/modbus-sungrow-sh10rs.py b/modbus-sungrow-sh10rs.py new file mode 100644 index 0000000..a5ae133 --- /dev/null +++ b/modbus-sungrow-sh10rs.py @@ -0,0 +1,129 @@ +""" +The SH10RS has 4 solar inputs, but is only single phase. It appears +that internally it's almost identical to the three-phase hybrid +inverters, as it responds with zero to queries against them. +There are more addresses that contain data, but I didn't investigate +what they actually were. + +Use the modbus-sungrow-scanall.py map to dump all the potential +registers. + +Copyright: Rob Thomas May 2024 + +Licenced under the MIT licence and any additional licence that +the solariot project may be released under. +""" + +read_register = { + "5001": "nominal_active_power_10", + "5002": "output_type", + "5003": "daily_power_yield_0.01", # Wh + "5004": "total_power_yield_100", # MWh, but use 5144 instead + "5006": "total_running_time", + "5008": "internal_temp_10", + "5009": "apparent_power_1000", # From Inverter to Grid/Home + "5011": "pv1_voltage_10", + "5012": "pv1_current_10", + "5013": "pv2_voltage_10", + "5014": "pv2_current_10", + "5015": "pv3_voltage_10", + "5016": "pv3_current_10", # Note pv4 is 5115/5116 + "5017": "total_pv_power", + "5019": "grid_voltage_a_10", + "5020": "grid_voltage_b_10", # V, returns zero + "5021": "grid_voltage_c_10", # V, returns zero + "5022": "inverter_current_a_10", # A + "5023": "inverter_current_b_10", # A, returns zero + "5024": "inverter_current_c_10", # A, returns zero + "5031": "total_active_power", + "5033": "reactive_power", + "5034": "power_factor", + "5035": "real_power_factor", + "5036": "grid_frequency_10", # Use 5148 instead + "5038": "work_state", + "5091": "meter_load_power", + "5115": "pv4_voltage_10", + "5116": "pv4_current_10", + "5144": "total_power_yield_10000", # 0.1kWh > MWh - Higher Accuracy (See: 5004) + "5146": "negative_voltage_to_ground", # 0.1V + "5147": "bus_voltage", # 0.1V + "5148": "grid_frequency_100", # 0.01Hz > Hz - Higher Accuracy (See: 5036) + "13001": "running_state", + "13002": "daily_pv_energy_10", + "13003": "total_pv_energy_10", + "13005": "daily_export_energy_10", + "13006": "total_export_energy_10", + "13008": "load_power", + "13010": "export_power", + "13011": "grid_import_or_export", + "13012": "daily_charge_energy_10", + "13013": "total_charge_energy_10", + "13015": "co2_emission_reduction", + "13017": "daily_use_energy_10", + "13018": "total_use_energy_10", + "13020": "battery_voltage_10", + "13021": "battery_current_10", + "13022": "battery_power", + "13023": "battery_level_10", + "13024": "battery_health_10", + "13025": "battery_temp_10", + "13026": "daily_discharge_energy_10", + "13027": "total_discharge_energy_10", + "13029": "self_consumption_power_today", + "13030": "grid_state", + "13031": "backup_current_a_10", + "13032": "backup_current_b_10", + "13033": "backup_current_c_10", + "13034": "pv_power", + "13035": "total_active_power", + "13036": "daily_import_energy", + "13037": "total_import_energy", + "13038": "battery_capacity" +} + +holding_register = { + "5000": "year", + "5001": "month", + "5002": "day", + "5003": "hour", + "5004": "minute", + "5005": "second" +} + +scan = """{ + "read": [ + { + "start": "4999", + "range": "100" + }, + { + "start": "5099", + "range": "100" + }, + { + "start": "5199", + "range": "100" + }, + { + "start": "13000", + "range": "100" + } + ], + "holding": [ + { + "start": "4999", + "range": "100" + } + ] +}""" + +# Match Modbus registers to pvoutput api fields +# Reference: https://pvoutput.org/help.html#api-addstatus +pvoutput = { + "Energy Generation": "daily_pv_energy", + "Power Generation": "total_pv_power", + "Energy Consumption": "daily_use_energy", + "Power Consumption": "load_power", + "Temperature": "internal_temp", + "Voltage": "grid_voltage" +}