From 98ecf2888ce143dab56e7654e559de633531bc75 Mon Sep 17 00:00:00 2001 From: Alan Tse Date: Wed, 8 Sep 2021 22:12:03 -0700 Subject: [PATCH] Remove tesla integration (#55988) Co-authored-by: Paulus Schoutsen --- .coveragerc | 8 - CODEOWNERS | 1 - homeassistant/components/tesla/__init__.py | 357 ------------------ .../components/tesla/binary_sensor.py | 39 -- homeassistant/components/tesla/climate.py | 120 ------ homeassistant/components/tesla/config_flow.py | 191 ---------- homeassistant/components/tesla/const.py | 33 -- .../components/tesla/device_tracker.py | 57 --- homeassistant/components/tesla/lock.py | 41 -- homeassistant/components/tesla/manifest.json | 23 -- homeassistant/components/tesla/sensor.py | 97 ----- homeassistant/components/tesla/strings.json | 34 -- homeassistant/components/tesla/switch.py | 130 ------- .../components/tesla/translations/ca.json | 34 -- .../components/tesla/translations/cs.json | 32 -- .../components/tesla/translations/da.json | 23 -- .../components/tesla/translations/de.json | 34 -- .../components/tesla/translations/en.json | 34 -- .../components/tesla/translations/es-419.json | 24 -- .../components/tesla/translations/es.json | 34 -- .../components/tesla/translations/et.json | 34 -- .../components/tesla/translations/fi.json | 11 - .../components/tesla/translations/fr.json | 34 -- .../components/tesla/translations/he.json | 21 -- .../components/tesla/translations/hu.json | 34 -- .../components/tesla/translations/id.json | 33 -- .../components/tesla/translations/it.json | 34 -- .../components/tesla/translations/ka.json | 7 - .../components/tesla/translations/ko.json | 33 -- .../components/tesla/translations/lb.json | 29 -- .../components/tesla/translations/lv.json | 12 - .../components/tesla/translations/nl.json | 34 -- .../components/tesla/translations/no.json | 34 -- .../components/tesla/translations/pl.json | 34 -- .../components/tesla/translations/pt-BR.json | 23 -- .../components/tesla/translations/pt.json | 17 - .../components/tesla/translations/ru.json | 34 -- .../components/tesla/translations/sl.json | 24 -- .../components/tesla/translations/sv.json | 23 -- .../components/tesla/translations/tr.json | 18 - .../components/tesla/translations/uk.json | 29 -- .../tesla/translations/zh-Hans.json | 11 - .../tesla/translations/zh-Hant.json | 34 -- homeassistant/generated/config_flows.py | 1 - homeassistant/generated/dhcp.py | 15 - mypy.ini | 3 - requirements_all.txt | 3 - requirements_test_all.txt | 3 - script/hassfest/mypy_config.py | 1 - tests/components/tesla/__init__.py | 1 - tests/components/tesla/test_config_flow.py | 270 ------------- 51 files changed, 2240 deletions(-) delete mode 100644 homeassistant/components/tesla/__init__.py delete mode 100644 homeassistant/components/tesla/binary_sensor.py delete mode 100644 homeassistant/components/tesla/climate.py delete mode 100644 homeassistant/components/tesla/config_flow.py delete mode 100644 homeassistant/components/tesla/const.py delete mode 100644 homeassistant/components/tesla/device_tracker.py delete mode 100644 homeassistant/components/tesla/lock.py delete mode 100644 homeassistant/components/tesla/manifest.json delete mode 100644 homeassistant/components/tesla/sensor.py delete mode 100644 homeassistant/components/tesla/strings.json delete mode 100644 homeassistant/components/tesla/switch.py delete mode 100644 homeassistant/components/tesla/translations/ca.json delete mode 100644 homeassistant/components/tesla/translations/cs.json delete mode 100644 homeassistant/components/tesla/translations/da.json delete mode 100644 homeassistant/components/tesla/translations/de.json delete mode 100644 homeassistant/components/tesla/translations/en.json delete mode 100644 homeassistant/components/tesla/translations/es-419.json delete mode 100644 homeassistant/components/tesla/translations/es.json delete mode 100644 homeassistant/components/tesla/translations/et.json delete mode 100644 homeassistant/components/tesla/translations/fi.json delete mode 100644 homeassistant/components/tesla/translations/fr.json delete mode 100644 homeassistant/components/tesla/translations/he.json delete mode 100644 homeassistant/components/tesla/translations/hu.json delete mode 100644 homeassistant/components/tesla/translations/id.json delete mode 100644 homeassistant/components/tesla/translations/it.json delete mode 100644 homeassistant/components/tesla/translations/ka.json delete mode 100644 homeassistant/components/tesla/translations/ko.json delete mode 100644 homeassistant/components/tesla/translations/lb.json delete mode 100644 homeassistant/components/tesla/translations/lv.json delete mode 100644 homeassistant/components/tesla/translations/nl.json delete mode 100644 homeassistant/components/tesla/translations/no.json delete mode 100644 homeassistant/components/tesla/translations/pl.json delete mode 100644 homeassistant/components/tesla/translations/pt-BR.json delete mode 100644 homeassistant/components/tesla/translations/pt.json delete mode 100644 homeassistant/components/tesla/translations/ru.json delete mode 100644 homeassistant/components/tesla/translations/sl.json delete mode 100644 homeassistant/components/tesla/translations/sv.json delete mode 100644 homeassistant/components/tesla/translations/tr.json delete mode 100644 homeassistant/components/tesla/translations/uk.json delete mode 100644 homeassistant/components/tesla/translations/zh-Hans.json delete mode 100644 homeassistant/components/tesla/translations/zh-Hant.json delete mode 100644 tests/components/tesla/__init__.py delete mode 100644 tests/components/tesla/test_config_flow.py diff --git a/.coveragerc b/.coveragerc index 684322359b5..28b62776d8e 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1049,14 +1049,6 @@ omit = homeassistant/components/telnet/switch.py homeassistant/components/temper/sensor.py homeassistant/components/tensorflow/image_processing.py - homeassistant/components/tesla/__init__.py - homeassistant/components/tesla/binary_sensor.py - homeassistant/components/tesla/climate.py - homeassistant/components/tesla/const.py - homeassistant/components/tesla/device_tracker.py - homeassistant/components/tesla/lock.py - homeassistant/components/tesla/sensor.py - homeassistant/components/tesla/switch.py homeassistant/components/tfiac/climate.py homeassistant/components/thermoworks_smoke/sensor.py homeassistant/components/thethingsnetwork/* diff --git a/CODEOWNERS b/CODEOWNERS index 1a9e4bb62f7..35572933213 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -518,7 +518,6 @@ homeassistant/components/tasmota/* @emontnemery homeassistant/components/tautulli/* @ludeeus homeassistant/components/tellduslive/* @fredrike homeassistant/components/template/* @PhracturedBlue @tetienne @home-assistant/core -homeassistant/components/tesla/* @zabuldon @alandtse homeassistant/components/tfiac/* @fredrike @mellado homeassistant/components/thethingsnetwork/* @fabaff homeassistant/components/threshold/* @fabaff diff --git a/homeassistant/components/tesla/__init__.py b/homeassistant/components/tesla/__init__.py deleted file mode 100644 index 798e769dc47..00000000000 --- a/homeassistant/components/tesla/__init__.py +++ /dev/null @@ -1,357 +0,0 @@ -"""Support for Tesla cars.""" -import asyncio -from collections import defaultdict -from datetime import timedelta -import logging - -import async_timeout -import httpx -from teslajsonpy import Controller as TeslaAPI -from teslajsonpy.exceptions import IncompleteCredentials, TeslaException -import voluptuous as vol - -from homeassistant.config_entries import SOURCE_IMPORT -from homeassistant.const import ( - ATTR_BATTERY_CHARGING, - ATTR_BATTERY_LEVEL, - CONF_ACCESS_TOKEN, - CONF_PASSWORD, - CONF_SCAN_INTERVAL, - CONF_TOKEN, - CONF_USERNAME, - EVENT_HOMEASSISTANT_CLOSE, - HTTP_UNAUTHORIZED, -) -from homeassistant.core import callback -from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady -from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.httpx_client import SERVER_SOFTWARE, USER_AGENT -from homeassistant.helpers.update_coordinator import ( - CoordinatorEntity, - DataUpdateCoordinator, - UpdateFailed, -) -from homeassistant.util import slugify - -from .config_flow import CannotConnect, InvalidAuth, validate_input -from .const import ( - CONF_EXPIRATION, - CONF_WAKE_ON_START, - DATA_LISTENER, - DEFAULT_SCAN_INTERVAL, - DEFAULT_WAKE_ON_START, - DOMAIN, - ICONS, - MIN_SCAN_INTERVAL, - PLATFORMS, -) - -_LOGGER = logging.getLogger(__name__) - -CONFIG_SCHEMA = vol.Schema( - { - DOMAIN: vol.Schema( - { - vol.Required(CONF_USERNAME): cv.string, - vol.Required(CONF_PASSWORD): cv.string, - vol.Optional( - CONF_SCAN_INTERVAL, default=DEFAULT_SCAN_INTERVAL - ): vol.All(cv.positive_int, vol.Clamp(min=MIN_SCAN_INTERVAL)), - } - ) - }, - extra=vol.ALLOW_EXTRA, -) - - -@callback -def _async_save_tokens(hass, config_entry, access_token, refresh_token): - hass.config_entries.async_update_entry( - config_entry, - data={ - **config_entry.data, - CONF_ACCESS_TOKEN: access_token, - CONF_TOKEN: refresh_token, - }, - ) - - -@callback -def _async_configured_emails(hass): - """Return a set of configured Tesla emails.""" - return { - entry.data[CONF_USERNAME] - for entry in hass.config_entries.async_entries(DOMAIN) - if CONF_USERNAME in entry.data - } - - -async def async_setup(hass, base_config): - """Set up of Tesla component.""" - - def _update_entry(email, data=None, options=None): - data = data or {} - options = options or { - CONF_SCAN_INTERVAL: DEFAULT_SCAN_INTERVAL, - CONF_WAKE_ON_START: DEFAULT_WAKE_ON_START, - } - for entry in hass.config_entries.async_entries(DOMAIN): - if email != entry.title: - continue - hass.config_entries.async_update_entry(entry, data=data, options=options) - - config = base_config.get(DOMAIN) - if not config: - return True - email = config[CONF_USERNAME] - password = config[CONF_PASSWORD] - scan_interval = config[CONF_SCAN_INTERVAL] - if email in _async_configured_emails(hass): - try: - info = await validate_input(hass, config) - except (CannotConnect, InvalidAuth): - return False - _update_entry( - email, - data={ - CONF_USERNAME: email, - CONF_PASSWORD: password, - CONF_ACCESS_TOKEN: info[CONF_ACCESS_TOKEN], - CONF_TOKEN: info[CONF_TOKEN], - CONF_EXPIRATION: info[CONF_EXPIRATION], - }, - options={CONF_SCAN_INTERVAL: scan_interval}, - ) - else: - hass.async_create_task( - hass.config_entries.flow.async_init( - DOMAIN, - context={"source": SOURCE_IMPORT}, - data={CONF_USERNAME: email, CONF_PASSWORD: password}, - ) - ) - hass.data.setdefault(DOMAIN, {}) - hass.data[DOMAIN][email] = {CONF_SCAN_INTERVAL: scan_interval} - return True - - -async def async_setup_entry(hass, config_entry): - """Set up Tesla as config entry.""" - hass.data.setdefault(DOMAIN, {}) - 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) - email = config_entry.title - if email in hass.data[DOMAIN] and CONF_SCAN_INTERVAL in hass.data[DOMAIN][email]: - scan_interval = hass.data[DOMAIN][email][CONF_SCAN_INTERVAL] - hass.config_entries.async_update_entry( - config_entry, options={CONF_SCAN_INTERVAL: scan_interval} - ) - hass.data[DOMAIN].pop(email) - try: - controller = TeslaAPI( - async_client, - email=config.get(CONF_USERNAME), - password=config.get(CONF_PASSWORD), - refresh_token=config[CONF_TOKEN], - access_token=config[CONF_ACCESS_TOKEN], - expiration=config.get(CONF_EXPIRATION, 0), - update_interval=config_entry.options.get( - CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL - ), - ) - result = await controller.connect( - wake_if_asleep=config_entry.options.get( - CONF_WAKE_ON_START, DEFAULT_WAKE_ON_START - ) - ) - refresh_token = result["refresh_token"] - access_token = result["access_token"] - except IncompleteCredentials as ex: - await async_client.aclose() - raise ConfigEntryAuthFailed from ex - except httpx.ConnectTimeout as ex: - await async_client.aclose() - raise ConfigEntryNotReady from ex - except TeslaException as ex: - await async_client.aclose() - if ex.code == HTTP_UNAUTHORIZED: - raise ConfigEntryAuthFailed from ex - if ex.message in [ - "VEHICLE_UNAVAILABLE", - "TOO_MANY_REQUESTS", - "SERVICE_MAINTENANCE", - "UPSTREAM_TIMEOUT", - ]: - raise ConfigEntryNotReady( - f"Temporarily unable to communicate with Tesla API: {ex.message}" - ) from ex - _LOGGER.error("Unable to communicate with Tesla API: %s", ex.message) - return False - - async def _async_close_client(*_): - await async_client.aclose() - - @callback - def _async_create_close_task(): - asyncio.create_task(_async_close_client()) - - config_entry.async_on_unload( - hass.bus.async_listen_once(EVENT_HOMEASSISTANT_CLOSE, _async_close_client) - ) - config_entry.async_on_unload(_async_create_close_task) - - _async_save_tokens(hass, config_entry, access_token, refresh_token) - coordinator = TeslaDataUpdateCoordinator( - hass, config_entry=config_entry, controller=controller - ) - # Fetch initial data so we have data when entities subscribe - entry_data = hass.data[DOMAIN][config_entry.entry_id] = { - "coordinator": coordinator, - "devices": defaultdict(list), - DATA_LISTENER: [config_entry.add_update_listener(update_listener)], - } - _LOGGER.debug("Connected to the Tesla API") - - await coordinator.async_config_entry_first_refresh() - - all_devices = controller.get_homeassistant_components() - - if not all_devices: - return False - - for device in all_devices: - entry_data["devices"][device.hass_type].append(device) - - hass.config_entries.async_setup_platforms(config_entry, PLATFORMS) - - return True - - -async def async_unload_entry(hass, config_entry) -> bool: - """Unload a config entry.""" - unload_ok = await hass.config_entries.async_unload_platforms( - config_entry, PLATFORMS - ) - for listener in hass.data[DOMAIN][config_entry.entry_id][DATA_LISTENER]: - listener() - username = config_entry.title - if unload_ok: - hass.data[DOMAIN].pop(config_entry.entry_id) - _LOGGER.debug("Unloaded entry for %s", username) - return True - return False - - -async def update_listener(hass, config_entry): - """Update when config_entry options update.""" - controller = hass.data[DOMAIN][config_entry.entry_id]["coordinator"].controller - old_update_interval = controller.update_interval - controller.update_interval = config_entry.options.get(CONF_SCAN_INTERVAL) - if old_update_interval != controller.update_interval: - _LOGGER.debug( - "Changing scan_interval from %s to %s", - old_update_interval, - controller.update_interval, - ) - - -class TeslaDataUpdateCoordinator(DataUpdateCoordinator): - """Class to manage fetching Tesla data.""" - - def __init__(self, hass, *, config_entry, controller): - """Initialize global Tesla data updater.""" - self.controller = controller - self.config_entry = config_entry - - update_interval = timedelta(seconds=MIN_SCAN_INTERVAL) - - super().__init__( - hass, - _LOGGER, - name=DOMAIN, - update_interval=update_interval, - ) - - async def _async_update_data(self): - """Fetch data from API endpoint.""" - if self.controller.is_token_refreshed(): - result = self.controller.get_tokens() - refresh_token = result["refresh_token"] - access_token = result["access_token"] - _async_save_tokens( - self.hass, self.config_entry, access_token, refresh_token - ) - _LOGGER.debug("Saving new tokens in config_entry") - - try: - # Note: asyncio.TimeoutError and aiohttp.ClientError are already - # handled by the data update coordinator. - async with async_timeout.timeout(30): - return await self.controller.update() - except TeslaException as err: - raise UpdateFailed(f"Error communicating with API: {err}") from err - - -class TeslaDevice(CoordinatorEntity): - """Representation of a Tesla device.""" - - def __init__(self, tesla_device, coordinator): - """Initialise the Tesla device.""" - super().__init__(coordinator) - self.tesla_device = tesla_device - self._name = self.tesla_device.name - self._unique_id = slugify(self.tesla_device.uniq_name) - self._attributes = self.tesla_device.attrs.copy() - - @property - def name(self): - """Return the name of the device.""" - return self._name - - @property - def unique_id(self) -> str: - """Return a unique ID.""" - return self._unique_id - - @property - def icon(self): - """Return the icon of the sensor.""" - if self.device_class: - return None - - return ICONS.get(self.tesla_device.type) - - @property - def extra_state_attributes(self): - """Return the state attributes of the device.""" - attr = self._attributes - if self.tesla_device.has_battery(): - attr[ATTR_BATTERY_LEVEL] = self.tesla_device.battery_level() - attr[ATTR_BATTERY_CHARGING] = self.tesla_device.battery_charging() - return attr - - @property - def device_info(self): - """Return the device_info of the device.""" - return { - "identifiers": {(DOMAIN, self.tesla_device.id())}, - "name": self.tesla_device.car_name(), - "manufacturer": "Tesla", - "model": self.tesla_device.car_type, - "sw_version": self.tesla_device.car_version, - } - - async def async_added_to_hass(self): - """Register state update callback.""" - self.async_on_remove(self.coordinator.async_add_listener(self.refresh)) - - @callback - def refresh(self) -> None: - """Refresh the state of the device. - - This assumes the coordinator has updated the controller. - """ - self.tesla_device.refresh() - self._attributes = self.tesla_device.attrs.copy() - self.async_write_ha_state() diff --git a/homeassistant/components/tesla/binary_sensor.py b/homeassistant/components/tesla/binary_sensor.py deleted file mode 100644 index 77315ef1e3c..00000000000 --- a/homeassistant/components/tesla/binary_sensor.py +++ /dev/null @@ -1,39 +0,0 @@ -"""Support for Tesla binary sensor.""" - -from homeassistant.components.binary_sensor import DEVICE_CLASSES, BinarySensorEntity - -from . import DOMAIN as TESLA_DOMAIN, TeslaDevice - - -async def async_setup_entry(hass, config_entry, async_add_entities): - """Set up the Tesla binary_sensors by config_entry.""" - async_add_entities( - [ - TeslaBinarySensor( - device, - hass.data[TESLA_DOMAIN][config_entry.entry_id]["coordinator"], - ) - for device in hass.data[TESLA_DOMAIN][config_entry.entry_id]["devices"][ - "binary_sensor" - ] - ], - True, - ) - - -class TeslaBinarySensor(TeslaDevice, BinarySensorEntity): - """Implement an Tesla binary sensor for parking and charger.""" - - @property - def device_class(self): - """Return the class of this binary sensor.""" - return ( - self.tesla_device.sensor_type - if self.tesla_device.sensor_type in DEVICE_CLASSES - else None - ) - - @property - def is_on(self): - """Return the state of the binary sensor.""" - return self.tesla_device.get_value() diff --git a/homeassistant/components/tesla/climate.py b/homeassistant/components/tesla/climate.py deleted file mode 100644 index 81639bc3fe4..00000000000 --- a/homeassistant/components/tesla/climate.py +++ /dev/null @@ -1,120 +0,0 @@ -"""Support for Tesla HVAC system.""" -from __future__ import annotations - -import logging - -from teslajsonpy.exceptions import UnknownPresetMode - -from homeassistant.components.climate import ClimateEntity -from homeassistant.components.climate.const import ( - HVAC_MODE_HEAT_COOL, - HVAC_MODE_OFF, - SUPPORT_PRESET_MODE, - SUPPORT_TARGET_TEMPERATURE, -) -from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS, TEMP_FAHRENHEIT - -from . import DOMAIN as TESLA_DOMAIN, TeslaDevice - -_LOGGER = logging.getLogger(__name__) - -SUPPORT_HVAC = [HVAC_MODE_HEAT_COOL, HVAC_MODE_OFF] - - -async def async_setup_entry(hass, config_entry, async_add_entities): - """Set up the Tesla binary_sensors by config_entry.""" - async_add_entities( - [ - TeslaThermostat( - device, - hass.data[TESLA_DOMAIN][config_entry.entry_id]["coordinator"], - ) - for device in hass.data[TESLA_DOMAIN][config_entry.entry_id]["devices"][ - "climate" - ] - ], - True, - ) - - -class TeslaThermostat(TeslaDevice, ClimateEntity): - """Representation of a Tesla climate.""" - - @property - def supported_features(self): - """Return the list of supported features.""" - return SUPPORT_TARGET_TEMPERATURE | SUPPORT_PRESET_MODE - - @property - def hvac_mode(self): - """Return hvac operation ie. heat, cool mode. - - Need to be one of HVAC_MODE_*. - """ - if self.tesla_device.is_hvac_enabled(): - return HVAC_MODE_HEAT_COOL - return HVAC_MODE_OFF - - @property - def hvac_modes(self): - """Return the list of available hvac operation modes. - - Need to be a subset of HVAC_MODES. - """ - return SUPPORT_HVAC - - @property - def temperature_unit(self): - """Return the unit of measurement.""" - if self.tesla_device.measurement == "F": - return TEMP_FAHRENHEIT - return TEMP_CELSIUS - - @property - def current_temperature(self): - """Return the current temperature.""" - return self.tesla_device.get_current_temp() - - @property - def target_temperature(self): - """Return the temperature we try to reach.""" - return self.tesla_device.get_goal_temp() - - async def async_set_temperature(self, **kwargs): - """Set new target temperatures.""" - temperature = kwargs.get(ATTR_TEMPERATURE) - if temperature: - _LOGGER.debug("%s: Setting temperature to %s", self.name, temperature) - await self.tesla_device.set_temperature(temperature) - - async def async_set_hvac_mode(self, hvac_mode): - """Set new target hvac mode.""" - _LOGGER.debug("%s: Setting hvac mode to %s", self.name, hvac_mode) - if hvac_mode == HVAC_MODE_OFF: - await self.tesla_device.set_status(False) - elif hvac_mode == HVAC_MODE_HEAT_COOL: - await self.tesla_device.set_status(True) - - async def async_set_preset_mode(self, preset_mode: str) -> None: - """Set new preset mode.""" - _LOGGER.debug("%s: Setting preset_mode to: %s", self.name, preset_mode) - try: - await self.tesla_device.set_preset_mode(preset_mode) - except UnknownPresetMode as ex: - _LOGGER.error("%s", ex.message) - - @property - def preset_mode(self) -> str | None: - """Return the current preset mode, e.g., home, away, temp. - - Requires SUPPORT_PRESET_MODE. - """ - return self.tesla_device.preset_mode - - @property - def preset_modes(self) -> list[str] | None: - """Return a list of available preset modes. - - Requires SUPPORT_PRESET_MODE. - """ - return self.tesla_device.preset_modes diff --git a/homeassistant/components/tesla/config_flow.py b/homeassistant/components/tesla/config_flow.py deleted file mode 100644 index 5a88999a7e3..00000000000 --- a/homeassistant/components/tesla/config_flow.py +++ /dev/null @@ -1,191 +0,0 @@ -"""Tesla Config Flow.""" -import logging - -import httpx -from teslajsonpy import Controller as TeslaAPI, TeslaException -from teslajsonpy.exceptions import IncompleteCredentials -import voluptuous as vol - -from homeassistant import config_entries, core, exceptions -from homeassistant.const import ( - CONF_ACCESS_TOKEN, - CONF_PASSWORD, - CONF_SCAN_INTERVAL, - CONF_TOKEN, - CONF_USERNAME, - HTTP_UNAUTHORIZED, -) -from homeassistant.core import callback -from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.httpx_client import SERVER_SOFTWARE, USER_AGENT - -from .const import ( - CONF_EXPIRATION, - CONF_MFA, - CONF_WAKE_ON_START, - DEFAULT_SCAN_INTERVAL, - DEFAULT_WAKE_ON_START, - DOMAIN, - MIN_SCAN_INTERVAL, -) - -_LOGGER = logging.getLogger(__name__) - - -class TeslaConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): - """Handle a config flow for Tesla.""" - - VERSION = 1 - - def __init__(self) -> None: - """Initialize the tesla flow.""" - self.username = None - self.reauth = False - - async def async_step_import(self, import_config): - """Import a config entry from configuration.yaml.""" - return await self.async_step_user(import_config) - - async def async_step_user(self, user_input=None): - """Handle the start of the config flow.""" - errors = {} - - if user_input is not None: - existing_entry = self._async_entry_for_username(user_input[CONF_USERNAME]) - if existing_entry and not self.reauth: - return self.async_abort(reason="already_configured") - - try: - info = await validate_input(self.hass, user_input) - except CannotConnect: - errors["base"] = "cannot_connect" - except InvalidAuth: - errors["base"] = "invalid_auth" - - if not errors: - if existing_entry: - self.hass.config_entries.async_update_entry( - existing_entry, data=info - ) - await self.hass.config_entries.async_reload(existing_entry.entry_id) - return self.async_abort(reason="reauth_successful") - - return self.async_create_entry( - title=user_input[CONF_USERNAME], data=info - ) - - return self.async_show_form( - step_id="user", - data_schema=self._async_schema(), - errors=errors, - description_placeholders={}, - ) - - async def async_step_reauth(self, data): - """Handle configuration by re-auth.""" - self.username = data[CONF_USERNAME] - self.reauth = True - return await self.async_step_user() - - @staticmethod - @callback - def async_get_options_flow(config_entry): - """Get the options flow for this handler.""" - return OptionsFlowHandler(config_entry) - - @callback - def _async_schema(self): - """Fetch schema with defaults.""" - return vol.Schema( - { - vol.Required(CONF_USERNAME, default=self.username): str, - vol.Required(CONF_PASSWORD): str, - vol.Optional(CONF_MFA): str, - } - ) - - @callback - def _async_entry_for_username(self, username): - """Find an existing entry for a username.""" - for entry in self._async_current_entries(): - if entry.data.get(CONF_USERNAME) == username: - return entry - return None - - -class OptionsFlowHandler(config_entries.OptionsFlow): - """Handle a option flow for Tesla.""" - - def __init__(self, config_entry: config_entries.ConfigEntry) -> None: - """Initialize options flow.""" - self.config_entry = config_entry - - async def async_step_init(self, user_input=None): - """Handle options flow.""" - if user_input is not None: - return self.async_create_entry(title="", data=user_input) - - data_schema = vol.Schema( - { - vol.Optional( - CONF_SCAN_INTERVAL, - default=self.config_entry.options.get( - CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL - ), - ): vol.All(cv.positive_int, vol.Clamp(min=MIN_SCAN_INTERVAL)), - vol.Optional( - CONF_WAKE_ON_START, - default=self.config_entry.options.get( - CONF_WAKE_ON_START, DEFAULT_WAKE_ON_START - ), - ): bool, - } - ) - return self.async_show_form(step_id="init", data_schema=data_schema) - - -async def validate_input(hass: core.HomeAssistant, data): - """Validate the user input allows us to connect. - - Data has the keys from DATA_SCHEMA with values provided by the user. - """ - - config = {} - async_client = httpx.AsyncClient(headers={USER_AGENT: SERVER_SOFTWARE}, timeout=60) - - try: - controller = TeslaAPI( - async_client, - email=data[CONF_USERNAME], - password=data[CONF_PASSWORD], - update_interval=DEFAULT_SCAN_INTERVAL, - ) - result = await controller.connect( - test_login=True, mfa_code=(data[CONF_MFA] if CONF_MFA in data else "") - ) - config[CONF_TOKEN] = result["refresh_token"] - config[CONF_ACCESS_TOKEN] = result["access_token"] - config[CONF_EXPIRATION] = result[CONF_EXPIRATION] - config[CONF_USERNAME] = data[CONF_USERNAME] - config[CONF_PASSWORD] = data[CONF_PASSWORD] - except IncompleteCredentials as ex: - _LOGGER.error("Authentication error: %s %s", ex.message, ex) - raise InvalidAuth() from ex - except TeslaException as ex: - if ex.code == HTTP_UNAUTHORIZED: - _LOGGER.error("Invalid credentials: %s", ex) - raise InvalidAuth() from ex - _LOGGER.error("Unable to communicate with Tesla API: %s", ex.message) - raise CannotConnect() from ex - finally: - await async_client.aclose() - _LOGGER.debug("Credentials successfully connected to the Tesla API") - return config - - -class CannotConnect(exceptions.HomeAssistantError): - """Error to indicate we cannot connect.""" - - -class InvalidAuth(exceptions.HomeAssistantError): - """Error to indicate there is invalid auth.""" diff --git a/homeassistant/components/tesla/const.py b/homeassistant/components/tesla/const.py deleted file mode 100644 index c288b3c1cda..00000000000 --- a/homeassistant/components/tesla/const.py +++ /dev/null @@ -1,33 +0,0 @@ -"""Const file for Tesla cars.""" -CONF_EXPIRATION = "expiration" -CONF_WAKE_ON_START = "enable_wake_on_start" -CONF_MFA = "mfa" -DOMAIN = "tesla" -DATA_LISTENER = "listener" -DEFAULT_SCAN_INTERVAL = 660 -DEFAULT_WAKE_ON_START = False -MIN_SCAN_INTERVAL = 60 - -PLATFORMS = [ - "sensor", - "lock", - "climate", - "binary_sensor", - "device_tracker", - "switch", -] - -ICONS = { - "battery sensor": "mdi:battery", - "range sensor": "mdi:gauge", - "mileage sensor": "mdi:counter", - "parking brake sensor": "mdi:car-brake-parking", - "charger sensor": "mdi:ev-station", - "charger switch": "mdi:battery-charging", - "update switch": "mdi:update", - "maxrange switch": "mdi:gauge-full", - "temperature sensor": "mdi:thermometer", - "location tracker": "mdi:crosshairs-gps", - "charging rate sensor": "mdi:speedometer", - "sentry mode switch": "mdi:shield-car", -} diff --git a/homeassistant/components/tesla/device_tracker.py b/homeassistant/components/tesla/device_tracker.py deleted file mode 100644 index 6813b3769e7..00000000000 --- a/homeassistant/components/tesla/device_tracker.py +++ /dev/null @@ -1,57 +0,0 @@ -"""Support for tracking Tesla cars.""" -from __future__ import annotations - -from homeassistant.components.device_tracker import SOURCE_TYPE_GPS -from homeassistant.components.device_tracker.config_entry import TrackerEntity - -from . import DOMAIN as TESLA_DOMAIN, TeslaDevice - - -async def async_setup_entry(hass, config_entry, async_add_entities): - """Set up the Tesla binary_sensors by config_entry.""" - entities = [ - TeslaDeviceEntity( - device, - hass.data[TESLA_DOMAIN][config_entry.entry_id]["coordinator"], - ) - for device in hass.data[TESLA_DOMAIN][config_entry.entry_id]["devices"][ - "devices_tracker" - ] - ] - async_add_entities(entities, True) - - -class TeslaDeviceEntity(TeslaDevice, TrackerEntity): - """A class representing a Tesla device.""" - - @property - def latitude(self) -> float | None: - """Return latitude value of the device.""" - location = self.tesla_device.get_location() - return self.tesla_device.get_location().get("latitude") if location else None - - @property - def longitude(self) -> float | None: - """Return longitude value of the device.""" - location = self.tesla_device.get_location() - return self.tesla_device.get_location().get("longitude") if location else None - - @property - def source_type(self): - """Return the source type, eg gps or router, of the device.""" - return SOURCE_TYPE_GPS - - @property - def extra_state_attributes(self): - """Return the state attributes of the device.""" - attr = super().extra_state_attributes.copy() - location = self.tesla_device.get_location() - if location: - attr.update( - { - "trackr_id": self.unique_id, - "heading": location["heading"], - "speed": location["speed"], - } - ) - return attr diff --git a/homeassistant/components/tesla/lock.py b/homeassistant/components/tesla/lock.py deleted file mode 100644 index 7a74d2ececb..00000000000 --- a/homeassistant/components/tesla/lock.py +++ /dev/null @@ -1,41 +0,0 @@ -"""Support for Tesla door locks.""" -import logging - -from homeassistant.components.lock import LockEntity - -from . import DOMAIN as TESLA_DOMAIN, TeslaDevice - -_LOGGER = logging.getLogger(__name__) - - -async def async_setup_entry(hass, config_entry, async_add_entities): - """Set up the Tesla binary_sensors by config_entry.""" - entities = [ - TeslaLock( - device, - hass.data[TESLA_DOMAIN][config_entry.entry_id]["coordinator"], - ) - for device in hass.data[TESLA_DOMAIN][config_entry.entry_id]["devices"]["lock"] - ] - async_add_entities(entities, True) - - -class TeslaLock(TeslaDevice, LockEntity): - """Representation of a Tesla door lock.""" - - async def async_lock(self, **kwargs): - """Send the lock command.""" - _LOGGER.debug("Locking doors for: %s", self.name) - await self.tesla_device.lock() - - async def async_unlock(self, **kwargs): - """Send the unlock command.""" - _LOGGER.debug("Unlocking doors for: %s", self.name) - await self.tesla_device.unlock() - - @property - def is_locked(self): - """Get whether the lock is in locked state.""" - if self.tesla_device.is_locked() is None: - return None - return self.tesla_device.is_locked() diff --git a/homeassistant/components/tesla/manifest.json b/homeassistant/components/tesla/manifest.json deleted file mode 100644 index 8604436d5a4..00000000000 --- a/homeassistant/components/tesla/manifest.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "domain": "tesla", - "name": "Tesla", - "config_flow": true, - "documentation": "https://www.home-assistant.io/integrations/tesla", - "requirements": ["teslajsonpy==0.18.3"], - "codeowners": ["@zabuldon", "@alandtse"], - "dhcp": [ - { - "hostname": "tesla_*", - "macaddress": "4CFCAA*" - }, - { - "hostname": "tesla_*", - "macaddress": "044EAF*" - }, - { - "hostname": "tesla_*", - "macaddress": "98ED5C*" - } - ], - "iot_class": "cloud_polling" -} diff --git a/homeassistant/components/tesla/sensor.py b/homeassistant/components/tesla/sensor.py deleted file mode 100644 index 60e3e19047d..00000000000 --- a/homeassistant/components/tesla/sensor.py +++ /dev/null @@ -1,97 +0,0 @@ -"""Support for the Tesla sensors.""" -from __future__ import annotations - -from homeassistant.components.sensor import DEVICE_CLASSES, SensorEntity -from homeassistant.const import ( - LENGTH_KILOMETERS, - LENGTH_MILES, - TEMP_CELSIUS, - TEMP_FAHRENHEIT, -) -from homeassistant.util.distance import convert - -from . import DOMAIN as TESLA_DOMAIN, TeslaDevice - - -async def async_setup_entry(hass, config_entry, async_add_entities): - """Set up the Tesla binary_sensors by config_entry.""" - coordinator = hass.data[TESLA_DOMAIN][config_entry.entry_id]["coordinator"] - entities = [] - for device in hass.data[TESLA_DOMAIN][config_entry.entry_id]["devices"]["sensor"]: - if device.type == "temperature sensor": - entities.append(TeslaSensor(device, coordinator, "inside")) - entities.append(TeslaSensor(device, coordinator, "outside")) - else: - entities.append(TeslaSensor(device, coordinator)) - async_add_entities(entities, True) - - -class TeslaSensor(TeslaDevice, SensorEntity): - """Representation of Tesla sensors.""" - - def __init__(self, tesla_device, coordinator, sensor_type=None): - """Initialize of the sensor.""" - super().__init__(tesla_device, coordinator) - self.type = sensor_type - if self.type: - self._name = f"{super().name} ({self.type})" - self._unique_id = f"{super().unique_id}_{self.type}" - - @property - def native_value(self) -> float | None: - """Return the state of the sensor.""" - if self.tesla_device.type == "temperature sensor": - if self.type == "outside": - return self.tesla_device.get_outside_temp() - return self.tesla_device.get_inside_temp() - if self.tesla_device.type in ("range sensor", "mileage sensor"): - units = self.tesla_device.measurement - if units == "LENGTH_MILES": - return self.tesla_device.get_value() - return round( - convert(self.tesla_device.get_value(), LENGTH_MILES, LENGTH_KILOMETERS), - 2, - ) - if self.tesla_device.type == "charging rate sensor": - return self.tesla_device.charging_rate - return self.tesla_device.get_value() - - @property - def native_unit_of_measurement(self) -> str | None: - """Return the unit_of_measurement of the device.""" - units = self.tesla_device.measurement - if units == "F": - return TEMP_FAHRENHEIT - if units == "C": - return TEMP_CELSIUS - if units == "LENGTH_MILES": - return LENGTH_MILES - if units == "LENGTH_KILOMETERS": - return LENGTH_KILOMETERS - return units - - @property - def device_class(self) -> str | None: - """Return the device_class of the device.""" - return ( - self.tesla_device.device_class - if self.tesla_device.device_class in DEVICE_CLASSES - else None - ) - - @property - def extra_state_attributes(self): - """Return the state attributes of the device.""" - attr = self._attributes.copy() - if self.tesla_device.type == "charging rate sensor": - attr.update( - { - "time_left": self.tesla_device.time_left, - "added_range": self.tesla_device.added_range, - "charge_energy_added": self.tesla_device.charge_energy_added, - "charge_current_request": self.tesla_device.charge_current_request, - "charger_actual_current": self.tesla_device.charger_actual_current, - "charger_voltage": self.tesla_device.charger_voltage, - } - ) - return attr diff --git a/homeassistant/components/tesla/strings.json b/homeassistant/components/tesla/strings.json deleted file mode 100644 index 755e5d5a7cf..00000000000 --- a/homeassistant/components/tesla/strings.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "config": { - "error": { - "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", - "already_configured": "[%key:common::config_flow::abort::already_configured_account%]", - "invalid_auth": "[%key:common::config_flow::error::invalid_auth%]" - }, - "abort": { - "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]", - "already_configured": "[%key:common::config_flow::abort::already_configured_account%]" - }, - "step": { - "user": { - "data": { - "username": "[%key:common::config_flow::data::email%]", - "password": "[%key:common::config_flow::data::password%]", - "mfa": "MFA Code (optional)" - }, - "description": "Please enter your information.", - "title": "Tesla - Configuration" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "scan_interval": "Seconds between scans", - "enable_wake_on_start": "Force cars awake on startup" - } - } - } - } -} diff --git a/homeassistant/components/tesla/switch.py b/homeassistant/components/tesla/switch.py deleted file mode 100644 index efcb955ebf8..00000000000 --- a/homeassistant/components/tesla/switch.py +++ /dev/null @@ -1,130 +0,0 @@ -"""Support for Tesla charger switches.""" -import logging - -from homeassistant.components.switch import SwitchEntity - -from . import DOMAIN as TESLA_DOMAIN, TeslaDevice - -_LOGGER = logging.getLogger(__name__) - - -async def async_setup_entry(hass, config_entry, async_add_entities): - """Set up the Tesla binary_sensors by config_entry.""" - coordinator = hass.data[TESLA_DOMAIN][config_entry.entry_id]["coordinator"] - entities = [] - for device in hass.data[TESLA_DOMAIN][config_entry.entry_id]["devices"]["switch"]: - if device.type == "charger switch": - entities.append(ChargerSwitch(device, coordinator)) - entities.append(UpdateSwitch(device, coordinator)) - elif device.type == "maxrange switch": - entities.append(RangeSwitch(device, coordinator)) - elif device.type == "sentry mode switch": - entities.append(SentryModeSwitch(device, coordinator)) - async_add_entities(entities, True) - - -class ChargerSwitch(TeslaDevice, SwitchEntity): - """Representation of a Tesla charger switch.""" - - async def async_turn_on(self, **kwargs): - """Send the on command.""" - _LOGGER.debug("Enable charging: %s", self.name) - await self.tesla_device.start_charge() - self.async_write_ha_state() - - async def async_turn_off(self, **kwargs): - """Send the off command.""" - _LOGGER.debug("Disable charging for: %s", self.name) - await self.tesla_device.stop_charge() - self.async_write_ha_state() - - @property - def is_on(self): - """Get whether the switch is in on state.""" - if self.tesla_device.is_charging() is None: - return None - return self.tesla_device.is_charging() - - -class RangeSwitch(TeslaDevice, SwitchEntity): - """Representation of a Tesla max range charging switch.""" - - async def async_turn_on(self, **kwargs): - """Send the on command.""" - _LOGGER.debug("Enable max range charging: %s", self.name) - await self.tesla_device.set_max() - self.async_write_ha_state() - - async def async_turn_off(self, **kwargs): - """Send the off command.""" - _LOGGER.debug("Disable max range charging: %s", self.name) - await self.tesla_device.set_standard() - self.async_write_ha_state() - - @property - def is_on(self): - """Get whether the switch is in on state.""" - if self.tesla_device.is_maxrange() is None: - return None - return bool(self.tesla_device.is_maxrange()) - - -class UpdateSwitch(TeslaDevice, SwitchEntity): - """Representation of a Tesla update switch.""" - - def __init__(self, tesla_device, coordinator): - """Initialise the switch.""" - super().__init__(tesla_device, coordinator) - self.controller = coordinator.controller - - @property - def name(self): - """Return the name of the device.""" - return super().name.replace("charger", "update") - - @property - def unique_id(self) -> str: - """Return a unique ID.""" - return super().unique_id.replace("charger", "update") - - async def async_turn_on(self, **kwargs): - """Send the on command.""" - _LOGGER.debug("Enable updates: %s %s", self.name, self.tesla_device.id()) - self.controller.set_updates(self.tesla_device.id(), True) - self.async_write_ha_state() - - async def async_turn_off(self, **kwargs): - """Send the off command.""" - _LOGGER.debug("Disable updates: %s %s", self.name, self.tesla_device.id()) - self.controller.set_updates(self.tesla_device.id(), False) - self.async_write_ha_state() - - @property - def is_on(self): - """Get whether the switch is in on state.""" - if self.controller.get_updates(self.tesla_device.id()) is None: - return None - return bool(self.controller.get_updates(self.tesla_device.id())) - - -class SentryModeSwitch(TeslaDevice, SwitchEntity): - """Representation of a Tesla sentry mode switch.""" - - async def async_turn_on(self, **kwargs): - """Send the on command.""" - _LOGGER.debug("Enable sentry mode: %s", self.name) - await self.tesla_device.enable_sentry_mode() - self.async_write_ha_state() - - async def async_turn_off(self, **kwargs): - """Send the off command.""" - _LOGGER.debug("Disable sentry mode: %s", self.name) - await self.tesla_device.disable_sentry_mode() - self.async_write_ha_state() - - @property - def is_on(self): - """Get whether the switch is in on state.""" - if self.tesla_device.is_on() is None: - return None - return self.tesla_device.is_on() diff --git a/homeassistant/components/tesla/translations/ca.json b/homeassistant/components/tesla/translations/ca.json deleted file mode 100644 index f5c0117f6a0..00000000000 --- a/homeassistant/components/tesla/translations/ca.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "El compte ja ha estat configurat", - "reauth_successful": "Re-autenticaci\u00f3 realitzada correctament" - }, - "error": { - "already_configured": "El compte ja ha estat configurat", - "cannot_connect": "Ha fallat la connexi\u00f3", - "invalid_auth": "Autenticaci\u00f3 inv\u00e0lida" - }, - "step": { - "user": { - "data": { - "mfa": "Codi MFA (opcional)", - "password": "Contrasenya", - "username": "Correu electr\u00f2nic" - }, - "description": "Introdueix la teva informaci\u00f3.", - "title": "Configuraci\u00f3 de Tesla" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "For\u00e7a el despertar del cotxe en la posada en marxa", - "scan_interval": "Segons entre escanejos" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/cs.json b/homeassistant/components/tesla/translations/cs.json deleted file mode 100644 index 9c117223d40..00000000000 --- a/homeassistant/components/tesla/translations/cs.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "\u00da\u010det je ji\u017e nastaven", - "reauth_successful": "Op\u011btovn\u00e9 ov\u011b\u0159en\u00ed bylo \u00fasp\u011b\u0161n\u00e9" - }, - "error": { - "already_configured": "\u00da\u010det je ji\u017e nastaven", - "cannot_connect": "Nepoda\u0159ilo se p\u0159ipojit", - "invalid_auth": "Neplatn\u00e9 ov\u011b\u0159en\u00ed" - }, - "step": { - "user": { - "data": { - "password": "Heslo", - "username": "E-mail" - }, - "description": "Zadejte sv\u00e9 \u00fadaje.", - "title": "Tesla - Nastaven\u00ed" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "scan_interval": "Po\u010det sekund mezi sledov\u00e1n\u00edm" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/da.json b/homeassistant/components/tesla/translations/da.json deleted file mode 100644 index c6cb8b5b208..00000000000 --- a/homeassistant/components/tesla/translations/da.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "config": { - "step": { - "user": { - "data": { - "password": "Adgangskode", - "username": "Email-adresse" - }, - "description": "Indtast dine oplysninger.", - "title": "Tesla - Konfiguration" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "scan_interval": "Sekunder mellem scanninger" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/de.json b/homeassistant/components/tesla/translations/de.json deleted file mode 100644 index 09934369f6b..00000000000 --- a/homeassistant/components/tesla/translations/de.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Konto wurde bereits konfiguriert", - "reauth_successful": "Die erneute Authentifizierung war erfolgreich" - }, - "error": { - "already_configured": "Konto wurde bereits konfiguriert", - "cannot_connect": "Verbindung fehlgeschlagen", - "invalid_auth": "Ung\u00fcltige Authentifizierung" - }, - "step": { - "user": { - "data": { - "mfa": "MFA-Code (optional)", - "password": "Passwort", - "username": "E-Mail" - }, - "description": "Bitte gib deine Daten ein.", - "title": "Tesla - Konfiguration" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "Aufwachen des Autos beim Start erzwingen", - "scan_interval": "Sekunden zwischen den Scans" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/en.json b/homeassistant/components/tesla/translations/en.json deleted file mode 100644 index 80cbee7e122..00000000000 --- a/homeassistant/components/tesla/translations/en.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Account is already configured", - "reauth_successful": "Re-authentication was successful" - }, - "error": { - "already_configured": "Account is already configured", - "cannot_connect": "Failed to connect", - "invalid_auth": "Invalid authentication" - }, - "step": { - "user": { - "data": { - "mfa": "MFA Code (optional)", - "password": "Password", - "username": "Email" - }, - "description": "Please enter your information.", - "title": "Tesla - Configuration" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "Force cars awake on startup", - "scan_interval": "Seconds between scans" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/es-419.json b/homeassistant/components/tesla/translations/es-419.json deleted file mode 100644 index 20fe7b3c436..00000000000 --- a/homeassistant/components/tesla/translations/es-419.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "config": { - "step": { - "user": { - "data": { - "password": "Contrase\u00f1a", - "username": "Direcci\u00f3n de correo electr\u00f3nico" - }, - "description": "Por favor ingrese su informaci\u00f3n.", - "title": "Tesla - Configuraci\u00f3n" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "Forzar a autom\u00f3viles despertar al inicio", - "scan_interval": "Segundos entre escaneos" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/es.json b/homeassistant/components/tesla/translations/es.json deleted file mode 100644 index 8211e806741..00000000000 --- a/homeassistant/components/tesla/translations/es.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "La cuenta ya ha sido configurada", - "reauth_successful": "La reautenticaci\u00f3n se realiz\u00f3 correctamente" - }, - "error": { - "already_configured": "La cuenta ya ha sido configurada", - "cannot_connect": "No se pudo conectar", - "invalid_auth": "Autenticaci\u00f3n no v\u00e1lida" - }, - "step": { - "user": { - "data": { - "mfa": "C\u00f3digo MFA (opcional)", - "password": "Contrase\u00f1a", - "username": "Correo electr\u00f3nico" - }, - "description": "Por favor, introduzca su informaci\u00f3n.", - "title": "Tesla - Configuraci\u00f3n" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "Forzar autom\u00f3viles despiertos al inicio", - "scan_interval": "Segundos entre escaneos" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/et.json b/homeassistant/components/tesla/translations/et.json deleted file mode 100644 index ab36a4e503d..00000000000 --- a/homeassistant/components/tesla/translations/et.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Kasutaja on juba seadistatud", - "reauth_successful": "Taastuvastamine \u00f5nnestus" - }, - "error": { - "already_configured": "Konto on juba h\u00e4\u00e4lestatud", - "cannot_connect": "\u00dchendamine nurjus", - "invalid_auth": "Tuvastamise viga" - }, - "step": { - "user": { - "data": { - "mfa": "MFA kood (valikuline)", - "password": "Salas\u00f5na", - "username": "E-post" - }, - "description": "Palun sisesta oma andmed.", - "title": "Tesla - seadistamine" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "Sunni autod k\u00e4ivitamisel \u00e4rkama (?)", - "scan_interval": "P\u00e4ringute vahe sekundites" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/fi.json b/homeassistant/components/tesla/translations/fi.json deleted file mode 100644 index b7ed0a4bd5c..00000000000 --- a/homeassistant/components/tesla/translations/fi.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "config": { - "step": { - "user": { - "data": { - "mfa": "MFA-koodi (valinnainen)" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/fr.json b/homeassistant/components/tesla/translations/fr.json deleted file mode 100644 index 174b687f26f..00000000000 --- a/homeassistant/components/tesla/translations/fr.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Le compte est d\u00e9j\u00e0 configur\u00e9", - "reauth_successful": "La r\u00e9-authentification a r\u00e9ussi" - }, - "error": { - "already_configured": "Le compte est d\u00e9j\u00e0 configur\u00e9", - "cannot_connect": "\u00c9chec de connexion", - "invalid_auth": "Authentification invalide" - }, - "step": { - "user": { - "data": { - "mfa": "Code MFA (facultatif)", - "password": "Mot de passe", - "username": "Email" - }, - "description": "Veuillez saisir vos informations.", - "title": "Tesla - Configuration" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "Forcer les voitures \u00e0 se r\u00e9veiller au d\u00e9marrage", - "scan_interval": "Secondes entre les scans" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/he.json b/homeassistant/components/tesla/translations/he.json deleted file mode 100644 index 9f3eeb2fc21..00000000000 --- a/homeassistant/components/tesla/translations/he.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "\u05ea\u05e6\u05d5\u05e8\u05ea \u05d4\u05d7\u05e9\u05d1\u05d5\u05df \u05db\u05d1\u05e8 \u05e0\u05e7\u05d1\u05e2\u05d4", - "reauth_successful": "\u05d4\u05d0\u05d9\u05de\u05d5\u05ea \u05de\u05d7\u05d3\u05e9 \u05d4\u05e6\u05dc\u05d9\u05d7" - }, - "error": { - "already_configured": "\u05ea\u05e6\u05d5\u05e8\u05ea \u05d4\u05d7\u05e9\u05d1\u05d5\u05df \u05db\u05d1\u05e8 \u05e0\u05e7\u05d1\u05e2\u05d4", - "cannot_connect": "\u05d4\u05d4\u05ea\u05d7\u05d1\u05e8\u05d5\u05ea \u05e0\u05db\u05e9\u05dc\u05d4", - "invalid_auth": "\u05d0\u05d9\u05de\u05d5\u05ea \u05dc\u05d0 \u05d7\u05d5\u05e7\u05d9" - }, - "step": { - "user": { - "data": { - "password": "\u05e1\u05d9\u05e1\u05de\u05d4", - "username": "\u05d3\u05d5\u05d0\"\u05dc" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/hu.json b/homeassistant/components/tesla/translations/hu.json deleted file mode 100644 index 75a93566df5..00000000000 --- a/homeassistant/components/tesla/translations/hu.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "A fi\u00f3k m\u00e1r konfigur\u00e1lva van", - "reauth_successful": "Az \u00fajrahiteles\u00edt\u00e9s sikeres volt" - }, - "error": { - "already_configured": "A fi\u00f3k m\u00e1r konfigur\u00e1lva van", - "cannot_connect": "Sikertelen csatlakoz\u00e1s", - "invalid_auth": "\u00c9rv\u00e9nytelen hiteles\u00edt\u00e9s" - }, - "step": { - "user": { - "data": { - "mfa": "MFA k\u00f3d (opcion\u00e1lis)", - "password": "Jelsz\u00f3", - "username": "E-mail" - }, - "description": "K\u00e9rlek, add meg az adataidat.", - "title": "Tesla - Konfigur\u00e1ci\u00f3" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "Az aut\u00f3k \u00e9bred\u00e9sre k\u00e9nyszer\u00edt\u00e9se ind\u00edt\u00e1skor", - "scan_interval": "Szkennel\u00e9sek k\u00f6z\u00f6tti m\u00e1sodpercek" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/id.json b/homeassistant/components/tesla/translations/id.json deleted file mode 100644 index 681504d0d42..00000000000 --- a/homeassistant/components/tesla/translations/id.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Akun sudah dikonfigurasi", - "reauth_successful": "Autentikasi ulang berhasil" - }, - "error": { - "already_configured": "Akun sudah dikonfigurasi", - "cannot_connect": "Gagal terhubung", - "invalid_auth": "Autentikasi tidak valid" - }, - "step": { - "user": { - "data": { - "password": "Kata Sandi", - "username": "Email" - }, - "description": "Masukkan informasi Anda.", - "title": "Tesla - Konfigurasi" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "Paksa mobil bangun saat dinyalakan", - "scan_interval": "Interval pemindaian dalam detik" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/it.json b/homeassistant/components/tesla/translations/it.json deleted file mode 100644 index 05a663df149..00000000000 --- a/homeassistant/components/tesla/translations/it.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "L'account \u00e8 gi\u00e0 configurato", - "reauth_successful": "La nuova autenticazione \u00e8 stata eseguita correttamente" - }, - "error": { - "already_configured": "L'account \u00e8 gi\u00e0 configurato", - "cannot_connect": "Impossibile connettersi", - "invalid_auth": "Autenticazione non valida" - }, - "step": { - "user": { - "data": { - "mfa": "Codice autenticazione a pi\u00f9 fattori MFA (facoltativo)", - "password": "Password", - "username": "E-mail" - }, - "description": "Si prega di inserire le tue informazioni.", - "title": "Tesla - Configurazione" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "Forza il risveglio delle auto all'avvio", - "scan_interval": "Secondi tra le scansioni" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/ka.json b/homeassistant/components/tesla/translations/ka.json deleted file mode 100644 index 249c8f6cffb..00000000000 --- a/homeassistant/components/tesla/translations/ka.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "config": { - "error": { - "already_configured": "\u10d0\u10dc\u10d2\u10d0\u10e0\u10d8\u10e8\u10d8 \u10e3\u10d9\u10d5\u10d4 \u10d9\u10dd\u10dc\u10e4\u10d8\u10d2\u10e3\u10e0\u10d8\u10e0\u10d4\u10d1\u10e3\u10da\u10d8\u10d0" - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/ko.json b/homeassistant/components/tesla/translations/ko.json deleted file mode 100644 index 285326f39de..00000000000 --- a/homeassistant/components/tesla/translations/ko.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "\uacc4\uc815\uc774 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4", - "reauth_successful": "\uc7ac\uc778\uc99d\uc5d0 \uc131\uacf5\ud588\uc2b5\ub2c8\ub2e4" - }, - "error": { - "already_configured": "\uacc4\uc815\uc774 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4", - "cannot_connect": "\uc5f0\uacb0\ud558\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4", - "invalid_auth": "\uc778\uc99d\uc774 \uc798\ubabb\ub418\uc5c8\uc2b5\ub2c8\ub2e4" - }, - "step": { - "user": { - "data": { - "password": "\ube44\ubc00\ubc88\ud638", - "username": "\uc774\uba54\uc77c" - }, - "description": "\uc0ac\uc6a9\uc790 \uc815\ubcf4\ub97c \uc785\ub825\ud574\uc8fc\uc138\uc694", - "title": "Tesla - \uad6c\uc131" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "\uc2dc\ub3d9 \uc2dc \ucc28\ub7c9 \uae68\uc6b0\uae30", - "scan_interval": "\uc2a4\uce94 \uac04\uaca9 (\ucd08)" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/lb.json b/homeassistant/components/tesla/translations/lb.json deleted file mode 100644 index 32353c99b3e..00000000000 --- a/homeassistant/components/tesla/translations/lb.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "config": { - "error": { - "already_configured": "Kont ass scho konfigur\u00e9iert", - "cannot_connect": "Feeler beim verbannen", - "invalid_auth": "Ong\u00eblteg Authentifikatioun" - }, - "step": { - "user": { - "data": { - "password": "Passwuert", - "username": "E-Mail" - }, - "description": "F\u00ebllt \u00e4r Informatiounen aus.", - "title": "Tesla - Konfiguratioun" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "Forc\u00e9ier d'Erw\u00e4chen vun den Autoen beim starten", - "scan_interval": "Sekonnen t\u00ebscht Scannen" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/lv.json b/homeassistant/components/tesla/translations/lv.json deleted file mode 100644 index eab98211e14..00000000000 --- a/homeassistant/components/tesla/translations/lv.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "config": { - "step": { - "user": { - "data": { - "password": "Parole", - "username": "E-pasta adrese" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/nl.json b/homeassistant/components/tesla/translations/nl.json deleted file mode 100644 index 689766cd906..00000000000 --- a/homeassistant/components/tesla/translations/nl.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Account is al geconfigureerd", - "reauth_successful": "Herauthenticatie was succesvol" - }, - "error": { - "already_configured": "Account is al geconfigureerd", - "cannot_connect": "Kan geen verbinding maken", - "invalid_auth": "Ongeldige authenticatie" - }, - "step": { - "user": { - "data": { - "mfa": "MFA Code (optioneel)", - "password": "Wachtwoord", - "username": "E-mail" - }, - "description": "Vul alstublieft uw gegevens in.", - "title": "Tesla - Configuratie" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "Forceer auto's wakker bij het opstarten", - "scan_interval": "Seconden tussen scans" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/no.json b/homeassistant/components/tesla/translations/no.json deleted file mode 100644 index 11e49486107..00000000000 --- a/homeassistant/components/tesla/translations/no.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Kontoen er allerede konfigurert", - "reauth_successful": "Godkjenning p\u00e5 nytt var vellykket" - }, - "error": { - "already_configured": "Kontoen er allerede konfigurert", - "cannot_connect": "Tilkobling mislyktes", - "invalid_auth": "Ugyldig godkjenning" - }, - "step": { - "user": { - "data": { - "mfa": "MFA -kode (valgfritt)", - "password": "Passord", - "username": "E-post" - }, - "description": "Vennligst fyll inn din informasjonen.", - "title": "Tesla - Konfigurasjon" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "Tving biler til \u00e5 v\u00e5kne ved oppstart", - "scan_interval": "Sekunder mellom skanninger" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/pl.json b/homeassistant/components/tesla/translations/pl.json deleted file mode 100644 index 266a0e82dbe..00000000000 --- a/homeassistant/components/tesla/translations/pl.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Konto jest ju\u017c skonfigurowane", - "reauth_successful": "Ponowne uwierzytelnienie powiod\u0142o si\u0119" - }, - "error": { - "already_configured": "Konto jest ju\u017c skonfigurowane", - "cannot_connect": "Nie mo\u017cna nawi\u0105za\u0107 po\u0142\u0105czenia", - "invalid_auth": "Niepoprawne uwierzytelnienie" - }, - "step": { - "user": { - "data": { - "mfa": "Kod uwierzytelniania wielosk\u0142adnikowego (opcjonalnie)", - "password": "Has\u0142o", - "username": "Adres e-mail" - }, - "description": "Wprowad\u017a dane", - "title": "Tesla \u2014 konfiguracja" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "Wymu\u015b wybudzenie samochod\u00f3w podczas uruchamiania", - "scan_interval": "Cz\u0119stotliwo\u015b\u0107 aktualizacji" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/pt-BR.json b/homeassistant/components/tesla/translations/pt-BR.json deleted file mode 100644 index 1317f4b1dd7..00000000000 --- a/homeassistant/components/tesla/translations/pt-BR.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "config": { - "step": { - "user": { - "data": { - "password": "Senha", - "username": "Endere\u00e7o de e-mail" - }, - "description": "Por favor, insira suas informa\u00e7\u00f5es.", - "title": "Tesla - Configura\u00e7\u00e3o" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "For\u00e7ar carros a acordar na inicializa\u00e7\u00e3o" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/pt.json b/homeassistant/components/tesla/translations/pt.json deleted file mode 100644 index c249c325adc..00000000000 --- a/homeassistant/components/tesla/translations/pt.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "config": { - "error": { - "already_configured": "Conta j\u00e1 configurada", - "cannot_connect": "Falha na liga\u00e7\u00e3o", - "invalid_auth": "Autentica\u00e7\u00e3o inv\u00e1lida" - }, - "step": { - "user": { - "data": { - "password": "Palavra-passe", - "username": "Endere\u00e7o de e-mail" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/ru.json b/homeassistant/components/tesla/translations/ru.json deleted file mode 100644 index 191d10b8bea..00000000000 --- a/homeassistant/components/tesla/translations/ru.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "\u042d\u0442\u0430 \u0443\u0447\u0451\u0442\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0432 Home Assistant.", - "reauth_successful": "\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e." - }, - "error": { - "already_configured": "\u042d\u0442\u0430 \u0443\u0447\u0451\u0442\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0432 Home Assistant.", - "cannot_connect": "\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f.", - "invalid_auth": "\u041e\u0448\u0438\u0431\u043a\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438." - }, - "step": { - "user": { - "data": { - "mfa": "\u041a\u043e\u0434 MFA (\u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e)", - "password": "\u041f\u0430\u0440\u043e\u043b\u044c", - "username": "\u0410\u0434\u0440\u0435\u0441 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u044b" - }, - "description": "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0443\u0447\u0451\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438.", - "title": "Tesla" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "\u041f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u0431\u0443\u0434\u0438\u0442\u044c \u043c\u0430\u0448\u0438\u043d\u0443 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435", - "scan_interval": "\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u043c\u0435\u0436\u0434\u0443 \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f\u043c\u0438 (\u0441\u0435\u043a.)" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/sl.json b/homeassistant/components/tesla/translations/sl.json deleted file mode 100644 index e72538e09bc..00000000000 --- a/homeassistant/components/tesla/translations/sl.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "config": { - "step": { - "user": { - "data": { - "password": "Geslo", - "username": "E-po\u0161tni naslov" - }, - "description": "Prosimo, vnesite svoje podatke.", - "title": "Tesla - konfiguracija" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "Vsili zbujanje avtomobila ob zagonu", - "scan_interval": "Sekund med skeniranjem" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/sv.json b/homeassistant/components/tesla/translations/sv.json deleted file mode 100644 index d347634cb14..00000000000 --- a/homeassistant/components/tesla/translations/sv.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "config": { - "step": { - "user": { - "data": { - "password": "L\u00f6senord", - "username": "E-postadress" - }, - "description": "V\u00e4nligen ange din information.", - "title": "Tesla - Konfiguration" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "scan_interval": "Sekunder mellan skanningar" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/tr.json b/homeassistant/components/tesla/translations/tr.json deleted file mode 100644 index cf0d144c1ed..00000000000 --- a/homeassistant/components/tesla/translations/tr.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "config": { - "error": { - "already_configured": "Hesap zaten yap\u0131land\u0131r\u0131lm\u0131\u015f", - "cannot_connect": "Ba\u011flanma hatas\u0131", - "invalid_auth": "Ge\u00e7ersiz kimlik do\u011frulama" - }, - "step": { - "user": { - "data": { - "password": "Parola", - "username": "E-posta" - }, - "description": "L\u00fctfen bilgilerinizi giriniz." - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/uk.json b/homeassistant/components/tesla/translations/uk.json deleted file mode 100644 index 90d47ec2ff5..00000000000 --- a/homeassistant/components/tesla/translations/uk.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "config": { - "error": { - "already_configured": "\u0426\u0435\u0439 \u043e\u0431\u043b\u0456\u043a\u043e\u0432\u0438\u0439 \u0437\u0430\u043f\u0438\u0441 \u0432\u0436\u0435 \u0434\u043e\u0434\u0430\u043d\u043e \u0432 Home Assistant.", - "cannot_connect": "\u041d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f \u043f\u0456\u0434'\u0454\u0434\u043d\u0430\u0442\u0438\u0441\u044f", - "invalid_auth": "\u041d\u0435\u0432\u0456\u0440\u043d\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u044f." - }, - "step": { - "user": { - "data": { - "password": "\u041f\u0430\u0440\u043e\u043b\u044c", - "username": "\u0410\u0434\u0440\u0435\u0441\u0430 \u0435\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0457 \u043f\u043e\u0448\u0442\u0438" - }, - "description": "\u0412\u0432\u0435\u0434\u0456\u0442\u044c \u0434\u0430\u043d\u0456 \u043e\u0431\u043b\u0456\u043a\u043e\u0432\u043e\u0433\u043e \u0437\u0430\u043f\u0438\u0441\u0443.", - "title": "Tesla" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "\u041f\u0440\u0438\u043c\u0443\u0441\u043e\u0432\u043e \u0440\u043e\u0437\u0431\u0443\u0434\u0438\u0442\u0438 \u043c\u0430\u0448\u0438\u043d\u0443 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0443", - "scan_interval": "\u0406\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u043c\u0456\u0436 \u0441\u043a\u0430\u043d\u0443\u0432\u0430\u043d\u043d\u044f\u043c\u0438 (\u0441\u0435\u043a.)" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/zh-Hans.json b/homeassistant/components/tesla/translations/zh-Hans.json deleted file mode 100644 index 35635ce3be3..00000000000 --- a/homeassistant/components/tesla/translations/zh-Hans.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "config": { - "step": { - "user": { - "data": { - "mfa": "MFA \u4ee3\u7801\uff08\u53ef\u9009\uff09" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/tesla/translations/zh-Hant.json b/homeassistant/components/tesla/translations/zh-Hant.json deleted file mode 100644 index 9ff407efaa3..00000000000 --- a/homeassistant/components/tesla/translations/zh-Hant.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "\u5e33\u865f\u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210", - "reauth_successful": "\u91cd\u65b0\u8a8d\u8b49\u6210\u529f" - }, - "error": { - "already_configured": "\u5e33\u865f\u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210", - "cannot_connect": "\u9023\u7dda\u5931\u6557", - "invalid_auth": "\u9a57\u8b49\u78bc\u7121\u6548" - }, - "step": { - "user": { - "data": { - "mfa": "MFA \u78bc\uff08\u9078\u9805\uff09", - "password": "\u5bc6\u78bc", - "username": "\u96fb\u5b50\u90f5\u4ef6" - }, - "description": "\u8acb\u8f38\u5165\u8cc7\u8a0a\u3002", - "title": "Tesla - \u8a2d\u5b9a" - } - } - }, - "options": { - "step": { - "init": { - "data": { - "enable_wake_on_start": "\u65bc\u555f\u52d5\u6642\u5f37\u5236\u559a\u9192\u6c7d\u8eca", - "scan_interval": "\u6383\u63cf\u9593\u9694\u79d2\u6578" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/generated/config_flows.py b/homeassistant/generated/config_flows.py index 2eb4e43fe32..57f152bb5a2 100644 --- a/homeassistant/generated/config_flows.py +++ b/homeassistant/generated/config_flows.py @@ -272,7 +272,6 @@ FLOWS = [ "tado", "tasmota", "tellduslive", - "tesla", "tibber", "tile", "toon", diff --git a/homeassistant/generated/dhcp.py b/homeassistant/generated/dhcp.py index cf442504121..3e00f8f5605 100644 --- a/homeassistant/generated/dhcp.py +++ b/homeassistant/generated/dhcp.py @@ -259,21 +259,6 @@ DHCP = [ "domain": "tado", "hostname": "tado*" }, - { - "domain": "tesla", - "hostname": "tesla_*", - "macaddress": "4CFCAA*" - }, - { - "domain": "tesla", - "hostname": "tesla_*", - "macaddress": "044EAF*" - }, - { - "domain": "tesla", - "hostname": "tesla_*", - "macaddress": "98ED5C*" - }, { "domain": "toon", "hostname": "eneco-*", diff --git a/mypy.ini b/mypy.ini index e2e570c18c2..8967a0502d1 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1618,9 +1618,6 @@ ignore_errors = true [mypy-homeassistant.components.template.*] ignore_errors = true -[mypy-homeassistant.components.tesla.*] -ignore_errors = true - [mypy-homeassistant.components.toon.*] ignore_errors = true diff --git a/requirements_all.txt b/requirements_all.txt index 20f5472f62d..4d8230c8bee 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2283,9 +2283,6 @@ temperusb==1.5.3 # homeassistant.components.powerwall tesla-powerwall==0.3.10 -# homeassistant.components.tesla -teslajsonpy==0.18.3 - # homeassistant.components.tensorflow # tf-models-official==2.3.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 532faf9456c..47598fde7f8 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1275,9 +1275,6 @@ tellduslive==0.10.11 # homeassistant.components.powerwall tesla-powerwall==0.3.10 -# homeassistant.components.tesla -teslajsonpy==0.18.3 - # homeassistant.components.toon toonapi==0.2.0 diff --git a/script/hassfest/mypy_config.py b/script/hassfest/mypy_config.py index 78707494ef5..6a076a5a5e6 100644 --- a/script/hassfest/mypy_config.py +++ b/script/hassfest/mypy_config.py @@ -128,7 +128,6 @@ IGNORED_MODULES: Final[list[str]] = [ "homeassistant.components.tado.*", "homeassistant.components.telegram_bot.*", "homeassistant.components.template.*", - "homeassistant.components.tesla.*", "homeassistant.components.toon.*", "homeassistant.components.tplink.*", "homeassistant.components.unifi.*", diff --git a/tests/components/tesla/__init__.py b/tests/components/tesla/__init__.py deleted file mode 100644 index 89b1e1c0c54..00000000000 --- a/tests/components/tesla/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Tests for the Tesla integration.""" diff --git a/tests/components/tesla/test_config_flow.py b/tests/components/tesla/test_config_flow.py deleted file mode 100644 index 4a45aac5124..00000000000 --- a/tests/components/tesla/test_config_flow.py +++ /dev/null @@ -1,270 +0,0 @@ -"""Test the Tesla config flow.""" -import datetime -from unittest.mock import patch - -from teslajsonpy.exceptions import IncompleteCredentials, TeslaException - -from homeassistant import config_entries, data_entry_flow, setup -from homeassistant.components.tesla.const import ( - CONF_EXPIRATION, - CONF_WAKE_ON_START, - DEFAULT_SCAN_INTERVAL, - DEFAULT_WAKE_ON_START, - DOMAIN, - MIN_SCAN_INTERVAL, -) -from homeassistant.const import ( - CONF_ACCESS_TOKEN, - CONF_PASSWORD, - CONF_SCAN_INTERVAL, - CONF_TOKEN, - CONF_USERNAME, - HTTP_NOT_FOUND, -) - -from tests.common import MockConfigEntry - -TEST_USERNAME = "test-username" -TEST_TOKEN = "test-token" -TEST_PASSWORD = "test-password" -TEST_ACCESS_TOKEN = "test-access-token" -TEST_VALID_EXPIRATION = datetime.datetime.now().timestamp() * 2 - - -async def test_form(hass): - """Test we get the form.""" - await setup.async_setup_component(hass, "persistent_notification", {}) - result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": config_entries.SOURCE_USER} - ) - assert result["type"] == "form" - assert result["errors"] == {} - - with patch( - "homeassistant.components.tesla.config_flow.TeslaAPI.connect", - return_value={ - "refresh_token": TEST_TOKEN, - CONF_ACCESS_TOKEN: TEST_ACCESS_TOKEN, - CONF_EXPIRATION: TEST_VALID_EXPIRATION, - }, - ), patch( - "homeassistant.components.tesla.async_setup", return_value=True - ) as mock_setup, patch( - "homeassistant.components.tesla.async_setup_entry", return_value=True - ) as mock_setup_entry: - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], {CONF_PASSWORD: "test", CONF_USERNAME: "test@email.com"} - ) - await hass.async_block_till_done() - - assert result2["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY - assert result2["title"] == "test@email.com" - assert result2["data"] == { - CONF_USERNAME: "test@email.com", - CONF_PASSWORD: "test", - CONF_TOKEN: TEST_TOKEN, - CONF_ACCESS_TOKEN: TEST_ACCESS_TOKEN, - CONF_EXPIRATION: TEST_VALID_EXPIRATION, - } - assert len(mock_setup.mock_calls) == 1 - assert len(mock_setup_entry.mock_calls) == 1 - - -async def test_form_invalid_auth(hass): - """Test we handle invalid auth.""" - result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": config_entries.SOURCE_USER} - ) - - with patch( - "homeassistant.components.tesla.config_flow.TeslaAPI.connect", - side_effect=TeslaException(401), - ): - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - {CONF_USERNAME: TEST_USERNAME, CONF_PASSWORD: TEST_PASSWORD}, - ) - - assert result2["type"] == "form" - assert result2["errors"] == {"base": "invalid_auth"} - - -async def test_form_invalid_auth_incomplete_credentials(hass): - """Test we handle invalid auth with incomplete credentials.""" - result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": config_entries.SOURCE_USER} - ) - - with patch( - "homeassistant.components.tesla.config_flow.TeslaAPI.connect", - side_effect=IncompleteCredentials(401), - ): - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - {CONF_USERNAME: TEST_USERNAME, CONF_PASSWORD: TEST_PASSWORD}, - ) - - assert result2["type"] == "form" - assert result2["errors"] == {"base": "invalid_auth"} - - -async def test_form_cannot_connect(hass): - """Test we handle cannot connect error.""" - result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": config_entries.SOURCE_USER} - ) - - with patch( - "homeassistant.components.tesla.config_flow.TeslaAPI.connect", - side_effect=TeslaException(code=HTTP_NOT_FOUND), - ): - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - {CONF_PASSWORD: TEST_PASSWORD, CONF_USERNAME: TEST_USERNAME}, - ) - - assert result2["type"] == "form" - assert result2["errors"] == {"base": "cannot_connect"} - - -async def test_form_repeat_identifier(hass): - """Test we handle repeat identifiers.""" - entry = MockConfigEntry( - domain=DOMAIN, - title=TEST_USERNAME, - data={"username": TEST_USERNAME, "password": TEST_PASSWORD}, - options=None, - ) - entry.add_to_hass(hass) - - result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": config_entries.SOURCE_USER} - ) - with patch( - "homeassistant.components.tesla.config_flow.TeslaAPI.connect", - return_value={ - "refresh_token": TEST_TOKEN, - CONF_ACCESS_TOKEN: TEST_ACCESS_TOKEN, - CONF_EXPIRATION: TEST_VALID_EXPIRATION, - }, - ): - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - {CONF_USERNAME: TEST_USERNAME, CONF_PASSWORD: TEST_PASSWORD}, - ) - - assert result2["type"] == "abort" - assert result2["reason"] == "already_configured" - - -async def test_form_reauth(hass): - """Test we handle reauth.""" - entry = MockConfigEntry( - domain=DOMAIN, - title=TEST_USERNAME, - data={"username": TEST_USERNAME, "password": "same"}, - options=None, - ) - entry.add_to_hass(hass) - - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": config_entries.SOURCE_REAUTH}, - data={"username": TEST_USERNAME}, - ) - with patch( - "homeassistant.components.tesla.config_flow.TeslaAPI.connect", - return_value={ - "refresh_token": TEST_TOKEN, - CONF_ACCESS_TOKEN: TEST_ACCESS_TOKEN, - CONF_EXPIRATION: TEST_VALID_EXPIRATION, - }, - ): - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - {CONF_USERNAME: TEST_USERNAME, CONF_PASSWORD: "new-password"}, - ) - - assert result2["type"] == "abort" - assert result2["reason"] == "reauth_successful" - - -async def test_import(hass): - """Test import step.""" - - with patch( - "homeassistant.components.tesla.config_flow.TeslaAPI.connect", - return_value={ - "refresh_token": TEST_TOKEN, - CONF_ACCESS_TOKEN: TEST_ACCESS_TOKEN, - CONF_EXPIRATION: TEST_VALID_EXPIRATION, - }, - ): - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": config_entries.SOURCE_IMPORT}, - data={CONF_PASSWORD: TEST_PASSWORD, CONF_USERNAME: TEST_USERNAME}, - ) - assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY - assert result["title"] == TEST_USERNAME - assert result["data"][CONF_ACCESS_TOKEN] == TEST_ACCESS_TOKEN - assert result["data"][CONF_TOKEN] == TEST_TOKEN - assert result["description_placeholders"] is None - - -async def test_option_flow(hass): - """Test config flow options.""" - entry = MockConfigEntry(domain=DOMAIN, data={}, options=None) - entry.add_to_hass(hass) - - result = await hass.config_entries.options.async_init(entry.entry_id) - - assert result["type"] == "form" - assert result["step_id"] == "init" - - result = await hass.config_entries.options.async_configure( - result["flow_id"], - user_input={CONF_SCAN_INTERVAL: 350, CONF_WAKE_ON_START: True}, - ) - assert result["type"] == "create_entry" - assert result["data"] == {CONF_SCAN_INTERVAL: 350, CONF_WAKE_ON_START: True} - - -async def test_option_flow_defaults(hass): - """Test config flow options.""" - entry = MockConfigEntry(domain=DOMAIN, data={}, options=None) - entry.add_to_hass(hass) - - result = await hass.config_entries.options.async_init(entry.entry_id) - - assert result["type"] == "form" - assert result["step_id"] == "init" - - result = await hass.config_entries.options.async_configure( - result["flow_id"], user_input={} - ) - assert result["type"] == "create_entry" - assert result["data"] == { - CONF_SCAN_INTERVAL: DEFAULT_SCAN_INTERVAL, - CONF_WAKE_ON_START: DEFAULT_WAKE_ON_START, - } - - -async def test_option_flow_input_floor(hass): - """Test config flow options.""" - entry = MockConfigEntry(domain=DOMAIN, data={}, options=None) - entry.add_to_hass(hass) - - result = await hass.config_entries.options.async_init(entry.entry_id) - - assert result["type"] == "form" - assert result["step_id"] == "init" - - result = await hass.config_entries.options.async_configure( - result["flow_id"], user_input={CONF_SCAN_INTERVAL: 1} - ) - assert result["type"] == "create_entry" - assert result["data"] == { - CONF_SCAN_INTERVAL: MIN_SCAN_INTERVAL, - CONF_WAKE_ON_START: DEFAULT_WAKE_ON_START, - }