carconnectivity-connector-skoda 0.2a4__tar.gz → 0.3__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.

Potentially problematic release.


This version of carconnectivity-connector-skoda might be problematic. Click here for more details.

Files changed (42) hide show
  1. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/CHANGELOG.md +8 -1
  2. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/PKG-INFO +2 -2
  3. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/pyproject.toml +1 -1
  4. carconnectivity_connector_skoda-0.3/setup_requirements.txt +6 -0
  5. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connector_skoda.egg-info/PKG-INFO +2 -2
  6. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connector_skoda.egg-info/SOURCES.txt +1 -0
  7. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connector_skoda.egg-info/requires.txt +1 -1
  8. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connectors/skoda/_version.py +2 -2
  9. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connectors/skoda/connector.py +55 -67
  10. carconnectivity_connector_skoda-0.3/src/carconnectivity_connectors/skoda/ui/connector_ui.py +39 -0
  11. carconnectivity_connector_skoda-0.2a4/setup_requirements.txt +0 -3
  12. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/.flake8 +0 -0
  13. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  14. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  15. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/.github/dependabot.yml +0 -0
  16. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/.github/workflows/build.yml +0 -0
  17. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/.github/workflows/build_and_publish.yml +0 -0
  18. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/.github/workflows/codeql-analysis.yml +0 -0
  19. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/.gitignore +0 -0
  20. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/LICENSE +0 -0
  21. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/Makefile +0 -0
  22. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/README.md +0 -0
  23. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/doc/Config.md +0 -0
  24. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/setup.cfg +0 -0
  25. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connector_skoda.egg-info/dependency_links.txt +0 -0
  26. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connector_skoda.egg-info/top_level.txt +0 -0
  27. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connectors/skoda/__init__.py +0 -0
  28. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connectors/skoda/auth/__init__.py +0 -0
  29. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connectors/skoda/auth/auth_util.py +0 -0
  30. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connectors/skoda/auth/helpers/blacklist_retry.py +0 -0
  31. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connectors/skoda/auth/my_skoda_session.py +0 -0
  32. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connectors/skoda/auth/openid_session.py +0 -0
  33. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connectors/skoda/auth/session_manager.py +0 -0
  34. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connectors/skoda/auth/skoda_web_session.py +0 -0
  35. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connectors/skoda/capability.py +0 -0
  36. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connectors/skoda/charging.py +0 -0
  37. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connectors/skoda/climatization.py +0 -0
  38. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connectors/skoda/command_impl.py +0 -0
  39. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connectors/skoda/error.py +0 -0
  40. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connectors/skoda/mqtt_client.py +0 -0
  41. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/src/carconnectivity_connectors/skoda/vehicle.py +0 -0
  42. {carconnectivity_connector_skoda-0.2a4 → carconnectivity_connector_skoda-0.3}/test/integration_test/carConnectivity.json +0 -0
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
5
5
  ## [Unreleased]
6
6
  - No unreleased changes so far
7
7
 
8
+ ## [0.3] - 2025-02-19
9
+ ### Added
10
+ - Added support for images
11
+ - Added tags to attributes
12
+ - Added support for webui via carconnectivity-plugin-webui
13
+
8
14
  ## [0.2] - 2025-02-02
9
15
  ### Added
10
16
  - Wake Sleep command
@@ -13,6 +19,7 @@ All notable changes to this project will be documented in this file.
13
19
  Initial release, let's go and give this to the public to try out...
14
20
  The API is not yet implemented completely but most functions already work
15
21
 
16
- [unreleased]: https://github.com/tillsteinbach/CarConnectivity-connector-skoda/compare/v0.2...HEAD
22
+ [unreleased]: https://github.com/tillsteinbach/CarConnectivity-connector-skoda/compare/v0.3...HEAD
23
+ [0.3]: https://github.com/tillsteinbach/CarConnectivity-connector-skoda/releases/tag/v0.3
17
24
  [0.2]: https://github.com/tillsteinbach/CarConnectivity-connector-skoda/releases/tag/v0.2
18
25
  [0.1]: https://github.com/tillsteinbach/CarConnectivity-connector-skoda/releases/tag/v0.1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: carconnectivity-connector-skoda
3
- Version: 0.2a4
3
+ Version: 0.3
4
4
  Summary: CarConnectivity connector for Skoda services
5
5
  Author: Till Steinbach
6
6
  License: MIT License
@@ -37,7 +37,7 @@ Classifier: Topic :: Software Development :: Libraries
37
37
  Requires-Python: >=3.8
38
38
  Description-Content-Type: text/markdown
39
39
  License-File: LICENSE
40
- Requires-Dist: carconnectivity>=0.3a2
40
+ Requires-Dist: carconnectivity>=0.3
41
41
  Requires-Dist: oauthlib~=3.2.2
42
42
  Requires-Dist: requests~=2.32.3
43
43
  Requires-Dist: jwt~=1.3.1
@@ -14,7 +14,7 @@ authors = [
14
14
  { name = "Till Steinbach" }
15
15
  ]
16
16
  dependencies = [
17
- "carconnectivity>=0.3a2",
17
+ "carconnectivity>=0.3",
18
18
  "oauthlib~=3.2.2",
19
19
  "requests~=2.32.3",
20
20
  "jwt~=1.3.1",
@@ -0,0 +1,6 @@
1
+ flake8~=7.1.2
2
+ pylint~=3.3.4
3
+ bandit~=1.8.3
4
+
5
+ # For UI only
6
+ Flask~=3.1.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: carconnectivity-connector-skoda
3
- Version: 0.2a4
3
+ Version: 0.3
4
4
  Summary: CarConnectivity connector for Skoda services
5
5
  Author: Till Steinbach
6
6
  License: MIT License
@@ -37,7 +37,7 @@ Classifier: Topic :: Software Development :: Libraries
37
37
  Requires-Python: >=3.8
38
38
  Description-Content-Type: text/markdown
39
39
  License-File: LICENSE
40
- Requires-Dist: carconnectivity>=0.3a2
40
+ Requires-Dist: carconnectivity>=0.3
41
41
  Requires-Dist: oauthlib~=3.2.2
42
42
  Requires-Dist: requests~=2.32.3
43
43
  Requires-Dist: jwt~=1.3.1
@@ -35,4 +35,5 @@ src/carconnectivity_connectors/skoda/auth/openid_session.py
35
35
  src/carconnectivity_connectors/skoda/auth/session_manager.py
36
36
  src/carconnectivity_connectors/skoda/auth/skoda_web_session.py
37
37
  src/carconnectivity_connectors/skoda/auth/helpers/blacklist_retry.py
38
+ src/carconnectivity_connectors/skoda/ui/connector_ui.py
38
39
  test/integration_test/carConnectivity.json
@@ -1,4 +1,4 @@
1
- carconnectivity>=0.3a2
1
+ carconnectivity>=0.3
2
2
  oauthlib~=3.2.2
3
3
  requests~=2.32.3
4
4
  jwt~=1.3.1
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.2a4'
16
- __version_tuple__ = version_tuple = (0, 2)
15
+ __version__ = version = '0.3'
16
+ __version_tuple__ = version_tuple = (0, 3)
@@ -15,7 +15,7 @@ import requests
15
15
  from carconnectivity.garage import Garage
16
16
  from carconnectivity.vehicle import GenericVehicle
17
17
  from carconnectivity.errors import AuthenticationError, TooManyRequestsError, RetrievalError, APIError, APICompatibilityError, \
18
- TemporaryAuthenticationError, ConfigurationError, SetterError, CommandError
18
+ TemporaryAuthenticationError, SetterError, CommandError
19
19
  from carconnectivity.util import robust_time_parse, log_extra_keys, config_remove_credentials
20
20
  from carconnectivity.units import Length, Speed, Power, Temperature
21
21
  from carconnectivity.doors import Doors
@@ -71,7 +71,7 @@ class Connector(BaseConnector):
71
71
  max_age (Optional[int]): Maximum age for cached data in seconds.
72
72
  """
73
73
  def __init__(self, connector_id: str, car_connectivity: CarConnectivity, config: Dict) -> None:
74
- BaseConnector.__init__(self, connector_id=connector_id, car_connectivity=car_connectivity, config=config)
74
+ BaseConnector.__init__(self, connector_id=connector_id, car_connectivity=car_connectivity, config=config, log=LOG, api_log=LOG_API)
75
75
 
76
76
  self._mqtt_client: SkodaMQTTClient = SkodaMQTTClient(skoda_connector=self)
77
77
 
@@ -85,77 +85,62 @@ class Connector(BaseConnector):
85
85
 
86
86
  self.user_id: Optional[str] = None
87
87
 
88
- # Configure logging
89
- if 'log_level' in config and config['log_level'] is not None:
90
- config['log_level'] = config['log_level'].upper()
91
- if config['log_level'] in logging._nameToLevel:
92
- LOG.setLevel(config['log_level'])
93
- self.log_level._set_value(config['log_level']) # pylint: disable=protected-access
94
- logging.getLogger('requests').setLevel(config['log_level'])
95
- logging.getLogger('urllib3').setLevel(config['log_level'])
96
- logging.getLogger('oauthlib').setLevel(config['log_level'])
97
- else:
98
- raise ConfigurationError(f'Invalid log level: "{config["log_level"]}" not in {list(logging._nameToLevel.keys())}')
99
- if 'api_log_level' in config and config['api_log_level'] is not None:
100
- config['api_log_level'] = config['api_log_level'].upper()
101
- if config['api_log_level'] in logging._nameToLevel:
102
- LOG_API.setLevel(config['api_log_level'])
103
- else:
104
- raise ConfigurationError(f'Invalid log level: "{config["log_level"]}" not in {list(logging._nameToLevel.keys())}')
105
- LOG.info("Loading skoda connector with config %s", config_remove_credentials(self.config))
88
+ LOG.info("Loading skoda connector with config %s", config_remove_credentials(config))
106
89
 
107
90
  if 'spin' in config and config['spin'] is not None:
108
- self._spin: Optional[str] = config['spin']
91
+ self.active_config['spin'] = config['spin']
109
92
  else:
110
- self._spin = None
93
+ self.active_config['spin'] = None
111
94
 
112
- username: Optional[str] = None
113
- password: Optional[str] = None
114
- if 'username' in self.config and 'password' in self.config:
115
- username = self.config['username']
116
- password = self.config['password']
95
+ self.active_config['username'] = None
96
+ self.active_config['password'] = None
97
+ if 'username' in config and 'password' in config:
98
+ self.active_config['username'] = config['username']
99
+ self.active_config['password'] = config['password']
117
100
  else:
118
- if 'netrc' in self.config:
119
- netrc_filename: str = self.config['netrc']
101
+ if 'netrc' in config:
102
+ self.active_config['netrc'] = config['netrc']
120
103
  else:
121
- netrc_filename = os.path.join(os.path.expanduser("~"), ".netrc")
104
+ self.active_config['netrc'] = os.path.join(os.path.expanduser("~"), ".netrc")
122
105
  try:
123
- secrets = netrc.netrc(file=netrc_filename)
106
+ secrets = netrc.netrc(file=self.active_config['netrc'])
124
107
  secret: tuple[str, str, str] | None = secrets.authenticators("skoda")
125
108
  if secret is None:
126
- raise AuthenticationError(f'Authentication using {netrc_filename} failed: skoda not found in netrc')
127
- username, account, password = secret
109
+ raise AuthenticationError(f'Authentication using {self.active_config["netrc"]} failed: skoda not found in netrc')
110
+ self.active_config['username'], account, self.active_config['password'] = secret
128
111
 
129
- if self._spin is None and account is not None:
112
+ if self.active_config['spin'] is None and account is not None:
130
113
  try:
131
- self._spin = account
114
+ self.active_config['spin'] = account
132
115
  except ValueError as err:
133
116
  LOG.error('Could not parse spin from netrc: %s', err)
134
117
  except netrc.NetrcParseError as err:
135
- LOG.error('Authentification using %s failed: %s', netrc_filename, err)
136
- raise AuthenticationError(f'Authentication using {netrc_filename} failed: {err}') from err
118
+ LOG.error('Authentification using %s failed: %s', self.active_config['netrc'], err)
119
+ raise AuthenticationError(f'Authentication using {self.active_config["netrc"]} failed: {err}') from err
137
120
  except TypeError as err:
138
- if 'username' not in self.config:
139
- raise AuthenticationError(f'"skoda" entry was not found in {netrc_filename} netrc-file.'
121
+ if 'username' not in config:
122
+ raise AuthenticationError(f'"skoda" entry was not found in {self.active_config["netrc"]} netrc-file.'
140
123
  ' Create it or provide username and password in config') from err
141
124
  except FileNotFoundError as err:
142
- raise AuthenticationError(f'{netrc_filename} netrc-file was not found. Create it or provide username and password in config') from err
143
-
144
- interval: int = 300
145
- if 'interval' in self.config:
146
- interval = self.config['interval']
147
- if interval < 300:
148
- raise ValueError('Intervall must be at least 300 seconds')
149
- self.max_age: int = interval - 1
150
- if 'max_age' in self.config:
151
- self.max_age = self.config['max_age']
152
- self.interval._set_value(timedelta(seconds=interval)) # pylint: disable=protected-access
153
-
154
- if username is None or password is None:
125
+ raise AuthenticationError(f'{self.active_config["netrc"]} netrc-file was not found. Create it or provide username and password in config') \
126
+ from err
127
+
128
+ self.active_config['interval'] = 300
129
+ if 'interval' in config:
130
+ self.active_config['interval'] = config['interval']
131
+ if self.active_config['interval'] < 180:
132
+ raise ValueError('Intervall must be at least 180 seconds')
133
+ self.active_config['max_age'] = self.active_config['interval'] - 1
134
+ if 'max_age' in config:
135
+ self.active_config['max_age'] = config['max_age']
136
+ self.interval._set_value(timedelta(seconds=self.active_config['interval'])) # pylint: disable=protected-access
137
+
138
+ if self.active_config['username'] is None or self.active_config['password'] is None:
155
139
  raise AuthenticationError('Username or password not provided')
156
140
 
157
141
  self._manager: SessionManager = SessionManager(tokenstore=car_connectivity.get_tokenstore(), cache=car_connectivity.get_cache())
158
- session: requests.Session = self._manager.get_session(Service.MY_SKODA, SessionUser(username=username, password=password))
142
+ session: requests.Session = self._manager.get_session(Service.MY_SKODA, SessionUser(username=self.active_config['username'],
143
+ password=self.active_config['password']))
159
144
  if not isinstance(session, MySkodaSession):
160
145
  raise AuthenticationError('Could not create session')
161
146
  self.session: MySkodaSession = session
@@ -948,7 +933,7 @@ class Connector(BaseConnector):
948
933
  data = self._fetch_data(url, session=self.session, allow_http_error=True)
949
934
  if data is not None and 'compositeRenders' in data: # pylint: disable=too-many-nested-blocks
950
935
  for image in data['compositeRenders']:
951
- if not 'layers' in image or image['layers'] is None or len(image['layers']) == 0:
936
+ if 'layers' not in image or image['layers'] is None or len(image['layers']) == 0:
952
937
  continue
953
938
  image_url: Optional[str] = None
954
939
  for layer in image['layers']:
@@ -959,13 +944,13 @@ class Connector(BaseConnector):
959
944
  continue
960
945
  img = None
961
946
  cache_date = None
962
- if self.max_age is not None and self.session.cache is not None and image_url in self.session.cache:
947
+ if self.active_config['max_age'] is not None and self.session.cache is not None and image_url in self.session.cache:
963
948
  img, cache_date_string = self.session.cache[image_url]
964
949
  img = base64.b64decode(img) # pyright: ignore[reportPossiblyUnboundVariable]
965
950
  img = Image.open(io.BytesIO(img)) # pyright: ignore[reportPossiblyUnboundVariable]
966
951
  cache_date = datetime.fromisoformat(cache_date_string)
967
- if img is None or self.max_age is None \
968
- or (cache_date is not None and cache_date < (datetime.utcnow() - timedelta(seconds=self.max_age))):
952
+ if img is None or self.active_config['max_age'] is None \
953
+ or (cache_date is not None and cache_date < (datetime.utcnow() - timedelta(seconds=self.active_config['max_age']))):
969
954
  try:
970
955
  image_download_response = requests.get(image_url, stream=True)
971
956
  if image_download_response.status_code == requests.codes['ok']:
@@ -1000,8 +985,8 @@ class Connector(BaseConnector):
1000
985
  if 'car_picture' in vehicle.images.images:
1001
986
  vehicle.images.images['car_picture']._set_value(img) # pylint: disable=protected-access
1002
987
  else:
1003
- vehicle.images.images['car_picture']: ImageAttribute = ImageAttribute(name="car_picture", parent=vehicle.images,
1004
- value=img, tags={'carconnectivity'})
988
+ vehicle.images.images['car_picture'] = ImageAttribute(name="car_picture", parent=vehicle.images,
989
+ value=img, tags={'carconnectivity'})
1005
990
  return vehicle
1006
991
 
1007
992
  def fetch_driving_range(self, vehicle: SkodaVehicle, no_cache: bool = False) -> SkodaVehicle:
@@ -1140,6 +1125,9 @@ class Connector(BaseConnector):
1140
1125
  if vehicle_status_data['overall']['doorsLocked'] == 'YES':
1141
1126
  vehicle.doors.lock_state._set_value(Doors.LockState.LOCKED, measured=captured_at) # pylint: disable=protected-access
1142
1127
  vehicle.doors.open_state._set_value(Doors.OpenState.CLOSED, measured=captured_at) # pylint: disable=protected-access
1128
+ elif vehicle_status_data['overall']['doorsLocked'] == 'NO':
1129
+ vehicle.doors.lock_state._set_value(Doors.LockState.UNLOCKED, measured=captured_at) # pylint: disable=protected-access
1130
+ vehicle.doors.open_state._set_value(Doors.OpenState.UNKNOWN, measured=captured_at) # pylint: disable=protected-access
1143
1131
  elif vehicle_status_data['overall']['doorsLocked'] == 'OPENED':
1144
1132
  vehicle.doors.lock_state._set_value(Doors.LockState.UNLOCKED, measured=captured_at) # pylint: disable=protected-access
1145
1133
  vehicle.doors.open_state._set_value(Doors.OpenState.OPEN, measured=captured_at) # pylint: disable=protected-access
@@ -1221,11 +1209,11 @@ class Connector(BaseConnector):
1221
1209
  allowed_errors=None) -> Optional[Dict[str, Any]]: # noqa: C901
1222
1210
  data: Optional[Dict[str, Any]] = None
1223
1211
  cache_date: Optional[datetime] = None
1224
- if not no_cache and (self.max_age is not None and session.cache is not None and url in session.cache):
1212
+ if not no_cache and (self.active_config['max_age'] is not None and session.cache is not None and url in session.cache):
1225
1213
  data, cache_date_string = session.cache[url]
1226
1214
  cache_date = datetime.fromisoformat(cache_date_string)
1227
- if data is None or self.max_age is None \
1228
- or (cache_date is not None and cache_date < (datetime.utcnow() - timedelta(seconds=self.max_age))):
1215
+ if data is None or self.active_config['max_age'] is None \
1216
+ or (cache_date is not None and cache_date < (datetime.utcnow() - timedelta(seconds=self.active_config['max_age']))):
1229
1217
  try:
1230
1218
  status_response: requests.Response = session.get(url, allow_redirects=False)
1231
1219
  self._record_elapsed(status_response.elapsed)
@@ -1485,9 +1473,9 @@ class Connector(BaseConnector):
1485
1473
  if 'spin' in command_arguments:
1486
1474
  command_dict['currentSpin'] = command_arguments['spin']
1487
1475
  else:
1488
- if self._spin is None:
1476
+ if self.active_config['spin'] is None:
1489
1477
  raise CommandError('S-PIN is missing, please add S-PIN to your configuration or .netrc file')
1490
- command_dict['currentSpin'] = self._spin
1478
+ command_dict['currentSpin'] = self.active_config['spin']
1491
1479
  if command_arguments['command'] == LockUnlockCommand.Command.LOCK:
1492
1480
  url = f'https://mysmob.api.connect.skoda-auto.cz/api/v1/vehicle-access/{vin}/lock'
1493
1481
  elif command_arguments['command'] == LockUnlockCommand.Command.UNLOCK:
@@ -1534,14 +1522,14 @@ class Connector(BaseConnector):
1534
1522
  if 'command' not in command_arguments:
1535
1523
  raise CommandError('Command argument missing')
1536
1524
  command_dict = {}
1537
- if self._spin is None:
1525
+ if self.active_config['spin'] is None:
1538
1526
  raise CommandError('S-PIN is missing, please add S-PIN to your configuration or .netrc file')
1539
1527
  if 'spin' in command_arguments:
1540
1528
  command_dict['currentSpin'] = command_arguments['spin']
1541
1529
  else:
1542
- if self._spin is None or self._spin == '':
1530
+ if self.active_config['spin'] is None or self.active_config['spin'] == '':
1543
1531
  raise CommandError('S-PIN is missing, please add S-PIN to your configuration or .netrc file')
1544
- command_dict['currentSpin'] = self._spin
1532
+ command_dict['currentSpin'] = self.active_config['spin']
1545
1533
  if command_arguments['command'] == SpinCommand.Command.VERIFY:
1546
1534
  url = 'https://mysmob.api.connect.skoda-auto.cz/api/v1/spin/verify'
1547
1535
  else:
@@ -0,0 +1,39 @@
1
+ """ User interface for the Skoda connector in the Car Connectivity application. """
2
+ from __future__ import annotations
3
+ from typing import TYPE_CHECKING
4
+
5
+ import os
6
+
7
+ import flask
8
+
9
+ from carconnectivity_connectors.base.ui.connector_ui import BaseConnectorUI
10
+
11
+ if TYPE_CHECKING:
12
+ from typing import Optional, List, Dict, Union, Literal
13
+
14
+ from carconnectivity_connectors.base.connector import BaseConnector
15
+
16
+
17
+ class ConnectorUI(BaseConnectorUI):
18
+ """
19
+ A user interface class for the Skoda connector in the Car Connectivity application.
20
+ """
21
+ def __init__(self, connector: BaseConnector):
22
+ blueprint: Optional[flask.Blueprint] = flask.Blueprint(name='skoda', import_name='carconnectivity-connector-skoda', url_prefix='/skoda',
23
+ template_folder=os.path.dirname(__file__) + '/templates')
24
+ super().__init__(connector, blueprint=blueprint)
25
+
26
+ def get_nav_items(self) -> List[Dict[Literal['text', 'url', 'sublinks', 'divider'], Union[str, List]]]:
27
+ """
28
+ Generates a list of navigation items for the Skoda connector UI.
29
+ """
30
+ return super().get_nav_items()
31
+
32
+ def get_title(self) -> str:
33
+ """
34
+ Returns the title of the connector.
35
+
36
+ Returns:
37
+ str: The title of the connector, which is "Skoda".
38
+ """
39
+ return "Skoda"
@@ -1,3 +0,0 @@
1
- flake8~=7.1.1
2
- pylint~=3.3.4
3
- bandit~=1.8.2