pycupra 0.1.13__tar.gz → 0.1.14__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.
- {pycupra-0.1.13 → pycupra-0.1.14}/.gitignore +1 -1
- {pycupra-0.1.13/pycupra.egg-info → pycupra-0.1.14}/PKG-INFO +6 -2
- {pycupra-0.1.13 → pycupra-0.1.14}/example/PyCupra.py +12 -4
- pycupra-0.1.14/example/PyCupra_ExportDrivingData.py +113 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/connection.py +75 -67
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/dashboard.py +36 -36
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/firebase.py +11 -8
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/firebase_messaging/fcmpushclient.py +8 -7
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/firebase_messaging/fcmregister.py +3 -3
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/utilities.py +2 -26
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/vehicle.py +299 -226
- {pycupra-0.1.13 → pycupra-0.1.14/pycupra.egg-info}/PKG-INFO +6 -2
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra.egg-info/SOURCES.txt +1 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra.egg-info/requires.txt +4 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra_credentials.json.demo +1 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pyproject.toml +7 -3
- {pycupra-0.1.13 → pycupra-0.1.14}/LICENSE +0 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/README.md +0 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/__init__.py +0 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/const.py +0 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/exceptions.py +0 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/firebase_messaging/__init__.py +0 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/firebase_messaging/android_checkin.proto +0 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/firebase_messaging/android_checkin_pb2.py +0 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/firebase_messaging/android_checkin_pb2.pyi +0 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/firebase_messaging/checkin.proto +0 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/firebase_messaging/checkin_pb2.py +0 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/firebase_messaging/checkin_pb2.pyi +0 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/firebase_messaging/const.py +0 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/firebase_messaging/mcs.proto +0 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/firebase_messaging/mcs_pb2.py +0 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/firebase_messaging/mcs_pb2.pyi +0 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra/firebase_messaging/py.typed +0 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra.egg-info/dependency_links.txt +0 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/pycupra.egg-info/top_level.txt +0 -0
- {pycupra-0.1.13 → pycupra-0.1.14}/setup.cfg +0 -0
@@ -1,9 +1,9 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: pycupra
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.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
|
License-Expression: Apache-2.0
|
6
|
-
Requires-Python: >=3.
|
6
|
+
Requires-Python: >=3.12
|
7
7
|
Description-Content-Type: text/markdown
|
8
8
|
License-File: LICENSE
|
9
9
|
Requires-Dist: aiohttp
|
@@ -13,6 +13,10 @@ Requires-Dist: lxml
|
|
13
13
|
Requires-Dist: PyJWT
|
14
14
|
Requires-Dist: xmltodict
|
15
15
|
Requires-Dist: pandas
|
16
|
+
Requires-Dist: pillow
|
17
|
+
Requires-Dist: protobuf
|
18
|
+
Requires-Dist: http-ece
|
19
|
+
Requires-Dist: requests-oauthlib
|
16
20
|
Dynamic: license-file
|
17
21
|
|
18
22
|
# PyCupra
|
@@ -10,9 +10,11 @@ import pandas as pd
|
|
10
10
|
from aiohttp import ClientSession
|
11
11
|
from datetime import datetime
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
currentframe = inspect.currentframe()
|
14
|
+
if currentframe != None:
|
15
|
+
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(currentframe)))
|
16
|
+
parentdir = os.path.dirname(currentdir)
|
17
|
+
sys.path.insert(0, parentdir)
|
16
18
|
|
17
19
|
try:
|
18
20
|
from pycupra import Connection
|
@@ -383,6 +385,12 @@ async def main():
|
|
383
385
|
if credentials==None or credentials.get('username','')=='' or (credentials.get('password','')==''):
|
384
386
|
_LOGGER.warning('Can not use the credentials read from the credentials file.')
|
385
387
|
raise
|
388
|
+
if credentials.get('brand','')!='':
|
389
|
+
BRAND = credentials.get('brand','')
|
390
|
+
print('Read brand from the credentials file.')
|
391
|
+
else:
|
392
|
+
print('No brand found in the credentials file. Using the default value.')
|
393
|
+
print(f'Now working with brand={BRAND}')
|
386
394
|
async with ClientSession(headers={'Connection': 'keep-alive'}) as session:
|
387
395
|
print('')
|
388
396
|
print('######################################################')
|
@@ -594,7 +602,7 @@ async def main():
|
|
594
602
|
i=i+1
|
595
603
|
_LOGGER.debug(f'Round {i}')
|
596
604
|
|
597
|
-
exit
|
605
|
+
sys.exit(1)
|
598
606
|
|
599
607
|
if __name__ == "__main__":
|
600
608
|
loop = asyncio.new_event_loop()
|
@@ -0,0 +1,113 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
""" Sample program to export the trip statistics as csv file"""
|
3
|
+
import asyncio
|
4
|
+
import logging
|
5
|
+
import inspect
|
6
|
+
import sys
|
7
|
+
import os
|
8
|
+
import json
|
9
|
+
import pandas as pd
|
10
|
+
from aiohttp import ClientSession
|
11
|
+
from datetime import datetime
|
12
|
+
|
13
|
+
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
14
|
+
parentdir = os.path.dirname(currentdir)
|
15
|
+
sys.path.insert(0, parentdir)
|
16
|
+
|
17
|
+
try:
|
18
|
+
from pycupra import Connection
|
19
|
+
except ModuleNotFoundError as e:
|
20
|
+
print(f"Unable to import library: {e}")
|
21
|
+
sys.exit(1)
|
22
|
+
|
23
|
+
logging.basicConfig(level=logging.WARN)
|
24
|
+
_LOGGER = logging.getLogger(__name__)
|
25
|
+
BRAND = 'cupra' # or 'seat' (Default value if no brand is provided via credentials file)
|
26
|
+
|
27
|
+
PRINTRESPONSE = True
|
28
|
+
INTERVAL = 5
|
29
|
+
TOKEN_FILE_NAME_AND_PATH='./pycupra_token.json'
|
30
|
+
CREDENTIALS_FILE_NAME_AND_PATH='./pycupra_credentials.json'
|
31
|
+
|
32
|
+
def readCredentialsFile():
|
33
|
+
try:
|
34
|
+
with open(CREDENTIALS_FILE_NAME_AND_PATH, "r") as f:
|
35
|
+
credentialsString=f.read()
|
36
|
+
credentials=json.loads(credentialsString)
|
37
|
+
return credentials
|
38
|
+
except:
|
39
|
+
_LOGGER.info('readCredentialsFile not successful. Perhaps no credentials file present.')
|
40
|
+
return None
|
41
|
+
|
42
|
+
def exportToCSV(vehicle, csvFileName, dataType='short'):
|
43
|
+
df= pd.DataFrame(vehicle._states['tripstatistics'][dataType])
|
44
|
+
_LOGGER.debug('Exporting trip data to csv')
|
45
|
+
df.to_csv(csvFileName)
|
46
|
+
return True
|
47
|
+
|
48
|
+
async def main():
|
49
|
+
"""Main method."""
|
50
|
+
print('')
|
51
|
+
print('######################################################')
|
52
|
+
print('# Reading credentials file #')
|
53
|
+
print('######################################################')
|
54
|
+
credentials= readCredentialsFile()
|
55
|
+
if credentials==None or credentials.get('username','')=='' or (credentials.get('password','')==''):
|
56
|
+
_LOGGER.warning('Can not use the credentials read from the credentials file.')
|
57
|
+
raise
|
58
|
+
if credentials.get('brand','')!='':
|
59
|
+
BRAND = credentials.get('brand','')
|
60
|
+
print('Read brand from the credentials file.')
|
61
|
+
else:
|
62
|
+
print('No brand found in the credentials file. Using the default value.')
|
63
|
+
print(f'Now working with brand={BRAND}')
|
64
|
+
async with ClientSession(headers={'Connection': 'keep-alive'}) as session:
|
65
|
+
print('')
|
66
|
+
print('######################################################')
|
67
|
+
print('# Logging on to ola.prod.code.seat.cloud.vwgroup.com #')
|
68
|
+
print('######################################################')
|
69
|
+
print(f"Initiating new session to Cupra/Seat Cloud with {credentials.get('username')} as username")
|
70
|
+
connection = Connection(session, BRAND, credentials.get('username'), credentials.get('password'), PRINTRESPONSE, nightlyUpdateReduction=False, anonymise=True, tripStatisticsStartDate='1970-01-01')
|
71
|
+
print("Attempting to login to the Seat Cloud service")
|
72
|
+
if await connection.doLogin(tokenFile=TOKEN_FILE_NAME_AND_PATH, apiKey=credentials.get('apiKey',None)):
|
73
|
+
print('Login or token refresh success!')
|
74
|
+
print(datetime.now())
|
75
|
+
print('Fetching user information for account.')
|
76
|
+
await connection.get_userData()
|
77
|
+
print(f"\tName: {connection._userData.get('name','')}")
|
78
|
+
print(f"\tNickname: {connection._userData.get('nickname','')}")
|
79
|
+
print(f"\tEmail: {connection._userData.get('email','')}")
|
80
|
+
print(f"\tPicture: {connection._userData.get('picture','')}")
|
81
|
+
print("")
|
82
|
+
print('Fetching vehicles associated with account.')
|
83
|
+
await connection.get_vehicles()
|
84
|
+
|
85
|
+
print('')
|
86
|
+
print('########################################')
|
87
|
+
print('# Vehicles discovered #')
|
88
|
+
print('########################################')
|
89
|
+
for vehicle in connection.vehicles:
|
90
|
+
print(f"\tVIN: {vehicle.vin}")
|
91
|
+
print(f"\tModel: {vehicle.model}")
|
92
|
+
print(f"\tManufactured: {vehicle.model_year}")
|
93
|
+
print(f"\tConnect service deactivated: {vehicle.deactivated}")
|
94
|
+
print("")
|
95
|
+
if vehicle.is_nickname_supported: print(f"\tNickname: {vehicle.nickname}")
|
96
|
+
else:
|
97
|
+
return False
|
98
|
+
|
99
|
+
for vehicle in connection.vehicles:
|
100
|
+
txt = vehicle.vin
|
101
|
+
print('########################################')
|
102
|
+
print('# Export driving data to csv #')
|
103
|
+
print(txt.center(40, '#'))
|
104
|
+
exportToCSV(vehicle, credentials.get('csvFileName','./drivingData.csv'), 'short') # possible value: short/cyclic
|
105
|
+
print('')
|
106
|
+
print('Export of driving data to csv complete')
|
107
|
+
sys.exit(1)
|
108
|
+
|
109
|
+
if __name__ == "__main__":
|
110
|
+
loop = asyncio.new_event_loop()
|
111
|
+
asyncio.set_event_loop(loop)
|
112
|
+
loop.run_until_complete(main())
|
113
|
+
|