carconnectivity-connector-skoda 0.7.1a1__tar.gz → 0.8.1__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.7.1a1 → carconnectivity_connector_skoda-0.8.1}/.github/workflows/build.yml +3 -3
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/.github/workflows/build_and_publish.yml +2 -2
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/.github/workflows/codeql-analysis.yml +4 -4
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/CHANGELOG.md +35 -1
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/PKG-INFO +5 -4
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/pyproject.toml +4 -3
- carconnectivity_connector_skoda-0.8.1/setup_requirements.txt +6 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connector_skoda.egg-info/PKG-INFO +5 -4
- carconnectivity_connector_skoda-0.8.1/src/carconnectivity_connector_skoda.egg-info/requires.txt +5 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connectors/skoda/_version.py +16 -3
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connectors/skoda/auth/my_skoda_session.py +19 -13
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connectors/skoda/auth/openid_session.py +5 -1
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connectors/skoda/capability.py +1 -1
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connectors/skoda/connector.py +17 -3
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connectors/skoda/mqtt_client.py +19 -2
- carconnectivity_connector_skoda-0.7.1a1/setup_requirements.txt +0 -6
- carconnectivity_connector_skoda-0.7.1a1/src/carconnectivity_connector_skoda.egg-info/requires.txt +0 -5
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/.flake8 +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/.github/dependabot.yml +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/.gitignore +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/LICENSE +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/Makefile +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/README.md +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/doc/Config.md +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/setup.cfg +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connector_skoda.egg-info/SOURCES.txt +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connector_skoda.egg-info/dependency_links.txt +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connector_skoda.egg-info/top_level.txt +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connectors/skoda/__init__.py +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connectors/skoda/auth/__init__.py +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connectors/skoda/auth/auth_util.py +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connectors/skoda/auth/helpers/blacklist_retry.py +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connectors/skoda/auth/session_manager.py +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connectors/skoda/auth/skoda_web_session.py +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connectors/skoda/charging.py +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connectors/skoda/climatization.py +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connectors/skoda/command_impl.py +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connectors/skoda/error.py +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connectors/skoda/ui/connector_ui.py +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/src/carconnectivity_connectors/skoda/vehicle.py +0 -0
- {carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/test/integration_test/carConnectivity.json +0 -0
|
@@ -22,12 +22,12 @@ jobs:
|
|
|
22
22
|
runs-on: ubuntu-latest
|
|
23
23
|
strategy:
|
|
24
24
|
matrix:
|
|
25
|
-
python-version: ['3.
|
|
25
|
+
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
|
|
26
26
|
|
|
27
27
|
steps:
|
|
28
|
-
- uses: actions/checkout@
|
|
28
|
+
- uses: actions/checkout@v5
|
|
29
29
|
- name: Set up Python ${{ matrix.python-version }}
|
|
30
|
-
uses: actions/setup-python@
|
|
30
|
+
uses: actions/setup-python@v6
|
|
31
31
|
with:
|
|
32
32
|
python-version: ${{ matrix.python-version }}
|
|
33
33
|
- name: Install dependencies
|
|
@@ -15,11 +15,11 @@ jobs:
|
|
|
15
15
|
id-token: write
|
|
16
16
|
|
|
17
17
|
steps:
|
|
18
|
-
- uses: actions/checkout@
|
|
18
|
+
- uses: actions/checkout@v5
|
|
19
19
|
with:
|
|
20
20
|
fetch-depth: 0
|
|
21
21
|
- name: Set up Python
|
|
22
|
-
uses: actions/setup-python@
|
|
22
|
+
uses: actions/setup-python@v6
|
|
23
23
|
with:
|
|
24
24
|
python-version: "3.x"
|
|
25
25
|
- name: Install dependencies
|
|
@@ -26,11 +26,11 @@ jobs:
|
|
|
26
26
|
|
|
27
27
|
steps:
|
|
28
28
|
- name: Checkout repository
|
|
29
|
-
uses: actions/checkout@
|
|
29
|
+
uses: actions/checkout@v5
|
|
30
30
|
|
|
31
31
|
# Initializes the CodeQL tools for scanning.
|
|
32
32
|
- name: Initialize CodeQL
|
|
33
|
-
uses: github/codeql-action/init@
|
|
33
|
+
uses: github/codeql-action/init@v4
|
|
34
34
|
with:
|
|
35
35
|
languages: ${{ matrix.language }}
|
|
36
36
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
|
@@ -41,7 +41,7 @@ jobs:
|
|
|
41
41
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
|
42
42
|
# If this step fails, then you should remove it and run the build manually (see below)
|
|
43
43
|
- name: Autobuild
|
|
44
|
-
uses: github/codeql-action/autobuild@
|
|
44
|
+
uses: github/codeql-action/autobuild@v4
|
|
45
45
|
|
|
46
46
|
# ℹ️ Command-line programs to run using the OS shell.
|
|
47
47
|
# 📚 https://git.io/JvXDl
|
|
@@ -55,4 +55,4 @@ jobs:
|
|
|
55
55
|
# make release
|
|
56
56
|
|
|
57
57
|
- name: Perform CodeQL Analysis
|
|
58
|
-
uses: github/codeql-action/analyze@
|
|
58
|
+
uses: github/codeql-action/analyze@v4
|
{carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/CHANGELOG.md
RENAMED
|
@@ -5,6 +5,35 @@ 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.8.1] - 2025-11-02
|
|
9
|
+
### Fixed
|
|
10
|
+
- Relogin when MQTT client receives a bad username or password error
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Warning when connector detects suspicious token expiry
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- Updated some dependencies
|
|
17
|
+
|
|
18
|
+
## [0.8] - 2025-06-27
|
|
19
|
+
### Added
|
|
20
|
+
- Support for adblue range
|
|
21
|
+
|
|
22
|
+
## [0.7.3] - 2025-06-20
|
|
23
|
+
### Fixed
|
|
24
|
+
- Fixes bug that registers hooks several times, causing multiple calls to the servers
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- Updated dependencies
|
|
28
|
+
|
|
29
|
+
## [0.7.2] - 2025-04-19
|
|
30
|
+
### Fixed
|
|
31
|
+
- Fix for problems introduced with PyJWT
|
|
32
|
+
|
|
33
|
+
## [0.7.1] - 2025-04-18
|
|
34
|
+
### Fixed
|
|
35
|
+
- Fixed problem where driving range was not fetched when measurements capability had an expired license. Now it will be also fetched when charging license is active.
|
|
36
|
+
|
|
8
37
|
## [0.7] - 2025-04-17
|
|
9
38
|
### Fixed
|
|
10
39
|
- Bug in mode attribute that caused the connector to crash
|
|
@@ -62,7 +91,12 @@ All notable changes to this project will be documented in this file.
|
|
|
62
91
|
Initial release, let's go and give this to the public to try out...
|
|
63
92
|
The API is not yet implemented completely but most functions already work
|
|
64
93
|
|
|
65
|
-
[unreleased]: https://github.com/tillsteinbach/CarConnectivity-connector-skoda/compare/v0.
|
|
94
|
+
[unreleased]: https://github.com/tillsteinbach/CarConnectivity-connector-skoda/compare/v0.8.1...HEAD
|
|
95
|
+
[0.8.1]: https://github.com/tillsteinbach/CarConnectivity-connector-skoda/releases/tag/v0.8.1
|
|
96
|
+
[0.8]: https://github.com/tillsteinbach/CarConnectivity-connector-skoda/releases/tag/v0.8
|
|
97
|
+
[0.7.3]: https://github.com/tillsteinbach/CarConnectivity-connector-skoda/releases/tag/v0.7.3
|
|
98
|
+
[0.7.2]: https://github.com/tillsteinbach/CarConnectivity-connector-skoda/releases/tag/v0.7.2
|
|
99
|
+
[0.7.1]: https://github.com/tillsteinbach/CarConnectivity-connector-skoda/releases/tag/v0.7.1
|
|
66
100
|
[0.7]: https://github.com/tillsteinbach/CarConnectivity-connector-skoda/releases/tag/v0.7
|
|
67
101
|
[0.6]: https://github.com/tillsteinbach/CarConnectivity-connector-skoda/releases/tag/v0.6
|
|
68
102
|
[0.5]: https://github.com/tillsteinbach/CarConnectivity-connector-skoda/releases/tag/v0.5
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: carconnectivity-connector-skoda
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.1
|
|
4
4
|
Summary: CarConnectivity connector for Skoda services
|
|
5
5
|
Author: Till Steinbach
|
|
6
6
|
License: MIT License
|
|
@@ -33,13 +33,14 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
33
33
|
Classifier: Programming Language :: Python :: 3.11
|
|
34
34
|
Classifier: Programming Language :: Python :: 3.12
|
|
35
35
|
Classifier: Programming Language :: Python :: 3.13
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
36
37
|
Classifier: Topic :: Software Development :: Libraries
|
|
37
38
|
Requires-Python: >=3.8
|
|
38
39
|
Description-Content-Type: text/markdown
|
|
39
40
|
License-File: LICENSE
|
|
40
|
-
Requires-Dist: carconnectivity>=0.
|
|
41
|
-
Requires-Dist: oauthlib~=3.
|
|
42
|
-
Requires-Dist: requests~=2.32.
|
|
41
|
+
Requires-Dist: carconnectivity>=0.8.1
|
|
42
|
+
Requires-Dist: oauthlib~=3.3.1
|
|
43
|
+
Requires-Dist: requests~=2.32.5
|
|
43
44
|
Requires-Dist: pyjwt~=2.10
|
|
44
45
|
Requires-Dist: paho-mqtt~=2.1.0
|
|
45
46
|
Dynamic: license-file
|
{carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/pyproject.toml
RENAMED
|
@@ -14,9 +14,9 @@ authors = [
|
|
|
14
14
|
{ name = "Till Steinbach" }
|
|
15
15
|
]
|
|
16
16
|
dependencies = [
|
|
17
|
-
"carconnectivity>=0.
|
|
18
|
-
"oauthlib~=3.
|
|
19
|
-
"requests~=2.32.
|
|
17
|
+
"carconnectivity>=0.8.1",
|
|
18
|
+
"oauthlib~=3.3.1",
|
|
19
|
+
"requests~=2.32.5",
|
|
20
20
|
"pyjwt~=2.10",
|
|
21
21
|
"paho-mqtt~=2.1.0",
|
|
22
22
|
]
|
|
@@ -31,6 +31,7 @@ classifiers = [
|
|
|
31
31
|
"Programming Language :: Python :: 3.11",
|
|
32
32
|
"Programming Language :: Python :: 3.12",
|
|
33
33
|
"Programming Language :: Python :: 3.13",
|
|
34
|
+
"Programming Language :: Python :: 3.14",
|
|
34
35
|
"Topic :: Software Development :: Libraries"
|
|
35
36
|
]
|
|
36
37
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: carconnectivity-connector-skoda
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.1
|
|
4
4
|
Summary: CarConnectivity connector for Skoda services
|
|
5
5
|
Author: Till Steinbach
|
|
6
6
|
License: MIT License
|
|
@@ -33,13 +33,14 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
33
33
|
Classifier: Programming Language :: Python :: 3.11
|
|
34
34
|
Classifier: Programming Language :: Python :: 3.12
|
|
35
35
|
Classifier: Programming Language :: Python :: 3.13
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
36
37
|
Classifier: Topic :: Software Development :: Libraries
|
|
37
38
|
Requires-Python: >=3.8
|
|
38
39
|
Description-Content-Type: text/markdown
|
|
39
40
|
License-File: LICENSE
|
|
40
|
-
Requires-Dist: carconnectivity>=0.
|
|
41
|
-
Requires-Dist: oauthlib~=3.
|
|
42
|
-
Requires-Dist: requests~=2.32.
|
|
41
|
+
Requires-Dist: carconnectivity>=0.8.1
|
|
42
|
+
Requires-Dist: oauthlib~=3.3.1
|
|
43
|
+
Requires-Dist: requests~=2.32.5
|
|
43
44
|
Requires-Dist: pyjwt~=2.10
|
|
44
45
|
Requires-Dist: paho-mqtt~=2.1.0
|
|
45
46
|
Dynamic: license-file
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
# file generated by setuptools-scm
|
|
2
2
|
# don't change, don't track in version control
|
|
3
3
|
|
|
4
|
-
__all__ = [
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
5
12
|
|
|
6
13
|
TYPE_CHECKING = False
|
|
7
14
|
if TYPE_CHECKING:
|
|
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
|
|
|
9
16
|
from typing import Union
|
|
10
17
|
|
|
11
18
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
12
20
|
else:
|
|
13
21
|
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
14
23
|
|
|
15
24
|
version: str
|
|
16
25
|
__version__: str
|
|
17
26
|
__version_tuple__: VERSION_TUPLE
|
|
18
27
|
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
19
30
|
|
|
20
|
-
__version__ = version = '0.
|
|
21
|
-
__version_tuple__ = version_tuple = (0,
|
|
31
|
+
__version__ = version = '0.8.1'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 8, 1)
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = 'g5123c7f6f'
|
|
@@ -15,6 +15,7 @@ from urllib.parse import parse_qsl, urlparse
|
|
|
15
15
|
|
|
16
16
|
import requests
|
|
17
17
|
from requests.models import CaseInsensitiveDict
|
|
18
|
+
from requests.exceptions import ReadTimeout, ConnectionError
|
|
18
19
|
|
|
19
20
|
from oauthlib.common import add_params_to_uri, generate_nonce, to_unicode
|
|
20
21
|
from oauthlib.oauth2 import InsecureTransportError
|
|
@@ -58,17 +59,22 @@ class MySkodaSession(SkodaWebSession):
|
|
|
58
59
|
def login(self):
|
|
59
60
|
super(MySkodaSession, self).login()
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
62
|
+
try:
|
|
63
|
+
verifier = "".join(random.choices(string.ascii_uppercase + string.digits, k=16))
|
|
64
|
+
verifier_hash = hashlib.sha256(verifier.encode("utf-8")).digest()
|
|
65
|
+
code_challenge = base64.b64encode(verifier_hash).decode("utf-8").replace("+", "-").replace("/", "_").rstrip("=")
|
|
66
|
+
# retrieve authorization URL
|
|
67
|
+
authorization_url = self.authorization_url(url='https://identity.vwgroup.io/oidc/v1/authorize', prompt='login', code_challenge=code_challenge,
|
|
68
|
+
code_challenge_method='s256')
|
|
69
|
+
# perform web authentication
|
|
70
|
+
response = self.do_web_auth(authorization_url)
|
|
71
|
+
# fetch tokens from web authentication response
|
|
72
|
+
self.fetch_tokens('https://mysmob.api.connect.skoda-auto.cz/api/v1/authentication/exchange-authorization-code?tokenType=CONNECT',
|
|
73
|
+
authorization_response=response, verifier=verifier)
|
|
74
|
+
except ReadTimeout as exc:
|
|
75
|
+
raise TemporaryAuthenticationError('Login timed out (Read timeout)') from exc
|
|
76
|
+
except ConnectionError as exc:
|
|
77
|
+
raise TemporaryAuthenticationError('Login failed due to connection error') from exc
|
|
72
78
|
|
|
73
79
|
def refresh(self) -> None:
|
|
74
80
|
# refresh tokens from refresh endpoint
|
|
@@ -118,7 +124,7 @@ class MySkodaSession(SkodaWebSession):
|
|
|
118
124
|
token_response = self.post(token_url, headers=request_headers, data=body, allow_redirects=False,
|
|
119
125
|
access_type=AccessType.NONE) # pyright: ignore reportCallIssue
|
|
120
126
|
if token_response.status_code != requests.codes['ok']:
|
|
121
|
-
raise TemporaryAuthenticationError(f'Token could not be fetched due to temporary
|
|
127
|
+
raise TemporaryAuthenticationError(f'Token could not be fetched due to temporary MySkoda failure: {token_response.status_code}')
|
|
122
128
|
# parse token from response body
|
|
123
129
|
token = self.parse_from_body(token_response.text)
|
|
124
130
|
return token
|
|
@@ -132,7 +138,7 @@ class MySkodaSession(SkodaWebSession):
|
|
|
132
138
|
# Tokens are in body of response in json format
|
|
133
139
|
token = json.loads(token_response)
|
|
134
140
|
except json.decoder.JSONDecodeError as err:
|
|
135
|
-
raise TemporaryAuthenticationError('Token could not be refreshed due to temporary
|
|
141
|
+
raise TemporaryAuthenticationError('Token could not be refreshed due to temporary MySkoda failure: json could not be decoded') from err
|
|
136
142
|
found_tokens: Set[str] = set()
|
|
137
143
|
# Fix token keys, we want access_token instead of accessToken
|
|
138
144
|
if 'accessToken' in token:
|
|
@@ -153,7 +153,7 @@ class OpenIDSession(requests.Session):
|
|
|
153
153
|
new_token['expires_in'] = self._token['expires_in']
|
|
154
154
|
else:
|
|
155
155
|
if 'id_token' in new_token:
|
|
156
|
-
meta_data = jwt.decode(new_token['id_token'],
|
|
156
|
+
meta_data = jwt.decode(new_token['id_token'], options={"verify_signature": False})
|
|
157
157
|
if 'exp' in meta_data:
|
|
158
158
|
new_token['expires_at'] = meta_data['exp']
|
|
159
159
|
expires_at = datetime.fromtimestamp(meta_data['exp'], tz=timezone.utc)
|
|
@@ -165,6 +165,10 @@ class OpenIDSession(requests.Session):
|
|
|
165
165
|
# If expires_in is set and expires_at is not set we calculate expires_at from expires_in using the current time
|
|
166
166
|
if 'expires_in' in new_token and 'expires_at' not in new_token:
|
|
167
167
|
new_token['expires_at'] = time.time() + int(new_token.get('expires_in'))
|
|
168
|
+
if new_token['expires_in'] > 3600:
|
|
169
|
+
LOG.warning('unexpected Token expires_in > 3600s (%d)', new_token['expires_in'])
|
|
170
|
+
if new_token['expires_at'] > (time.time() + 3600):
|
|
171
|
+
LOG.warning('unexpected Token expires_at after more than 3600s')
|
|
168
172
|
self._token = new_token
|
|
169
173
|
|
|
170
174
|
@property
|
|
@@ -132,7 +132,7 @@ class Capability(GenericObject):
|
|
|
132
132
|
LOCATION_DATA_DISABLED = 1013
|
|
133
133
|
LICENSE_INACTIVE = 2001
|
|
134
134
|
LICENSE_EXPIRED = 2002
|
|
135
|
-
|
|
135
|
+
LICENSE_MISSING = 2003
|
|
136
136
|
USER_NOT_VERIFIED = 3001
|
|
137
137
|
TERMS_AND_CONDITIONS_NOT_ACCEPTED = 3002
|
|
138
138
|
INSUFFICIENT_RIGHTS = 3003
|
|
@@ -22,7 +22,7 @@ from carconnectivity.units import Length, Speed, Power, Temperature
|
|
|
22
22
|
from carconnectivity.doors import Doors
|
|
23
23
|
from carconnectivity.windows import Windows
|
|
24
24
|
from carconnectivity.lights import Lights
|
|
25
|
-
from carconnectivity.drive import GenericDrive, ElectricDrive, CombustionDrive
|
|
25
|
+
from carconnectivity.drive import GenericDrive, ElectricDrive, CombustionDrive, DieselDrive
|
|
26
26
|
from carconnectivity.attributes import BooleanAttribute, DurationAttribute, TemperatureAttribute, EnumAttribute, LevelAttribute, \
|
|
27
27
|
CurrentAttribute
|
|
28
28
|
from carconnectivity.charging import Charging
|
|
@@ -407,7 +407,7 @@ class Connector(BaseConnector):
|
|
|
407
407
|
if vehicle is not None:
|
|
408
408
|
if vehicle.connection_state is not None and vehicle.connection_state.enabled \
|
|
409
409
|
and vehicle.connection_state.value == GenericVehicle.ConnectionState.OFFLINE:
|
|
410
|
-
vehicle.state._set_value(GenericVehicle.State.OFFLINE)
|
|
410
|
+
vehicle.state._set_value(GenericVehicle.State.OFFLINE) # pylint: disable=protected-access
|
|
411
411
|
elif vehicle.in_motion is not None and vehicle.in_motion.enabled and vehicle.in_motion.value:
|
|
412
412
|
vehicle.state._set_value(GenericVehicle.State.IGNITION_ON) # pylint: disable=protected-access
|
|
413
413
|
elif vehicle.position is not None and vehicle.position.enabled and vehicle.position.position_type is not None \
|
|
@@ -1301,10 +1301,11 @@ class Connector(BaseConnector):
|
|
|
1301
1301
|
else:
|
|
1302
1302
|
if engine_type == GenericDrive.Type.ELECTRIC:
|
|
1303
1303
|
drive = ElectricDrive(drive_id=drive_id, drives=vehicle.drives)
|
|
1304
|
+
elif engine_type == GenericDrive.Type.DIESEL:
|
|
1305
|
+
drive = DieselDrive(drive_id=drive_id, drives=vehicle.drives)
|
|
1304
1306
|
elif engine_type in [GenericDrive.Type.FUEL,
|
|
1305
1307
|
GenericDrive.Type.GASOLINE,
|
|
1306
1308
|
GenericDrive.Type.PETROL,
|
|
1307
|
-
GenericDrive.Type.DIESEL,
|
|
1308
1309
|
GenericDrive.Type.CNG,
|
|
1309
1310
|
GenericDrive.Type.LPG]:
|
|
1310
1311
|
drive = CombustionDrive(drive_id=drive_id, drives=vehicle.drives)
|
|
@@ -1335,9 +1336,22 @@ class Connector(BaseConnector):
|
|
|
1335
1336
|
'currentSoCInPercent',
|
|
1336
1337
|
'currentFuelLevelInPercent',
|
|
1337
1338
|
'remainingRangeInKm'})
|
|
1339
|
+
if 'adBlueRange' in range_data and range_data['adBlueRange'] is not None:
|
|
1340
|
+
# pylint: disable-next=protected-access
|
|
1341
|
+
for drive in vehicle.drives.drives.values():
|
|
1342
|
+
if isinstance(drive, DieselDrive):
|
|
1343
|
+
# pylint: disable-next=protected-access
|
|
1344
|
+
drive.adblue_range._set_value(value=range_data['adBlueRange'], measured=captured_at, unit=Length.KM)
|
|
1345
|
+
drive.adblue_range.precision = 1
|
|
1346
|
+
else:
|
|
1347
|
+
for drive in vehicle.drives.drives.values():
|
|
1348
|
+
if isinstance(drive, DieselDrive):
|
|
1349
|
+
# pylint: disable-next=protected-access
|
|
1350
|
+
drive.adblue_range._set_value(value=None, measured=captured_at, unit=Length.KM)
|
|
1338
1351
|
log_extra_keys(LOG_API, '/api/v2/vehicle-status/{vin}/driving-range', range_data, {'carCapturedTimestamp',
|
|
1339
1352
|
'carType',
|
|
1340
1353
|
'totalRangeInKm',
|
|
1354
|
+
'adBlueRange',
|
|
1341
1355
|
'primaryEngineRange',
|
|
1342
1356
|
'secondaryEngineRange'})
|
|
1343
1357
|
return vehicle
|
|
@@ -13,7 +13,7 @@ from datetime import timedelta, timezone
|
|
|
13
13
|
from paho.mqtt.client import Client
|
|
14
14
|
from paho.mqtt.enums import MQTTProtocolVersion, CallbackAPIVersion, MQTTErrorCode
|
|
15
15
|
|
|
16
|
-
from carconnectivity.errors import CarConnectivityError
|
|
16
|
+
from carconnectivity.errors import CarConnectivityError, TemporaryAuthenticationError
|
|
17
17
|
from carconnectivity.observable import Observable
|
|
18
18
|
from carconnectivity.vehicle import GenericVehicle
|
|
19
19
|
|
|
@@ -70,6 +70,8 @@ class SkodaMQTTClient(Client): # pylint: disable=too-many-instance-attributes
|
|
|
70
70
|
self.delayed_access_function_timers: Dict[str, threading.Timer] = {}
|
|
71
71
|
|
|
72
72
|
self.tls_set(cert_reqs=ssl.CERT_NONE)
|
|
73
|
+
|
|
74
|
+
self._retry_refresh_login_once = True
|
|
73
75
|
|
|
74
76
|
def connect(self, *args, **kwargs) -> MQTTErrorCode:
|
|
75
77
|
"""
|
|
@@ -98,7 +100,12 @@ class SkodaMQTTClient(Client): # pylint: disable=too-many-instance-attributes
|
|
|
98
100
|
del userdata
|
|
99
101
|
|
|
100
102
|
if self._skoda_connector.session.expired or self._skoda_connector.session.access_token is None:
|
|
101
|
-
|
|
103
|
+
try:
|
|
104
|
+
self._skoda_connector.session.refresh()
|
|
105
|
+
except ConnectionError as exc:
|
|
106
|
+
LOG.error('Token refresh failed due to connection error: %s', exc)
|
|
107
|
+
except TemporaryAuthenticationError as exc:
|
|
108
|
+
LOG.error('Token refresh failed due to temporary MySkoda error: %s', exc)
|
|
102
109
|
if not self._skoda_connector.session.expired and self._skoda_connector.session.access_token is not None:
|
|
103
110
|
# pylint: disable-next=attribute-defined-outside-init # this is a false positive, password has a setter in super class
|
|
104
111
|
self._password = self._skoda_connector.session.access_token # This is a bit hacky but if password attribute is used here there is an Exception
|
|
@@ -321,6 +328,7 @@ class SkodaMQTTClient(Client): # pylint: disable=too-many-instance-attributes
|
|
|
321
328
|
self._skoda_connector.car_connectivity.garage.add_observer(observer=self._on_carconnectivity_vehicle_enabled,
|
|
322
329
|
flag=observer_flags,
|
|
323
330
|
priority=Observable.ObserverPriority.USER_MID)
|
|
331
|
+
self._retry_refresh_login_once = True
|
|
324
332
|
self._subscribe_vehicles()
|
|
325
333
|
|
|
326
334
|
# Handle different reason codes
|
|
@@ -338,6 +346,15 @@ class SkodaMQTTClient(Client): # pylint: disable=too-many-instance-attributes
|
|
|
338
346
|
LOG.error('Could not connect (%s): Client identifier not valid', reason_code)
|
|
339
347
|
elif reason_code == 134:
|
|
340
348
|
LOG.error('Could not connect (%s): Bad user name or password', reason_code)
|
|
349
|
+
if self._retry_refresh_login_once == True:
|
|
350
|
+
self._retry_refresh_login_once = False
|
|
351
|
+
LOG.info('trying a relogin once to resolve the error')
|
|
352
|
+
try:
|
|
353
|
+
self._skoda_connector.session.login()
|
|
354
|
+
except TemporaryAuthenticationError as exc:
|
|
355
|
+
LOG.error('Login failed due to temporary MySkoda error: %s', exc)
|
|
356
|
+
except ConnectionError as exc:
|
|
357
|
+
LOG.error('Login failed due to connection error: %s', exc)
|
|
341
358
|
elif reason_code == 135:
|
|
342
359
|
LOG.error('Could not connect (%s): Not authorized', reason_code)
|
|
343
360
|
elif reason_code == 136:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/.gitignore
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{carconnectivity_connector_skoda-0.7.1a1 → carconnectivity_connector_skoda-0.8.1}/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
|