pycupra 0.1.5__py3-none-any.whl → 0.1.7__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 +1868 -1816
- pycupra/const.py +1 -0
- pycupra/dashboard.py +12 -0
- pycupra/firebase.py +37 -20
- pycupra/firebase_messaging/fcmpushclient.py +14 -3
- pycupra/utilities.py +116 -116
- pycupra/vehicle.py +69 -14
- {pycupra-0.1.5.dist-info → pycupra-0.1.7.dist-info}/METADATA +1 -1
- {pycupra-0.1.5.dist-info → pycupra-0.1.7.dist-info}/RECORD +13 -13
- {pycupra-0.1.5.dist-info → pycupra-0.1.7.dist-info}/WHEEL +0 -0
- {pycupra-0.1.5.dist-info → pycupra-0.1.7.dist-info}/licenses/LICENSE +0 -0
- {pycupra-0.1.5.dist-info → pycupra-0.1.7.dist-info}/top_level.txt +0 -0
pycupra/const.py
CHANGED
pycupra/dashboard.py
CHANGED
@@ -755,6 +755,18 @@ class Warnings(Sensor):
|
|
755
755
|
def assumed_state(self):
|
756
756
|
return False
|
757
757
|
|
758
|
+
@property
|
759
|
+
def attributes(self):
|
760
|
+
attrs = {'warnings': 'No warnings'}
|
761
|
+
if self.vehicle.attrs.get('warninglights', {}).get('statuses',[]):
|
762
|
+
warningTextList = []
|
763
|
+
for elem in self.vehicle.attrs['warninglights']['statuses']:
|
764
|
+
if isinstance(elem, dict):
|
765
|
+
if elem.get('text',''):
|
766
|
+
warningTextList.append(elem.get('text',''))
|
767
|
+
attrs['warnings'] = warningTextList
|
768
|
+
return attrs
|
769
|
+
|
758
770
|
class DepartureTimer1(Switch):
|
759
771
|
def __init__(self):
|
760
772
|
super().__init__(attr="departure1", name="Departure timer 1", icon="mdi:radiator")
|
pycupra/firebase.py
CHANGED
@@ -16,29 +16,46 @@ from .const import (
|
|
16
16
|
_LOGGER = logging.getLogger(__name__)
|
17
17
|
|
18
18
|
class Firebase():
|
19
|
+
def __init__(self):
|
20
|
+
self._pushClient = None
|
21
|
+
|
19
22
|
async def firebaseStart(self, onNotificationFunc, firebaseCredentialsFileName, brand='cupra'):
|
20
23
|
""" Starts the firebase cloud messaging receiver """
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
credentials
|
24
|
+
try:
|
25
|
+
loop = asyncio.get_running_loop()
|
26
|
+
credentials = await loop.run_in_executor(None, readFCMCredsFile, firebaseCredentialsFileName)
|
27
|
+
#credentials = readFCMCredsFile(firebaseCredentialsFileName)
|
28
|
+
if credentials == {}:
|
29
|
+
credentials =''
|
26
30
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
fcm_project_id=FCM_PROJECT_ID
|
32
|
+
fcm_app_id=FCM_APP_ID[brand]
|
33
|
+
fcm_api_key=FCM_API_KEY
|
34
|
+
chars = string.ascii_letters + string.digits
|
35
|
+
fcmMessageSenderId = ''.join(secrets.choice(chars) for i in range(16))
|
36
|
+
fcmMessageSenderId= 'fxpWQ_'+fcmMessageSenderId
|
33
37
|
|
38
|
+
fcm_config = FcmRegisterConfig(fcm_project_id, fcm_app_id, fcm_api_key, fcmMessageSenderId)
|
39
|
+
self._pushClient = FcmPushClient(onNotificationFunc, fcm_config, credentials, onFCMCredentialsUpdated)
|
40
|
+
fcm_token = await self._pushClient.checkin_or_register(firebaseCredentialsFileName)
|
41
|
+
_LOGGER.debug(f'Firebase.checkin_or_register() returned a token:{fcm_token}')
|
42
|
+
await self._pushClient.start()
|
43
|
+
await asyncio.sleep(5)
|
44
|
+
return self._pushClient.is_started()
|
45
|
+
except Exception as e:
|
46
|
+
_LOGGER.error('Error in firebaseStart. Error: {e}')
|
47
|
+
return False
|
34
48
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
49
|
+
async def firebaseStop(self):
|
50
|
+
""" Stops the firebase cloud messaging receiver """
|
51
|
+
try:
|
52
|
+
await self._pushClient.stop()
|
53
|
+
#await asyncio.sleep(5)
|
54
|
+
self._pushClient = None
|
55
|
+
return True
|
56
|
+
except Exception as e:
|
57
|
+
_LOGGER.error('Error in firebaseStop. Error: {e}')
|
58
|
+
return False
|
42
59
|
|
43
60
|
def readFCMCredsFile(credsFile):
|
44
61
|
""" Reads the firebase cloud messaging credentials from file"""
|
@@ -52,8 +69,8 @@ def readFCMCredsFile(credsFile):
|
|
52
69
|
else:
|
53
70
|
_LOGGER.debug(f'{credsFile} not found.')
|
54
71
|
return {}
|
55
|
-
except:
|
56
|
-
_LOGGER.warning('readFCMCredsFile() not successful.')
|
72
|
+
except Exception as e:
|
73
|
+
_LOGGER.warning('readFCMCredsFile() not successful. Error: {e}')
|
57
74
|
return ''
|
58
75
|
|
59
76
|
def writeFCMCredsFile(creds, firebaseCredentialsFileName):
|
@@ -599,10 +599,21 @@ class FcmPushClient: # pylint:disable=too-many-instance-attributes
|
|
599
599
|
return
|
600
600
|
|
601
601
|
if isinstance(msg, DataMessageStanza):
|
602
|
-
await self._handle_data_message(msg)
|
603
|
-
self.persistent_ids.append(msg.persistent_id)
|
602
|
+
#await self._handle_data_message(msg)
|
603
|
+
#self.persistent_ids.append(msg.persistent_id)
|
604
|
+
#if self.config.send_selective_acknowledgements:
|
605
|
+
# await self._send_selective_ack(msg.persistent_id)
|
604
606
|
if self.config.send_selective_acknowledgements:
|
605
|
-
|
607
|
+
# As handle_data_message with the callback of onNotification can take some time, send_selective_ack is called in parallel
|
608
|
+
await asyncio.gather(
|
609
|
+
self._handle_data_message(msg),
|
610
|
+
self._send_selective_ack(msg.persistent_id),
|
611
|
+
return_exceptions=True
|
612
|
+
)
|
613
|
+
self.persistent_ids.append(msg.persistent_id),
|
614
|
+
else:
|
615
|
+
await self._handle_data_message(msg)
|
616
|
+
self.persistent_ids.append(msg.persistent_id)
|
606
617
|
elif isinstance(msg, HeartbeatPing):
|
607
618
|
await self._handle_ping(msg)
|
608
619
|
elif isinstance(msg, HeartbeatAck):
|
pycupra/utilities.py
CHANGED
@@ -1,116 +1,116 @@
|
|
1
|
-
from datetime import date, datetime
|
2
|
-
from base64 import b64encode
|
3
|
-
from string import ascii_letters as letters, digits
|
4
|
-
from sys import argv
|
5
|
-
from os import environ as env
|
6
|
-
from os.path import join, dirname, expanduser
|
7
|
-
from itertools import product
|
8
|
-
import json
|
9
|
-
import logging
|
10
|
-
import re
|
11
|
-
|
12
|
-
_LOGGER = logging.getLogger(__name__)
|
13
|
-
|
14
|
-
|
15
|
-
def read_config():
|
16
|
-
"""Read config from file."""
|
17
|
-
for directory, filename in product(
|
18
|
-
[
|
19
|
-
dirname(argv[0]),
|
20
|
-
expanduser("~"),
|
21
|
-
env.get("XDG_CONFIG_HOME", join(expanduser("~"), ".config")),
|
22
|
-
],
|
23
|
-
["seat.conf", ".seat.conf"],
|
24
|
-
):
|
25
|
-
try:
|
26
|
-
config = join(directory, filename)
|
27
|
-
_LOGGER.debug("checking for config file %s", config)
|
28
|
-
with open(config) as config:
|
29
|
-
return dict(
|
30
|
-
x.split(": ")
|
31
|
-
for x in config.read().strip().splitlines()
|
32
|
-
if not x.startswith("#")
|
33
|
-
)
|
34
|
-
except (IOError, OSError):
|
35
|
-
continue
|
36
|
-
return {}
|
37
|
-
|
38
|
-
|
39
|
-
def json_loads(s):
|
40
|
-
return json.loads(s, object_hook=obj_parser)
|
41
|
-
|
42
|
-
|
43
|
-
def obj_parser(obj):
|
44
|
-
"""Parse datetime."""
|
45
|
-
for key, val in obj.items():
|
46
|
-
try:
|
47
|
-
obj[key] = datetime.strptime(val, "%Y-%m-%dT%H:%M:%S%z")
|
48
|
-
except (TypeError, ValueError):
|
49
|
-
pass
|
50
|
-
return obj
|
51
|
-
|
52
|
-
|
53
|
-
def find_path(src, path):
|
54
|
-
"""Simple navigation of a hierarchical dict structure using XPATH-like syntax.
|
55
|
-
|
56
|
-
>>> find_path(dict(a=1), 'a')
|
57
|
-
1
|
58
|
-
|
59
|
-
>>> find_path(dict(a=1), '')
|
60
|
-
{'a': 1}
|
61
|
-
|
62
|
-
>>> find_path(dict(a=None), 'a')
|
63
|
-
|
64
|
-
|
65
|
-
>>> find_path(dict(a=1), 'b')
|
66
|
-
Traceback (most recent call last):
|
67
|
-
...
|
68
|
-
KeyError: 'b'
|
69
|
-
|
70
|
-
>>> find_path(dict(a=dict(b=1)), 'a.b')
|
71
|
-
1
|
72
|
-
|
73
|
-
>>> find_path(dict(a=dict(b=1)), 'a')
|
74
|
-
{'b': 1}
|
75
|
-
|
76
|
-
>>> find_path(dict(a=dict(b=1)), 'a.c')
|
77
|
-
Traceback (most recent call last):
|
78
|
-
...
|
79
|
-
KeyError: 'c'
|
80
|
-
|
81
|
-
"""
|
82
|
-
if not path:
|
83
|
-
return src
|
84
|
-
if isinstance(path, str):
|
85
|
-
path = path.split(".")
|
86
|
-
return find_path(src[path[0]], path[1:])
|
87
|
-
|
88
|
-
|
89
|
-
def is_valid_path(src, path):
|
90
|
-
"""
|
91
|
-
>>> is_valid_path(dict(a=1), 'a')
|
92
|
-
True
|
93
|
-
|
94
|
-
>>> is_valid_path(dict(a=1), '')
|
95
|
-
True
|
96
|
-
|
97
|
-
>>> is_valid_path(dict(a=1), None)
|
98
|
-
True
|
99
|
-
|
100
|
-
>>> is_valid_path(dict(a=1), 'b')
|
101
|
-
False
|
102
|
-
"""
|
103
|
-
try:
|
104
|
-
find_path(src, path)
|
105
|
-
return True
|
106
|
-
except KeyError:
|
107
|
-
return False
|
108
|
-
|
109
|
-
|
110
|
-
def camel2slug(s):
|
111
|
-
"""Convert camelCase to camel_case.
|
112
|
-
|
113
|
-
>>> camel2slug('fooBar')
|
114
|
-
'foo_bar'
|
115
|
-
"""
|
116
|
-
return re.sub("([A-Z])", "_\\1", s).lower().lstrip("_")
|
1
|
+
from datetime import date, datetime
|
2
|
+
from base64 import b64encode
|
3
|
+
from string import ascii_letters as letters, digits
|
4
|
+
from sys import argv
|
5
|
+
from os import environ as env
|
6
|
+
from os.path import join, dirname, expanduser
|
7
|
+
from itertools import product
|
8
|
+
import json
|
9
|
+
import logging
|
10
|
+
import re
|
11
|
+
|
12
|
+
_LOGGER = logging.getLogger(__name__)
|
13
|
+
|
14
|
+
|
15
|
+
def read_config():
|
16
|
+
"""Read config from file."""
|
17
|
+
for directory, filename in product(
|
18
|
+
[
|
19
|
+
dirname(argv[0]),
|
20
|
+
expanduser("~"),
|
21
|
+
env.get("XDG_CONFIG_HOME", join(expanduser("~"), ".config")),
|
22
|
+
],
|
23
|
+
["seat.conf", ".seat.conf"],
|
24
|
+
):
|
25
|
+
try:
|
26
|
+
config = join(directory, filename)
|
27
|
+
_LOGGER.debug("checking for config file %s", config)
|
28
|
+
with open(config) as config:
|
29
|
+
return dict(
|
30
|
+
x.split(": ")
|
31
|
+
for x in config.read().strip().splitlines()
|
32
|
+
if not x.startswith("#")
|
33
|
+
)
|
34
|
+
except (IOError, OSError):
|
35
|
+
continue
|
36
|
+
return {}
|
37
|
+
|
38
|
+
|
39
|
+
def json_loads(s):
|
40
|
+
return json.loads(s, object_hook=obj_parser)
|
41
|
+
|
42
|
+
|
43
|
+
def obj_parser(obj):
|
44
|
+
"""Parse datetime."""
|
45
|
+
for key, val in obj.items():
|
46
|
+
try:
|
47
|
+
obj[key] = datetime.strptime(val, "%Y-%m-%dT%H:%M:%S%z")
|
48
|
+
except (TypeError, ValueError):
|
49
|
+
pass
|
50
|
+
return obj
|
51
|
+
|
52
|
+
|
53
|
+
def find_path(src, path):
|
54
|
+
"""Simple navigation of a hierarchical dict structure using XPATH-like syntax.
|
55
|
+
|
56
|
+
>>> find_path(dict(a=1), 'a')
|
57
|
+
1
|
58
|
+
|
59
|
+
>>> find_path(dict(a=1), '')
|
60
|
+
{'a': 1}
|
61
|
+
|
62
|
+
>>> find_path(dict(a=None), 'a')
|
63
|
+
|
64
|
+
|
65
|
+
>>> find_path(dict(a=1), 'b')
|
66
|
+
Traceback (most recent call last):
|
67
|
+
...
|
68
|
+
KeyError: 'b'
|
69
|
+
|
70
|
+
>>> find_path(dict(a=dict(b=1)), 'a.b')
|
71
|
+
1
|
72
|
+
|
73
|
+
>>> find_path(dict(a=dict(b=1)), 'a')
|
74
|
+
{'b': 1}
|
75
|
+
|
76
|
+
>>> find_path(dict(a=dict(b=1)), 'a.c')
|
77
|
+
Traceback (most recent call last):
|
78
|
+
...
|
79
|
+
KeyError: 'c'
|
80
|
+
|
81
|
+
"""
|
82
|
+
if not path:
|
83
|
+
return src
|
84
|
+
if isinstance(path, str):
|
85
|
+
path = path.split(".")
|
86
|
+
return find_path(src[path[0]], path[1:])
|
87
|
+
|
88
|
+
|
89
|
+
def is_valid_path(src, path):
|
90
|
+
"""
|
91
|
+
>>> is_valid_path(dict(a=1), 'a')
|
92
|
+
True
|
93
|
+
|
94
|
+
>>> is_valid_path(dict(a=1), '')
|
95
|
+
True
|
96
|
+
|
97
|
+
>>> is_valid_path(dict(a=1), None)
|
98
|
+
True
|
99
|
+
|
100
|
+
>>> is_valid_path(dict(a=1), 'b')
|
101
|
+
False
|
102
|
+
"""
|
103
|
+
try:
|
104
|
+
find_path(src, path)
|
105
|
+
return True
|
106
|
+
except KeyError:
|
107
|
+
return False
|
108
|
+
|
109
|
+
|
110
|
+
def camel2slug(s):
|
111
|
+
"""Convert camelCase to camel_case.
|
112
|
+
|
113
|
+
>>> camel2slug('fooBar')
|
114
|
+
'foo_bar'
|
115
|
+
"""
|
116
|
+
return re.sub("([A-Z])", "_\\1", s).lower().lstrip("_")
|
pycupra/vehicle.py
CHANGED
@@ -24,6 +24,7 @@ from .const import (
|
|
24
24
|
FIREBASE_STATUS_NOT_INITIALISED,
|
25
25
|
FIREBASE_STATUS_ACTIVATED,
|
26
26
|
FIREBASE_STATUS_ACTIVATION_FAILED,
|
27
|
+
FIREBASE_STATUS_ACTIVATION_STOPPED,
|
27
28
|
FIREBASE_STATUS_NOT_WANTED,
|
28
29
|
)
|
29
30
|
|
@@ -34,7 +35,7 @@ _LOGGER = logging.getLogger(__name__)
|
|
34
35
|
DATEZERO = datetime(1970,1,1)
|
35
36
|
class Vehicle:
|
36
37
|
def __init__(self, conn, data):
|
37
|
-
_LOGGER.debug(f'Creating Vehicle class object with data {data}')
|
38
|
+
_LOGGER.debug(conn.anonymise(f'Creating Vehicle class object with data {data}'))
|
38
39
|
self._connection = conn
|
39
40
|
self._url = data.get('vin', '')
|
40
41
|
self._connectivities = data.get('connectivities', '')
|
@@ -50,6 +51,7 @@ class Vehicle:
|
|
50
51
|
self._firebaseCredentialsFileName = None
|
51
52
|
self._firebaseLastMessageId = ''
|
52
53
|
self.firebaseStatus = FIREBASE_STATUS_NOT_INITIALISED
|
54
|
+
self.firebase = None
|
53
55
|
self.updateCallback = None
|
54
56
|
|
55
57
|
self._requests = {
|
@@ -152,6 +154,11 @@ class Vehicle:
|
|
152
154
|
if not self.deactivated:
|
153
155
|
try:
|
154
156
|
if self.firebaseStatus == FIREBASE_STATUS_ACTIVATED:
|
157
|
+
# Check, if fcmpushclient still started
|
158
|
+
if not self.firebase._pushClient.is_started():
|
159
|
+
_LOGGER.warning(f'firebaseStatus={self.firebaseStatus}, but state of push client is not started. Changing firebaseStatus to {FIREBASE_STATUS_ACTIVATION_STOPPED}')
|
160
|
+
self.firebaseStatus = FIREBASE_STATUS_ACTIVATION_STOPPED
|
161
|
+
|
155
162
|
fullUpdateExpired = datetime.now(tz=None) - timedelta(seconds= 1700)
|
156
163
|
oldMileage = self.distance
|
157
164
|
if self._last_get_mileage < datetime.now(tz=None) - timedelta(seconds= 300):
|
@@ -184,13 +191,24 @@ class Vehicle:
|
|
184
191
|
if hasattr(self, '_last_full_update'):
|
185
192
|
_LOGGER.debug(f'last_full_update= {self._last_full_update}, fullUpdateExpired= {fullUpdateExpired}.')
|
186
193
|
if updateType!=1 and (hasattr(self, '_last_full_update') and self._last_full_update>fullUpdateExpired):
|
187
|
-
_LOGGER.debug(f'Just performed small update for vehicle with VIN {self.vin}.')
|
194
|
+
_LOGGER.debug(f'Just performed small update for vehicle with VIN {self._connection.anonymise(self.vin)}.')
|
188
195
|
return True
|
189
196
|
|
190
197
|
# Data to be updated less often
|
191
198
|
if self.firebaseStatus != FIREBASE_STATUS_ACTIVATED:
|
192
199
|
await self.get_mileage()
|
193
200
|
|
201
|
+
if self.firebaseStatus == FIREBASE_STATUS_ACTIVATION_STOPPED:
|
202
|
+
# Trying to activate firebase connection again
|
203
|
+
await self.firebase._pushClient.start()
|
204
|
+
#await asyncio.sleep(5)
|
205
|
+
if self.firebase._pushClient.is_started():
|
206
|
+
self.firebaseStatus = FIREBASE_STATUS_ACTIVATED
|
207
|
+
_LOGGER.debug(f'Successfully restarted push client. New firebase status ={self.firebaseStatus}')
|
208
|
+
else:
|
209
|
+
_LOGGER.debug(f'Restart of push client failed. Firebase status ={self.firebaseStatus}')
|
210
|
+
|
211
|
+
|
194
212
|
await asyncio.gather(
|
195
213
|
#self.get_statusreport(),
|
196
214
|
self.get_charger(),
|
@@ -206,13 +224,13 @@ class Vehicle:
|
|
206
224
|
return_exceptions=True
|
207
225
|
)
|
208
226
|
self._last_full_update = datetime.now(tz=None)
|
209
|
-
_LOGGER.debug(f'Performed full update for vehicle with VIN {self.vin}.')
|
227
|
+
_LOGGER.debug(f'Performed full update for vehicle with VIN {self._connection.anonymise(self.vin)}.')
|
210
228
|
_LOGGER.debug(f'So far about {self._connection._sessionRequestCounter} API calls since {self._connection._sessionRequestTimestamp}.')
|
211
229
|
except:
|
212
230
|
raise SeatException("Update failed")
|
213
231
|
return True
|
214
232
|
else:
|
215
|
-
_LOGGER.info(f'Vehicle with VIN {self.vin} is deactivated.')
|
233
|
+
_LOGGER.info(f'Vehicle with VIN {self._connection.anonymise(self.vin)} is deactivated.')
|
216
234
|
return False
|
217
235
|
return True
|
218
236
|
|
@@ -290,6 +308,14 @@ class Vehicle:
|
|
290
308
|
if self._relevantCapabilties.get('vehicleHealthWarnings', {}).get('active', False):
|
291
309
|
data = await self._connection.getVehicleHealthWarnings(self.vin, self._apibase)
|
292
310
|
if data:
|
311
|
+
#warningsList = data.get('warninglights',{}).get('statuses',[])
|
312
|
+
#for i in range(len(warningsList)):
|
313
|
+
# _LOGGER.debug(f'Element {i} in warninglights: {warningsList[i]}')
|
314
|
+
# if isinstance(warningsList[i], dict):
|
315
|
+
# if warningsList[i].get('icon',''):
|
316
|
+
# #Value of icon is very long and can lead to problems
|
317
|
+
# _LOGGER.debug(f'Substituting value of icon by \'DELETED\'')
|
318
|
+
# data['warninglights']['statuses'][i]['icon']='DELETED'
|
293
319
|
self._states.update(data)
|
294
320
|
else:
|
295
321
|
_LOGGER.debug('Could not fetch vehicle health warnings')
|
@@ -1394,6 +1420,17 @@ class Vehicle:
|
|
1394
1420
|
# if car.get('deactivated', False):
|
1395
1421
|
# return True
|
1396
1422
|
|
1423
|
+
@property
|
1424
|
+
def brand(self):
|
1425
|
+
"""Return brand"""
|
1426
|
+
return self._specification.get('factoryModel', False).get('vehicleBrand', 'Unknown')
|
1427
|
+
|
1428
|
+
@property
|
1429
|
+
def is_brand_supported(self):
|
1430
|
+
"""Return true if brand is supported."""
|
1431
|
+
if self._specification.get('factoryModel', False).get('vehicleBrand', False):
|
1432
|
+
return True
|
1433
|
+
|
1397
1434
|
@property
|
1398
1435
|
def model(self):
|
1399
1436
|
"""Return model"""
|
@@ -2216,9 +2253,7 @@ class Vehicle:
|
|
2216
2253
|
@property
|
2217
2254
|
def warnings(self):
|
2218
2255
|
"""Return warnings."""
|
2219
|
-
|
2220
|
-
return self.attrs.get('warninglights', {}).get('statuses',[])
|
2221
|
-
return 'No warnings'
|
2256
|
+
return len(self.attrs.get('warninglights', {}).get('statuses',[]))
|
2222
2257
|
|
2223
2258
|
@property
|
2224
2259
|
def is_warnings_supported(self):
|
@@ -3120,6 +3155,27 @@ class Vehicle:
|
|
3120
3155
|
)
|
3121
3156
|
|
3122
3157
|
|
3158
|
+
async def stopFirebase(self):
|
3159
|
+
# Check if firebase is activated
|
3160
|
+
if self.firebaseStatus!= FIREBASE_STATUS_ACTIVATED:
|
3161
|
+
_LOGGER.info(f'No need to stop firebase. Firebase status={self.firebaseStatus}')
|
3162
|
+
return self.firebaseStatus
|
3163
|
+
|
3164
|
+
if self.firebase == None:
|
3165
|
+
_LOGGER.error(f'Internal error: Firebase status={self.firebaseStatus} but firebase variable not set. Setting firebase status back to not initialised.')
|
3166
|
+
self.firebaseStatus = FIREBASE_STATUS_NOT_INITIALISED
|
3167
|
+
return self.firebaseStatus
|
3168
|
+
|
3169
|
+
success = await self.firebase.firebaseStop()
|
3170
|
+
if not success:
|
3171
|
+
_LOGGER.warning('Stopping of firebase messaging failed.')
|
3172
|
+
return self.firebaseStatus
|
3173
|
+
|
3174
|
+
#await asyncio.sleep(5) # Wait to ignore the first notifications
|
3175
|
+
self.firebaseStatus = FIREBASE_STATUS_NOT_INITIALISED
|
3176
|
+
_LOGGER.info('Stopping of firebase messaging was successful.')
|
3177
|
+
return self.firebaseStatus
|
3178
|
+
|
3123
3179
|
async def initialiseFirebase(self, firebaseCredentialsFileName=None, updateCallback=None):
|
3124
3180
|
# Check if firebase shall be used
|
3125
3181
|
if firebaseCredentialsFileName == None:
|
@@ -3141,12 +3197,13 @@ class Vehicle:
|
|
3141
3197
|
subscribedBrand = credentials.get('subscription',{}).get('brand','')
|
3142
3198
|
if subscribedVin != '' and subscribedUserId != '':
|
3143
3199
|
if subscribedVin != self.vin or subscribedUserId != self._connection._user_id or subscribedBrand != self._connection._session_auth_brand:
|
3144
|
-
_LOGGER.debug(f'Change of vin, userId or brand. Deleting subscription for vin={subscribedVin} and userId={subscribedUserId}.')
|
3200
|
+
_LOGGER.debug(self._connection.anonymise(f'Change of vin, userId or brand. Deleting subscription for vin={subscribedVin} and userId={subscribedUserId}.'))
|
3145
3201
|
result = await self._connection.deleteSubscription(credentials)
|
3146
3202
|
|
3147
3203
|
# Start firebase
|
3148
|
-
|
3149
|
-
|
3204
|
+
if self.firebase == None:
|
3205
|
+
self.firebase = Firebase()
|
3206
|
+
success = await self.firebase.firebaseStart(self.onNotification, firebaseCredentialsFileName, brand=self._connection._session_auth_brand)
|
3150
3207
|
if not success:
|
3151
3208
|
self.firebaseStatus = FIREBASE_STATUS_ACTIVATION_FAILED
|
3152
3209
|
_LOGGER.warning('Activation of firebase messaging failed.')
|
@@ -3167,7 +3224,7 @@ class Vehicle:
|
|
3167
3224
|
loop = asyncio.get_running_loop()
|
3168
3225
|
await loop.run_in_executor(None, writeFCMCredsFile, credentials, firebaseCredentialsFileName)
|
3169
3226
|
|
3170
|
-
await asyncio.sleep(5) # Wait to
|
3227
|
+
await asyncio.sleep(5) # Wait to ignore the first notifications
|
3171
3228
|
self.firebaseStatus = FIREBASE_STATUS_ACTIVATED
|
3172
3229
|
_LOGGER.info('Activation of firebase messaging was successful.')
|
3173
3230
|
return self.firebaseStatus
|
@@ -3247,7 +3304,7 @@ class Vehicle:
|
|
3247
3304
|
await self.updateCallback(2)
|
3248
3305
|
else:
|
3249
3306
|
_LOGGER.debug(f'It is now {datetime.now(tz=None)}. Last get_charger was at {self._last_get_charger}. So no need to update.')
|
3250
|
-
elif type in ('climatisation-status-changed','climatisation-started', 'climatisation-stopped'):
|
3307
|
+
elif type in ('climatisation-status-changed','climatisation-started', 'climatisation-stopped', 'climatisation-settings-updated'):
|
3251
3308
|
if self._requests.get('climatisation', {}).get('id', None):
|
3252
3309
|
openRequest= self._requests.get('climatisation', {}).get('id', None)
|
3253
3310
|
if openRequest == requestId:
|
@@ -3273,8 +3330,6 @@ class Vehicle:
|
|
3273
3330
|
else:
|
3274
3331
|
_LOGGER.warning(f' Don\'t know what to do with a notification of type \'{type}\')')
|
3275
3332
|
|
3276
|
-
|
3277
|
-
|
3278
3333
|
|
3279
3334
|
def storeFirebaseNotifications(self, obj, notification, data_message):
|
3280
3335
|
_LOGGER.debug(f'In storeFirebaseNotifications. notification={notification}')
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: pycupra
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.7
|
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
|
@@ -1,25 +1,25 @@
|
|
1
1
|
pycupra/__init__.py,sha256=p0880jPkLqOErX3u3qaLboBLOsEHFpe44axApdaGeqI,231
|
2
|
-
pycupra/__version__.py,sha256=
|
3
|
-
pycupra/connection.py,sha256=
|
4
|
-
pycupra/const.py,sha256=
|
5
|
-
pycupra/dashboard.py,sha256=
|
2
|
+
pycupra/__version__.py,sha256=DKM773a_0KC1VMvD1yaWYuzJUpp3XsxR_HcWB1g_-Ys,207
|
3
|
+
pycupra/connection.py,sha256=GWup_DcxnHNydb0DRJV79Hd108HJxMrGk89vi5R7meE,91150
|
4
|
+
pycupra/const.py,sha256=F6y3qt_wS1QxhdSR-NHxB7lpUcf5uKLeoeTAJcAXgsE,10630
|
5
|
+
pycupra/dashboard.py,sha256=xWggxTyKTBm3ByjRtymVzLJWtlIa52IEJsNx0z7bA9Q,44324
|
6
6
|
pycupra/exceptions.py,sha256=Nq_F79GP8wjHf5lpvPy9TbSIrRHAJrFMo0T1N9TcgSQ,2917
|
7
|
-
pycupra/firebase.py,sha256=
|
8
|
-
pycupra/utilities.py,sha256=
|
9
|
-
pycupra/vehicle.py,sha256=
|
7
|
+
pycupra/firebase.py,sha256=tuN_W3OX3h3-yfdprWzmCn6z_T-BMx-OpL7Z6hOA8Lc,3451
|
8
|
+
pycupra/utilities.py,sha256=6sDxWP13-XtxmqhuBJBGdVbkj48BQ9AxFMrBPxH0J7g,2679
|
9
|
+
pycupra/vehicle.py,sha256=jOtpn8WUxKBYPIuCuPMfmH19AVfY0Mn1GXtRJM_gosQ,157941
|
10
10
|
pycupra/firebase_messaging/__init__.py,sha256=oerLHWvEf4qRqu3GxSX6SLY_OYI430ydAiAhKtzyMEM,666
|
11
11
|
pycupra/firebase_messaging/android_checkin_pb2.py,sha256=-U1oGroFt3KRuGDieae3iTcux6mAfx1TFkE1Q35ul2E,2849
|
12
12
|
pycupra/firebase_messaging/android_checkin_pb2.pyi,sha256=7KL-zQIz2Zz7uftcLkv57Podzu-yk6trn50FN4X4A8E,9379
|
13
13
|
pycupra/firebase_messaging/checkin_pb2.py,sha256=lFzCIAkYz9NFUpRbVuW-2kM_EaYKVWHeifHS1PV2eHQ,2795
|
14
14
|
pycupra/firebase_messaging/checkin_pb2.pyi,sha256=mHOqbedt5jZDI20jcyFrTMSnQ0f_tq4zkIlHiaSC3xI,14626
|
15
15
|
pycupra/firebase_messaging/const.py,sha256=XMy8kJ37uBSkTpVpdLeSjxk5UIPuvDuo-rxYdgmo2G8,1191
|
16
|
-
pycupra/firebase_messaging/fcmpushclient.py,sha256=
|
16
|
+
pycupra/firebase_messaging/fcmpushclient.py,sha256=7ADEYA6Aw4c42bwbIJr_I76wGiLOu99oV7PSNC4UcVs,30157
|
17
17
|
pycupra/firebase_messaging/fcmregister.py,sha256=yZngC-0ZfTygtjfdzg03OW_3xk2n_uSQQ3Lrash5Y_E,18091
|
18
18
|
pycupra/firebase_messaging/mcs_pb2.py,sha256=nwXY7IDgLYPxgpSGs6wyTSyYDdomQsyGqH8R8EgODLg,7733
|
19
19
|
pycupra/firebase_messaging/mcs_pb2.pyi,sha256=HfIhInC3wRg8_caKwUm-V3knE2jTdEQvBy6uXgQ5rHY,33959
|
20
20
|
pycupra/firebase_messaging/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
21
|
-
pycupra-0.1.
|
22
|
-
pycupra-0.1.
|
23
|
-
pycupra-0.1.
|
24
|
-
pycupra-0.1.
|
25
|
-
pycupra-0.1.
|
21
|
+
pycupra-0.1.7.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
22
|
+
pycupra-0.1.7.dist-info/METADATA,sha256=hQAjfqNAkgF72DsnoCrLL6NtkF5_iIWY8mgc4ssgsCo,3757
|
23
|
+
pycupra-0.1.7.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
24
|
+
pycupra-0.1.7.dist-info/top_level.txt,sha256=9Lbj_jG4JvpGwt6K3AwhWFc0XieDnuHFOP4x44wSXSQ,8
|
25
|
+
pycupra-0.1.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|