Skip to content

Commit 9795ce7

Browse files
authored
Merge pull request #2172 from TCWORLD/solinteg-models
Add provisional support for Solinteg M2HT model inverters
2 parents fc082e5 + dde741f commit 9795ce7

1 file changed

Lines changed: 209 additions & 23 deletions

File tree

custom_components/solax_modbus/plugin_solinteg.py

Lines changed: 209 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
GEN2 = 0x0002
6464
ALL_GEN_GROUP = GEN2
6565

66-
X1 = 0x0100 # not needed
66+
X1 = 0x0100
6767
X3 = 0x0200
6868
ALL_X_GROUP = X1 | X3
6969

@@ -85,9 +85,9 @@
8585

8686
# 1 is minimum
8787
MPPT2 = 0x40000
88-
MPPT4 = MPPT2 * 2
89-
MPPT_MIN2 = MPPT2 | MPPT4
90-
ALL_MPPT = MPPT2 | MPPT4
88+
MPPT4 = 0x80000
89+
MPPT6 = 0x100000
90+
ALL_MPPT = MPPT2 | MPPT4 | MPPT6
9191

9292
# ALLDEFAULT = 0 # should be equivalent to HYBRID | AC | GEN2 | GEN3 | GEN4 | X1 | X3
9393
ALLDEFAULT = 0 # HYBRID | AC | ALL_X_GROUP
@@ -142,7 +142,7 @@ def _bytes_str(b_array: list[int]) -> str:
142142

143143

144144
def _model_str(val: int) -> str:
145-
# there are models 40,41,42, docu not found
145+
# Mapping based on Solinteg documentation in issue #2158
146146
d = {
147147
30: [
148148
"MHT-4K-25",
@@ -175,6 +175,29 @@ def _model_str(val: int) -> str:
175175
"MHT-40K-100",
176176
"MHT-50K-100",
177177
],
178+
40: [
179+
"M2HT-3K-30",
180+
"M2HT-3.6K-30",
181+
"M2HT-4.2K-30",
182+
"M2HT-4.6K-30",
183+
"M2HT-5K-30",
184+
"M2HT-6K-30",
185+
],
186+
41: [
187+
"M2HT-25K-150",
188+
"M2HT-29.9K-150",
189+
"M2HT-30K-150",
190+
"M2HT-40K-150",
191+
"M2HT-50K-150",
192+
],
193+
43: [
194+
"M2HT-75K-300",
195+
"M2HT-80K-300",
196+
"M2HT-99K-300",
197+
"M2HT-100K-300",
198+
"M2HT-110K-300",
199+
"M2HT-125K-300",
200+
],
178201
}
179202
try:
180203
bh, bl = val // 256, val % 256
@@ -968,7 +991,7 @@ class SolintegModbusSensorEntityDescription(BaseModbusSensorEntityDescription):
968991
key="pv_voltage_2",
969992
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
970993
device_class=SensorDeviceClass.VOLTAGE,
971-
allowedtypes=MPPT_MIN2,
994+
allowedtypes=MPPT2 | MPPT4 | MPPT6,
972995
register=11040,
973996
scale=0.1,
974997
scan_group=SCAN_GROUP_MPPT,
@@ -979,7 +1002,7 @@ class SolintegModbusSensorEntityDescription(BaseModbusSensorEntityDescription):
9791002
key="pv_current_2",
9801003
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
9811004
device_class=SensorDeviceClass.CURRENT,
982-
allowedtypes=MPPT_MIN2,
1005+
allowedtypes=MPPT2 | MPPT4 | MPPT6,
9831006
register=11041,
9841007
scale=0.1,
9851008
scan_group=SCAN_GROUP_MPPT,
@@ -991,7 +1014,7 @@ class SolintegModbusSensorEntityDescription(BaseModbusSensorEntityDescription):
9911014
native_unit_of_measurement=UnitOfPower.WATT,
9921015
device_class=SensorDeviceClass.POWER,
9931016
state_class=SensorStateClass.MEASUREMENT,
994-
allowedtypes=MPPT_MIN2,
1017+
allowedtypes=MPPT2 | MPPT4 | MPPT6,
9951018
register=11064,
9961019
register_data_type=REGISTER_U32,
9971020
scan_group=SCAN_GROUP_MPPT,
@@ -1002,7 +1025,7 @@ class SolintegModbusSensorEntityDescription(BaseModbusSensorEntityDescription):
10021025
key="pv_voltage_3",
10031026
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
10041027
device_class=SensorDeviceClass.VOLTAGE,
1005-
allowedtypes=MPPT4,
1028+
allowedtypes=MPPT4 | MPPT6,
10061029
register=11042,
10071030
scale=0.1,
10081031
scan_group=SCAN_GROUP_MPPT,
@@ -1013,7 +1036,7 @@ class SolintegModbusSensorEntityDescription(BaseModbusSensorEntityDescription):
10131036
key="pv_current_3",
10141037
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
10151038
device_class=SensorDeviceClass.CURRENT,
1016-
allowedtypes=MPPT4,
1039+
allowedtypes=MPPT4 | MPPT6,
10171040
register=11043,
10181041
scale=0.1,
10191042
scan_group=SCAN_GROUP_MPPT,
@@ -1025,7 +1048,7 @@ class SolintegModbusSensorEntityDescription(BaseModbusSensorEntityDescription):
10251048
native_unit_of_measurement=UnitOfPower.WATT,
10261049
device_class=SensorDeviceClass.POWER,
10271050
state_class=SensorStateClass.MEASUREMENT,
1028-
allowedtypes=MPPT4,
1051+
allowedtypes=MPPT4 | MPPT6,
10291052
register=11066,
10301053
register_data_type=REGISTER_U32,
10311054
scan_group=SCAN_GROUP_MPPT,
@@ -1036,7 +1059,7 @@ class SolintegModbusSensorEntityDescription(BaseModbusSensorEntityDescription):
10361059
key="pv_voltage_4",
10371060
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
10381061
device_class=SensorDeviceClass.VOLTAGE,
1039-
allowedtypes=MPPT4,
1062+
allowedtypes=MPPT4 | MPPT6,
10401063
register=11044,
10411064
scale=0.1,
10421065
scan_group=SCAN_GROUP_MPPT,
@@ -1047,7 +1070,7 @@ class SolintegModbusSensorEntityDescription(BaseModbusSensorEntityDescription):
10471070
key="pv_current_4",
10481071
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
10491072
device_class=SensorDeviceClass.CURRENT,
1050-
allowedtypes=MPPT4,
1073+
allowedtypes=MPPT4 | MPPT6,
10511074
register=11045,
10521075
scale=0.1,
10531076
scan_group=SCAN_GROUP_MPPT,
@@ -1059,12 +1082,80 @@ class SolintegModbusSensorEntityDescription(BaseModbusSensorEntityDescription):
10591082
native_unit_of_measurement=UnitOfPower.WATT,
10601083
device_class=SensorDeviceClass.POWER,
10611084
state_class=SensorStateClass.MEASUREMENT,
1062-
allowedtypes=MPPT4,
1085+
allowedtypes=MPPT4 | MPPT6,
10631086
register=11068,
10641087
register_data_type=REGISTER_U32,
10651088
scan_group=SCAN_GROUP_MPPT,
10661089
icon="mdi:solar-power-variant",
10671090
),
1091+
SolintegModbusSensorEntityDescription(
1092+
name="PV Voltage 5",
1093+
key="pv_voltage_5",
1094+
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
1095+
device_class=SensorDeviceClass.VOLTAGE,
1096+
allowedtypes=MPPT6,
1097+
register=11046,
1098+
scale=0.1,
1099+
scan_group=SCAN_GROUP_MPPT,
1100+
icon="mdi:current-dc",
1101+
),
1102+
SolintegModbusSensorEntityDescription(
1103+
name="PV Current 5",
1104+
key="pv_current_5",
1105+
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
1106+
device_class=SensorDeviceClass.CURRENT,
1107+
allowedtypes=MPPT6,
1108+
register=11047,
1109+
scale=0.1,
1110+
scan_group=SCAN_GROUP_MPPT,
1111+
icon="mdi:current-dc",
1112+
),
1113+
SolintegModbusSensorEntityDescription(
1114+
name="PV Power 5",
1115+
key="pv_power_5",
1116+
native_unit_of_measurement=UnitOfPower.WATT,
1117+
device_class=SensorDeviceClass.POWER,
1118+
state_class=SensorStateClass.MEASUREMENT,
1119+
allowedtypes=MPPT6,
1120+
register=11070,
1121+
register_data_type=REGISTER_U32,
1122+
scan_group=SCAN_GROUP_MPPT,
1123+
icon="mdi:solar-power-variant",
1124+
),
1125+
SolintegModbusSensorEntityDescription(
1126+
name="PV Voltage 6",
1127+
key="pv_voltage_6",
1128+
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
1129+
device_class=SensorDeviceClass.VOLTAGE,
1130+
allowedtypes=MPPT6,
1131+
register=11048,
1132+
scale=0.1,
1133+
scan_group=SCAN_GROUP_MPPT,
1134+
icon="mdi:current-dc",
1135+
),
1136+
SolintegModbusSensorEntityDescription(
1137+
name="PV Current 6",
1138+
key="pv_current_6",
1139+
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
1140+
device_class=SensorDeviceClass.CURRENT,
1141+
allowedtypes=MPPT6,
1142+
register=11049,
1143+
scale=0.1,
1144+
scan_group=SCAN_GROUP_MPPT,
1145+
icon="mdi:current-dc",
1146+
),
1147+
SolintegModbusSensorEntityDescription(
1148+
name="PV Power 6",
1149+
key="pv_power_6",
1150+
native_unit_of_measurement=UnitOfPower.WATT,
1151+
device_class=SensorDeviceClass.POWER,
1152+
state_class=SensorStateClass.MEASUREMENT,
1153+
allowedtypes=MPPT6,
1154+
register=11072,
1155+
register_data_type=REGISTER_U32,
1156+
scan_group=SCAN_GROUP_MPPT,
1157+
icon="mdi:solar-power-variant",
1158+
),
10681159
SolintegModbusSensorEntityDescription(
10691160
name="PV Power Total",
10701161
key="pv_power_total",
@@ -1533,6 +1624,7 @@ class SolintegModbusSensorEntityDescription(BaseModbusSensorEntityDescription):
15331624
native_unit_of_measurement=UnitOfPower.WATT,
15341625
device_class=SensorDeviceClass.POWER,
15351626
state_class=SensorStateClass.MEASUREMENT,
1627+
allowedtypes=HYBRID | ALL_EPS_GROUP,
15361628
icon="mdi:home",
15371629
),
15381630
# internal sensors are only used for polling values for selects, etc
@@ -1791,18 +1883,23 @@ async def async_determineInverterType(self, hub: Any, configdict: dict[str, Any]
17911883

17921884
bh, bl = model // 256, model % 256
17931885
invertertype = 0
1794-
if bh in [30, 31, 32]:
1886+
if bh in [30, 31, 32, 40, 41, 43]:
17951887
invertertype = invertertype | HYBRID
17961888

1797-
if bh in [30, 32, 40, 42]:
1889+
if bh in [30, 32, 41, 43]:
17981890
invertertype = invertertype | X3
1891+
else:
1892+
invertertype = invertertype | X1
17991893

1800-
if bh == 30 and bl in [0, 1]:
1894+
if (bh == 31 and bl in [8, 9]) or (bh == 40 and bl == 0):
18011895
mppt = 1
1802-
elif bh == 32:
1896+
elif bh == 43:
1897+
mppt = 6
1898+
invertertype = invertertype | MPPT6
1899+
elif bh in [32, 41]:
18031900
mppt = 4
18041901
invertertype = invertertype | MPPT4
1805-
else: # bh == 31, other 30...
1902+
else:
18061903
mppt = 2
18071904
invertertype = invertertype | MPPT2
18081905

@@ -1862,20 +1959,109 @@ def getHardwareVersion(self, new_data: dict[str, Any]) -> str | None:
18621959
ENERGY_DASHBOARD_MAPPING = EnergyDashboardMapping(
18631960
plugin_name="solinteg",
18641961
mappings=[
1962+
# ===== SOC SENSOR =====
1963+
# Battery SoC %
1964+
EnergyDashboardSensorMapping(
1965+
source_key="battery_soc",
1966+
target_key="battery_soc",
1967+
name="Battery SoC",
1968+
),
1969+
# ===== POWER SENSORS =====
1970+
# Grid Power
18651971
EnergyDashboardSensorMapping(
18661972
source_key="measured_power",
1867-
source_key_pm=None, # measured_power is system-wide
18681973
target_key="grid_power",
18691974
name="Grid Power",
18701975
invert=True,
18711976
icon="mdi:transmission-tower",
18721977
),
1978+
# Solar Power
1979+
EnergyDashboardSensorMapping(
1980+
source_key="pv_power_total",
1981+
target_key="solar_power",
1982+
name="Solar Power",
1983+
),
1984+
# PV Variant Power
1985+
EnergyDashboardSensorMapping(
1986+
source_key="pv_power_{n}",
1987+
target_key="pv_power_{n}",
1988+
name="PV Power {n}",
1989+
),
1990+
# Battery Power
18731991
EnergyDashboardSensorMapping(
1874-
source_key="battery_power", # Note: plugin_solinteg uses battery_power (not battery_power_charge)
1875-
source_key_pm=None, # No parallel mode support in this plugin
1992+
source_key="battery_power",
18761993
target_key="battery_power",
18771994
name="Battery Power",
1878-
invert=True,
1995+
),
1996+
# Home Consumption Power
1997+
EnergyDashboardSensorMapping(
1998+
source_key="house_total_load",
1999+
target_key="home_consumption_power",
2000+
name="Home Consumption Power",
2001+
),
2002+
# Grid to Battery Power (TODO)
2003+
# EnergyDashboardSensorMapping(
2004+
# source_key="inverter_power",
2005+
# target_key="grid_to_battery_power",
2006+
# name="Grid to Battery Power",
2007+
# filter_function=lambda v: max(0 - v, 0),
2008+
# icon="mdi:transmission-tower-export",
2009+
# ),
2010+
# ===== ENERGY SENSORS =====
2011+
# PV Variant Energy (per string).
2012+
EnergyDashboardSensorMapping(
2013+
source_key="pv_power_{n}",
2014+
target_key="pv_energy_{n}",
2015+
name="PV Energy {n}",
2016+
use_riemann_sum=True,
2017+
filter_function=lambda v: max(0, v),
2018+
),
2019+
# Grid Import Energy
2020+
EnergyDashboardSensorMapping(
2021+
source_key="grid_import_today",
2022+
target_key="grid_energy_import",
2023+
name="Grid Import Energy",
2024+
),
2025+
# Grid Export Energy
2026+
EnergyDashboardSensorMapping(
2027+
source_key="grid_export_today",
2028+
target_key="grid_energy_export",
2029+
name="Grid Export Energy",
2030+
),
2031+
# Home Consumption Energy
2032+
# The 'house_energy_today' sensor does not provide valid information
2033+
# on some inverters, so use riemann sum of house load power.
2034+
EnergyDashboardSensorMapping(
2035+
source_key="house_load_total",
2036+
target_key="home_consumption_energy",
2037+
name="Home Consumption Energy",
2038+
use_riemann_sum=True,
2039+
filter_function=lambda v: max(0, v),
2040+
),
2041+
# Battery Charge Energy
2042+
EnergyDashboardSensorMapping(
2043+
source_key="battery_charge_today",
2044+
target_key="battery_energy_charge",
2045+
name="Battery Charge Energy",
2046+
),
2047+
# Battery Discharge Energy
2048+
EnergyDashboardSensorMapping(
2049+
source_key="battery_discharge_today",
2050+
target_key="battery_energy_discharge",
2051+
name="Battery Discharge Energy",
2052+
),
2053+
# Grid to Battery Energy (TODO)
2054+
# EnergyDashboardSensorMapping(
2055+
# source_key="e_charge_today",
2056+
# target_key="grid_to_battery_energy",
2057+
# name="Grid to Battery Energy",
2058+
# icon="mdi:transmission-tower-export",
2059+
# ),
2060+
# Solar Production Energy
2061+
EnergyDashboardSensorMapping(
2062+
source_key="energy_generation_today",
2063+
target_key="solar_energy_production",
2064+
name="Solar Production Energy",
18792065
),
18802066
],
18812067
parallel_mode_supported=False, # Plugin doesn't support parallel mode

0 commit comments

Comments
 (0)