Skip to content

Commit 4b2b0de

Browse files
authored
DT Series Updates (#115)
1 parent 32c9871 commit 4b2b0de

6 files changed

Lines changed: 68 additions & 33 deletions

File tree

VERSION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0.0.0-dev

goodwe/const.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,3 +333,9 @@
333333
1: 'Active power derating',
334334
0: 'Overtemperature derating',
335335
}
336+
337+
METER_COMMUNICATION_STATUS: dict[int, str] = {
338+
0: '',
339+
1: 'Normal',
340+
2: 'Disconnected',
341+
}

goodwe/dt.py

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ class DT(Inverter):
5757
"W",
5858
Kind.PV,
5959
),
60-
# Voltage("vpv4", 14, "PV4 Voltage", Kind.PV),
61-
# Current("ipv4", 16, "PV4 Current", Kind.PV),
62-
# Voltage("vpv5", 14, "PV5 Voltage", Kind.PV),
63-
# Current("ipv5", 16, "PV5 Current", Kind.PV),
64-
# Voltage("vpv6", 14, "PV6 Voltage", Kind.PV),
65-
# Current("ipv6", 16, "PV7 Current", Kind.PV),
60+
# Voltage("vpv4", 30109, "PV4 Voltage", Kind.PV),
61+
# Current("ipv4", 30110, "PV4 Current", Kind.PV),
62+
# Voltage("vpv5", 30111, "PV5 Voltage", Kind.PV),
63+
# Current("ipv5", 30112, "PV5 Current", Kind.PV),
64+
# Voltage("vpv6", 30113, "PV6 Voltage", Kind.PV),
65+
# Current("ipv6", 30114, "PV7 Current", Kind.PV),
6666
Voltage("vline1", 30115, "On-grid L1-L2 Voltage", Kind.AC),
6767
Voltage("vline2", 30116, "On-grid L2-L3 Voltage", Kind.AC),
6868
Voltage("vline3", 30117, "On-grid L3-L1 Voltage", Kind.AC),
@@ -103,8 +103,7 @@ class DT(Inverter):
103103
Integer("warning_code", 30132, "Warning code"),
104104
Apparent4("apparent_power", 30133, "Apparent Power", Kind.AC),
105105
Reactive4("reactive_power", 30135, "Reactive Power", Kind.AC),
106-
# 30137 reserved
107-
PowerS("total_input_power", 30138, "Total Input Power", Kind.PV),
106+
PowerS("total_input_power", 30137, "Total Input Power", Kind.PV),
108107
Decimal("power_factor", 30139, 1000, "Power Factor", "", Kind.GRID),
109108
# 30140 inverter efficiency
110109
Temp("temperature", 30141, "Inverter Temperature", Kind.AC),
@@ -117,29 +116,29 @@ class DT(Inverter):
117116
Enum2(
118117
"safety_country_label", 30149, SAFETY_COUNTRIES, "Safety Country", Kind.AC
119118
),
120-
# 30150 reserved
121-
# 30151 reserved
122-
# 30152 reserved
123-
# 30153 reserved
124-
# 30154 reserved
125-
# 30155 reserved
126-
# 30156 reserved
127-
# 30157 reserved
128-
# 30158 reserved
129-
# 30159 reserved
130-
# 30160 reserved
131-
# 30161 reserved
119+
# 30150 PV1 input power kW
120+
# 30152 PV2 input power kW
121+
# 30154 PV3 input power kW
122+
# 30156 PV4 input power kW
123+
# 30158 PV5 input power kW
124+
# 30160 PV6 input power kW
132125
Integer("funbit", 30162, "FunctionBit", "", Kind.PV),
133126
Voltage("vbus", 30163, "Bus Voltage", Kind.PV),
134127
Voltage("vnbus", 30164, "NBus Voltage", Kind.PV),
135128
Long("derating_mode", 30165, "Derating Mode code"),
136129
EnumBitmap4("derating_mode_label", 30165, DERATING_MODE_CODES, "Derating Mode"),
137-
# 30167 reserved
138-
# 30168 reserved
139-
# 30169 reserved
140-
# 30170 reserved
141-
# 30171 reserved
130+
# 30167 PV2 fault value
131+
# 30168 Line2 fault value
132+
# 30169 Line3 fault value
133+
# 30170 Line3 fault value (duplicate commentary in modbus protocol document)
134+
# 30171 Manufacture ID
142135
Integer("rssi", 30172, "RSSI"),
136+
# 30173 ISO test value
137+
# 30174 PID and Wietap status
138+
# 30175 String 1 Current
139+
# 30176 String 2 Current
140+
# 30177 String 3 Current
141+
# 30178 - 30194 listed String 4 Current through to String 20 Current
143142
)
144143

145144
# Inverter's meter data
@@ -148,9 +147,24 @@ class DT(Inverter):
148147
Power4S("meter_active_power", 30195, "Meter Active Power", Kind.GRID),
149148
Energy4W("meter_e_total_exp", 30197, "Meter Total Energy (export)", Kind.GRID),
150149
Energy4W("meter_e_total_imp", 30199, "Meter Total Energy (import)", Kind.GRID),
151-
Integer(
152-
"meter_comm_status", 30209, "Meter Communication Status"
153-
), # 1 OK, 0 NotOK
150+
# 30201 GPRS Burn Mode
151+
# 30202 Cabinet Humidity %
152+
# 30203 ARM Error Message
153+
# 30205 Warning Code 2
154+
# 30207 AFCI Status
155+
# 30208 Output control status - Japanese models only
156+
Integer("meter_comm_status", 30209, "Meter Communication Status code"), # 1 Normal, 2 Disconnected
157+
Enum2("meter_comm_label", 30209, METER_COMMUNICATION_STATUS, "Meter Communication Status"),
158+
Calculated("house_consumption", lambda data: None, "House Consumption", "W", Kind.AC), # calculated and patched in read_runtime_data as we are unable to calculate it from seperate modbus offsets in all_sensors and all_sensors_meter
159+
CurrentSmA("leakage_current", 30210, "Leakage Current", Kind.PV),
160+
# 30211 repeat of 30197 in U64 instead of U32
161+
# 30215 repeat of 30199 in U64 instead of U32
162+
# 30219 Wireless Module AT Instruction Status Log
163+
# 30220 Disable Inverter Flag - 0 for normal operation, 1 for inverter disabled until safety regulations changed
164+
# 30221 ARM Internal Firmware Version
165+
# 30227 G100 CLS State (UK anti-reflux status)
166+
# 30228 Grid power monitored by DSPs CT (S32)
167+
# 30230 String Current Detection Flag - 0 No string current detected, 1 String current detected
154168
)
155169

156170
# Modbus registers of inverter settings, offsets are modbus register addresses
@@ -159,9 +173,8 @@ class DT(Inverter):
159173
Integer("shadow_scan_pv1", 40326, "Shadow Scan Status PV1", "", Kind.PV),
160174
Integer("shadow_scan_pv2", 40352, "Shadow Scan Status PV2", "", Kind.PV),
161175
Integer("shadow_scan_pv3", 40362, "Shadow Scan Status PV3", "", Kind.PV),
162-
Integer("shadow_scan_pv1_time", 40347, "Shadow Scan PV1 Time", "", Kind.PV),
163-
Integer("shadow_scan_pv2_time", 40353, "Shadow Scan PV2 Time", "", Kind.PV),
164-
# Integer("shadow_scan_pv3_time", 40xxx, "Shadow Scan PV3 Time", "", Kind.PV), #TBC
176+
Integer("shadow_scan_time", 40347, "Shadow Scan Time", "", Kind.PV),
177+
# Integer("shadow_scan_pv2_time", 40353, "Shadow Scan PV2 Time", "", Kind.PV), - documentation suggests a duplicate of 40347 as the value is global for all 3 strings
165178
Integer("grid_export", 40327, "Grid Export Limit Enabled", "", Kind.GRID),
166179
Integer("grid_export_limit", 40328, "Grid Export Limit", "%", Kind.GRID),
167180
Integer("start", 40330, "Start / Power On", "", Kind.GRID),
@@ -268,6 +281,8 @@ async def read_runtime_data(self) -> dict[str, Any]:
268281
try:
269282
response = await self._read_from_socket(self._READ_METER_DATA)
270283
data.update(self._map_response(response, self._sensors_meter))
284+
#patch house_consumption int from all_sensors_meter now that we have values available
285+
data["house_consumption"] = abs(data.get("ppv", 0) - data.get("meter_active_power", 0))
271286
except (RequestRejectedException, RequestFailedException):
272287
logger.info("Meter values not supported, disabling further attempts.")
273288
self._has_meter = False

goodwe/sensor.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,19 @@ def encode_value(self, value: Any, register_value: bytes = None) -> bytes:
120120
return encode_current_signed(value)
121121

122122

123+
class CurrentSmA(Sensor):
124+
"""Sensor representing current [mA] value encoded in 2 (signed) bytes"""
125+
126+
def __init__(self, id_: str, offset: int, name: str, kind: Optional[SensorKind]):
127+
super().__init__(id_, offset, name, 2, "mA", kind)
128+
129+
def read_value(self, data: ProtocolResponse):
130+
return read_current_signed(data)
131+
132+
def encode_value(self, value: Any, register_value: bytes = None) -> bytes:
133+
return encode_current_signed(value)
134+
135+
123136
class Frequency(Sensor):
124137
"""Sensor representing frequency [Hz] value encoded in 2 bytes"""
125138

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ long_description_content_type = text/markdown
66
version = file: VERSION
77
keywords = GoodWe, Solar Panel, Inverter, Photovoltaics, PV
88
license = MIT
9+
license_files = LICENSE
910
author = Martin Letenay, Marcel Blijleven
1011
author_email = [email protected]
1112
url = https://github.com/marcelblijleven/goodwe
1213
classifiers =
1314
Development Status :: 5 - Production/Stable
1415
Intended Audience :: Developers
1516
Topic :: Software Development :: Libraries :: Python Modules
16-
License :: OSI Approved :: MIT License
1717
Programming Language :: Python :: 3
1818
Programming Language :: Python :: 3.8
1919
Programming Language :: Python :: 3.9

tests/test_dt.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def test_GW6000_DT_runtime_data(self):
114114
self.assertFalse(self.sensor_map, f"Some sensors were not tested {self.sensor_map}")
115115

116116
def test_GW6000_DT_setting(self):
117-
self.assertEqual(12, len(self.settings()))
117+
self.assertEqual(11, len(self.settings()))
118118
settings = {s.id_: s for s in self.settings()}
119119
self.assertEqual('Timestamp', type(settings.get("time")).__name__)
120120
self.assertEqual('Integer', type(settings.get("grid_export")).__name__)

0 commit comments

Comments
 (0)