Skip to content

Commit dcb47b5

Browse files
committed
Add profile helpers module to fix broken import chain
Created helpers.py with reusable register map building functions: - merge_register_maps() for combining register dictionaries - create_base_registers() for common PV/AC registers - create_diagnostic_registers() for fault/warning codes - create_temperature_registers() for temperature sensors - Additional helpers for PV3, battery, and 3-phase systems This fixes the import errors in profile stub files (sph.py, spa.py, tl_xh.py, mod.py, max.py, mac.py, mix.py, wit.py, sph_tl3.py) that were attempting to import .helpers module. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent d4a3b76 commit dcb47b5

1 file changed

Lines changed: 128 additions & 0 deletions

File tree

  • custom_components/growatt_modbus/profiles
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
"""Helper functions for building Growatt inverter profile register maps.
2+
3+
These helpers reduce repetition across profiles by providing common register sets.
4+
"""
5+
6+
from typing import Dict, Any
7+
8+
9+
def merge_register_maps(*maps: Dict[str, Any]) -> Dict[str, Any]:
10+
"""Merge multiple register maps into one.
11+
12+
Args:
13+
*maps: Variable number of register map dictionaries
14+
15+
Returns:
16+
Combined dictionary with all registers
17+
"""
18+
result = {}
19+
for map_dict in maps:
20+
result.update(map_dict)
21+
return result
22+
23+
24+
def create_base_registers() -> Dict[str, Any]:
25+
"""Create common base registers found in all inverters.
26+
27+
Returns:
28+
Dictionary of basic PV input and AC output registers
29+
"""
30+
return {
31+
"status": {"address": 0, "type": "holding", "scale": 1, "unit": ""},
32+
"pv1_voltage": {"address": 3, "type": "holding", "scale": 0.1, "unit": "V"},
33+
"pv1_current": {"address": 4, "type": "holding", "scale": 0.1, "unit": "A"},
34+
"pv1_power": {"address": 5, "type": "holding", "scale": 0.1, "unit": "W"},
35+
"pv2_voltage": {"address": 7, "type": "holding", "scale": 0.1, "unit": "V"},
36+
"pv2_current": {"address": 8, "type": "holding", "scale": 0.1, "unit": "A"},
37+
"pv2_power": {"address": 9, "type": "holding", "scale": 0.1, "unit": "W"},
38+
"ac_voltage": {"address": 38, "type": "holding", "scale": 0.1, "unit": "V"},
39+
"ac_current": {"address": 39, "type": "holding", "scale": 0.1, "unit": "A"},
40+
"ac_power": {"address": 40, "type": "holding", "scale": 0.1, "unit": "W"},
41+
"ac_frequency": {"address": 37, "type": "holding", "scale": 0.01, "unit": "Hz"},
42+
"energy_today": {"address": 53, "type": "holding", "scale": 0.1, "unit": "kWh"},
43+
"energy_total": {"address": 55, "type": "holding", "scale": 0.1, "unit": "kWh"},
44+
}
45+
46+
47+
def create_diagnostic_registers() -> Dict[str, Any]:
48+
"""Create common diagnostic registers for fault/warning codes.
49+
50+
Returns:
51+
Dictionary of diagnostic registers
52+
"""
53+
return {
54+
"fault_code": {"address": 105, "type": "holding", "scale": 1, "unit": ""},
55+
"warning_code": {"address": 112, "type": "holding", "scale": 1, "unit": ""},
56+
"derating_mode": {"address": 104, "type": "holding", "scale": 1, "unit": ""},
57+
}
58+
59+
60+
def create_temperature_registers() -> Dict[str, Any]:
61+
"""Create common temperature sensor registers.
62+
63+
Returns:
64+
Dictionary of temperature registers
65+
"""
66+
return {
67+
"inverter_temp": {"address": 93, "type": "holding", "scale": 0.1, "unit": "°C"},
68+
"ipm_temp": {"address": 94, "type": "holding", "scale": 0.1, "unit": "°C"},
69+
"boost_temp": {"address": 95, "type": "holding", "scale": 0.1, "unit": "°C"},
70+
}
71+
72+
73+
def create_pv3_registers() -> Dict[str, Any]:
74+
"""Create PV3 string registers for 3-string inverters.
75+
76+
Returns:
77+
Dictionary of PV3 registers
78+
"""
79+
return {
80+
"pv3_voltage": {"address": 11, "type": "holding", "scale": 0.1, "unit": "V"},
81+
"pv3_current": {"address": 12, "type": "holding", "scale": 0.1, "unit": "A"},
82+
"pv3_power": {"address": 13, "type": "holding", "scale": 0.1, "unit": "W"},
83+
}
84+
85+
86+
def create_battery_registers() -> Dict[str, Any]:
87+
"""Create battery storage registers for hybrid inverters.
88+
89+
Returns:
90+
Dictionary of battery registers
91+
"""
92+
return {
93+
"battery_voltage": {"address": 13, "type": "holding", "scale": 0.1, "unit": "V"},
94+
"battery_current": {"address": 14, "type": "holding", "scale": 0.1, "unit": "A"},
95+
"battery_power": {"address": 15, "type": "holding", "scale": 1, "unit": "W", "signed": True},
96+
"battery_soc": {"address": 17, "type": "holding", "unit": "%"},
97+
"battery_temp": {"address": 18, "type": "holding", "scale": 0.1, "unit": "°C"},
98+
}
99+
100+
101+
def create_three_phase_registers() -> Dict[str, Any]:
102+
"""Create three-phase AC registers.
103+
104+
Returns:
105+
Dictionary of 3-phase AC registers
106+
"""
107+
return {
108+
"ac_voltage_r": {"address": 38, "type": "holding", "scale": 0.1, "unit": "V"},
109+
"ac_voltage_s": {"address": 42, "type": "holding", "scale": 0.1, "unit": "V"},
110+
"ac_voltage_t": {"address": 46, "type": "holding", "scale": 0.1, "unit": "V"},
111+
"ac_current_r": {"address": 39, "type": "holding", "scale": 0.1, "unit": "A"},
112+
"ac_current_s": {"address": 43, "type": "holding", "scale": 0.1, "unit": "A"},
113+
"ac_current_t": {"address": 47, "type": "holding", "scale": 0.1, "unit": "A"},
114+
"ac_power_r": {"address": 40, "type": "holding", "scale": 0.1, "unit": "W"},
115+
"ac_power_s": {"address": 44, "type": "holding", "scale": 0.1, "unit": "W"},
116+
"ac_power_t": {"address": 48, "type": "holding", "scale": 0.1, "unit": "W"},
117+
}
118+
119+
120+
__all__ = [
121+
"merge_register_maps",
122+
"create_base_registers",
123+
"create_diagnostic_registers",
124+
"create_temperature_registers",
125+
"create_pv3_registers",
126+
"create_battery_registers",
127+
"create_three_phase_registers",
128+
]

0 commit comments

Comments
 (0)