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.
- alphaess_aio-0.0.0.dist-info/LICENSE +21 -0
- alphaess_aio-0.0.0.dist-info/METADATA +70 -0
- alphaess_aio-0.0.0.dist-info/RECORD +8 -0
- alphaess_aio-0.0.0.dist-info/WHEEL +5 -0
- alphaess_aio-0.0.0.dist-info/top_level.txt +1 -0
- alphaessaio/__init__.py +7 -0
- alphaessaio/client.py +443 -0
- alphaessaio/response.py +636 -0
|
@@ -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 @@
|
|
|
1
|
+
alphaessaio
|
alphaessaio/__init__.py
ADDED
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)
|
alphaessaio/response.py
ADDED
|
@@ -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
|