solax-py-library 1.0.0.24__py3-none-any.whl → 1.0.0.26__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 (71) hide show
  1. solax_py_library/__init__.py +1 -1
  2. solax_py_library/device/constant/cabinet.py +2 -0
  3. solax_py_library/device/constant/inverter_model_info.py +312 -312
  4. solax_py_library/device/core/interver/__init__.py +36 -36
  5. solax_py_library/device/core/interver/base.py +215 -215
  6. solax_py_library/device/types/alarm.py +16 -0
  7. solax_py_library/device/types/inverter_config.py +41 -41
  8. solax_py_library/device/types/modbus_point.py +30 -30
  9. solax_py_library/exception.py +10 -10
  10. solax_py_library/smart_scene/__init__.py +0 -0
  11. solax_py_library/smart_scene/constant/__init__.py +0 -0
  12. solax_py_library/smart_scene/constant/message_entry.py +179 -0
  13. solax_py_library/smart_scene/core/__init__.py +0 -0
  14. solax_py_library/smart_scene/core/action/__init__.py +0 -0
  15. solax_py_library/smart_scene/core/action/base.py +10 -0
  16. solax_py_library/smart_scene/core/action/ems_action.py +6 -0
  17. solax_py_library/smart_scene/core/action/system_action.py +6 -0
  18. solax_py_library/smart_scene/core/condition/__init__.py +17 -0
  19. solax_py_library/smart_scene/core/condition/base.py +17 -0
  20. solax_py_library/smart_scene/core/condition/cabinet_condition.py +44 -0
  21. solax_py_library/smart_scene/core/condition/date_condition.py +23 -0
  22. solax_py_library/smart_scene/core/condition/price_condition.py +110 -0
  23. solax_py_library/smart_scene/core/condition/system_condition.py +35 -0
  24. solax_py_library/smart_scene/core/condition/weather_condition.py +61 -0
  25. solax_py_library/smart_scene/core/service/__init__.py +3 -0
  26. solax_py_library/smart_scene/core/service/runner.py +156 -0
  27. solax_py_library/smart_scene/exceptions/__init__.py +7 -0
  28. solax_py_library/smart_scene/exceptions/price.py +5 -0
  29. solax_py_library/smart_scene/exceptions/smart_scene.py +82 -0
  30. solax_py_library/smart_scene/exceptions/weather.py +5 -0
  31. solax_py_library/smart_scene/types/__init__.py +0 -0
  32. solax_py_library/smart_scene/types/action.py +164 -0
  33. solax_py_library/smart_scene/types/condition.py +299 -0
  34. solax_py_library/smart_scene/types/smart_scene_content.py +173 -0
  35. solax_py_library/snap_shot/__init__.py +3 -3
  36. solax_py_library/snap_shot/constant/__init__.py +5 -5
  37. solax_py_library/snap_shot/constant/crc_table.py +258 -258
  38. solax_py_library/snap_shot/core/__init__.py +9 -9
  39. solax_py_library/snap_shot/core/base_modbus.py +14 -14
  40. solax_py_library/snap_shot/exceptions/__init__.py +3 -3
  41. solax_py_library/snap_shot/exceptions/snap_shot.py +9 -9
  42. solax_py_library/snap_shot/types/__init__.py +15 -15
  43. solax_py_library/snap_shot/types/address.py +39 -39
  44. solax_py_library/test/__init__.py +0 -0
  45. solax_py_library/test/test_smart_scene/__init__.py +0 -0
  46. solax_py_library/test/test_smart_scene/test_condition.py +11 -0
  47. solax_py_library/test/test_utils/__init__.py +0 -0
  48. solax_py_library/test/test_utils/test_cloud_client.py +14 -0
  49. solax_py_library/upload/__init__.py +3 -3
  50. solax_py_library/upload/api/__init__.py +3 -3
  51. solax_py_library/upload/api/service.py +24 -24
  52. solax_py_library/upload/core/__init__.py +3 -3
  53. solax_py_library/upload/core/data_adapter/__init__.py +5 -5
  54. solax_py_library/upload/core/data_adapter/base.py +9 -9
  55. solax_py_library/upload/core/data_adapter/csv.py +26 -26
  56. solax_py_library/upload/core/upload_service/__init__.py +15 -15
  57. solax_py_library/upload/core/upload_service/base.py +43 -43
  58. solax_py_library/upload/exceptions/__init__.py +8 -8
  59. solax_py_library/upload/exceptions/upload_error.py +21 -21
  60. solax_py_library/upload/test/test_ftp.py +113 -113
  61. solax_py_library/upload/types/__init__.py +11 -11
  62. solax_py_library/upload/types/client.py +19 -19
  63. solax_py_library/upload/types/ftp.py +37 -37
  64. solax_py_library/utils/cloud_client.py +210 -0
  65. solax_py_library/utils/common.py +38 -38
  66. solax_py_library/utils/struct_util.py +42 -30
  67. solax_py_library/utils/time_util.py +38 -0
  68. {solax_py_library-1.0.0.24.dist-info → solax_py_library-1.0.0.26.dist-info}/METADATA +2 -1
  69. solax_py_library-1.0.0.26.dist-info/RECORD +80 -0
  70. solax_py_library-1.0.0.24.dist-info/RECORD +0 -46
  71. {solax_py_library-1.0.0.24.dist-info → solax_py_library-1.0.0.26.dist-info}/WHEEL +0 -0
@@ -1,37 +1,37 @@
1
- import os
2
- from enum import IntEnum
3
- from typing import Any, Optional
4
-
5
- from pydantic import BaseModel
6
-
7
-
8
- class FTPFileType(IntEnum):
9
- CSV = 1
10
-
11
- @classmethod
12
- def get_file_suffix(cls, value):
13
- return {
14
- FTPFileType.CSV: ".csv",
15
- }.get(value)
16
-
17
-
18
- class FTPData(BaseModel):
19
- file_type: FTPFileType
20
- file_name: str
21
- data: Any
22
-
23
- def build_full_path(self, remote_path) -> str:
24
- return os.path.join(remote_path, self.file_name)
25
-
26
-
27
- class FTPServiceConfig(BaseModel):
28
- host: str
29
- port: int
30
- user: Optional[str]
31
- password: Optional[str]
32
- remote_path: str
33
-
34
-
35
- class FTPParsedData(BaseModel):
36
- file_name: str
37
- file_path: str
1
+ import os
2
+ from enum import IntEnum
3
+ from typing import Any, Optional
4
+
5
+ from pydantic import BaseModel
6
+
7
+
8
+ class FTPFileType(IntEnum):
9
+ CSV = 1
10
+
11
+ @classmethod
12
+ def get_file_suffix(cls, value):
13
+ return {
14
+ FTPFileType.CSV: ".csv",
15
+ }.get(value)
16
+
17
+
18
+ class FTPData(BaseModel):
19
+ file_type: FTPFileType
20
+ file_name: str
21
+ data: Any
22
+
23
+ def build_full_path(self, remote_path) -> str:
24
+ return os.path.join(remote_path, self.file_name)
25
+
26
+
27
+ class FTPServiceConfig(BaseModel):
28
+ host: str
29
+ port: int
30
+ user: Optional[str]
31
+ password: Optional[str]
32
+ remote_path: str
33
+
34
+
35
+ class FTPParsedData(BaseModel):
36
+ file_name: str
37
+ file_path: str
@@ -0,0 +1,210 @@
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 __init__(self, base_url):
12
+ self.base_url = base_url
13
+
14
+ def get_token(self, ems_sn, sn_secret):
15
+ token_url = self.base_url + "/device/token/getByRegistrationSn"
16
+ try:
17
+ response = requests.post(
18
+ token_url,
19
+ json={
20
+ "registrationSn": ems_sn,
21
+ "snSecret": sn_secret,
22
+ },
23
+ timeout=5,
24
+ )
25
+ if response.content:
26
+ response_data = json.loads(response.content)
27
+ print(f"获取token结果 {response_data}")
28
+ if response_data.get("code") == 0 and response_data.get("result"):
29
+ token = response_data["result"]
30
+ return token
31
+ except Exception as e:
32
+ print(f"访问token接口失败: {str(e)}")
33
+
34
+ def get_weather_data_from_cloud(self, ems_sn, token):
35
+ """获取未来24小时天气数据"""
36
+ try:
37
+ weather_url = self.base_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, ems_sn, token):
141
+ try:
142
+ price_url = self.base_url + "/powerStation/station/getCurrentElectrovalence"
143
+ response = requests.post(
144
+ url=price_url,
145
+ headers={"token": token, "Content-Type": "application/json"},
146
+ json={"registerNo": ems_sn},
147
+ timeout=5,
148
+ )
149
+ # 访问失败或获取数据失败,则重复插入最后一条数据
150
+ if response.status_code != 200:
151
+ print(f"获取电价数据失败 状态码 {response.status_code}")
152
+ return False
153
+ response_data = response.json()
154
+ if response_data.get("result") is None:
155
+ print(f"获取电价数据失败 返回数据 {response_data}")
156
+ return False
157
+ today = datetime.strftime(datetime.now(), "%Y-%m-%d %H:%M:%S")
158
+ ele_price_info = {
159
+ "buy": [None] * 192,
160
+ "sell": [None] * 192,
161
+ "date": today,
162
+ }
163
+ ele_price_info["ele_unit"] = response_data["result"]["unit"]
164
+ if ele_price_info["ele_unit"] == "¥":
165
+ rate = 1
166
+ ele_price_info["ele_unit"] = "¥/kWh"
167
+ else:
168
+ rate = 100
169
+ ele_price_info["ele_unit"] = "Cents €/kWh"
170
+ for detail_info in response_data["result"]["list"]:
171
+ start_index = trans_str_time_to_index(detail_info["startTime"])
172
+ end_index = trans_str_time_to_index(detail_info["endTime"])
173
+ # 处理欧分的情况
174
+ if detail_info["buyPrice"] is not None:
175
+ buy_price = round(detail_info["buyPrice"] * rate, 5)
176
+ else:
177
+ buy_price = detail_info["buyPrice"]
178
+ if detail_info["salePrice"] is not None:
179
+ sale_price = round(detail_info["salePrice"] * rate, 5)
180
+ else:
181
+ sale_price = detail_info["salePrice"]
182
+ ele_price_info["buy"][start_index:end_index] = [buy_price] * (
183
+ end_index - start_index
184
+ )
185
+ ele_price_info["sell"][start_index:end_index] = [sale_price] * (
186
+ end_index - start_index
187
+ )
188
+ if response_data["result"].get("tomorrow") is not None:
189
+ for detail_info in response_data["result"]["tomorrow"]:
190
+ start_index = trans_str_time_to_index(detail_info["startTime"]) + 96
191
+ end_index = trans_str_time_to_index(detail_info["endTime"]) + 96
192
+ if detail_info["buyPrice"] is not None:
193
+ buy_price = round(detail_info["buyPrice"] * rate, 5)
194
+ else:
195
+ buy_price = detail_info["buyPrice"]
196
+ if detail_info["salePrice"] is not None:
197
+ sale_price = round(detail_info["salePrice"] * rate, 5)
198
+ else:
199
+ sale_price = detail_info["salePrice"]
200
+ ele_price_info["buy"][start_index:end_index] = [buy_price] * (
201
+ end_index - start_index
202
+ )
203
+ ele_price_info["sell"][start_index:end_index] = [sale_price] * (
204
+ end_index - start_index
205
+ )
206
+ print("获取电价数据成功")
207
+ return ele_price_info
208
+ except Exception:
209
+ print(f"获取电价数据失败 异常 {traceback.format_exc()}")
210
+ return False
@@ -1,38 +1,38 @@
1
- import asyncio
2
- from decimal import Decimal, ROUND_HALF_UP
3
-
4
-
5
- def retry(max_attempts=3, delay=0.5, assign_exception=Exception):
6
- def decorator(func):
7
- async def wrapper(*args, **kwargs):
8
- attempts = 0
9
- while attempts < max_attempts:
10
- try:
11
- return await func(*args, **kwargs)
12
- except Exception as e:
13
- print(f"尝试 {attempts+1} 失败: {e}")
14
- await asyncio.sleep(delay)
15
- attempts += 1
16
- raise assign_exception(f"操作失败 {max_attempts} 次")
17
-
18
- return wrapper
19
-
20
- return decorator
21
-
22
-
23
- def round_value(value, decimal_places=0):
24
- """
25
- 实现四舍五入 代替round函数 遇到5向上取整
26
- @param value: 传入数值
27
- @param decimal_places: 保留几位小数
28
- @return:
29
- """
30
- if isinstance(value, int):
31
- return value
32
- else:
33
- # 优化小数位 Decimal函数太耗时 曲线数据直接使用round函数
34
- # rounded_value = ("{:.%df}" % decimal_places).format(value)
35
- rounded_value = Decimal(str(value)).quantize(
36
- Decimal("1e-" + str(decimal_places)), rounding=ROUND_HALF_UP
37
- )
38
- return float(rounded_value)
1
+ import asyncio
2
+ from decimal import Decimal, ROUND_HALF_UP
3
+
4
+
5
+ def retry(max_attempts=3, delay=0.5, assign_exception=Exception):
6
+ def decorator(func):
7
+ async def wrapper(*args, **kwargs):
8
+ attempts = 0
9
+ while attempts < max_attempts:
10
+ try:
11
+ return await func(*args, **kwargs)
12
+ except Exception as e:
13
+ print(f"尝试 {attempts+1} 失败: {e}")
14
+ await asyncio.sleep(delay)
15
+ attempts += 1
16
+ raise assign_exception(f"操作失败 {max_attempts} 次")
17
+
18
+ return wrapper
19
+
20
+ return decorator
21
+
22
+
23
+ def round_value(value, decimal_places=0):
24
+ """
25
+ 实现四舍五入 代替round函数 遇到5向上取整
26
+ @param value: 传入数值
27
+ @param decimal_places: 保留几位小数
28
+ @return:
29
+ """
30
+ if isinstance(value, int):
31
+ return value
32
+ else:
33
+ # 优化小数位 Decimal函数太耗时 曲线数据直接使用round函数
34
+ # rounded_value = ("{:.%df}" % decimal_places).format(value)
35
+ rounded_value = Decimal(str(value)).quantize(
36
+ Decimal("1e-" + str(decimal_places)), rounding=ROUND_HALF_UP
37
+ )
38
+ return float(rounded_value)
@@ -1,30 +1,42 @@
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
+ format_map = {
6
+ "int8": {"format_str": "bb", "length": 1},
7
+ "uint8": {"format_str": "BB", "length": 1},
8
+ "int16": {"format_str": "h", "length": 1},
9
+ "uint16": {"format_str": "H", "length": 1},
10
+ "int32": {"format_str": "i", "length": 2},
11
+ "uint32": {"format_str": "I", "length": 2},
12
+ "int64": {"format_str": "q", "length": 4},
13
+ "uint64": {"format_str": "Q", "length": 4},
14
+ "float": {"format_str": "f", "length": 1},
15
+ }
16
+
17
+
18
+ def unpack(data: List, data_format, reversed=False):
19
+ """
20
+ :param data: 数据字节, 入参均是由modbus读取到的list[uint16]进行转换
21
+ :param data_format: 数据格式
22
+ :param reversed: 是否翻转大小端
23
+ """
24
+ cur_data = copy.deepcopy(data)
25
+ data_format = data_format.lower()
26
+ if data_format not in format_map:
27
+ raise Exception("暂不支持")
28
+ pack_str = ("<" if reversed else ">") + "H" * len(cur_data)
29
+ to_pack_data = struct.pack(pack_str, *cur_data)
30
+ struct_format = ("<" if reversed else ">") + format_map[data_format]["format_str"]
31
+ return struct.unpack(struct_format, to_pack_data)
32
+
33
+
34
+ def pack(value, fmt, order="big"):
35
+ """将10进制的原始值转换为modbus协议需要的精度与类型的值"""
36
+ opt = "<" if order == "little" else ">"
37
+ if fmt not in format_map:
38
+ raise Exception("暂不支持")
39
+ value = int(value)
40
+ ret = struct.pack(f'{opt}{format_map[fmt]["format_str"]}', value)
41
+ ret_list = struct.unpack(f'{opt}{"H" * format_map[fmt]["length"]}', ret)
42
+ return list(ret_list)
@@ -0,0 +1,38 @@
1
+ from datetime import datetime, timedelta
2
+
3
+
4
+ def trans_str_time_to_index(now_time, minute=15):
5
+ """将时间按照minute切换为索引,时间格式为 %H-%M"""
6
+ time_list = [int(i) for i in now_time.split(":")]
7
+ time_int = time_list[0] * 4 + time_list[1] // minute
8
+ return time_int
9
+
10
+
11
+ def get_highest_or_lowest_value(start_time, end_time, hours, price_list, reverse=False):
12
+ start_index = trans_str_time_to_index(start_time)
13
+ end_index = trans_str_time_to_index(end_time)
14
+ arr = price_list[start_index:end_index]
15
+ if None in arr:
16
+ return False
17
+ indices = list(range(end_index - start_index))
18
+ sorted_indices = sorted(indices, key=lambda i: arr[i], reverse=reverse)
19
+ return sorted_indices[: int(hours * 4)], start_index
20
+
21
+
22
+ def get_rounded_times():
23
+ """
24
+ 返回距离当前时间最近的15min的整点时间以及后一整点5min时间(天气是预测未来15min的,也就是在00:00时,只能拿到00:15的数据)
25
+ """
26
+ now = datetime.now()
27
+ # 确定当前时间所属的15分钟区间
28
+ index_1 = now.minute // 15
29
+ index_2 = now.minute % 15
30
+ left_time = now.replace(minute=15 * index_1, second=0, microsecond=0)
31
+ right_time = left_time + timedelta(minutes=15)
32
+ if index_2 < 8:
33
+ nearest_time = left_time
34
+ else:
35
+ nearest_time = right_time
36
+ return datetime.strftime(nearest_time, "%Y-%m-%d %H:%M:%S"), datetime.strftime(
37
+ right_time, "%Y-%m-%d %H:%M:%S"
38
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: solax-py-library
3
- Version: 1.0.0.24
3
+ Version: 1.0.0.26
4
4
  Summary: some common tool
5
5
  Author: shenlvyu
6
6
  Author-email: 13296718439@163.com
@@ -13,6 +13,7 @@ Classifier: Programming Language :: Python :: 3.11
13
13
  Classifier: Programming Language :: Python :: 3.12
14
14
  Classifier: Programming Language :: Python :: 3.13
15
15
  Requires-Dist: pydantic (>=1.10.0,<2.0.0)
16
+ Requires-Dist: requests (==2.32.3)
16
17
  Requires-Dist: typing-extensions (==4.7.1)
17
18
  Description-Content-Type: text/markdown
18
19
 
@@ -0,0 +1,80 @@
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/cabinet.py,sha256=V76qP2JXjdjTnsIo8wXGXYhbUb4YNKANFY-r4CrTFD4,68
5
+ solax_py_library/device/constant/inverter_model_info.py,sha256=Ujnwv79qycOTV_zqqr21wKXXj_lGLgrA56X_-Vjuxqw,18049
6
+ solax_py_library/device/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ solax_py_library/device/core/interver/__init__.py,sha256=RKye2D6NawSGdL4YUp_H-LmKIjThBp9CWhb6zwyM97s,1153
8
+ solax_py_library/device/core/interver/base.py,sha256=2TXHsjigMcIvGDLF3ZD4dw6UDrRRAk9Mq6sdBKRvydc,7191
9
+ solax_py_library/device/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ solax_py_library/device/types/alarm.py,sha256=kartXs_iRSV9Y3weFSsh9wMXU1_FxHZa6inHThyQCOk,358
11
+ solax_py_library/device/types/inverter_config.py,sha256=qCInNPbgsWf6yQjSw59kfQtJJWilMYUhvx_qo5qwRlU,912
12
+ solax_py_library/device/types/modbus_point.py,sha256=YmXe92gWXL_voVXDJE5zzNzr6dpPs7Ff3ciOAW-LgPs,580
13
+ solax_py_library/exception.py,sha256=ygAccdTqJctRrdt9bu6-vqZP5KadfKVS_1tjt4KcRn8,257
14
+ solax_py_library/smart_scene/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ solax_py_library/smart_scene/constant/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ solax_py_library/smart_scene/constant/message_entry.py,sha256=r-hSUQItc0xEgodXtDct7AltFHQZxj5KH6ZP_ioZtAQ,9191
17
+ solax_py_library/smart_scene/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
+ solax_py_library/smart_scene/core/action/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ solax_py_library/smart_scene/core/action/base.py,sha256=CCYrlCZeb3CfGZgTWQN673VJmuYNsTbEtdZ4ERUV7RA,395
20
+ solax_py_library/smart_scene/core/action/ems_action.py,sha256=sML6qasFoqOktTvEcHm0vKPYCj60VcKjAFz8RAaQc2U,206
21
+ solax_py_library/smart_scene/core/action/system_action.py,sha256=oGXq3yXS9nKcGjJActjk0R2Wr3AoO9uoyRPyuiM053g,204
22
+ solax_py_library/smart_scene/core/condition/__init__.py,sha256=1nN-N52Oq7LKdn6ApKGtSZq5fB1qJzJq8BOKOumfQvY,475
23
+ solax_py_library/smart_scene/core/condition/base.py,sha256=saj7dc0Su2Wi_Lx04cesHFgIPDyQUwvHuDElcaDOIHU,596
24
+ solax_py_library/smart_scene/core/condition/cabinet_condition.py,sha256=HEVifO3rHk2ElfSCEB0MzVdfrFWlkwqjt6tFhtJ8CLY,1581
25
+ solax_py_library/smart_scene/core/condition/date_condition.py,sha256=Xhca6VjoM8Bq-I-dFj1RPLTTzbBL81ORkBnR8D-YqUw,772
26
+ solax_py_library/smart_scene/core/condition/price_condition.py,sha256=IkgoB5YhpMxgFVkabilcBXtkjsqae01kkjF3tH10CK0,4006
27
+ solax_py_library/smart_scene/core/condition/system_condition.py,sha256=q5KDQdK6wjEvq0__WwBR4Sk-59yA2aIAgxTf1xjxJQk,1338
28
+ solax_py_library/smart_scene/core/condition/weather_condition.py,sha256=Xp7l9m3NW1vyyRGaJC5_gAX4HM-iuj7OGaw5LbZ4ztU,2223
29
+ solax_py_library/smart_scene/core/service/__init__.py,sha256=wWzHSN2XaHnI-TNtCJWWRHnNC7s3-2GNQo9y0K_PC4Q,69
30
+ solax_py_library/smart_scene/core/service/runner.py,sha256=SwQ6jb5yFPcyHyfU-THyGDjPEMcNFUOHkvVYA9wB1EE,6201
31
+ solax_py_library/smart_scene/exceptions/__init__.py,sha256=0hDgr70fFLQB14uorVCwbBhl1yQmZ-uBYGH5XtGm_dg,147
32
+ solax_py_library/smart_scene/exceptions/price.py,sha256=3bnY6JzeEskUoXVzEs8bpg6hQzgbinBKY4GP4hBITWU,152
33
+ solax_py_library/smart_scene/exceptions/smart_scene.py,sha256=69khvoFm1Eki4NBT45gVnsyWubEzF7dqnhU-unqT20g,1701
34
+ solax_py_library/smart_scene/exceptions/weather.py,sha256=bJl1VwiIXEpLQ9VjlVrDoTAIMFqVZdRCas7dtR7eAJc,133
35
+ solax_py_library/smart_scene/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ solax_py_library/smart_scene/types/action.py,sha256=cYICnxLfLRWFAlOGWpS2HBw-PyaB6TNlNuEmSsme26k,5723
37
+ solax_py_library/smart_scene/types/condition.py,sha256=mGjd-Kh34EjnHf8IKKAOdYPhPHlLB0HRVzC1pfkZsxo,9564
38
+ solax_py_library/smart_scene/types/smart_scene_content.py,sha256=C8H17QEicmDBbxN-m550njwaZyUhAL2hUhlLg3Qj1zM,6061
39
+ solax_py_library/snap_shot/__init__.py,sha256=Ex12q6BCkdU-3OP-f-ehGCetJJWnoZ7KxhEDd_lXh6M,81
40
+ solax_py_library/snap_shot/constant/__init__.py,sha256=UNfjAlx1wovXc1oH74af9oIe2TljwCCiTzNXzWgtUms,65
41
+ solax_py_library/snap_shot/constant/crc_table.py,sha256=D-pSxpf1XDzu7YR8LmbnzdLRvI8exDL2dyDh7RRc4Io,3566
42
+ solax_py_library/snap_shot/core/__init__.py,sha256=lovGQAEfqxPaLlE6gr9HJjgsKjZZLosgaWeGO0Q_JCI,178
43
+ solax_py_library/snap_shot/core/base_modbus.py,sha256=EdDSRvRC2a4IE_LGvjxGznqi6AX5x4O0_Wn1IkHzIpA,403
44
+ solax_py_library/snap_shot/core/parser.py,sha256=IM7SWqbRHGk9KwVRwP3jwht6tGIMClagdszodGiEJ_c,8999
45
+ solax_py_library/snap_shot/core/snap_shot.py,sha256=j6exbbzahmYtoCRsG9e5S64Lw2DOYgOFKtOfa0oz8xY,11109
46
+ solax_py_library/snap_shot/exceptions/__init__.py,sha256=9wLhmIelRKCXvlymcu3EewasVVYuPu4QQxTDLjGj6NQ,112
47
+ solax_py_library/snap_shot/exceptions/snap_shot.py,sha256=-oxxh_lUhfZwtggJ4zfNBPdkhdGPvcVvDezNlj4nFfY,154
48
+ solax_py_library/snap_shot/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
+ solax_py_library/snap_shot/types/__init__.py,sha256=g9ybB88TntvAMGIhLgJ31Xxn26zluSfI496bg-apSTU,290
50
+ solax_py_library/snap_shot/types/address.py,sha256=JhyB-t2OnKuE8akKk120sojCNXv4_OlLLuWsl5ChFZ8,1148
51
+ solax_py_library/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
+ solax_py_library/test/test_smart_scene/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
+ solax_py_library/test/test_smart_scene/test_condition.py,sha256=w-REUzkaDrq9acye2qZeAbTQb8bpgAykLfylsLvNrx8,331
54
+ solax_py_library/test/test_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
+ solax_py_library/test/test_utils/test_cloud_client.py,sha256=gOrHGXkFXpFV4kXTnjhmyJGem8VaGKw8OmXyW884oJ0,395
56
+ solax_py_library/upload/__init__.py,sha256=XhZar7BKaRN0XcdPl4QffWr488L3UWvuq5syT8nX2OU,93
57
+ solax_py_library/upload/api/__init__.py,sha256=ASShe-YQxP0aA3B_I8EmpWKXIdXPWvaANifrzlYrFEk,84
58
+ solax_py_library/upload/api/service.py,sha256=-APuz86t4loCkjzaxq02kuKrB6jxaPV-Tz1V__j6cY0,763
59
+ solax_py_library/upload/core/__init__.py,sha256=XMcnyDzCfsLwWaTAZt9-an7TuwYFqVNSt9W1_QRUrwA,89
60
+ solax_py_library/upload/core/data_adapter/__init__.py,sha256=9CXepLZSOjZMfNjyYKAWQCWZt353kTL_0tFBlIeUIOo,116
61
+ solax_py_library/upload/core/data_adapter/base.py,sha256=Va-SEe0eL3gobhNOnzHGkYBLIwf5RVawQdYRHHXg9g0,170
62
+ solax_py_library/upload/core/data_adapter/csv.py,sha256=8nlnV_43mMAR3re50MQJymzT5HYpZOo7eSeMsEfnEVE,861
63
+ solax_py_library/upload/core/upload_service/__init__.py,sha256=uA-UeH31rDNxByeZwvPhNFHPV_-J8JyCev8geuc---k,269
64
+ solax_py_library/upload/core/upload_service/base.py,sha256=dxCBVtPxDhN7oRTjnwnjtc2XAF4hyIz9HsYCJePlggg,912
65
+ solax_py_library/upload/core/upload_service/ftp.py,sha256=3Immu1SfJZ6vXIoUpDSx1_C4Saa0x9pNg-XgJCf7Fhg,3277
66
+ solax_py_library/upload/exceptions/__init__.py,sha256=12D68_mODfJkVFa1f65QgPUn8bvD5BDAeiHgNgU0258,186
67
+ solax_py_library/upload/exceptions/upload_error.py,sha256=V2_yEMLj9KQEkdQ0Cm1DOogbjZWGb4p8RVnFx7D9yLY,425
68
+ solax_py_library/upload/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
+ solax_py_library/upload/test/test_ftp.py,sha256=NPIt_BjSt_PH6XMP9c_7p7nAuktUyKu82_zTRgO8Cfw,3809
70
+ solax_py_library/upload/types/__init__.py,sha256=og9KBpYbcs36_S1izURj3vyHeuNOLJQrD9GpxK_JJaw,244
71
+ solax_py_library/upload/types/client.py,sha256=fG674_QEpOw3ibO171lcxJ0cz27yGR_sd3zgiyr4yuI,492
72
+ solax_py_library/upload/types/ftp.py,sha256=9kCeLB0g5Je19v4ifz8YYEsGOhJL1lKBO2C6V2VBndc,679
73
+ solax_py_library/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
+ solax_py_library/utils/cloud_client.py,sha256=5dZrc5fzrNFSXqTPZd7oHt-Y9Jj6RCigB7aXJQMJ8sQ,9610
75
+ solax_py_library/utils/common.py,sha256=bfnZcX9uM-PjJrYAFv1UMmZgt6bGR7MaOd7jRPNHGxw,1238
76
+ solax_py_library/utils/struct_util.py,sha256=pL6L80GXIHasy1ZDIj89-5BzXW1BWI3TPitH7thGGIE,1577
77
+ solax_py_library/utils/time_util.py,sha256=bY5kj9dmyOuLEQ6uYGQK7jU7y1RMiHZgevEKnkcQcSU,1461
78
+ solax_py_library-1.0.0.26.dist-info/METADATA,sha256=r0f6Z_QGhZwZehgD063VJ4aQlrakVmJGqmX8WQpxthY,1825
79
+ solax_py_library-1.0.0.26.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
80
+ solax_py_library-1.0.0.26.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=dbFWwXdHFXXvX_FLgFceYcSlJuuymLKm9CXnlk7szmQ,18361
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=Mnc31li74rkHzNmTrCbSqQiVrs_0OfJDQNlXCR_XURA,187
16
- solax_py_library/snap_shot/core/base_modbus.py,sha256=hd8047JdB97X9sF3ZzzjR8YjUNV7qWc0T6xtJEg5Pvs,417
17
- solax_py_library/snap_shot/core/parser.py,sha256=IM7SWqbRHGk9KwVRwP3jwht6tGIMClagdszodGiEJ_c,8999
18
- solax_py_library/snap_shot/core/snap_shot.py,sha256=j6exbbzahmYtoCRsG9e5S64Lw2DOYgOFKtOfa0oz8xY,11109
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=VHRXkLLQKsIeUi4T-osSsURmcJS6cM5rhhvUwF6aLG8,87
26
- solax_py_library/upload/api/service.py,sha256=FSAz-WWHRG72vE45gu73n0hheyXuB94GQdgSMfqusOA,787
27
- solax_py_library/upload/core/__init__.py,sha256=LxE2LrHB9vfyGwb1YbxHfbeyfdOhlSZdXvDp2L2Jtvs,92
28
- solax_py_library/upload/core/data_adapter/__init__.py,sha256=AAt7SndlSM3_0iE9q7Uevg51PraUWgoFOgYg9XBKktM,121
29
- solax_py_library/upload/core/data_adapter/base.py,sha256=HoN9WVLzOjt-0lg7x0DR0H0Fflg7V97WJmtgBZeY37g,179
30
- solax_py_library/upload/core/data_adapter/csv.py,sha256=QaTjHw_aGZyEPUkr2AfBh5ITgRDE9dWN2d8sXh1xlZc,887
31
- solax_py_library/upload/core/upload_service/__init__.py,sha256=iVlmUxDNBroqA0yBGf4DnIt-3RMdBoUr2kxuP-z1Y_8,284
32
- solax_py_library/upload/core/upload_service/base.py,sha256=U4wyynOtE1dYT11nstPgbCjnEgknqzsk6wQqxfM1MC4,955
33
- solax_py_library/upload/core/upload_service/ftp.py,sha256=3Immu1SfJZ6vXIoUpDSx1_C4Saa0x9pNg-XgJCf7Fhg,3277
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=fIyAABF3v1qLlLehJ7SCRi6WcX7vjYE9swPKLPdSRj8,3922
38
- solax_py_library/upload/types/__init__.py,sha256=mgfwypAgvWNfhLMOK-osoF6Nf5QSn-uB02MkaH4m5pY,255
39
- solax_py_library/upload/types/client.py,sha256=KqrwTRniunJCV6HjaXkZAYzFryYxXirmIWmfh5V93qI,511
40
- solax_py_library/upload/types/ftp.py,sha256=kgjB0DyUQCGLH2iZncMuuRWKrxhh1fBD_KTu_PeEPUE,716
41
- solax_py_library/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
- solax_py_library/utils/common.py,sha256=Ttzw6ZMjFCS4Qqu3l1A04vR6cPLvVKCNwBAmwgREFbs,1276
43
- solax_py_library/utils/struct_util.py,sha256=ER0F6W_QCGM98NItGbQLmdZtbPn1UAZ-qh2tnqHi004,943
44
- solax_py_library-1.0.0.24.dist-info/METADATA,sha256=fUbGIBlBiVGeh0hBF0hGDTi-GyOIDMYFYSD3-nI5_aI,1790
45
- solax_py_library-1.0.0.24.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
46
- solax_py_library-1.0.0.24.dist-info/RECORD,,