solax-py-library 1.0.0.23__py3-none-any.whl → 1.0.0.2501__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.
Files changed (48) hide show
  1. solax_py_library/__init__.py +1 -1
  2. solax_py_library/device/core/interver/__init__.py +36 -36
  3. solax_py_library/device/core/interver/base.py +215 -215
  4. solax_py_library/device/types/inverter_config.py +41 -41
  5. solax_py_library/device/types/modbus_point.py +30 -30
  6. solax_py_library/exception.py +10 -10
  7. solax_py_library/smart_scene/__init__.py +0 -0
  8. solax_py_library/smart_scene/constant/__init__.py +0 -0
  9. solax_py_library/smart_scene/constant/message_entry.py +338 -0
  10. solax_py_library/smart_scene/core/__init__.py +0 -0
  11. solax_py_library/smart_scene/core/action/__init__.py +0 -0
  12. solax_py_library/smart_scene/core/condition/__init__.py +0 -0
  13. solax_py_library/smart_scene/core/condition/base.py +12 -0
  14. solax_py_library/smart_scene/core/condition/cabinet_condition.py +104 -0
  15. solax_py_library/smart_scene/core/condition/date_condition.py +26 -0
  16. solax_py_library/smart_scene/core/condition/price_condition.py +105 -0
  17. solax_py_library/smart_scene/core/condition/system_condition.py +41 -0
  18. solax_py_library/smart_scene/core/condition/weather_condition.py +67 -0
  19. solax_py_library/smart_scene/exceptions/__init__.py +0 -0
  20. solax_py_library/smart_scene/exceptions/price.py +5 -0
  21. solax_py_library/smart_scene/exceptions/smart_scene.py +81 -0
  22. solax_py_library/smart_scene/exceptions/weather.py +5 -0
  23. solax_py_library/smart_scene/types/__init__.py +0 -0
  24. solax_py_library/smart_scene/types/action.py +156 -0
  25. solax_py_library/smart_scene/types/condition.py +293 -0
  26. solax_py_library/smart_scene/types/smart_scene_content.py +173 -0
  27. solax_py_library/snap_shot/__init__.py +3 -3
  28. solax_py_library/snap_shot/constant/__init__.py +5 -5
  29. solax_py_library/snap_shot/constant/crc_table.py +258 -258
  30. solax_py_library/snap_shot/core/base_modbus.py +14 -14
  31. solax_py_library/snap_shot/core/parser.py +261 -225
  32. solax_py_library/snap_shot/core/snap_shot.py +25 -7
  33. solax_py_library/snap_shot/exceptions/__init__.py +3 -3
  34. solax_py_library/snap_shot/exceptions/snap_shot.py +9 -9
  35. solax_py_library/snap_shot/types/__init__.py +15 -15
  36. solax_py_library/snap_shot/types/address.py +39 -39
  37. solax_py_library/upload/__init__.py +3 -3
  38. solax_py_library/upload/api/service.py +24 -24
  39. solax_py_library/upload/core/upload_service/ftp.py +1 -0
  40. solax_py_library/upload/exceptions/__init__.py +8 -8
  41. solax_py_library/upload/exceptions/upload_error.py +21 -21
  42. solax_py_library/utils/cloud_client.py +213 -0
  43. solax_py_library/utils/struct_util.py +30 -30
  44. solax_py_library/utils/time_util.py +5 -0
  45. {solax_py_library-1.0.0.23.dist-info → solax_py_library-1.0.0.2501.dist-info}/METADATA +1 -1
  46. solax_py_library-1.0.0.2501.dist-info/RECORD +68 -0
  47. solax_py_library-1.0.0.23.dist-info/RECORD +0 -46
  48. {solax_py_library-1.0.0.23.dist-info → solax_py_library-1.0.0.2501.dist-info}/WHEEL +0 -0
@@ -1,15 +1,15 @@
1
- from .address import (
2
- SnapshotMCUSource,
3
- SnapshotRegisterAddress,
4
- SnapshotStartResult,
5
- SnapshotExportDevice,
6
- CommandType,
7
- )
8
-
9
- __all__ = [
10
- "SnapshotMCUSource",
11
- "SnapshotRegisterAddress",
12
- "SnapshotStartResult",
13
- "SnapshotExportDevice",
14
- "CommandType",
15
- ]
1
+ from .address import (
2
+ SnapshotMCUSource,
3
+ SnapshotRegisterAddress,
4
+ SnapshotStartResult,
5
+ SnapshotExportDevice,
6
+ CommandType,
7
+ )
8
+
9
+ __all__ = [
10
+ "SnapshotMCUSource",
11
+ "SnapshotRegisterAddress",
12
+ "SnapshotStartResult",
13
+ "SnapshotExportDevice",
14
+ "CommandType",
15
+ ]
@@ -1,39 +1,39 @@
1
- from enum import IntEnum
2
-
3
-
4
- class SnapshotMCUSource(IntEnum):
5
- MCU_SOURCE_MDSP = 0
6
- MCU_SOURCE_SDSP = 1
7
-
8
-
9
- class SnapshotExportDevice(IntEnum):
10
- EXPORT_DEVICE_UART = 0
11
- EXPORT_DEVICE_USB = 1
12
-
13
-
14
- class SnapshotStartResult(IntEnum):
15
- SNAPSHOT_START_START = 0xAAAA
16
- SNAPSHOT_START_SUCCESS = 0xA5A5
17
- SNAPSHOT_START_FAILED = 0x5A5A
18
- SNAPSHOT_START_STOP = 0xBBBB
19
-
20
-
21
- class SnapshotRegisterAddress(IntEnum):
22
- SNAPSHOT_REGISTERADDRESS_MCUSOURCE = 0x4011
23
- SNAPSHOT_REGISTERADDRESS_EXPORTDEVICE = 0x4012
24
- SNAPSHOT_REGISTERADDRESS_START = 0x4013
25
- SNAPSHOT_REGISTERADDRESS_TOTALNUMBER = 0x4070
26
- SNAPSHOT_REGISTERADDRESS_SNAPSHOTINDEX = 0x4071
27
- SNAPSHOT_REGISTERADDRESS_PACKDATASTATUS = 0x4072
28
- SNAPSHOT_REGISTERADDRESS_DATASIZE = 0x4073
29
- SNAPSHOT_REGISTERADDRESS_CHANNELNUMBER = 0x4074
30
- SNAPSHOT_REGISTERADDRESS_CHANNELDATASIZE = 0x4075
31
- SNAPSHOT_REGISTERADDRESS_PACKINDEX = 0x407F
32
- SNAPSHOT_REGISTERADDRESS_PACKDATA = 0x4080
33
-
34
-
35
- class CommandType(IntEnum):
36
- ACK = 0x80 # 接收应答
37
- TOTAL_PACKETS = 0x81 # 上报总包数
38
- DATA_PACKET = 0x82 # 具体分包数据
39
- ERROR = 0x83 # 报错应答
1
+ from enum import IntEnum
2
+
3
+
4
+ class SnapshotMCUSource(IntEnum):
5
+ MCU_SOURCE_MDSP = 0
6
+ MCU_SOURCE_SDSP = 1
7
+
8
+
9
+ class SnapshotExportDevice(IntEnum):
10
+ EXPORT_DEVICE_UART = 0
11
+ EXPORT_DEVICE_USB = 1
12
+
13
+
14
+ class SnapshotStartResult(IntEnum):
15
+ SNAPSHOT_START_START = 0xAAAA
16
+ SNAPSHOT_START_SUCCESS = 0xA5A5
17
+ SNAPSHOT_START_FAILED = 0x5A5A
18
+ SNAPSHOT_START_STOP = 0xBBBB
19
+
20
+
21
+ class SnapshotRegisterAddress(IntEnum):
22
+ SNAPSHOT_REGISTERADDRESS_MCUSOURCE = 0x4011
23
+ SNAPSHOT_REGISTERADDRESS_EXPORTDEVICE = 0x4012
24
+ SNAPSHOT_REGISTERADDRESS_START = 0x4013
25
+ SNAPSHOT_REGISTERADDRESS_TOTALNUMBER = 0x4070
26
+ SNAPSHOT_REGISTERADDRESS_SNAPSHOTINDEX = 0x4071
27
+ SNAPSHOT_REGISTERADDRESS_PACKDATASTATUS = 0x4072
28
+ SNAPSHOT_REGISTERADDRESS_DATASIZE = 0x4073
29
+ SNAPSHOT_REGISTERADDRESS_CHANNELNUMBER = 0x4074
30
+ SNAPSHOT_REGISTERADDRESS_CHANNELDATASIZE = 0x4075
31
+ SNAPSHOT_REGISTERADDRESS_PACKINDEX = 0x407F
32
+ SNAPSHOT_REGISTERADDRESS_PACKDATA = 0x4080
33
+
34
+
35
+ class CommandType(IntEnum):
36
+ ACK = 0x80 # 接收应答
37
+ TOTAL_PACKETS = 0x81 # 上报总包数
38
+ DATA_PACKET = 0x82 # 具体分包数据
39
+ ERROR = 0x83 # 报错应答
@@ -1,3 +1,3 @@
1
- from . import api, types, core, exceptions
2
-
3
- __all__ = ["api", "core", "exceptions", "types"]
1
+ from . import api, types, core, exceptions
2
+
3
+ __all__ = ["api", "core", "exceptions", "types"]
@@ -1,24 +1,24 @@
1
- from typing import Dict, Any
2
-
3
- from solax_py_library.upload.core.upload_service import upload_service_map
4
- from solax_py_library.exception import SolaxBaseError
5
- from solax_py_library.upload.types.client import UploadType, UploadData
6
-
7
-
8
- def upload_service(upload_type: UploadType, configuration: Dict[str, Any]):
9
- """
10
- upload_type: 上传类型。
11
- configuration: 配置信息
12
- """
13
- upload_class = upload_service_map.get(upload_type)
14
- if not upload_class:
15
- raise SolaxBaseError
16
- return upload_class(**configuration)
17
-
18
-
19
- async def upload(
20
- upload_type: UploadType, configuration: Dict[str, Any], upload_data: UploadData
21
- ):
22
- service = upload_service(upload_type, configuration)
23
- with service as s:
24
- await s.upload(upload_data)
1
+ from typing import Dict, Any
2
+
3
+ from solax_py_library.upload.core.upload_service import upload_service_map
4
+ from solax_py_library.exception import SolaxBaseError
5
+ from solax_py_library.upload.types.client import UploadType, UploadData
6
+
7
+
8
+ def upload_service(upload_type: UploadType, configuration: Dict[str, Any]):
9
+ """
10
+ upload_type: 上传类型。
11
+ configuration: 配置信息
12
+ """
13
+ upload_class = upload_service_map.get(upload_type)
14
+ if not upload_class:
15
+ raise SolaxBaseError
16
+ return upload_class(**configuration)
17
+
18
+
19
+ async def upload(
20
+ upload_type: UploadType, configuration: Dict[str, Any], upload_data: UploadData
21
+ ):
22
+ service = upload_service(upload_type, configuration)
23
+ with service as s:
24
+ await s.upload(upload_data)
@@ -79,6 +79,7 @@ class FTPUploadService(BaseUploadService):
79
79
  try:
80
80
  if not self._is_connect:
81
81
  raise ConnectError(message="not connect yet")
82
+ # self._client.set_pasv(False)
82
83
  self._cwd_folder()
83
84
  with open(data.file_path, "rb") as f:
84
85
  self._client.storbinary(f"STOR {data.file_name}", f)
@@ -1,8 +1,8 @@
1
- from .upload_error import ConfigurationError, ConnectError, LoginError, SendDataError
2
-
3
- __all__ = [
4
- "ConnectError",
5
- "LoginError",
6
- "SendDataError",
7
- "ConfigurationError",
8
- ]
1
+ from .upload_error import ConfigurationError, ConnectError, LoginError, SendDataError
2
+
3
+ __all__ = [
4
+ "ConnectError",
5
+ "LoginError",
6
+ "SendDataError",
7
+ "ConfigurationError",
8
+ ]
@@ -1,21 +1,21 @@
1
- from solax_py_library.exception import SolaxBaseError
2
-
3
-
4
- class ConnectError(SolaxBaseError):
5
- code = 0x1001
6
- message = "connect error"
7
-
8
-
9
- class LoginError(SolaxBaseError):
10
- code = 0x1002
11
- message = "authentication error"
12
-
13
-
14
- class SendDataError(SolaxBaseError):
15
- code = 0x1003
16
- message = "send data error"
17
-
18
-
19
- class ConfigurationError(SolaxBaseError):
20
- code = 0x1004
21
- message = "server configuration error"
1
+ from solax_py_library.exception import SolaxBaseError
2
+
3
+
4
+ class ConnectError(SolaxBaseError):
5
+ code = 0x1001
6
+ message = "connect error"
7
+
8
+
9
+ class LoginError(SolaxBaseError):
10
+ code = 0x1002
11
+ message = "authentication error"
12
+
13
+
14
+ class SendDataError(SolaxBaseError):
15
+ code = 0x1003
16
+ message = "send data error"
17
+
18
+
19
+ class ConfigurationError(SolaxBaseError):
20
+ code = 0x1004
21
+ message = "server configuration error"
@@ -0,0 +1,213 @@
1
+ import json
2
+ import traceback
3
+ from datetime import datetime
4
+
5
+ import requests
6
+
7
+ from solax_py_library.utils.time_util import trans_str_time_to_index
8
+
9
+
10
+ class CloudClient:
11
+ def get_token(self, cloud_url, ems_sn, sn_secret):
12
+ token_url = cloud_url + "/device/token/getByRegistrationSn"
13
+ try:
14
+ response = requests.post(
15
+ token_url,
16
+ json={
17
+ "registrationSn": ems_sn,
18
+ "snSecret": sn_secret,
19
+ },
20
+ timeout=5
21
+ )
22
+ if response.content:
23
+ response_data = json.loads(response.content)
24
+ print(f"获取token结果 {response_data}")
25
+ if response_data.get("code") == 0 and response_data.get("result"):
26
+ token = response_data["result"]
27
+ return token
28
+ except Exception as e:
29
+ print(f"访问token接口失败: {str(e)}")
30
+
31
+ def get_weather_data_from_cloud(self, cloud_url, ems_sn, sn_secret):
32
+ """获取未来24小时天气数据"""
33
+ try:
34
+ token = self.get_token(cloud_url, ems_sn, sn_secret)
35
+ if not token:
36
+ return False
37
+ weather_url = cloud_url + "/ess/web/v1/powerStation/station/solcast/get"
38
+ headers = {"token": token, "Content-Type": "application/json"}
39
+ post_dict = {"registerNo": ems_sn, "day": 1}
40
+ response = requests.post(
41
+ url=weather_url, data=json.dumps(post_dict), headers=headers, timeout=5
42
+ )
43
+ # 访问失败或获取数据失败,则重复插入最后一条数据
44
+ if response.status_code != 200:
45
+ print(f"获取天气数据失败 状态码 {response.status_code}")
46
+ return False
47
+ response_data = response.json()
48
+ if response_data.get("result") is None:
49
+ print(f"获取天气数据失败 返回数据 {response_data}")
50
+ return False
51
+ weather_info = {
52
+ "timeList": [],
53
+ "irradiance": {"valueList": []},
54
+ "temperature": {"valueList": []},
55
+ "humidity": {"valueList": []},
56
+ "wind": {"valueList": []},
57
+ "barometricPressure": {"valueList": []},
58
+ "rain": {"valueList": []},
59
+ }
60
+ for info in response_data["result"]:
61
+ weather_info["timeList"].append(info["localTime"])
62
+ weather_info["irradiance"]["valueList"].append(float(info["ghi"]))
63
+ weather_info["temperature"]["valueList"].append(float(info["air_temp"]))
64
+ weather_info["humidity"]["valueList"].append(
65
+ float(info["relative_humidity"])
66
+ )
67
+ weather_info["wind"]["valueList"].append(float(info["wind_speed_10m"]))
68
+ weather_info["barometricPressure"]["valueList"].append(
69
+ float(info.get("surface_pressure", 0))
70
+ )
71
+ rain = 1 if float(info["precipitation_rate"]) > 2.5 else 0
72
+ weather_info["rain"]["valueList"].append(rain)
73
+ data_length = len(weather_info["irradiance"]["valueList"])
74
+ if weather_info["timeList"] == []:
75
+ weather_info = {}
76
+ else:
77
+ weather_info["irradiance"]["maxValue"] = max(
78
+ weather_info["irradiance"]["valueList"]
79
+ )
80
+ weather_info["irradiance"]["avgValue"] = round(
81
+ sum(weather_info["irradiance"]["valueList"]) / data_length, 3
82
+ )
83
+ weather_info["irradiance"]["minValue"] = min(
84
+ weather_info["irradiance"]["valueList"]
85
+ )
86
+
87
+ weather_info["temperature"]["maxValue"] = max(
88
+ weather_info["temperature"]["valueList"]
89
+ )
90
+ weather_info["temperature"]["avgValue"] = round(
91
+ sum(weather_info["temperature"]["valueList"]) / data_length, 3
92
+ )
93
+ weather_info["temperature"]["minValue"] = min(
94
+ weather_info["temperature"]["valueList"]
95
+ )
96
+
97
+ weather_info["humidity"]["maxValue"] = max(
98
+ weather_info["humidity"]["valueList"]
99
+ )
100
+ weather_info["humidity"]["avgValue"] = round(
101
+ sum(weather_info["humidity"]["valueList"]) / data_length, 3
102
+ )
103
+ weather_info["humidity"]["minValue"] = min(
104
+ weather_info["humidity"]["valueList"]
105
+ )
106
+
107
+ weather_info["wind"]["maxValue"] = max(
108
+ weather_info["wind"]["valueList"]
109
+ )
110
+ weather_info["wind"]["avgValue"] = round(
111
+ sum(weather_info["wind"]["valueList"]) / data_length, 3
112
+ )
113
+ weather_info["wind"]["minValue"] = min(
114
+ weather_info["wind"]["valueList"]
115
+ )
116
+
117
+ weather_info["barometricPressure"]["maxValue"] = max(
118
+ weather_info["barometricPressure"]["valueList"]
119
+ )
120
+ weather_info["barometricPressure"]["avgValue"] = round(
121
+ sum(weather_info["barometricPressure"]["valueList"]) / data_length,
122
+ 3,
123
+ )
124
+ weather_info["barometricPressure"]["minValue"] = min(
125
+ weather_info["barometricPressure"]["valueList"]
126
+ )
127
+
128
+ weather_info["rain"]["maxValue"] = max(
129
+ weather_info["rain"]["valueList"]
130
+ )
131
+ weather_info["rain"]["minValue"] = min(
132
+ weather_info["rain"]["valueList"]
133
+ )
134
+ return weather_info
135
+ print("获取天气数据成功")
136
+ except Exception:
137
+ print(f"获取天气数据失败 异常 {traceback.format_exc()}")
138
+ return False
139
+
140
+ def get_electrovalence_data_from_cloud(self, cloud_url, ems_sn, sn_secret):
141
+ try:
142
+ token = self.get_token(cloud_url, ems_sn, sn_secret)
143
+ if not token:
144
+ return False
145
+ price_url = cloud_url + "/powerStation/station/getCurrentElectrovalence"
146
+ response = requests.post(
147
+ url=price_url,
148
+ headers={"token": token, "Content-Type": "application/json"},
149
+ json={"registerNo": ems_sn},
150
+ timeout=5
151
+ )
152
+ # 访问失败或获取数据失败,则重复插入最后一条数据
153
+ if response.status_code != 200:
154
+ print(f"获取电价数据失败 状态码 {response.status_code}")
155
+ return False
156
+ response_data = response.json()
157
+ if response_data.get("result") is None:
158
+ print(f"获取电价数据失败 返回数据 {response_data}")
159
+ return False
160
+ today = datetime.strftime(datetime.now(), "%Y-%m-%d %H:%M:%S")
161
+ ele_price_info = {
162
+ "buy": [None] * 192,
163
+ "sell": [None] * 192,
164
+ "date": today,
165
+ }
166
+ ele_price_info["ele_unit"] = response_data["result"]["unit"]
167
+ if ele_price_info["ele_unit"] == "¥":
168
+ rate = 1
169
+ ele_price_info["ele_unit"] = "¥/kWh"
170
+ else:
171
+ rate = 100
172
+ ele_price_info["ele_unit"] = "Cents €/kWh"
173
+ for detail_info in response_data["result"]["list"]:
174
+ start_index = trans_str_time_to_index(detail_info["startTime"])
175
+ end_index = trans_str_time_to_index(detail_info["endTime"])
176
+ # 处理欧分的情况
177
+ if detail_info["buyPrice"] is not None:
178
+ buy_price = round(detail_info["buyPrice"] * rate, 5)
179
+ else:
180
+ buy_price = detail_info["buyPrice"]
181
+ if detail_info["salePrice"] is not None:
182
+ sale_price = round(detail_info["salePrice"] * rate, 5)
183
+ else:
184
+ sale_price = detail_info["salePrice"]
185
+ ele_price_info["buy"][start_index:end_index] = [buy_price] * (
186
+ end_index - start_index
187
+ )
188
+ ele_price_info["sell"][start_index:end_index] = [sale_price] * (
189
+ end_index - start_index
190
+ )
191
+ if response_data["result"].get("tomorrow") is not None:
192
+ for detail_info in response_data["result"]["tomorrow"]:
193
+ start_index = trans_str_time_to_index(detail_info["startTime"]) + 96
194
+ end_index = trans_str_time_to_index(detail_info["endTime"]) + 96
195
+ if detail_info["buyPrice"] is not None:
196
+ buy_price = round(detail_info["buyPrice"] * rate, 5)
197
+ else:
198
+ buy_price = detail_info["buyPrice"]
199
+ if detail_info["salePrice"] is not None:
200
+ sale_price = round(detail_info["salePrice"] * rate, 5)
201
+ else:
202
+ sale_price = detail_info["salePrice"]
203
+ ele_price_info["buy"][start_index:end_index] = [buy_price] * (
204
+ end_index - start_index
205
+ )
206
+ ele_price_info["sell"][start_index:end_index] = [sale_price] * (
207
+ end_index - start_index
208
+ )
209
+ print("获取电价数据成功")
210
+ return ele_price_info
211
+ except Exception:
212
+ print(f"获取电价数据失败 异常 {traceback.format_exc()}")
213
+ return False
@@ -1,30 +1,30 @@
1
- import copy
2
- import struct
3
- from typing import List
4
-
5
-
6
- def unpack(data: List, data_format, reversed=False):
7
- """
8
- :param data: 数据字节, 入参均是由modbus读取到的list[uint16]进行转换
9
- :param data_format: 数据格式
10
- :param reversed: 是否翻转大小端
11
- """
12
- cur_data = copy.deepcopy(data)
13
- data_format = data_format.lower()
14
- format_map = {
15
- "int8": "bb",
16
- "uint8": "BB",
17
- "int16": "h",
18
- "uint16": "H",
19
- "int32": "i",
20
- "uint32": "I",
21
- "int64": "q",
22
- "uint64": "Q",
23
- "float": "f",
24
- }
25
- if data_format not in format_map:
26
- raise Exception("暂不支持")
27
- pack_str = ("<" if reversed else ">") + "H" * len(cur_data)
28
- to_pack_data = struct.pack(pack_str, *cur_data)
29
- struct_format = ("<" if reversed else ">") + format_map[data_format]
30
- return struct.unpack(struct_format, to_pack_data)
1
+ import copy
2
+ import struct
3
+ from typing import List
4
+
5
+
6
+ def unpack(data: List, data_format, reversed=False):
7
+ """
8
+ :param data: 数据字节, 入参均是由modbus读取到的list[uint16]进行转换
9
+ :param data_format: 数据格式
10
+ :param reversed: 是否翻转大小端
11
+ """
12
+ cur_data = copy.deepcopy(data)
13
+ data_format = data_format.lower()
14
+ format_map = {
15
+ "int8": "bb",
16
+ "uint8": "BB",
17
+ "int16": "h",
18
+ "uint16": "H",
19
+ "int32": "i",
20
+ "uint32": "I",
21
+ "int64": "q",
22
+ "uint64": "Q",
23
+ "float": "f",
24
+ }
25
+ if data_format not in format_map:
26
+ raise Exception("暂不支持")
27
+ pack_str = ("<" if reversed else ">") + "H" * len(cur_data)
28
+ to_pack_data = struct.pack(pack_str, *cur_data)
29
+ struct_format = ("<" if reversed else ">") + format_map[data_format]
30
+ return struct.unpack(struct_format, to_pack_data)
@@ -0,0 +1,5 @@
1
+ def trans_str_time_to_index(now_time, minute=15):
2
+ """将时间按照minute切换为索引,时间格式为 %H-%M"""
3
+ time_list = [int(i) for i in now_time.split(":")]
4
+ time_int = time_list[0] * 4 + time_list[1] // minute
5
+ return time_int
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: solax-py-library
3
- Version: 1.0.0.23
3
+ Version: 1.0.0.2501
4
4
  Summary: some common tool
5
5
  Author: shenlvyu
6
6
  Author-email: 13296718439@163.com
@@ -0,0 +1,68 @@
1
+ solax_py_library/__init__.py,sha256=4wrB7TuGOQaYHQvdn574G4JrcOnH6l8RNSR6AtKAiKc,34
2
+ solax_py_library/device/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ solax_py_library/device/constant/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ solax_py_library/device/constant/inverter_model_info.py,sha256=Ujnwv79qycOTV_zqqr21wKXXj_lGLgrA56X_-Vjuxqw,18049
5
+ solax_py_library/device/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ solax_py_library/device/core/interver/__init__.py,sha256=RKye2D6NawSGdL4YUp_H-LmKIjThBp9CWhb6zwyM97s,1153
7
+ solax_py_library/device/core/interver/base.py,sha256=2TXHsjigMcIvGDLF3ZD4dw6UDrRRAk9Mq6sdBKRvydc,7191
8
+ solax_py_library/device/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ solax_py_library/device/types/inverter_config.py,sha256=qCInNPbgsWf6yQjSw59kfQtJJWilMYUhvx_qo5qwRlU,912
10
+ solax_py_library/device/types/modbus_point.py,sha256=YmXe92gWXL_voVXDJE5zzNzr6dpPs7Ff3ciOAW-LgPs,580
11
+ solax_py_library/exception.py,sha256=ygAccdTqJctRrdt9bu6-vqZP5KadfKVS_1tjt4KcRn8,257
12
+ solax_py_library/smart_scene/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ solax_py_library/smart_scene/constant/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ solax_py_library/smart_scene/constant/message_entry.py,sha256=wTd9_yBMesHhj-Ws5OncHq-JnU_W8XBoWCxhZYUhJ2U,9118
15
+ solax_py_library/smart_scene/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ solax_py_library/smart_scene/core/action/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ solax_py_library/smart_scene/core/condition/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
+ solax_py_library/smart_scene/core/condition/base.py,sha256=r3YRW5jsza0HWQtiisI_Pf9UROvTsG0CgTElpK9xbKg,339
19
+ solax_py_library/smart_scene/core/condition/cabinet_condition.py,sha256=MoP8pi7O9vVDCoSXx4kQApIyk-vYlHP8JtszNqqzELg,4492
20
+ solax_py_library/smart_scene/core/condition/date_condition.py,sha256=cuS2Pn6EO8IAJgenkn9FZy_Ml9SeyA_nG8HeAM28_Pg,894
21
+ solax_py_library/smart_scene/core/condition/price_condition.py,sha256=REIDSxVkkWoAz9YV6QRlqwM01vGSCvE6Xn3zgmngUAc,3934
22
+ solax_py_library/smart_scene/core/condition/system_condition.py,sha256=JdoWc8wHpP55AIR2srG8Bvm4VfPalnC-MmJKSJdE9fY,1546
23
+ solax_py_library/smart_scene/core/condition/weather_condition.py,sha256=bhv4x3xcYn4-qcoNHCzj7y_yMqcreQllBUqIN5csclg,2583
24
+ solax_py_library/smart_scene/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
+ solax_py_library/smart_scene/exceptions/price.py,sha256=ztsM8leCsxbzx1TYS5GQAVbfvxlU49QymS1NUykqM_g,142
26
+ solax_py_library/smart_scene/exceptions/smart_scene.py,sha256=VFjRe7fUg5JA13Wg8BFvxzlF-pBSNaGJJBpnphYdSbM,1774
27
+ solax_py_library/smart_scene/exceptions/weather.py,sha256=bJl1VwiIXEpLQ9VjlVrDoTAIMFqVZdRCas7dtR7eAJc,133
28
+ solax_py_library/smart_scene/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
+ solax_py_library/smart_scene/types/action.py,sha256=YP2BRd24BILn82Dj6xGzaa8zypuLyx5BS_YNx6SJjNQ,5565
30
+ solax_py_library/smart_scene/types/condition.py,sha256=NlTKATka1mI0G94Fx1m4ouVUZ9ZeMPocfZooQyiKTPM,9381
31
+ solax_py_library/smart_scene/types/smart_scene_content.py,sha256=-aehAnRz_dTZmiRYTUpMYvl63UOokRiS_l4cbGPz8IE,6005
32
+ solax_py_library/snap_shot/__init__.py,sha256=Ex12q6BCkdU-3OP-f-ehGCetJJWnoZ7KxhEDd_lXh6M,81
33
+ solax_py_library/snap_shot/constant/__init__.py,sha256=UNfjAlx1wovXc1oH74af9oIe2TljwCCiTzNXzWgtUms,65
34
+ solax_py_library/snap_shot/constant/crc_table.py,sha256=D-pSxpf1XDzu7YR8LmbnzdLRvI8exDL2dyDh7RRc4Io,3566
35
+ solax_py_library/snap_shot/core/__init__.py,sha256=lovGQAEfqxPaLlE6gr9HJjgsKjZZLosgaWeGO0Q_JCI,178
36
+ solax_py_library/snap_shot/core/base_modbus.py,sha256=EdDSRvRC2a4IE_LGvjxGznqi6AX5x4O0_Wn1IkHzIpA,403
37
+ solax_py_library/snap_shot/core/parser.py,sha256=IM7SWqbRHGk9KwVRwP3jwht6tGIMClagdszodGiEJ_c,8999
38
+ solax_py_library/snap_shot/core/snap_shot.py,sha256=j6exbbzahmYtoCRsG9e5S64Lw2DOYgOFKtOfa0oz8xY,11109
39
+ solax_py_library/snap_shot/exceptions/__init__.py,sha256=9wLhmIelRKCXvlymcu3EewasVVYuPu4QQxTDLjGj6NQ,112
40
+ solax_py_library/snap_shot/exceptions/snap_shot.py,sha256=-oxxh_lUhfZwtggJ4zfNBPdkhdGPvcVvDezNlj4nFfY,154
41
+ solax_py_library/snap_shot/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
+ solax_py_library/snap_shot/types/__init__.py,sha256=g9ybB88TntvAMGIhLgJ31Xxn26zluSfI496bg-apSTU,290
43
+ solax_py_library/snap_shot/types/address.py,sha256=JhyB-t2OnKuE8akKk120sojCNXv4_OlLLuWsl5ChFZ8,1148
44
+ solax_py_library/upload/__init__.py,sha256=XhZar7BKaRN0XcdPl4QffWr488L3UWvuq5syT8nX2OU,93
45
+ solax_py_library/upload/api/__init__.py,sha256=ASShe-YQxP0aA3B_I8EmpWKXIdXPWvaANifrzlYrFEk,84
46
+ solax_py_library/upload/api/service.py,sha256=-APuz86t4loCkjzaxq02kuKrB6jxaPV-Tz1V__j6cY0,763
47
+ solax_py_library/upload/core/__init__.py,sha256=XMcnyDzCfsLwWaTAZt9-an7TuwYFqVNSt9W1_QRUrwA,89
48
+ solax_py_library/upload/core/data_adapter/__init__.py,sha256=9CXepLZSOjZMfNjyYKAWQCWZt353kTL_0tFBlIeUIOo,116
49
+ solax_py_library/upload/core/data_adapter/base.py,sha256=Va-SEe0eL3gobhNOnzHGkYBLIwf5RVawQdYRHHXg9g0,170
50
+ solax_py_library/upload/core/data_adapter/csv.py,sha256=8nlnV_43mMAR3re50MQJymzT5HYpZOo7eSeMsEfnEVE,861
51
+ solax_py_library/upload/core/upload_service/__init__.py,sha256=uA-UeH31rDNxByeZwvPhNFHPV_-J8JyCev8geuc---k,269
52
+ solax_py_library/upload/core/upload_service/base.py,sha256=dxCBVtPxDhN7oRTjnwnjtc2XAF4hyIz9HsYCJePlggg,912
53
+ solax_py_library/upload/core/upload_service/ftp.py,sha256=3Immu1SfJZ6vXIoUpDSx1_C4Saa0x9pNg-XgJCf7Fhg,3277
54
+ solax_py_library/upload/exceptions/__init__.py,sha256=12D68_mODfJkVFa1f65QgPUn8bvD5BDAeiHgNgU0258,186
55
+ solax_py_library/upload/exceptions/upload_error.py,sha256=V2_yEMLj9KQEkdQ0Cm1DOogbjZWGb4p8RVnFx7D9yLY,425
56
+ solax_py_library/upload/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
+ solax_py_library/upload/test/test_ftp.py,sha256=NPIt_BjSt_PH6XMP9c_7p7nAuktUyKu82_zTRgO8Cfw,3809
58
+ solax_py_library/upload/types/__init__.py,sha256=og9KBpYbcs36_S1izURj3vyHeuNOLJQrD9GpxK_JJaw,244
59
+ solax_py_library/upload/types/client.py,sha256=fG674_QEpOw3ibO171lcxJ0cz27yGR_sd3zgiyr4yuI,492
60
+ solax_py_library/upload/types/ftp.py,sha256=9kCeLB0g5Je19v4ifz8YYEsGOhJL1lKBO2C6V2VBndc,679
61
+ solax_py_library/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
+ solax_py_library/utils/cloud_client.py,sha256=QbINoIMAxMm3UHr-lSL_MuZUbMR2SKvgy1TefRxmZdg,9809
63
+ solax_py_library/utils/common.py,sha256=bfnZcX9uM-PjJrYAFv1UMmZgt6bGR7MaOd7jRPNHGxw,1238
64
+ solax_py_library/utils/struct_util.py,sha256=4SKx5IyAke88PGHPHDK3OEDtyGHdapGoQ1BnGR0F2ts,913
65
+ solax_py_library/utils/time_util.py,sha256=oVnC-NrPrVggvrhnDnUAeZOJmfgUXuY_P9jKKsgFweI,252
66
+ solax_py_library-1.0.0.2501.dist-info/METADATA,sha256=zlm5HzCMmKvfd90-1KoAIcAW05ntKT3qIB7csMkOyRQ,1792
67
+ solax_py_library-1.0.0.2501.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
68
+ solax_py_library-1.0.0.2501.dist-info/RECORD,,
@@ -1,46 +0,0 @@
1
- solax_py_library/__init__.py,sha256=zLUfOeLUGy1sFFu4tZI8cDlfuEATRZ3VcYywVhPLObE,35
2
- solax_py_library/device/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- solax_py_library/device/constant/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- solax_py_library/device/constant/inverter_model_info.py,sha256=Ujnwv79qycOTV_zqqr21wKXXj_lGLgrA56X_-Vjuxqw,18049
5
- solax_py_library/device/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- solax_py_library/device/core/interver/__init__.py,sha256=gnERg9RssRoZvfylG5CgXT8XiwwCf5hQ5_phch6lQM8,1189
7
- solax_py_library/device/core/interver/base.py,sha256=8Zexb1ELWQkD_3LzYyEK7Oro0z71nl2m72RSA5w0bZQ,7406
8
- solax_py_library/device/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- solax_py_library/device/types/inverter_config.py,sha256=8oNO0PkoBrvCe9XnKpuz8QSs7A0jpW2l-vG6IttV0lA,953
10
- solax_py_library/device/types/modbus_point.py,sha256=vukTJhqw7ZxFs4T2hbo975ZW0-oMUIKSF6CLF9muhoU,610
11
- solax_py_library/exception.py,sha256=1NNSqi--RC_sEv_1uJ1z01QVBIs8lNe1YemzND_Vluo,267
12
- solax_py_library/snap_shot/__init__.py,sha256=50fik3nxjnQoLIFEecc6c557pRtpQ1OxAqjp5HFgfe0,84
13
- solax_py_library/snap_shot/constant/__init__.py,sha256=vFoN2ZJWjhpXBQ4BU9vUa9GnvRYA6253bcTZ_nec7AQ,70
14
- solax_py_library/snap_shot/constant/crc_table.py,sha256=mTRYF3f7SxvVcVfFNHsgMMiXj2A_GGjRWfWXv4TSMNs,3824
15
- solax_py_library/snap_shot/core/__init__.py,sha256=lovGQAEfqxPaLlE6gr9HJjgsKjZZLosgaWeGO0Q_JCI,178
16
- solax_py_library/snap_shot/core/base_modbus.py,sha256=hd8047JdB97X9sF3ZzzjR8YjUNV7qWc0T6xtJEg5Pvs,417
17
- solax_py_library/snap_shot/core/parser.py,sha256=pIpQBMkS79BrSvdl2WPGCbVcaGAn0eACCkkdkCKHCvE,7928
18
- solax_py_library/snap_shot/core/snap_shot.py,sha256=W5m9K5VDIgPiyzv8BoxqfnzZgXvtlFWkuSXqURo-6uE,10471
19
- solax_py_library/snap_shot/exceptions/__init__.py,sha256=PZt5-dSRyBmRVjgBrFseZ_vpOLb8gThRnTtlw4bWP9Y,115
20
- solax_py_library/snap_shot/exceptions/snap_shot.py,sha256=8afTk1Y09Pu47yA1yOvu7kxxxZavob1yvDBYlI0WP9w,163
21
- solax_py_library/snap_shot/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
- solax_py_library/snap_shot/types/__init__.py,sha256=wQRjRVD-bBTAAoVPh69XgmDQfl-pVmS1DzZYhphixlg,305
23
- solax_py_library/snap_shot/types/address.py,sha256=8bheI03XMXXMNr7rFHkf9ZdacyGeQgc63bGP9bsojck,1187
24
- solax_py_library/upload/__init__.py,sha256=V8QbJ1xmaJZBHWRxBo_OzIrs50Y56QsH9T7qn3kY3M8,96
25
- solax_py_library/upload/api/__init__.py,sha256=ASShe-YQxP0aA3B_I8EmpWKXIdXPWvaANifrzlYrFEk,84
26
- solax_py_library/upload/api/service.py,sha256=FSAz-WWHRG72vE45gu73n0hheyXuB94GQdgSMfqusOA,787
27
- solax_py_library/upload/core/__init__.py,sha256=XMcnyDzCfsLwWaTAZt9-an7TuwYFqVNSt9W1_QRUrwA,89
28
- solax_py_library/upload/core/data_adapter/__init__.py,sha256=9CXepLZSOjZMfNjyYKAWQCWZt353kTL_0tFBlIeUIOo,116
29
- solax_py_library/upload/core/data_adapter/base.py,sha256=Va-SEe0eL3gobhNOnzHGkYBLIwf5RVawQdYRHHXg9g0,170
30
- solax_py_library/upload/core/data_adapter/csv.py,sha256=8nlnV_43mMAR3re50MQJymzT5HYpZOo7eSeMsEfnEVE,861
31
- solax_py_library/upload/core/upload_service/__init__.py,sha256=uA-UeH31rDNxByeZwvPhNFHPV_-J8JyCev8geuc---k,269
32
- solax_py_library/upload/core/upload_service/base.py,sha256=dxCBVtPxDhN7oRTjnwnjtc2XAF4hyIz9HsYCJePlggg,912
33
- solax_py_library/upload/core/upload_service/ftp.py,sha256=QGgL1wJwRFwIUaAWNqH4oupeu0W0bAN6CLffCil0GHc,3234
34
- solax_py_library/upload/exceptions/__init__.py,sha256=iSPPPHBP_aG9-9OCR_tCrGihL-uEIpSwvi9JZxSYbUk,194
35
- solax_py_library/upload/exceptions/upload_error.py,sha256=sqJvooTZxM9eKqFUV5-sI101xw24ubEdyUZq4mG8sbM,446
36
- solax_py_library/upload/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
- solax_py_library/upload/test/test_ftp.py,sha256=NPIt_BjSt_PH6XMP9c_7p7nAuktUyKu82_zTRgO8Cfw,3809
38
- solax_py_library/upload/types/__init__.py,sha256=og9KBpYbcs36_S1izURj3vyHeuNOLJQrD9GpxK_JJaw,244
39
- solax_py_library/upload/types/client.py,sha256=fG674_QEpOw3ibO171lcxJ0cz27yGR_sd3zgiyr4yuI,492
40
- solax_py_library/upload/types/ftp.py,sha256=9kCeLB0g5Je19v4ifz8YYEsGOhJL1lKBO2C6V2VBndc,679
41
- solax_py_library/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
- solax_py_library/utils/common.py,sha256=bfnZcX9uM-PjJrYAFv1UMmZgt6bGR7MaOd7jRPNHGxw,1238
43
- solax_py_library/utils/struct_util.py,sha256=ER0F6W_QCGM98NItGbQLmdZtbPn1UAZ-qh2tnqHi004,943
44
- solax_py_library-1.0.0.23.dist-info/METADATA,sha256=MSpCrSinQelIEXyz-E09BNvO3EuzpI2IGjlU86linAE,1790
45
- solax_py_library-1.0.0.23.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
46
- solax_py_library-1.0.0.23.dist-info/RECORD,,