Skip to content

Commit

Permalink
Fix decoding of energy values
Browse files Browse the repository at this point in the history
Enrgy sensors are always encoded as unsigned values.
  • Loading branch information
mletenay committed Apr 9, 2024
1 parent 71c79a9 commit f41674c
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 24 deletions.
4 changes: 2 additions & 2 deletions goodwe/es.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class ES(Inverter):
Voltage("vgrid", 34, "On-grid Voltage", Kind.AC),
Current("igrid", 36, "On-grid Current", Kind.AC),
Calculated("pgrid",
lambda data: abs(read_bytes2(data, 38)) * (-1 if read_byte(data, 80) == 2 else 1),
lambda data: abs(read_bytes2_signed(data, 38)) * (-1 if read_byte(data, 80) == 2 else 1),
"On-grid Export Power", "W", Kind.AC),
Frequency("fgrid", 40, "On-grid Frequency", Kind.AC),
Byte("grid_mode", 42, "Work Mode code", "", Kind.GRID),
Expand Down Expand Up @@ -121,7 +121,7 @@ class ES(Inverter):
round(read_voltage(data, 5) * read_current(data, 7)) +
(abs(round(read_voltage(data, 10) * read_current(data, 18))) *
(-1 if read_byte(data, 30) == 3 else 1)) -
(abs(read_bytes2(data, 38)) * (-1 if read_byte(data, 80) == 2 else 1)),
(abs(read_bytes2_signed(data, 38)) * (-1 if read_byte(data, 80) == 2 else 1)),
"House Consumption", "W", Kind.AC),
)

Expand Down
2 changes: 1 addition & 1 deletion goodwe/et.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class ET(Inverter):
read_bytes4(data, 35113) +
read_bytes4(data, 35117) +
read_bytes4_signed(data, 35182) -
read_bytes2(data, 35140),
read_bytes2_signed(data, 35140),
"House Consumption", "W", Kind.AC),
)

Expand Down
38 changes: 20 additions & 18 deletions goodwe/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def __init__(self, id_: str, offset: int, name: str, kind: Optional[SensorKind])
super().__init__(id_, offset, name, 2, "W", kind)

def read_value(self, data: ProtocolResponse):
return read_bytes2(data)
return read_bytes2_signed(data)


class Power4(Sensor):
Expand Down Expand Up @@ -169,10 +169,7 @@ def __init__(self, id_: str, offset: int, name: str, kind: Optional[SensorKind])

def read_value(self, data: ProtocolResponse):
value = read_bytes2(data)
if value == -1:
return None
else:
return float(value) / 10
return float(value) / 10


class Energy4(Sensor):
Expand All @@ -182,11 +179,8 @@ def __init__(self, id_: str, offset: int, name: str, kind: Optional[SensorKind])
super().__init__(id_, offset, name, 4, "kWh", kind)

def read_value(self, data: ProtocolResponse):
value = read_bytes4_signed(data)
if value == -1:
return None
else:
return float(value) / 10
value = read_bytes4(data)
return float(value) / 10


class Apparent(Sensor):
Expand All @@ -196,7 +190,7 @@ def __init__(self, id_: str, offset: int, name: str, kind: Optional[SensorKind])
super().__init__(id_, offset, name, 2, "VA", kind)

def read_value(self, data: ProtocolResponse):
return read_bytes2(data)
return read_bytes2_signed(data)


class Apparent4(Sensor):
Expand All @@ -216,7 +210,7 @@ def __init__(self, id_: str, offset: int, name: str, kind: Optional[SensorKind])
super().__init__(id_, offset, name, 2, "var", kind)

def read_value(self, data: ProtocolResponse):
return read_bytes2(data)
return read_bytes2_signed(data)


class Reactive4(Sensor):
Expand Down Expand Up @@ -300,7 +294,7 @@ def __init__(self, id_: str, offset: int, name: str, unit: str = "", kind: Optio
super().__init__(id_, offset, name, 2, unit, kind)

def read_value(self, data: ProtocolResponse):
return read_bytes2(data)
return read_bytes2_signed(data)

def encode_value(self, value: Any, register_value: bytes = None) -> bytes:
return int.to_bytes(int(value), length=2, byteorder="big", signed=True)
Expand Down Expand Up @@ -506,7 +500,7 @@ def read_value(self, data: ProtocolResponse):
self.end_m = read_byte(data)
if self.end_m < 0 or self.end_m > 59:
raise ValueError(f"{self.id_}: end_m value {self.end_m} out of range.")
self.power = read_bytes2(data) # negative=charge, positive=discharge
self.power = read_bytes2_signed(data) # negative=charge, positive=discharge
if self.power < -100 or self.power > 100:
raise ValueError(f"{self.id_}: power value {self.power} out of range.")
self.on_off = read_byte(data)
Expand Down Expand Up @@ -615,13 +609,13 @@ def read_value(self, data: ProtocolResponse):
self.days = decode_day_of_week(self.day_bits)
if self.day_bits < 0:
raise ValueError(f"{self.id_}: day_bits value {self.day_bits} out of range.")
self.power = read_bytes2(data) # negative=charge, positive=discharge
self.power = read_bytes2_signed(data) # negative=charge, positive=discharge
if not self.schedule_type.is_in_range(self.power):
raise ValueError(f"{self.id_}: power value {self.power} out of range.")
self.soc = read_bytes2(data)
self.soc = read_bytes2_signed(data)
if self.soc < 0 or self.soc > 100:
raise ValueError(f"{self.id_}: SoC value {self.soc} out of range.")
self.month_bits = read_bytes2(data)
self.month_bits = read_bytes2_signed(data)
self.months = decode_months(self.month_bits)
return self

Expand Down Expand Up @@ -727,6 +721,14 @@ def read_byte(buffer: ProtocolResponse, offset: int = None) -> int:


def read_bytes2(buffer: ProtocolResponse, offset: int = None) -> int:
"""Retrieve 2 byte (unsigned int) value from buffer"""
if offset is not None:
buffer.seek(offset)
value = int.from_bytes(buffer.read(2), byteorder="big", signed=False)
return value if value != 0xffff else 0


def read_bytes2_signed(buffer: ProtocolResponse, offset: int = None) -> int:
"""Retrieve 2 byte (signed int) value from buffer"""
if offset is not None:
buffer.seek(offset)
Expand Down Expand Up @@ -853,7 +855,7 @@ def encode_datetime(value: Any) -> bytes:

def read_grid_mode(buffer: ProtocolResponse, offset: int = None) -> int:
"""Retrieve 'grid mode' sign value from buffer"""
value = read_bytes2(buffer, offset)
value = read_bytes2_signed(buffer, offset)
if value < -90:
return 2
elif value >= 90:
Expand Down
4 changes: 2 additions & 2 deletions tests/test_dt.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ def test_GW8K_DT_runtime_data(self):
self.assertSensor("apparent_power", 0, "VA", data),
self.assertSensor("reactive_power", 0, "var", data),
self.assertSensor('temperature', 45.3, 'C', data)
self.assertSensor('e_day', None, 'kWh', data)
self.assertSensor('e_total', None, 'kWh', data)
self.assertSensor('e_day', 0.0, 'kWh', data)
self.assertSensor('e_total', 0.0, 'kWh', data)
self.assertSensor('h_total', -1, 'h', data)
self.assertSensor('safety_country', 32, '', data)
self.assertSensor('safety_country_label', '50Hz 230Vac Default', '', data)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def test_energy4(self):
data = MockResponse("00020972")
self.assertEqual(13349.0, testee.read(data))
data = MockResponse("ffffffff")
self.assertIsNone(testee.read(data))
self.assertEqual(0.0, testee.read(data))

def test_timestamp(self):
testee = Timestamp("", 0, "", None)
Expand Down

0 comments on commit f41674c

Please sign in to comment.