11import logging
2- from dataclasses import dataclass
2+ from dataclasses import dataclass , replace
33from typing import Any
44
55from homeassistant .components .number import NumberDeviceClass
9494MPPT10 = 0x400000
9595ALL_MPPT_GROUP = MPPT3 | MPPT4 | MPPT6 | MPPT8 | MPPT10
9696
97+ # DLP MID 30KTL3-XH units expose BMS1 module 1 through the APX input-register block.
98+ APX_BMS_INPUT = 0x800000
99+ ALL_APX_BMS_REGISTER_GROUP = APX_BMS_INPUT
100+
101+ APX_BMS_INPUT_SERIAL_PREFIXES = ["DLP" ]
102+
97103ALLDEFAULT = 0 # should be equivalent to HYBRID | AC | GEN | GEN2 | GEN3 | GEN4 | X1 | X3
98104
99105# SPF models known to expose only one PV input / MPPT even if the generic SPF block defines PV2 sensors.
@@ -6695,6 +6701,7 @@ def value_function_inverter_module(initval: int, descr: Any, datadict: dict[str,
66956701 scale = value_function_module_status ,
66966702 allowedtypes = HYBRID | GEN4 ,
66976703 entity_registry_enabled_default = False ,
6704+ blacklist = APX_BMS_INPUT_SERIAL_PREFIXES ,
66986705 icon = "mdi:battery" ,
66996706 ),
67006707 GrowattModbusSensorEntityDescription (
@@ -6716,10 +6723,11 @@ def value_function_inverter_module(initval: int, descr: Any, datadict: dict[str,
67166723 device_class = SensorDeviceClass .BATTERY ,
67176724 state_class = SensorStateClass .MEASUREMENT ,
67186725 register = 5882 ,
6719- register_type = REG_HOLDING , ### HOLDING!!!
6726+ register_type = REG_HOLDING ,
67206727 register_data_type = REGISTER_U16 ,
67216728 allowedtypes = HYBRID | GEN4 ,
67226729 entity_registry_enabled_default = False ,
6730+ blacklist = APX_BMS_INPUT_SERIAL_PREFIXES ,
67236731 icon = "mdi:battery-heart" ,
67246732 ),
67256733 GrowattModbusSensorEntityDescription (
@@ -6729,11 +6737,12 @@ def value_function_inverter_module(initval: int, descr: Any, datadict: dict[str,
67296737 device_class = SensorDeviceClass .VOLTAGE ,
67306738 state_class = SensorStateClass .MEASUREMENT ,
67316739 register = 5883 ,
6732- register_type = REG_HOLDING , ### HOLDING!!!
6740+ register_type = REG_HOLDING ,
67336741 register_data_type = REGISTER_U16 ,
67346742 scale = 0.1 ,
67356743 allowedtypes = GEN4 | HYBRID ,
67366744 entity_registry_enabled_default = False ,
6745+ blacklist = APX_BMS_INPUT_SERIAL_PREFIXES ,
67376746 icon = "mdi:battery" ,
67386747 ),
67396748 GrowattModbusSensorEntityDescription (
@@ -6743,11 +6752,12 @@ def value_function_inverter_module(initval: int, descr: Any, datadict: dict[str,
67436752 device_class = SensorDeviceClass .CURRENT ,
67446753 state_class = SensorStateClass .MEASUREMENT ,
67456754 register = 5884 ,
6746- register_type = REG_HOLDING , ### HOLDING!!!
6755+ register_type = REG_HOLDING ,
67476756 register_data_type = REGISTER_U16 ,
67486757 scale = value_function_bms_module_combined_current ,
67496758 allowedtypes = GEN4 | HYBRID ,
67506759 entity_registry_enabled_default = False ,
6760+ blacklist = APX_BMS_INPUT_SERIAL_PREFIXES ,
67516761 icon = "mdi:battery" ,
67526762 ),
67536763 GrowattModbusSensorEntityDescription (
@@ -6762,6 +6772,7 @@ def value_function_inverter_module(initval: int, descr: Any, datadict: dict[str,
67626772 register_data_type = REGISTER_U16 ,
67636773 entity_registry_enabled_default = True ,
67646774 allowedtypes = GEN4 | HYBRID ,
6775+ blacklist = APX_BMS_INPUT_SERIAL_PREFIXES ,
67656776 icon = "mdi:battery" ,
67666777 ),
67676778 GrowattModbusSensorEntityDescription (
@@ -6771,11 +6782,12 @@ def value_function_inverter_module(initval: int, descr: Any, datadict: dict[str,
67716782 device_class = SensorDeviceClass .ENERGY ,
67726783 state_class = SensorStateClass .TOTAL_INCREASING ,
67736784 register = 5887 , # maybe 5886 and U32
6774- register_type = REG_HOLDING , ### HOLDING!!!
6785+ register_type = REG_HOLDING ,
67756786 register_data_type = REGISTER_U16 , # maybe U32 but then change register to 5886
67766787 scale = 0.1 ,
67776788 allowedtypes = GEN4 | HYBRID ,
67786789 entity_registry_enabled_default = False ,
6790+ blacklist = APX_BMS_INPUT_SERIAL_PREFIXES ,
67796791 icon = "mdi:battery" ,
67806792 ),
67816793 GrowattModbusSensorEntityDescription (
@@ -6790,6 +6802,7 @@ def value_function_inverter_module(initval: int, descr: Any, datadict: dict[str,
67906802 scale = 0.1 ,
67916803 allowedtypes = GEN4 | HYBRID ,
67926804 entity_registry_enabled_default = False ,
6805+ blacklist = APX_BMS_INPUT_SERIAL_PREFIXES ,
67936806 icon = "mdi:battery" ,
67946807 ),
67956808 GrowattModbusSensorEntityDescription (
@@ -6804,6 +6817,7 @@ def value_function_inverter_module(initval: int, descr: Any, datadict: dict[str,
68046817 scale = 0.1 ,
68056818 allowedtypes = GEN4 | HYBRID ,
68066819 entity_registry_enabled_default = False ,
6820+ blacklist = APX_BMS_INPUT_SERIAL_PREFIXES ,
68076821 icon = "mdi:battery" ,
68086822 ),
68096823 GrowattModbusSensorEntityDescription (
@@ -6815,6 +6829,7 @@ def value_function_inverter_module(initval: int, descr: Any, datadict: dict[str,
68156829 scale = value_function_module_warning_text ,
68166830 allowedtypes = HYBRID | GEN4 ,
68176831 entity_registry_enabled_default = False ,
6832+ blacklist = APX_BMS_INPUT_SERIAL_PREFIXES ,
68186833 icon = "mdi:battery" ,
68196834 ),
68206835 GrowattModbusSensorEntityDescription (
@@ -6825,6 +6840,7 @@ def value_function_inverter_module(initval: int, descr: Any, datadict: dict[str,
68256840 register_data_type = REGISTER_U16 ,
68266841 allowedtypes = GEN4 | HYBRID ,
68276842 entity_registry_enabled_default = False ,
6843+ blacklist = APX_BMS_INPUT_SERIAL_PREFIXES ,
68286844 icon = "mdi:battery" ,
68296845 ),
68306846 GrowattModbusSensorEntityDescription (
@@ -9174,6 +9190,33 @@ def value_function_inverter_module(initval: int, descr: Any, datadict: dict[str,
91749190 ),
91759191]
91769192
9193+ APX_BMS1_MODULE1_INPUT_REGISTERS = {
9194+ "bms_1_module_1_status" : 5080 ,
9195+ "bms_1_module_1_soh" : 5082 ,
9196+ "bms_1_module_1_volt" : 5083 ,
9197+ "bms_1_module_1_combined_current" : 5084 ,
9198+ "bms_1_module_1_combined_power" : 5085 ,
9199+ "bms_1_module_1_toe" : 5087 ,
9200+ "bms_1_module_1_max_cell_temp" : 5090 ,
9201+ "bms_1_module_1_min_cell_temp" : 5091 ,
9202+ "bms_1_module_1_warning_text" : 5098 ,
9203+ "bms_1_module_1_charge_cycles" : 5108 ,
9204+ }
9205+
9206+ # Keep the established 588x holding-register descriptions for other Growatt models,
9207+ # and create a DLP-only 508x input-register variant from the same metadata.
9208+ SENSOR_TYPES .extend (
9209+ replace (
9210+ description ,
9211+ register = APX_BMS1_MODULE1_INPUT_REGISTERS [description .key ],
9212+ register_type = REG_INPUT ,
9213+ allowedtypes = description .allowedtypes | APX_BMS_INPUT ,
9214+ blacklist = None ,
9215+ )
9216+ for description in tuple (SENSOR_TYPES )
9217+ if description .key in APX_BMS1_MODULE1_INPUT_REGISTERS
9218+ )
9219+
91779220
91789221TIME_TYPES = [
91799222 GrowattModbusTimeEntityDescription (
@@ -9684,7 +9727,7 @@ def value_function_inverter_module(initval: int, descr: Any, datadict: dict[str,
96849727 "KMN" : HYBRID | GEN4 | X3 , # MID 17000 TL3-XH Hybrid, 2 MPPT
96859728 "KNN" : HYBRID | GEN4 | X3 | MPPT3 , # MID 25000 TL3-XH Hybrid, 3 MPPT
96869729 "RKM" : HYBRID | GEN4 | X3 | MPPT3 , # MID 30000 TL3-XH Hybrid, 3 MPPT
9687- "DLP" : HYBRID | GEN4 | X3 | MPPT3 , # MID 30000 TL3-XH Hybrid, 3 MPPT
9730+ "DLP" : HYBRID | GEN4 | X3 | MPPT3 | APX_BMS_INPUT , # MID 30000 TL3-XH Hybrid, 3 MPPT
96889731 # MOD BP hybrid
96899732 "FMP" : HYBRID | GEN4 | X3 , # MOD 5000 TL3-XH (BP) Hybrid, 2 MPPT
96909733 "FPP" : HYBRID | GEN4 | X3 , # MOD 7000 TL3-XH (BP) Hybrid, 2 MPPT
@@ -9825,12 +9868,13 @@ def matchInverterWithMask(
98259868 epsmatch = ((inverterspec & entitymask & ALL_EPS_GROUP ) != 0 ) or (entitymask & ALL_EPS_GROUP == 0 )
98269869 dcbmatch = ((inverterspec & entitymask & ALL_DCB_GROUP ) != 0 ) or (entitymask & ALL_DCB_GROUP == 0 )
98279870 mpptmatch = ((inverterspec & entitymask & ALL_MPPT_GROUP ) != 0 ) or (entitymask & ALL_MPPT_GROUP == 0 )
9871+ apx_bms_register_match = ((inverterspec & entitymask & ALL_APX_BMS_REGISTER_GROUP ) != 0 ) or (entitymask & ALL_APX_BMS_REGISTER_GROUP == 0 )
98289872 blacklisted = False
98299873 if blacklist :
98309874 for start in blacklist :
98319875 if serialnumber .startswith (start ):
98329876 blacklisted = True
9833- return (genmatch and xmatch and hybmatch and epsmatch and dcbmatch and mpptmatch ) and not blacklisted
9877+ return (genmatch and xmatch and hybmatch and epsmatch and dcbmatch and mpptmatch and apx_bms_register_match ) and not blacklisted
98349878
98359879
98369880ENERGY_DASHBOARD_MAPPING = EnergyDashboardMapping (
0 commit comments