pycupra 0.1.4__tar.gz → 0.1.5__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.
Files changed (37) hide show
  1. {pycupra-0.1.4/pycupra.egg-info → pycupra-0.1.5}/PKG-INFO +1 -1
  2. {pycupra-0.1.4 → pycupra-0.1.5}/example/PyCupra.py +26 -14
  3. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/__version__.py +1 -1
  4. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/connection.py +30 -13
  5. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/dashboard.py +2 -0
  6. pycupra-0.1.5/pycupra/firebase_messaging/android_checkin.proto +96 -0
  7. pycupra-0.1.5/pycupra/firebase_messaging/checkin.proto +155 -0
  8. pycupra-0.1.5/pycupra/firebase_messaging/mcs.proto +328 -0
  9. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/vehicle.py +39 -5
  10. {pycupra-0.1.4 → pycupra-0.1.5/pycupra.egg-info}/PKG-INFO +1 -1
  11. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra.egg-info/SOURCES.txt +3 -0
  12. {pycupra-0.1.4 → pycupra-0.1.5}/.gitignore +0 -0
  13. {pycupra-0.1.4 → pycupra-0.1.5}/LICENSE +0 -0
  14. {pycupra-0.1.4 → pycupra-0.1.5}/README.md +0 -0
  15. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/__init__.py +0 -0
  16. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/const.py +0 -0
  17. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/exceptions.py +0 -0
  18. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/firebase.py +0 -0
  19. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/firebase_messaging/__init__.py +0 -0
  20. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/firebase_messaging/android_checkin_pb2.py +0 -0
  21. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/firebase_messaging/android_checkin_pb2.pyi +0 -0
  22. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/firebase_messaging/checkin_pb2.py +0 -0
  23. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/firebase_messaging/checkin_pb2.pyi +0 -0
  24. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/firebase_messaging/const.py +0 -0
  25. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/firebase_messaging/fcmpushclient.py +0 -0
  26. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/firebase_messaging/fcmregister.py +0 -0
  27. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/firebase_messaging/mcs_pb2.py +0 -0
  28. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/firebase_messaging/mcs_pb2.pyi +0 -0
  29. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/firebase_messaging/py.typed +0 -0
  30. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra/utilities.py +0 -0
  31. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra.egg-info/dependency_links.txt +0 -0
  32. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra.egg-info/requires.txt +0 -0
  33. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra.egg-info/top_level.txt +0 -0
  34. {pycupra-0.1.4 → pycupra-0.1.5}/pycupra_credentials.json.demo +0 -0
  35. {pycupra-0.1.4 → pycupra-0.1.5}/requirements.txt +0 -0
  36. {pycupra-0.1.4 → pycupra-0.1.5}/setup.cfg +0 -0
  37. {pycupra-0.1.4 → pycupra-0.1.5}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pycupra
3
- Version: 0.1.4
3
+ Version: 0.1.5
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
@@ -177,7 +177,18 @@ async def demo_set_charger_current(vehicle, value="reduced"):
177
177
  print('########################################')
178
178
  print('# Change charging current #')
179
179
  print('########################################')
180
- success= await vehicle.set_charger_current(value) # value = "max" or "reduced".
180
+ success= await vehicle.set_charger_current(value)
181
+ if success:
182
+ print(" Request completed successfully.")
183
+ else:
184
+ print(" Request failed.")
185
+ return success
186
+
187
+ async def demo_set_charger_target_soc(vehicle, value=80):
188
+ print('########################################')
189
+ print('# Change target state of charge #')
190
+ print('########################################')
191
+ success= await vehicle.set_charger_target_soc(value)
181
192
  if success:
182
193
  print(" Request completed successfully.")
183
194
  else:
@@ -532,35 +543,36 @@ async def main():
532
543
 
533
544
  # Examples for using set functions:
534
545
 
535
- #await demo_set_charger(vehicle, action = "start") # action = "start" or "stop"
536
- #await demo_set_charger_current(vehicle, value='reduced') # value = 1-255/Maximum/Reduced (PHEV: 252 for reduced and 254 for max, EV: Maximum/Reduced)
546
+ #await demo_set_charger(vehicle, action = "start") # action = "start" or "stop"
547
+ #await demo_set_charger_current(vehicle, value='reduced') # value = 1-255/Maximum/Reduced (PHEV: 252 for reduced and 254 for max, EV: Maximum/Reduced)
548
+ #await demo_set_charger_target_soc(vehicle, value=70) # value = 1-100
537
549
 
538
- #await demo_set_climatisation(vehicle, action = "start", temp=18.0) # action = "auxilliary", "electric" or "off". spin is S-PIN and only needed for aux heating
539
- #await demo_set_climatisation_temp(vehicle, temp = 18.0) # temp = integer from 16 to 30
550
+ #await demo_set_climatisation(vehicle, action = "start", temp=18.0) # action = "auxilliary", "electric" or "off". spin is S-PIN and only needed for aux heating
551
+ #await demo_set_climatisation_temp(vehicle, temp = 18.0) # temp = integer from 16 to 30
540
552
  #await demo_set_battery_climatisation(vehicle, mode=False) # mode = False or True
541
- #await demo_set_windowheating(vehicle, action = "stop") # action = "start" or "stop"
553
+ #await demo_set_windowheating(vehicle, action = "stop") # action = "start" or "stop"
542
554
 
543
- #await demo_set_timer_schedule(vehicle) # arguments id and schedule can be found in the demo function
544
- #await demo_set_timer_active(vehicle, id=3, action="off") # id = 1, 2, 3, action = "on" or "off".
545
- #await demo_set_charge_limit(vehicle, 30) # limit = PHEV: 0/10/20/30/40/50, EV: 50/60/70/80/90/100
555
+ #await demo_set_timer_schedule(vehicle) # arguments id and schedule can be found in the demo function
556
+ #await demo_set_timer_active(vehicle, id=3, action="off") # id = 1, 2, 3, action = "on" or "off".
557
+ #await demo_set_charge_limit(vehicle, 30) # limit = PHEV: 0/10/20/30/40/50, EV: 50/60/70/80/90/100
546
558
 
547
- #await demo_set_departure_profile_schedule(vehicle) # arguments id and schedule can be found in the demo function
559
+ #await demo_set_departure_profile_schedule(vehicle) # arguments id and schedule can be found in the demo function
548
560
  #await demo_set_departure_profile_active(vehicle, id=3, action="off") # id = 1, 2, 3, action = "on" or "off".
549
561
 
550
562
  #await demo_set_lock(vehicle,action = "lock",
551
563
  # spin = credentials.get('spin','')) # action = "unlock" or "lock". spin = SPIN, needed for both
552
564
 
553
- #await vehicle.set_pheater(mode = "heating", spin = "1234") # action = "heating", "ventilation" or "off". spin = SPIN, not needed for off
565
+ #await vehicle.set_pheater(mode = "heating", spin = "1234") # action = "heating", "ventilation" or "off". spin = SPIN, not needed for off
554
566
 
555
- #await demo_set_honkandflash(vehicle, action="flash") # action = "honkandflash" or "flash"
567
+ #await demo_set_honkandflash(vehicle, action="flash") # action = "honkandflash" or "flash"
556
568
 
557
- #await vehicle.set_refresh() # Takes no arguments, will trigger forced update
569
+ #await vehicle.set_refresh() # Takes no arguments, will trigger forced update
558
570
 
559
571
  #print(f"Sleeping for {2*INTERVAL} seconds")
560
572
  #await asyncio.sleep(2*INTERVAL)
561
573
  #await demo_show_last_honkandflash_info(vehicle) # Returns the info of the last honkandflash_action
562
574
 
563
- #await demo_send_destination(vehicle) # arguments can be found in the demo function
575
+ #await demo_send_destination(vehicle) # arguments can be found in the demo function
564
576
 
565
577
  print('########################################')
566
578
  print('# Export all attributes to file #')
@@ -3,4 +3,4 @@ pycupra - A Python 3 library for interacting with the My Cupra/My Seat portal.
3
3
 
4
4
  For more details and documentation, visit the github page at https://github.com/WulfgarW/pycupra
5
5
  """
6
- __version__ = "0.1.4"
6
+ __version__ = "0.1.5"
@@ -1151,10 +1151,11 @@ class Connection:
1151
1151
  _LOGGER.warning(f'Could not fetch departure profiles, error: {error}')
1152
1152
  return False
1153
1153
 
1154
- async def getClimater(self, vin, baseurl):
1154
+ async def getClimater(self, vin, baseurl, oldClimatingData):
1155
1155
  """Get climatisation data."""
1156
- data={}
1157
- data['climater']={}
1156
+ #data={}
1157
+ #data['climater']={}
1158
+ data = {'climater': oldClimatingData}
1158
1159
  await self.set_token(self._session_auth_brand)
1159
1160
  try:
1160
1161
  response = await self.get(eval(f"f'{API_CLIMATER_STATUS}'"))
@@ -1180,12 +1181,14 @@ class Connection:
1180
1181
  return False
1181
1182
  return data
1182
1183
 
1183
- async def getCharger(self, vin, baseurl):
1184
+ async def getCharger(self, vin, baseurl, oldChargingData):
1184
1185
  """Get charger data."""
1185
1186
  await self.set_token(self._session_auth_brand)
1186
1187
  try:
1187
1188
  chargingStatus = {}
1188
1189
  chargingInfo = {}
1190
+ #chargingModes = {}
1191
+ #chargingProfiles = {}
1189
1192
  response = await self.get(eval(f"f'{API_CHARGING}/status'"))
1190
1193
  if response.get('battery', {}):
1191
1194
  chargingStatus = response
@@ -1207,16 +1210,30 @@ class Connection:
1207
1210
  _LOGGER.warning(f'Could not fetch charging modes, HTTP status code: {response.get("status_code")}')
1208
1211
  else:
1209
1212
  _LOGGER.info('Unhandled error while trying to fetch charging modes')"""
1210
- if chargingStatus != {} and chargingInfo != {}:
1211
- data = {'charging': {
1212
- 'status': chargingStatus,
1213
- 'info' : chargingInfo,
1214
- #'modes' : chargingModes,
1215
- }
1216
- }
1213
+ """response = await self.get(eval(f"f'{API_CHARGING}/profiles'"))
1214
+ if response.get('profiles', {}):
1215
+ chargingProfiles = response
1216
+ elif response.get('status_code', {}):
1217
+ _LOGGER.warning(f'Could not fetch charging profiles, HTTP status code: {response.get("status_code")}')
1218
+ else:
1219
+ _LOGGER.info('Unhandled error while trying to fetch charging profiles')"""
1220
+ data = {'charging': oldChargingData}
1221
+ if chargingStatus != {}:
1222
+ data['charging']['status'] = chargingStatus
1223
+ else:
1224
+ _LOGGER.warning(f'getCharger() got no valid data for charging status')
1225
+ if chargingInfo != {}:
1226
+ data['charging']['info'] = chargingInfo
1217
1227
  else:
1218
- _LOGGER.warning(f'getCharger() got no valid data. Returning None')
1219
- return None
1228
+ _LOGGER.warning(f'getCharger() got no valid data for charging info')
1229
+ #if chargingModes != {}:
1230
+ # data['charging']['modes'] = chargingModes
1231
+ #else:
1232
+ # _LOGGER.warning(f'getCharger() got no valid data for charging modes')
1233
+ #if chargingProfiles != {}:
1234
+ # data['charging']['profiles'] = chargingProfiles
1235
+ #else:
1236
+ # _LOGGER.warning(f'getCharger() got no valid data for charging profiles')
1220
1237
  return data
1221
1238
  except Exception as error:
1222
1239
  _LOGGER.warning(f'Could not fetch charger, error: {error}')
@@ -453,6 +453,7 @@ class RequestRefresh(Switch):
453
453
  return self.vehicle.refresh_data
454
454
 
455
455
  async def turn_on(self):
456
+ _LOGGER.debug('User has called RequestRefresh().')
456
457
  await self.vehicle.set_refresh()
457
458
  await self.vehicle.update(updateType=1) #full update after set_refresh
458
459
  if self.callback is not None:
@@ -479,6 +480,7 @@ class RequestUpdate(Switch):
479
480
  return False #self.vehicle.update
480
481
 
481
482
  async def turn_on(self):
483
+ _LOGGER.debug('User has called RequestUpdate().')
482
484
  await self.vehicle.update(updateType=1) #full update after set_refresh
483
485
  if self.callback is not None:
484
486
  self.callback()
@@ -0,0 +1,96 @@
1
+ // Copyright 2014 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+ //
5
+ // Logging information for Android "checkin" events (automatic, periodic
6
+ // requests made by Android devices to the server).
7
+
8
+ syntax = "proto2";
9
+
10
+ option optimize_for = LITE_RUNTIME;
11
+ package checkin_proto;
12
+
13
+ // Build characteristics unique to the Chrome browser, and Chrome OS
14
+ message ChromeBuildProto {
15
+ enum Platform {
16
+ PLATFORM_WIN = 1;
17
+ PLATFORM_MAC = 2;
18
+ PLATFORM_LINUX = 3;
19
+ PLATFORM_CROS = 4;
20
+ PLATFORM_IOS = 5;
21
+ // Just a placeholder. Likely don't need it due to the presence of the
22
+ // Android GCM on phone/tablet devices.
23
+ PLATFORM_ANDROID = 6;
24
+ }
25
+
26
+ enum Channel {
27
+ CHANNEL_STABLE = 1;
28
+ CHANNEL_BETA = 2;
29
+ CHANNEL_DEV = 3;
30
+ CHANNEL_CANARY = 4;
31
+ CHANNEL_UNKNOWN = 5; // for tip of tree or custom builds
32
+ }
33
+
34
+ // The platform of the device.
35
+ optional Platform platform = 1;
36
+
37
+ // The Chrome instance's version.
38
+ optional string chrome_version = 2;
39
+
40
+ // The Channel (build type) of Chrome.
41
+ optional Channel channel = 3;
42
+ }
43
+
44
+ // Information sent by the device in a "checkin" request.
45
+ message AndroidCheckinProto {
46
+ // Miliseconds since the Unix epoch of the device's last successful checkin.
47
+ optional int64 last_checkin_msec = 2;
48
+
49
+ // The current MCC+MNC of the mobile device's current cell.
50
+ optional string cell_operator = 6;
51
+
52
+ // The MCC+MNC of the SIM card (different from operator if the
53
+ // device is roaming, for instance).
54
+ optional string sim_operator = 7;
55
+
56
+ // The device's current roaming state (reported starting in eclair builds).
57
+ // Currently one of "{,not}mobile-{,not}roaming", if it is present at all.
58
+ optional string roaming = 8;
59
+
60
+ // For devices supporting multiple user profiles (which may be
61
+ // supported starting in jellybean), the ordinal number of the
62
+ // profile that is checking in. This is 0 for the primary profile
63
+ // (which can't be changed without wiping the device), and 1,2,3,...
64
+ // for additional profiles (which can be added and deleted freely).
65
+ optional int32 user_number = 9;
66
+
67
+ // Class of device. Indicates the type of build proto
68
+ // (IosBuildProto/ChromeBuildProto/AndroidBuildProto)
69
+ // That is included in this proto
70
+ optional DeviceType type = 12 [default = DEVICE_ANDROID_OS];
71
+
72
+ // For devices running MCS on Chrome, build-specific characteristics
73
+ // of the browser. There are no hardware aspects (except for ChromeOS).
74
+ // This will only be populated for Chrome builds/ChromeOS devices
75
+ optional checkin_proto.ChromeBuildProto chrome_build = 13;
76
+
77
+ // Note: Some of the Android specific optional fields were skipped to limit
78
+ // the protobuf definition.
79
+ // Next 14
80
+ }
81
+
82
+ // enum values correspond to the type of device.
83
+ // Used in the AndroidCheckinProto and Device proto.
84
+ enum DeviceType {
85
+ // Android Device
86
+ DEVICE_ANDROID_OS = 1;
87
+
88
+ // Apple IOS device
89
+ DEVICE_IOS_OS = 2;
90
+
91
+ // Chrome browser - Not Chrome OS. No hardware records.
92
+ DEVICE_CHROME_BROWSER = 3;
93
+
94
+ // Chrome OS
95
+ DEVICE_CHROME_OS = 4;
96
+ }
@@ -0,0 +1,155 @@
1
+ // Copyright 2014 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+ //
5
+ // Request and reply to the "checkin server" devices poll every few hours.
6
+
7
+ syntax = "proto2";
8
+
9
+ option optimize_for = LITE_RUNTIME;
10
+
11
+ package checkin_proto;
12
+
13
+ import "android_checkin.proto";
14
+
15
+ // A concrete name/value pair sent to the device's Gservices database.
16
+ message GservicesSetting {
17
+ required bytes name = 1;
18
+ required bytes value = 2;
19
+ }
20
+
21
+ // Devices send this every few hours to tell us how they're doing.
22
+ message AndroidCheckinRequest {
23
+ // IMEI (used by GSM phones) is sent and stored as 15 decimal
24
+ // digits; the 15th is a check digit.
25
+ optional string imei = 1; // IMEI, reported but not logged.
26
+
27
+ // MEID (used by CDMA phones) is sent and stored as 14 hexadecimal
28
+ // digits (no check digit).
29
+ optional string meid = 10; // MEID, reported but not logged.
30
+
31
+ // MAC address (used by non-phone devices). 12 hexadecimal digits;
32
+ // no separators (eg "0016E6513AC2", not "00:16:E6:51:3A:C2").
33
+ repeated string mac_addr = 9; // MAC address, reported but not logged.
34
+
35
+ // An array parallel to mac_addr, describing the type of interface.
36
+ // Currently accepted values: "wifi", "ethernet", "bluetooth". If
37
+ // not present, "wifi" is assumed.
38
+ repeated string mac_addr_type = 19;
39
+
40
+ // Serial number (a manufacturer-defined unique hardware
41
+ // identifier). Alphanumeric, case-insensitive.
42
+ optional string serial_number = 16;
43
+
44
+ // Older CDMA networks use an ESN (8 hex digits) instead of an MEID.
45
+ optional string esn = 17; // ESN, reported but not logged
46
+
47
+ optional int64 id = 2; // Android device ID, not logged
48
+ optional int64 logging_id = 7; // Pseudonymous logging ID for Sawmill
49
+ optional string digest = 3; // Digest of device provisioning, not logged.
50
+ optional string locale = 6; // Current locale in standard (xx_XX) format
51
+ required AndroidCheckinProto checkin = 4;
52
+
53
+ // DEPRECATED, see AndroidCheckinProto.requested_group
54
+ optional string desired_build = 5;
55
+
56
+ // Blob of data from the Market app to be passed to Market API server
57
+ optional string market_checkin = 8;
58
+
59
+ // SID cookies of any google accounts stored on the phone. Not logged.
60
+ repeated string account_cookie = 11;
61
+
62
+ // Time zone. Not currently logged.
63
+ optional string time_zone = 12;
64
+
65
+ // Security token used to validate the checkin request.
66
+ // Required for android IDs issued to Froyo+ devices, not for legacy IDs.
67
+ optional fixed64 security_token = 13;
68
+
69
+ // Version of checkin protocol.
70
+ //
71
+ // There are currently two versions:
72
+ //
73
+ // - version field missing: android IDs are assigned based on
74
+ // hardware identifiers. unsecured in the sense that you can
75
+ // "unregister" someone's phone by sending a registration request
76
+ // with their IMEI/MEID/MAC.
77
+ //
78
+ // - version=2: android IDs are assigned randomly. The device is
79
+ // sent a security token that must be included in all future
80
+ // checkins for that android id.
81
+ //
82
+ // - version=3: same as version 2, but the 'fragment' field is
83
+ // provided, and the device understands incremental updates to the
84
+ // gservices table (ie, only returning the keys whose values have
85
+ // changed.)
86
+ //
87
+ // (version=1 was skipped to avoid confusion with the "missing"
88
+ // version field that is effectively version 1.)
89
+ optional int32 version = 14;
90
+
91
+ // OTA certs accepted by device (base-64 SHA-1 of cert files). Not
92
+ // logged.
93
+ repeated string ota_cert = 15;
94
+
95
+ // Honeycomb and newer devices send configuration data with their checkin.
96
+ // optional DeviceConfigurationProto device_configuration = 18;
97
+
98
+ // A single CheckinTask on the device may lead to multiple checkin
99
+ // requests if there is too much log data to upload in a single
100
+ // request. For version 3 and up, this field will be filled in with
101
+ // the number of the request, starting with 0.
102
+ optional int32 fragment = 20;
103
+
104
+ // For devices supporting multiple users, the name of the current
105
+ // profile (they all check in independently, just as if they were
106
+ // multiple physical devices). This may not be set, even if the
107
+ // device is using multiuser. (checkin.user_number should be set to
108
+ // the ordinal of the user.)
109
+ optional string user_name = 21;
110
+
111
+ // For devices supporting multiple user profiles, the serial number
112
+ // for the user checking in. Not logged. May not be set, even if
113
+ // the device supportes multiuser. checkin.user_number is the
114
+ // ordinal of the user (0, 1, 2, ...), which may be reused if users
115
+ // are deleted and re-created. user_serial_number is never reused
116
+ // (unless the device is wiped).
117
+ optional int32 user_serial_number = 22;
118
+
119
+ // NEXT TAG: 23
120
+ }
121
+
122
+ // The response to the device.
123
+ message AndroidCheckinResponse {
124
+ required bool stats_ok = 1; // Whether statistics were recorded properly.
125
+ optional int64 time_msec = 3; // Time of day from server (Java epoch).
126
+ // repeated AndroidIntentProto intent = 2;
127
+
128
+ // Provisioning is sent if the request included an obsolete digest.
129
+ //
130
+ // For version <= 2, 'digest' contains the digest that should be
131
+ // sent back to the server on the next checkin, and 'setting'
132
+ // contains the entire gservices table (which replaces the entire
133
+ // current table on the device).
134
+ //
135
+ // for version >= 3, 'digest' will be absent. If 'settings_diff'
136
+ // is false, then 'setting' contains the entire table, as in version
137
+ // 2. If 'settings_diff' is true, then 'delete_setting' contains
138
+ // the keys to delete, and 'setting' contains only keys to be added
139
+ // or for which the value has changed. All other keys in the
140
+ // current table should be left untouched. If 'settings_diff' is
141
+ // absent, don't touch the existing gservices table.
142
+ //
143
+ optional string digest = 4;
144
+ optional bool settings_diff = 9;
145
+ repeated string delete_setting = 10;
146
+ repeated GservicesSetting setting = 5;
147
+
148
+ optional bool market_ok = 6; // If Market got the market_checkin data OK.
149
+
150
+ optional fixed64 android_id = 7; // From the request, or newly assigned
151
+ optional fixed64 security_token = 8; // The associated security token
152
+
153
+ optional string version_info = 11;
154
+ // NEXT TAG: 12
155
+ }
@@ -0,0 +1,328 @@
1
+ // Copyright 2013 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+ //
5
+ // MCS protocol for communication between Chrome client and Mobile Connection
6
+ // Server .
7
+
8
+ syntax = "proto2";
9
+
10
+ option optimize_for = LITE_RUNTIME;
11
+
12
+ package mcs_proto;
13
+
14
+ /*
15
+ Common fields/comments:
16
+
17
+ stream_id: no longer sent by server, each side keeps a counter
18
+ last_stream_id_received: sent only if a packet was received since last time
19
+ a last_stream was sent
20
+ status: new bitmask including the 'idle' as bit 0.
21
+
22
+ */
23
+
24
+ /**
25
+ TAG: 0
26
+ */
27
+ message HeartbeatPing {
28
+ optional int32 stream_id = 1;
29
+ optional int32 last_stream_id_received = 2;
30
+ optional int64 status = 3;
31
+ }
32
+
33
+ /**
34
+ TAG: 1
35
+ */
36
+ message HeartbeatAck {
37
+ optional int32 stream_id = 1;
38
+ optional int32 last_stream_id_received = 2;
39
+ optional int64 status = 3;
40
+ }
41
+
42
+ message ErrorInfo {
43
+ required int32 code = 1;
44
+ optional string message = 2;
45
+ optional string type = 3;
46
+ optional Extension extension = 4;
47
+ }
48
+
49
+ // MobileSettings class.
50
+ // "u:f", "u:b", "u:s" - multi user devices reporting foreground, background
51
+ // and stopped users.
52
+ // hbping: heatbeat ping interval
53
+ // rmq2v: include explicit stream IDs
54
+
55
+ message Setting {
56
+ required string name = 1;
57
+ required string value = 2;
58
+ }
59
+
60
+ message HeartbeatStat {
61
+ required string ip = 1;
62
+ required bool timeout = 2;
63
+ required int32 interval_ms = 3;
64
+ }
65
+
66
+ message HeartbeatConfig {
67
+ optional bool upload_stat = 1;
68
+ optional string ip = 2;
69
+ optional int32 interval_ms = 3;
70
+ }
71
+
72
+ // ClientEvents are used to inform the server of failed and successful
73
+ // connections.
74
+ message ClientEvent {
75
+ enum Type {
76
+ UNKNOWN = 0;
77
+ // Count of discarded events if the buffer filled up and was trimmed.
78
+ DISCARDED_EVENTS = 1;
79
+ // Failed connection event: the connection failed to be established or we
80
+ // had a login error.
81
+ FAILED_CONNECTION = 2;
82
+ // Successful connection event: information about the last successful
83
+ // connection, including the time at which it was established.
84
+ SUCCESSFUL_CONNECTION = 3;
85
+ }
86
+
87
+ // Common fields [1-99]
88
+ optional Type type = 1;
89
+
90
+ // Fields for DISCARDED_EVENTS messages [100-199]
91
+ optional uint32 number_discarded_events = 100;
92
+
93
+ // Fields for FAILED_CONNECTION and SUCCESSFUL_CONNECTION messages [200-299]
94
+ // Network type is a value in net::NetworkChangeNotifier::ConnectionType.
95
+ optional int32 network_type = 200;
96
+ // Reserved for network_port.
97
+ reserved 201;
98
+ optional uint64 time_connection_started_ms = 202;
99
+ optional uint64 time_connection_ended_ms = 203;
100
+ // Error code should be a net::Error value.
101
+ optional int32 error_code = 204;
102
+
103
+ // Fields for SUCCESSFUL_CONNECTION messages [300-399]
104
+ optional uint64 time_connection_established_ms = 300;
105
+ }
106
+
107
+ /**
108
+ TAG: 2
109
+ */
110
+ message LoginRequest {
111
+ enum AuthService {
112
+ ANDROID_ID = 2;
113
+ }
114
+ required string id = 1; // Must be present ( proto required ), may be empty
115
+ // string.
116
+ // mcs.android.com.
117
+ required string domain = 2;
118
+ // Decimal android ID
119
+ required string user = 3;
120
+
121
+ required string resource = 4;
122
+
123
+ // Secret
124
+ required string auth_token = 5;
125
+
126
+ // Format is: android-HEX_DEVICE_ID
127
+ // The user is the decimal value.
128
+ optional string device_id = 6;
129
+
130
+ // RMQ1 - no longer used
131
+ optional int64 last_rmq_id = 7;
132
+
133
+ repeated Setting setting = 8;
134
+ //optional int32 compress = 9;
135
+ repeated string received_persistent_id = 10;
136
+
137
+ // Replaced by "rmq2v" setting
138
+ // optional bool include_stream_ids = 11;
139
+
140
+ optional bool adaptive_heartbeat = 12;
141
+ optional HeartbeatStat heartbeat_stat = 13;
142
+ // Must be true.
143
+ optional bool use_rmq2 = 14;
144
+ optional int64 account_id = 15;
145
+
146
+ // ANDROID_ID = 2
147
+ optional AuthService auth_service = 16;
148
+
149
+ optional int32 network_type = 17;
150
+ optional int64 status = 18;
151
+
152
+ // 19, 20, and 21 are not currently populated by Chrome.
153
+ reserved 19, 20, 21;
154
+
155
+ // Events recorded on the client after the last successful connection.
156
+ repeated ClientEvent client_event = 22;
157
+ }
158
+
159
+ /**
160
+ * TAG: 3
161
+ */
162
+ message LoginResponse {
163
+ required string id = 1;
164
+ // Not used.
165
+ optional string jid = 2;
166
+ // Null if login was ok.
167
+ optional ErrorInfo error = 3;
168
+ repeated Setting setting = 4;
169
+ optional int32 stream_id = 5;
170
+ // Should be "1"
171
+ optional int32 last_stream_id_received = 6;
172
+ optional HeartbeatConfig heartbeat_config = 7;
173
+ // used by the client to synchronize with the server timestamp.
174
+ optional int64 server_timestamp = 8;
175
+ }
176
+
177
+ message StreamErrorStanza {
178
+ required string type = 1;
179
+ optional string text = 2;
180
+ }
181
+
182
+ /**
183
+ * TAG: 4
184
+ */
185
+ message Close {
186
+ }
187
+
188
+ message Extension {
189
+ // 12: SelectiveAck
190
+ // 13: StreamAck
191
+ required int32 id = 1;
192
+ required bytes data = 2;
193
+ }
194
+
195
+ /**
196
+ * TAG: 7
197
+ * IqRequest must contain a single extension. IqResponse may contain 0 or 1
198
+ * extensions.
199
+ */
200
+ message IqStanza {
201
+ enum IqType {
202
+ GET = 0;
203
+ SET = 1;
204
+ RESULT = 2;
205
+ IQ_ERROR = 3;
206
+ }
207
+
208
+ optional int64 rmq_id = 1;
209
+ required IqType type = 2;
210
+ required string id = 3;
211
+ optional string from = 4;
212
+ optional string to = 5;
213
+ optional ErrorInfo error = 6;
214
+
215
+ // Only field used in the 38+ protocol (besides common last_stream_id_received, status, rmq_id)
216
+ optional Extension extension = 7;
217
+
218
+ optional string persistent_id = 8;
219
+ optional int32 stream_id = 9;
220
+ optional int32 last_stream_id_received = 10;
221
+ optional int64 account_id = 11;
222
+ optional int64 status = 12;
223
+ }
224
+
225
+ message AppData {
226
+ required string key = 1;
227
+ required string value = 2;
228
+ }
229
+
230
+ /**
231
+ * TAG: 8
232
+ */
233
+ message DataMessageStanza {
234
+ // Not used.
235
+ // optional int64 rmq_id = 1;
236
+
237
+ // This is the message ID, set by client, DMP.9 (message_id)
238
+ optional string id = 2;
239
+
240
+ // Project ID of the sender, DMP.1
241
+ required string from = 3;
242
+
243
+ // Part of DMRequest - also the key in DataMessageProto.
244
+ optional string to = 4;
245
+
246
+ // Package name. DMP.2
247
+ required string category = 5;
248
+
249
+ // The collapsed key, DMP.3
250
+ optional string token = 6;
251
+
252
+ // User data + GOOGLE. prefixed special entries, DMP.4
253
+ repeated AppData app_data = 7;
254
+
255
+ // Not used.
256
+ optional bool from_trusted_server = 8;
257
+
258
+ // Part of the ACK protocol, returned in DataMessageResponse on server side.
259
+ // It's part of the key of DMP.
260
+ optional string persistent_id = 9;
261
+
262
+ // In-stream ack. Increments on each message sent - a bit redundant
263
+ // Not used in DMP/DMR.
264
+ optional int32 stream_id = 10;
265
+ optional int32 last_stream_id_received = 11;
266
+
267
+ // Not used.
268
+ // optional string permission = 12;
269
+
270
+ // Sent by the device shortly after registration.
271
+ optional string reg_id = 13;
272
+
273
+ // Not used.
274
+ // optional string pkg_signature = 14;
275
+ // Not used.
276
+ // optional string client_id = 15;
277
+
278
+ // serial number of the target user, DMP.8
279
+ // It is the 'serial number' according to user manager.
280
+ optional int64 device_user_id = 16;
281
+
282
+ // Time to live, in seconds.
283
+ optional int32 ttl = 17;
284
+ // Timestamp ( according to client ) when message was sent by app, in seconds
285
+ optional int64 sent = 18;
286
+
287
+ // How long has the message been queued before the flush, in seconds.
288
+ // This is needed to account for the time difference between server and
289
+ // client: server should adjust 'sent' based on its 'receive' time.
290
+ optional int32 queued = 19;
291
+
292
+ optional int64 status = 20;
293
+
294
+ // Optional field containing the binary payload of the message.
295
+ optional bytes raw_data = 21;
296
+
297
+ // Not used.
298
+ // The maximum delay of the message, in seconds.
299
+ // optional int32 max_delay = 22;
300
+
301
+ // Not used.
302
+ // How long the message was delayed before it was sent, in seconds.
303
+ // optional int32 actual_delay = 23;
304
+
305
+ // If set the server requests immediate ack. Used for important messages and
306
+ // for testing.
307
+ optional bool immediate_ack = 24;
308
+
309
+ // Not used.
310
+ // Enables message receipts from MCS/GCM back to CCS clients
311
+ // optional bool delivery_receipt_requested = 25;
312
+ }
313
+
314
+ /**
315
+ Included in IQ with ID 13, sent from client or server after 10 unconfirmed
316
+ messages.
317
+ */
318
+ message StreamAck {
319
+ // No last_streamid_received required. This is included within an IqStanza,
320
+ // which includes the last_stream_id_received.
321
+ }
322
+
323
+ /**
324
+ Included in IQ sent after LoginResponse from server with ID 12.
325
+ */
326
+ message SelectiveAck {
327
+ repeated string id = 1;
328
+ }
@@ -76,6 +76,7 @@ class Vehicle:
76
76
  'vehicleHealthWarnings': {'active': False, 'reason': 'not supported'},
77
77
  'state': {'active': False, 'reason': 'not supported'},
78
78
  'charging': {'active': False, 'reason': 'not supported', 'supportsTargetStateOfCharge': False},
79
+ 'chargingProfiles': {'active': False, 'reason': 'not supported', "supportsTimerClimatisation": False,"supportsVehiclePositionedInProfileID": False,"supportsSingleTimer": False},
79
80
  'honkAndFlash': {'active': False, 'reason': 'not supported'},
80
81
  'parkingPosition': {'active': False, 'reason': 'not supported'},
81
82
  'departureTimers': {'active': False, 'reason': 'not supported', 'supportsSingleTimer': False},
@@ -121,6 +122,10 @@ class Vehicle:
121
122
  data['supportsTargetStateOfCharge']=True
122
123
  if capa['parameters'].get('supportsSingleTimer',False)==True or capa['parameters'].get('supportsSingleTimer',False)=='true':
123
124
  data['supportsSingleTimer']=True
125
+ if capa['parameters'].get('supportsVehiclePositionedInProfileID',False)==True or capa['parameters'].get('supportsVehiclePositionedInProfileID',False)=='true':
126
+ data['supportsVehiclePositionedInProfileID']=True
127
+ if capa['parameters'].get('supportsTimerClimatisation',False)==True or capa['parameters'].get('supportsTimerClimatisation',False)=='true':
128
+ data['supportsTimerClimatisation']=True
124
129
  self._relevantCapabilties[id].update(data)
125
130
 
126
131
 
@@ -245,7 +250,7 @@ class Vehicle:
245
250
  async def get_climater(self):
246
251
  """Fetch climater data if function is enabled."""
247
252
  if self._relevantCapabilties.get('climatisation', {}).get('active', False):
248
- data = await self._connection.getClimater(self.vin, self._apibase)
253
+ data = await self._connection.getClimater(self.vin, self._apibase, deepcopy(self.attrs.get('climater',{})))
249
254
  if data:
250
255
  self._states.update(data)
251
256
  self._last_get_climater = datetime.now(tz=None)
@@ -311,7 +316,7 @@ class Vehicle:
311
316
  async def get_charger(self):
312
317
  """Fetch charger data if function is enabled."""
313
318
  if self._relevantCapabilties.get('charging', {}).get('active', False):
314
- data = await self._connection.getCharger(self.vin, self._apibase)
319
+ data = await self._connection.getCharger(self.vin, self._apibase, deepcopy(self.attrs.get('charging',{})))
315
320
  if data:
316
321
  self._states.update(data)
317
322
  self._last_get_charger = datetime.now(tz=None)
@@ -396,6 +401,33 @@ class Vehicle:
396
401
  _LOGGER.error('No charger support.')
397
402
  raise SeatInvalidRequestException('No charger support.')
398
403
 
404
+ async def set_charger_target_soc(self, value):
405
+ """Set target state of charge"""
406
+ if self.is_charging_supported:
407
+ if isinstance(value, int):
408
+ if 1 <= int(value) <= 100:
409
+ # VW-Group API charger current request
410
+ if self._relevantCapabilties.get('charging', {}).get('active', False) and self._relevantCapabilties.get('charging', {}).get('supportsTargetStateOfCharge', False):
411
+ data= deepcopy(self.attrs.get('charging',{}).get('info',{}).get('settings',{}))
412
+ if data=={}:
413
+ _LOGGER.error(f'Can not set target soc, because currently no charging settings are present.')
414
+ raise SeatInvalidRequestException(f'Set target soc not possible. Charging settings not present.')
415
+ data['targetSoc'] = int(value)
416
+ else:
417
+ _LOGGER.warning(f'Can not set target soc, because vehicle does not support this feature.')
418
+ return False
419
+ else:
420
+ _LOGGER.error(f'Set target soc to {value} is not supported.')
421
+ raise SeatInvalidRequestException(f'Set target soc to {value} is not supported.')
422
+ # Mimick app and set charger max ampere to Maximum/Reduced
423
+ else:
424
+ _LOGGER.error(f'Data type passed is invalid.')
425
+ raise SeatInvalidRequestException(f'Invalid data type.')
426
+ return await self.set_charger('settings', data)
427
+ else:
428
+ _LOGGER.error('No charger support.')
429
+ raise SeatInvalidRequestException('No charger support.')
430
+
399
431
  async def set_charger(self, action, data=None):
400
432
  """Charging actions."""
401
433
  if not self._relevantCapabilties.get('charging', {}).get('active', False):
@@ -450,9 +482,11 @@ class Vehicle:
450
482
  if not self.charging:
451
483
  actionSuccessful = True
452
484
  elif mode == 'settings':
485
+ if data.get('targetSoc',0) == self.target_soc: # In case targetSoc is changed
486
+ actionSuccessful = True
453
487
  if data.get('maxChargeCurrentAc','') == self.charge_max_ampere: # In case 'maximum', 'reduced'
454
488
  actionSuccessful = True
455
- if data.get('maxChargeCurrentAcInAmperes',0) == self.charge_max_ampere: # In case of a numerical value
489
+ if data.get('maxChargeCurrentAcInAmperes',0) == self.charge_max_ampere: # In case of a numerical value for charge current
456
490
  actionSuccessful = True
457
491
  else:
458
492
  _LOGGER.error(f'Missing code in vehicle._set_charger() for mode {mode}')
@@ -3150,7 +3184,7 @@ class Vehicle:
3150
3184
  self.storeFirebaseNotifications(obj, notification, data_message)
3151
3185
 
3152
3186
  if self.firebaseStatus != FIREBASE_STATUS_ACTIVATED:
3153
- _LOGGER.info(f'While firebase is not fully activated, received notifications are just acknoledged.')
3187
+ _LOGGER.info(f'While firebase is not fully activated, received notifications are just acknowledged.')
3154
3188
  # As long as the firebase status is not set to activated, ignore the notifications
3155
3189
  return False
3156
3190
 
@@ -3200,7 +3234,7 @@ class Vehicle:
3200
3234
  await self.get_departure_profiles()
3201
3235
  if self.updateCallback:
3202
3236
  await self.updateCallback(2)
3203
- elif type in ('charging-status-changed', 'charging-started', 'charging-stopped'):
3237
+ elif type in ('charging-status-changed', 'charging-started', 'charging-stopped', 'charging-settings-updated'):
3204
3238
  if self._requests.get('batterycharge', {}).get('id', None):
3205
3239
  openRequest= self._requests.get('batterycharge', {}).get('id', None)
3206
3240
  if openRequest == requestId:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pycupra
3
- Version: 0.1.4
3
+ Version: 0.1.5
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
@@ -21,13 +21,16 @@ pycupra.egg-info/dependency_links.txt
21
21
  pycupra.egg-info/requires.txt
22
22
  pycupra.egg-info/top_level.txt
23
23
  pycupra/firebase_messaging/__init__.py
24
+ pycupra/firebase_messaging/android_checkin.proto
24
25
  pycupra/firebase_messaging/android_checkin_pb2.py
25
26
  pycupra/firebase_messaging/android_checkin_pb2.pyi
27
+ pycupra/firebase_messaging/checkin.proto
26
28
  pycupra/firebase_messaging/checkin_pb2.py
27
29
  pycupra/firebase_messaging/checkin_pb2.pyi
28
30
  pycupra/firebase_messaging/const.py
29
31
  pycupra/firebase_messaging/fcmpushclient.py
30
32
  pycupra/firebase_messaging/fcmregister.py
33
+ pycupra/firebase_messaging/mcs.proto
31
34
  pycupra/firebase_messaging/mcs_pb2.py
32
35
  pycupra/firebase_messaging/mcs_pb2.pyi
33
36
  pycupra/firebase_messaging/py.typed
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes