goodwe 0.3.2__py3-none-any.whl → 0.3.3__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/es.py +1 -1
- goodwe/et.py +18 -4
- goodwe/inverter.py +2 -2
- goodwe/model.py +24 -14
- goodwe/sensor.py +72 -13
- {goodwe-0.3.2.dist-info → goodwe-0.3.3.dist-info}/METADATA +1 -1
- goodwe-0.3.3.dist-info/RECORD +16 -0
- goodwe-0.3.2.dist-info/RECORD +0 -16
- {goodwe-0.3.2.dist-info → goodwe-0.3.3.dist-info}/LICENSE +0 -0
- {goodwe-0.3.2.dist-info → goodwe-0.3.3.dist-info}/WHEEL +0 -0
- {goodwe-0.3.2.dist-info → goodwe-0.3.3.dist-info}/top_level.txt +0 -0
goodwe/es.py
CHANGED
|
@@ -15,7 +15,7 @@ logger = logging.getLogger(__name__)
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class ES(Inverter):
|
|
18
|
-
"""Class representing inverter of ES/EM/BP family"""
|
|
18
|
+
"""Class representing inverter of ES/EM/BP family AKA platform 105"""
|
|
19
19
|
|
|
20
20
|
_READ_DEVICE_VERSION_INFO: ProtocolCommand = Aa55ProtocolCommand("010200", "0182")
|
|
21
21
|
_READ_DEVICE_RUNNING_DATA: ProtocolCommand = Aa55ProtocolCommand("010600", "0186")
|
goodwe/et.py
CHANGED
|
@@ -7,7 +7,7 @@ from .exceptions import RequestRejectedException
|
|
|
7
7
|
from .inverter import Inverter
|
|
8
8
|
from .inverter import OperationMode
|
|
9
9
|
from .inverter import SensorKind as Kind
|
|
10
|
-
from .model import is_2_battery, is_4_mppt, is_single_phase
|
|
10
|
+
from .model import is_2_battery, is_4_mppt, is_745_platform, is_single_phase
|
|
11
11
|
from .protocol import ProtocolCommand, ModbusReadCommand, ModbusWriteCommand, ModbusWriteMultiCommand
|
|
12
12
|
from .sensor import *
|
|
13
13
|
|
|
@@ -15,7 +15,7 @@ logger = logging.getLogger(__name__)
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class ET(Inverter):
|
|
18
|
-
"""Class representing inverter of ET/EH/BT/BH or GE's GEH families"""
|
|
18
|
+
"""Class representing inverter of ET/EH/BT/BH or GE's GEH families AKA platform 205 or 745"""
|
|
19
19
|
|
|
20
20
|
# Modbus registers from offset 0x891c (35100), count 0x7d (125)
|
|
21
21
|
__all_sensors: Tuple[Sensor, ...] = (
|
|
@@ -384,19 +384,25 @@ class ET(Inverter):
|
|
|
384
384
|
|
|
385
385
|
Integer("load_control_mode", 47595, "Load Control Mode", "", Kind.AC),
|
|
386
386
|
Integer("load_control_switch", 47596, "Load Control Switch", "", Kind.AC),
|
|
387
|
-
Integer("load_control_soc",
|
|
387
|
+
Integer("load_control_soc", 47597, "Load Control SoC", "", Kind.AC),
|
|
388
388
|
|
|
389
389
|
Integer("fast_charging_power", 47603, "Fast Charging Power", "%", Kind.BAT),
|
|
390
390
|
)
|
|
391
391
|
|
|
392
392
|
# Settings added in ARM firmware 22
|
|
393
393
|
__settings_arm_fw_22: Tuple[Sensor, ...] = (
|
|
394
|
+
Long("peak_shaving_power_limit", 47542, "Peak Shaving Power Limit"),
|
|
395
|
+
Integer("peak_shaving_soc", 47544, "Peak Shaving SoC"),
|
|
394
396
|
# EcoModeV2("eco_modeV2_5", 47571, "Eco Mode Version 2 Power Group 5"),
|
|
395
397
|
# EcoModeV2("eco_modeV2_6", 47577, "Eco Mode Version 2 Power Group 6"),
|
|
396
398
|
# EcoModeV2("eco_modeV2_7", 47583, "Eco Mode Version 2 Power Group 7"),
|
|
397
399
|
PeakShavingMode("peak_shaving_mode", 47589, "Peak Shaving Mode"),
|
|
398
400
|
|
|
399
401
|
Integer("dod_holding", 47602, "DoD Holding", "", Kind.BAT),
|
|
402
|
+
Integer("backup_mode_enable", 47605, "Backup Mode Switch"),
|
|
403
|
+
Integer("max_charge_power", 47606, "Max Charge Power"),
|
|
404
|
+
Integer("smart_charging_enable", 47609, "Smart Charging Mode Switch"),
|
|
405
|
+
Integer("eco_mode_enable", 47612, "Eco Mode Switch"),
|
|
400
406
|
)
|
|
401
407
|
|
|
402
408
|
def __init__(self, host: str, comm_addr: int = 0, timeout: int = 1, retries: int = 3):
|
|
@@ -626,6 +632,7 @@ class ET(Inverter):
|
|
|
626
632
|
await self._set_offline(True)
|
|
627
633
|
await self.write_setting('backup_supply', 1)
|
|
628
634
|
await self.write_setting('cold_start', 4)
|
|
635
|
+
await self._clear_battery_mode_param()
|
|
629
636
|
elif operation_mode == OperationMode.BACKUP:
|
|
630
637
|
await self.write_setting('work_mode', 2)
|
|
631
638
|
await self._set_offline(False)
|
|
@@ -636,13 +643,20 @@ class ET(Inverter):
|
|
|
636
643
|
elif operation_mode == OperationMode.PEAK_SHAVING:
|
|
637
644
|
await self.write_setting('work_mode', 4)
|
|
638
645
|
await self._set_offline(False)
|
|
646
|
+
await self._clear_battery_mode_param()
|
|
639
647
|
elif operation_mode in (OperationMode.ECO_CHARGE, OperationMode.ECO_DISCHARGE):
|
|
640
648
|
if eco_mode_power < 0 or eco_mode_power > 100:
|
|
641
649
|
raise ValueError()
|
|
642
650
|
if eco_mode_soc < 0 or eco_mode_soc > 100:
|
|
643
651
|
raise ValueError()
|
|
652
|
+
|
|
644
653
|
eco_mode: EcoMode | Sensor = self._settings.get('eco_mode_1')
|
|
645
|
-
|
|
654
|
+
# Load the current values to try to detect schedule type
|
|
655
|
+
try:
|
|
656
|
+
await self._read_setting(eco_mode)
|
|
657
|
+
except ValueError:
|
|
658
|
+
pass
|
|
659
|
+
eco_mode.set_schedule_type(ScheduleType.ECO_MODE, is_745_platform(self))
|
|
646
660
|
if operation_mode == OperationMode.ECO_CHARGE:
|
|
647
661
|
await self.write_setting('eco_mode_1', eco_mode.encode_charge(eco_mode_power, eco_mode_soc))
|
|
648
662
|
else:
|
goodwe/inverter.py
CHANGED
goodwe/model.py
CHANGED
|
@@ -1,27 +1,32 @@
|
|
|
1
|
+
# Serial number tags to identify inverter type
|
|
1
2
|
from .inverter import Inverter
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
PLATFORM_105_MODELS = ("ESU", "EMU", "ESA", "BPS", "BPU", "EMJ", "IJL")
|
|
5
|
+
PLATFORM_205_MODELS = ("ETU", "ETL", "ETR", "BHN", "EHU", "BHU", "EHR", "BTU")
|
|
6
|
+
PLATFORM_745_LV_MODELS = ("ESN", "EBN", "EMN", "SPN", "ERN", "ESC", "HLB", "HMB", "HBB", "EOA")
|
|
7
|
+
PLATFORM_745_HV_MODELS = ("ETT", "HTA", "HUB", "AEB", "SPB", "CUB", "EUB", "HEB", "ERB", "BTT", "ETF", "ARB", "URB",
|
|
8
|
+
"EBR")
|
|
9
|
+
PLATFORM_753_MODELS = ("AES", "HHI", "ABP", "EHB", "HSB", "HUA", "CUA")
|
|
10
|
+
|
|
11
|
+
ET_MODEL_TAGS = PLATFORM_205_MODELS + PLATFORM_745_LV_MODELS + PLATFORM_745_HV_MODELS + PLATFORM_753_MODELS + (
|
|
12
|
+
"ETC", "BTC", "BTN") # Qianhai
|
|
13
|
+
ES_MODEL_TAGS = PLATFORM_105_MODELS
|
|
14
|
+
DT_MODEL_TAGS = ("DTU", "DTS",
|
|
10
15
|
"MSU", "MST", "MSC", "DSN", "DTN", "DST", "NSU", "SSN", "SST", "SSX", "SSY",
|
|
11
|
-
"PSB", "PSC"
|
|
16
|
+
"PSB", "PSC")
|
|
12
17
|
|
|
13
|
-
SINGLE_PHASE_MODELS =
|
|
18
|
+
SINGLE_PHASE_MODELS = ("DSN", "DST", "NSU", "SSN", "SST", "SSX", "SSY", # DT
|
|
14
19
|
"MSU", "MST", "PSB", "PSC",
|
|
15
20
|
"MSC", # Found on third gen MS
|
|
16
21
|
"EHU", "EHR", "HSB", # ET
|
|
17
|
-
"ESN", "EMN", "ERN", "EBN", "HLB", "HMB", "HBB", "SPN"
|
|
22
|
+
"ESN", "EMN", "ERN", "EBN", "HLB", "HMB", "HBB", "SPN") # ES Gen 2
|
|
18
23
|
|
|
19
|
-
MPPT3_MODELS =
|
|
20
|
-
"25KET", "29K9ET"
|
|
24
|
+
MPPT3_MODELS = ("MSU", "MST", "PSC", "MSC",
|
|
25
|
+
"25KET", "29K9ET")
|
|
21
26
|
|
|
22
|
-
MPPT4_MODELS =
|
|
27
|
+
MPPT4_MODELS = ("HSB",)
|
|
23
28
|
|
|
24
|
-
BAT_2_MODELS =
|
|
29
|
+
BAT_2_MODELS = ("25KET", "29K9ET")
|
|
25
30
|
|
|
26
31
|
|
|
27
32
|
def is_single_phase(inverter: Inverter) -> bool:
|
|
@@ -38,3 +43,8 @@ def is_4_mppt(inverter: Inverter) -> bool:
|
|
|
38
43
|
|
|
39
44
|
def is_2_battery(inverter: Inverter) -> bool:
|
|
40
45
|
return any(model in inverter.serial_number for model in BAT_2_MODELS)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def is_745_platform(inverter: Inverter) -> bool:
|
|
49
|
+
return any(model in inverter.serial_number for model in PLATFORM_745_LV_MODELS) or any(
|
|
50
|
+
model in inverter.serial_number for model in PLATFORM_745_HV_MODELS)
|
goodwe/sensor.py
CHANGED
|
@@ -21,12 +21,13 @@ class ScheduleType(IntEnum):
|
|
|
21
21
|
PEAK_SHAVING = 3,
|
|
22
22
|
BACKUP_MODE = 4,
|
|
23
23
|
SMART_CHARGE_MODE = 5,
|
|
24
|
-
ECO_MODE_745 = 6
|
|
24
|
+
ECO_MODE_745 = 6,
|
|
25
|
+
NOT_SET = 85
|
|
25
26
|
|
|
26
27
|
@classmethod
|
|
27
28
|
def detect_schedule_type(cls, value: int) -> ScheduleType:
|
|
28
29
|
"""Detect schedule type from its on/off value"""
|
|
29
|
-
if value in (0, -1
|
|
30
|
+
if value in (0, -1):
|
|
30
31
|
return ScheduleType.ECO_MODE
|
|
31
32
|
elif value in (1, -2):
|
|
32
33
|
return ScheduleType.DRY_CONTACT_LOAD
|
|
@@ -40,6 +41,8 @@ class ScheduleType(IntEnum):
|
|
|
40
41
|
return ScheduleType.SMART_CHARGE_MODE
|
|
41
42
|
elif value in (6, -7):
|
|
42
43
|
return ScheduleType.ECO_MODE_745
|
|
44
|
+
elif value == 85:
|
|
45
|
+
return ScheduleType.NOT_SET
|
|
43
46
|
else:
|
|
44
47
|
raise ValueError(f"{value}: on_off value {value} out of range.")
|
|
45
48
|
|
|
@@ -52,12 +55,13 @@ class ScheduleType(IntEnum):
|
|
|
52
55
|
|
|
53
56
|
def decode_power(self, value: int) -> int:
|
|
54
57
|
"""Decode human readable value of power parameter"""
|
|
55
|
-
if self == ScheduleType.
|
|
56
|
-
return value
|
|
57
|
-
elif self == ScheduleType.PEAK_SHAVING:
|
|
58
|
+
if self == ScheduleType.PEAK_SHAVING:
|
|
58
59
|
return value * 10
|
|
59
|
-
|
|
60
|
+
elif self == ScheduleType.ECO_MODE_745:
|
|
60
61
|
return int(value / 10)
|
|
62
|
+
elif self == ScheduleType.NOT_SET:
|
|
63
|
+
# Prevent out of range values when changing mode
|
|
64
|
+
return value if -100 <= value <= 100 else int(value / 10)
|
|
61
65
|
else:
|
|
62
66
|
return value
|
|
63
67
|
|
|
@@ -67,7 +71,7 @@ class ScheduleType(IntEnum):
|
|
|
67
71
|
return value
|
|
68
72
|
elif self == ScheduleType.PEAK_SHAVING:
|
|
69
73
|
return int(value / 10)
|
|
70
|
-
|
|
74
|
+
elif self == ScheduleType.ECO_MODE_745:
|
|
71
75
|
return value * 10
|
|
72
76
|
else:
|
|
73
77
|
return value
|
|
@@ -76,7 +80,7 @@ class ScheduleType(IntEnum):
|
|
|
76
80
|
"""Check if the value fits in allowed values range"""
|
|
77
81
|
if self == ScheduleType.ECO_MODE:
|
|
78
82
|
return -100 <= value <= 100
|
|
79
|
-
|
|
83
|
+
elif self == ScheduleType.ECO_MODE_745:
|
|
80
84
|
return -1000 <= value <= 1000
|
|
81
85
|
else:
|
|
82
86
|
return True
|
|
@@ -298,6 +302,19 @@ class ByteL(Byte):
|
|
|
298
302
|
|
|
299
303
|
|
|
300
304
|
class Integer(Sensor):
|
|
305
|
+
"""Sensor representing unsigned int value encoded in 2 bytes"""
|
|
306
|
+
|
|
307
|
+
def __init__(self, id_: str, offset: int, name: str, unit: str = "", kind: Optional[SensorKind] = None):
|
|
308
|
+
super().__init__(id_, offset, name, 2, unit, kind)
|
|
309
|
+
|
|
310
|
+
def read_value(self, data: ProtocolResponse):
|
|
311
|
+
return read_bytes2(data)
|
|
312
|
+
|
|
313
|
+
def encode_value(self, value: Any, register_value: bytes = None) -> bytes:
|
|
314
|
+
return int.to_bytes(int(value), length=2, byteorder="big", signed=False)
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
class IntegerS(Sensor):
|
|
301
318
|
"""Sensor representing signed int value encoded in 2 bytes"""
|
|
302
319
|
|
|
303
320
|
def __init__(self, id_: str, offset: int, name: str, unit: str = "", kind: Optional[SensorKind] = None):
|
|
@@ -311,6 +328,19 @@ class Integer(Sensor):
|
|
|
311
328
|
|
|
312
329
|
|
|
313
330
|
class Long(Sensor):
|
|
331
|
+
"""Sensor representing unsigned int value encoded in 4 bytes"""
|
|
332
|
+
|
|
333
|
+
def __init__(self, id_: str, offset: int, name: str, unit: str = "", kind: Optional[SensorKind] = None):
|
|
334
|
+
super().__init__(id_, offset, name, 4, unit, kind)
|
|
335
|
+
|
|
336
|
+
def read_value(self, data: ProtocolResponse):
|
|
337
|
+
return read_bytes4(data)
|
|
338
|
+
|
|
339
|
+
def encode_value(self, value: Any, register_value: bytes = None) -> bytes:
|
|
340
|
+
return int.to_bytes(int(value), length=4, byteorder="big", signed=False)
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
class LongS(Sensor):
|
|
314
344
|
"""Sensor representing signed int value encoded in 4 bytes"""
|
|
315
345
|
|
|
316
346
|
def __init__(self, id_: str, offset: int, name: str, unit: str = "", kind: Optional[SensorKind] = None):
|
|
@@ -476,6 +506,14 @@ class EcoMode(ABC):
|
|
|
476
506
|
def is_eco_discharge_mode(self) -> bool:
|
|
477
507
|
"""Answer if it represents the emulated 24/7 fulltime discharge mode"""
|
|
478
508
|
|
|
509
|
+
@abstractmethod
|
|
510
|
+
def get_schedule_type(self) -> ScheduleType:
|
|
511
|
+
"""Answer the schedule type"""
|
|
512
|
+
|
|
513
|
+
@abstractmethod
|
|
514
|
+
def set_schedule_type(self, schedule_type: ScheduleType, is745: bool):
|
|
515
|
+
"""Set the schedule type"""
|
|
516
|
+
|
|
479
517
|
|
|
480
518
|
class EcoModeV1(Sensor, EcoMode):
|
|
481
519
|
"""Sensor representing Eco Mode Battery Power Group encoded in 8 bytes"""
|
|
@@ -518,8 +556,6 @@ class EcoModeV1(Sensor, EcoMode):
|
|
|
518
556
|
raise ValueError(f"{self.id_}: on_off value {self.on_off} out of range.")
|
|
519
557
|
self.day_bits = read_byte(data)
|
|
520
558
|
self.days = decode_day_of_week(self.day_bits)
|
|
521
|
-
if self.day_bits < 0:
|
|
522
|
-
raise ValueError(f"{self.id_}: day_bits value {self.day_bits} out of range.")
|
|
523
559
|
return self
|
|
524
560
|
|
|
525
561
|
def encode_value(self, value: Any, register_value: bytes = None) -> bytes:
|
|
@@ -561,6 +597,14 @@ class EcoModeV1(Sensor, EcoMode):
|
|
|
561
597
|
and self.day_bits == 127 \
|
|
562
598
|
and self.power > 0
|
|
563
599
|
|
|
600
|
+
def get_schedule_type(self) -> ScheduleType:
|
|
601
|
+
"""Answer the schedule type"""
|
|
602
|
+
return ScheduleType.ECO_MODE
|
|
603
|
+
|
|
604
|
+
def set_schedule_type(self, schedule_type: ScheduleType, is745: bool):
|
|
605
|
+
"""Set the schedule type"""
|
|
606
|
+
pass
|
|
607
|
+
|
|
564
608
|
def as_eco_mode_v2(self) -> EcoModeV2:
|
|
565
609
|
"""Convert V1 to V2 EcoMode"""
|
|
566
610
|
result = EcoModeV2(self.id_, self.offset, self.name)
|
|
@@ -617,8 +661,6 @@ class Schedule(Sensor, EcoMode):
|
|
|
617
661
|
self.schedule_type = ScheduleType.detect_schedule_type(self.on_off)
|
|
618
662
|
self.day_bits = read_byte(data)
|
|
619
663
|
self.days = decode_day_of_week(self.day_bits)
|
|
620
|
-
if self.day_bits < 0:
|
|
621
|
-
raise ValueError(f"{self.id_}: day_bits value {self.day_bits} out of range.")
|
|
622
664
|
self.power = read_bytes2_signed(data) # negative=charge, positive=discharge
|
|
623
665
|
if not self.schedule_type.is_in_range(self.power):
|
|
624
666
|
raise ValueError(f"{self.id_}: power value {self.power} out of range.")
|
|
@@ -680,6 +722,19 @@ class Schedule(Sensor, EcoMode):
|
|
|
680
722
|
and self.power > 0 \
|
|
681
723
|
and (self.month_bits == 0 or self.month_bits == 0x0fff)
|
|
682
724
|
|
|
725
|
+
def get_schedule_type(self) -> ScheduleType:
|
|
726
|
+
"""Answer the schedule type"""
|
|
727
|
+
return self.schedule_type
|
|
728
|
+
|
|
729
|
+
def set_schedule_type(self, schedule_type: ScheduleType, is745: bool):
|
|
730
|
+
"""Set the schedule type"""
|
|
731
|
+
if schedule_type == ScheduleType.ECO_MODE:
|
|
732
|
+
# try to keep-reuse the type, use is745 only when necessary
|
|
733
|
+
if self.schedule_type not in (ScheduleType.ECO_MODE, ScheduleType.ECO_MODE_745):
|
|
734
|
+
self.schedule_type = ScheduleType.ECO_MODE_745 if is745 else ScheduleType.ECO_MODE
|
|
735
|
+
else:
|
|
736
|
+
self.schedule_type = schedule_type
|
|
737
|
+
|
|
683
738
|
def as_eco_mode_v1(self) -> EcoModeV1:
|
|
684
739
|
"""Convert V2 to V1 EcoMode"""
|
|
685
740
|
result = EcoModeV1(self.id_, self.offset, self.name)
|
|
@@ -891,6 +946,10 @@ def decode_bitmap(value: int, bitmap: Dict[int, str]) -> str:
|
|
|
891
946
|
|
|
892
947
|
|
|
893
948
|
def decode_day_of_week(data: int) -> str:
|
|
949
|
+
if data == -1:
|
|
950
|
+
return "Mon-Sun"
|
|
951
|
+
elif data == 0:
|
|
952
|
+
return ""
|
|
894
953
|
bits = bin(data)[2:]
|
|
895
954
|
daynames = list(DAY_NAMES)
|
|
896
955
|
days = ""
|
|
@@ -904,7 +963,7 @@ def decode_day_of_week(data: int) -> str:
|
|
|
904
963
|
|
|
905
964
|
|
|
906
965
|
def decode_months(data: int) -> str | None:
|
|
907
|
-
if data
|
|
966
|
+
if data <= 0 or data == 0x0fff:
|
|
908
967
|
return None
|
|
909
968
|
bits = bin(data)[2:]
|
|
910
969
|
monthnames = list(MONTH_NAMES)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
goodwe/__init__.py,sha256=PInrrZEpTmMOQKk494vIz8EKSaw_qLBNz-6t9eLIUcg,5642
|
|
2
|
+
goodwe/const.py,sha256=Nw-nd4UJuqUOLfbmOrxTHEdS1AuaTDSpZzQqR6tBb8w,7912
|
|
3
|
+
goodwe/dt.py,sha256=bI53MVdZjtxTYU2qJLO8icsvF6UiXrkgH95V3iUwXT0,10581
|
|
4
|
+
goodwe/es.py,sha256=KZLBydRSzzAnbI8-o_-sKiJeunJGuCKr7N8V8_Ft__U,22434
|
|
5
|
+
goodwe/et.py,sha256=P4H5Q17Gx8V8Y9os5HfiECsVIZ1znx13pGRFzc93n54,39228
|
|
6
|
+
goodwe/exceptions.py,sha256=I6PHG0GTWgxNrDVZwJZBnyzItRq5eiM6ci23-EEsn1I,1012
|
|
7
|
+
goodwe/inverter.py,sha256=uiQdti_4lGVLrSG94GgxgALWuevY6hl9ekdHQTomR-0,10325
|
|
8
|
+
goodwe/modbus.py,sha256=ZPib-zKnOVE5zc0RNnhlf0w_26QBees1ScWGo6bAj0o,4685
|
|
9
|
+
goodwe/model.py,sha256=dWBjMFJMnhZoUdDd9fGT54DERDANz4TirK0Wy8kWMbk,2068
|
|
10
|
+
goodwe/protocol.py,sha256=pUkXTP2DqpKXGO7rbRfHq1x82Y1QM6OiRVx8cAtS0sM,13162
|
|
11
|
+
goodwe/sensor.py,sha256=cPZCC3_9gk5zPVTkzhuDa6byz_dM4xCyE8FtV5nxqgg,36845
|
|
12
|
+
goodwe-0.3.3.dist-info/LICENSE,sha256=aZAhk3lRdYT1YZV-IKRHISEcc_KNUmgfuNO3QhRamNM,1073
|
|
13
|
+
goodwe-0.3.3.dist-info/METADATA,sha256=0sEhEL3Uv3TSMsOTCqZSE1YEpeoDD609fcQodacEIvs,3050
|
|
14
|
+
goodwe-0.3.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
15
|
+
goodwe-0.3.3.dist-info/top_level.txt,sha256=kKoiqiVvAxDaDJYMZZQLgHQj9cuWT1MXLfXElTDuf8s,7
|
|
16
|
+
goodwe-0.3.3.dist-info/RECORD,,
|
goodwe-0.3.2.dist-info/RECORD
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
goodwe/__init__.py,sha256=PInrrZEpTmMOQKk494vIz8EKSaw_qLBNz-6t9eLIUcg,5642
|
|
2
|
-
goodwe/const.py,sha256=Nw-nd4UJuqUOLfbmOrxTHEdS1AuaTDSpZzQqR6tBb8w,7912
|
|
3
|
-
goodwe/dt.py,sha256=bI53MVdZjtxTYU2qJLO8icsvF6UiXrkgH95V3iUwXT0,10581
|
|
4
|
-
goodwe/es.py,sha256=d0RyW70dnxaMNVZzSxE7eEoW2dMDzQQxA4MlSADOyuo,22417
|
|
5
|
-
goodwe/et.py,sha256=zQUZAhaC4HUV_0hzF6M85ffXasBBKSbpNkT_x37EZjw,38443
|
|
6
|
-
goodwe/exceptions.py,sha256=I6PHG0GTWgxNrDVZwJZBnyzItRq5eiM6ci23-EEsn1I,1012
|
|
7
|
-
goodwe/inverter.py,sha256=HvVtFBz5Zvl1je1V2AuLqpoB1vsur_gDHu-6SjNbJ8o,10323
|
|
8
|
-
goodwe/modbus.py,sha256=ZPib-zKnOVE5zc0RNnhlf0w_26QBees1ScWGo6bAj0o,4685
|
|
9
|
-
goodwe/model.py,sha256=Yy662c6VpuLozxo1Q7Llw1g34UhT5qJd9_rITIjmEd4,1523
|
|
10
|
-
goodwe/protocol.py,sha256=pUkXTP2DqpKXGO7rbRfHq1x82Y1QM6OiRVx8cAtS0sM,13162
|
|
11
|
-
goodwe/sensor.py,sha256=M8v3flB4V7VxY91G1m2a1tdaD5j_lqtVzkxxrcTFHmE,34696
|
|
12
|
-
goodwe-0.3.2.dist-info/LICENSE,sha256=aZAhk3lRdYT1YZV-IKRHISEcc_KNUmgfuNO3QhRamNM,1073
|
|
13
|
-
goodwe-0.3.2.dist-info/METADATA,sha256=izdqayJnYLUwJt9DPS2oUrgMUxGzNNIDMmokDNb3RNs,3050
|
|
14
|
-
goodwe-0.3.2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
15
|
-
goodwe-0.3.2.dist-info/top_level.txt,sha256=kKoiqiVvAxDaDJYMZZQLgHQj9cuWT1MXLfXElTDuf8s,7
|
|
16
|
-
goodwe-0.3.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|