alphaess-aio 0.0.0__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 zeguramente
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,70 @@
1
+ Metadata-Version: 2.1
2
+ Name: alphaess-aio
3
+ Version: 0.0.0
4
+ Summary: Sends get and post requests to available AlphaCloud API endpoints.
5
+ Author-email: Markus Ziegler <frage_n@web.de>
6
+ Maintainer-email: Markus Ziegler <frage_n@web.de>
7
+ License: MIT License
8
+
9
+ Copyright (c) 2024 zeguramente
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
28
+
29
+ Project-URL: Repository, https://github.com/zeguramente/alphaess-aio
30
+ Keywords: alphaess,api
31
+ Classifier: Development Status :: 4 - Beta
32
+ Classifier: Programming Language :: Python
33
+ Requires-Python: >=3.10
34
+ Description-Content-Type: text/markdown
35
+ License-File: LICENSE
36
+ Requires-Dist: aiohttp==3.9.3
37
+ Requires-Dist: pydantic==2.6.4
38
+ Provides-Extra: lint
39
+ Requires-Dist: ruff>=0.4.2; extra == "lint"
40
+ Provides-Extra: test
41
+ Requires-Dist: pytest; extra == "test"
42
+ Requires-Dist: pytest-mock; extra == "test"
43
+ Requires-Dist: pytest-asyncio; extra == "test"
44
+ Requires-Dist: pytest-aiohttp; extra == "test"
45
+
46
+ # Alphaess-aio - a Alpha Open API client
47
+
48
+ ## About
49
+
50
+ Sends get and post requests to available AlphaCloud API endpoints and retrieves data about you AlphaESS system.
51
+ Code generated out of API description.
52
+
53
+ ## Prerequisites
54
+
55
+ Register account at https://open.alphaess.com/. You will recieve an AppID and AppSecret needed for authentification.
56
+
57
+ ## How to use
58
+
59
+ ```python
60
+ import asyncio
61
+ from alphaessaio import AlphaEssAPI, AlphaEssAuth
62
+
63
+ # setup auth
64
+ auth = AlphaEssAuth(appid="your_app_id", appsecret="your_app_secret")
65
+
66
+ #init api
67
+ alphaess_api = AlphaEssAPI(auth)
68
+
69
+ ess_list = asyncio.run(alphaess_api.get_ess_list())
70
+ ```
@@ -0,0 +1,8 @@
1
+ alphaessaio/__init__.py,sha256=BYSefY6wRYNeTACcqmfJkKKTQC_g4e9goaiyJaCFC4o,139
2
+ alphaessaio/client.py,sha256=FpfqWwzQ5J7DxHY5B6RuGHY087-GVe2AkWPZcnGBzX8,14978
3
+ alphaessaio/response.py,sha256=ZNH2NQ7gmmD0G6x_CIo4TbUqw1tqqm7at9rhXobcVdM,21737
4
+ alphaess_aio-0.0.0.dist-info/LICENSE,sha256=mGNPWRhKGcc61AN72O3M7i4CuJu_VuTcFBWNcpe8LaQ,1068
5
+ alphaess_aio-0.0.0.dist-info/METADATA,sha256=2LyQDGJfhj8lN7qnpib18JexHKAVocd3LBnlXXcYsYU,2678
6
+ alphaess_aio-0.0.0.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
7
+ alphaess_aio-0.0.0.dist-info/top_level.txt,sha256=inFWZRPfHD42viOPGUjT5E30RAxpKp4yLDBkIv7WovA,12
8
+ alphaess_aio-0.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (75.5.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ alphaessaio
@@ -0,0 +1,7 @@
1
+ """Import stuff"""
2
+
3
+ from alphaessaio.client import AlphaEssAPI, AlphaEssAuth
4
+
5
+ __all__ = [AlphaEssAPI, AlphaEssAuth]
6
+
7
+ __version__ = "0.0.0"
alphaessaio/client.py ADDED
@@ -0,0 +1,443 @@
1
+ """Sending requests to AlphaESS API"""
2
+
3
+ import logging
4
+ import time
5
+ import hashlib
6
+ import json
7
+ import aiohttp
8
+ import pydantic
9
+ from alphaessaio import response
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ class AlphaEssRequestError(Exception):
15
+ def __init__(self, response_data: dict):
16
+ message = f"Error: {response_data}"
17
+ super().__init__(message)
18
+
19
+
20
+ class AlphaEssAuth(pydantic.BaseModel):
21
+ appid: str
22
+ appsecret: pydantic.SecretStr
23
+
24
+ def _get_signature(self, timestamp) -> str:
25
+ return str(
26
+ hashlib.sha512(
27
+ (f"{self.appid}{self.appsecret.get_secret_value()}{timestamp}").encode(
28
+ "ascii"
29
+ )
30
+ ).hexdigest()
31
+ )
32
+
33
+ def create_headers(self):
34
+ timestamp = str(int(time.time()))
35
+ sign = self._get_signature(timestamp)
36
+ return {"appId": self.appid, "timeStamp": timestamp, "sign": sign}
37
+
38
+
39
+ class AlphaEssAPI:
40
+ def __init__(self, auth: AlphaEssAuth):
41
+ self.auth = auth
42
+
43
+ async def _get(self, url, params) -> dict:
44
+ headers = self.auth.create_headers()
45
+ async with aiohttp.ClientSession() as session:
46
+ logger.debug(f"Sending get request to {url=} with {params=}")
47
+ async with session.get(url, headers=headers, params=params) as resp:
48
+ return await self._evaluate_response(resp)
49
+
50
+ async def _post(self, url, params) -> dict:
51
+ headers = self.auth.create_headers()
52
+ async with aiohttp.ClientSession() as session:
53
+ async with session.post(url, headers=headers, json=params) as resp:
54
+ return await self._evaluate_response(resp)
55
+
56
+ @staticmethod
57
+ async def _evaluate_response(resp: aiohttp.ClientResponse) -> dict:
58
+ try:
59
+ data = await resp.json()
60
+ logger.debug(f"api response: {data}")
61
+ except json.JSONDecodeError as json_decode_error:
62
+ raise AlphaEssRequestError(
63
+ {"msg": "returned data is not valid json", "err": json_decode_error}
64
+ )
65
+ if resp.status == 200 and data.get("code", 0) == 200:
66
+ logger.debug(f"Request successful. {resp.url}")
67
+ return data
68
+ logger.error(f"Request error: {data=}")
69
+ raise AlphaEssRequestError(data)
70
+
71
+ @pydantic.validate_call
72
+ async def get_ev_charger_config_list(
73
+ self, sys_sn: str
74
+ ) -> response.EvChargerConfigList:
75
+ """Obtain the SN of the charging pile according to the SN, and set the model
76
+
77
+ Args:
78
+ sys_sn (str): System S/N
79
+
80
+ Returns:
81
+ (response.EvChargerConfigList): response data
82
+ """
83
+
84
+ raw_response: dict = await self._get(
85
+ "https://openapi.alphaess.com/api/getEvChargerConfigList", {"sysSn": sys_sn}
86
+ )
87
+
88
+ return response.EvChargerConfigList(**raw_response)
89
+
90
+ @pydantic.validate_call
91
+ async def get_ev_charger_currents_by_sn(
92
+ self, sys_sn: str
93
+ ) -> response.EvChargerCurrentsBySn:
94
+ """Obtain the current setting of charging pile household according to SN
95
+
96
+ Args:
97
+ sys_sn (str): sys sn
98
+
99
+ Returns:
100
+ (response.EvChargerCurrentsBySn): response data
101
+ """
102
+
103
+ raw_response: dict = await self._get(
104
+ "https://openapi.alphaess.com/api/getEvChargerCurrentsBySn",
105
+ {"sysSn": sys_sn},
106
+ )
107
+
108
+ return response.EvChargerCurrentsBySn(**raw_response)
109
+
110
+ @pydantic.validate_call
111
+ async def set_ev_charger_currents_by_sn(
112
+ self, sys_sn: str, currentsetting: float
113
+ ) -> response.EvChargerCurrentsBySn:
114
+ """Set charging pile household current setting according to SN
115
+
116
+ Args:
117
+ sys_sn (str): SN
118
+ currentsetting (float): Household current setup
119
+
120
+ Returns:
121
+ (response.EvChargerCurrentsBySn): response data
122
+ """
123
+
124
+ raw_response: dict = await self._post(
125
+ "https://openapi.alphaess.com/api/setEvChargerCurrentsBySn",
126
+ {"sysSn": sys_sn, "currentsetting": currentsetting},
127
+ )
128
+
129
+ return response.EvChargerCurrentsBySn(**raw_response)
130
+
131
+ @pydantic.validate_call
132
+ async def get_ev_charger_status_by_sn(
133
+ self, sys_sn: str, evcharger_sn: str
134
+ ) -> response.EvChargerStatusBySn:
135
+ """Obtain charging pile status according to SN+charging pile SN
136
+
137
+ Args:
138
+ sys_sn (str): sys SN
139
+ evcharger_sn (str): EV-charger SN
140
+
141
+ Returns:
142
+ (response.EvChargerStatusBySn): response data
143
+ """
144
+
145
+ raw_response: dict = await self._get(
146
+ "https://openapi.alphaess.com/api/getEvChargerStatusBySn",
147
+ {"sysSn": sys_sn, "evchargerSn": evcharger_sn},
148
+ )
149
+
150
+ return response.EvChargerStatusBySn(**raw_response)
151
+
152
+ @pydantic.validate_call
153
+ async def remote_control_ev_charger(
154
+ self, sys_sn: str, evcharger_sn: str, control_mode: int
155
+ ) -> response.ControlEvCharger:
156
+ """According to SN+ charging pile SN remote control charging pile to start charging/stop charging
157
+
158
+ Args:
159
+ sys_sn (str): sys sn
160
+ evcharger_sn (str): EV-charger SN
161
+ control_mode (int): 0-Stop Charging,1-Start Charging
162
+
163
+ Returns:
164
+ (response.ControlEvCharger): response data
165
+ """
166
+
167
+ raw_response: dict = await self._post(
168
+ "https://openapi.alphaess.com/api/remoteControlEvCharger",
169
+ {"sysSn": sys_sn, "evchargerSn": evcharger_sn, "controlMode": control_mode},
170
+ )
171
+
172
+ return response.ControlEvCharger(**raw_response)
173
+
174
+ @pydantic.validate_call
175
+ async def get_sum_data_for_customer(
176
+ self, sys_sn: str
177
+ ) -> response.SumDataForCustomer:
178
+ """According SN to get System Summary data
179
+
180
+ Args:
181
+ sys_sn (str): System S/N
182
+
183
+ Returns:
184
+ (response.SumDataForCustomer): response data
185
+ """
186
+
187
+ raw_response: dict = await self._get(
188
+ "https://openapi.alphaess.com/api/getSumDataForCustomer", {"sysSn": sys_sn}
189
+ )
190
+
191
+ return response.SumDataForCustomer(**raw_response)
192
+
193
+ @pydantic.validate_call
194
+ async def get_last_power_data(self, sys_sn: str) -> response.LastPowerData:
195
+ """Get real-time power data based on SN
196
+
197
+ Args:
198
+ sys_sn (str): system SN
199
+
200
+ Returns:
201
+ (response.LastPowerData): response data
202
+ """
203
+
204
+ raw_response: dict = await self._get(
205
+ "https://openapi.alphaess.com/api/getLastPowerData", {"sysSn": sys_sn}
206
+ )
207
+
208
+ return response.LastPowerData(**raw_response)
209
+
210
+ @pydantic.validate_call
211
+ async def get_one_day_power_by_sn(
212
+ self, query_date: str, sys_sn: str
213
+ ) -> response.OneDayPowerBySn:
214
+ """According SN to get system power data
215
+
216
+ Args:
217
+ query_date (str): Date,Format:yyyy-MM-dd
218
+ sys_sn (str): System S/N
219
+
220
+ Returns:
221
+ (response.OneDayPowerBySn): response data
222
+ """
223
+
224
+ raw_response: dict = await self._get(
225
+ "https://openapi.alphaess.com/api/getOneDayPowerBySn",
226
+ {"queryDate": query_date, "sysSn": sys_sn},
227
+ )
228
+
229
+ return response.OneDayPowerBySn(**raw_response)
230
+
231
+ @pydantic.validate_call
232
+ async def get_one_date_energy_by_sn(
233
+ self, query_date: str, sys_sn: str
234
+ ) -> response.OneDateEnergyBySn:
235
+ """According SN to get System Energy Data
236
+
237
+ Args:
238
+ query_date (str): Date,Format:yyyy-MM-dd
239
+ sys_sn (str): System S/N
240
+
241
+ Returns:
242
+ (response.OneDateEnergyBySn): response data
243
+ """
244
+
245
+ raw_response: dict = await self._get(
246
+ "https://openapi.alphaess.com/api/getOneDateEnergyBySn",
247
+ {"queryDate": query_date, "sysSn": sys_sn},
248
+ )
249
+
250
+ return response.OneDateEnergyBySn(**raw_response)
251
+
252
+ @pydantic.validate_call
253
+ async def get_charge_config_info(self, sys_sn: str) -> response.ChargeConfigInfo:
254
+ """According SN to get charging setting information
255
+
256
+ Args:
257
+ sys_sn (str): System S/N
258
+
259
+ Returns:
260
+ (response.ChargeConfigInfo): response data
261
+ """
262
+
263
+ raw_response: dict = await self._get(
264
+ "https://openapi.alphaess.com/api/getChargeConfigInfo", {"sysSn": sys_sn}
265
+ )
266
+
267
+ return response.ChargeConfigInfo(**raw_response)
268
+
269
+ @pydantic.validate_call
270
+ async def update_charge_config_info(
271
+ self,
272
+ sys_sn: str,
273
+ bat_high_cap: float,
274
+ grid_charge: int,
275
+ time_chae1: str,
276
+ time_chae2: str,
277
+ time_chaf1: str,
278
+ time_chaf2: str,
279
+ ) -> response.ChargeConfigInfo:
280
+ """According SN to Set charging information,Setting frequency 24 hours, set once a day
281
+
282
+ Args:
283
+ sys_sn (str): System S/N
284
+ bat_high_cap (float): Charging Stops at SOC [%]
285
+ grid_charge (int): Enable Grid Charging Battery
286
+ time_chae1 (str): Charging Period 1 end time, the time format is HH:mm, such as: 00:00, the maximum is 23:45, the minimum is 00:00, and the interval is 15 minutes, such as: 00:15, 00:30, 00:45, otherwise no effect
287
+ time_chae2 (str): Charging Period 2 end time, the time format is HH:mm, such as: 00:00, the maximum is 23:45, the minimum is 00:00, and the interval is 15 minutes, such as: 00:15, 00:30, 00:45, otherwise no effect
288
+ time_chaf1 (str): Charging Period 1 start time, the time format is HH:mm, such as: 00:00, the maximum is 23:45, the minimum is 00:00, and the interval is 15 minutes, such as: 00:15, 00:30, 00:45, otherwise no effect
289
+ time_chaf2 (str): Charging Period 2 start time, the time format is HH:mm, such as: 00:00, the maximum is 23:45, the minimum is 00:00, and the interval is 15 minutes, such as: 00:15, 00:30, 00:45, otherwise no effect
290
+
291
+ Returns:
292
+ (response.ChargeConfigInfo): response data
293
+ """
294
+
295
+ raw_response: dict = await self._post(
296
+ "https://openapi.alphaess.com/api/updateChargeConfigInfo",
297
+ {
298
+ "sysSn": sys_sn,
299
+ "batHighCap": bat_high_cap,
300
+ "gridCharge": grid_charge,
301
+ "timeChae1": time_chae1,
302
+ "timeChae2": time_chae2,
303
+ "timeChaf1": time_chaf1,
304
+ "timeChaf2": time_chaf2,
305
+ },
306
+ )
307
+
308
+ return response.ChargeConfigInfo(**raw_response)
309
+
310
+ @pydantic.validate_call
311
+ async def get_dis_charge_config_info(
312
+ self, sys_sn: str
313
+ ) -> response.DisChargeConfigInfo:
314
+ """According to SN discharge setting information
315
+
316
+ Args:
317
+ sys_sn (str): System S/N
318
+
319
+ Returns:
320
+ (response.DisChargeConfigInfo): response data
321
+ """
322
+
323
+ raw_response: dict = await self._get(
324
+ "https://openapi.alphaess.com/api/getDisChargeConfigInfo", {"sysSn": sys_sn}
325
+ )
326
+
327
+ return response.DisChargeConfigInfo(**raw_response)
328
+
329
+ @pydantic.validate_call
330
+ async def update_dis_charge_config_info(
331
+ self,
332
+ bat_use_cap: float,
333
+ ctr_dis: int,
334
+ time_dise1: str,
335
+ time_dise2: str,
336
+ time_disf1: str,
337
+ time_disf2: str,
338
+ sys_sn: str,
339
+ ) -> response.DisChargeConfigInfo:
340
+ """According to SN Set discharge information,Setting frequency 24 hours, set once a day
341
+
342
+ Args:
343
+ bat_use_cap (float): Discharging Cutoff SOC [%]
344
+ ctr_dis (int): Enable Battery Discharge Time Control
345
+ time_dise1 (str): Discharging Period 1 End time, the time format is HH:mm, such as: 00:00, the maximum is 23:45, the minimum is 00:00, and the interval is 15 minutes, such as: 00:15, 00:30, 00:45, otherwise no effect
346
+ time_dise2 (str): Discharging Period 2 End time, the time format is HH:mm, such as: 00:00, the maximum is 23:45, the minimum is 00:00, and the interval is 15 minutes, such as: 00:15, 00:30, 00:45, otherwise no effect
347
+ time_disf1 (str): Discharging Period 1 Start time, the time format is HH:mm, such as: 00:00, the maximum is 23:45, the minimum is 00:00, and the interval is 15 minutes, such as: 00:15, 00:30, 00:45, otherwise no effect
348
+ time_disf2 (str): Discharging Period 2 Start time, the time format is HH:mm, such as: 00:00, the maximum is 23:45, the minimum is 00:00, and the interval is 15 minutes, such as: 00:15, 00:30, 00:45, otherwise no effect
349
+ sys_sn (str): System S/N
350
+
351
+ Returns:
352
+ (response.DisChargeConfigInfo): response data
353
+ """
354
+
355
+ raw_response: dict = await self._post(
356
+ "https://openapi.alphaess.com/api/updateDisChargeConfigInfo",
357
+ {
358
+ "batUseCap": bat_use_cap,
359
+ "ctrDis": ctr_dis,
360
+ "timeDise1": time_dise1,
361
+ "timeDise2": time_dise2,
362
+ "timeDisf1": time_disf1,
363
+ "timeDisf2": time_disf2,
364
+ "sysSn": sys_sn,
365
+ },
366
+ )
367
+
368
+ return response.DisChargeConfigInfo(**raw_response)
369
+
370
+ @pydantic.validate_call
371
+ async def get_verification_code(
372
+ self, sys_sn: str, check_code: str
373
+ ) -> response.VerificationCode:
374
+ """According to SN get the check code according to SN
375
+
376
+ Args:
377
+ sys_sn (str): System S/N
378
+ check_code (str): checkCode
379
+
380
+ Returns:
381
+ (response.VerificationCode): response data
382
+ """
383
+
384
+ raw_response: dict = await self._get(
385
+ "https://openapi.alphaess.com/api/getVerificationCode",
386
+ {"sysSn": sys_sn, "checkCode": check_code},
387
+ )
388
+
389
+ return response.VerificationCode(**raw_response)
390
+
391
+ @pydantic.validate_call
392
+ async def bind_sn(self, sys_sn: str, code: str) -> response.Sn:
393
+ """According to SN and check code Bind the system bind the system
394
+
395
+ Args:
396
+ sys_sn (str): System S/N
397
+ code (str): Verification Code
398
+
399
+ Returns:
400
+ (response.Sn): response data
401
+ """
402
+
403
+ raw_response: dict = await self._post(
404
+ "https://openapi.alphaess.com/api/bindSn", {"sysSn": sys_sn, "code": code}
405
+ )
406
+
407
+ return response.Sn(**raw_response)
408
+
409
+ @pydantic.validate_call
410
+ async def un_bind_sn(self, sys_sn: str) -> response.BindSn:
411
+ """According to SN and check code Unbind the system
412
+
413
+ Args:
414
+ sys_sn (str): System S/N
415
+
416
+ Returns:
417
+ (response.BindSn): response data
418
+ """
419
+
420
+ raw_response: dict = await self._post(
421
+ "https://openapi.alphaess.com/api/unBindSn", {"sysSn": sys_sn}
422
+ )
423
+
424
+ return response.BindSn(**raw_response)
425
+
426
+ @pydantic.validate_call
427
+ async def get_ess_list(
428
+ self,
429
+ ) -> response.EssList:
430
+ """According to SN to get system list data
431
+
432
+ Args:
433
+
434
+
435
+ Returns:
436
+ (response.EssList): response data
437
+ """
438
+
439
+ raw_response: dict = await self._get(
440
+ "https://openapi.alphaess.com/api/getEssList", {}
441
+ )
442
+
443
+ return response.EssList(**raw_response)
@@ -0,0 +1,636 @@
1
+ """Response classes for alphaess requests."""
2
+
3
+ import logging
4
+ import datetime
5
+ from typing import List
6
+ from pydantic import BaseModel, Field, model_validator, ConfigDict, AliasChoices
7
+
8
+
9
+ class DataSn(BaseModel):
10
+ "Response data model for Sn"
11
+
12
+ model_config = ConfigDict(extra="allow")
13
+
14
+ @model_validator(mode="after")
15
+ def check_extras(self):
16
+ logging.debug(f"extra fields detected: {self.model_extra}")
17
+ return self
18
+
19
+
20
+ class DataVerificationCode(BaseModel):
21
+ "Response data model for VerificationCode"
22
+
23
+ model_config = ConfigDict(extra="allow")
24
+
25
+ @model_validator(mode="after")
26
+ def check_extras(self):
27
+ logging.debug(f"extra fields detected: {self.model_extra}")
28
+ return self
29
+
30
+
31
+ class DataControlEvCharger(BaseModel):
32
+ "Response data model for ControlEvCharger"
33
+
34
+ model_config = ConfigDict(extra="allow")
35
+
36
+ @model_validator(mode="after")
37
+ def check_extras(self):
38
+ logging.debug(f"extra fields detected: {self.model_extra}")
39
+ return self
40
+
41
+
42
+ class DataEvChargerConfigList(BaseModel):
43
+ "Response data model for getEvChargerConfigList"
44
+
45
+ evcharger_sn: str = Field(..., alias="evchargerSn", description="EV-charger SN")
46
+ evcharger_model: str = Field(
47
+ ..., alias="evchargerModel", description="EV-charger model"
48
+ )
49
+
50
+ model_config = ConfigDict(extra="allow")
51
+
52
+ @model_validator(mode="after")
53
+ def check_extras(self):
54
+ if self.model_extra:
55
+ logging.debug(f"extra fields detected: {self.model_extra }")
56
+ return self
57
+
58
+
59
+ class EvChargerConfigList(BaseModel):
60
+ "Response data model for getEvChargerConfigList"
61
+
62
+ code: int = Field(..., alias="code", description="Return Code")
63
+ info: str = Field(
64
+ ..., validation_alias=AliasChoices("info", "msg"), description="Return Message"
65
+ )
66
+ data: List[DataEvChargerConfigList] = Field(
67
+ ..., alias="data", description="Data List"
68
+ )
69
+
70
+ model_config = ConfigDict(extra="allow")
71
+
72
+ @model_validator(mode="after")
73
+ def check_extras(self):
74
+ if self.model_extra:
75
+ logging.debug(f"extra fields detected: {self.model_extra }")
76
+ return self
77
+
78
+
79
+ class DataEvChargerCurrentsBySn(BaseModel):
80
+ "Response data model for getEvChargerCurrentsBySn"
81
+
82
+ currentsetting: float = Field(
83
+ ..., alias="currentsetting", description="Household current setup"
84
+ )
85
+
86
+ model_config = ConfigDict(extra="allow")
87
+
88
+ @model_validator(mode="after")
89
+ def check_extras(self):
90
+ if self.model_extra:
91
+ logging.debug(f"extra fields detected: {self.model_extra }")
92
+ return self
93
+
94
+
95
+ class EvChargerCurrentsBySn(BaseModel):
96
+ "Response data model for set and getEvChargerCurrentsBySn"
97
+
98
+ code: int = Field(..., alias="code", description="Return Code")
99
+ info: str = Field(
100
+ ..., validation_alias=AliasChoices("info", "msg"), description="Return Message"
101
+ )
102
+ data: DataEvChargerCurrentsBySn = Field(..., alias="data", description="Data")
103
+
104
+ model_config = ConfigDict(extra="allow")
105
+
106
+ @model_validator(mode="after")
107
+ def check_extras(self):
108
+ if self.model_extra:
109
+ logging.debug(f"extra fields detected: {self.model_extra }")
110
+ return self
111
+
112
+
113
+ class DataEvChargerStatusBySn(BaseModel):
114
+ "Response data model for getEvChargerStatusBySn"
115
+
116
+ evcharger_status: int = Field(
117
+ ...,
118
+ alias="evchargerStatus",
119
+ description="1: Available state (not plugged in)2: Preparing state of insertion (plugged in and not activated)3: Charging state (charging with power output)4: SuspendedEVSE pile Suspended at the terminal (already started but no available power)5: SuspendedEV Suspended at the vehicle end (with available power, waiting for the car to respond)6: Finishing The charging end state (actively swiping the card to stop or EMS stop control)9: Faulted fault state (pile failure)",
120
+ )
121
+
122
+ model_config = ConfigDict(extra="allow")
123
+
124
+ @model_validator(mode="after")
125
+ def check_extras(self):
126
+ if self.model_extra:
127
+ logging.debug(f"extra fields detected: {self.model_extra }")
128
+ return self
129
+
130
+
131
+ class EvChargerStatusBySn(BaseModel):
132
+ "Response data model for getEvChargerStatusBySn"
133
+
134
+ code: int = Field(..., alias="code", description="Return Code")
135
+ info: str = Field(
136
+ ..., validation_alias=AliasChoices("info", "msg"), description="Return Message"
137
+ )
138
+ data: List[DataEvChargerStatusBySn] = Field(
139
+ ..., alias="data", description="Data List"
140
+ )
141
+
142
+ model_config = ConfigDict(extra="allow")
143
+
144
+ @model_validator(mode="after")
145
+ def check_extras(self):
146
+ if self.model_extra:
147
+ logging.debug(f"extra fields detected: {self.model_extra }")
148
+ return self
149
+
150
+
151
+ class ControlEvCharger(BaseModel):
152
+ "Response data model for remoteControlEvCharger"
153
+
154
+ code: int = Field(..., alias="code", description="Return Code")
155
+ info: str = Field(
156
+ ..., validation_alias=AliasChoices("info", "msg"), description="Return Message"
157
+ )
158
+ data: DataControlEvCharger = Field(..., alias="data", description="Data")
159
+
160
+ model_config = ConfigDict(extra="allow")
161
+
162
+ @model_validator(mode="after")
163
+ def check_extras(self):
164
+ if self.model_extra:
165
+ logging.debug(f"extra fields detected: {self.model_extra }")
166
+ return self
167
+
168
+
169
+ class DataSumDataForCustomer(BaseModel):
170
+ "Response data model for getSumDataForCustomer"
171
+
172
+ epvtoday: float = Field(
173
+ ..., alias="epvtoday", description="Today's Generation,unit:kwh"
174
+ )
175
+ epvtotal: float = Field(
176
+ ..., alias="epvtotal", description="Total Generation,unit:kwh"
177
+ )
178
+ eload: float = Field(..., alias="eload", description="Today's Load,unit:kwh")
179
+ eoutput: float = Field(
180
+ ..., alias="eoutput", description="Today's Feed-in,unit:kwh"
181
+ )
182
+ einput: float = Field(..., alias="einput", description="Today's Consumed,unit:kwh")
183
+ echarge: float = Field(
184
+ ..., alias="echarge", description="Today's Charged,unit:kwh"
185
+ )
186
+ edischarge: float = Field(
187
+ ..., alias="edischarge", description="Today's DisCharged,unit:kwh"
188
+ )
189
+ today_income: float = Field(..., alias="todayIncome", description="Today's Income")
190
+ total_income: float = Field(..., alias="totalIncome", description="Total Profit")
191
+ eself_consumption: float = Field(
192
+ ..., alias="eselfConsumption", description="Self-consumption,unit:%"
193
+ )
194
+ eself_sufficiency: float = Field(
195
+ ..., alias="eselfSufficiency", description="Self-sufficiency,unit:%"
196
+ )
197
+ tree_num: float = Field(..., alias="treeNum", description="Trees Planted")
198
+ carbon_num: float = Field(
199
+ ..., alias="carbonNum", description="CO2 Reduction,unit:kg"
200
+ )
201
+ money_type: str = Field(..., alias="moneyType", description="Currencies")
202
+
203
+ model_config = ConfigDict(extra="allow")
204
+
205
+ @model_validator(mode="after")
206
+ def check_extras(self):
207
+ if self.model_extra:
208
+ logging.debug(f"extra fields detected: {self.model_extra }")
209
+ return self
210
+
211
+
212
+ class SumDataForCustomer(BaseModel):
213
+ "Response data model for getSumDataForCustomer"
214
+
215
+ code: int = Field(..., alias="code", description="Return Code")
216
+ info: str = Field(
217
+ ..., validation_alias=AliasChoices("info", "msg"), description="Return Message"
218
+ )
219
+ data: DataSumDataForCustomer = Field(..., alias="data", description="Return Data")
220
+
221
+ model_config = ConfigDict(extra="allow")
222
+
223
+ @model_validator(mode="after")
224
+ def check_extras(self):
225
+ if self.model_extra:
226
+ logging.debug(f"extra fields detected: {self.model_extra }")
227
+ return self
228
+
229
+
230
+ class PevDetail(BaseModel):
231
+ "Response data model for getLastPowerData"
232
+
233
+ ev1_power: float = Field(..., alias="ev1Power", description="ev1Power")
234
+ ev2_power: float = Field(..., alias="ev2Power", description="ev2Power")
235
+ ev3_power: float = Field(..., alias="ev3Power", description="ev3Power")
236
+ ev4_power: float = Field(..., alias="ev4Power", description="ev4Power")
237
+
238
+ model_config = ConfigDict(extra="allow")
239
+
240
+ @model_validator(mode="after")
241
+ def check_extras(self):
242
+ if self.model_extra:
243
+ logging.debug(f"extra fields detected: {self.model_extra }")
244
+ return self
245
+
246
+
247
+ class PgridDetail(BaseModel):
248
+ "Response data model for getLastPowerData"
249
+
250
+ pmeter_l1: float = Field(..., alias="pmeterL1", description="pmeterL1")
251
+ pmeter_l2: float = Field(..., alias="pmeterL2", description="pmeterL2")
252
+ pmeter_l3: float = Field(..., alias="pmeterL3", description="pmeterL3")
253
+
254
+ model_config = ConfigDict(extra="allow")
255
+
256
+ @model_validator(mode="after")
257
+ def check_extras(self):
258
+ if self.model_extra:
259
+ logging.debug(f"extra fields detected: {self.model_extra }")
260
+ return self
261
+
262
+
263
+ class PpvDetail(BaseModel):
264
+ "Response data model for getLastPowerData"
265
+
266
+ ppv1: float = Field(..., alias="ppv1", description="ppv1")
267
+ ppv2: float = Field(..., alias="ppv2", description="ppv2")
268
+ ppv3: float = Field(..., alias="ppv3", description="ppv3")
269
+ ppv4: float = Field(..., alias="ppv4", description="ppv4")
270
+ pmeter_dc: float = Field(..., alias="pmeterDc", description="pmeterDc")
271
+
272
+ model_config = ConfigDict(extra="allow")
273
+
274
+ @model_validator(mode="after")
275
+ def check_extras(self):
276
+ if self.model_extra:
277
+ logging.debug(f"extra fields detected: {self.model_extra }")
278
+ return self
279
+
280
+
281
+ class DataLastPowerData(BaseModel):
282
+ "Response data model for getLastPowerData"
283
+
284
+ ppv: float = Field(..., alias="ppv", description="Pv total power, unit: W")
285
+ ppv_detail: PpvDetail = Field(..., alias="ppvDetail", description="Data entity")
286
+ pload: float = Field(..., alias="pload", description="Load, unit: W")
287
+ soc: float = Field(..., alias="soc", description="soc")
288
+ pgrid: float = Field(
289
+ ...,
290
+ alias="pgrid",
291
+ description="When pgrid is positive, it means taking electricity from the mains; when pgrid is negative, it means selling electricity. Unit:W",
292
+ )
293
+ pgrid_detail: PgridDetail = Field(
294
+ ..., alias="pgridDetail", description="data entity"
295
+ )
296
+ pbat: float = Field(..., alias="pbat", description="Battery power, unit: W")
297
+ preal_l1: float = Field(..., alias="prealL1", description="prealL1")
298
+ preal_l2: float = Field(..., alias="prealL2", description="prealL2")
299
+ preal_l3: float = Field(..., alias="prealL3", description="prealL3")
300
+ pev: float = Field(
301
+ ..., alias="pev", description="Total power of charging pile, unit: W"
302
+ )
303
+ pev_detail: PevDetail = Field(..., alias="pevDetail", description="Data entity")
304
+
305
+ model_config = ConfigDict(extra="allow")
306
+
307
+ @model_validator(mode="after")
308
+ def check_extras(self):
309
+ if self.model_extra:
310
+ logging.debug(f"extra fields detected: {self.model_extra }")
311
+ return self
312
+
313
+
314
+ class LastPowerData(BaseModel):
315
+ "Response data model for getLastPowerData"
316
+
317
+ code: int = Field(
318
+ ...,
319
+ alias="code",
320
+ description="Return status. If 200 is returned, the operation is successful. If other codes are returned, you need to check the return code to indicate the description corresponding to this code.",
321
+ )
322
+ info: str = Field(
323
+ ...,
324
+ validation_alias=AliasChoices("info", "msg"),
325
+ description="Return information",
326
+ )
327
+ data: DataLastPowerData = Field(..., alias="data", description="return data set")
328
+
329
+ model_config = ConfigDict(extra="allow")
330
+
331
+ @model_validator(mode="after")
332
+ def check_extras(self):
333
+ if self.model_extra:
334
+ logging.debug(f"extra fields detected: {self.model_extra }")
335
+ return self
336
+
337
+
338
+ class DataOneDayPowerBySn(BaseModel):
339
+ "Response data model for getOneDayPowerBySn"
340
+
341
+ cbat: float = Field(
342
+ ..., validation_alias=AliasChoices("cbat", "cobat"), description="BAT"
343
+ )
344
+ feed_in: float = Field(..., alias="feedIn", description="Feed-in")
345
+ grid_charge: float = Field(
346
+ ..., alias="gridCharge", description="Grid purchase real-time power"
347
+ )
348
+ load: float = Field(..., alias="load", description="Load")
349
+ pcharging_pile: float = Field(
350
+ ..., alias="pchargingPile", description="Charging pile power"
351
+ )
352
+ ppv: float = Field(..., alias="ppv", description="PV power")
353
+ sys_sn: str = Field(..., alias="sysSn", description="System S/N")
354
+ upload_time: datetime.datetime = Field(
355
+ ..., alias="uploadTime", description="upload Time"
356
+ )
357
+
358
+ model_config = ConfigDict(extra="allow")
359
+
360
+ @model_validator(mode="after")
361
+ def check_extras(self):
362
+ if self.model_extra:
363
+ logging.debug(f"extra fields detected: {self.model_extra }")
364
+ return self
365
+
366
+
367
+ class OneDayPowerBySn(BaseModel):
368
+ "Response data model for getOneDayPowerBySn"
369
+
370
+ code: int = Field(..., alias="code", description="Return Code")
371
+ info: str = Field(
372
+ ..., validation_alias=AliasChoices("info", "msg"), description="Return Message"
373
+ )
374
+ data: List[DataOneDayPowerBySn] = Field(
375
+ ..., alias="data", description="Return Data"
376
+ )
377
+
378
+ model_config = ConfigDict(extra="allow")
379
+
380
+ @model_validator(mode="after")
381
+ def check_extras(self):
382
+ if self.model_extra:
383
+ logging.debug(f"extra fields detected: {self.model_extra }")
384
+ return self
385
+
386
+
387
+ class DataOneDateEnergyBySn(BaseModel):
388
+ "Response data model for getOneDateEnergyBySn"
389
+
390
+ e_charge: float = Field(
391
+ ..., alias="eCharge", description="total energy charged from battery,unit:kWh"
392
+ )
393
+ e_charging_pile: float = Field(
394
+ ...,
395
+ alias="eChargingPile",
396
+ description="Total energy consumed by charging piles,unit:kWh",
397
+ )
398
+ e_discharge: float = Field(
399
+ ..., alias="eDischarge", description="Discharge,unit:kWh"
400
+ )
401
+ e_grid_charge: float = Field(
402
+ ..., alias="eGridCharge", description="Grid-charge,unit:kWh"
403
+ )
404
+ e_input: float = Field(
405
+ ..., alias="eInput", description="Grid consumption,unit:kWh"
406
+ )
407
+ e_output: float = Field(..., alias="eOutput", description="Feed-in,unit:kWh")
408
+ epv: float = Field(..., alias="epv", description="PV generation,unit:kWh")
409
+ sys_sn: str = Field(..., alias="sysSn", description="System S/N")
410
+ the_date: str = Field(..., alias="theDate", description="Date")
411
+
412
+ model_config = ConfigDict(extra="allow")
413
+
414
+ @model_validator(mode="after")
415
+ def check_extras(self):
416
+ if self.model_extra:
417
+ logging.debug(f"extra fields detected: {self.model_extra }")
418
+ return self
419
+
420
+
421
+ class OneDateEnergyBySn(BaseModel):
422
+ "Response data model for getOneDateEnergyBySn"
423
+
424
+ code: int = Field(..., alias="code", description="Return Code")
425
+ info: str = Field(
426
+ ..., validation_alias=AliasChoices("info", "msg"), description="Return Message"
427
+ )
428
+ data: DataOneDateEnergyBySn = Field(..., alias="data", description="Return Data")
429
+
430
+ model_config = ConfigDict(extra="allow")
431
+
432
+ @model_validator(mode="after")
433
+ def check_extras(self):
434
+ if self.model_extra:
435
+ logging.debug(f"extra fields detected: {self.model_extra }")
436
+ return self
437
+
438
+
439
+ class DataChargeConfigInfo(BaseModel):
440
+ "Response data model for getChargeConfigInfo"
441
+
442
+ bat_high_cap: float = Field(
443
+ ..., alias="batHighCap", description="Charging Stops at SOC [%]"
444
+ )
445
+ grid_charge: int = Field(
446
+ ..., alias="gridCharge", description="Enable Grid Charging Battery"
447
+ )
448
+ time_chae1: str = Field(
449
+ ..., alias="timeChae1", description="Charging Period 1 end time"
450
+ )
451
+ time_chae2: str = Field(
452
+ ..., alias="timeChae2", description="Charging Period 2 end time"
453
+ )
454
+ time_chaf1: str = Field(
455
+ ..., alias="timeChaf1", description="Charging Period 1 start time"
456
+ )
457
+ time_chaf2: str = Field(
458
+ ..., alias="timeChaf2", description="Charging Period 2 start time"
459
+ )
460
+
461
+ model_config = ConfigDict(extra="allow")
462
+
463
+ @model_validator(mode="after")
464
+ def check_extras(self):
465
+ if self.model_extra:
466
+ logging.debug(f"extra fields detected: {self.model_extra }")
467
+ return self
468
+
469
+
470
+ class ChargeConfigInfo(BaseModel):
471
+ "Response data model for update and getChargeConfigInfo"
472
+
473
+ code: int = Field(..., alias="code", description="Return Code")
474
+ info: str = Field(
475
+ ..., validation_alias=AliasChoices("info", "msg"), description="Return Message"
476
+ )
477
+ data: DataChargeConfigInfo = Field(..., alias="data", description="Return Data")
478
+
479
+ model_config = ConfigDict(extra="allow")
480
+
481
+ @model_validator(mode="after")
482
+ def check_extras(self):
483
+ if self.model_extra:
484
+ logging.debug(f"extra fields detected: {self.model_extra }")
485
+ return self
486
+
487
+
488
+ class DataDisChargeConfigInfo(BaseModel):
489
+ "Response data model for getDisChargeConfigInfo"
490
+
491
+ bat_use_cap: float = Field(
492
+ ..., alias="batUseCap", description="Discharging Cutoff SOC [%]"
493
+ )
494
+ ctr_dis: int = Field(
495
+ ..., alias="ctrDis", description="Enable Battery Discharge Time Control"
496
+ )
497
+ time_dise1: str = Field(
498
+ ..., alias="timeDise1", description="Discharging Period 1 End time"
499
+ )
500
+ time_dise2: str = Field(
501
+ ..., alias="timeDise2", description="Discharging Period 2 End time"
502
+ )
503
+ time_disf1: str = Field(
504
+ ..., alias="timeDisf1", description="Discharging Period 1 Start time"
505
+ )
506
+ time_disf2: str = Field(
507
+ ..., alias="timeDisf2", description="Discharging Period 2 Start time"
508
+ )
509
+
510
+ model_config = ConfigDict(extra="allow")
511
+
512
+ @model_validator(mode="after")
513
+ def check_extras(self):
514
+ if self.model_extra:
515
+ logging.debug(f"extra fields detected: {self.model_extra }")
516
+ return self
517
+
518
+
519
+ class DisChargeConfigInfo(BaseModel):
520
+ "Response data model for update and getDisChargeConfigInfo"
521
+
522
+ code: int = Field(..., alias="code", description="Return Code")
523
+ info: str = Field(
524
+ ..., validation_alias=AliasChoices("info", "msg"), description="Return Message"
525
+ )
526
+ data: DataDisChargeConfigInfo = Field(..., alias="data", description="Return Data")
527
+
528
+ model_config = ConfigDict(extra="allow")
529
+
530
+ @model_validator(mode="after")
531
+ def check_extras(self):
532
+ if self.model_extra:
533
+ logging.debug(f"extra fields detected: {self.model_extra }")
534
+ return self
535
+
536
+
537
+ class VerificationCode(BaseModel):
538
+ "Response data model for getVerificationCode"
539
+
540
+ code: int = Field(..., alias="code", description="Return Code")
541
+ info: str = Field(
542
+ ..., validation_alias=AliasChoices("info", "msg"), description="Return Message"
543
+ )
544
+ data: DataVerificationCode = Field(..., alias="data", description="Return Data")
545
+
546
+ model_config = ConfigDict(extra="allow")
547
+
548
+ @model_validator(mode="after")
549
+ def check_extras(self):
550
+ if self.model_extra:
551
+ logging.debug(f"extra fields detected: {self.model_extra }")
552
+ return self
553
+
554
+
555
+ class Sn(BaseModel):
556
+ "Response data model for bindSn"
557
+
558
+ code: int = Field(..., alias="code", description="Return Code")
559
+ info: str = Field(
560
+ ..., validation_alias=AliasChoices("info", "msg"), description="Return Message"
561
+ )
562
+ data: DataSn = Field(..., alias="data", description="Return Data")
563
+
564
+ model_config = ConfigDict(extra="allow")
565
+
566
+ @model_validator(mode="after")
567
+ def check_extras(self):
568
+ if self.model_extra:
569
+ logging.debug(f"extra fields detected: {self.model_extra }")
570
+ return self
571
+
572
+
573
+ class BindSn(BaseModel):
574
+ "Response data model for unBindSn"
575
+
576
+ code: int = Field(..., alias="code", description="Return Code")
577
+ info: str = Field(
578
+ ..., validation_alias=AliasChoices("info", "msg"), description="Return Message"
579
+ )
580
+ data: DataSn = Field(..., alias="data", description="Return Data")
581
+
582
+ model_config = ConfigDict(extra="allow")
583
+
584
+ @model_validator(mode="after")
585
+ def check_extras(self):
586
+ if self.model_extra:
587
+ logging.debug(f"extra fields detected: {self.model_extra }")
588
+ return self
589
+
590
+
591
+ class DataEssList(BaseModel):
592
+ "Response data model for getEssList"
593
+
594
+ cbat: float = Field(
595
+ ...,
596
+ validation_alias=AliasChoices("cbat", "cobat"),
597
+ description="battery capacity",
598
+ )
599
+ ems_status: str = Field(..., alias="emsStatus", description="EMS status")
600
+ mbat: str = Field(..., alias="mbat", description="battery model")
601
+ minv: str = Field(..., alias="minv", description="Inverter model")
602
+ poinv: float = Field(..., alias="poinv", description="Inverter nominal Power")
603
+ popv: float = Field(..., alias="popv", description="Pv nominal Power")
604
+ surplus_cobat: float = Field(
605
+ ..., alias="surplusCobat", description="Battery capacity remaining"
606
+ )
607
+ sys_sn: str = Field(..., alias="sysSn", description="System S/N")
608
+ us_capacity: float = Field(
609
+ ..., alias="usCapacity", description="Battery Available Percentage"
610
+ )
611
+
612
+ model_config = ConfigDict(extra="allow")
613
+
614
+ @model_validator(mode="after")
615
+ def check_extras(self):
616
+ if self.model_extra:
617
+ logging.debug(f"extra fields detected: {self.model_extra }")
618
+ return self
619
+
620
+
621
+ class EssList(BaseModel):
622
+ "Response data model for getEssList"
623
+
624
+ code: int = Field(..., alias="code", description="Return Code")
625
+ info: str = Field(
626
+ ..., validation_alias=AliasChoices("info", "msg"), description="Return Message"
627
+ )
628
+ data: List[DataEssList] = Field(..., alias="data", description="Return Data")
629
+
630
+ model_config = ConfigDict(extra="allow")
631
+
632
+ @model_validator(mode="after")
633
+ def check_extras(self):
634
+ if self.model_extra:
635
+ logging.debug(f"extra fields detected: {self.model_extra }")
636
+ return self