solax-py-library 1.0.0.2501__py3-none-any.whl → 1.0.0.2503__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.
@@ -1,8 +1,10 @@
1
+ import operator
1
2
  from enum import IntEnum, Enum
2
3
  from typing import Optional, List, Union, Any
3
4
 
4
5
  from pydantic import BaseModel, validator, root_validator
5
6
 
7
+ from solax_py_library.device.types.alarm import AlarmLevel
6
8
  from solax_py_library.smart_scene.constant.message_entry import MESSAGE_ENTRY
7
9
 
8
10
 
@@ -16,6 +18,13 @@ class ConditionFunc(IntEnum):
16
18
  LT = 101
17
19
  EQ = 102
18
20
 
21
+ def function(self):
22
+ return {
23
+ ConditionFunc.GT: operator.gt,
24
+ ConditionFunc.LT: operator.lt,
25
+ ConditionFunc.EQ: operator.eq,
26
+ }.get(self)
27
+
19
28
 
20
29
  class RepeatFunc(IntEnum):
21
30
  ONCE = 103
@@ -79,13 +88,13 @@ class PriceConditionItemData(BaseModel):
79
88
 
80
89
  @validator("childData", always=True)
81
90
  def _check_child_data(cls, value, values):
82
- childType = values.get("childType")
83
- if childType in {
91
+ child_type = values.get("childType")
92
+ if child_type in {
84
93
  PriceConditionType.lowerPrice,
85
94
  PriceConditionType.higherPrice,
86
95
  }:
87
96
  assert value.data[0] > 0, ValueError
88
- elif childType in {
97
+ elif child_type in {
89
98
  PriceConditionType.expensiveHours,
90
99
  PriceConditionType.cheapestHours,
91
100
  }:
@@ -119,14 +128,14 @@ class SystemConditionItemData(BaseModel):
119
128
 
120
129
  @validator("childData", always=True)
121
130
  def _check_child_data(cls, value, values):
122
- childType = values.get("childType")
123
- if childType in {
131
+ child_type = values.get("childType")
132
+ if child_type in {
124
133
  SystemConditionType.systemExportPower,
125
134
  SystemConditionType.systemImportPower,
126
135
  }:
127
136
  assert 0 <= value.data[0] <= 100000, ValueError
128
137
  value.data[0] = round(value.data[0], 2) # 功率保留两位小数
129
- elif childType == SystemConditionType.systemSoc:
138
+ elif child_type == SystemConditionType.systemSoc:
130
139
  assert 5 <= value.data[0] <= 100, ValueError
131
140
  return value
132
141
 
@@ -152,14 +161,14 @@ class CabinetConditionItemData(BaseModel):
152
161
 
153
162
  @validator("childData", always=True)
154
163
  def _check_child_data(cls, value, values):
155
- childType = values.get("childType")
156
- # if childType == CabinetConditionType.cabinetAlarm:
157
- # assert value.data[0] in {
158
- # AlarmLevel.TIPS,
159
- # AlarmLevel.NORMAL,
160
- # AlarmLevel.EMERGENCY,
161
- # }, ValueError
162
- if childType == CabinetConditionType.cabinetSoc:
164
+ child_type = values.get("childType")
165
+ if child_type == CabinetConditionType.cabinetAlarm:
166
+ assert value.data[0] in {
167
+ AlarmLevel.TIPS,
168
+ AlarmLevel.NORMAL,
169
+ AlarmLevel.EMERGENCY,
170
+ }, ValueError
171
+ if child_type == CabinetConditionType.cabinetSoc:
163
172
  assert 0 <= value.data[0] <= 100, ValueError
164
173
  return value
165
174
 
@@ -182,11 +191,11 @@ class DateConditionItemData(BaseModel):
182
191
 
183
192
  @validator("childData", always=True)
184
193
  def check_param(cls, value, values):
185
- childType = values.get("childType")
194
+ child_type = values.get("childType")
186
195
  data = value.data
187
- if childType == DateConditionType.time:
196
+ if child_type == DateConditionType.time:
188
197
  assert isinstance(data[0], str), ValueError
189
- elif childType == DateConditionType.duration:
198
+ elif child_type == DateConditionType.duration:
190
199
  assert isinstance(data[0], int), ValueError
191
200
  return value
192
201
 
@@ -203,8 +212,8 @@ class WeatherConditionItemData(BaseModel):
203
212
 
204
213
  @validator("childData", always=True)
205
214
  def _check_child_data(cls, value, values):
206
- childType = values.get("childType")
207
- if childType == WeatherConditionType.irradiance:
215
+ child_type = values.get("childType")
216
+ if child_type == WeatherConditionType.irradiance:
208
217
  assert value.data[0] > 0, ValueError
209
218
  assert 0 <= value.data[1] <= 24, ValueError
210
219
  return value
@@ -247,7 +256,9 @@ class ConditionItem(BaseModel):
247
256
  return {self.type: [d.to_text(lang, unit) for d in self.data]}
248
257
  elif self.type == ConditionType.cabinet:
249
258
  cabinet_sns = ",".join(self.cabinet)
250
- return {self.type: [d.to_text(lang, unit) for d in self.data] + [cabinet_sns]}
259
+ return {
260
+ self.type: [d.to_text(lang, unit) for d in self.data] + [cabinet_sns]
261
+ }
251
262
 
252
263
 
253
264
  class SmartSceneCondition(BaseModel):
@@ -273,13 +284,8 @@ class SmartSceneCondition(BaseModel):
273
284
  return values
274
285
 
275
286
  def to_text(self, lang, unit):
276
- # ret = {
277
- # "operation": MESSAGE_ENTRY[self.operation.name][lang],
278
- # "value": {}
279
- # }
280
- ret = {}
287
+ ret = {"operation": [MESSAGE_ENTRY[self.operation.name][lang]]}
281
288
  for v in self.value:
282
- # ret["value"].update(v.to_text(lang, unit))
283
289
  ret.update(v.to_text(lang, unit))
284
290
  return ret
285
291
 
@@ -5,21 +5,21 @@ from typing import Optional, List
5
5
  from pydantic import Field
6
6
  from pydantic.main import BaseModel
7
7
 
8
- from domain.ems_enum.smart_scene.action import (
8
+ from solax_py_library.device.constant.cabinet import TRENE_CABINET_ENUM
9
+ from solax_py_library.smart_scene.constant.message_entry import MESSAGE_ENTRY
10
+ from solax_py_library.smart_scene.types.action import (
11
+ SmartSceneAction,
9
12
  ActionType,
10
13
  SystemActionType,
11
- SmartSceneAction,
12
14
  )
13
- from domain.ems_enum.smart_scene.base import MESSAGE_ENTRY
14
- from domain.ems_enum.smart_scene.condition import (
15
- LogicFunc,
16
- ConditionFunc,
15
+ from solax_py_library.smart_scene.types.condition import (
17
16
  RepeatFunc,
17
+ SmartSceneCondition,
18
+ LogicFunc,
18
19
  ConditionType,
19
20
  PriceConditionType,
20
- SmartSceneCondition,
21
+ ConditionFunc,
21
22
  )
22
- from settings.const import DeviceInfo
23
23
 
24
24
 
25
25
  class SmartSceneOtherInfo(BaseModel):
@@ -145,7 +145,7 @@ class SmartSceneContent(BaseModel):
145
145
  ],
146
146
  "elseThen": [],
147
147
  }
148
- if cabinet_type in DeviceInfo.TRENE_CABINET_ENUM:
148
+ if cabinet_type in TRENE_CABINET_ENUM:
149
149
  return [scene_rec_2]
150
150
  else:
151
151
  return [scene_rec_1, scene_rec_2]
File without changes
File without changes
@@ -0,0 +1,14 @@
1
+ from unittest import TestCase
2
+
3
+ from solax_py_library.utils.cloud_client import CloudClient
4
+
5
+
6
+ class TestCloudClient(TestCase):
7
+ def test_get_weather(self):
8
+ client = CloudClient()
9
+ ret = client.get_weather_data_from_cloud(
10
+ "https://aliyun-sit.solaxtech.net:5050",
11
+ "XMG11A011L",
12
+ "b080a22827484db6bd509d496f9df90b",
13
+ )
14
+ print(ret)
@@ -8,8 +8,11 @@ from solax_py_library.utils.time_util import trans_str_time_to_index
8
8
 
9
9
 
10
10
  class CloudClient:
11
- def get_token(self, cloud_url, ems_sn, sn_secret):
12
- token_url = cloud_url + "/device/token/getByRegistrationSn"
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"
13
16
  try:
14
17
  response = requests.post(
15
18
  token_url,
@@ -17,7 +20,7 @@ class CloudClient:
17
20
  "registrationSn": ems_sn,
18
21
  "snSecret": sn_secret,
19
22
  },
20
- timeout=5
23
+ timeout=5,
21
24
  )
22
25
  if response.content:
23
26
  response_data = json.loads(response.content)
@@ -28,13 +31,10 @@ class CloudClient:
28
31
  except Exception as e:
29
32
  print(f"访问token接口失败: {str(e)}")
30
33
 
31
- def get_weather_data_from_cloud(self, cloud_url, ems_sn, sn_secret):
34
+ def get_weather_data_from_cloud(self, ems_sn, token):
32
35
  """获取未来24小时天气数据"""
33
36
  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"
37
+ weather_url = self.base_url + "/ess/web/v1/powerStation/station/solcast/get"
38
38
  headers = {"token": token, "Content-Type": "application/json"}
39
39
  post_dict = {"registerNo": ems_sn, "day": 1}
40
40
  response = requests.post(
@@ -137,17 +137,14 @@ class CloudClient:
137
137
  print(f"获取天气数据失败 异常 {traceback.format_exc()}")
138
138
  return False
139
139
 
140
- def get_electrovalence_data_from_cloud(self, cloud_url, ems_sn, sn_secret):
140
+ def get_electrovalence_data_from_cloud(self, ems_sn, token):
141
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"
142
+ price_url = self.base_url + "/powerStation/station/getCurrentElectrovalence"
146
143
  response = requests.post(
147
144
  url=price_url,
148
145
  headers={"token": token, "Content-Type": "application/json"},
149
146
  json={"registerNo": ems_sn},
150
- timeout=5
147
+ timeout=5,
151
148
  )
152
149
  # 访问失败或获取数据失败,则重复插入最后一条数据
153
150
  if response.status_code != 200:
@@ -1,5 +1,38 @@
1
+ from datetime import datetime, timedelta
2
+
3
+
1
4
  def trans_str_time_to_index(now_time, minute=15):
2
5
  """将时间按照minute切换为索引,时间格式为 %H-%M"""
3
6
  time_list = [int(i) for i in now_time.split(":")]
4
7
  time_int = time_list[0] * 4 + time_list[1] // minute
5
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.2501
3
+ Version: 1.0.0.2503
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
 
@@ -1,34 +1,39 @@
1
1
  solax_py_library/__init__.py,sha256=4wrB7TuGOQaYHQvdn574G4JrcOnH6l8RNSR6AtKAiKc,34
2
2
  solax_py_library/device/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
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
4
5
  solax_py_library/device/constant/inverter_model_info.py,sha256=Ujnwv79qycOTV_zqqr21wKXXj_lGLgrA56X_-Vjuxqw,18049
5
6
  solax_py_library/device/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
7
  solax_py_library/device/core/interver/__init__.py,sha256=RKye2D6NawSGdL4YUp_H-LmKIjThBp9CWhb6zwyM97s,1153
7
8
  solax_py_library/device/core/interver/base.py,sha256=2TXHsjigMcIvGDLF3ZD4dw6UDrRRAk9Mq6sdBKRvydc,7191
8
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
9
11
  solax_py_library/device/types/inverter_config.py,sha256=qCInNPbgsWf6yQjSw59kfQtJJWilMYUhvx_qo5qwRlU,912
10
12
  solax_py_library/device/types/modbus_point.py,sha256=YmXe92gWXL_voVXDJE5zzNzr6dpPs7Ff3ciOAW-LgPs,580
11
13
  solax_py_library/exception.py,sha256=ygAccdTqJctRrdt9bu6-vqZP5KadfKVS_1tjt4KcRn8,257
12
14
  solax_py_library/smart_scene/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
15
  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
16
+ solax_py_library/smart_scene/constant/message_entry.py,sha256=Ah2yDNpsf1W4HKD-tCzK6xtew0H5TLN7ko7kSsXgcng,8973
15
17
  solax_py_library/smart_scene/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
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=vSC3rL9qfPy41Nlds_0QcTLMbf4n-P18XUBJ3oYiNGk,237
20
+ solax_py_library/smart_scene/core/action/ems_action.py,sha256=tasL7pUJbnmrEEokAa9Mug5eUFvHuFKGYZKNvNMdrBs,610
21
+ solax_py_library/smart_scene/core/action/system_action.py,sha256=mVLTg9pZ7tDayLbr3I92a33snA2AGT3meUdm_XYDQEc,10839
17
22
  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
23
+ solax_py_library/smart_scene/core/condition/base.py,sha256=dQK5gRguOo7GmQkRSnae2kTv4wvZh7zJeyQCdX09OmE,177
24
+ solax_py_library/smart_scene/core/condition/cabinet_condition.py,sha256=vbo5wHf_p1qoTgItcyh-DcxE4GOe-2mUK5tYCg5pRCM,879
25
+ solax_py_library/smart_scene/core/condition/date_condition.py,sha256=NXDN2A7t6h8r_F9GNUD8YPAJLFedFDXlrQhs5vvyNyo,899
26
+ solax_py_library/smart_scene/core/condition/price_condition.py,sha256=4k4oDKSiSFdAM5reRVdfBW25XNw0o1QKYm0PUB_Mnxw,4174
27
+ solax_py_library/smart_scene/core/condition/system_condition.py,sha256=100lBBf_yhdPbzK000U1OSfanKtA2xH4PoM6RRc42x0,1522
28
+ solax_py_library/smart_scene/core/condition/weather_condition.py,sha256=kQ-0pM07G9-mOqOGp6BNbEdP3HuZyOdBqTQD0cAl8Ck,2469
24
29
  solax_py_library/smart_scene/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
30
  solax_py_library/smart_scene/exceptions/price.py,sha256=ztsM8leCsxbzx1TYS5GQAVbfvxlU49QymS1NUykqM_g,142
26
31
  solax_py_library/smart_scene/exceptions/smart_scene.py,sha256=VFjRe7fUg5JA13Wg8BFvxzlF-pBSNaGJJBpnphYdSbM,1774
27
32
  solax_py_library/smart_scene/exceptions/weather.py,sha256=bJl1VwiIXEpLQ9VjlVrDoTAIMFqVZdRCas7dtR7eAJc,133
28
33
  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
34
+ solax_py_library/smart_scene/types/action.py,sha256=zvMsy_SVLIvsV3kHSbI6xEJLOYThQ6_ucGpYn3TXCUs,5607
35
+ solax_py_library/smart_scene/types/condition.py,sha256=xJGv4Xv-kRzMYzlj6y6Q3eeMSVLwoOY9V-denlyicik,9552
36
+ solax_py_library/smart_scene/types/smart_scene_content.py,sha256=C8H17QEicmDBbxN-m550njwaZyUhAL2hUhlLg3Qj1zM,6061
32
37
  solax_py_library/snap_shot/__init__.py,sha256=Ex12q6BCkdU-3OP-f-ehGCetJJWnoZ7KxhEDd_lXh6M,81
33
38
  solax_py_library/snap_shot/constant/__init__.py,sha256=UNfjAlx1wovXc1oH74af9oIe2TljwCCiTzNXzWgtUms,65
34
39
  solax_py_library/snap_shot/constant/crc_table.py,sha256=D-pSxpf1XDzu7YR8LmbnzdLRvI8exDL2dyDh7RRc4Io,3566
@@ -41,6 +46,9 @@ solax_py_library/snap_shot/exceptions/snap_shot.py,sha256=-oxxh_lUhfZwtggJ4zfNBP
41
46
  solax_py_library/snap_shot/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
47
  solax_py_library/snap_shot/types/__init__.py,sha256=g9ybB88TntvAMGIhLgJ31Xxn26zluSfI496bg-apSTU,290
43
48
  solax_py_library/snap_shot/types/address.py,sha256=JhyB-t2OnKuE8akKk120sojCNXv4_OlLLuWsl5ChFZ8,1148
49
+ solax_py_library/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
+ solax_py_library/test/test_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
+ solax_py_library/test/test_utils/test_cloud_client.py,sha256=gOrHGXkFXpFV4kXTnjhmyJGem8VaGKw8OmXyW884oJ0,395
44
52
  solax_py_library/upload/__init__.py,sha256=XhZar7BKaRN0XcdPl4QffWr488L3UWvuq5syT8nX2OU,93
45
53
  solax_py_library/upload/api/__init__.py,sha256=ASShe-YQxP0aA3B_I8EmpWKXIdXPWvaANifrzlYrFEk,84
46
54
  solax_py_library/upload/api/service.py,sha256=-APuz86t4loCkjzaxq02kuKrB6jxaPV-Tz1V__j6cY0,763
@@ -59,10 +67,10 @@ solax_py_library/upload/types/__init__.py,sha256=og9KBpYbcs36_S1izURj3vyHeuNOLJQ
59
67
  solax_py_library/upload/types/client.py,sha256=fG674_QEpOw3ibO171lcxJ0cz27yGR_sd3zgiyr4yuI,492
60
68
  solax_py_library/upload/types/ftp.py,sha256=9kCeLB0g5Je19v4ifz8YYEsGOhJL1lKBO2C6V2VBndc,679
61
69
  solax_py_library/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
- solax_py_library/utils/cloud_client.py,sha256=QbINoIMAxMm3UHr-lSL_MuZUbMR2SKvgy1TefRxmZdg,9809
70
+ solax_py_library/utils/cloud_client.py,sha256=5dZrc5fzrNFSXqTPZd7oHt-Y9Jj6RCigB7aXJQMJ8sQ,9610
63
71
  solax_py_library/utils/common.py,sha256=bfnZcX9uM-PjJrYAFv1UMmZgt6bGR7MaOd7jRPNHGxw,1238
64
72
  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,,
73
+ solax_py_library/utils/time_util.py,sha256=bY5kj9dmyOuLEQ6uYGQK7jU7y1RMiHZgevEKnkcQcSU,1461
74
+ solax_py_library-1.0.0.2503.dist-info/METADATA,sha256=vk7Hfoh4mLBm6qpGLhpsqNgPN01FRrex8Cu24KqzNYg,1827
75
+ solax_py_library-1.0.0.2503.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
76
+ solax_py_library-1.0.0.2503.dist-info/RECORD,,