carconnectivity-connector-skoda 0.4a3__tar.gz → 0.4a5__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.4a3 → carconnectivity_connector_skoda-0.4a5}/PKG-INFO +2 -2
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/pyproject.toml +1 -1
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connector_skoda.egg-info/PKG-INFO +2 -2
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connector_skoda.egg-info/requires.txt +1 -1
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connectors/skoda/_version.py +1 -1
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connectors/skoda/auth/skoda_web_session.py +2 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connectors/skoda/connector.py +98 -4
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connectors/skoda/vehicle.py +4 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/.flake8 +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/.github/dependabot.yml +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/.github/workflows/build.yml +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/.github/workflows/build_and_publish.yml +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/.github/workflows/codeql-analysis.yml +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/.gitignore +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/CHANGELOG.md +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/LICENSE +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/Makefile +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/README.md +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/doc/Config.md +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/setup.cfg +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/setup_requirements.txt +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connector_skoda.egg-info/SOURCES.txt +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connector_skoda.egg-info/dependency_links.txt +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connector_skoda.egg-info/top_level.txt +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connectors/skoda/__init__.py +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connectors/skoda/auth/__init__.py +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connectors/skoda/auth/auth_util.py +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connectors/skoda/auth/helpers/blacklist_retry.py +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connectors/skoda/auth/my_skoda_session.py +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connectors/skoda/auth/openid_session.py +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connectors/skoda/auth/session_manager.py +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connectors/skoda/capability.py +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connectors/skoda/charging.py +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connectors/skoda/climatization.py +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connectors/skoda/command_impl.py +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connectors/skoda/error.py +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connectors/skoda/mqtt_client.py +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/src/carconnectivity_connectors/skoda/ui/connector_ui.py +0 -0
- {carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/test/integration_test/carConnectivity.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: carconnectivity-connector-skoda
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4a5
|
|
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.4a8
|
|
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.4a5
|
|
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.4a8
|
|
41
41
|
Requires-Dist: oauthlib~=3.2.2
|
|
42
42
|
Requires-Dist: requests~=2.32.3
|
|
43
43
|
Requires-Dist: jwt~=1.3.1
|
|
@@ -121,6 +121,8 @@ class SkodaWebSession(OpenIDSession):
|
|
|
121
121
|
raise RetrievalError('Temporary server error during login')
|
|
122
122
|
|
|
123
123
|
if 'Location' not in response.headers:
|
|
124
|
+
if 'consent' in url:
|
|
125
|
+
raise AuthenticationError('Could not find Location in headers, probably due to missing consent. Try visiting: ' + url)
|
|
124
126
|
raise APICompatibilityError('Forwarding without Location in headers')
|
|
125
127
|
|
|
126
128
|
url = response.headers['Location']
|
|
@@ -4,6 +4,7 @@ from typing import TYPE_CHECKING
|
|
|
4
4
|
|
|
5
5
|
import threading
|
|
6
6
|
import os
|
|
7
|
+
import traceback
|
|
7
8
|
import logging
|
|
8
9
|
import netrc
|
|
9
10
|
from datetime import datetime, timedelta, timezone
|
|
@@ -22,7 +23,7 @@ from carconnectivity.doors import Doors
|
|
|
22
23
|
from carconnectivity.windows import Windows
|
|
23
24
|
from carconnectivity.lights import Lights
|
|
24
25
|
from carconnectivity.drive import GenericDrive, ElectricDrive, CombustionDrive
|
|
25
|
-
from carconnectivity.attributes import BooleanAttribute, DurationAttribute, TemperatureAttribute
|
|
26
|
+
from carconnectivity.attributes import GenericAttribute, BooleanAttribute, DurationAttribute, TemperatureAttribute
|
|
26
27
|
from carconnectivity.charging import Charging
|
|
27
28
|
from carconnectivity.position import Position
|
|
28
29
|
from carconnectivity.climatization import Climatization
|
|
@@ -72,6 +73,7 @@ class Connector(BaseConnector):
|
|
|
72
73
|
"""
|
|
73
74
|
def __init__(self, connector_id: str, car_connectivity: CarConnectivity, config: Dict) -> None:
|
|
74
75
|
BaseConnector.__init__(self, connector_id=connector_id, car_connectivity=car_connectivity, config=config, log=LOG, api_log=LOG_API)
|
|
76
|
+
self._healthy = False
|
|
75
77
|
|
|
76
78
|
self._mqtt_client: SkodaMQTTClient = SkodaMQTTClient(skoda_connector=self)
|
|
77
79
|
|
|
@@ -81,6 +83,16 @@ class Connector(BaseConnector):
|
|
|
81
83
|
|
|
82
84
|
self.connected: BooleanAttribute = BooleanAttribute(name="connected", parent=self, tags={'connector_custom'})
|
|
83
85
|
self.interval: DurationAttribute = DurationAttribute(name="interval", parent=self, tags={'connector_custom'})
|
|
86
|
+
|
|
87
|
+
def __check_interval(attribute: GenericAttribute, value: Any) -> Any:
|
|
88
|
+
del attribute
|
|
89
|
+
if value is not None and value < timedelta(seconds=180):
|
|
90
|
+
raise ValueError('Intervall must be at least 180 seconds')
|
|
91
|
+
return value
|
|
92
|
+
|
|
93
|
+
self.interval._is_changeable = True # pylint: disable=protected-access
|
|
94
|
+
self.interval._add_on_set_hook(__check_interval) # pylint: disable=protected-access
|
|
95
|
+
|
|
84
96
|
self.commands: Commands = Commands(parent=self)
|
|
85
97
|
|
|
86
98
|
self.user_id: Optional[str] = None
|
|
@@ -154,12 +166,15 @@ class Connector(BaseConnector):
|
|
|
154
166
|
self._stop_event.clear()
|
|
155
167
|
# Start background thread for Rest API polling
|
|
156
168
|
self._background_thread = threading.Thread(target=self._background_loop, daemon=False)
|
|
169
|
+
self._background_thread.name = 'carconnectivity.connectors.skoda-background'
|
|
157
170
|
self._background_thread.start()
|
|
158
171
|
# Start background thread for MQTT connection
|
|
159
172
|
self._background_connect_thread = threading.Thread(target=self._background_connect_loop, daemon=False)
|
|
173
|
+
self._background_connect_thread.name = 'carconnectivity.connectors.skoda-background_connect'
|
|
160
174
|
self._background_connect_thread.start()
|
|
161
175
|
# Start MQTT thread
|
|
162
176
|
self._mqtt_client.loop_start()
|
|
177
|
+
self._healthy = True
|
|
163
178
|
|
|
164
179
|
def _background_connect_loop(self) -> None:
|
|
165
180
|
while not self._stop_event.is_set():
|
|
@@ -204,6 +219,10 @@ class Connector(BaseConnector):
|
|
|
204
219
|
except TemporaryAuthenticationError as err:
|
|
205
220
|
LOG.error('Temporary authentification error during update (%s). Will try again after configured interval of %ss', str(err), interval)
|
|
206
221
|
self._stop_event.wait(interval)
|
|
222
|
+
except Exception as err:
|
|
223
|
+
LOG.critical('Critical error during update: %s', traceback.format_exc())
|
|
224
|
+
self._healthy = False
|
|
225
|
+
raise err
|
|
207
226
|
else:
|
|
208
227
|
self._stop_event.wait(interval)
|
|
209
228
|
|
|
@@ -236,12 +255,12 @@ class Connector(BaseConnector):
|
|
|
236
255
|
self.car_connectivity.garage.remove_vehicle(vehicle.id)
|
|
237
256
|
vehicle.enabled = False
|
|
238
257
|
self._stop_event.set()
|
|
258
|
+
self.session.close()
|
|
239
259
|
if self._background_thread is not None:
|
|
240
260
|
self._background_thread.join()
|
|
241
261
|
if self._background_connect_thread is not None:
|
|
242
262
|
self._background_connect_thread.join()
|
|
243
263
|
self.persist()
|
|
244
|
-
self.session.close()
|
|
245
264
|
return super().shutdown()
|
|
246
265
|
|
|
247
266
|
def fetch_all(self) -> None:
|
|
@@ -339,6 +358,8 @@ class Connector(BaseConnector):
|
|
|
339
358
|
vehicle_to_update = self.fetch_vehicle_status(vehicle_to_update)
|
|
340
359
|
vehicle_to_update = self.fetch_driving_range(vehicle_to_update)
|
|
341
360
|
if vehicle_to_update.capabilities is not None and vehicle_to_update.capabilities.enabled:
|
|
361
|
+
if vehicle_to_update.capabilities.has_capability('READINESS'):
|
|
362
|
+
vehicle_to_update = self.fetch_connection_status(vehicle_to_update)
|
|
342
363
|
if vehicle_to_update.capabilities.has_capability('PARKING_POSITION'):
|
|
343
364
|
vehicle_to_update = self.fetch_position(vehicle_to_update)
|
|
344
365
|
if vehicle_to_update.capabilities.has_capability('CHARGING') and isinstance(vehicle_to_update, SkodaElectricVehicle):
|
|
@@ -347,6 +368,27 @@ class Connector(BaseConnector):
|
|
|
347
368
|
vehicle_to_update = self.fetch_air_conditioning(vehicle_to_update)
|
|
348
369
|
if vehicle_to_update.capabilities.has_capability('VEHICLE_HEALTH_INSPECTION'):
|
|
349
370
|
vehicle_to_update = self.fetch_maintenance(vehicle_to_update)
|
|
371
|
+
vehicle_to_update = self.decide_state(vehicle_to_update)
|
|
372
|
+
|
|
373
|
+
def decide_state(self, vehicle: SkodaVehicle) -> SkodaVehicle:
|
|
374
|
+
"""
|
|
375
|
+
Decides the state of the vehicle based on the current data.
|
|
376
|
+
|
|
377
|
+
Args:
|
|
378
|
+
vehicle (SkodaVehicle): The Skoda vehicle object.
|
|
379
|
+
|
|
380
|
+
Returns:
|
|
381
|
+
SkodaVehicle: The Skoda vehicle object with the updated state.
|
|
382
|
+
"""
|
|
383
|
+
if vehicle is not None:
|
|
384
|
+
if vehicle.in_motion is not None and vehicle.in_motion.enabled and vehicle.in_motion.value:
|
|
385
|
+
vehicle.state._set_value(GenericVehicle.State.IGNITION_ON) # pylint: disable=protected-access
|
|
386
|
+
elif vehicle.position is not None and vehicle.position.enabled and vehicle.position.position_type is not None \
|
|
387
|
+
and vehicle.position.position_type.enabled and vehicle.position.position_type.value == Position.PositionType.PARKING:
|
|
388
|
+
vehicle.state._set_value(GenericVehicle.State.PARKED) # pylint: disable=protected-access
|
|
389
|
+
else:
|
|
390
|
+
vehicle.state._set_value(None) # pylint: disable=protected-access
|
|
391
|
+
return vehicle
|
|
350
392
|
|
|
351
393
|
def fetch_charging(self, vehicle: SkodaElectricVehicle, no_cache: bool = False) -> SkodaElectricVehicle:
|
|
352
394
|
"""
|
|
@@ -555,6 +597,41 @@ class Connector(BaseConnector):
|
|
|
555
597
|
vehicle.charging.errors.clear()
|
|
556
598
|
log_extra_keys(LOG_API, 'charging data', data, {'carCapturedTimestamp', 'status', 'isVehicleInSavedLocation', 'errors', 'settings'})
|
|
557
599
|
return vehicle
|
|
600
|
+
|
|
601
|
+
def fetch_connection_status(self, vehicle: SkodaVehicle, no_cache: bool = False) -> SkodaVehicle:
|
|
602
|
+
"""
|
|
603
|
+
Fetches the connection status of the given Skoda vehicle and updates its connection attributes.
|
|
604
|
+
|
|
605
|
+
Args:
|
|
606
|
+
vehicle (SkodaVehicle): The Skoda vehicle object containing the VIN and connection attributes.
|
|
607
|
+
|
|
608
|
+
Returns:
|
|
609
|
+
SkodaVehicle: The updated Skoda vehicle object with the fetched connection data.
|
|
610
|
+
|
|
611
|
+
Raises:
|
|
612
|
+
APIError: If the VIN is missing.
|
|
613
|
+
ValueError: If the vehicle has no connection object.
|
|
614
|
+
"""
|
|
615
|
+
vin = vehicle.vin.value
|
|
616
|
+
if vin is None:
|
|
617
|
+
raise APIError('VIN is missing')
|
|
618
|
+
url = f'https://mysmob.api.connect.skoda-auto.cz/api/v2/connection-status/{vin}/readiness'
|
|
619
|
+
data: Dict[str, Any] | None = self._fetch_data(url=url, session=self.session, no_cache=no_cache)
|
|
620
|
+
# {'unreachable': False, 'inMotion': False, 'batteryProtectionLimitOn': False}
|
|
621
|
+
if data is not None:
|
|
622
|
+
if 'unreachable' in data and data['unreachable'] is not None:
|
|
623
|
+
if data['unreachable']:
|
|
624
|
+
vehicle.connection_state._set_value(vehicle.ConnectionState.OFFLINE) # pylint: disable=protected-access
|
|
625
|
+
else:
|
|
626
|
+
vehicle.connection_state._set_value(vehicle.ConnectionState.REACHABLE) # pylint: disable=protected-access
|
|
627
|
+
else:
|
|
628
|
+
vehicle.connection_state._set_value(None) # pylint: disable=protected-access
|
|
629
|
+
if 'inMotion' in data and data['inMotion'] is not None:
|
|
630
|
+
vehicle.in_motion._set_value(data['inMotion']) # pylint: disable=protected-access
|
|
631
|
+
else:
|
|
632
|
+
vehicle.in_motion._set_value(None) # pylint: disable=protected-access
|
|
633
|
+
log_extra_keys(LOG_API, 'connection status', data, {'unreachable'})
|
|
634
|
+
return vehicle
|
|
558
635
|
|
|
559
636
|
def fetch_position(self, vehicle: SkodaVehicle, no_cache: bool = False) -> SkodaVehicle:
|
|
560
637
|
"""
|
|
@@ -716,12 +793,19 @@ class Connector(BaseConnector):
|
|
|
716
793
|
# pylint: disable-next=protected-access
|
|
717
794
|
vehicle.climatization.settings.target_temperature._add_on_set_hook(self.__on_air_conditioning_target_temperature_change)
|
|
718
795
|
vehicle.climatization.settings.target_temperature._is_changeable = True # pylint: disable=protected-access
|
|
796
|
+
precision: float = 0.5
|
|
797
|
+
min_temperature: Optional[float] = None
|
|
798
|
+
max_temperature: Optional[float] = None
|
|
719
799
|
unit: Temperature = Temperature.UNKNOWN
|
|
720
800
|
if 'unitInCar' in data['targetTemperature'] and data['targetTemperature']['unitInCar'] is not None:
|
|
721
801
|
if data['targetTemperature']['unitInCar'] == 'CELSIUS':
|
|
722
802
|
unit = Temperature.C
|
|
803
|
+
min_temperature: Optional[float] = 16
|
|
804
|
+
max_temperature: Optional[float] = 29.5
|
|
723
805
|
elif data['targetTemperature']['unitInCar'] == 'FAHRENHEIT':
|
|
724
806
|
unit = Temperature.F
|
|
807
|
+
min_temperature: Optional[float] = 61
|
|
808
|
+
max_temperature: Optional[float] = 85
|
|
725
809
|
elif data['targetTemperature']['unitInCar'] == 'KELVIN':
|
|
726
810
|
unit = Temperature.K
|
|
727
811
|
else:
|
|
@@ -731,6 +815,10 @@ class Connector(BaseConnector):
|
|
|
731
815
|
vehicle.climatization.settings.target_temperature._set_value(value=data['targetTemperature']['temperatureValue'],
|
|
732
816
|
measured=captured_at,
|
|
733
817
|
unit=unit)
|
|
818
|
+
vehicle.climatization.settings.target_temperature.precision = precision
|
|
819
|
+
vehicle.climatization.settings.target_temperature.minimum = min_temperature
|
|
820
|
+
vehicle.climatization.settings.target_temperature.maximum = max_temperature
|
|
821
|
+
|
|
734
822
|
else:
|
|
735
823
|
# pylint: disable-next=protected-access
|
|
736
824
|
vehicle.climatization.settings.target_temperature._set_value(value=None, measured=captured_at, unit=unit)
|
|
@@ -1428,9 +1516,10 @@ class Connector(BaseConnector):
|
|
|
1428
1516
|
if command_arguments['command'] == ClimatizationStartStopCommand.Command.START:
|
|
1429
1517
|
command_dict['heaterSource'] = 'ELECTRIC'
|
|
1430
1518
|
command_dict['targetTemperature'] = {}
|
|
1519
|
+
precision: float = 0.5
|
|
1431
1520
|
if 'target_temperature' in command_arguments:
|
|
1432
1521
|
# Round target temperature to nearest 0.5
|
|
1433
|
-
command_dict['targetTemperature']['temperatureValue'] = round(command_arguments['target_temperature']
|
|
1522
|
+
command_dict['targetTemperature']['temperatureValue'] = round(command_arguments['target_temperature'] / precision) * precision
|
|
1434
1523
|
if 'target_temperature_unit' in command_arguments:
|
|
1435
1524
|
if not isinstance(command_arguments['target_temperature_unit'], Temperature):
|
|
1436
1525
|
raise CommandError('Temperature unit is not of type Temperature')
|
|
@@ -1448,8 +1537,10 @@ class Connector(BaseConnector):
|
|
|
1448
1537
|
and isinstance(climatization, Climatization) and climatization.settings is not None \
|
|
1449
1538
|
and climatization.settings.target_temperature is not None and climatization.settings.target_temperature.enabled \
|
|
1450
1539
|
and climatization.settings.target_temperature.value is not None: # pylint: disable=too-many-boolean-expressions
|
|
1540
|
+
if climatization.settings.target_temperature.precision is not None:
|
|
1541
|
+
precision = climatization.settings.target_temperature.precision
|
|
1451
1542
|
# Round target temperature to nearest 0.5
|
|
1452
|
-
command_dict['targetTemperature']['temperatureValue'] = round(climatization.settings.target_temperature.value
|
|
1543
|
+
command_dict['targetTemperature']['temperatureValue'] = round(climatization.settings.target_temperature.value / precision) * precision
|
|
1453
1544
|
if climatization.settings.target_temperature.unit == Temperature.C:
|
|
1454
1545
|
command_dict['targetTemperature']['unitInCar'] = 'CELSIUS'
|
|
1455
1546
|
elif climatization.settings.target_temperature.unit == Temperature.F:
|
|
@@ -1681,3 +1772,6 @@ class Connector(BaseConnector):
|
|
|
1681
1772
|
except requests.exceptions.RetryError as retry_error:
|
|
1682
1773
|
raise CommandError(f'Retrying failed: {retry_error}') from retry_error
|
|
1683
1774
|
return command_arguments
|
|
1775
|
+
|
|
1776
|
+
def is_healthy(self) -> bool:
|
|
1777
|
+
return self._healthy and super().is_healthy()
|
|
@@ -4,6 +4,7 @@ from typing import TYPE_CHECKING
|
|
|
4
4
|
|
|
5
5
|
from carconnectivity.vehicle import GenericVehicle, ElectricVehicle, CombustionVehicle, HybridVehicle
|
|
6
6
|
from carconnectivity.charging import Charging
|
|
7
|
+
from carconnectivity.attributes import BooleanAttribute
|
|
7
8
|
|
|
8
9
|
from carconnectivity_connectors.skoda.capability import Capabilities
|
|
9
10
|
from carconnectivity_connectors.skoda.charging import SkodaCharging
|
|
@@ -32,6 +33,8 @@ class SkodaVehicle(GenericVehicle): # pylint: disable=too-many-instance-attribu
|
|
|
32
33
|
super().__init__(origin=origin)
|
|
33
34
|
self.capabilities: Capabilities = origin.capabilities
|
|
34
35
|
self.capabilities.parent = self
|
|
36
|
+
self.in_motion: BooleanAttribute = origin.in_motion
|
|
37
|
+
self.in_motion.parent = self
|
|
35
38
|
if SUPPORT_IMAGES:
|
|
36
39
|
self._car_images = origin._car_images
|
|
37
40
|
|
|
@@ -39,6 +42,7 @@ class SkodaVehicle(GenericVehicle): # pylint: disable=too-many-instance-attribu
|
|
|
39
42
|
super().__init__(vin=vin, garage=garage, managing_connector=managing_connector)
|
|
40
43
|
self.climatization = SkodaClimatization(vehicle=self, origin=self.climatization)
|
|
41
44
|
self.capabilities = Capabilities(vehicle=self)
|
|
45
|
+
self.in_motion = BooleanAttribute(name='in_motion', parent=self, tags={'connector_custom'})
|
|
42
46
|
if SUPPORT_IMAGES:
|
|
43
47
|
self._car_images: Dict[str, Image.Image] = {}
|
|
44
48
|
self.manufacturer._set_value(value='Škoda') # pylint: disable=protected-access
|
|
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.4a3 → carconnectivity_connector_skoda-0.4a5}/CHANGELOG.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{carconnectivity_connector_skoda-0.4a3 → carconnectivity_connector_skoda-0.4a5}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|