python-chargepoint 2.2.0__tar.gz → 2.3.1__tar.gz
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.
- {python_chargepoint-2.2.0 → python_chargepoint-2.3.1}/PKG-INFO +27 -1
- {python_chargepoint-2.2.0 → python_chargepoint-2.3.1}/README.md +26 -0
- {python_chargepoint-2.2.0 → python_chargepoint-2.3.1}/pyproject.toml +1 -1
- {python_chargepoint-2.2.0 → python_chargepoint-2.3.1}/python_chargepoint/__main__.py +109 -0
- {python_chargepoint-2.2.0 → python_chargepoint-2.3.1}/python_chargepoint/client.py +88 -150
- {python_chargepoint-2.2.0 → python_chargepoint-2.3.1}/python_chargepoint/types.py +22 -0
- {python_chargepoint-2.2.0 → python_chargepoint-2.3.1}/LICENSE +0 -0
- {python_chargepoint-2.2.0 → python_chargepoint-2.3.1}/python_chargepoint/__init__.py +0 -0
- {python_chargepoint-2.2.0 → python_chargepoint-2.3.1}/python_chargepoint/constants.py +0 -0
- {python_chargepoint-2.2.0 → python_chargepoint-2.3.1}/python_chargepoint/exceptions.py +0 -0
- {python_chargepoint-2.2.0 → python_chargepoint-2.3.1}/python_chargepoint/global_config.py +0 -0
- {python_chargepoint-2.2.0 → python_chargepoint-2.3.1}/python_chargepoint/session.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-chargepoint
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.1
|
|
4
4
|
Summary: A simple, Pythonic wrapper for the ChargePoint API.
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -172,6 +172,29 @@ await client.set_led_brightness(charger_id, 3) # 60%
|
|
|
172
172
|
await client.restart_home_charger(charger_id)
|
|
173
173
|
```
|
|
174
174
|
|
|
175
|
+
#### Charging schedule
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
schedule = await client.get_home_charger_schedule(charger_id)
|
|
179
|
+
print(schedule.schedule_enabled) # False
|
|
180
|
+
if schedule.default_schedule:
|
|
181
|
+
print(schedule.default_schedule.weekdays.start_time) # "23:00"
|
|
182
|
+
print(schedule.default_schedule.weekdays.end_time) # "07:00"
|
|
183
|
+
print(schedule.default_schedule.weekends.start_time) # "19:00"
|
|
184
|
+
print(schedule.default_schedule.weekends.end_time) # "15:00"
|
|
185
|
+
|
|
186
|
+
# Enable a schedule
|
|
187
|
+
schedule = await client.set_home_charger_schedule(
|
|
188
|
+
charger_id,
|
|
189
|
+
weekday_start="23:00", weekday_end="07:00",
|
|
190
|
+
weekend_start="19:00", weekend_end="15:00",
|
|
191
|
+
)
|
|
192
|
+
print(schedule.schedule_enabled) # True
|
|
193
|
+
|
|
194
|
+
# Disable the schedule
|
|
195
|
+
await client.disable_home_charger_schedule(charger_id)
|
|
196
|
+
```
|
|
197
|
+
|
|
175
198
|
---
|
|
176
199
|
|
|
177
200
|
### Charging Status and Sessions
|
|
@@ -327,6 +350,9 @@ chargepoint charger config <charger_id>
|
|
|
327
350
|
chargepoint charger set-amperage <charger_id> <amps>
|
|
328
351
|
chargepoint charger set-led <charger_id> <level> # 0=off 1=20% 2=40% 3=60% 4=80% 5=100%
|
|
329
352
|
chargepoint charger restart <charger_id>
|
|
353
|
+
chargepoint charger schedule <charger_id>
|
|
354
|
+
chargepoint charger set-schedule <charger_id> --weekday-start 23:00 --weekday-end 07:00 --weekend-start 19:00 --weekend-end 15:00
|
|
355
|
+
chargepoint charger disable-schedule <charger_id>
|
|
330
356
|
|
|
331
357
|
# Sessions
|
|
332
358
|
chargepoint session get <session_id>
|
|
@@ -151,6 +151,29 @@ await client.set_led_brightness(charger_id, 3) # 60%
|
|
|
151
151
|
await client.restart_home_charger(charger_id)
|
|
152
152
|
```
|
|
153
153
|
|
|
154
|
+
#### Charging schedule
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
schedule = await client.get_home_charger_schedule(charger_id)
|
|
158
|
+
print(schedule.schedule_enabled) # False
|
|
159
|
+
if schedule.default_schedule:
|
|
160
|
+
print(schedule.default_schedule.weekdays.start_time) # "23:00"
|
|
161
|
+
print(schedule.default_schedule.weekdays.end_time) # "07:00"
|
|
162
|
+
print(schedule.default_schedule.weekends.start_time) # "19:00"
|
|
163
|
+
print(schedule.default_schedule.weekends.end_time) # "15:00"
|
|
164
|
+
|
|
165
|
+
# Enable a schedule
|
|
166
|
+
schedule = await client.set_home_charger_schedule(
|
|
167
|
+
charger_id,
|
|
168
|
+
weekday_start="23:00", weekday_end="07:00",
|
|
169
|
+
weekend_start="19:00", weekend_end="15:00",
|
|
170
|
+
)
|
|
171
|
+
print(schedule.schedule_enabled) # True
|
|
172
|
+
|
|
173
|
+
# Disable the schedule
|
|
174
|
+
await client.disable_home_charger_schedule(charger_id)
|
|
175
|
+
```
|
|
176
|
+
|
|
154
177
|
---
|
|
155
178
|
|
|
156
179
|
### Charging Status and Sessions
|
|
@@ -306,6 +329,9 @@ chargepoint charger config <charger_id>
|
|
|
306
329
|
chargepoint charger set-amperage <charger_id> <amps>
|
|
307
330
|
chargepoint charger set-led <charger_id> <level> # 0=off 1=20% 2=40% 3=60% 4=80% 5=100%
|
|
308
331
|
chargepoint charger restart <charger_id>
|
|
332
|
+
chargepoint charger schedule <charger_id>
|
|
333
|
+
chargepoint charger set-schedule <charger_id> --weekday-start 23:00 --weekday-end 07:00 --weekend-start 19:00 --weekend-end 15:00
|
|
334
|
+
chargepoint charger disable-schedule <charger_id>
|
|
309
335
|
|
|
310
336
|
# Sessions
|
|
311
337
|
chargepoint session get <session_id>
|
|
@@ -519,6 +519,115 @@ async def charger_restart(ctx, charger_id: int) -> None:
|
|
|
519
519
|
await client.close()
|
|
520
520
|
|
|
521
521
|
|
|
522
|
+
@charger.command("schedule")
|
|
523
|
+
@click.argument("charger_id", type=int)
|
|
524
|
+
@click.pass_context
|
|
525
|
+
@async_cmd
|
|
526
|
+
async def charger_schedule(ctx, charger_id: int) -> None:
|
|
527
|
+
"""Show the charging schedule for a home charger."""
|
|
528
|
+
client = await _make_client(ctx.obj["debug"])
|
|
529
|
+
try:
|
|
530
|
+
schedule = await client.get_home_charger_schedule(charger_id)
|
|
531
|
+
if ctx.obj["as_json"]:
|
|
532
|
+
_dump_json(schedule)
|
|
533
|
+
else:
|
|
534
|
+
click.echo(f"Enabled: {schedule.schedule_enabled}")
|
|
535
|
+
for label, window in [
|
|
536
|
+
(
|
|
537
|
+
"Weekdays",
|
|
538
|
+
(
|
|
539
|
+
schedule.default_schedule.weekdays
|
|
540
|
+
if schedule.default_schedule
|
|
541
|
+
else None
|
|
542
|
+
),
|
|
543
|
+
),
|
|
544
|
+
(
|
|
545
|
+
"Weekends",
|
|
546
|
+
(
|
|
547
|
+
schedule.default_schedule.weekends
|
|
548
|
+
if schedule.default_schedule
|
|
549
|
+
else None
|
|
550
|
+
),
|
|
551
|
+
),
|
|
552
|
+
]:
|
|
553
|
+
if window:
|
|
554
|
+
click.echo(f"{label}: {window.start_time} – {window.end_time}")
|
|
555
|
+
except CommunicationError as e:
|
|
556
|
+
click.echo(f"Error: {e.message}", err=True)
|
|
557
|
+
sys.exit(1)
|
|
558
|
+
finally:
|
|
559
|
+
await client.close()
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
@charger.command("set-schedule")
|
|
563
|
+
@click.argument("charger_id", type=int)
|
|
564
|
+
@click.option(
|
|
565
|
+
"--weekday-start", required=True, help='Weekday charge start time, e.g. "23:00"'
|
|
566
|
+
)
|
|
567
|
+
@click.option(
|
|
568
|
+
"--weekday-end", required=True, help='Weekday charge end time, e.g. "07:00"'
|
|
569
|
+
)
|
|
570
|
+
@click.option(
|
|
571
|
+
"--weekend-start", required=True, help='Weekend charge start time, e.g. "19:00"'
|
|
572
|
+
)
|
|
573
|
+
@click.option(
|
|
574
|
+
"--weekend-end", required=True, help='Weekend charge end time, e.g. "15:00"'
|
|
575
|
+
)
|
|
576
|
+
@click.pass_context
|
|
577
|
+
@async_cmd
|
|
578
|
+
async def charger_set_schedule(
|
|
579
|
+
ctx,
|
|
580
|
+
charger_id: int,
|
|
581
|
+
weekday_start: str,
|
|
582
|
+
weekday_end: str,
|
|
583
|
+
weekend_start: str,
|
|
584
|
+
weekend_end: str,
|
|
585
|
+
) -> None:
|
|
586
|
+
"""Set the charging schedule for a home charger."""
|
|
587
|
+
client = await _make_client(ctx.obj["debug"])
|
|
588
|
+
try:
|
|
589
|
+
schedule = await client.set_home_charger_schedule(
|
|
590
|
+
charger_id, weekday_start, weekday_end, weekend_start, weekend_end
|
|
591
|
+
)
|
|
592
|
+
if ctx.obj["as_json"]:
|
|
593
|
+
_dump_json(schedule)
|
|
594
|
+
else:
|
|
595
|
+
click.echo(f"Schedule enabled: {schedule.schedule_enabled}")
|
|
596
|
+
if schedule.user_schedule:
|
|
597
|
+
click.echo(
|
|
598
|
+
f"Weekdays: {schedule.user_schedule.weekdays.start_time} – {schedule.user_schedule.weekdays.end_time}"
|
|
599
|
+
)
|
|
600
|
+
click.echo(
|
|
601
|
+
f"Weekends: {schedule.user_schedule.weekends.start_time} – {schedule.user_schedule.weekends.end_time}"
|
|
602
|
+
)
|
|
603
|
+
except CommunicationError as e:
|
|
604
|
+
click.echo(f"Error: {e.message}", err=True)
|
|
605
|
+
sys.exit(1)
|
|
606
|
+
finally:
|
|
607
|
+
await client.close()
|
|
608
|
+
|
|
609
|
+
|
|
610
|
+
@charger.command("disable-schedule")
|
|
611
|
+
@click.argument("charger_id", type=int)
|
|
612
|
+
@click.confirmation_option(prompt="Disable the charging schedule?")
|
|
613
|
+
@click.pass_context
|
|
614
|
+
@async_cmd
|
|
615
|
+
async def charger_disable_schedule(ctx, charger_id: int) -> None:
|
|
616
|
+
"""Disable the charging schedule for a home charger."""
|
|
617
|
+
client = await _make_client(ctx.obj["debug"])
|
|
618
|
+
try:
|
|
619
|
+
schedule = await client.disable_home_charger_schedule(charger_id)
|
|
620
|
+
if ctx.obj["as_json"]:
|
|
621
|
+
_dump_json(schedule)
|
|
622
|
+
else:
|
|
623
|
+
click.echo(f"Schedule enabled: {schedule.schedule_enabled}")
|
|
624
|
+
except CommunicationError as e:
|
|
625
|
+
click.echo(f"Error: {e.message}", err=True)
|
|
626
|
+
sys.exit(1)
|
|
627
|
+
finally:
|
|
628
|
+
await client.close()
|
|
629
|
+
|
|
630
|
+
|
|
522
631
|
# ---------------------------------------------------------------------------
|
|
523
632
|
# session subgroup
|
|
524
633
|
# ---------------------------------------------------------------------------
|
|
@@ -13,6 +13,7 @@ from .types import (
|
|
|
13
13
|
Account,
|
|
14
14
|
ElectricVehicle,
|
|
15
15
|
HomeChargerConfiguration,
|
|
16
|
+
HomeChargerSchedule,
|
|
16
17
|
HomeChargerStatus,
|
|
17
18
|
HomeChargerTechnicalInfo,
|
|
18
19
|
MapFilter,
|
|
@@ -128,6 +129,13 @@ class ChargePoint:
|
|
|
128
129
|
_LOGGER.debug("[%s] %s", method, url)
|
|
129
130
|
headers = {**self._request_headers, **kwargs.pop("headers", {})}
|
|
130
131
|
response = await self._session.request(method, url, headers=headers, **kwargs)
|
|
132
|
+
|
|
133
|
+
# ChargePoint servers return coulomb_sess with Max-Age=7200 on every response.
|
|
134
|
+
# Re-set it without expiry so the cookie jar never evicts it.
|
|
135
|
+
refreshed = response.cookies.get(COULOMB_SESSION)
|
|
136
|
+
if refreshed and refreshed.value:
|
|
137
|
+
self._set_coulomb_token(refreshed.value)
|
|
138
|
+
|
|
131
139
|
_LOGGER.debug("Status: %d", response.status)
|
|
132
140
|
_LOGGER.debug("Request Headers: %s", response.request_info.headers)
|
|
133
141
|
_LOGGER.debug("Response Headers: %s", response.headers)
|
|
@@ -150,6 +158,18 @@ class ChargePoint:
|
|
|
150
158
|
|
|
151
159
|
return response
|
|
152
160
|
|
|
161
|
+
async def _raise_for_status(
|
|
162
|
+
self, response: aiohttp.ClientResponse, message: str
|
|
163
|
+
) -> None:
|
|
164
|
+
if response.status != 200:
|
|
165
|
+
text = await response.text()
|
|
166
|
+
_LOGGER.error(
|
|
167
|
+
"status_code=%s err=%s",
|
|
168
|
+
response.status,
|
|
169
|
+
text,
|
|
170
|
+
)
|
|
171
|
+
raise CommunicationError(response=response, message=message)
|
|
172
|
+
|
|
153
173
|
async def _init_account_parameters(self):
|
|
154
174
|
account: Account = await self.get_account()
|
|
155
175
|
self._user_id = account.user.user_id
|
|
@@ -231,13 +251,7 @@ class ChargePoint:
|
|
|
231
251
|
self._global_config.endpoints.sso_endpoint / "v1/user/logout",
|
|
232
252
|
)
|
|
233
253
|
|
|
234
|
-
|
|
235
|
-
text = await response.text()
|
|
236
|
-
_LOGGER.error(
|
|
237
|
-
"Failed to log out! status_code=%s err=%s", response.status, text
|
|
238
|
-
)
|
|
239
|
-
raise CommunicationError(response=response, message="Failed to log out!")
|
|
240
|
-
|
|
254
|
+
await self._raise_for_status(response, "Failed to log out!")
|
|
241
255
|
await response.release()
|
|
242
256
|
self._session.cookie_jar.clear()
|
|
243
257
|
self._user_id = None
|
|
@@ -246,17 +260,9 @@ class ChargePoint:
|
|
|
246
260
|
_LOGGER.debug("Discovering account region for username %s", username)
|
|
247
261
|
request = {"username": username}
|
|
248
262
|
response = await self._request("POST", DISCOVERY_API, json=request)
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
"Failed to discover region! status_code=%s err=%s",
|
|
253
|
-
response.status,
|
|
254
|
-
text,
|
|
255
|
-
)
|
|
256
|
-
raise CommunicationError(
|
|
257
|
-
response=response,
|
|
258
|
-
message="Failed to discover region for provided username!",
|
|
259
|
-
)
|
|
263
|
+
await self._raise_for_status(
|
|
264
|
+
response, "Failed to discover region for provided username!"
|
|
265
|
+
)
|
|
260
266
|
config = GlobalConfiguration.model_validate(await response.json())
|
|
261
267
|
_LOGGER.debug(
|
|
262
268
|
"Discovered account region: %s / %s (%s)",
|
|
@@ -274,17 +280,7 @@ class ChargePoint:
|
|
|
274
280
|
self._global_config.endpoints.accounts_endpoint / "v1/driver/profile/user",
|
|
275
281
|
)
|
|
276
282
|
|
|
277
|
-
|
|
278
|
-
text = await response.text()
|
|
279
|
-
_LOGGER.error(
|
|
280
|
-
"Failed to get account information! status_code=%s err=%s",
|
|
281
|
-
response.status,
|
|
282
|
-
text,
|
|
283
|
-
)
|
|
284
|
-
raise CommunicationError(
|
|
285
|
-
response=response, message="Failed to get user information."
|
|
286
|
-
)
|
|
287
|
-
|
|
283
|
+
await self._raise_for_status(response, "Failed to get user information.")
|
|
288
284
|
return Account.model_validate(await response.json())
|
|
289
285
|
|
|
290
286
|
@_require_login
|
|
@@ -295,17 +291,7 @@ class ChargePoint:
|
|
|
295
291
|
self._global_config.endpoints.accounts_endpoint / "v1/driver/vehicle",
|
|
296
292
|
)
|
|
297
293
|
|
|
298
|
-
|
|
299
|
-
text = await response.text()
|
|
300
|
-
_LOGGER.error(
|
|
301
|
-
"Failed to list vehicles! status_code=%s err=%s",
|
|
302
|
-
response.status,
|
|
303
|
-
text,
|
|
304
|
-
)
|
|
305
|
-
raise CommunicationError(
|
|
306
|
-
response=response, message="Failed to retrieve EVs."
|
|
307
|
-
)
|
|
308
|
-
|
|
294
|
+
await self._raise_for_status(response, "Failed to retrieve EVs.")
|
|
309
295
|
evs = await response.json()
|
|
310
296
|
return [ElectricVehicle.model_validate(ev) for ev in evs]
|
|
311
297
|
|
|
@@ -318,17 +304,7 @@ class ChargePoint:
|
|
|
318
304
|
/ f"api/v1/configuration/users/{self.user_id}/chargers",
|
|
319
305
|
)
|
|
320
306
|
|
|
321
|
-
|
|
322
|
-
text = await response.text()
|
|
323
|
-
_LOGGER.error(
|
|
324
|
-
"Failed to get home chargers! status_code=%s err=%s",
|
|
325
|
-
response.status,
|
|
326
|
-
text,
|
|
327
|
-
)
|
|
328
|
-
raise CommunicationError(
|
|
329
|
-
response=response, message="Failed to retrieve Home Flex chargers."
|
|
330
|
-
)
|
|
331
|
-
|
|
307
|
+
await self._raise_for_status(response, "Failed to retrieve Home Flex chargers.")
|
|
332
308
|
data = (await response.json())["data"]
|
|
333
309
|
chargers = [int(item["id"]) for item in data]
|
|
334
310
|
_LOGGER.debug(
|
|
@@ -347,17 +323,7 @@ class ChargePoint:
|
|
|
347
323
|
/ f"api/v1/configuration/users/{self.user_id}/chargers/{charger_id}/status",
|
|
348
324
|
)
|
|
349
325
|
|
|
350
|
-
|
|
351
|
-
text = await response.text()
|
|
352
|
-
_LOGGER.error(
|
|
353
|
-
"Failed to determine home charger status! status_code=%s err=%s",
|
|
354
|
-
response.status,
|
|
355
|
-
text,
|
|
356
|
-
)
|
|
357
|
-
raise CommunicationError(
|
|
358
|
-
response=response, message="Failed to get home charger status."
|
|
359
|
-
)
|
|
360
|
-
|
|
326
|
+
await self._raise_for_status(response, "Failed to get home charger status.")
|
|
361
327
|
status = await response.json()
|
|
362
328
|
_LOGGER.debug(status)
|
|
363
329
|
return HomeChargerStatus.model_validate({"charger_id": charger_id, **status})
|
|
@@ -373,17 +339,7 @@ class ChargePoint:
|
|
|
373
339
|
/ f"api/v1/configuration/users/{self.user_id}/chargers/{charger_id}/technical-info",
|
|
374
340
|
)
|
|
375
341
|
|
|
376
|
-
|
|
377
|
-
text = await response.text()
|
|
378
|
-
_LOGGER.error(
|
|
379
|
-
"Failed to get home charger tech info! status_code=%s err=%s",
|
|
380
|
-
response.status,
|
|
381
|
-
text,
|
|
382
|
-
)
|
|
383
|
-
raise CommunicationError(
|
|
384
|
-
response=response, message="Failed to get home charger tech info."
|
|
385
|
-
)
|
|
386
|
-
|
|
342
|
+
await self._raise_for_status(response, "Failed to get home charger tech info.")
|
|
387
343
|
return HomeChargerTechnicalInfo.model_validate(await response.json())
|
|
388
344
|
|
|
389
345
|
@_require_login
|
|
@@ -394,17 +350,7 @@ class ChargePoint:
|
|
|
394
350
|
"POST", self._global_config.endpoints.mapcache_endpoint / "v2", json=request
|
|
395
351
|
)
|
|
396
352
|
|
|
397
|
-
|
|
398
|
-
text = await response.text()
|
|
399
|
-
_LOGGER.error(
|
|
400
|
-
"Failed to get account charging status! status_code=%s err=%s",
|
|
401
|
-
response.status,
|
|
402
|
-
text,
|
|
403
|
-
)
|
|
404
|
-
raise CommunicationError(
|
|
405
|
-
response=response, message="Failed to get user charging status."
|
|
406
|
-
)
|
|
407
|
-
|
|
353
|
+
await self._raise_for_status(response, "Failed to get user charging status.")
|
|
408
354
|
status = await response.json()
|
|
409
355
|
if not status["user_status"]:
|
|
410
356
|
_LOGGER.debug("No user status returned, assuming not charging.")
|
|
@@ -423,17 +369,7 @@ class ChargePoint:
|
|
|
423
369
|
json={"chargeAmperageLimit": amperage_limit},
|
|
424
370
|
)
|
|
425
371
|
|
|
426
|
-
|
|
427
|
-
text = await response.text()
|
|
428
|
-
_LOGGER.error(
|
|
429
|
-
"Failed to set amperage limit! status_code=%s err=%s",
|
|
430
|
-
response.status,
|
|
431
|
-
text,
|
|
432
|
-
)
|
|
433
|
-
raise CommunicationError(
|
|
434
|
-
response=response, message="Failed to set amperage limit."
|
|
435
|
-
)
|
|
436
|
-
|
|
372
|
+
await self._raise_for_status(response, "Failed to set amperage limit.")
|
|
437
373
|
await response.release()
|
|
438
374
|
|
|
439
375
|
@_require_login
|
|
@@ -452,17 +388,7 @@ class ChargePoint:
|
|
|
452
388
|
json={"ledBrightnessLevel": level},
|
|
453
389
|
)
|
|
454
390
|
|
|
455
|
-
|
|
456
|
-
text = await response.text()
|
|
457
|
-
_LOGGER.error(
|
|
458
|
-
"Failed to set LED brightness! status_code=%s err=%s",
|
|
459
|
-
response.status,
|
|
460
|
-
text,
|
|
461
|
-
)
|
|
462
|
-
raise CommunicationError(
|
|
463
|
-
response=response, message="Failed to set LED brightness."
|
|
464
|
-
)
|
|
465
|
-
|
|
391
|
+
await self._raise_for_status(response, "Failed to set LED brightness.")
|
|
466
392
|
await response.release()
|
|
467
393
|
|
|
468
394
|
@_require_login
|
|
@@ -474,17 +400,7 @@ class ChargePoint:
|
|
|
474
400
|
/ f"api/v1/configuration/users/{self.user_id}/chargers/{charger_id}/restart",
|
|
475
401
|
)
|
|
476
402
|
|
|
477
|
-
|
|
478
|
-
text = await response.text()
|
|
479
|
-
_LOGGER.error(
|
|
480
|
-
"Failed to restart charger! status_code=%s err=%s",
|
|
481
|
-
response.status,
|
|
482
|
-
text,
|
|
483
|
-
)
|
|
484
|
-
raise CommunicationError(
|
|
485
|
-
response=response, message="Failed to restart charger."
|
|
486
|
-
)
|
|
487
|
-
|
|
403
|
+
await self._raise_for_status(response, "Failed to restart charger.")
|
|
488
404
|
await response.release()
|
|
489
405
|
|
|
490
406
|
@_require_login
|
|
@@ -498,19 +414,61 @@ class ChargePoint:
|
|
|
498
414
|
/ f"api/v1/configuration/users/{self.user_id}/chargers/{charger_id}/configurations",
|
|
499
415
|
)
|
|
500
416
|
|
|
501
|
-
|
|
502
|
-
text = await response.text()
|
|
503
|
-
_LOGGER.error(
|
|
504
|
-
"Failed to get charger configuration! status_code=%s err=%s",
|
|
505
|
-
response.status,
|
|
506
|
-
text,
|
|
507
|
-
)
|
|
508
|
-
raise CommunicationError(
|
|
509
|
-
response=response, message="Failed to get charger configuration."
|
|
510
|
-
)
|
|
511
|
-
|
|
417
|
+
await self._raise_for_status(response, "Failed to get charger configuration.")
|
|
512
418
|
return HomeChargerConfiguration.model_validate(await response.json())
|
|
513
419
|
|
|
420
|
+
@_require_login
|
|
421
|
+
async def get_home_charger_schedule(self, charger_id: int) -> HomeChargerSchedule:
|
|
422
|
+
_LOGGER.debug("Getting schedule for charger: %s", charger_id)
|
|
423
|
+
response = await self._request(
|
|
424
|
+
"GET",
|
|
425
|
+
self._global_config.endpoints.hcpo_hcm_endpoint
|
|
426
|
+
/ f"api/v1/schedule/charger/{charger_id}/schedule",
|
|
427
|
+
)
|
|
428
|
+
|
|
429
|
+
await self._raise_for_status(response, "Failed to get charger schedule.")
|
|
430
|
+
return HomeChargerSchedule.model_validate(await response.json())
|
|
431
|
+
|
|
432
|
+
@_require_login
|
|
433
|
+
async def set_home_charger_schedule(
|
|
434
|
+
self,
|
|
435
|
+
charger_id: int,
|
|
436
|
+
weekday_start: str,
|
|
437
|
+
weekday_end: str,
|
|
438
|
+
weekend_start: str,
|
|
439
|
+
weekend_end: str,
|
|
440
|
+
) -> HomeChargerSchedule:
|
|
441
|
+
_LOGGER.debug("Setting schedule for charger: %s", charger_id)
|
|
442
|
+
response = await self._request(
|
|
443
|
+
"PUT",
|
|
444
|
+
self._global_config.endpoints.hcpo_hcm_endpoint
|
|
445
|
+
/ f"api/v1/schedule/charger/{charger_id}/schedule",
|
|
446
|
+
json={
|
|
447
|
+
"schedule": {
|
|
448
|
+
"weekdays": {"startTime": weekday_start, "endTime": weekday_end},
|
|
449
|
+
"weekends": {"startTime": weekend_start, "endTime": weekend_end},
|
|
450
|
+
}
|
|
451
|
+
},
|
|
452
|
+
)
|
|
453
|
+
|
|
454
|
+
await self._raise_for_status(response, "Failed to set charger schedule.")
|
|
455
|
+
return HomeChargerSchedule.model_validate(await response.json())
|
|
456
|
+
|
|
457
|
+
@_require_login
|
|
458
|
+
async def disable_home_charger_schedule(
|
|
459
|
+
self, charger_id: int
|
|
460
|
+
) -> HomeChargerSchedule:
|
|
461
|
+
_LOGGER.debug("Disabling schedule for charger: %s", charger_id)
|
|
462
|
+
response = await self._request(
|
|
463
|
+
"PUT",
|
|
464
|
+
self._global_config.endpoints.hcpo_hcm_endpoint
|
|
465
|
+
/ f"api/v1/schedule/charger/{charger_id}/schedule",
|
|
466
|
+
json={},
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
await self._raise_for_status(response, "Failed to disable charger schedule.")
|
|
470
|
+
return HomeChargerSchedule.model_validate(await response.json())
|
|
471
|
+
|
|
514
472
|
@_require_login
|
|
515
473
|
async def get_charging_session(self, session_id: int) -> ChargingSession:
|
|
516
474
|
session = ChargingSession(session_id=session_id)
|
|
@@ -530,17 +488,7 @@ class ChargePoint:
|
|
|
530
488
|
).update_query({"deviceId": str(device_id), "use_cache": "false"})
|
|
531
489
|
response = await self._request("GET", url)
|
|
532
490
|
|
|
533
|
-
|
|
534
|
-
text = await response.text()
|
|
535
|
-
_LOGGER.error(
|
|
536
|
-
"Failed to get station info! status_code=%s err=%s",
|
|
537
|
-
response.status,
|
|
538
|
-
text,
|
|
539
|
-
)
|
|
540
|
-
raise CommunicationError(
|
|
541
|
-
response=response, message="Failed to get station info."
|
|
542
|
-
)
|
|
543
|
-
|
|
491
|
+
await self._raise_for_status(response, "Failed to get station info.")
|
|
544
492
|
data = await response.json()
|
|
545
493
|
return StationInfo.model_validate(data)
|
|
546
494
|
|
|
@@ -576,17 +524,7 @@ class ChargePoint:
|
|
|
576
524
|
"POST", self._global_config.endpoints.mapcache_endpoint / "v2", json=request
|
|
577
525
|
)
|
|
578
526
|
|
|
579
|
-
|
|
580
|
-
text = await response.text()
|
|
581
|
-
_LOGGER.error(
|
|
582
|
-
"Failed to get nearby stations! status_code=%s err=%s",
|
|
583
|
-
response.status,
|
|
584
|
-
text,
|
|
585
|
-
)
|
|
586
|
-
raise CommunicationError(
|
|
587
|
-
response=response, message="Failed to get nearby stations."
|
|
588
|
-
)
|
|
589
|
-
|
|
527
|
+
await self._raise_for_status(response, "Failed to get nearby stations.")
|
|
590
528
|
data = await response.json()
|
|
591
529
|
stations = data["map_data"].get("stations", [])
|
|
592
530
|
return [MapStation.model_validate(s) for s in stations]
|
|
@@ -166,6 +166,28 @@ class HomeChargerConfiguration(_CamelModel):
|
|
|
166
166
|
return {**settings, "led_brightness": led_brightness}
|
|
167
167
|
|
|
168
168
|
|
|
169
|
+
class ChargeScheduleWindow(_CamelModel):
|
|
170
|
+
start_time: str = ""
|
|
171
|
+
end_time: str = ""
|
|
172
|
+
start_weekday: Optional[int] = None
|
|
173
|
+
end_weekday: Optional[int] = None
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class ChargeSchedule(_CamelModel):
|
|
177
|
+
weekdays: ChargeScheduleWindow = Field(default_factory=ChargeScheduleWindow)
|
|
178
|
+
weekends: ChargeScheduleWindow = Field(default_factory=ChargeScheduleWindow)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class HomeChargerSchedule(_CamelModel):
|
|
182
|
+
has_tou_pricing: bool = False
|
|
183
|
+
schedule_enabled: bool = False
|
|
184
|
+
has_utility_info: bool = False
|
|
185
|
+
based_on_utility: Optional["PowerUtility"] = None
|
|
186
|
+
default_schedule: Optional[ChargeSchedule] = None
|
|
187
|
+
user_schedule: Optional[ChargeSchedule] = None
|
|
188
|
+
utility_schedule: Optional[ChargeSchedule] = None
|
|
189
|
+
|
|
190
|
+
|
|
169
191
|
class Station(_BaseModel):
|
|
170
192
|
id: int = Field(0, alias="deviceId")
|
|
171
193
|
name: str = ""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|