goodwe 0.4.5__py3-none-any.whl → 0.4.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- goodwe/dt.py +12 -1
- goodwe/es.py +9 -6
- goodwe/et.py +40 -5
- goodwe/model.py +4 -0
- goodwe/protocol.py +26 -4
- goodwe/sensor.py +23 -4
- {goodwe-0.4.5.dist-info → goodwe-0.4.7.dist-info}/METADATA +1 -1
- goodwe-0.4.7.dist-info/RECORD +16 -0
- goodwe-0.4.5.dist-info/RECORD +0 -16
- {goodwe-0.4.5.dist-info → goodwe-0.4.7.dist-info}/LICENSE +0 -0
- {goodwe-0.4.5.dist-info → goodwe-0.4.7.dist-info}/WHEEL +0 -0
- {goodwe-0.4.5.dist-info → goodwe-0.4.7.dist-info}/top_level.txt +0 -0
goodwe/dt.py
CHANGED
|
@@ -35,6 +35,12 @@ class DT(Inverter):
|
|
|
35
35
|
Calculated("ppv3",
|
|
36
36
|
lambda data: round(read_voltage(data, 30107) * read_current(data, 30108)),
|
|
37
37
|
"PV3 Power", "W", Kind.PV),
|
|
38
|
+
# ppv1 + ppv2 + ppv3
|
|
39
|
+
Calculated("ppv",
|
|
40
|
+
lambda data: (round(read_voltage(data, 30103) * read_current(data, 30104))) + (round(
|
|
41
|
+
read_voltage(data, 30105) * read_current(data, 30106))) + (round(
|
|
42
|
+
read_voltage(data, 30107) * read_current(data, 30108))),
|
|
43
|
+
"PV Power", "W", Kind.PV),
|
|
38
44
|
# Voltage("vpv4", 14, "PV4 Voltage", Kind.PV),
|
|
39
45
|
# Current("ipv4", 16, "PV4 Current", Kind.PV),
|
|
40
46
|
# Voltage("vpv5", 14, "PV5 Voltage", Kind.PV),
|
|
@@ -63,7 +69,7 @@ class DT(Inverter):
|
|
|
63
69
|
lambda data: round(read_voltage(data, 30120) * read_current(data, 30123)),
|
|
64
70
|
"On-grid L3 Power", "W", Kind.AC),
|
|
65
71
|
# 30127 reserved
|
|
66
|
-
|
|
72
|
+
PowerS("active_power", 30128, "Active Power", Kind.AC),
|
|
67
73
|
Integer("work_mode", 30129, "Work Mode code"),
|
|
68
74
|
Enum2("work_mode_label", 30129, WORK_MODES, "Work Mode"),
|
|
69
75
|
Long("error_codes", 30130, "Error Codes"),
|
|
@@ -114,6 +120,10 @@ class DT(Inverter):
|
|
|
114
120
|
Integer("shadow_scan", 40326, "Shadow Scan", "", Kind.PV),
|
|
115
121
|
Integer("grid_export", 40327, "Grid Export Enabled", "", Kind.GRID),
|
|
116
122
|
Integer("grid_export_limit", 40328, "Grid Export Limit", "%", Kind.GRID),
|
|
123
|
+
Integer("start", 40330, "Start / Power On", "", Kind.GRID),
|
|
124
|
+
Integer("stop", 40331, "Stop / Power Off", "", Kind.GRID),
|
|
125
|
+
Integer("restart", 40332, "Restart", "", Kind.GRID),
|
|
126
|
+
Integer("grid_export_hw", 40345, "Grid Export Enabled (HW)", "", Kind.GRID),
|
|
117
127
|
)
|
|
118
128
|
|
|
119
129
|
# Settings for single phase inverters
|
|
@@ -196,6 +206,7 @@ class DT(Inverter):
|
|
|
196
206
|
if ex.message == ILLEGAL_DATA_ADDRESS:
|
|
197
207
|
logger.debug("Unsupported setting %s", setting.id_)
|
|
198
208
|
self._settings.pop(setting.id_, None)
|
|
209
|
+
raise ValueError(f'Unknown setting "{setting.id_}"')
|
|
199
210
|
return None
|
|
200
211
|
|
|
201
212
|
async def write_setting(self, setting_id: str, value: Any):
|
goodwe/es.py
CHANGED
|
@@ -174,11 +174,11 @@ class ES(Inverter):
|
|
|
174
174
|
def _supports_eco_mode_v2(self) -> bool:
|
|
175
175
|
if self.arm_version < 14:
|
|
176
176
|
return False
|
|
177
|
-
if "EMU" in self.serial_number:
|
|
177
|
+
if "EMU" in self.serial_number or "EMJ" in self.serial_number:
|
|
178
178
|
return self.dsp1_version >= 11
|
|
179
|
-
if "ESU" in self.serial_number:
|
|
179
|
+
if "ESU" in self.serial_number or "ESA" in self.serial_number:
|
|
180
180
|
return self.dsp1_version >= 22
|
|
181
|
-
if "BPS" in self.serial_number:
|
|
181
|
+
if "BPS" in self.serial_number or "BPU" in self.serial_number:
|
|
182
182
|
return self.dsp1_version >= 10
|
|
183
183
|
return False
|
|
184
184
|
|
|
@@ -188,7 +188,7 @@ class ES(Inverter):
|
|
|
188
188
|
self.firmware = self._decode(response[0:5]).rstrip()
|
|
189
189
|
self.model_name = self._decode(response[5:15]).rstrip()
|
|
190
190
|
self.serial_number = self._decode(response[31:47])
|
|
191
|
-
self.
|
|
191
|
+
self.arm_firmware = self._decode(response[51:63]) # AKA software_version
|
|
192
192
|
try:
|
|
193
193
|
if len(self.firmware) >= 2:
|
|
194
194
|
self.dsp1_version = int(self.firmware[0:2])
|
|
@@ -220,9 +220,12 @@ class ES(Inverter):
|
|
|
220
220
|
elif setting_id.startswith("modbus"):
|
|
221
221
|
response = await self._read_from_socket(self._read_command(int(setting_id[7:]), 1))
|
|
222
222
|
return int.from_bytes(response.read(2), byteorder="big", signed=True)
|
|
223
|
-
|
|
223
|
+
elif setting_id in self._settings:
|
|
224
|
+
logger.debug("Reading setting %s", setting_id)
|
|
224
225
|
all_settings = await self.read_settings_data()
|
|
225
226
|
return all_settings.get(setting_id)
|
|
227
|
+
else:
|
|
228
|
+
raise ValueError(f'Unknown setting "{setting_id}"')
|
|
226
229
|
|
|
227
230
|
async def _read_setting(self, setting: Sensor) -> Any:
|
|
228
231
|
count = (setting.size_ + (setting.size_ % 2)) // 2
|
|
@@ -296,7 +299,7 @@ class ES(Inverter):
|
|
|
296
299
|
try:
|
|
297
300
|
mode = OperationMode(mode_id)
|
|
298
301
|
except ValueError:
|
|
299
|
-
logger.debug("Unknown work_mode value %
|
|
302
|
+
logger.debug("Unknown work_mode value %s", mode_id)
|
|
300
303
|
return None
|
|
301
304
|
if OperationMode.ECO != mode:
|
|
302
305
|
return mode
|
goodwe/et.py
CHANGED
|
@@ -257,7 +257,8 @@ class ET(Inverter):
|
|
|
257
257
|
Apparent4("meter_apparent_power_total", 36041, "Meter Apparent Power Total", Kind.GRID),
|
|
258
258
|
Integer("meter_type", 36043, "Meter Type", "", Kind.GRID), # (0: Single phase, 1: 3P3W, 2: 3P4W, 3: HomeKit)
|
|
259
259
|
Integer("meter_sw_version", 36044, "Meter Software Version", "", Kind.GRID),
|
|
260
|
-
|
|
260
|
+
|
|
261
|
+
# Sensors added in some ARM fw update (or platform 745/753), read when flag _has_meter_extended is on
|
|
261
262
|
Power4S("meter2_active_power", 36045, "Meter 2 Active Power", Kind.GRID),
|
|
262
263
|
Float("meter2_e_total_exp", 36047, 1000, "Meter 2 Total Energy (export)", "kWh", Kind.GRID),
|
|
263
264
|
Float("meter2_e_total_imp", 36049, 1000, "Meter 2 Total Energy (import)", "kWh", Kind.GRID),
|
|
@@ -268,6 +269,15 @@ class ET(Inverter):
|
|
|
268
269
|
Current("meter_current1", 36055, "Meter L1 Current", Kind.GRID),
|
|
269
270
|
Current("meter_current2", 36056, "Meter L2 Current", Kind.GRID),
|
|
270
271
|
Current("meter_current3", 36057, "Meter L3 Current", Kind.GRID),
|
|
272
|
+
|
|
273
|
+
Energy8("meter_e_total_exp1", 36092, "Meter Total Energy (export) L1", Kind.GRID),
|
|
274
|
+
Energy8("meter_e_total_exp2", 36096, "Meter Total Energy (export) L2", Kind.GRID),
|
|
275
|
+
Energy8("meter_e_total_exp3", 36100, "Meter Total Energy (export) L3", Kind.GRID),
|
|
276
|
+
Energy8("meter_e_total_exp", 36104, "Meter Total Energy (export)", Kind.GRID),
|
|
277
|
+
Energy8("meter_e_total_imp1", 36108, "Meter Total Energy (import) L1", Kind.GRID),
|
|
278
|
+
Energy8("meter_e_total_imp2", 36112, "Meter Total Energy (import) L2", Kind.GRID),
|
|
279
|
+
Energy8("meter_e_total_imp3", 36116, "Meter Total Energy (import) L3", Kind.GRID),
|
|
280
|
+
Energy8("meter_e_total_imp", 36120, "Meter Total Energy (import)", Kind.GRID),
|
|
271
281
|
)
|
|
272
282
|
|
|
273
283
|
# Inverter's MPPT data
|
|
@@ -332,7 +342,7 @@ class ET(Inverter):
|
|
|
332
342
|
# Modbus registers of inverter settings, offsets are modbus register addresses
|
|
333
343
|
__all_settings: Tuple[Sensor, ...] = (
|
|
334
344
|
Integer("comm_address", 45127, "Communication Address", ""),
|
|
335
|
-
|
|
345
|
+
Long("modbus_baud_rate", 45132, "Modbus Baud rate", ""),
|
|
336
346
|
Timestamp("time", 45200, "Inverter time"),
|
|
337
347
|
|
|
338
348
|
Integer("sensitivity_check", 45246, "Sensitivity Check Mode", "", Kind.AC),
|
|
@@ -357,6 +367,8 @@ class ET(Inverter):
|
|
|
357
367
|
Integer("work_mode", 47000, "Work Mode", "", Kind.AC),
|
|
358
368
|
Integer("dred", 47010, "DRED/Remote Shutdown", "", Kind.AC),
|
|
359
369
|
|
|
370
|
+
Integer("meter_target_power_offset", 47120, "Meter Target Power Offset", "W", Kind.AC),
|
|
371
|
+
|
|
360
372
|
Integer("battery_soc_protection", 47500, "Battery SoC Protection", "", Kind.BAT),
|
|
361
373
|
|
|
362
374
|
Integer("grid_export", 47509, "Grid Export Enabled", "", Kind.GRID),
|
|
@@ -462,6 +474,7 @@ class ET(Inverter):
|
|
|
462
474
|
self._READ_RUNNING_DATA: ProtocolCommand = self._read_command(0x891c, 0x007d)
|
|
463
475
|
self._READ_METER_DATA: ProtocolCommand = self._read_command(0x8ca0, 0x2d)
|
|
464
476
|
self._READ_METER_DATA_EXTENDED: ProtocolCommand = self._read_command(0x8ca0, 0x3a)
|
|
477
|
+
self._READ_METER_DATA_EXTENDED2: ProtocolCommand = self._read_command(0x8ca0, 0x7d)
|
|
465
478
|
self._READ_BATTERY_INFO: ProtocolCommand = self._read_command(0x9088, 0x0018)
|
|
466
479
|
self._READ_BATTERY2_INFO: ProtocolCommand = self._read_command(0x9858, 0x0016)
|
|
467
480
|
self._READ_MPPT_DATA: ProtocolCommand = self._read_command(0x89e5, 0x3d)
|
|
@@ -470,6 +483,7 @@ class ET(Inverter):
|
|
|
470
483
|
self._has_battery: bool = True
|
|
471
484
|
self._has_battery2: bool = False
|
|
472
485
|
self._has_meter_extended: bool = False
|
|
486
|
+
self._has_meter_extended2: bool = False
|
|
473
487
|
self._has_mppt: bool = False
|
|
474
488
|
self._sensors = self.__all_sensors
|
|
475
489
|
self._sensors_battery = self.__all_sensors_battery
|
|
@@ -488,6 +502,11 @@ class ET(Inverter):
|
|
|
488
502
|
"""Filter to exclude extended meter sensors"""
|
|
489
503
|
return s.offset < 36045
|
|
490
504
|
|
|
505
|
+
@staticmethod
|
|
506
|
+
def _not_extended_meter2(s: Sensor) -> bool:
|
|
507
|
+
"""Filter to exclude extended meter sensors"""
|
|
508
|
+
return s.offset < 36058
|
|
509
|
+
|
|
491
510
|
async def read_device_info(self):
|
|
492
511
|
response = await self._read_from_socket(self._READ_DEVICE_VERSION_INFO)
|
|
493
512
|
response = response.response_data()
|
|
@@ -518,9 +537,10 @@ class ET(Inverter):
|
|
|
518
537
|
if is_2_battery(self) or self.rated_power >= 25000:
|
|
519
538
|
self._has_battery2 = True
|
|
520
539
|
|
|
521
|
-
if self.rated_power >= 15000:
|
|
540
|
+
if is_745_platform(self) or self.rated_power >= 15000:
|
|
522
541
|
self._has_mppt = True
|
|
523
542
|
self._has_meter_extended = True
|
|
543
|
+
self._has_meter_extended2 = True
|
|
524
544
|
else:
|
|
525
545
|
self._sensors_meter = tuple(filter(self._not_extended_meter, self._sensors_meter))
|
|
526
546
|
|
|
@@ -575,7 +595,21 @@ class ET(Inverter):
|
|
|
575
595
|
else:
|
|
576
596
|
raise ex
|
|
577
597
|
|
|
578
|
-
if self.
|
|
598
|
+
if self._has_meter_extended2:
|
|
599
|
+
try:
|
|
600
|
+
response = await self._read_from_socket(self._READ_METER_DATA_EXTENDED2)
|
|
601
|
+
data.update(self._map_response(response, self._sensors_meter))
|
|
602
|
+
except RequestRejectedException as ex:
|
|
603
|
+
if ex.message == ILLEGAL_DATA_ADDRESS:
|
|
604
|
+
logger.info("Extended meter values not supported, disabling further attempts.")
|
|
605
|
+
self._has_meter_extended2 = False
|
|
606
|
+
self._sensors_meter = tuple(filter(self._not_extended_meter2, self._sensors_meter))
|
|
607
|
+
response = await self._read_from_socket(self._READ_METER_DATA_EXTENDED)
|
|
608
|
+
data.update(
|
|
609
|
+
self._map_response(response, self._sensors_meter))
|
|
610
|
+
else:
|
|
611
|
+
raise ex
|
|
612
|
+
elif self._has_meter_extended:
|
|
579
613
|
try:
|
|
580
614
|
response = await self._read_from_socket(self._READ_METER_DATA_EXTENDED)
|
|
581
615
|
data.update(self._map_response(response, self._sensors_meter))
|
|
@@ -626,6 +660,7 @@ class ET(Inverter):
|
|
|
626
660
|
if ex.message == ILLEGAL_DATA_ADDRESS:
|
|
627
661
|
logger.debug("Unsupported setting %s", setting.id_)
|
|
628
662
|
self._settings.pop(setting.id_, None)
|
|
663
|
+
raise ValueError(f'Unknown setting "{setting.id_}"')
|
|
629
664
|
return None
|
|
630
665
|
|
|
631
666
|
async def write_setting(self, setting_id: str, value: Any):
|
|
@@ -685,7 +720,7 @@ class ET(Inverter):
|
|
|
685
720
|
try:
|
|
686
721
|
mode = OperationMode(mode_id)
|
|
687
722
|
except ValueError:
|
|
688
|
-
logger.debug("Unknown work_mode value %
|
|
723
|
+
logger.debug("Unknown work_mode value %s", mode_id)
|
|
689
724
|
return None
|
|
690
725
|
if OperationMode.ECO != mode:
|
|
691
726
|
return mode
|
goodwe/model.py
CHANGED
|
@@ -48,3 +48,7 @@ def is_2_battery(inverter: Inverter) -> bool:
|
|
|
48
48
|
def is_745_platform(inverter: Inverter) -> bool:
|
|
49
49
|
return any(model in inverter.serial_number for model in PLATFORM_745_LV_MODELS) or any(
|
|
50
50
|
model in inverter.serial_number for model in PLATFORM_745_HV_MODELS)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def is_753_platform(inverter: Inverter) -> bool:
|
|
54
|
+
return any(model in inverter.serial_number for model in PLATFORM_753_MODELS)
|
goodwe/protocol.py
CHANGED
|
@@ -482,7 +482,7 @@ class Aa55ProtocolCommand(ProtocolCommand):
|
|
|
482
482
|
The last 2 bytes are again plain checksum of header+payload.
|
|
483
483
|
"""
|
|
484
484
|
|
|
485
|
-
def __init__(self, payload: str, response_type: str):
|
|
485
|
+
def __init__(self, payload: str, response_type: str, offset: int = 0, value: int = 0):
|
|
486
486
|
super().__init__(
|
|
487
487
|
bytes.fromhex(
|
|
488
488
|
"AA55C07F"
|
|
@@ -491,6 +491,8 @@ class Aa55ProtocolCommand(ProtocolCommand):
|
|
|
491
491
|
),
|
|
492
492
|
lambda x: self._validate_aa55_response(x, response_type),
|
|
493
493
|
)
|
|
494
|
+
self.first_address: int = offset
|
|
495
|
+
self.value = value
|
|
494
496
|
|
|
495
497
|
@staticmethod
|
|
496
498
|
def _checksum(data: bytes) -> bytes:
|
|
@@ -534,6 +536,17 @@ class Aa55ProtocolCommand(ProtocolCommand):
|
|
|
534
536
|
"""Trim raw response from header and checksum data"""
|
|
535
537
|
return raw_response[7:-2]
|
|
536
538
|
|
|
539
|
+
def __repr__(self):
|
|
540
|
+
if self.request[4] == 1:
|
|
541
|
+
if self.request[5] == 2:
|
|
542
|
+
return f'READ device info ({self.request.hex()})'
|
|
543
|
+
elif self.request[5] == 6:
|
|
544
|
+
return f'READ runtime data ({self.request.hex()})'
|
|
545
|
+
elif self.request[5] == 9:
|
|
546
|
+
return f'READ settings ({self.request.hex()})'
|
|
547
|
+
else:
|
|
548
|
+
return self.request.hex()
|
|
549
|
+
|
|
537
550
|
|
|
538
551
|
class Aa55ReadCommand(Aa55ProtocolCommand):
|
|
539
552
|
"""
|
|
@@ -541,7 +554,13 @@ class Aa55ReadCommand(Aa55ProtocolCommand):
|
|
|
541
554
|
"""
|
|
542
555
|
|
|
543
556
|
def __init__(self, offset: int, count: int):
|
|
544
|
-
super().__init__("011A03" + "{:04x}".format(offset) + "{:02x}".format(count), "019A")
|
|
557
|
+
super().__init__("011A03" + "{:04x}".format(offset) + "{:02x}".format(count), "019A", offset, count)
|
|
558
|
+
|
|
559
|
+
def __repr__(self):
|
|
560
|
+
if self.value > 1:
|
|
561
|
+
return f'READ {self.value} registers from {self.first_address} ({self.request.hex()})'
|
|
562
|
+
else:
|
|
563
|
+
return f'READ register {self.first_address} ({self.request.hex()})'
|
|
545
564
|
|
|
546
565
|
|
|
547
566
|
class Aa55WriteCommand(Aa55ProtocolCommand):
|
|
@@ -550,7 +569,10 @@ class Aa55WriteCommand(Aa55ProtocolCommand):
|
|
|
550
569
|
"""
|
|
551
570
|
|
|
552
571
|
def __init__(self, register: int, value: int):
|
|
553
|
-
super().__init__("023905" + "{:04x}".format(register) + "01" + "{:04x}".format(value), "02B9")
|
|
572
|
+
super().__init__("023905" + "{:04x}".format(register) + "01" + "{:04x}".format(value), "02B9", register, value)
|
|
573
|
+
|
|
574
|
+
def __repr__(self):
|
|
575
|
+
return f'WRITE {self.value} to register {self.first_address} ({self.request.hex()})'
|
|
554
576
|
|
|
555
577
|
|
|
556
578
|
class Aa55WriteMultiCommand(Aa55ProtocolCommand):
|
|
@@ -560,7 +582,7 @@ class Aa55WriteMultiCommand(Aa55ProtocolCommand):
|
|
|
560
582
|
|
|
561
583
|
def __init__(self, offset: int, values: bytes):
|
|
562
584
|
super().__init__("02390B" + "{:04x}".format(offset) + "{:02x}".format(len(values)) + values.hex(),
|
|
563
|
-
"02B9")
|
|
585
|
+
"02B9", offset, len(values) // 2)
|
|
564
586
|
|
|
565
587
|
|
|
566
588
|
class ModbusRtuProtocolCommand(ProtocolCommand):
|
goodwe/sensor.py
CHANGED
|
@@ -197,6 +197,17 @@ class Energy4(Sensor):
|
|
|
197
197
|
return float(value) / 10 if value is not None else None
|
|
198
198
|
|
|
199
199
|
|
|
200
|
+
class Energy8(Sensor):
|
|
201
|
+
"""Sensor representing energy [kWh] value encoded in 8 bytes"""
|
|
202
|
+
|
|
203
|
+
def __init__(self, id_: str, offset: int, name: str, kind: Optional[SensorKind]):
|
|
204
|
+
super().__init__(id_, offset, name, 8, "kWh", kind)
|
|
205
|
+
|
|
206
|
+
def read_value(self, data: ProtocolResponse):
|
|
207
|
+
value = read_bytes8(data)
|
|
208
|
+
return float(value) / 100 if value is not None else None
|
|
209
|
+
|
|
210
|
+
|
|
200
211
|
class Apparent(Sensor):
|
|
201
212
|
"""Sensor representing apparent power [VA] value encoded in 2 bytes"""
|
|
202
213
|
|
|
@@ -364,7 +375,7 @@ class Decimal(Sensor):
|
|
|
364
375
|
return read_decimal2(data, self.scale)
|
|
365
376
|
|
|
366
377
|
def encode_value(self, value: Any, register_value: bytes = None) -> bytes:
|
|
367
|
-
return int.to_bytes(int(value * self.scale), length=2, byteorder="big", signed=True)
|
|
378
|
+
return int.to_bytes(int(float(value) * self.scale), length=2, byteorder="big", signed=True)
|
|
368
379
|
|
|
369
380
|
|
|
370
381
|
class Float(Sensor):
|
|
@@ -840,6 +851,14 @@ def read_bytes4_signed(buffer: ProtocolResponse, offset: int = None) -> int:
|
|
|
840
851
|
return int.from_bytes(buffer.read(4), byteorder="big", signed=True)
|
|
841
852
|
|
|
842
853
|
|
|
854
|
+
def read_bytes8(buffer: ProtocolResponse, offset: int = None, undef: int = None) -> int:
|
|
855
|
+
"""Retrieve 8 byte (unsigned int) value from buffer"""
|
|
856
|
+
if offset is not None:
|
|
857
|
+
buffer.seek(offset)
|
|
858
|
+
value = int.from_bytes(buffer.read(8), byteorder="big", signed=False)
|
|
859
|
+
return undef if value == 0xffffffffffffffff else value
|
|
860
|
+
|
|
861
|
+
|
|
843
862
|
def read_decimal2(buffer: ProtocolResponse, scale: int, offset: int = None) -> float:
|
|
844
863
|
"""Retrieve 2 byte (signed float) value from buffer"""
|
|
845
864
|
if offset is not None:
|
|
@@ -868,7 +887,7 @@ def read_voltage(buffer: ProtocolResponse, offset: int = None) -> float:
|
|
|
868
887
|
|
|
869
888
|
def encode_voltage(value: Any) -> bytes:
|
|
870
889
|
"""Encode voltage value to raw (2 unsigned bytes) payload"""
|
|
871
|
-
return int.to_bytes(int(value * 10), length=2, byteorder="big", signed=False)
|
|
890
|
+
return int.to_bytes(int(float(value) * 10), length=2, byteorder="big", signed=False)
|
|
872
891
|
|
|
873
892
|
|
|
874
893
|
def read_current(buffer: ProtocolResponse, offset: int = None) -> float:
|
|
@@ -889,12 +908,12 @@ def read_current_signed(buffer: ProtocolResponse, offset: int = None) -> float:
|
|
|
889
908
|
|
|
890
909
|
def encode_current(value: Any) -> bytes:
|
|
891
910
|
"""Encode current value to raw (2 unsigned bytes) payload"""
|
|
892
|
-
return int.to_bytes(int(value * 10), length=2, byteorder="big", signed=False)
|
|
911
|
+
return int.to_bytes(int(float(value) * 10), length=2, byteorder="big", signed=False)
|
|
893
912
|
|
|
894
913
|
|
|
895
914
|
def encode_current_signed(value: Any) -> bytes:
|
|
896
915
|
"""Encode current value to raw (2 signed bytes) payload"""
|
|
897
|
-
return int.to_bytes(int(value * 10), length=2, byteorder="big", signed=True)
|
|
916
|
+
return int.to_bytes(int(float(value) * 10), length=2, byteorder="big", signed=True)
|
|
898
917
|
|
|
899
918
|
|
|
900
919
|
def read_freq(buffer: ProtocolResponse, offset: int = None) -> float:
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
goodwe/__init__.py,sha256=8fFGBBvBpCo6Ew4puTtW0kYo2hVPKUx6z5A-TA4Tbvc,5795
|
|
2
|
+
goodwe/const.py,sha256=yhWk56YV7k7-MbgfmWEMYNlqeRNLOfOpfTqEfRj6Hp8,7934
|
|
3
|
+
goodwe/dt.py,sha256=TxjJ4iqvtRiHGKwlfLoYWblN-COVZ3i48PPk4z4xJcc,12482
|
|
4
|
+
goodwe/es.py,sha256=vvHmxcFykp8nhR1I8p7SF0YcYpvdCKBYacgcolbVHXI,23009
|
|
5
|
+
goodwe/et.py,sha256=Sdgqj13DXIg36NptkHMKxuP78oo4aUQ_6zlToyt78qI,46002
|
|
6
|
+
goodwe/exceptions.py,sha256=dKMLxotjoR1ic8OVlw1joIJ4mKWD6oFtUMZ86fNM5ZE,1403
|
|
7
|
+
goodwe/inverter.py,sha256=86aMJzJjNOr1I_tCF5H6mBwzDTjLbGDKUL2hbi0XSxg,10459
|
|
8
|
+
goodwe/modbus.py,sha256=Mg_s_v8kbZgqXZM6ZUUxkZx2boAG8LkuDG5OiFKK2X4,8402
|
|
9
|
+
goodwe/model.py,sha256=OAKfw6ggClgLR9JIdNd7tQ4pnh_7o_UqVdm1KOVsm-Y,2200
|
|
10
|
+
goodwe/protocol.py,sha256=gnQ1vV4U_lPpaNq5-jmzJO6ngJEDFVo0jWXVujSyu_0,30083
|
|
11
|
+
goodwe/sensor.py,sha256=xeDZIwjJ_176ULrRXVCTYvVXx6o2_pWgS0KuR3PPQdg,38435
|
|
12
|
+
goodwe-0.4.7.dist-info/LICENSE,sha256=aZAhk3lRdYT1YZV-IKRHISEcc_KNUmgfuNO3QhRamNM,1073
|
|
13
|
+
goodwe-0.4.7.dist-info/METADATA,sha256=qzKMdlhzJDyLdHfqp5_x7jFZMI2B15mTnBhN_UksJzM,3376
|
|
14
|
+
goodwe-0.4.7.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
15
|
+
goodwe-0.4.7.dist-info/top_level.txt,sha256=kKoiqiVvAxDaDJYMZZQLgHQj9cuWT1MXLfXElTDuf8s,7
|
|
16
|
+
goodwe-0.4.7.dist-info/RECORD,,
|
goodwe-0.4.5.dist-info/RECORD
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
goodwe/__init__.py,sha256=8fFGBBvBpCo6Ew4puTtW0kYo2hVPKUx6z5A-TA4Tbvc,5795
|
|
2
|
-
goodwe/const.py,sha256=yhWk56YV7k7-MbgfmWEMYNlqeRNLOfOpfTqEfRj6Hp8,7934
|
|
3
|
-
goodwe/dt.py,sha256=oGbkdVHP51KnlwQraKeebmiP6AtJ1S67aLB7euNRIoE,11743
|
|
4
|
-
goodwe/es.py,sha256=iVK8EMCaAJJFihZLntJZ_Eu4sQWoZTVtTROp9mHFG6o,22730
|
|
5
|
-
goodwe/et.py,sha256=CiX-PE7wouDnj1RnPnOyqiNE4FELhOGdyPUOm9VCzUw,43890
|
|
6
|
-
goodwe/exceptions.py,sha256=dKMLxotjoR1ic8OVlw1joIJ4mKWD6oFtUMZ86fNM5ZE,1403
|
|
7
|
-
goodwe/inverter.py,sha256=86aMJzJjNOr1I_tCF5H6mBwzDTjLbGDKUL2hbi0XSxg,10459
|
|
8
|
-
goodwe/modbus.py,sha256=Mg_s_v8kbZgqXZM6ZUUxkZx2boAG8LkuDG5OiFKK2X4,8402
|
|
9
|
-
goodwe/model.py,sha256=dWBjMFJMnhZoUdDd9fGT54DERDANz4TirK0Wy8kWMbk,2068
|
|
10
|
-
goodwe/protocol.py,sha256=Ry1B-kki5F-AnsmpeUWuhP3eCCH1wrKKfDuT9BKfmvE,29140
|
|
11
|
-
goodwe/sensor.py,sha256=buPG8BcgZmRDqaMrLQUACLHB85U134qG6qo_ggsu48A,37679
|
|
12
|
-
goodwe-0.4.5.dist-info/LICENSE,sha256=aZAhk3lRdYT1YZV-IKRHISEcc_KNUmgfuNO3QhRamNM,1073
|
|
13
|
-
goodwe-0.4.5.dist-info/METADATA,sha256=9MoleSeCTePnmqw6x_u5WcBE0GXwVvCtxF-9s4hqEHw,3376
|
|
14
|
-
goodwe-0.4.5.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
15
|
-
goodwe-0.4.5.dist-info/top_level.txt,sha256=kKoiqiVvAxDaDJYMZZQLgHQj9cuWT1MXLfXElTDuf8s,7
|
|
16
|
-
goodwe-0.4.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|