carconnectivity-connector-skoda 0.2a5__tar.gz → 0.4a1__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.
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/CHANGELOG.md +8 -1
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/PKG-INFO +2 -2
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/pyproject.toml +1 -1
- carconnectivity_connector_skoda-0.4a1/setup_requirements.txt +6 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connector_skoda.egg-info/PKG-INFO +2 -2
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connector_skoda.egg-info/SOURCES.txt +1 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connector_skoda.egg-info/requires.txt +1 -1
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connectors/skoda/_version.py +9 -4
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connectors/skoda/climatization.py +8 -6
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connectors/skoda/connector.py +52 -67
- carconnectivity_connector_skoda-0.4a1/src/carconnectivity_connectors/skoda/ui/connector_ui.py +39 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connectors/skoda/vehicle.py +2 -0
- carconnectivity_connector_skoda-0.2a5/setup_requirements.txt +0 -3
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/.flake8 +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/.github/dependabot.yml +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/.github/workflows/build.yml +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/.github/workflows/build_and_publish.yml +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/.github/workflows/codeql-analysis.yml +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/.gitignore +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/LICENSE +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/Makefile +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/README.md +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/doc/Config.md +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/setup.cfg +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connector_skoda.egg-info/dependency_links.txt +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connector_skoda.egg-info/top_level.txt +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connectors/skoda/__init__.py +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connectors/skoda/auth/__init__.py +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connectors/skoda/auth/auth_util.py +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connectors/skoda/auth/helpers/blacklist_retry.py +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connectors/skoda/auth/my_skoda_session.py +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connectors/skoda/auth/openid_session.py +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connectors/skoda/auth/session_manager.py +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connectors/skoda/auth/skoda_web_session.py +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connectors/skoda/capability.py +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connectors/skoda/charging.py +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connectors/skoda/command_impl.py +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connectors/skoda/error.py +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/src/carconnectivity_connectors/skoda/mqtt_client.py +0 -0
- {carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/test/integration_test/carConnectivity.json +0 -0
{carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/CHANGELOG.md
RENAMED
|
@@ -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.
|
|
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.
|
|
3
|
+
Version: 0.4a1
|
|
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.
|
|
40
|
+
Requires-Dist: carconnectivity>=0.4a3
|
|
41
41
|
Requires-Dist: oauthlib~=3.2.2
|
|
42
42
|
Requires-Dist: requests~=2.32.3
|
|
43
43
|
Requires-Dist: jwt~=1.3.1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: carconnectivity-connector-skoda
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4a1
|
|
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.
|
|
40
|
+
Requires-Dist: carconnectivity>=0.4a3
|
|
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,8 +1,13 @@
|
|
|
1
|
-
# file generated by
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
2
|
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
|
|
5
|
+
|
|
3
6
|
TYPE_CHECKING = False
|
|
4
7
|
if TYPE_CHECKING:
|
|
5
|
-
from typing import Tuple
|
|
8
|
+
from typing import Tuple
|
|
9
|
+
from typing import Union
|
|
10
|
+
|
|
6
11
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
7
12
|
else:
|
|
8
13
|
VERSION_TUPLE = object
|
|
@@ -12,5 +17,5 @@ __version__: str
|
|
|
12
17
|
__version_tuple__: VERSION_TUPLE
|
|
13
18
|
version_tuple: VERSION_TUPLE
|
|
14
19
|
|
|
15
|
-
__version__ = version = '0.
|
|
16
|
-
__version_tuple__ = version_tuple = (0,
|
|
20
|
+
__version__ = version = '0.4a1'
|
|
21
|
+
__version_tuple__ = version_tuple = (0, 4)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Module for
|
|
2
|
+
Module for climatization for skoda vehicles.
|
|
3
3
|
"""
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
7
|
from carconnectivity.climatization import Climatization
|
|
8
8
|
from carconnectivity.objects import GenericObject
|
|
9
|
-
from carconnectivity.vehicle import
|
|
9
|
+
from carconnectivity.vehicle import GenericVehicle
|
|
10
10
|
|
|
11
11
|
from carconnectivity_connectors.skoda.error import Error
|
|
12
12
|
|
|
@@ -21,13 +21,15 @@ class SkodaClimatization(Climatization): # pylint: disable=too-many-instance-at
|
|
|
21
21
|
This class extends the Climatization class and includes an enumeration of various
|
|
22
22
|
charging states specific to Skoda vehicles.
|
|
23
23
|
"""
|
|
24
|
-
def __init__(self, vehicle:
|
|
24
|
+
def __init__(self, vehicle: GenericVehicle | None = None, origin: Optional[Climatization] = None) -> None:
|
|
25
25
|
if origin is not None:
|
|
26
26
|
super().__init__(origin=origin)
|
|
27
|
-
self.settings
|
|
27
|
+
if not isinstance(self.settings, SkodaClimatization.Settings):
|
|
28
|
+
self.settings: Climatization.Settings = SkodaClimatization.Settings(parent=self, origin=origin.settings)
|
|
29
|
+
self.settings.parent = self
|
|
28
30
|
else:
|
|
29
31
|
super().__init__(vehicle=vehicle)
|
|
30
|
-
self.settings: Climatization.Settings = SkodaClimatization.Settings(
|
|
32
|
+
self.settings: Climatization.Settings = SkodaClimatization.Settings(parent=self)
|
|
31
33
|
self.errors: Dict[str, Error] = {}
|
|
32
34
|
|
|
33
35
|
class Settings(Climatization.Settings):
|
|
@@ -36,6 +38,6 @@ class SkodaClimatization(Climatization): # pylint: disable=too-many-instance-at
|
|
|
36
38
|
"""
|
|
37
39
|
def __init__(self, parent: Optional[GenericObject] = None, origin: Optional[Climatization.Settings] = None) -> None:
|
|
38
40
|
if origin is not None:
|
|
39
|
-
super().__init__(origin=origin)
|
|
41
|
+
super().__init__(parent=parent, origin=origin)
|
|
40
42
|
else:
|
|
41
43
|
super().__init__(parent=parent)
|
|
@@ -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,
|
|
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
|
-
|
|
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.
|
|
91
|
+
self.active_config['spin'] = config['spin']
|
|
109
92
|
else:
|
|
110
|
-
self.
|
|
93
|
+
self.active_config['spin'] = None
|
|
111
94
|
|
|
112
|
-
username
|
|
113
|
-
password
|
|
114
|
-
if 'username' in
|
|
115
|
-
username =
|
|
116
|
-
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
|
|
119
|
-
|
|
101
|
+
if 'netrc' in config:
|
|
102
|
+
self.active_config['netrc'] = config['netrc']
|
|
120
103
|
else:
|
|
121
|
-
|
|
104
|
+
self.active_config['netrc'] = os.path.join(os.path.expanduser("~"), ".netrc")
|
|
122
105
|
try:
|
|
123
|
-
secrets = netrc.netrc(file=
|
|
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 {
|
|
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.
|
|
112
|
+
if self.active_config['spin'] is None and account is not None:
|
|
130
113
|
try:
|
|
131
|
-
self.
|
|
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',
|
|
136
|
-
raise AuthenticationError(f'Authentication using {
|
|
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
|
|
139
|
-
raise AuthenticationError(f'"skoda" entry was not found in {
|
|
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'{
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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,
|
|
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
|
|
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']
|
|
1004
|
-
|
|
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:
|
|
@@ -1224,11 +1209,11 @@ class Connector(BaseConnector):
|
|
|
1224
1209
|
allowed_errors=None) -> Optional[Dict[str, Any]]: # noqa: C901
|
|
1225
1210
|
data: Optional[Dict[str, Any]] = None
|
|
1226
1211
|
cache_date: Optional[datetime] = None
|
|
1227
|
-
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):
|
|
1228
1213
|
data, cache_date_string = session.cache[url]
|
|
1229
1214
|
cache_date = datetime.fromisoformat(cache_date_string)
|
|
1230
|
-
if data is None or self.max_age is None \
|
|
1231
|
-
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']))):
|
|
1232
1217
|
try:
|
|
1233
1218
|
status_response: requests.Response = session.get(url, allow_redirects=False)
|
|
1234
1219
|
self._record_elapsed(status_response.elapsed)
|
|
@@ -1488,9 +1473,9 @@ class Connector(BaseConnector):
|
|
|
1488
1473
|
if 'spin' in command_arguments:
|
|
1489
1474
|
command_dict['currentSpin'] = command_arguments['spin']
|
|
1490
1475
|
else:
|
|
1491
|
-
if self.
|
|
1476
|
+
if self.active_config['spin'] is None:
|
|
1492
1477
|
raise CommandError('S-PIN is missing, please add S-PIN to your configuration or .netrc file')
|
|
1493
|
-
command_dict['currentSpin'] = self.
|
|
1478
|
+
command_dict['currentSpin'] = self.active_config['spin']
|
|
1494
1479
|
if command_arguments['command'] == LockUnlockCommand.Command.LOCK:
|
|
1495
1480
|
url = f'https://mysmob.api.connect.skoda-auto.cz/api/v1/vehicle-access/{vin}/lock'
|
|
1496
1481
|
elif command_arguments['command'] == LockUnlockCommand.Command.UNLOCK:
|
|
@@ -1537,14 +1522,14 @@ class Connector(BaseConnector):
|
|
|
1537
1522
|
if 'command' not in command_arguments:
|
|
1538
1523
|
raise CommandError('Command argument missing')
|
|
1539
1524
|
command_dict = {}
|
|
1540
|
-
if self.
|
|
1525
|
+
if self.active_config['spin'] is None:
|
|
1541
1526
|
raise CommandError('S-PIN is missing, please add S-PIN to your configuration or .netrc file')
|
|
1542
1527
|
if 'spin' in command_arguments:
|
|
1543
1528
|
command_dict['currentSpin'] = command_arguments['spin']
|
|
1544
1529
|
else:
|
|
1545
|
-
if self.
|
|
1530
|
+
if self.active_config['spin'] is None or self.active_config['spin'] == '':
|
|
1546
1531
|
raise CommandError('S-PIN is missing, please add S-PIN to your configuration or .netrc file')
|
|
1547
|
-
command_dict['currentSpin'] = self.
|
|
1532
|
+
command_dict['currentSpin'] = self.active_config['spin']
|
|
1548
1533
|
if command_arguments['command'] == SpinCommand.Command.VERIFY:
|
|
1549
1534
|
url = 'https://mysmob.api.connect.skoda-auto.cz/api/v1/spin/verify'
|
|
1550
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"
|
|
@@ -7,6 +7,7 @@ from carconnectivity.charging import Charging
|
|
|
7
7
|
|
|
8
8
|
from carconnectivity_connectors.skoda.capability import Capabilities
|
|
9
9
|
from carconnectivity_connectors.skoda.charging import SkodaCharging
|
|
10
|
+
from carconnectivity_connectors.skoda.climatization import SkodaClimatization
|
|
10
11
|
|
|
11
12
|
SUPPORT_IMAGES = False
|
|
12
13
|
try:
|
|
@@ -36,6 +37,7 @@ class SkodaVehicle(GenericVehicle): # pylint: disable=too-many-instance-attribu
|
|
|
36
37
|
|
|
37
38
|
else:
|
|
38
39
|
super().__init__(vin=vin, garage=garage, managing_connector=managing_connector)
|
|
40
|
+
self.climatization = SkodaClimatization(vehicle=self, origin=self.climatization)
|
|
39
41
|
self.capabilities = Capabilities(vehicle=self)
|
|
40
42
|
if SUPPORT_IMAGES:
|
|
41
43
|
self._car_images: Dict[str, Image.Image] = {}
|
|
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
|
{carconnectivity_connector_skoda-0.2a5 → carconnectivity_connector_skoda-0.4a1}/doc/Config.md
RENAMED
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|