pycupra 0.0.13__py3-none-any.whl → 0.0.14__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.
- pycupra/__version__.py +1 -1
- pycupra/connection.py +4 -1
- pycupra/dashboard.py +9 -6
- pycupra/vehicle.py +75 -34
- {pycupra-0.0.13.dist-info → pycupra-0.0.14.dist-info}/METADATA +1 -1
- pycupra-0.0.14.dist-info/RECORD +13 -0
- pycupra-0.0.13.dist-info/RECORD +0 -13
- {pycupra-0.0.13.dist-info → pycupra-0.0.14.dist-info}/WHEEL +0 -0
- {pycupra-0.0.13.dist-info → pycupra-0.0.14.dist-info}/licenses/LICENSE +0 -0
- {pycupra-0.0.13.dist-info → pycupra-0.0.14.dist-info}/top_level.txt +0 -0
pycupra/__version__.py
CHANGED
pycupra/connection.py
CHANGED
@@ -108,11 +108,12 @@ TIMEOUT = timedelta(seconds=90)
|
|
108
108
|
class Connection:
|
109
109
|
""" Connection to Connect services """
|
110
110
|
# Init connection class
|
111
|
-
def __init__(self, session, brand='cupra', username='', password='', fulldebug=False, **optional):
|
111
|
+
def __init__(self, session, brand='cupra', username='', password='', fulldebug=False, nightlyUpdateReduction=False, **optional):
|
112
112
|
""" Initialize """
|
113
113
|
self._session = session
|
114
114
|
self._lock = asyncio.Lock()
|
115
115
|
self._session_fulldebug = fulldebug
|
116
|
+
self._session_nightlyUpdateReduction = nightlyUpdateReduction
|
116
117
|
self._session_headers = HEADERS_SESSION.get(brand).copy()
|
117
118
|
self._session_base = BASE_SESSION
|
118
119
|
self._session_auth_headers = HEADERS_AUTH.copy()
|
@@ -1369,6 +1370,8 @@ class Connection:
|
|
1369
1370
|
if mode in {'start', 'stop'}:
|
1370
1371
|
capability='charging'
|
1371
1372
|
return await self._setViaAPI(eval(f"f'{API_REQUESTS}/{mode}'"))
|
1373
|
+
elif mode=='settings':
|
1374
|
+
return await self._setViaAPI(eval(f"f'{API_CHARGING}/{mode}'"), json=data)
|
1372
1375
|
else:
|
1373
1376
|
_LOGGER.error(f'Not yet implemented. Mode: {mode}. Command ignored')
|
1374
1377
|
raise
|
pycupra/dashboard.py
CHANGED
@@ -948,11 +948,14 @@ class ChargingState(BinarySensor):
|
|
948
948
|
@property
|
949
949
|
def attributes(self):
|
950
950
|
attr = {}
|
951
|
-
state = self.vehicle.attrs.get('charging', {}).get('status', {}).get('state', '')
|
951
|
+
#state = self.vehicle.attrs.get('charging', {}).get('status', {}).get('state', '')
|
952
|
+
#type = self.vehicle.attrs.get('charging', {}).get('status', {}).get('charging', {}).get('type', '')
|
953
|
+
#mode = self.vehicle.attrs.get('charging', {}).get('status', {}).get('charging', {}).get('mode', '')
|
954
|
+
state = self.vehicle.attrs.get('mycar', {}).get('services', {}).get('charging', {}).get('status', '')
|
952
955
|
type = self.vehicle.attrs.get('charging', {}).get('status', {}).get('charging', {}).get('type', '')
|
953
|
-
mode = self.vehicle.attrs.get('
|
954
|
-
if state in {'charging', 'conservation'}:
|
955
|
-
attr['state']=state
|
956
|
+
mode = self.vehicle.attrs.get('mycar', {}).get('services', {}).get('charging', {}).get('chargeMode', '')
|
957
|
+
if state in {'charging','Charging', 'conservation','Conservation'}:
|
958
|
+
attr['state']=state.lower()
|
956
959
|
if type != '':
|
957
960
|
attr['type']=type
|
958
961
|
if mode != '':
|
@@ -1110,8 +1113,8 @@ def create_instruments():
|
|
1110
1113
|
attr="charge_max_ampere",
|
1111
1114
|
name="Charger max ampere",
|
1112
1115
|
icon="mdi:flash",
|
1113
|
-
unit="A",
|
1114
|
-
device_class="current"
|
1116
|
+
#unit="A",
|
1117
|
+
#device_class="current"
|
1115
1118
|
),
|
1116
1119
|
Sensor(
|
1117
1120
|
attr="climatisation_target_temperature",
|
pycupra/vehicle.py
CHANGED
@@ -129,9 +129,20 @@ class Vehicle:
|
|
129
129
|
# Fetch all data if car is not deactivated
|
130
130
|
if not self.deactivated:
|
131
131
|
try:
|
132
|
+
if self._connection._session_nightlyUpdateReduction:
|
133
|
+
# nightlyUpdateReduction is activated
|
134
|
+
if datetime.now(tz=None).hour<5 or datetime.now(tz=None).hour>=22:
|
135
|
+
# current time is within the night interval
|
136
|
+
fullUpdateExpired = datetime.now(tz=None) - timedelta(seconds= 1100)
|
137
|
+
if hasattr(self, '_last_full_update'):
|
138
|
+
_LOGGER.debug(f'last_full_update= {self._last_full_update}, fullUpdateExpired= {fullUpdateExpired}.')
|
139
|
+
if updateType!=1 and (hasattr(self, '_last_full_update') and self._last_full_update>fullUpdateExpired):
|
140
|
+
_LOGGER.debug('Nightly update reduction is active and current time within 22:00 and 5:00. So we skip small update.')
|
141
|
+
return True
|
142
|
+
|
132
143
|
# Data to be updated most often
|
133
144
|
await asyncio.gather(
|
134
|
-
self.get_charger(),
|
145
|
+
#self.get_charger(),
|
135
146
|
self.get_basiccardata(),
|
136
147
|
self.get_statusreport(),
|
137
148
|
return_exceptions=True
|
@@ -146,6 +157,8 @@ class Vehicle:
|
|
146
157
|
|
147
158
|
# Data to be updated less often
|
148
159
|
await asyncio.gather(
|
160
|
+
#self.get_statusreport(),
|
161
|
+
self.get_charger(),
|
149
162
|
self.get_preheater(),
|
150
163
|
self.get_climater(),
|
151
164
|
self.get_trip_statistic(),
|
@@ -320,7 +333,11 @@ class Vehicle:
|
|
320
333
|
if 1 <= int(value) <= 255:
|
321
334
|
# VW-Group API charger current request
|
322
335
|
if self._relevantCapabilties.get('charging', {}).get('active', False):
|
323
|
-
data = {'
|
336
|
+
data = {'maxChargeCurrentAc': int(value)}
|
337
|
+
if int(value)==252:
|
338
|
+
data = {'maxChargeCurrentAc': 'reduced'}
|
339
|
+
if int(value)==254:
|
340
|
+
data = {'maxChargeCurrentAc': 'maximum'}
|
324
341
|
else:
|
325
342
|
_LOGGER.error(f'Set charger maximum current to {value} is not supported.')
|
326
343
|
raise SeatInvalidRequestException(f'Set charger maximum current to {value} is not supported.')
|
@@ -330,9 +347,7 @@ class Vehicle:
|
|
330
347
|
# VW-Group API charger current request
|
331
348
|
if self._relevantCapabilties.get('charging', {}).get('active', False):
|
332
349
|
value = 'maximum' if value in ['Maximum', 'maximum', 'Max', 'max'] else 'reduced'
|
333
|
-
data = {'
|
334
|
-
{'maxChargeCurrentAC': value}
|
335
|
-
}
|
350
|
+
data = {'maxChargeCurrentAc': value}
|
336
351
|
else:
|
337
352
|
_LOGGER.error(f'Set charger maximum current to {value} is not supported.')
|
338
353
|
raise SeatInvalidRequestException(f'Set charger maximum current to {value} is not supported.')
|
@@ -344,7 +359,7 @@ class Vehicle:
|
|
344
359
|
_LOGGER.error('No charger support.')
|
345
360
|
raise SeatInvalidRequestException('No charger support.')
|
346
361
|
|
347
|
-
async def set_charger(self, action,
|
362
|
+
async def set_charger(self, action, data=None):
|
348
363
|
"""Charging actions."""
|
349
364
|
if not self._relevantCapabilties.get('charging', {}).get('active', False):
|
350
365
|
_LOGGER.info('Remote start/stop of charger is not supported.')
|
@@ -361,7 +376,7 @@ class Vehicle:
|
|
361
376
|
mode='start'
|
362
377
|
elif action in ['stop', 'Stop', 'Off', 'off']:
|
363
378
|
mode='stop'
|
364
|
-
elif
|
379
|
+
elif action=='settings':
|
365
380
|
mode=action
|
366
381
|
else:
|
367
382
|
_LOGGER.error(f'Invalid charger action: {action}. Must be either start, stop or setSettings')
|
@@ -386,6 +401,7 @@ class Vehicle:
|
|
386
401
|
while not actionSuccessful and retry < 2:
|
387
402
|
await asyncio.sleep(15)
|
388
403
|
await self.get_charger()
|
404
|
+
await self.get_basiccardata() # We get both, get_charger() and get_basiccardata()
|
389
405
|
if mode == 'start':
|
390
406
|
if self.charging:
|
391
407
|
actionSuccessful = True
|
@@ -393,7 +409,7 @@ class Vehicle:
|
|
393
409
|
if not self.charging:
|
394
410
|
actionSuccessful = True
|
395
411
|
elif mode == 'settings':
|
396
|
-
if data.get('
|
412
|
+
if data.get('maxChargeCurrentAc','') == self.charge_max_ampere:
|
397
413
|
actionSuccessful = True
|
398
414
|
else:
|
399
415
|
_LOGGER.error(f'Missing code in vehicle._set_charger() for mode {mode}')
|
@@ -1473,16 +1489,22 @@ class Vehicle:
|
|
1473
1489
|
@property
|
1474
1490
|
def charging(self):
|
1475
1491
|
"""Return battery level"""
|
1476
|
-
cstate = self.attrs.get('charging').get('status').get('charging').get('state','')
|
1492
|
+
#cstate = self.attrs.get('charging').get('status').get('charging').get('state','')
|
1493
|
+
cstate = self.attrs.get('mycar',{}).get('services',{}).get('charging',{}).get('status','')
|
1477
1494
|
return 1 if cstate in ['charging', 'Charging'] else 0
|
1478
1495
|
|
1479
1496
|
@property
|
1480
1497
|
def is_charging_supported(self):
|
1481
1498
|
"""Return true if charging is supported"""
|
1482
|
-
if self.attrs.get('charging', False):
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1499
|
+
#if self.attrs.get('charging', False):
|
1500
|
+
# if 'status' in self.attrs.get('charging', {}):
|
1501
|
+
# if 'charging' in self.attrs.get('charging')['status']:
|
1502
|
+
# if 'state' in self.attrs.get('charging')['status']['charging']:
|
1503
|
+
# return True
|
1504
|
+
if self.attrs.get('mycar', False):
|
1505
|
+
if 'services' in self.attrs.get('mycar', {}):
|
1506
|
+
if 'charging' in self.attrs.get('mycar')['services']:
|
1507
|
+
if 'status' in self.attrs.get('mycar')['services']['charging']:
|
1486
1508
|
return True
|
1487
1509
|
return False
|
1488
1510
|
|
@@ -1504,26 +1526,33 @@ class Vehicle:
|
|
1504
1526
|
@property
|
1505
1527
|
def battery_level(self):
|
1506
1528
|
"""Return battery level"""
|
1507
|
-
if self.attrs.get('charging', False):
|
1508
|
-
|
1529
|
+
#if self.attrs.get('charging', False):
|
1530
|
+
# return int(self.attrs.get('charging').get('status', {}).get('battery', {}).get('currentSocPercentage', 0))
|
1531
|
+
if self.attrs.get('mycar', False):
|
1532
|
+
return int(self.attrs.get('mycar',{}).get('services', {}).get('charging', {}).get('currentPct', 0))
|
1509
1533
|
else:
|
1510
1534
|
return 0
|
1511
1535
|
|
1512
1536
|
@property
|
1513
1537
|
def is_battery_level_supported(self):
|
1514
1538
|
"""Return true if battery level is supported"""
|
1515
|
-
if self.attrs.get('charging', False):
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1539
|
+
#if self.attrs.get('charging', False):
|
1540
|
+
# if 'status' in self.attrs.get('charging'):
|
1541
|
+
# if 'battery' in self.attrs.get('charging')['status']:
|
1542
|
+
# if 'currentSocPercentage' in self.attrs.get('charging')['status']['battery']:
|
1543
|
+
# return True
|
1544
|
+
if self.attrs.get('mycar', False):
|
1545
|
+
if 'services' in self.attrs.get('mycar'):
|
1546
|
+
if 'charging' in self.attrs.get('mycar')['services']:
|
1547
|
+
if 'currentPct' in self.attrs.get('mycar')['services']['charging']:
|
1519
1548
|
return True
|
1520
1549
|
return False
|
1521
1550
|
|
1522
1551
|
@property
|
1523
1552
|
def charge_max_ampere(self):
|
1524
1553
|
"""Return charger max ampere setting."""
|
1525
|
-
if self.attrs.get('
|
1526
|
-
return self.attrs.get('
|
1554
|
+
if self.attrs.get('charging', False):
|
1555
|
+
return self.attrs.get('charging').get('info').get('settings').get('maxChargeCurrentAc')
|
1527
1556
|
return 0
|
1528
1557
|
|
1529
1558
|
@property
|
@@ -1532,7 +1561,7 @@ class Vehicle:
|
|
1532
1561
|
if self.attrs.get('charging', False):
|
1533
1562
|
if 'info' in self.attrs.get('charging', {}):
|
1534
1563
|
if 'settings' in self.attrs.get('charging')['info']:
|
1535
|
-
if '
|
1564
|
+
if 'maxChargeCurrentAc' in self.attrs.get('charging', {})['info']['settings']:
|
1536
1565
|
return True
|
1537
1566
|
return False
|
1538
1567
|
|
@@ -1575,9 +1604,12 @@ class Vehicle:
|
|
1575
1604
|
@property
|
1576
1605
|
def charging_time_left(self):
|
1577
1606
|
"""Return minutes to charging complete"""
|
1578
|
-
if self.external_power:
|
1579
|
-
|
1580
|
-
|
1607
|
+
#if self.external_power:
|
1608
|
+
if self.charging:
|
1609
|
+
#if self.attrs.get('charging', {}).get('status', {}).get('charging', {}).get('remainingTimeInMinutes', False):
|
1610
|
+
# minutes = int(self.attrs.get('charging', {}).get('status', {}).get('charging', {}).get('remainingTimeInMinutes', 0))
|
1611
|
+
if self.attrs.get('mycar', {}).get('services', {}).get('charging', {}).get('remainingTime', False):
|
1612
|
+
minutes = int(self.attrs.get('mycar', {}).get('services', {}).get('charging', {}).get('remainingTime', 0))
|
1581
1613
|
else:
|
1582
1614
|
minutes = 0
|
1583
1615
|
return minutes
|
@@ -1646,8 +1678,9 @@ class Vehicle:
|
|
1646
1678
|
@property
|
1647
1679
|
def charging_state(self):
|
1648
1680
|
"""Return true if vehicle is charging."""
|
1649
|
-
check = self.attrs.get('charging', {}).get('status', {}).get('state', '')
|
1650
|
-
|
1681
|
+
#check = self.attrs.get('charging', {}).get('status', {}).get('state', '')
|
1682
|
+
check = self.attrs.get('mycar',{}).get('services',{}).get('charging',{}).get('status','')
|
1683
|
+
if check in ('charging','Charging'):
|
1651
1684
|
return True
|
1652
1685
|
else:
|
1653
1686
|
return False
|
@@ -1655,17 +1688,23 @@ class Vehicle:
|
|
1655
1688
|
@property
|
1656
1689
|
def is_charging_state_supported(self):
|
1657
1690
|
"""Charging state supported."""
|
1658
|
-
if self.attrs.get('charging', {}).get('status', {}).get('state', False):
|
1659
|
-
|
1691
|
+
#if self.attrs.get('charging', {}).get('status', {}).get('state', False):
|
1692
|
+
# return True
|
1693
|
+
if self.attrs.get('mycar', False):
|
1694
|
+
if 'services' in self.attrs.get('mycar', {}):
|
1695
|
+
if 'charging' in self.attrs.get('mycar')['services']:
|
1696
|
+
if 'status' in self.attrs.get('mycar')['services']['charging']:
|
1697
|
+
return True
|
1660
1698
|
|
1661
1699
|
@property
|
1662
1700
|
def energy_flow(self):
|
1663
1701
|
"""Return true if energy is flowing to (i.e. charging) or from (i.e. climating with battery power) the battery."""
|
1664
1702
|
if self.charging_state:
|
1665
1703
|
return True
|
1666
|
-
check = self.attrs.get('charging', {}).get('status', {}).get('state', '')
|
1704
|
+
#check = self.attrs.get('charging', {}).get('status', {}).get('state', '')
|
1705
|
+
check = self.attrs.get('mycar',{}).get('services',{}).get('charging',{}).get('status','')
|
1667
1706
|
if self.is_electric_climatisation_supported:
|
1668
|
-
if self.electric_climatisation and check not in {'charging', 'conservation'}:
|
1707
|
+
if self.electric_climatisation and check not in {'charging','Charging', 'conservation','Conservation'}:
|
1669
1708
|
# electric climatisation is on and car is not charging or conserving power
|
1670
1709
|
return True
|
1671
1710
|
return False
|
@@ -2921,7 +2960,8 @@ class Vehicle:
|
|
2921
2960
|
@property
|
2922
2961
|
def is_request_results_supported(self):
|
2923
2962
|
"""Request results is supported if in progress is supported."""
|
2924
|
-
return
|
2963
|
+
return False # deactivated because it provides no usefull information
|
2964
|
+
#return self.is_request_in_progress_supported
|
2925
2965
|
|
2926
2966
|
@property
|
2927
2967
|
def requests_remaining(self):
|
@@ -2937,8 +2977,9 @@ class Vehicle:
|
|
2937
2977
|
|
2938
2978
|
@property
|
2939
2979
|
def is_requests_remaining_supported(self):
|
2940
|
-
|
2941
|
-
|
2980
|
+
return False # deactivated because it provides no usefull information
|
2981
|
+
#if self.is_request_in_progress_supported:
|
2982
|
+
# return True if self._requests.get('remaining', False) else False
|
2942
2983
|
|
2943
2984
|
#### Helper functions ####
|
2944
2985
|
def __str__(self):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: pycupra
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.14
|
4
4
|
Summary: A library to read and send vehicle data via Cupra/Seat portal using the same API calls as the MyCupra/MySeat mobile app.
|
5
5
|
Home-page: https://github.com/WulfgarW/pycupra
|
6
6
|
Author: WulfgarW
|
@@ -0,0 +1,13 @@
|
|
1
|
+
pycupra/__init__.py,sha256=VPzUfKd5mBFD1UERNV61FbGHih5dQPupLgIfYtmIUi4,230
|
2
|
+
pycupra/__version__.py,sha256=qY5o8F0qE8xC3RpWzlzulBbikrc7tq6TO-V5LlAJV5s,208
|
3
|
+
pycupra/connection.py,sha256=0SA-2UcL_uJhKMfluzyw_N4ZCqmsNEg3jU18XacMm5w,82641
|
4
|
+
pycupra/const.py,sha256=mgl29DcZz_J5hSzxknteu0ocDOXmQAgP0x17kvVSSi0,10234
|
5
|
+
pycupra/dashboard.py,sha256=3f4yBBBOMrXGiLdjO-2-1Ts2BVuQBw0wKa-2bhwid0c,42807
|
6
|
+
pycupra/exceptions.py,sha256=Nq_F79GP8wjHf5lpvPy9TbSIrRHAJrFMo0T1N9TcgSQ,2917
|
7
|
+
pycupra/utilities.py,sha256=cH4MiIzT2WlHgmnl_E7rR0R5LvCXfDNvirJolct50V8,2563
|
8
|
+
pycupra/vehicle.py,sha256=W1pQ8IkEmirSY6nha9OwSDFJyE2fcPGgeO_cVZAhgqg,135505
|
9
|
+
pycupra-0.0.14.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
10
|
+
pycupra-0.0.14.dist-info/METADATA,sha256=9txUYXQVhWep4acCAthlWizfMKKy19BCaiLPCdg0Wdk,2579
|
11
|
+
pycupra-0.0.14.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
12
|
+
pycupra-0.0.14.dist-info/top_level.txt,sha256=9Lbj_jG4JvpGwt6K3AwhWFc0XieDnuHFOP4x44wSXSQ,8
|
13
|
+
pycupra-0.0.14.dist-info/RECORD,,
|
pycupra-0.0.13.dist-info/RECORD
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
pycupra/__init__.py,sha256=VPzUfKd5mBFD1UERNV61FbGHih5dQPupLgIfYtmIUi4,230
|
2
|
-
pycupra/__version__.py,sha256=TaTBX6INREWajim6xVOUYCFZYeyoJA-OFOU2qeaT5nk,208
|
3
|
-
pycupra/connection.py,sha256=_bTo1sBsUUDEf6Q8-u4H079KT_IN5sW5vlYI26ZB9mc,82423
|
4
|
-
pycupra/const.py,sha256=mgl29DcZz_J5hSzxknteu0ocDOXmQAgP0x17kvVSSi0,10234
|
5
|
-
pycupra/dashboard.py,sha256=FYheQ_U_mJ6BpgGq0auzcL-MsGOzSIlRo9vPvjf2pGQ,42434
|
6
|
-
pycupra/exceptions.py,sha256=Nq_F79GP8wjHf5lpvPy9TbSIrRHAJrFMo0T1N9TcgSQ,2917
|
7
|
-
pycupra/utilities.py,sha256=cH4MiIzT2WlHgmnl_E7rR0R5LvCXfDNvirJolct50V8,2563
|
8
|
-
pycupra/vehicle.py,sha256=DTbUzd31lyXON77_6no1mCrw5uajx24K5qDKA70PL9M,132533
|
9
|
-
pycupra-0.0.13.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
10
|
-
pycupra-0.0.13.dist-info/METADATA,sha256=8xEMN1iXZC6Cc5sIOp_5dkzEpN9YXhdF_YoD07cFjLs,2579
|
11
|
-
pycupra-0.0.13.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
12
|
-
pycupra-0.0.13.dist-info/top_level.txt,sha256=9Lbj_jG4JvpGwt6K3AwhWFc0XieDnuHFOP4x44wSXSQ,8
|
13
|
-
pycupra-0.0.13.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|