diff --git a/custom_components/tesla_custom/__init__.py b/custom_components/tesla_custom/__init__.py index 54e78f35..2e3b8d7e 100644 --- a/custom_components/tesla_custom/__init__.py +++ b/custom_components/tesla_custom/__init__.py @@ -1,6 +1,7 @@ """Support for Tesla cars.""" import asyncio from datetime import timedelta +from functools import partial from http import HTTPStatus import logging @@ -39,6 +40,7 @@ PLATFORMS, ) from .services import async_setup_services, async_unload_services +from .util import SSL_CONTEXT _LOGGER = logging.getLogger(__name__) @@ -126,7 +128,9 @@ async def async_setup_entry(hass, config_entry): config = config_entry.data # Because users can have multiple accounts, we always # create a new session so they have separate cookies - async_client = httpx.AsyncClient(headers={USER_AGENT: SERVER_SOFTWARE}, timeout=60) + async_client = httpx.AsyncClient( + headers={USER_AGENT: SERVER_SOFTWARE}, timeout=60, verify=SSL_CONTEXT + ) email = config_entry.title if not hass.data[DOMAIN]: @@ -193,7 +197,18 @@ async def _async_close_client(*_): @callback def _async_create_close_task(): - asyncio.create_task(_async_close_client()) + # Background tasks are tracked in HA to prevent them from + # being garbage collected in the middle of the task since + # asyncio only holds a weak reference to them. + # + # https://docs.python.org/3/library/asyncio-task.html#creating-tasks + + if hasattr(hass, "async_create_background_task"): + hass.async_create_background_task( + _async_close_client(), "tesla_close_client" + ) + else: + asyncio.create_task(_async_close_client()) config_entry.async_on_unload( hass.bus.async_listen_once(EVENT_HOMEASSISTANT_CLOSE, _async_close_client) @@ -201,9 +216,6 @@ def _async_create_close_task(): config_entry.async_on_unload(_async_create_close_task) _async_save_tokens(hass, config_entry, access_token, refresh_token, expiration) - coordinator = TeslaDataUpdateCoordinator( - hass, config_entry=config_entry, controller=controller - ) try: if config_entry.data.get("initial_setup"): @@ -254,15 +266,38 @@ def _async_create_close_task(): return False + reload_lock = asyncio.Lock() + _partial_coordinator = partial( + TeslaDataUpdateCoordinator, + hass, + config_entry=config_entry, + controller=controller, + reload_lock=reload_lock, + energy_site_ids=set(), + vins=set(), + update_vehicles=False, + ) + coordinators = { + "update_vehicles": _partial_coordinator(update_vehicles=True), + **{ + energy_site_id: _partial_coordinator(energy_site_ids={energy_site_id}) + for energy_site_id in energysites + }, + **{vin: _partial_coordinator(vins={vin}) for vin in cars}, + } + hass.data[DOMAIN][config_entry.entry_id] = { - "coordinator": coordinator, + "controller": controller, + "coordinators": coordinators, "cars": cars, "energysites": energysites, DATA_LISTENER: [config_entry.add_update_listener(update_listener)], } _LOGGER.debug("Connected to the Tesla API") - await coordinator.async_config_entry_first_refresh() + # We do not do a first refresh as we already know the API is working + # from above. Each platform will schedule a refresh via update_before_add + # for the sites/vehicles they are interested in. await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS) @@ -274,11 +309,11 @@ async def async_unload_entry(hass, config_entry) -> bool: unload_ok = await hass.config_entries.async_unload_platforms( config_entry, PLATFORMS ) - await hass.data[DOMAIN].get(config_entry.entry_id)[ - "coordinator" - ].controller.disconnect() + entry_data = hass.data[DOMAIN][config_entry.entry_id] + controller: TeslaAPI = entry_data["controller"] + await controller.disconnect() - for listener in hass.data[DOMAIN][config_entry.entry_id][DATA_LISTENER]: + for listener in entry_data[DATA_LISTENER]: listener() username = config_entry.title @@ -296,7 +331,8 @@ async def async_unload_entry(hass, config_entry) -> bool: async def update_listener(hass, config_entry): """Update when config_entry options update.""" - controller = hass.data[DOMAIN][config_entry.entry_id]["coordinator"].controller + entry_data = hass.data[DOMAIN][config_entry.entry_id] + controller: TeslaAPI = entry_data["controller"] old_update_interval = controller.update_interval controller.update_interval = config_entry.options.get( CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL @@ -312,10 +348,24 @@ async def update_listener(hass, config_entry): class TeslaDataUpdateCoordinator(DataUpdateCoordinator): """Class to manage fetching Tesla data.""" - def __init__(self, hass, *, config_entry, controller: TeslaAPI): + def __init__( + self, + hass, + *, + config_entry, + controller: TeslaAPI, + reload_lock: asyncio.Lock, + vins: set[str], + energy_site_ids: set[str], + update_vehicles: bool, + ): """Initialize global Tesla data updater.""" self.controller = controller self.config_entry = config_entry + self.reload_lock = reload_lock + self.vins = vins + self.energy_site_ids = energy_site_ids + self.update_vehicles = update_vehicles update_interval = timedelta(seconds=MIN_SCAN_INTERVAL) @@ -329,6 +379,8 @@ def __init__(self, hass, *, config_entry, controller: TeslaAPI): async def _async_update_data(self): """Fetch data from API endpoint.""" if self.controller.is_token_refreshed(): + # It doesn't matter which coordinator calls this, as long as there + # are no awaits in the below code, it will be called only once. result = self.controller.get_tokens() refresh_token = result["refresh_token"] access_token = result["access_token"] @@ -343,8 +395,19 @@ async def _async_update_data(self): # handled by the data update coordinator. async with async_timeout.timeout(30): _LOGGER.debug("Running controller.update()") - return await self.controller.update() + return await self.controller.update( + vins=self.vins, + energy_site_ids=self.energy_site_ids, + update_vehicles=self.update_vehicles, + ) except IncompleteCredentials: - await self.hass.config_entries.async_reload(self.config_entry.entry_id) + if self.reload_lock.locked(): + # Any of the coordinators can trigger a reload, but we only + # want to do it once. If the lock is already locked, we know + # another coordinator is already reloading. + _LOGGER.debug("Config entry is already being reloaded") + return + async with self.reload_lock: + await self.hass.config_entries.async_reload(self.config_entry.entry_id) except TeslaException as err: raise UpdateFailed(f"Error communicating with API: {err}") from err diff --git a/custom_components/tesla_custom/binary_sensor.py b/custom_components/tesla_custom/binary_sensor.py index c2e9034f..741feca8 100644 --- a/custom_components/tesla_custom/binary_sensor.py +++ b/custom_components/tesla_custom/binary_sensor.py @@ -19,12 +19,14 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entities): """Set up the Tesla selects by config_entry.""" - coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"] - cars = hass.data[DOMAIN][config_entry.entry_id]["cars"] - energysites = hass.data[DOMAIN][config_entry.entry_id]["energysites"] + entry_data = hass.data[DOMAIN][config_entry.entry_id] + coordinators = entry_data["coordinators"] + cars = entry_data["cars"] + energysites = entry_data["energysites"] entities = [] - for car in cars.values(): + for vin, car in cars.items(): + coordinator = coordinators[vin] entities.append(TeslaCarParkingBrake(hass, car, coordinator)) entities.append(TeslaCarOnline(hass, car, coordinator)) entities.append(TeslaCarAsleep(hass, car, coordinator)) @@ -35,12 +37,13 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entitie entities.append(TeslaCarScheduledDeparture(hass, car, coordinator)) entities.append(TeslaCarUserPresent(hass, car, coordinator)) - for energysite in energysites.values(): + for energy_site_id, energysite in energysites.items(): + coordinator = coordinators[energy_site_id] if energysite.resource_type == RESOURCE_TYPE_BATTERY: entities.append(TeslaEnergyBatteryCharging(hass, energysite, coordinator)) entities.append(TeslaEnergyGridStatus(hass, energysite, coordinator)) - async_add_entities(entities, True) + async_add_entities(entities, update_before_add=True) class TeslaCarParkingBrake(TeslaCarEntity, BinarySensorEntity): diff --git a/custom_components/tesla_custom/button.py b/custom_components/tesla_custom/button.py index 11a0c657..d5431541 100644 --- a/custom_components/tesla_custom/button.py +++ b/custom_components/tesla_custom/button.py @@ -15,11 +15,13 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entities): """Set up the Tesla selects by config_entry.""" - coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"] - cars = hass.data[DOMAIN][config_entry.entry_id]["cars"] + entry_data = hass.data[DOMAIN][config_entry.entry_id] + coordinators = entry_data["coordinators"] + cars = entry_data["cars"] entities = [] - for car in cars.values(): + for vin, car in cars.items(): + coordinator = coordinators[vin] entities.append(TeslaCarHorn(hass, car, coordinator)) entities.append(TeslaCarFlashLights(hass, car, coordinator)) entities.append(TeslaCarWakeUp(hass, car, coordinator)) @@ -28,7 +30,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entitie entities.append(TeslaCarRemoteStart(hass, car, coordinator)) entities.append(TeslaCarEmissionsTest(hass, car, coordinator)) - async_add_entities(entities, True) + async_add_entities(entities, update_before_add=True) class TeslaCarHorn(TeslaCarEntity, ButtonEntity): diff --git a/custom_components/tesla_custom/climate.py b/custom_components/tesla_custom/climate.py index e1390736..0f689a61 100644 --- a/custom_components/tesla_custom/climate.py +++ b/custom_components/tesla_custom/climate.py @@ -34,18 +34,19 @@ async def async_setup_entry( hass: HomeAssistant, config_entry, async_add_entities ) -> None: """Set up the Tesla climate by config_entry.""" - coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"] - cars = hass.data[DOMAIN][config_entry.entry_id]["cars"] + entry_data = hass.data[DOMAIN][config_entry.entry_id] + coordinators = entry_data["coordinators"] + cars = entry_data["cars"] entities = [ TeslaCarClimate( hass, car, - coordinator, + coordinators[vin], ) - for car in cars.values() + for vin, car in cars.items() ] - async_add_entities(entities, True) + async_add_entities(entities, update_before_add=True) class TeslaCarClimate(TeslaCarEntity, ClimateEntity): diff --git a/custom_components/tesla_custom/config_flow.py b/custom_components/tesla_custom/config_flow.py index cf424509..5418d319 100644 --- a/custom_components/tesla_custom/config_flow.py +++ b/custom_components/tesla_custom/config_flow.py @@ -34,6 +34,7 @@ DOMAIN, MIN_SCAN_INTERVAL, ) +from .util import SSL_CONTEXT _LOGGER = logging.getLogger(__name__) @@ -173,7 +174,9 @@ async def validate_input(hass: core.HomeAssistant, data) -> dict: """ config = {} - async_client = httpx.AsyncClient(headers={USER_AGENT: SERVER_SOFTWARE}, timeout=60) + async_client = httpx.AsyncClient( + headers={USER_AGENT: SERVER_SOFTWARE}, timeout=60, verify=SSL_CONTEXT + ) try: controller = TeslaAPI( diff --git a/custom_components/tesla_custom/cover.py b/custom_components/tesla_custom/cover.py index f97011d5..1e5c58d3 100644 --- a/custom_components/tesla_custom/cover.py +++ b/custom_components/tesla_custom/cover.py @@ -18,17 +18,19 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entities): """Set up the Tesla locks by config_entry.""" - coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"] - cars = hass.data[DOMAIN][config_entry.entry_id]["cars"] + entry_data = hass.data[DOMAIN][config_entry.entry_id] + coordinators = entry_data["coordinators"] + cars = entry_data["cars"] entities = [] - for car in cars.values(): + for vin, car in cars.items(): + coordinator = coordinators[vin] entities.append(TeslaCarChargerDoor(hass, car, coordinator)) entities.append(TeslaCarFrunk(hass, car, coordinator)) entities.append(TeslaCarTrunk(hass, car, coordinator)) entities.append(TeslaCarWindows(hass, car, coordinator)) - async_add_entities(entities, True) + async_add_entities(entities, update_before_add=True) class TeslaCarChargerDoor(TeslaCarEntity, CoverEntity): diff --git a/custom_components/tesla_custom/device_tracker.py b/custom_components/tesla_custom/device_tracker.py index 57d6d7a9..ccfcaa36 100644 --- a/custom_components/tesla_custom/device_tracker.py +++ b/custom_components/tesla_custom/device_tracker.py @@ -15,15 +15,17 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entities): """Set up the Tesla device trackers by config_entry.""" - coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"] - cars = hass.data[DOMAIN][config_entry.entry_id]["cars"] + entry_data = hass.data[DOMAIN][config_entry.entry_id] + coordinators = entry_data["coordinators"] + cars = entry_data["cars"] entities = [] - for car in cars.values(): + for vin, car in cars.items(): + coordinator = coordinators[vin] entities.append(TeslaCarLocation(hass, car, coordinator)) entities.append(TeslaCarDestinationLocation(hass, car, coordinator)) - async_add_entities(entities, True) + async_add_entities(entities, update_before_add=True) class TeslaCarLocation(TeslaCarEntity, TrackerEntity): diff --git a/custom_components/tesla_custom/lock.py b/custom_components/tesla_custom/lock.py index 9b4ba91a..99f251b5 100644 --- a/custom_components/tesla_custom/lock.py +++ b/custom_components/tesla_custom/lock.py @@ -14,15 +14,17 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entities): """Set up the Tesla locks by config_entry.""" - coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"] - cars = hass.data[DOMAIN][config_entry.entry_id]["cars"] + entry_data = hass.data[DOMAIN][config_entry.entry_id] + coordinators = entry_data["coordinators"] + cars = entry_data["cars"] entities = [] - for car in cars.values(): + for vin, car in cars.items(): + coordinator = coordinators[vin] entities.append(TeslaCarDoors(hass, car, coordinator)) entities.append(TeslaCarChargePortLatch(hass, car, coordinator)) - async_add_entities(entities, True) + async_add_entities(entities, update_before_add=True) class TeslaCarDoors(TeslaCarEntity, LockEntity): diff --git a/custom_components/tesla_custom/manifest.json b/custom_components/tesla_custom/manifest.json index 8b477948..b92181b3 100644 --- a/custom_components/tesla_custom/manifest.json +++ b/custom_components/tesla_custom/manifest.json @@ -22,6 +22,6 @@ "iot_class": "cloud_polling", "issue_tracker": "https://github.com/alandtse/tesla/issues", "loggers": ["teslajsonpy"], - "requirements": ["teslajsonpy==3.7.5"], + "requirements": ["teslajsonpy==3.8.0"], "version": "3.10.4" } diff --git a/custom_components/tesla_custom/number.py b/custom_components/tesla_custom/number.py index 91837567..2f22443d 100644 --- a/custom_components/tesla_custom/number.py +++ b/custom_components/tesla_custom/number.py @@ -19,20 +19,23 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entities): """Set up the Tesla numbers by config_entry.""" - coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"] - cars = hass.data[DOMAIN][config_entry.entry_id]["cars"] - energysites = hass.data[DOMAIN][config_entry.entry_id]["energysites"] + entry_data = hass.data[DOMAIN][config_entry.entry_id] + coordinators = entry_data["coordinators"] + cars = entry_data["cars"] + energysites = entry_data["energysites"] entities = [] - for car in cars.values(): + for vin, car in cars.items(): + coordinator = coordinators[vin] entities.append(TeslaCarChargeLimit(hass, car, coordinator)) entities.append(TeslaCarChargingAmps(hass, car, coordinator)) - for energysite in energysites.values(): + for energy_site_id, energysite in energysites.items(): + coordinator = coordinators[energy_site_id] if energysite.resource_type == RESOURCE_TYPE_BATTERY: entities.append(TeslaEnergyBackupReserve(hass, energysite, coordinator)) - async_add_entities(entities, True) + async_add_entities(entities, update_before_add=True) class TeslaCarChargeLimit(TeslaCarEntity, NumberEntity): diff --git a/custom_components/tesla_custom/select.py b/custom_components/tesla_custom/select.py index 13c95c2e..edd8abde 100644 --- a/custom_components/tesla_custom/select.py +++ b/custom_components/tesla_custom/select.py @@ -69,12 +69,14 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entities): """Set up the Tesla selects by config_entry.""" - coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"] - cars = hass.data[DOMAIN][config_entry.entry_id]["cars"] - energysites = hass.data[DOMAIN][config_entry.entry_id]["energysites"] + entry_data = hass.data[DOMAIN][config_entry.entry_id] + coordinators = entry_data["coordinators"] + cars = entry_data["cars"] + energysites = entry_data["energysites"] entities = [] - for car in cars.values(): + for vin, car in cars.items(): + coordinator = coordinators[vin] entities.append(TeslaCarCabinOverheatProtection(hass, car, coordinator)) for seat_name in SEAT_ID_MAP: if "rear" in seat_name and not car.rear_seat_heaters: @@ -87,14 +89,15 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entitie continue entities.append(TeslaCarHeatedSeat(hass, car, coordinator, seat_name)) - for energysite in energysites.values(): + for energy_site_id, energysite in energysites.items(): + coordinator = coordinators[energy_site_id] if energysite.resource_type == RESOURCE_TYPE_BATTERY: entities.append(TeslaEnergyOperationMode(hass, energysite, coordinator)) if energysite.resource_type == RESOURCE_TYPE_BATTERY and energysite.has_solar: entities.append(TeslaEnergyExportRule(hass, energysite, coordinator)) entities.append(TeslaEnergyGridCharging(hass, energysite, coordinator)) - async_add_entities(entities, True) + async_add_entities(entities, update_before_add=True) class TeslaCarHeatedSeat(TeslaCarEntity, SelectEntity): diff --git a/custom_components/tesla_custom/sensor.py b/custom_components/tesla_custom/sensor.py index 74c8d479..8e27fc82 100644 --- a/custom_components/tesla_custom/sensor.py +++ b/custom_components/tesla_custom/sensor.py @@ -53,12 +53,14 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entities): """Set up the Tesla Sensors by config_entry.""" - coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"] - cars = hass.data[DOMAIN][config_entry.entry_id]["cars"] - energysites = hass.data[DOMAIN][config_entry.entry_id]["energysites"] + entry_data = hass.data[DOMAIN][config_entry.entry_id] + coordinators = entry_data["coordinators"] + cars = entry_data["cars"] + energysites = entry_data["energysites"] entities = [] - for car in cars.values(): + for vin, car in cars.items(): + coordinator = coordinators[vin] entities.append(TeslaCarBattery(hass, car, coordinator)) entities.append(TeslaCarChargerRate(hass, car, coordinator)) entities.append(TeslaCarChargerEnergy(hass, car, coordinator)) @@ -75,7 +77,8 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entitie entities.append(TeslaCarArrivalTime(hass, car, coordinator)) entities.append(TeslaCarDistanceToArrival(hass, car, coordinator)) - for energysite in energysites.values(): + for energy_site_id, energysite in energysites.items(): + coordinator = coordinators[energy_site_id] if ( energysite.resource_type == RESOURCE_TYPE_SOLAR and energysite.has_load_meter @@ -98,7 +101,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entitie TeslaEnergyPowerSensor(hass, energysite, coordinator, sensor_type) ) - async_add_entities(entities, True) + async_add_entities(entities, update_before_add=True) class TeslaCarBattery(TeslaCarEntity, SensorEntity): diff --git a/custom_components/tesla_custom/services.py b/custom_components/tesla_custom/services.py index c2157f06..06e673d2 100644 --- a/custom_components/tesla_custom/services.py +++ b/custom_components/tesla_custom/services.py @@ -95,7 +95,8 @@ async def api(call): and entry.title != email ): continue - controller = hass.data[DOMAIN].get(entry.entry_id)["coordinator"].controller + entry_data = hass.data[DOMAIN][entry.entry_id] + controller = entry_data["controller"] if controller is None: raise ValueError(f"No Tesla controllers found for email {email}") command = call.data.get(ATTR_COMMAND) @@ -134,7 +135,8 @@ async def set_update_interval(call): and entry.title != email ): continue - controller = hass.data[DOMAIN].get(entry.entry_id)["coordinator"].controller + entry_data = hass.data[DOMAIN][entry.entry_id] + controller = entry_data["controller"] if controller is None: raise ValueError(f"No Tesla controllers found for email {email}") diff --git a/custom_components/tesla_custom/switch.py b/custom_components/tesla_custom/switch.py index a71564de..f934bec8 100644 --- a/custom_components/tesla_custom/switch.py +++ b/custom_components/tesla_custom/switch.py @@ -15,18 +15,20 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entities): """Set up the Tesla switches by config_entry.""" - coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"] - cars = hass.data[DOMAIN][config_entry.entry_id]["cars"] + entry_data = hass.data[DOMAIN][config_entry.entry_id] + coordinators = entry_data["coordinators"] + cars = entry_data["cars"] entities = [] - for car in cars.values(): + for vin, car in cars.items(): + coordinator = coordinators[vin] entities.append(TeslaCarHeatedSteeringWheel(hass, car, coordinator)) entities.append(TeslaCarSentryMode(hass, car, coordinator)) entities.append(TeslaCarPolling(hass, car, coordinator)) entities.append(TeslaCarCharger(hass, car, coordinator)) entities.append(TeslaCarValetMode(hass, car, coordinator)) - async_add_entities(entities, True) + async_add_entities(entities, update_before_add=True) class TeslaCarHeatedSteeringWheel(TeslaCarEntity, SwitchEntity): diff --git a/custom_components/tesla_custom/update.py b/custom_components/tesla_custom/update.py index 2667fafe..e53112e1 100644 --- a/custom_components/tesla_custom/update.py +++ b/custom_components/tesla_custom/update.py @@ -12,18 +12,19 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entities): """Set up the Tesla update entities by config_entry.""" - coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"] - cars = hass.data[DOMAIN][config_entry.entry_id]["cars"] + entry_data = hass.data[DOMAIN][config_entry.entry_id] + coordinators = entry_data["coordinators"] + cars = entry_data["cars"] entities = [ TeslaCarUpdate( hass, car, - coordinator, + coordinators[vin], ) - for car in cars.values() + for vin, car in cars.items() ] - async_add_entities(entities, True) + async_add_entities(entities, update_before_add=True) INSTALLABLE_STATUSES = ["available", "scheduled"] diff --git a/custom_components/tesla_custom/util.py b/custom_components/tesla_custom/util.py new file mode 100644 index 00000000..8394de6d --- /dev/null +++ b/custom_components/tesla_custom/util.py @@ -0,0 +1,11 @@ +"""Utilities for tesla.""" + +try: + # Home Assistant 2023.4.x+ + from homeassistant.util.ssl import get_default_context + + SSL_CONTEXT = get_default_context() +except ImportError: + from homeassistant.util.ssl import client_context + + SSL_CONTEXT = client_context() diff --git a/poetry.lock b/poetry.lock index f83c7430..94f8dce5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.4.1 and should not be changed by hand. +# This file is automatically @generated by Poetry and should not be changed by hand. [[package]] name = "aiohttp" @@ -3010,14 +3010,14 @@ tests = ["pytest", "pytest-cov"] [[package]] name = "teslajsonpy" -version = "3.7.5" +version = "3.8.0" description = "A library to work with Tesla API." category = "main" optional = false python-versions = ">=3.7,<4.0" files = [ - {file = "teslajsonpy-3.7.5-py3-none-any.whl", hash = "sha256:17f6512a3dabb824ea9c22499495b0c51ba751aac3eb6e933aff5695a2ff3363"}, - {file = "teslajsonpy-3.7.5.tar.gz", hash = "sha256:e0fb861391a223f23d0aa59d944926d9eb2a43436943fa38c70f8472db0456ef"}, + {file = "teslajsonpy-3.8.0-py3-none-any.whl", hash = "sha256:e602ea5b76ed55d5a35ceafecfa56b33302eb7ef8563d3f4ad2412baf497b935"}, + {file = "teslajsonpy-3.8.0.tar.gz", hash = "sha256:562eb49d9b06c06a30694968fd61f587ad0eb28932ab0316f68fa85cc2581f04"}, ] [package.dependencies] @@ -3373,4 +3373,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "daf774bc715e26dfdba0dc2524b3afe3276c8a9774d66d2048f4e156fa7f1e2a" +content-hash = "305a72c3c821c7f605f11f4cbf4785bbc24152551b38ff5cb94d317efafeeeee" diff --git a/pyproject.toml b/pyproject.toml index 8b962c67..d3e579f9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ license = "Apache-2.0" [tool.poetry.dependencies] python = "^3.10" -teslajsonpy = "^3.7.5" +teslajsonpy = "^3.8.0" [tool.poetry.group.dev.dependencies]