From 0cf9e9904405244d51b631c393db28cae7369a01 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Wed, 11 Nov 2020 19:27:47 +0100 Subject: [PATCH 01/73] Bumped version to 0.118.0b0 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 173a39080b7..8adf37bb817 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 118 -PATCH_VERSION = "0.dev0" +PATCH_VERSION = "0b0" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 1) From f5184c5aef8957950412fab352aefb38f5636ae0 Mon Sep 17 00:00:00 2001 From: Marvin Wichmann Date: Fri, 13 Nov 2020 09:37:45 +0100 Subject: [PATCH 02/73] Update xknx to 0.15.3 (#42026) Co-authored-by: Paulus Schoutsen --- homeassistant/components/knx/binary_sensor.py | 10 +++++ homeassistant/components/knx/climate.py | 38 +++++++++---------- homeassistant/components/knx/const.py | 8 +++- homeassistant/components/knx/factory.py | 6 ++- homeassistant/components/knx/manifest.json | 2 +- homeassistant/components/knx/schema.py | 24 +++++++++--- homeassistant/components/knx/sensor.py | 10 +++++ requirements_all.txt | 2 +- 8 files changed, 70 insertions(+), 30 deletions(-) diff --git a/homeassistant/components/knx/binary_sensor.py b/homeassistant/components/knx/binary_sensor.py index a62e95f1def..35feb09dc1d 100644 --- a/homeassistant/components/knx/binary_sensor.py +++ b/homeassistant/components/knx/binary_sensor.py @@ -41,3 +41,13 @@ class KNXBinarySensor(KnxEntity, BinarySensorEntity): def device_state_attributes(self) -> Optional[Dict[str, Any]]: """Return device specific state attributes.""" return {ATTR_COUNTER: self._device.counter} + + @property + def force_update(self) -> bool: + """ + Return True if state updates should be forced. + + If True, a state change will be triggered anytime the state property is + updated, not just when the value changes. + """ + return self._device.ignore_internal_state diff --git a/homeassistant/components/knx/climate.py b/homeassistant/components/knx/climate.py index 1960627a8d6..070f635cc48 100644 --- a/homeassistant/components/knx/climate.py +++ b/homeassistant/components/knx/climate.py @@ -2,7 +2,7 @@ from typing import List, Optional from xknx.devices import Climate as XknxClimate -from xknx.dpt import HVACOperationMode +from xknx.dpt import HVACControllerMode, HVACOperationMode from homeassistant.components.climate import ClimateEntity from homeassistant.components.climate.const import ( @@ -14,11 +14,11 @@ from homeassistant.components.climate.const import ( ) from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS -from .const import DOMAIN, OPERATION_MODES, PRESET_MODES +from .const import CONTROLLER_MODES, DOMAIN, PRESET_MODES from .knx_entity import KnxEntity -OPERATION_MODES_INV = dict(reversed(item) for item in OPERATION_MODES.items()) -PRESET_MODES_INV = dict(reversed(item) for item in PRESET_MODES.items()) +CONTROLLER_MODES_INV = {value: key for key, value in CONTROLLER_MODES.items()} +PRESET_MODES_INV = {value: key for key, value in PRESET_MODES.items()} async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): @@ -92,27 +92,27 @@ class KNXClimate(KnxEntity, ClimateEntity): """Return current operation ie. heat, cool, idle.""" if self._device.supports_on_off and not self._device.is_on: return HVAC_MODE_OFF - if self._device.mode.supports_operation_mode: - return OPERATION_MODES.get( - self._device.mode.operation_mode.value, HVAC_MODE_HEAT + if self._device.mode.supports_controller_mode: + return CONTROLLER_MODES.get( + self._device.mode.controller_mode.value, HVAC_MODE_HEAT ) # default to "heat" return HVAC_MODE_HEAT @property def hvac_modes(self) -> Optional[List[str]]: - """Return the list of available operation modes.""" - _operations = [ - OPERATION_MODES.get(operation_mode.value) - for operation_mode in self._device.mode.operation_modes + """Return the list of available operation/controller modes.""" + _controller_modes = [ + CONTROLLER_MODES.get(controller_mode.value) + for controller_mode in self._device.mode.controller_modes ] if self._device.supports_on_off: - if not _operations: - _operations.append(HVAC_MODE_HEAT) - _operations.append(HVAC_MODE_OFF) + if not _controller_modes: + _controller_modes.append(HVAC_MODE_HEAT) + _controller_modes.append(HVAC_MODE_OFF) - _modes = list(set(filter(None, _operations))) + _modes = list(set(filter(None, _controller_modes))) # default to ["heat"] return _modes if _modes else [HVAC_MODE_HEAT] @@ -123,11 +123,11 @@ class KNXClimate(KnxEntity, ClimateEntity): else: if self._device.supports_on_off and not self._device.is_on: await self._device.turn_on() - if self._device.mode.supports_operation_mode: - knx_operation_mode = HVACOperationMode( - OPERATION_MODES_INV.get(hvac_mode) + if self._device.mode.supports_controller_mode: + knx_controller_mode = HVACControllerMode( + CONTROLLER_MODES_INV.get(hvac_mode) ) - await self._device.mode.set_operation_mode(knx_operation_mode) + await self._device.mode.set_controller_mode(knx_controller_mode) self.async_write_ha_state() @property diff --git a/homeassistant/components/knx/const.py b/homeassistant/components/knx/const.py index 8b0dd90393b..e434aed395d 100644 --- a/homeassistant/components/knx/const.py +++ b/homeassistant/components/knx/const.py @@ -11,13 +11,16 @@ from homeassistant.components.climate.const import ( PRESET_AWAY, PRESET_COMFORT, PRESET_ECO, + PRESET_NONE, PRESET_SLEEP, ) DOMAIN = "knx" +CONF_INVERT = "invert" CONF_STATE_ADDRESS = "state_address" CONF_SYNC_STATE = "sync_state" +CONF_RESET_AFTER = "reset_after" class ColorTempModes(Enum): @@ -41,8 +44,8 @@ class SupportedPlatforms(Enum): weather = "weather" -# Map KNX operation modes to HA modes. This list might not be complete. -OPERATION_MODES = { +# Map KNX controller modes to HA modes. This list might not be complete. +CONTROLLER_MODES = { # Map DPT 20.105 HVAC control modes "Auto": HVAC_MODE_AUTO, "Heat": HVAC_MODE_HEAT, @@ -54,6 +57,7 @@ OPERATION_MODES = { PRESET_MODES = { # Map DPT 20.102 HVAC operating modes to HA presets + "Auto": PRESET_NONE, "Frost Protection": PRESET_ECO, "Night": PRESET_SLEEP, "Standby": PRESET_AWAY, diff --git a/homeassistant/components/knx/factory.py b/homeassistant/components/knx/factory.py index 3334e49ce38..6da2b73cd6a 100644 --- a/homeassistant/components/knx/factory.py +++ b/homeassistant/components/knx/factory.py @@ -164,6 +164,7 @@ def _create_climate(knx_module: XKNX, config: ConfigType) -> XknxClimate: ClimateSchema.CONF_HEAT_COOL_STATE_ADDRESS ), operation_modes=config.get(ClimateSchema.CONF_OPERATION_MODES), + controller_modes=config.get(ClimateSchema.CONF_CONTROLLER_MODES), ) return XknxClimate( @@ -202,6 +203,7 @@ def _create_switch(knx_module: XKNX, config: ConfigType) -> XknxSwitch: name=config[CONF_NAME], group_address=config[CONF_ADDRESS], group_address_state=config.get(SwitchSchema.CONF_STATE_ADDRESS), + invert=config.get(SwitchSchema.CONF_INVERT), ) @@ -212,6 +214,7 @@ def _create_sensor(knx_module: XKNX, config: ConfigType) -> XknxSensor: name=config[CONF_NAME], group_address_state=config[SensorSchema.CONF_STATE_ADDRESS], sync_state=config[SensorSchema.CONF_SYNC_STATE], + always_callback=config[SensorSchema.CONF_ALWAYS_CALLBACK], value_type=config[CONF_TYPE], ) @@ -243,10 +246,11 @@ def _create_binary_sensor(knx_module: XKNX, config: ConfigType) -> XknxBinarySen knx_module, name=device_name, group_address_state=config[BinarySensorSchema.CONF_STATE_ADDRESS], + invert=config.get(BinarySensorSchema.CONF_INVERT), sync_state=config[BinarySensorSchema.CONF_SYNC_STATE], device_class=config.get(CONF_DEVICE_CLASS), ignore_internal_state=config[BinarySensorSchema.CONF_IGNORE_INTERNAL_STATE], - context_timeout=config[BinarySensorSchema.CONF_CONTEXT_TIMEOUT], + context_timeout=config.get(BinarySensorSchema.CONF_CONTEXT_TIMEOUT), reset_after=config.get(BinarySensorSchema.CONF_RESET_AFTER), ) diff --git a/homeassistant/components/knx/manifest.json b/homeassistant/components/knx/manifest.json index 2d387f0653d..4055048fd2d 100644 --- a/homeassistant/components/knx/manifest.json +++ b/homeassistant/components/knx/manifest.json @@ -2,7 +2,7 @@ "domain": "knx", "name": "KNX", "documentation": "https://www.home-assistant.io/integrations/knx", - "requirements": ["xknx==0.15.0"], + "requirements": ["xknx==0.15.3"], "codeowners": ["@Julius2342", "@farmio", "@marvin-w"], "quality_scale": "silver" } diff --git a/homeassistant/components/knx/schema.py b/homeassistant/components/knx/schema.py index 84a54536db5..cbf06925163 100644 --- a/homeassistant/components/knx/schema.py +++ b/homeassistant/components/knx/schema.py @@ -15,9 +15,11 @@ from homeassistant.const import ( import homeassistant.helpers.config_validation as cv from .const import ( + CONF_INVERT, + CONF_RESET_AFTER, CONF_STATE_ADDRESS, CONF_SYNC_STATE, - OPERATION_MODES, + CONTROLLER_MODES, PRESET_MODES, ColorTempModes, ) @@ -84,9 +86,10 @@ class BinarySensorSchema: CONF_STATE_ADDRESS = CONF_STATE_ADDRESS CONF_SYNC_STATE = CONF_SYNC_STATE + CONF_INVERT = CONF_INVERT CONF_IGNORE_INTERNAL_STATE = "ignore_internal_state" CONF_CONTEXT_TIMEOUT = "context_timeout" - CONF_RESET_AFTER = "reset_after" + CONF_RESET_AFTER = CONF_RESET_AFTER DEFAULT_NAME = "KNX Binary Sensor" @@ -101,12 +104,13 @@ class BinarySensorSchema: cv.boolean, cv.string, ), - vol.Optional(CONF_IGNORE_INTERNAL_STATE, default=True): cv.boolean, - vol.Optional(CONF_CONTEXT_TIMEOUT, default=1.0): vol.All( + vol.Optional(CONF_IGNORE_INTERNAL_STATE, default=False): cv.boolean, + vol.Required(CONF_STATE_ADDRESS): cv.string, + vol.Optional(CONF_CONTEXT_TIMEOUT): vol.All( vol.Coerce(float), vol.Range(min=0, max=10) ), - vol.Required(CONF_STATE_ADDRESS): cv.string, vol.Optional(CONF_DEVICE_CLASS): cv.string, + vol.Optional(CONF_INVERT): cv.boolean, vol.Optional(CONF_RESET_AFTER): cv.positive_int, } ), @@ -187,6 +191,7 @@ class ClimateSchema: CONF_OPERATION_MODE_COMFORT_ADDRESS = "operation_mode_comfort_address" CONF_OPERATION_MODE_STANDBY_ADDRESS = "operation_mode_standby_address" CONF_OPERATION_MODES = "operation_modes" + CONF_CONTROLLER_MODES = "controller_modes" CONF_ON_OFF_ADDRESS = "on_off_address" CONF_ON_OFF_STATE_ADDRESS = "on_off_state_address" CONF_ON_OFF_INVERT = "on_off_invert" @@ -240,7 +245,10 @@ class ClimateSchema: CONF_ON_OFF_INVERT, default=DEFAULT_ON_OFF_INVERT ): cv.boolean, vol.Optional(CONF_OPERATION_MODES): vol.All( - cv.ensure_list, [vol.In({**OPERATION_MODES, **PRESET_MODES})] + cv.ensure_list, [vol.In({**PRESET_MODES})] + ), + vol.Optional(CONF_CONTROLLER_MODES): vol.All( + cv.ensure_list, [vol.In({**CONTROLLER_MODES})] ), vol.Optional(CONF_MIN_TEMP): vol.Coerce(float), vol.Optional(CONF_MAX_TEMP): vol.Coerce(float), @@ -252,6 +260,7 @@ class ClimateSchema: class SwitchSchema: """Voluptuous schema for KNX switches.""" + CONF_INVERT = CONF_INVERT CONF_STATE_ADDRESS = CONF_STATE_ADDRESS DEFAULT_NAME = "KNX Switch" @@ -260,6 +269,7 @@ class SwitchSchema: vol.Required(CONF_ADDRESS): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_STATE_ADDRESS): cv.string, + vol.Optional(CONF_INVERT): cv.boolean, } ) @@ -299,6 +309,7 @@ class NotifySchema: class SensorSchema: """Voluptuous schema for KNX sensors.""" + CONF_ALWAYS_CALLBACK = "always_callback" CONF_STATE_ADDRESS = CONF_STATE_ADDRESS CONF_SYNC_STATE = CONF_SYNC_STATE DEFAULT_NAME = "KNX Sensor" @@ -311,6 +322,7 @@ class SensorSchema: cv.boolean, cv.string, ), + vol.Optional(CONF_ALWAYS_CALLBACK, default=False): cv.boolean, vol.Required(CONF_STATE_ADDRESS): cv.string, vol.Required(CONF_TYPE): vol.Any(int, float, str), } diff --git a/homeassistant/components/knx/sensor.py b/homeassistant/components/knx/sensor.py index fc2cbced8bb..dc9ffcb61b7 100644 --- a/homeassistant/components/knx/sensor.py +++ b/homeassistant/components/knx/sensor.py @@ -41,3 +41,13 @@ class KNXSensor(KnxEntity, Entity): if device_class in DEVICE_CLASSES: return device_class return None + + @property + def force_update(self) -> bool: + """ + Return True if state updates should be forced. + + If True, a state change will be triggered anytime the state property is + updated, not just when the value changes. + """ + return self._device.always_callback diff --git a/requirements_all.txt b/requirements_all.txt index 29cc2164b10..d612d2686aa 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2301,7 +2301,7 @@ xboxapi==2.0.1 xfinity-gateway==0.0.4 # homeassistant.components.knx -xknx==0.15.0 +xknx==0.15.3 # homeassistant.components.bluesound # homeassistant.components.rest From b17cf755835e5ea455ae7b7c330f0bb6b347504d Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Thu, 12 Nov 2020 00:37:27 -0500 Subject: [PATCH 03/73] Move setup_url_for_address to pyWeMo library (#42722) * Move setup_url_for_address to PyWemo library * Bump pywemo to 0.5.2 * Use module-level function call * Update requirements via script --- homeassistant/components/wemo/__init__.py | 13 +------------ homeassistant/components/wemo/manifest.json | 2 +- requirements_all.txt | 2 +- 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/homeassistant/components/wemo/__init__.py b/homeassistant/components/wemo/__init__.py index 0594747d0b2..c656926ecff 100644 --- a/homeassistant/components/wemo/__init__.py +++ b/homeassistant/components/wemo/__init__.py @@ -164,7 +164,7 @@ async def async_setup_entry(hass, entry): def validate_static_config(host, port): """Handle a static config.""" - url = setup_url_for_address(host, port) + url = pywemo.setup_url_for_address(host, port) if not url: _LOGGER.error( @@ -183,14 +183,3 @@ def validate_static_config(host, port): return None return device - - -def setup_url_for_address(host, port): - """Determine setup.xml url for given host and port pair.""" - if not port: - port = pywemo.ouimeaux_device.probe_wemo(host) - - if not port: - return None - - return f"http://{host}:{port}/setup.xml" diff --git a/homeassistant/components/wemo/manifest.json b/homeassistant/components/wemo/manifest.json index 357d9d95483..a7d2ca585a5 100644 --- a/homeassistant/components/wemo/manifest.json +++ b/homeassistant/components/wemo/manifest.json @@ -3,7 +3,7 @@ "name": "Belkin WeMo", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/wemo", - "requirements": ["pywemo==0.5.0"], + "requirements": ["pywemo==0.5.2"], "ssdp": [ { "manufacturer": "Belkin International Inc." diff --git a/requirements_all.txt b/requirements_all.txt index d612d2686aa..5810e11ba0c 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1888,7 +1888,7 @@ pyvolumio==0.1.3 pywebpush==1.9.2 # homeassistant.components.wemo -pywemo==0.5.0 +pywemo==0.5.2 # homeassistant.components.wilight pywilight==0.0.65 From 9e65eb53e47b6b0429d88ce622582aaf94c2ff15 Mon Sep 17 00:00:00 2001 From: SukramJ Date: Thu, 12 Nov 2020 10:33:01 +0100 Subject: [PATCH 04/73] Bump dependency for HomematicIP Cloud (#43018) Co-authored-by: Paulus Schoutsen --- .../components/homematicip_cloud/__init__.py | 36 ++- .../homematicip_cloud/binary_sensor.py | 10 +- .../components/homematicip_cloud/hap.py | 5 +- .../homematicip_cloud/manifest.json | 2 +- .../components/homematicip_cloud/sensor.py | 40 +-- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- .../components/homematicip_cloud/conftest.py | 2 +- tests/components/homematicip_cloud/helper.py | 6 +- .../homematicip_cloud/test_binary_sensor.py | 10 +- .../homematicip_cloud/test_device.py | 4 +- .../components/homematicip_cloud/test_init.py | 5 +- .../homematicip_cloud/test_sensor.py | 13 +- tests/fixtures/homematicip_cloud.json | 249 +++++++++++++++++- 14 files changed, 320 insertions(+), 66 deletions(-) diff --git a/homeassistant/components/homematicip_cloud/__init__.py b/homeassistant/components/homematicip_cloud/__init__.py index 2b078966ee8..7ea6a4fe0b4 100644 --- a/homeassistant/components/homematicip_cloud/__init__.py +++ b/homeassistant/components/homematicip_cloud/__init__.py @@ -1,11 +1,14 @@ """Support for HomematicIP Cloud devices.""" +import logging + import voluptuous as vol from homeassistant import config_entries from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME, EVENT_HOMEASSISTANT_STOP -from homeassistant.helpers import device_registry as dr +from homeassistant.helpers import device_registry as dr, entity_registry as er import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.entity_registry import async_entries_for_config_entry from homeassistant.helpers.typing import ConfigType, HomeAssistantType from .const import ( @@ -20,6 +23,8 @@ from .generic_entity import HomematicipGenericEntity # noqa: F401 from .hap import HomematicipAuth, HomematicipHAP # noqa: F401 from .services import async_setup_services, async_unload_services +_LOGGER = logging.getLogger(__name__) + CONFIG_SCHEMA = vol.Schema( { vol.Optional(DOMAIN, default=[]): vol.All( @@ -83,6 +88,7 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool return False await async_setup_services(hass) + await async_remove_obsolete_entities(hass, entry, hap) # Register on HA stop event to gracefully shutdown HomematicIP Cloud connection hap.reset_connection_listener = hass.bus.async_listen_once( @@ -91,16 +97,16 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool # Register hap as device in registry. device_registry = await dr.async_get_registry(hass) + home = hap.home - # Add the HAP name from configuration if set. - hapname = home.label if not home.name else f"{home.name} {home.label}" + hapname = home.label if home.label != entry.unique_id else f"Home-{home.label}" + device_registry.async_get_or_create( config_entry_id=entry.entry_id, identifiers={(DOMAIN, home.id)}, manufacturer="eQ-3", + # Add the name from config entry. name=hapname, - model=home.modelType, - sw_version=home.currentAPVersion, ) return True @@ -113,3 +119,23 @@ async def async_unload_entry(hass: HomeAssistantType, entry: ConfigEntry) -> boo await async_unload_services(hass) return await hap.async_reset() + + +async def async_remove_obsolete_entities( + hass: HomeAssistantType, entry: ConfigEntry, hap: HomematicipHAP +): + """Remove obsolete entities from entity registry.""" + + if hap.home.currentAPVersion < "2.2.12": + return + + entity_registry = await er.async_get_registry(hass) + er_entries = async_entries_for_config_entry(entity_registry, entry.entry_id) + for er_entry in er_entries: + if er_entry.unique_id.startswith("HomematicipAccesspointStatus"): + entity_registry.async_remove(er_entry.entity_id) + continue + + for hapid in hap.home.accessPointUpdateStates: + if er_entry.unique_id == f"HomematicipBatterySensor_{hapid}": + entity_registry.async_remove(er_entry.entity_id) diff --git a/homeassistant/components/homematicip_cloud/binary_sensor.py b/homeassistant/components/homematicip_cloud/binary_sensor.py index e03738e4a76..12bca8378c3 100644 --- a/homeassistant/components/homematicip_cloud/binary_sensor.py +++ b/homeassistant/components/homematicip_cloud/binary_sensor.py @@ -146,7 +146,15 @@ class HomematicipCloudConnectionSensor(HomematicipGenericEntity, BinarySensorEnt def __init__(self, hap: HomematicipHAP) -> None: """Initialize the cloud connection sensor.""" - super().__init__(hap, hap.home, "Cloud Connection") + super().__init__(hap, hap.home) + + @property + def name(self) -> str: + """Return the name cloud connection entity.""" + + name = "Cloud Connection" + # Add a prefix to the name if the homematic ip home has a name. + return name if not self._home.name else f"{self._home.name} {name}" @property def device_info(self) -> Dict[str, Any]: diff --git a/homeassistant/components/homematicip_cloud/hap.py b/homeassistant/components/homematicip_cloud/hap.py index 164997d5582..151807391b9 100644 --- a/homeassistant/components/homematicip_cloud/hap.py +++ b/homeassistant/components/homematicip_cloud/hap.py @@ -240,8 +240,9 @@ class HomematicipHAP: home = AsyncHome(hass.loop, async_get_clientsession(hass)) home.name = name - home.label = "Access Point" - home.modelType = "HmIP-HAP" + # Use the title of the config entry as title for the home. + home.label = self.config_entry.title + home.modelType = "HomematicIP Cloud Home" home.set_auth_token(authtoken) try: diff --git a/homeassistant/components/homematicip_cloud/manifest.json b/homeassistant/components/homematicip_cloud/manifest.json index 3ecf668e449..30ca5165c85 100644 --- a/homeassistant/components/homematicip_cloud/manifest.json +++ b/homeassistant/components/homematicip_cloud/manifest.json @@ -3,7 +3,7 @@ "name": "HomematicIP Cloud", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/homematicip_cloud", - "requirements": ["homematicip==0.11.0"], + "requirements": ["homematicip==0.12.1"], "codeowners": ["@SukramJ"], "quality_scale": "platinum" } diff --git a/homeassistant/components/homematicip_cloud/sensor.py b/homeassistant/components/homematicip_cloud/sensor.py index 66e0e1afd70..9e202302c10 100644 --- a/homeassistant/components/homematicip_cloud/sensor.py +++ b/homeassistant/components/homematicip_cloud/sensor.py @@ -6,6 +6,7 @@ from homematicip.aio.device import ( AsyncFullFlushSwitchMeasuring, AsyncHeatingThermostat, AsyncHeatingThermostatCompact, + AsyncHomeControlAccessPoint, AsyncLightSensor, AsyncMotionDetectorIndoor, AsyncMotionDetectorOutdoor, @@ -39,7 +40,6 @@ from homeassistant.const import ( from homeassistant.helpers.typing import HomeAssistantType from . import DOMAIN as HMIPC_DOMAIN, HomematicipGenericEntity -from .generic_entity import ATTR_IS_GROUP, ATTR_MODEL_TYPE from .hap import HomematicipHAP ATTR_CURRENT_ILLUMINATION = "current_illumination" @@ -63,8 +63,10 @@ async def async_setup_entry( ) -> None: """Set up the HomematicIP Cloud sensors from a config entry.""" hap = hass.data[HMIPC_DOMAIN][config_entry.unique_id] - entities = [HomematicipAccesspointStatus(hap)] + entities = [] for device in hap.home.devices: + if isinstance(device, AsyncHomeControlAccessPoint): + entities.append(HomematicipAccesspointDutyCycle(hap, device)) if isinstance(device, (AsyncHeatingThermostat, AsyncHeatingThermostatCompact)): entities.append(HomematicipHeatingThermostat(hap, device)) entities.append(HomematicipTemperatureSensor(hap, device)) @@ -119,23 +121,12 @@ async def async_setup_entry( async_add_entities(entities) -class HomematicipAccesspointStatus(HomematicipGenericEntity): +class HomematicipAccesspointDutyCycle(HomematicipGenericEntity): """Representation of then HomeMaticIP access point.""" - def __init__(self, hap: HomematicipHAP) -> None: + def __init__(self, hap: HomematicipHAP, device) -> None: """Initialize access point status entity.""" - super().__init__(hap, device=hap.home, post="Duty Cycle") - - @property - def device_info(self) -> Dict[str, Any]: - """Return device specific attributes.""" - # Adds a sensor to the existing HAP device - return { - "identifiers": { - # Serial numbers of Homematic IP device - (HMIPC_DOMAIN, self._home.id) - } - } + super().__init__(hap, device, post="Duty Cycle") @property def icon(self) -> str: @@ -145,28 +136,13 @@ class HomematicipAccesspointStatus(HomematicipGenericEntity): @property def state(self) -> float: """Return the state of the access point.""" - return self._home.dutyCycle - - @property - def available(self) -> bool: - """Return if access point is available.""" - return self._home.connected + return self._device.dutyCycleLevel @property def unit_of_measurement(self) -> str: """Return the unit this state is expressed in.""" return PERCENTAGE - @property - def device_state_attributes(self) -> Dict[str, Any]: - """Return the state attributes of the access point.""" - state_attr = super().device_state_attributes - - state_attr[ATTR_MODEL_TYPE] = "HmIP-HAP" - state_attr[ATTR_IS_GROUP] = False - - return state_attr - class HomematicipHeatingThermostat(HomematicipGenericEntity): """Representation of the HomematicIP heating thermostat.""" diff --git a/requirements_all.txt b/requirements_all.txt index 5810e11ba0c..2e112e72569 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -777,7 +777,7 @@ homeassistant-pyozw==0.1.10 homeconnect==0.6.3 # homeassistant.components.homematicip_cloud -homematicip==0.11.0 +homematicip==0.12.1 # homeassistant.components.horizon horimote==0.4.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index adaf2f94dfc..59bc7a86047 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -403,7 +403,7 @@ homeassistant-pyozw==0.1.10 homeconnect==0.6.3 # homeassistant.components.homematicip_cloud -homematicip==0.11.0 +homematicip==0.12.1 # homeassistant.components.google # homeassistant.components.remember_the_milk diff --git a/tests/components/homematicip_cloud/conftest.py b/tests/components/homematicip_cloud/conftest.py index b967ef79094..9764ee74e22 100644 --- a/tests/components/homematicip_cloud/conftest.py +++ b/tests/components/homematicip_cloud/conftest.py @@ -56,7 +56,7 @@ def hmip_config_entry_fixture() -> config_entries.ConfigEntry: config_entry = MockConfigEntry( version=1, domain=HMIPC_DOMAIN, - title=HAPID, + title="Home Test SN", unique_id=HAPID, data=entry_data, source=SOURCE_IMPORT, diff --git a/tests/components/homematicip_cloud/helper.py b/tests/components/homematicip_cloud/helper.py index dbbf0249c0c..ca7d8862756 100644 --- a/tests/components/homematicip_cloud/helper.py +++ b/tests/components/homematicip_cloud/helper.py @@ -136,9 +136,9 @@ class HomeTemplate(Home): def __init__(self, connection=None, home_name="", test_devices=[], test_groups=[]): """Init template with connection.""" super().__init__(connection=connection) - self.label = "Access Point" self.name = home_name - self.model_type = "HmIP-HAP" + self.label = "Home" + self.model_type = "HomematicIP Home" self.init_json_state = None self.test_devices = test_devices self.test_groups = test_groups @@ -196,7 +196,7 @@ class HomeTemplate(Home): and sets required attributes. """ mock_home = Mock( - spec=AsyncHome, wraps=self, label="Access Point", modelType="HmIP-HAP" + spec=AsyncHome, wraps=self, label="Home", modelType="HomematicIP Home" ) mock_home.__dict__.update(self.__dict__) diff --git a/tests/components/homematicip_cloud/test_binary_sensor.py b/tests/components/homematicip_cloud/test_binary_sensor.py index f7bfcbf2f96..420977cd40c 100644 --- a/tests/components/homematicip_cloud/test_binary_sensor.py +++ b/tests/components/homematicip_cloud/test_binary_sensor.py @@ -38,12 +38,10 @@ async def test_manually_configured_platform(hass): assert not hass.data.get(HMIPC_DOMAIN) -async def test_hmip_access_point_cloud_connection_sensor( - hass, default_mock_hap_factory -): +async def test_hmip_home_cloud_connection_sensor(hass, default_mock_hap_factory): """Test HomematicipCloudConnectionSensor.""" - entity_id = "binary_sensor.access_point_cloud_connection" - entity_name = "Access Point Cloud Connection" + entity_id = "binary_sensor.cloud_connection" + entity_name = "Cloud Connection" device_model = None mock_hap = await default_mock_hap_factory.async_get_mock_hap( test_devices=[entity_name] @@ -55,7 +53,7 @@ async def test_hmip_access_point_cloud_connection_sensor( assert ha_state.state == STATE_ON - await async_manipulate_test_data(hass, hmip_device, "connected", False) + await async_manipulate_test_data(hass, mock_hap.home, "connected", False) ha_state = hass.states.get(entity_id) assert ha_state.state == STATE_OFF diff --git a/tests/components/homematicip_cloud/test_device.py b/tests/components/homematicip_cloud/test_device.py index 4fecd3865a4..31e62a1a719 100644 --- a/tests/components/homematicip_cloud/test_device.py +++ b/tests/components/homematicip_cloud/test_device.py @@ -22,7 +22,7 @@ async def test_hmip_load_all_supported_devices(hass, default_mock_hap_factory): test_devices=None, test_groups=None ) - assert len(mock_hap.hmip_device_by_entity_id) == 231 + assert len(mock_hap.hmip_device_by_entity_id) == 233 async def test_hmip_remove_device(hass, default_mock_hap_factory): @@ -268,4 +268,4 @@ async def test_hmip_multi_area_device(hass, default_mock_hap_factory): # get the hap hap_device = device_registry.async_get(device.via_device_id) - assert hap_device.name == "Access Point" + assert hap_device.name == "Home" diff --git a/tests/components/homematicip_cloud/test_init.py b/tests/components/homematicip_cloud/test_init.py index 37b293a3452..46059f12d00 100644 --- a/tests/components/homematicip_cloud/test_init.py +++ b/tests/components/homematicip_cloud/test_init.py @@ -145,6 +145,7 @@ async def test_unload_entry(hass): instance.home.id = "1" instance.home.modelType = "mock-type" instance.home.name = "mock-name" + instance.home.label = "mock-label" instance.home.currentAPVersion = "mock-ap-version" instance.async_reset = AsyncMock(return_value=True) @@ -158,7 +159,7 @@ async def test_unload_entry(hass): assert config_entries[0].state == ENTRY_STATE_LOADED await hass.config_entries.async_unload(config_entries[0].entry_id) assert config_entries[0].state == ENTRY_STATE_NOT_LOADED - assert mock_hap.return_value.mock_calls[3][0] == "async_reset" + assert mock_hap.return_value.mock_calls[2][0] == "async_reset" # entry is unloaded assert hass.data[HMIPC_DOMAIN] == {} @@ -187,6 +188,7 @@ async def test_setup_services_and_unload_services(hass): instance.home.id = "1" instance.home.modelType = "mock-type" instance.home.name = "mock-name" + instance.home.label = "mock-label" instance.home.currentAPVersion = "mock-ap-version" instance.async_reset = AsyncMock(return_value=True) @@ -220,6 +222,7 @@ async def test_setup_two_haps_unload_one_by_one(hass): instance.home.id = "1" instance.home.modelType = "mock-type" instance.home.name = "mock-name" + instance.home.label = "mock-label" instance.home.currentAPVersion = "mock-ap-version" instance.async_reset = AsyncMock(return_value=True) diff --git a/tests/components/homematicip_cloud/test_sensor.py b/tests/components/homematicip_cloud/test_sensor.py index 20c5c41a5b5..34c119595b3 100644 --- a/tests/components/homematicip_cloud/test_sensor.py +++ b/tests/components/homematicip_cloud/test_sensor.py @@ -46,11 +46,11 @@ async def test_manually_configured_platform(hass): async def test_hmip_accesspoint_status(hass, default_mock_hap_factory): """Test HomematicipSwitch.""" - entity_id = "sensor.access_point_duty_cycle" - entity_name = "Access Point Duty Cycle" - device_model = None + entity_id = "sensor.home_control_access_point_duty_cycle" + entity_name = "HOME_CONTROL_ACCESS_POINT Duty Cycle" + device_model = "HmIP-HAP" mock_hap = await default_mock_hap_factory.async_get_mock_hap( - test_devices=[entity_name] + test_devices=["HOME_CONTROL_ACCESS_POINT"] ) ha_state, hmip_device = get_and_check_entity_basics( @@ -60,11 +60,6 @@ async def test_hmip_accesspoint_status(hass, default_mock_hap_factory): assert ha_state.state == "8.0" assert ha_state.attributes[ATTR_UNIT_OF_MEASUREMENT] == PERCENTAGE - await async_manipulate_test_data(hass, hmip_device, "dutyCycle", 17.3) - - ha_state = hass.states.get(entity_id) - assert ha_state.state == "17.3" - async def test_hmip_heating_thermostat(hass, default_mock_hap_factory): """Test HomematicipHeatingThermostat.""" diff --git a/tests/fixtures/homematicip_cloud.json b/tests/fixtures/homematicip_cloud.json index 4060ca7a820..9c2a1b1e371 100644 --- a/tests/fixtures/homematicip_cloud.json +++ b/tests/fixtures/homematicip_cloud.json @@ -14,6 +14,248 @@ } }, "devices": { + "3014F711A000000BAD0CAAAA": { + "availableFirmwareVersion": "2.2.18", + "connectionType": "HMIP_LAN", + "firmwareVersion": "2.2.18", + "firmwareVersionInteger": 131602, + "functionalChannels": { + "0": { + "accessPointPriority": 0, + "busConfigMismatch": null, + "carrierSenseLevel": 2.0, + "coProFaulty": false, + "coProRestartNeeded": false, + "coProUpdateFailure": false, + "configPending": false, + "deviceId": "3014F711A000000BAD0CAAAA", + "deviceOverheated": false, + "deviceOverloaded": false, + "devicePowerFailureDetected": false, + "deviceUndervoltage": false, + "dutyCycle": false, + "dutyCycleLevel": 8.0, + "functionalChannelType": "ACCESS_CONTROLLER_CHANNEL", + "groupIndex": 0, + "groups": [], + "index": 0, + "label": "", + "lowBat": null, + "multicastRoutingEnabled": false, + "powerShortCircuit": null, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": null, + "rssiPeerValue": null, + "shortCircuitDataLine": null, + "signalBrightness": 1.0, + "supportedOptionalFeatures": { + "IFeatureBusConfigMismatch": false, + "IFeatureDeviceCoProError": false, + "IFeatureDeviceCoProRestart": false, + "IFeatureDeviceCoProUpdate": false, + "IFeatureDeviceIdentify": false, + "IFeatureDeviceOverheated": false, + "IFeatureDeviceOverloaded": false, + "IFeatureDevicePowerFailure": false, + "IFeatureDeviceTemperatureOutOfRange": false, + "IFeatureDeviceUndervoltage": false, + "IFeatureMulticastRouter": false, + "IFeaturePowerShortCircuit": false, + "IFeatureRssiValue": false, + "IFeatureShortCircuitDataLine": false, + "IOptionalFeatureDutyCycle": true, + "IOptionalFeatureLowBat": false + }, + "temperatureOutOfRange": false, + "unreach": false + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F711A000000BAD0CAAAA", + "label": "AP1", + "lastStatusUpdate": 1604522238580, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 270, + "modelType": "HmIP-HAP", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F711A000000BAD0CAAAA", + "type": "HOME_CONTROL_ACCESS_POINT", + "updateState": "BACKGROUND_UPDATE_NOT_SUPPORTED" + }, + "3014F711A000000BAD0C0DED": { + "availableFirmwareVersion": "2.2.18", + "connectionType": "HMIP_LAN", + "firmwareVersion": "2.2.18", + "firmwareVersionInteger": 131602, + "functionalChannels": { + "0": { + "accessPointPriority": 1, + "busConfigMismatch": null, + "carrierSenseLevel": 2.0, + "coProFaulty": false, + "coProRestartNeeded": false, + "coProUpdateFailure": false, + "configPending": false, + "deviceId": "3014F711A000000BAD0C0DED", + "deviceOverheated": false, + "deviceOverloaded": false, + "devicePowerFailureDetected": false, + "deviceUndervoltage": false, + "dutyCycle": false, + "dutyCycleLevel": 8.0, + "functionalChannelType": "ACCESS_CONTROLLER_CHANNEL", + "groupIndex": 0, + "groups": [], + "index": 0, + "label": "", + "lowBat": null, + "multicastRoutingEnabled": false, + "powerShortCircuit": null, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": null, + "rssiPeerValue": null, + "shortCircuitDataLine": null, + "signalBrightness": 1.0, + "supportedOptionalFeatures": { + "IFeatureBusConfigMismatch": false, + "IFeatureDeviceCoProError": false, + "IFeatureDeviceCoProRestart": false, + "IFeatureDeviceCoProUpdate": false, + "IFeatureDeviceIdentify": false, + "IFeatureDeviceOverheated": false, + "IFeatureDeviceOverloaded": false, + "IFeatureDevicePowerFailure": false, + "IFeatureDeviceTemperatureOutOfRange": false, + "IFeatureDeviceUndervoltage": false, + "IFeatureMulticastRouter": false, + "IFeaturePowerShortCircuit": false, + "IFeatureRssiValue": false, + "IFeatureShortCircuitDataLine": false, + "IOptionalFeatureDutyCycle": true, + "IOptionalFeatureLowBat": false + }, + "temperatureOutOfRange": false, + "unreach": false + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F711A000000BAD0C0DED", + "label": "HOME_CONTROL_ACCESS_POINT", + "lastStatusUpdate": 1604522238580, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 270, + "modelType": "HmIP-HAP", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F711A000000BAD0C0DED", + "type": "HOME_CONTROL_ACCESS_POINT", + "updateState": "BACKGROUND_UPDATE_NOT_SUPPORTED" + }, + "3014F71100BLIND_MODULE00": { + "availableFirmwareVersion": "0.0.0", + "connectionType": "HMIP_RF", + "firmwareVersion": "1.0.4", + "firmwareVersionInteger": 65540, + "functionalChannels": { + "0": { + "busConfigMismatch": null, + "coProFaulty": false, + "coProRestartNeeded": false, + "coProUpdateFailure": false, + "configPending": false, + "deviceId": "3014F71100BLIND_MODULE00", + "deviceOverheated": false, + "deviceOverloaded": false, + "devicePowerFailureDetected": false, + "deviceUndervoltage": false, + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [ + ], + "index": 0, + "label": "", + "lowBat": false, + "multicastRoutingEnabled": false, + "powerShortCircuit": null, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -85, + "rssiPeerValue": -78, + "shortCircuitDataLine": null, + "supportedOptionalFeatures": { + "IFeatureBusConfigMismatch": false, + "IFeatureDeviceCoProError": false, + "IFeatureDeviceCoProRestart": false, + "IFeatureDeviceCoProUpdate": false, + "IFeatureDeviceIdentify": false, + "IFeatureDeviceOverheated": false, + "IFeatureDeviceOverloaded": false, + "IFeatureDevicePowerFailure": false, + "IFeatureDeviceTemperatureOutOfRange": false, + "IFeatureDeviceUndervoltage": false, + "IFeatureMulticastRouter": false, + "IFeaturePowerShortCircuit": false, + "IFeatureRssiValue": true, + "IFeatureShortCircuitDataLine": false, + "IOptionalFeatureDutyCycle": true, + "IOptionalFeatureLowBat": true + }, + "temperatureOutOfRange": false, + "unreach": false + }, + "1": { + "automationDriveSpeed": "SLOW_SPEED", + "deviceId": "3014F71100BLIND_MODULE00", + "favoritePrimaryShadingPosition": 0.5, + "favoriteSecondaryShadingPosition": 0.5, + "functionalChannelType": "SHADING_CHANNEL", + "groupIndex": 1, + "groups": [ + ], + "identifyOemSupported": true, + "index": 1, + "label": "", + "manualDriveSpeed": "NOMINAL_SPEED", + "previousPrimaryShadingLevel": null, + "previousSecondaryShadingLevel": null, + "primaryCloseAdjustable": true, + "primaryOpenAdjustable": true, + "primaryShadingLevel": 0.94956, + "primaryShadingStateType": "POSITION_USED", + "processing": false, + "productId": 10, + "profileMode": "AUTOMATIC", + "secondaryCloseAdjustable": false, + "secondaryOpenAdjustable": false, + "secondaryShadingLevel": null, + "secondaryShadingStateType": "NOT_EXISTENT", + "shadingDriveVersion": null, + "shadingPackagePosition": "TOP", + "shadingPositionAdjustmentActive": null, + "shadingPositionAdjustmentClientId": null, + "userDesiredProfileMode": "AUTOMATIC" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F71100BLIND_MODULE00", + "label": "Sonnenschutz Balkont\u00fcr", + "lastStatusUpdate": 1600002124559, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 7, + "modelId": 1, + "modelType": "HmIP-HDM1", + "oem": "HunterDouglas", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F71100BLIND_MODULE00", + "type": "BLIND_MODULE", + "updateState": "UP_TO_DATE" + }, "3014F7110TILTVIBRATIONSENSOR": { "availableFirmwareVersion": "0.0.0", "connectionType": "HMIP_RF", @@ -7307,6 +7549,11 @@ }, "home": { "accessPointUpdateStates": { + "3014F711A000000BAD0CAAAA": { + "accessPointUpdateState": "UP_TO_DATE", + "successfulUpdateTimestamp": 0, + "updateStateChangedTimestamp": 0 + }, "3014F711A000000BAD0C0DED": { "accessPointUpdateState": "UP_TO_DATE", "successfulUpdateTimestamp": 0, @@ -7449,4 +7696,4 @@ "windSpeed": 8.568 } } -} \ No newline at end of file +} From e7ce8940b20e82ff6cabcaa6707e7c261b4c2e2c Mon Sep 17 00:00:00 2001 From: Chris Talkington Date: Wed, 11 Nov 2020 13:17:46 -0600 Subject: [PATCH 05/73] Use media player image proxy for roku media browser (#43070) --- .../components/media_player/__init__.py | 18 +++++++++--------- homeassistant/components/roku/browse_media.py | 12 +++++++----- homeassistant/components/roku/media_player.py | 18 ++++++++++++++++-- tests/components/roku/test_media_player.py | 8 ++------ 4 files changed, 34 insertions(+), 22 deletions(-) diff --git a/homeassistant/components/media_player/__init__.py b/homeassistant/components/media_player/__init__.py index 4fb0cdae33e..71db60baa2e 100644 --- a/homeassistant/components/media_player/__init__.py +++ b/homeassistant/components/media_player/__init__.py @@ -900,6 +900,9 @@ class MediaPlayerEntity(Entity): except asyncio.TimeoutError: pass + if content is None: + _LOGGER.warning("Error retrieving proxied image from %s", url) + return content, content_type def get_browse_image_url( @@ -910,15 +913,12 @@ class MediaPlayerEntity(Entity): f"/api/media_player_proxy/{self.entity_id}/browse_media" f"/{media_content_type}/{media_content_id}" ) - url = str( - URL(url_path).with_query( - { - "token": self.access_token, - "media_image_id": media_image_id, - } - ) - ) - return url + + url_query = {"token": self.access_token} + if media_image_id: + url_query["media_image_id"] = media_image_id + + return str(URL(url_path).with_query(url_query)) class MediaPlayerImageView(HomeAssistantView): diff --git a/homeassistant/components/roku/browse_media.py b/homeassistant/components/roku/browse_media.py index b5be3e99d9a..8110174450e 100644 --- a/homeassistant/components/roku/browse_media.py +++ b/homeassistant/components/roku/browse_media.py @@ -34,7 +34,7 @@ EXPANDABLE_MEDIA_TYPES = [ ] -def build_item_response(coordinator, payload): +def build_item_response(coordinator, payload, get_thumbnail_url=None): """Create response payload for the provided media query.""" search_id = payload["search_id"] search_type = payload["search_type"] @@ -75,13 +75,13 @@ def build_item_response(coordinator, payload): title=title, can_play=search_type in PLAYABLE_MEDIA_TYPES and search_id, can_expand=True, - children=[item_payload(item, coordinator) for item in media], + children=[item_payload(item, coordinator, get_thumbnail_url) for item in media], children_media_class=children_media_class, thumbnail=thumbnail, ) -def item_payload(item, coordinator): +def item_payload(item, coordinator, get_thumbnail_url=None): """ Create response payload for a single media item. @@ -92,7 +92,8 @@ def item_payload(item, coordinator): if "app_id" in item: media_content_type = MEDIA_TYPE_APP media_content_id = item["app_id"] - thumbnail = coordinator.roku.app_icon_url(item["app_id"]) + if get_thumbnail_url: + thumbnail = get_thumbnail_url(media_content_type, media_content_id) elif "channel_number" in item: media_content_type = MEDIA_TYPE_CHANNEL media_content_id = item["channel_number"] @@ -115,7 +116,7 @@ def item_payload(item, coordinator): ) -def library_payload(coordinator): +def library_payload(coordinator, get_thumbnail_url=None): """ Create response payload to describe contents of a specific library. @@ -147,6 +148,7 @@ def library_payload(coordinator): item_payload( {"title": item["title"], "type": item["type"]}, coordinator, + get_thumbnail_url, ) ) diff --git a/homeassistant/components/roku/media_player.py b/homeassistant/components/roku/media_player.py index 0e035106824..e1662972cf6 100644 --- a/homeassistant/components/roku/media_player.py +++ b/homeassistant/components/roku/media_player.py @@ -238,16 +238,30 @@ class RokuMediaPlayer(RokuEntity, MediaPlayerEntity): """Emulate opening the search screen and entering the search keyword.""" await self.coordinator.roku.search(keyword) + async def async_get_browse_image( + self, media_content_type, media_content_id, media_image_id=None + ): + """Fetch media browser image to serve via proxy.""" + if media_content_type == MEDIA_TYPE_APP and media_content_id: + image_url = self.coordinator.roku.app_icon_url(media_content_id) + return await self._async_fetch_image(image_url) + + return (None, None) + async def async_browse_media(self, media_content_type=None, media_content_id=None): """Implement the websocket media browsing helper.""" + + def _get_thumbnail_url(*args, **kwargs): + return self.get_browse_image_url(*args, **kwargs) + if media_content_type in [None, "library"]: - return library_payload(self.coordinator) + return library_payload(self.coordinator, _get_thumbnail_url) payload = { "search_type": media_content_type, "search_id": media_content_id, } - response = build_item_response(self.coordinator, payload) + response = build_item_response(self.coordinator, payload, _get_thumbnail_url) if response is None: raise BrowseError( diff --git a/tests/components/roku/test_media_player.py b/tests/components/roku/test_media_player.py index b4ce1811c91..23dd9dbc6c8 100644 --- a/tests/components/roku/test_media_player.py +++ b/tests/components/roku/test_media_player.py @@ -539,18 +539,14 @@ async def test_media_browse(hass, aioclient_mock, hass_ws_client): assert msg["result"]["children"][0]["media_content_type"] == MEDIA_TYPE_APP assert msg["result"]["children"][0]["media_content_id"] == "tvinput.hdmi2" assert ( - msg["result"]["children"][0]["thumbnail"] - == "http://192.168.1.161:8060/query/icon/tvinput.hdmi2" + "/browse_media/app/tvinput.hdmi2" in msg["result"]["children"][0]["thumbnail"] ) assert msg["result"]["children"][0]["can_play"] assert msg["result"]["children"][3]["title"] == "Roku Channel Store" assert msg["result"]["children"][3]["media_content_type"] == MEDIA_TYPE_APP assert msg["result"]["children"][3]["media_content_id"] == "11" - assert ( - msg["result"]["children"][3]["thumbnail"] - == "http://192.168.1.161:8060/query/icon/11" - ) + assert "/browse_media/app/11" in msg["result"]["children"][3]["thumbnail"] assert msg["result"]["children"][3]["can_play"] # test channels From 3732b5286dbab36364cff4cdf1429bc5e3cda144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Wed, 11 Nov 2020 20:12:24 +0100 Subject: [PATCH 06/73] Add system health section for the Supervisor (#43074) --- homeassistant/components/hassio/__init__.py | 28 ++++- homeassistant/components/hassio/handler.py | 16 +++ homeassistant/components/hassio/manifest.json | 2 +- homeassistant/components/hassio/strings.json | 18 +++ .../components/hassio/system_health.py | 72 +++++++++++ .../components/hassio/translations/en.json | 19 ++- .../components/homeassistant/strings.json | 20 ++-- .../components/homeassistant/system_health.py | 16 ++- .../homeassistant/translations/en.json | 33 +++-- tests/components/hassio/test_handler.py | 33 +++++ tests/components/hassio/test_init.py | 22 ++-- tests/components/hassio/test_system_health.py | 113 ++++++++++++++++++ tests/components/onboarding/test_views.py | 6 + 13 files changed, 354 insertions(+), 44 deletions(-) create mode 100644 homeassistant/components/hassio/strings.json create mode 100644 homeassistant/components/hassio/system_health.py create mode 100644 tests/components/hassio/test_system_health.py diff --git a/homeassistant/components/hassio/__init__.py b/homeassistant/components/hassio/__init__.py index 1180e0a01d2..6484c85b95e 100644 --- a/homeassistant/components/hassio/__init__.py +++ b/homeassistant/components/hassio/__init__.py @@ -42,9 +42,11 @@ CONFIG_SCHEMA = vol.Schema( ) -DATA_INFO = "hassio_info" -DATA_HOST_INFO = "hassio_host_info" DATA_CORE_INFO = "hassio_core_info" +DATA_HOST_INFO = "hassio_host_info" +DATA_INFO = "hassio_info" +DATA_OS_INFO = "hassio_os_info" +DATA_SUPERVISOR_INFO = "hassio_supervisor_info" HASSIO_UPDATE_INTERVAL = timedelta(minutes=55) SERVICE_ADDON_START = "addon_start" @@ -218,6 +220,26 @@ def get_host_info(hass): return hass.data.get(DATA_HOST_INFO) +@callback +@bind_hass +def get_supervisor_info(hass): + """Return Supervisor information. + + Async friendly. + """ + return hass.data.get(DATA_SUPERVISOR_INFO) + + +@callback +@bind_hass +def get_os_info(hass): + """Return OS information. + + Async friendly. + """ + return hass.data.get(DATA_OS_INFO) + + @callback @bind_hass def get_core_info(hass): @@ -358,6 +380,8 @@ async def async_setup(hass, config): hass.data[DATA_INFO] = await hassio.get_info() hass.data[DATA_HOST_INFO] = await hassio.get_host_info() hass.data[DATA_CORE_INFO] = await hassio.get_core_info() + hass.data[DATA_SUPERVISOR_INFO] = await hassio.get_supervisor_info() + hass.data[DATA_OS_INFO] = await hassio.get_os_info() except HassioAPIError as err: _LOGGER.warning("Can't read last version: %s", err) diff --git a/homeassistant/components/hassio/handler.py b/homeassistant/components/hassio/handler.py index 58dd9db6623..6bc3cb345a5 100644 --- a/homeassistant/components/hassio/handler.py +++ b/homeassistant/components/hassio/handler.py @@ -82,6 +82,14 @@ class HassIO: """ return self.send_command("/host/info", method="get") + @api_data + def get_os_info(self): + """Return data for the OS. + + This method return a coroutine. + """ + return self.send_command("/os/info", method="get") + @api_data def get_core_info(self): """Return data for Home Asssistant Core. @@ -90,6 +98,14 @@ class HassIO: """ return self.send_command("/core/info", method="get") + @api_data + def get_supervisor_info(self): + """Return data for the Supervisor. + + This method returns a coroutine. + """ + return self.send_command("/supervisor/info", method="get") + @api_data def get_addon_info(self, addon): """Return data for a Add-on. diff --git a/homeassistant/components/hassio/manifest.json b/homeassistant/components/hassio/manifest.json index 193c9640cd5..ba969a4af3a 100644 --- a/homeassistant/components/hassio/manifest.json +++ b/homeassistant/components/hassio/manifest.json @@ -1,6 +1,6 @@ { "domain": "hassio", - "name": "Hass.io", + "name": "Home Assistant Supervisor", "documentation": "https://www.home-assistant.io/hassio", "dependencies": ["http"], "after_dependencies": ["panel_custom"], diff --git a/homeassistant/components/hassio/strings.json b/homeassistant/components/hassio/strings.json new file mode 100644 index 00000000000..875a79a60d7 --- /dev/null +++ b/homeassistant/components/hassio/strings.json @@ -0,0 +1,18 @@ +{ + "system_health": { + "info": { + "board": "Board", + "disk_total": "Disk Total", + "disk_used": "Disk Used", + "docker_version": "Docker Version", + "healthy": "Healthy", + "host_os": "Host Operating System", + "installed_addons": "Installed Add-ons", + "supervisor_api": "Supervisor API", + "supervisor_version": "Supervisor Version", + "supported": "Supported", + "update_channel": "Update Channel", + "version_api": "Version API" + } + } +} diff --git a/homeassistant/components/hassio/system_health.py b/homeassistant/components/hassio/system_health.py new file mode 100644 index 00000000000..530703d3e25 --- /dev/null +++ b/homeassistant/components/hassio/system_health.py @@ -0,0 +1,72 @@ +"""Provide info to system health.""" +import os + +from homeassistant.components import system_health +from homeassistant.core import HomeAssistant, callback + +SUPERVISOR_PING = f"http://{os.environ['HASSIO']}/supervisor/ping" +OBSERVER_URL = f"http://{os.environ['HASSIO']}:4357" + + +@callback +def async_register( + hass: HomeAssistant, register: system_health.SystemHealthRegistration +) -> None: + """Register system health callbacks.""" + register.async_register_info(system_health_info, "/hassio") + + +async def system_health_info(hass: HomeAssistant): + """Get info for the info page.""" + info = hass.components.hassio.get_info() + host_info = hass.components.hassio.get_host_info() + supervisor_info = hass.components.hassio.get_supervisor_info() + + if supervisor_info.get("healthy"): + healthy = True + else: + healthy = { + "type": "failed", + "error": "Unhealthy", + "more_info": "/hassio/system", + } + + if supervisor_info.get("supported"): + supported = True + else: + supported = { + "type": "failed", + "error": "Unsupported", + "more_info": "/hassio/system", + } + + information = { + "host_os": host_info.get("operating_system"), + "update_channel": info.get("channel"), + "supervisor_version": info.get("supervisor"), + "docker_version": info.get("docker"), + "disk_total": f"{host_info.get('disk_total')} GB", + "disk_used": f"{host_info.get('disk_used')} GB", + "healthy": healthy, + "supported": supported, + } + + if info.get("hassos") is not None: + os_info = hass.components.hassio.get_os_info() + information["board"] = os_info.get("board") + + information["supervisor_api"] = system_health.async_check_can_reach_url( + hass, SUPERVISOR_PING, OBSERVER_URL + ) + information["version_api"] = system_health.async_check_can_reach_url( + hass, + f"https://version.home-assistant.io/{info.get('channel')}.json", + "/hassio/system", + ) + + information["installed_addons"] = ", ".join( + f"{addon['name']} ({addon['version']})" + for addon in supervisor_info.get("addons", []) + ) + + return information diff --git a/homeassistant/components/hassio/translations/en.json b/homeassistant/components/hassio/translations/en.json index 981cb51c83a..875a79a60d7 100644 --- a/homeassistant/components/hassio/translations/en.json +++ b/homeassistant/components/hassio/translations/en.json @@ -1,3 +1,18 @@ { - "title": "Hass.io" -} \ No newline at end of file + "system_health": { + "info": { + "board": "Board", + "disk_total": "Disk Total", + "disk_used": "Disk Used", + "docker_version": "Docker Version", + "healthy": "Healthy", + "host_os": "Host Operating System", + "installed_addons": "Installed Add-ons", + "supervisor_api": "Supervisor API", + "supervisor_version": "Supervisor Version", + "supported": "Supported", + "update_channel": "Update Channel", + "version_api": "Version API" + } + } +} diff --git a/homeassistant/components/homeassistant/strings.json b/homeassistant/components/homeassistant/strings.json index e349cc1cb83..1aa414c4984 100644 --- a/homeassistant/components/homeassistant/strings.json +++ b/homeassistant/components/homeassistant/strings.json @@ -1,20 +1,16 @@ { "system_health": { "info": { - "installation_type": "Installation Type", - "version": "Version", - "dev": "Development", - "virtualenv": "Virtual Environment", - "python_version": "Python Version", - "docker": "Docker", "arch": "CPU Architecture", - "timezone": "Timezone", - "os_name": "Operating System Name", + "dev": "Development", + "docker": "Docker", + "installation_type": "Installation Type", + "os_name": "Operating System Family", "os_version": "Operating System Version", - "supervisor": "Supervisor", - "host_os": "Home Assistant OS", - "chassis": "Chassis", - "docker_version": "Docker" + "python_version": "Python Version", + "timezone": "Timezone", + "version": "Version", + "virtualenv": "Virtual Environment" } } } diff --git a/homeassistant/components/homeassistant/system_health.py b/homeassistant/components/homeassistant/system_health.py index af1be3bd0a5..b0245d9beec 100644 --- a/homeassistant/components/homeassistant/system_health.py +++ b/homeassistant/components/homeassistant/system_health.py @@ -15,5 +15,17 @@ def async_register( async def system_health_info(hass): """Get info for the info page.""" info = await system_info.async_get_system_info(hass) - info.pop("hassio") - return info + + return { + "version": info.get("version"), + "installation_type": info.get("installation_type"), + "dev": info.get("dev"), + "hassio": info.get("hassio"), + "docker": info.get("docker"), + "virtualenv": info.get("virtualenv"), + "python_version": info.get("python_version"), + "os_name": info.get("os_name"), + "os_version": info.get("os_version"), + "arch": info.get("arch"), + "timezone": info.get("timezone"), + } diff --git a/homeassistant/components/homeassistant/translations/en.json b/homeassistant/components/homeassistant/translations/en.json index 9885785fa4d..8e810ef2143 100644 --- a/homeassistant/components/homeassistant/translations/en.json +++ b/homeassistant/components/homeassistant/translations/en.json @@ -1,20 +1,17 @@ { - "system_health": { - "info": { - "arch": "CPU Architecture", - "chassis": "Chassis", - "dev": "Development", - "docker": "Docker", - "docker_version": "Docker", - "host_os": "Home Assistant OS", - "installation_type": "Installation Type", - "os_name": "Operating System Name", - "os_version": "Operating System Version", - "python_version": "Python Version", - "supervisor": "Supervisor", - "timezone": "Timezone", - "version": "Version", - "virtualenv": "Virtual Environment" - } + "system_health": { + "info": { + "arch": "CPU Architecture", + "dev": "Development", + "docker": "Docker", + "installation_type": "Installation Type", + "os_name": "Operating System Family", + "os_version": "Operating System Version", + "python_version": "Python Version", + "timezone": "Timezone", + "version": "Version", + "virtualenv": "Virtual Environment" } -} \ No newline at end of file + }, + "title": "Home Assistant" +} diff --git a/tests/components/hassio/test_handler.py b/tests/components/hassio/test_handler.py index 311fc6c7e8c..33fb00b4485 100644 --- a/tests/components/hassio/test_handler.py +++ b/tests/components/hassio/test_handler.py @@ -80,6 +80,39 @@ async def test_api_host_info(hassio_handler, aioclient_mock): assert data["operating_system"] == "Debian GNU/Linux 10 (buster)" +async def test_api_supervisor_info(hassio_handler, aioclient_mock): + """Test setup with API Supervisor info.""" + aioclient_mock.get( + "http://127.0.0.1/supervisor/info", + json={ + "result": "ok", + "data": {"supported": True, "version": "2020.11.1", "channel": "stable"}, + }, + ) + + data = await hassio_handler.get_supervisor_info() + assert aioclient_mock.call_count == 1 + assert data["supported"] + assert data["version"] == "2020.11.1" + assert data["channel"] == "stable" + + +async def test_api_os_info(hassio_handler, aioclient_mock): + """Test setup with API OS info.""" + aioclient_mock.get( + "http://127.0.0.1/os/info", + json={ + "result": "ok", + "data": {"board": "odroid-n2", "version": "2020.11.1"}, + }, + ) + + data = await hassio_handler.get_os_info() + assert aioclient_mock.call_count == 1 + assert data["board"] == "odroid-n2" + assert data["version"] == "2020.11.1" + + async def test_api_host_info_error(hassio_handler, aioclient_mock): """Test setup with API Home Assistant info error.""" aioclient_mock.get( diff --git a/tests/components/hassio/test_init.py b/tests/components/hassio/test_init.py index 62b4a4adbd2..214551bc3b7 100644 --- a/tests/components/hassio/test_init.py +++ b/tests/components/hassio/test_init.py @@ -44,6 +44,14 @@ def mock_all(aioclient_mock): "http://127.0.0.1/core/info", json={"result": "ok", "data": {"version_latest": "1.0.0"}}, ) + aioclient_mock.get( + "http://127.0.0.1/os/info", + json={"result": "ok", "data": {"version_latest": "1.0.0"}}, + ) + aioclient_mock.get( + "http://127.0.0.1/supervisor/info", + json={"result": "ok", "data": {"version_latest": "1.0.0"}}, + ) aioclient_mock.get( "http://127.0.0.1/ingress/panels", json={"result": "ok", "data": {"panels": {}}} ) @@ -55,7 +63,7 @@ async def test_setup_api_ping(hass, aioclient_mock): result = await async_setup_component(hass, "hassio", {}) assert result - assert aioclient_mock.call_count == 7 + assert aioclient_mock.call_count == 9 assert hass.components.hassio.get_core_info()["version_latest"] == "1.0.0" assert hass.components.hassio.is_hassio() @@ -94,7 +102,7 @@ async def test_setup_api_push_api_data(hass, aioclient_mock): ) assert result - assert aioclient_mock.call_count == 7 + assert aioclient_mock.call_count == 9 assert not aioclient_mock.mock_calls[1][2]["ssl"] assert aioclient_mock.mock_calls[1][2]["port"] == 9999 assert aioclient_mock.mock_calls[1][2]["watchdog"] @@ -110,7 +118,7 @@ async def test_setup_api_push_api_data_server_host(hass, aioclient_mock): ) assert result - assert aioclient_mock.call_count == 7 + assert aioclient_mock.call_count == 9 assert not aioclient_mock.mock_calls[1][2]["ssl"] assert aioclient_mock.mock_calls[1][2]["port"] == 9999 assert not aioclient_mock.mock_calls[1][2]["watchdog"] @@ -122,7 +130,7 @@ async def test_setup_api_push_api_data_default(hass, aioclient_mock, hass_storag result = await async_setup_component(hass, "hassio", {"http": {}, "hassio": {}}) assert result - assert aioclient_mock.call_count == 7 + assert aioclient_mock.call_count == 9 assert not aioclient_mock.mock_calls[1][2]["ssl"] assert aioclient_mock.mock_calls[1][2]["port"] == 8123 refresh_token = aioclient_mock.mock_calls[1][2]["refresh_token"] @@ -169,7 +177,7 @@ async def test_setup_api_existing_hassio_user(hass, aioclient_mock, hass_storage result = await async_setup_component(hass, "hassio", {"http": {}, "hassio": {}}) assert result - assert aioclient_mock.call_count == 7 + assert aioclient_mock.call_count == 9 assert not aioclient_mock.mock_calls[1][2]["ssl"] assert aioclient_mock.mock_calls[1][2]["port"] == 8123 assert aioclient_mock.mock_calls[1][2]["refresh_token"] == token.token @@ -183,7 +191,7 @@ async def test_setup_core_push_timezone(hass, aioclient_mock): result = await async_setup_component(hass, "hassio", {"hassio": {}}) assert result - assert aioclient_mock.call_count == 7 + assert aioclient_mock.call_count == 9 assert aioclient_mock.mock_calls[2][2]["timezone"] == "testzone" with patch("homeassistant.util.dt.set_default_time_zone"): @@ -200,7 +208,7 @@ async def test_setup_hassio_no_additional_data(hass, aioclient_mock): result = await async_setup_component(hass, "hassio", {"hassio": {}}) assert result - assert aioclient_mock.call_count == 7 + assert aioclient_mock.call_count == 9 assert aioclient_mock.mock_calls[-1][3]["X-Hassio-Key"] == "123456" diff --git a/tests/components/hassio/test_system_health.py b/tests/components/hassio/test_system_health.py new file mode 100644 index 00000000000..cd6cb2d939f --- /dev/null +++ b/tests/components/hassio/test_system_health.py @@ -0,0 +1,113 @@ +"""Test hassio system health.""" +import asyncio +import os + +from aiohttp import ClientError + +from homeassistant.setup import async_setup_component + +from .test_init import MOCK_ENVIRON + +from tests.async_mock import patch +from tests.common import get_system_health_info + + +async def test_hassio_system_health(hass, aioclient_mock): + """Test hassio system health.""" + aioclient_mock.get("http://127.0.0.1/info", json={"result": "ok", "data": {}}) + aioclient_mock.get("http://127.0.0.1/host/info", json={"result": "ok", "data": {}}) + aioclient_mock.get("http://127.0.0.1/os/info", json={"result": "ok", "data": {}}) + aioclient_mock.get("http://127.0.0.1/supervisor/ping", text="") + aioclient_mock.get("https://version.home-assistant.io/stable.json", text="") + aioclient_mock.get( + "http://127.0.0.1/supervisor/info", json={"result": "ok", "data": {}} + ) + + hass.config.components.add("hassio") + with patch.dict(os.environ, MOCK_ENVIRON): + assert await async_setup_component(hass, "system_health", {}) + + hass.data["hassio_info"] = { + "channel": "stable", + "supervisor": "2020.11.1", + "docker": "19.0.3", + "hassos": True, + } + hass.data["hassio_host_info"] = { + "operating_system": "Home Assistant OS 5.9", + "disk_total": "32.0", + "disk_used": "30.0", + } + hass.data["hassio_os_info"] = {"board": "odroid-n2"} + hass.data["hassio_supervisor_info"] = { + "healthy": True, + "supported": True, + "addons": [{"name": "Awesome Addon", "version": "1.0.0"}], + } + + info = await get_system_health_info(hass, "hassio") + + for key, val in info.items(): + if asyncio.iscoroutine(val): + info[key] = await val + + assert info == { + "board": "odroid-n2", + "disk_total": "32.0 GB", + "disk_used": "30.0 GB", + "docker_version": "19.0.3", + "healthy": True, + "host_os": "Home Assistant OS 5.9", + "installed_addons": "Awesome Addon (1.0.0)", + "supervisor_api": "ok", + "supervisor_version": "2020.11.1", + "supported": True, + "update_channel": "stable", + "version_api": "ok", + } + + +async def test_hassio_system_health_with_issues(hass, aioclient_mock): + """Test hassio system health.""" + aioclient_mock.get("http://127.0.0.1/info", json={"result": "ok", "data": {}}) + aioclient_mock.get("http://127.0.0.1/host/info", json={"result": "ok", "data": {}}) + aioclient_mock.get("http://127.0.0.1/os/info", json={"result": "ok", "data": {}}) + aioclient_mock.get("http://127.0.0.1/supervisor/ping", text="") + aioclient_mock.get("https://version.home-assistant.io/stable.json", exc=ClientError) + aioclient_mock.get( + "http://127.0.0.1/supervisor/info", json={"result": "ok", "data": {}} + ) + + hass.config.components.add("hassio") + with patch.dict(os.environ, MOCK_ENVIRON): + assert await async_setup_component(hass, "system_health", {}) + + hass.data["hassio_info"] = {"channel": "stable"} + hass.data["hassio_host_info"] = {} + hass.data["hassio_os_info"] = {} + hass.data["hassio_supervisor_info"] = { + "healthy": False, + "supported": False, + } + + info = await get_system_health_info(hass, "hassio") + + for key, val in info.items(): + if asyncio.iscoroutine(val): + info[key] = await val + + assert info["healthy"] == { + "error": "Unhealthy", + "more_info": "/hassio/system", + "type": "failed", + } + assert info["supported"] == { + "error": "Unsupported", + "more_info": "/hassio/system", + "type": "failed", + } + assert info["version_api"] == { + "error": "unreachable", + "more_info": "/hassio/system", + "type": "failed", + } diff --git a/tests/components/onboarding/test_views.py b/tests/components/onboarding/test_views.py index a4826c00328..73845aba7b2 100644 --- a/tests/components/onboarding/test_views.py +++ b/tests/components/onboarding/test_views.py @@ -72,6 +72,12 @@ async def mock_supervisor_fixture(hass, aioclient_mock): ), patch( "homeassistant.components.hassio.HassIO.get_host_info", return_value={}, + ), patch( + "homeassistant.components.hassio.HassIO.get_supervisor_info", + return_value={}, + ), patch( + "homeassistant.components.hassio.HassIO.get_os_info", + return_value={}, ), patch( "homeassistant.components.hassio.HassIO.get_ingress_panels", return_value={"panels": {}}, From 6cfbf294d1c4c340bf5bbe8a6cee3aa613bac377 Mon Sep 17 00:00:00 2001 From: Hmmbob <33529490+hmmbob@users.noreply.github.com> Date: Wed, 11 Nov 2020 19:47:03 +0100 Subject: [PATCH 07/73] Bump pycsspeechtts to 1.0.4 (#43105) --- homeassistant/components/microsoft/manifest.json | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/microsoft/manifest.json b/homeassistant/components/microsoft/manifest.json index 0e371199a18..5b936bc7ded 100644 --- a/homeassistant/components/microsoft/manifest.json +++ b/homeassistant/components/microsoft/manifest.json @@ -2,6 +2,6 @@ "domain": "microsoft", "name": "Microsoft Text-to-Speech (TTS)", "documentation": "https://www.home-assistant.io/integrations/microsoft", - "requirements": ["pycsspeechtts==1.0.3"], + "requirements": ["pycsspeechtts==1.0.4"], "codeowners": [] } diff --git a/requirements_all.txt b/requirements_all.txt index 2e112e72569..84f97fbd592 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1322,7 +1322,7 @@ pycoolmasternet-async==0.1.2 pycountry==19.8.18 # homeassistant.components.microsoft -pycsspeechtts==1.0.3 +pycsspeechtts==1.0.4 # homeassistant.components.cups # pycups==1.9.73 From 86a26d1a7ce815b584bc98d41f10ec22bc7e4b3c Mon Sep 17 00:00:00 2001 From: Aaron Bach Date: Thu, 12 Nov 2020 10:47:47 -0700 Subject: [PATCH 08/73] Fix incorrect Notion battery state calculation (#43108) * Fix incorrect Notion battery state calculation * Both cases --- homeassistant/components/notion/binary_sensor.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/notion/binary_sensor.py b/homeassistant/components/notion/binary_sensor.py index e6f4307a53c..b8fd96fabc5 100644 --- a/homeassistant/components/notion/binary_sensor.py +++ b/homeassistant/components/notion/binary_sensor.py @@ -79,14 +79,10 @@ class NotionBinarySensor(NotionEntity, BinarySensorEntity): """Fetch new state data for the sensor.""" task = self.coordinator.data["tasks"][self._task_id] - if task["task_type"] == SENSOR_BATTERY: - self._state = self.coordinator.data["tasks"][self._task_id]["status"][ - "data" - ]["to_state"] - else: - self._state = self.coordinator.data["tasks"][self._task_id]["status"][ - "value" - ] + if "value" in task["status"]: + self._state = task["status"]["value"] + elif task["task_type"] == SENSOR_BATTERY: + self._state = task["status"]["data"]["to_state"] @property def is_on(self) -> bool: @@ -94,7 +90,7 @@ class NotionBinarySensor(NotionEntity, BinarySensorEntity): task = self.coordinator.data["tasks"][self._task_id] if task["task_type"] == SENSOR_BATTERY: - return self._state != "critical" + return self._state == "critical" if task["task_type"] in ( SENSOR_DOOR, SENSOR_GARAGE_DOOR, From f7544b94277579083a6193f565eabfb7b20ef50b Mon Sep 17 00:00:00 2001 From: Shay Levy Date: Thu, 12 Nov 2020 11:12:56 +0200 Subject: [PATCH 09/73] Make Appliance Type Case-insensitive (#43114) "appliance_type" is a free text parameter in the device settings, this fix will make the comparison case-insensitive --- homeassistant/components/shelly/light.py | 20 +++++++++--------- homeassistant/components/shelly/switch.py | 25 +++++++++++++---------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/homeassistant/components/shelly/light.py b/homeassistant/components/shelly/light.py index 7c4af9cf1ae..922d874a4cc 100644 --- a/homeassistant/components/shelly/light.py +++ b/homeassistant/components/shelly/light.py @@ -30,18 +30,18 @@ async def async_setup_entry(hass, config_entry, async_add_entities): for block in wrapper.device.blocks: if block.type == "light": blocks.append(block) - elif ( - block.type == "relay" - and wrapper.device.settings["relays"][int(block.channel)].get( + elif block.type == "relay": + appliance_type = wrapper.device.settings["relays"][int(block.channel)].get( "appliance_type" ) - == "light" - ): - blocks.append(block) - unique_id = f'{wrapper.device.shelly["mac"]}-{block.type}_{block.channel}' - await async_remove_entity_by_domain( - hass, "switch", unique_id, config_entry.entry_id - ) + if appliance_type and appliance_type.lower() == "light": + blocks.append(block) + unique_id = ( + f'{wrapper.device.shelly["mac"]}-{block.type}_{block.channel}' + ) + await async_remove_entity_by_domain( + hass, "switch", unique_id, config_entry.entry_id + ) if not blocks: return diff --git a/homeassistant/components/shelly/switch.py b/homeassistant/components/shelly/switch.py index 48cb6d728e9..1f14053929d 100644 --- a/homeassistant/components/shelly/switch.py +++ b/homeassistant/components/shelly/switch.py @@ -23,18 +23,21 @@ async def async_setup_entry(hass, config_entry, async_add_entities): relay_blocks = [] for block in wrapper.device.blocks: - if block.type == "relay" and ( - wrapper.device.settings["relays"][int(block.channel)].get("appliance_type") - != "light" - ): - relay_blocks.append(block) - unique_id = f'{wrapper.device.shelly["mac"]}-{block.type}_{block.channel}' - await async_remove_entity_by_domain( - hass, - "light", - unique_id, - config_entry.entry_id, + if block.type == "relay": + appliance_type = wrapper.device.settings["relays"][int(block.channel)].get( + "appliance_type" ) + if not appliance_type or appliance_type.lower() != "light": + relay_blocks.append(block) + unique_id = ( + f'{wrapper.device.shelly["mac"]}-{block.type}_{block.channel}' + ) + await async_remove_entity_by_domain( + hass, + "light", + unique_id, + config_entry.entry_id, + ) if not relay_blocks: return From 3caa94e81ebadeec505657a6825a4e223b78f246 Mon Sep 17 00:00:00 2001 From: Aaron Bach Date: Fri, 13 Nov 2020 01:38:58 -0700 Subject: [PATCH 10/73] Streamline SimpliSafe errors (#43117) --- .../components/simplisafe/__init__.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/homeassistant/components/simplisafe/__init__.py b/homeassistant/components/simplisafe/__init__.py index e06e0b113ab..2430aad43cf 100644 --- a/homeassistant/components/simplisafe/__init__.py +++ b/homeassistant/components/simplisafe/__init__.py @@ -534,8 +534,7 @@ class SimpliSafe: ) ) - LOGGER.error("Update failed with stored refresh token") - raise UpdateFailed from result + raise UpdateFailed("Update failed with stored refresh token") LOGGER.warning("SimpliSafe cloud error; trying stored refresh token") self._emergency_refresh_token_used = True @@ -546,23 +545,18 @@ class SimpliSafe: ) return except SimplipyError as err: - LOGGER.error("Error while using stored refresh token: %s", err) - raise UpdateFailed from err + raise UpdateFailed( # pylint: disable=raise-missing-from + f"Error while using stored refresh token: {err}" + ) if isinstance(result, EndpointUnavailable): - # In case the user attempt an action not allowed in their current plan, + # In case the user attempts an action not allowed in their current plan, # we merely log that message at INFO level (so the user is aware, # but not spammed with ERROR messages that they cannot change): LOGGER.info(result) - raise UpdateFailed from result if isinstance(result, SimplipyError): - LOGGER.error("SimpliSafe error while updating: %s", result) - raise UpdateFailed from result - - if isinstance(result, Exception): - LOGGER.error("Unknown error while updating: %s", result) - raise UpdateFailed from result + raise UpdateFailed(f"SimpliSafe error while updating: {result}") if self._api.refresh_token != self.config_entry.data[CONF_TOKEN]: _async_save_refresh_token( From b0ff1e3885f0cd2517c9d83891ccf1fd8aac303c Mon Sep 17 00:00:00 2001 From: Aaron Bach Date: Thu, 12 Nov 2020 13:45:20 -0700 Subject: [PATCH 11/73] Fix bug preventing Notion entities from updating their bridge (#43122) --- homeassistant/components/notion/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/notion/__init__.py b/homeassistant/components/notion/__init__.py index c17b68a55b1..296eb34934b 100644 --- a/homeassistant/components/notion/__init__.py +++ b/homeassistant/components/notion/__init__.py @@ -249,6 +249,7 @@ class NotionEntity(CoordinatorEntity): @callback def _handle_coordinator_update(self): """Respond to a DataUpdateCoordinator update.""" + self.hass.async_create_task(self._async_update_bridge_id()) self._async_update_from_latest_data() self.async_write_ha_state() From 9fbf39b0ff99cce3781188db7713584d04555bda Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Thu, 12 Nov 2020 11:50:24 +0100 Subject: [PATCH 12/73] Added missing system health translation for "Views" (#43126) --- homeassistant/components/lovelace/strings.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/lovelace/strings.json b/homeassistant/components/lovelace/strings.json index 6d79805105d..87f8407d93c 100644 --- a/homeassistant/components/lovelace/strings.json +++ b/homeassistant/components/lovelace/strings.json @@ -3,7 +3,8 @@ "info": { "dashboards": "Dashboards", "mode": "Mode", - "resources": "Resources" + "resources": "Resources", + "views": "Views" } } } From c5f8b4106e9730a15153c99262d43253623caf3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Fri, 13 Nov 2020 09:39:36 +0100 Subject: [PATCH 13/73] Add missing 'hassio' translation string (#43127) * Add missing 'hassio' translation string * Fix typo... --- homeassistant/components/homeassistant/strings.json | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/homeassistant/strings.json b/homeassistant/components/homeassistant/strings.json index 1aa414c4984..7da4a5a9d8a 100644 --- a/homeassistant/components/homeassistant/strings.json +++ b/homeassistant/components/homeassistant/strings.json @@ -4,6 +4,7 @@ "arch": "CPU Architecture", "dev": "Development", "docker": "Docker", + "hassio": "Supervisor", "installation_type": "Installation Type", "os_name": "Operating System Family", "os_version": "Operating System Version", From b90cf94df3be5416f30f488fbe43b67cd833c160 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Thu, 12 Nov 2020 18:29:06 +0100 Subject: [PATCH 14/73] Bump hatasmota to 0.0.30 (#43140) --- homeassistant/components/tasmota/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/tasmota/manifest.json b/homeassistant/components/tasmota/manifest.json index dbe27e1a003..7892b0fc231 100644 --- a/homeassistant/components/tasmota/manifest.json +++ b/homeassistant/components/tasmota/manifest.json @@ -3,7 +3,7 @@ "name": "Tasmota (beta)", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/tasmota", - "requirements": ["hatasmota==0.0.29"], + "requirements": ["hatasmota==0.0.30"], "dependencies": ["mqtt"], "mqtt": ["tasmota/discovery/#"], "codeowners": ["@emontnemery"] diff --git a/requirements_all.txt b/requirements_all.txt index 84f97fbd592..6e0c20310c9 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -741,7 +741,7 @@ hass-nabucasa==0.37.1 hass_splunk==0.1.1 # homeassistant.components.tasmota -hatasmota==0.0.29 +hatasmota==0.0.30 # homeassistant.components.jewish_calendar hdate==0.9.12 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 59bc7a86047..0aff033db8d 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -376,7 +376,7 @@ hangups==0.4.11 hass-nabucasa==0.37.1 # homeassistant.components.tasmota -hatasmota==0.0.29 +hatasmota==0.0.30 # homeassistant.components.jewish_calendar hdate==0.9.12 From 91f265dd93490e0b3a7a691b3e57a0851e5d7c10 Mon Sep 17 00:00:00 2001 From: Anders Melchiorsen Date: Fri, 13 Nov 2020 09:40:00 +0100 Subject: [PATCH 15/73] Fix playing of Spotify URIs on Sonos (#43154) --- homeassistant/components/sonos/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/sonos/manifest.json b/homeassistant/components/sonos/manifest.json index 659d9bd1b1d..49826ebc410 100644 --- a/homeassistant/components/sonos/manifest.json +++ b/homeassistant/components/sonos/manifest.json @@ -3,7 +3,7 @@ "name": "Sonos", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/sonos", - "requirements": ["pysonos==0.0.35"], + "requirements": ["pysonos==0.0.36"], "ssdp": [ { "st": "urn:schemas-upnp-org:device:ZonePlayer:1" diff --git a/requirements_all.txt b/requirements_all.txt index 6e0c20310c9..4617e66fd97 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1695,7 +1695,7 @@ pysnmp==4.4.12 pysoma==0.0.10 # homeassistant.components.sonos -pysonos==0.0.35 +pysonos==0.0.36 # homeassistant.components.spc pyspcwebgw==0.4.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 0aff033db8d..c6c76947778 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -842,7 +842,7 @@ pysmartthings==0.7.4 pysoma==0.0.10 # homeassistant.components.sonos -pysonos==0.0.35 +pysonos==0.0.36 # homeassistant.components.spc pyspcwebgw==0.4.0 From c37c0da19136b4a355a49b3aa0c47ffb12006710 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 12 Nov 2020 22:40:25 -1000 Subject: [PATCH 16/73] Guard against empty ssdp locations (#43156) --- homeassistant/components/ssdp/__init__.py | 5 ++++- tests/components/ssdp/test_init.py | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/ssdp/__init__.py b/homeassistant/components/ssdp/__init__.py index b3d8a7f2898..e962c141bef 100644 --- a/homeassistant/components/ssdp/__init__.py +++ b/homeassistant/components/ssdp/__init__.py @@ -92,7 +92,10 @@ class Scanner: entries_to_process.append(entry) - if entry.location not in self._description_cache: + if ( + entry.location is not None + and entry.location not in self._description_cache + ): unseen_locations.add(entry.location) if not entries_to_process: diff --git a/tests/components/ssdp/test_init.py b/tests/components/ssdp/test_init.py index b6c8266b5da..008995cd78d 100644 --- a/tests/components/ssdp/test_init.py +++ b/tests/components/ssdp/test_init.py @@ -10,7 +10,7 @@ from homeassistant.components import ssdp from tests.common import mock_coro -async def test_scan_match_st(hass): +async def test_scan_match_st(hass, caplog): """Test matching based on ST.""" scanner = ssdp.Scanner(hass, {"mock-domain": [{"st": "mock-st"}]}) @@ -38,6 +38,7 @@ async def test_scan_match_st(hass): ssdp.ATTR_SSDP_SERVER: "mock-server", ssdp.ATTR_SSDP_EXT: "", } + assert "Failed to fetch ssdp data" not in caplog.text @pytest.mark.parametrize( From b93648f85676c137bb0680eb4304854fe834cf50 Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Thu, 12 Nov 2020 00:10:58 +0000 Subject: [PATCH 17/73] [ci skip] Translation update --- .../components/acmeda/translations/cs.json | 7 ++++ .../components/airvisual/translations/cs.json | 3 ++ .../components/august/translations/cs.json | 2 ++ .../components/aurora/translations/ca.json | 26 ++++++++++++++ .../components/aurora/translations/cs.json | 26 ++++++++++++++ .../components/awair/translations/cs.json | 3 +- .../components/axis/translations/cs.json | 10 ++++++ .../binary_sensor/translations/lb.json | 16 +++++++++ .../components/canary/translations/cs.json | 1 + .../cert_expiry/translations/cs.json | 3 +- .../components/cloud/translations/ca.json | 16 +++++++++ .../components/cloud/translations/lb.json | 16 +++++++++ .../components/cloud/translations/no.json | 4 +-- .../components/control4/translations/cs.json | 10 ++++++ .../components/deconz/translations/cs.json | 1 + .../components/demo/translations/cs.json | 1 + .../components/denonavr/translations/cs.json | 12 ++++++- .../components/doorbird/translations/cs.json | 3 +- .../components/dsmr/translations/ca.json | 10 ++++++ .../components/dunehd/translations/cs.json | 1 + .../flick_electric/translations/cs.json | 1 + .../forked_daapd/translations/cs.json | 20 +++++++++-- .../components/goalzero/translations/cs.json | 1 + .../components/hassio/translations/ca.json | 16 +++++++++ .../components/hassio/translations/cs.json | 16 +++++++++ .../components/hassio/translations/en.json | 35 ++++++++++--------- .../homeassistant/translations/ca.json | 20 +++++++++++ .../homeassistant/translations/cs.json | 2 +- .../homeassistant/translations/en.json | 33 +++++++++-------- .../homekit_controller/translations/cs.json | 1 + .../huawei_lte/translations/cs.json | 1 + .../components/insteon/translations/cs.json | 13 +++++-- .../components/iqvia/translations/cs.json | 1 + .../components/isy994/translations/cs.json | 3 ++ .../components/kodi/translations/cs.json | 3 +- .../components/konnected/translations/cs.json | 3 +- .../components/lovelace/translations/ca.json | 9 +++++ .../components/netatmo/translations/cs.json | 8 +++-- .../components/plex/translations/cs.json | 3 ++ .../components/plugwise/translations/cs.json | 2 ++ .../components/rfxtrx/translations/cs.json | 8 ++++- .../components/roon/translations/cs.json | 1 + .../simplisafe/translations/cs.json | 2 ++ .../components/smappee/translations/cs.json | 2 ++ .../components/smarthab/translations/cs.json | 3 +- .../smartthings/translations/cs.json | 2 ++ .../components/soma/translations/cs.json | 3 +- .../components/syncthru/translations/cs.json | 3 ++ .../components/toon/translations/cs.json | 1 + .../transmission/translations/cs.json | 1 + .../components/vera/translations/cs.json | 1 + .../components/vilfo/translations/cs.json | 1 + .../components/vizio/translations/cs.json | 3 +- .../components/wolflink/translations/cs.json | 3 +- .../wolflink/translations/sensor.cs.json | 14 ++++++++ .../xiaomi_aqara/translations/cs.json | 5 ++- .../components/zha/translations/cs.json | 1 + 57 files changed, 363 insertions(+), 53 deletions(-) create mode 100644 homeassistant/components/aurora/translations/ca.json create mode 100644 homeassistant/components/aurora/translations/cs.json create mode 100644 homeassistant/components/cloud/translations/ca.json create mode 100644 homeassistant/components/cloud/translations/lb.json create mode 100644 homeassistant/components/homeassistant/translations/ca.json create mode 100644 homeassistant/components/lovelace/translations/ca.json diff --git a/homeassistant/components/acmeda/translations/cs.json b/homeassistant/components/acmeda/translations/cs.json index 3f0012e00d2..3f392ed0347 100644 --- a/homeassistant/components/acmeda/translations/cs.json +++ b/homeassistant/components/acmeda/translations/cs.json @@ -2,6 +2,13 @@ "config": { "abort": { "no_devices_found": "V s\u00edti nebyla nalezena \u017e\u00e1dn\u00e1 za\u0159\u00edzen\u00ed" + }, + "step": { + "user": { + "data": { + "id": "ID hostitele" + } + } } } } \ No newline at end of file diff --git a/homeassistant/components/airvisual/translations/cs.json b/homeassistant/components/airvisual/translations/cs.json index 72e456806e0..5c26dcf98ef 100644 --- a/homeassistant/components/airvisual/translations/cs.json +++ b/homeassistant/components/airvisual/translations/cs.json @@ -44,6 +44,9 @@ "options": { "step": { "init": { + "data": { + "show_on_map": "Uk\u00e1zat monitorovanou oblast na map\u011b" + }, "title": "Nastavte AirVisual" } } diff --git a/homeassistant/components/august/translations/cs.json b/homeassistant/components/august/translations/cs.json index f1db40b0beb..4100014abb6 100644 --- a/homeassistant/components/august/translations/cs.json +++ b/homeassistant/components/august/translations/cs.json @@ -17,12 +17,14 @@ "timeout": "\u010casov\u00fd limit (v sekund\u00e1ch)", "username": "U\u017eivatelsk\u00e9 jm\u00e9no" }, + "description": "Pokud je metoda p\u0159ihl\u00e1\u0161en\u00ed \"e-mail\", je e-mailovou adresou u\u017eivatelsk\u00e9 jm\u00e9no. Pokud je p\u0159ihla\u0161ovac\u00ed metoda \"telefon\", u\u017eivatelsk\u00e9 jm\u00e9no je telefonn\u00ed \u010d\u00edslo ve form\u00e1tu \"+NNNNNNNNN\".", "title": "Nastavte \u00fa\u010det August" }, "validation": { "data": { "code": "Ov\u011b\u0159ovac\u00ed k\u00f3d" }, + "description": "Zkontrolujte pros\u00edm {login_method} ({username}) a n\u00ed\u017ee zadejte ov\u011b\u0159ovac\u00ed k\u00f3d", "title": "Dvoufaktorov\u00e9 ov\u011b\u0159ov\u00e1n\u00ed" } } diff --git a/homeassistant/components/aurora/translations/ca.json b/homeassistant/components/aurora/translations/ca.json new file mode 100644 index 00000000000..99db9855e74 --- /dev/null +++ b/homeassistant/components/aurora/translations/ca.json @@ -0,0 +1,26 @@ +{ + "config": { + "error": { + "cannot_connect": "Ha fallat la connexi\u00f3" + }, + "step": { + "user": { + "data": { + "latitude": "Latitud", + "longitude": "Longitud", + "name": "Nom" + } + } + } + }, + "options": { + "step": { + "init": { + "data": { + "threshold": "Llindar (%)" + } + } + } + }, + "title": "Sensor Aurora NOAA" +} \ No newline at end of file diff --git a/homeassistant/components/aurora/translations/cs.json b/homeassistant/components/aurora/translations/cs.json new file mode 100644 index 00000000000..e7a10c94241 --- /dev/null +++ b/homeassistant/components/aurora/translations/cs.json @@ -0,0 +1,26 @@ +{ + "config": { + "error": { + "cannot_connect": "Nepoda\u0159ilo se p\u0159ipojit" + }, + "step": { + "user": { + "data": { + "latitude": "Zem\u011bpisn\u00e1 \u0161\u00ed\u0159ka", + "longitude": "Zem\u011bpisn\u00e1 d\u00e9lka", + "name": "Jm\u00e9no" + } + } + } + }, + "options": { + "step": { + "init": { + "data": { + "threshold": "Pr\u00e1h (%)" + } + } + } + }, + "title": "Senzor NOAA Aurora" +} \ No newline at end of file diff --git a/homeassistant/components/awair/translations/cs.json b/homeassistant/components/awair/translations/cs.json index 5bc950b7dcf..dfc83778bf9 100644 --- a/homeassistant/components/awair/translations/cs.json +++ b/homeassistant/components/awair/translations/cs.json @@ -20,7 +20,8 @@ "data": { "access_token": "P\u0159\u00edstupov\u00fd token", "email": "E-mail" - } + }, + "description": "Pro p\u0159\u00edstupov\u00fd token v\u00fdvoj\u00e1\u0159e Awair se mus\u00edte zaregistrovat na: https://developer.getawair.com/onboard/login" } } } diff --git a/homeassistant/components/axis/translations/cs.json b/homeassistant/components/axis/translations/cs.json index a6060a13d21..fd99c68ab35 100644 --- a/homeassistant/components/axis/translations/cs.json +++ b/homeassistant/components/axis/translations/cs.json @@ -23,5 +23,15 @@ "title": "Nastaven\u00ed za\u0159\u00edzen\u00ed Axis" } } + }, + "options": { + "step": { + "configure_stream": { + "data": { + "stream_profile": "Vyberte profil streamu, kter\u00fd chcete pou\u017e\u00edt" + }, + "title": "Mo\u017enosti video streamu za\u0159\u00edzen\u00ed Axis" + } + } } } \ No newline at end of file diff --git a/homeassistant/components/binary_sensor/translations/lb.json b/homeassistant/components/binary_sensor/translations/lb.json index 4c816d6424a..fc186bee447 100644 --- a/homeassistant/components/binary_sensor/translations/lb.json +++ b/homeassistant/components/binary_sensor/translations/lb.json @@ -98,6 +98,10 @@ "off": "Normal", "on": "Niddreg" }, + "battery_charging": { + "off": "Lued net", + "on": "Lued" + }, "cold": { "off": "Normal", "on": "Kal" @@ -122,6 +126,10 @@ "off": "Normal", "on": "Waarm" }, + "light": { + "off": "Keng Luucht", + "on": "Luucht detekt\u00e9iert" + }, "lock": { "off": "Gespaart", "on": "Net gespaart" @@ -134,6 +142,10 @@ "off": "Roueg", "on": "Detekt\u00e9iert" }, + "moving": { + "off": "Keng Beweegung", + "on": "Beweegung" + }, "occupancy": { "off": "Roueg", "on": "Detekt\u00e9iert" @@ -142,6 +154,10 @@ "off": "Zou", "on": "Op" }, + "plug": { + "off": "Net ugeschloss", + "on": "Ugeschloss" + }, "problem": { "off": "OK", "on": "Problem" diff --git a/homeassistant/components/canary/translations/cs.json b/homeassistant/components/canary/translations/cs.json index 5b883f253be..1cc46650531 100644 --- a/homeassistant/components/canary/translations/cs.json +++ b/homeassistant/components/canary/translations/cs.json @@ -22,6 +22,7 @@ "step": { "init": { "data": { + "ffmpeg_arguments": "Argumenty p\u0159edan\u00e9 ffmpeg pro kamery", "timeout": "\u010casov\u00fd limit po\u017eadavku (v sekund\u00e1ch)" } } diff --git a/homeassistant/components/cert_expiry/translations/cs.json b/homeassistant/components/cert_expiry/translations/cs.json index 61bd93f40b3..c4b61df7084 100644 --- a/homeassistant/components/cert_expiry/translations/cs.json +++ b/homeassistant/components/cert_expiry/translations/cs.json @@ -17,5 +17,6 @@ } } } - } + }, + "title": "Platnost certifik\u00e1tu" } \ No newline at end of file diff --git a/homeassistant/components/cloud/translations/ca.json b/homeassistant/components/cloud/translations/ca.json new file mode 100644 index 00000000000..fede749c7dd --- /dev/null +++ b/homeassistant/components/cloud/translations/ca.json @@ -0,0 +1,16 @@ +{ + "system_health": { + "info": { + "alexa_enabled": "Alexa activada", + "can_reach_cert_server": "Servidor de certificaci\u00f3 accessible", + "can_reach_cloud": "Home Assistant Cloud accessible", + "can_reach_cloud_auth": "Servidor d'autenticaci\u00f3 accessible", + "google_enabled": "Google activat", + "logged_in": "Sessi\u00f3 iniciada", + "relayer_connected": "Encaminador connectat", + "remote_connected": "Connexi\u00f3 remota establerta", + "remote_enabled": "Connexi\u00f3 remota activada", + "subscription_expiration": "Caducitat de la subscripci\u00f3" + } + } +} \ No newline at end of file diff --git a/homeassistant/components/cloud/translations/lb.json b/homeassistant/components/cloud/translations/lb.json new file mode 100644 index 00000000000..3806c2d6ebe --- /dev/null +++ b/homeassistant/components/cloud/translations/lb.json @@ -0,0 +1,16 @@ +{ + "system_health": { + "info": { + "alexa_enabled": "Alexa aktiv\u00e9iert", + "can_reach_cert_server": "Zertifikat Server ereechbar", + "can_reach_cloud": "Home Assistant Cloud ereechbar", + "can_reach_cloud_auth": "Authentifikatioun Server ereechbar", + "google_enabled": "Google aktiv\u00e9iert", + "logged_in": "Ageloggt", + "relayer_connected": "Relayer verbonnen", + "remote_connected": "Remote verbonnen", + "remote_enabled": "Remote aktiv\u00e9iert", + "subscription_expiration": "Abonnement Verfallsdatum" + } + } +} \ No newline at end of file diff --git a/homeassistant/components/cloud/translations/no.json b/homeassistant/components/cloud/translations/no.json index 96fddd84b2b..585811f0eb4 100644 --- a/homeassistant/components/cloud/translations/no.json +++ b/homeassistant/components/cloud/translations/no.json @@ -8,8 +8,8 @@ "google_enabled": "Google aktivert", "logged_in": "Logget inn", "relayer_connected": "Relayer tilkoblet", - "remote_connected": "Fjernkontroll tilkoblet", - "remote_enabled": "Fjernkontroll aktivert", + "remote_connected": "Ekstern tilkobling", + "remote_enabled": "Ekstern aktivert", "subscription_expiration": "Abonnementets utl\u00f8p" } } diff --git a/homeassistant/components/control4/translations/cs.json b/homeassistant/components/control4/translations/cs.json index c54454e9afe..327d642b308 100644 --- a/homeassistant/components/control4/translations/cs.json +++ b/homeassistant/components/control4/translations/cs.json @@ -14,6 +14,16 @@ "host": "IP adresa", "password": "Heslo", "username": "U\u017eivatelsk\u00e9 jm\u00e9no" + }, + "description": "Zadejte pros\u00edm \u00fadaje o sv\u00e9m \u00fa\u010dtu Control4 a IP adresu m\u00edstn\u00edho ovlada\u010de." + } + } + }, + "options": { + "step": { + "init": { + "data": { + "scan_interval": "Po\u010det sekund mezi aktualizacemi" } } } diff --git a/homeassistant/components/deconz/translations/cs.json b/homeassistant/components/deconz/translations/cs.json index d5b5e066c37..3ad72dc9ac9 100644 --- a/homeassistant/components/deconz/translations/cs.json +++ b/homeassistant/components/deconz/translations/cs.json @@ -4,6 +4,7 @@ "already_configured": "P\u0159emost\u011bn\u00ed je ji\u017e nastaveno", "already_in_progress": "Konfigurace ji\u017e prob\u00edh\u00e1", "no_bridges": "\u017d\u00e1dn\u00e9 deCONZ p\u0159emost\u011bn\u00ed nebyly nalezeny", + "no_hardware_available": "K deCONZ nen\u00ed p\u0159ipojeno \u017e\u00e1dn\u00e9 r\u00e1diov\u00e9 za\u0159\u00edzen\u00ed", "not_deconz_bridge": "Nejedn\u00e1 se o deCONZ p\u0159emost\u011bn\u00ed", "updated_instance": "Instance deCONZ aktualizov\u00e1na s nov\u00fdm hostitelem" }, diff --git a/homeassistant/components/demo/translations/cs.json b/homeassistant/components/demo/translations/cs.json index 1a9e6570085..1bac6710266 100644 --- a/homeassistant/components/demo/translations/cs.json +++ b/homeassistant/components/demo/translations/cs.json @@ -3,6 +3,7 @@ "step": { "options_1": { "data": { + "constant": "Konstanta", "int": "\u010c\u00edseln\u00fd vstup" } }, diff --git a/homeassistant/components/denonavr/translations/cs.json b/homeassistant/components/denonavr/translations/cs.json index 0dd0a9db578..1c66dae10f0 100644 --- a/homeassistant/components/denonavr/translations/cs.json +++ b/homeassistant/components/denonavr/translations/cs.json @@ -3,9 +3,19 @@ "abort": { "already_configured": "Za\u0159\u00edzen\u00ed je ji\u017e nastaveno", "already_in_progress": "Konfigurace ji\u017e prob\u00edh\u00e1", - "cannot_connect": "P\u0159ipojen\u00ed se nezda\u0159ilo, zkuste to pros\u00edm znovu - odpojen\u00ed napajec\u00edch a ethernetov\u00fdch kabel\u016f a jejich op\u011btovn\u00e9 p\u0159ipojen\u00ed m\u016f\u017ee pomoci" + "cannot_connect": "P\u0159ipojen\u00ed se nezda\u0159ilo, zkuste to pros\u00edm znovu - odpojen\u00ed napajec\u00edch a ethernetov\u00fdch kabel\u016f a jejich op\u011btovn\u00e9 p\u0159ipojen\u00ed m\u016f\u017ee pomoci", + "not_denonavr_manufacturer": "Nejedn\u00e1 se o s\u00ed\u0165ov\u00fd p\u0159ij\u00edma\u010d Denon AVR, objeven\u00fd v\u00fdrobce se neshoduje", + "not_denonavr_missing": "Nejedn\u00e1 se o s\u00ed\u0165ov\u00fd p\u0159ij\u00edma\u010d Denon AVR, informace o zji\u0161\u0165ov\u00e1n\u00ed nejsou \u00fapln\u00e9" }, + "error": { + "discovery_error": "Nepoda\u0159ilo se naj\u00edt s\u00ed\u0165ov\u00fd p\u0159ij\u00edma\u010d Denon AVR" + }, + "flow_title": "S\u00ed\u0165ov\u00fd p\u0159ij\u00edma\u010d Denon AVR: {name}", "step": { + "confirm": { + "description": "Potvr\u010fte pros\u00edm p\u0159id\u00e1n\u00ed p\u0159ij\u00edma\u010de", + "title": "S\u00ed\u0165ov\u00e9 p\u0159ij\u00edma\u010de Denon AVR" + }, "user": { "data": { "host": "IP adresa" diff --git a/homeassistant/components/doorbird/translations/cs.json b/homeassistant/components/doorbird/translations/cs.json index 6000c40e5a2..fea0647ec85 100644 --- a/homeassistant/components/doorbird/translations/cs.json +++ b/homeassistant/components/doorbird/translations/cs.json @@ -28,7 +28,8 @@ "init": { "data": { "events": "Seznam ud\u00e1lost\u00ed odd\u011blen\u00fdch \u010d\u00e1rkami." - } + }, + "description": "Zadejte n\u00e1zvy ud\u00e1lost\u00ed odd\u011blen\u00e9 \u010d\u00e1rkou, kter\u00e9 chcete sledovat. Po jejich zad\u00e1n\u00ed je pomoc\u00ed aplikace DoorBird p\u0159i\u0159a\u010fte ke konkr\u00e9tn\u00ed ud\u00e1losti. Viz dokumentace na https://www.home-assistant.io/integrations/doorbird/#events. P\u0159\u00edklad: nekdo_stiskl_tlacitko, pohyb" } } } diff --git a/homeassistant/components/dsmr/translations/ca.json b/homeassistant/components/dsmr/translations/ca.json index 14e637f5f98..a876776fea2 100644 --- a/homeassistant/components/dsmr/translations/ca.json +++ b/homeassistant/components/dsmr/translations/ca.json @@ -3,5 +3,15 @@ "abort": { "already_configured": "El dispositiu ja est\u00e0 configurat" } + }, + "options": { + "step": { + "init": { + "data": { + "time_between_update": "Temps m\u00ednim entre actualitzacions d'entitats [s]" + }, + "title": "Opcions de DSMR" + } + } } } \ No newline at end of file diff --git a/homeassistant/components/dunehd/translations/cs.json b/homeassistant/components/dunehd/translations/cs.json index 231ff6055b6..b52eb3d2cdf 100644 --- a/homeassistant/components/dunehd/translations/cs.json +++ b/homeassistant/components/dunehd/translations/cs.json @@ -13,6 +13,7 @@ "data": { "host": "Hostitel" }, + "description": "Nastaven\u00ed integrace Dune HD. Pokud m\u00e1te probl\u00e9my s nastaven\u00edm, p\u0159ejd\u011bte na: https://www.home-assistant.io/integrations/dunehd \n\nUjist\u011bte se, \u017ee je v\u00e1\u0161 p\u0159ehr\u00e1va\u010d zapnut\u00fd.", "title": "Dune HD" } } diff --git a/homeassistant/components/flick_electric/translations/cs.json b/homeassistant/components/flick_electric/translations/cs.json index 9a09785d5d8..6653b76bcd2 100644 --- a/homeassistant/components/flick_electric/translations/cs.json +++ b/homeassistant/components/flick_electric/translations/cs.json @@ -11,6 +11,7 @@ "step": { "user": { "data": { + "client_id": "ID klienta (voliteln\u00e9)", "password": "Heslo", "username": "U\u017eivatelsk\u00e9 jm\u00e9no" }, diff --git a/homeassistant/components/forked_daapd/translations/cs.json b/homeassistant/components/forked_daapd/translations/cs.json index 8732191dab0..55fa46e68ca 100644 --- a/homeassistant/components/forked_daapd/translations/cs.json +++ b/homeassistant/components/forked_daapd/translations/cs.json @@ -7,16 +7,32 @@ "error": { "forbidden": "Nelze se p\u0159ipojit. Zkontrolujte pros\u00edm opr\u00e1vn\u011bn\u00ed s\u00edt\u011b forked-daapd.", "unknown_error": "Neo\u010dek\u00e1van\u00e1 chyba", + "websocket_not_enabled": "Websocket serveru forked-daapd nen\u00ed povolen.", + "wrong_host_or_port": "Nelze se p\u0159ipojit. Zkontrolujte hostitele a port.", "wrong_password": "Nespr\u00e1vn\u00e9 heslo.", "wrong_server_type": "Integrace forked-daapd vy\u017eaduje server forked-daapd s verz\u00ed >= 27.0." }, + "flow_title": "Server forked-daapd: {name} ({host})", "step": { "user": { "data": { "host": "Hostitel", "name": "Zobrazovan\u00e9 jm\u00e9no", - "password": "Heslo API (ponechte pr\u00e1zdn\u00e9, pokud \u017e\u00e1dn\u00e9 heslo nen\u00ed)" - } + "password": "Heslo API (ponechte pr\u00e1zdn\u00e9, pokud \u017e\u00e1dn\u00e9 heslo nen\u00ed)", + "port": "Port API" + }, + "title": "Nastaven\u00ed za\u0159\u00edzen\u00ed forked-daapd" + } + } + }, + "options": { + "step": { + "init": { + "data": { + "max_playlists": "Maxim\u00e1ln\u00ed po\u010det seznam\u016f skladeb pou\u017eit\u00fdch jako zdroje" + }, + "description": "Nastavte r\u016fzn\u00e9 mo\u017enosti integrace forked-daapd.", + "title": "Nastavte mo\u017enosti forked-daapd" } } } diff --git a/homeassistant/components/goalzero/translations/cs.json b/homeassistant/components/goalzero/translations/cs.json index db33844a04d..4d39a29a7c3 100644 --- a/homeassistant/components/goalzero/translations/cs.json +++ b/homeassistant/components/goalzero/translations/cs.json @@ -14,6 +14,7 @@ "host": "Hostitel", "name": "Jm\u00e9no" }, + "description": "Nejprve si mus\u00edte st\u00e1hnout aplikaci Goal Zero: https://www.goalzero.com/product-features/yeti-app/ \n\nPodle pokyn\u016f p\u0159ipojte za\u0159\u00edzen\u00ed Yeti k s\u00edti Wifi. Pot\u00e9 z\u00edskejte hostitelskou IP z routeru. Aby se IP hostitele nezm\u011bnila, mus\u00ed b\u00fdt v nastaven\u00ed routeru pro za\u0159\u00edzen\u00ed nastaven DHCP. Informace nalezenete v u\u017eivatelsk\u00e9 p\u0159\u00edru\u010dce k routeru.", "title": "Goal Zero Yeti" } } diff --git a/homeassistant/components/hassio/translations/ca.json b/homeassistant/components/hassio/translations/ca.json index 981cb51c83a..ac804794b48 100644 --- a/homeassistant/components/hassio/translations/ca.json +++ b/homeassistant/components/hassio/translations/ca.json @@ -1,3 +1,19 @@ { + "system_health": { + "info": { + "board": "Placa", + "disk_total": "Total disc", + "disk_used": "Disc utilitzat", + "docker_version": "Versi\u00f3 de Docker", + "healthy": "Saludable", + "host_os": "Sistema operatiu amfitri\u00f3", + "installed_addons": "Complements instal\u00b7lats", + "supervisor_api": "API del Supervisor", + "supervisor_version": "Versi\u00f3 del Supervisor", + "supported": "Compatible", + "update_channel": "Canal d'actualitzaci\u00f3", + "version_api": "API de versions" + } + }, "title": "Hass.io" } \ No newline at end of file diff --git a/homeassistant/components/hassio/translations/cs.json b/homeassistant/components/hassio/translations/cs.json index 981cb51c83a..729dc069d7d 100644 --- a/homeassistant/components/hassio/translations/cs.json +++ b/homeassistant/components/hassio/translations/cs.json @@ -1,3 +1,19 @@ { + "system_health": { + "info": { + "board": "Deska", + "disk_total": "Kapacita disku", + "disk_used": "Obsazen\u00fd disk", + "docker_version": "Verze Dockeru", + "healthy": "V po\u0159\u00e1dku", + "host_os": "Hostitelsk\u00fd opera\u010dn\u00ed syst\u00e9m", + "installed_addons": "Nainstalovan\u00e9 dopl\u0148ky", + "supervisor_api": "API Supervisora", + "supervisor_version": "Verze Supervizora", + "supported": "Podporov\u00e1no", + "update_channel": "Kan\u00e1l aktualizac\u00ed", + "version_api": "Verze API" + } + }, "title": "Hass.io" } \ No newline at end of file diff --git a/homeassistant/components/hassio/translations/en.json b/homeassistant/components/hassio/translations/en.json index 875a79a60d7..230e0c11fea 100644 --- a/homeassistant/components/hassio/translations/en.json +++ b/homeassistant/components/hassio/translations/en.json @@ -1,18 +1,19 @@ { - "system_health": { - "info": { - "board": "Board", - "disk_total": "Disk Total", - "disk_used": "Disk Used", - "docker_version": "Docker Version", - "healthy": "Healthy", - "host_os": "Host Operating System", - "installed_addons": "Installed Add-ons", - "supervisor_api": "Supervisor API", - "supervisor_version": "Supervisor Version", - "supported": "Supported", - "update_channel": "Update Channel", - "version_api": "Version API" - } - } -} + "system_health": { + "info": { + "board": "Board", + "disk_total": "Disk Total", + "disk_used": "Disk Used", + "docker_version": "Docker Version", + "healthy": "Healthy", + "host_os": "Host Operating System", + "installed_addons": "Installed Add-ons", + "supervisor_api": "Supervisor API", + "supervisor_version": "Supervisor Version", + "supported": "Supported", + "update_channel": "Update Channel", + "version_api": "Version API" + } + }, + "title": "Hass.io" +} \ No newline at end of file diff --git a/homeassistant/components/homeassistant/translations/ca.json b/homeassistant/components/homeassistant/translations/ca.json new file mode 100644 index 00000000000..f02939b201e --- /dev/null +++ b/homeassistant/components/homeassistant/translations/ca.json @@ -0,0 +1,20 @@ +{ + "system_health": { + "info": { + "arch": "Arquitectura de la CPU", + "chassis": "Xass\u00eds", + "dev": "Desenvolupament", + "docker": "Docker", + "docker_version": "Docker", + "host_os": "Home Assistant OS", + "installation_type": "Tipus d'instal\u00b7laci\u00f3", + "os_name": "Fam\u00edlia del sistema operatiu", + "os_version": "Versi\u00f3 del sistema operatiu", + "python_version": "Versi\u00f3 de Python", + "supervisor": "Supervisor", + "timezone": "Zona hor\u00e0ria", + "version": "Versi\u00f3", + "virtualenv": "Entorn virtual" + } + } +} \ No newline at end of file diff --git a/homeassistant/components/homeassistant/translations/cs.json b/homeassistant/components/homeassistant/translations/cs.json index 59c99f1edfa..46bf2c56b4b 100644 --- a/homeassistant/components/homeassistant/translations/cs.json +++ b/homeassistant/components/homeassistant/translations/cs.json @@ -8,7 +8,7 @@ "docker_version": "Docker", "host_os": "Home Assistant OS", "installation_type": "Typ instalace", - "os_name": "Jm\u00e9no opera\u010dn\u00edho syst\u00e9mu", + "os_name": "Rodina opera\u010dn\u00edch syst\u00e9m\u016f", "os_version": "Verze opera\u010dn\u00edho syst\u00e9mu", "python_version": "Verze Pythonu", "supervisor": "Supervisor", diff --git a/homeassistant/components/homeassistant/translations/en.json b/homeassistant/components/homeassistant/translations/en.json index 8e810ef2143..3eb1f91eefc 100644 --- a/homeassistant/components/homeassistant/translations/en.json +++ b/homeassistant/components/homeassistant/translations/en.json @@ -1,17 +1,20 @@ { - "system_health": { - "info": { - "arch": "CPU Architecture", - "dev": "Development", - "docker": "Docker", - "installation_type": "Installation Type", - "os_name": "Operating System Family", - "os_version": "Operating System Version", - "python_version": "Python Version", - "timezone": "Timezone", - "version": "Version", - "virtualenv": "Virtual Environment" + "system_health": { + "info": { + "arch": "CPU Architecture", + "chassis": "Chassis", + "dev": "Development", + "docker": "Docker", + "docker_version": "Docker", + "host_os": "Home Assistant OS", + "installation_type": "Installation Type", + "os_name": "Operating System Family", + "os_version": "Operating System Version", + "python_version": "Python Version", + "supervisor": "Supervisor", + "timezone": "Timezone", + "version": "Version", + "virtualenv": "Virtual Environment" + } } - }, - "title": "Home Assistant" -} +} \ No newline at end of file diff --git a/homeassistant/components/homekit_controller/translations/cs.json b/homeassistant/components/homekit_controller/translations/cs.json index 6e41f423250..9a2159eda05 100644 --- a/homeassistant/components/homekit_controller/translations/cs.json +++ b/homeassistant/components/homekit_controller/translations/cs.json @@ -7,6 +7,7 @@ "already_paired": "Toto p\u0159\u00edslu\u0161enstv\u00ed je ji\u017e sp\u00e1rov\u00e1no s jin\u00fdm za\u0159\u00edzen\u00edm. Resetujte p\u0159\u00edslu\u0161enstv\u00ed a zkuste to znovu.", "ignored_model": "Podpora pro tento model je v HomeKit blokov\u00e1na, proto\u017ee je k dispozici nativn\u00ed integrace s v\u00edce funkcemi.", "invalid_config_entry": "Toto za\u0159\u00edzen\u00ed vypad\u00e1, \u017ee je p\u0159ipraven\u00e9 ke sp\u00e1rov\u00e1n\u00ed, ale v Home Assistant ji\u017e existuje konfliktn\u00ed polo\u017eka konfigurace, kterou je t\u0159eba nejprve odebrat.", + "invalid_properties": "Neplatn\u00e9 vlastnosti ozn\u00e1men\u00e9 za\u0159\u00edzen\u00edm.", "no_devices": "Nebyla nalezena \u017e\u00e1dn\u00e1 nesp\u00e1rov\u00e1 za\u0159\u00edzen\u00ed" }, "error": { diff --git a/homeassistant/components/huawei_lte/translations/cs.json b/homeassistant/components/huawei_lte/translations/cs.json index 79d8b594256..298cf182b08 100644 --- a/homeassistant/components/huawei_lte/translations/cs.json +++ b/homeassistant/components/huawei_lte/translations/cs.json @@ -23,6 +23,7 @@ "url": "URL", "username": "U\u017eivatelsk\u00e9 jm\u00e9no" }, + "description": "Zadejte podrobnosti o p\u0159\u00edstupu k za\u0159\u00edzen\u00ed. Zad\u00e1n\u00ed u\u017eivatelsk\u00e9ho jm\u00e9na a hesla je voliteln\u00e9, ale umo\u017e\u0148uje podporu dal\u0161\u00edch funkc\u00ed integrace. Na druhou stranu m\u016f\u017ee pou\u017eit\u00ed autorizovan\u00e9ho p\u0159ipojen\u00ed zp\u016fsobit probl\u00e9my s p\u0159\u00edstupem k webov\u00e9mu rozhran\u00ed Home Assistant zven\u010d\u00ed, kdy\u017e je integrace aktivn\u00ed, a naopak.", "title": "Konfigurovat Huawei LTE" } } diff --git a/homeassistant/components/insteon/translations/cs.json b/homeassistant/components/insteon/translations/cs.json index 6b0effe3759..18d7ff1c999 100644 --- a/homeassistant/components/insteon/translations/cs.json +++ b/homeassistant/components/insteon/translations/cs.json @@ -30,7 +30,8 @@ "plm": { "data": { "device": "Cesta k USB za\u0159\u00edzen\u00ed" - } + }, + "description": "Nastavte modem Insteon PowerLink (PLM)." }, "user": { "data": { @@ -57,7 +58,10 @@ }, "add_x10": { "data": { - "platform": "Platforma" + "housecode": "K\u00f3d domu (a-p)", + "platform": "Platforma", + "steps": "Kroky stm\u00edva\u010de (pouze pro sv\u011btla, v\u00fdchoz\u00ed 22)", + "unitcode": "K\u00f3d jednotky (1-16)" }, "title": "Insteon" }, @@ -68,6 +72,7 @@ "port": "Port", "username": "U\u017eivatelsk\u00e9 jm\u00e9no" }, + "description": "Zm\u011b\u0148te informace o p\u0159ipojen\u00ed rozbo\u010dova\u010de Insteon. Po proveden\u00ed t\u00e9to zm\u011bny mus\u00edte Home Assistant restartovat. T\u00edm se nezm\u011bn\u00ed nastaven\u00ed samotn\u00e9ho rozbo\u010dova\u010de. Chcete-li zm\u011bnit nastaven\u00ed rozbo\u010dova\u010de, pou\u017eijte jeho aplikaci.", "title": "Insteon" }, "init": { @@ -75,9 +80,13 @@ "add_x10": "P\u0159idejte za\u0159\u00edzen\u00ed X10.", "remove_x10": "Odeberte za\u0159\u00edzen\u00ed X10." }, + "description": "Vyberte mo\u017enost k nastaven\u00ed.", "title": "Insteon" }, "remove_override": { + "data": { + "address": "Vyberte adresu za\u0159\u00edzen\u00ed, kter\u00e9 chcete odebrat" + }, "title": "Insteon" }, "remove_x10": { diff --git a/homeassistant/components/iqvia/translations/cs.json b/homeassistant/components/iqvia/translations/cs.json index 6754cdc84af..04829af0b8f 100644 --- a/homeassistant/components/iqvia/translations/cs.json +++ b/homeassistant/components/iqvia/translations/cs.json @@ -11,6 +11,7 @@ "data": { "zip_code": "PS\u010c" }, + "description": "Vypl\u0148te sv\u00e9 americk\u00e9 nebo kanadsk\u00e9 PS\u010c.", "title": "IQVIA" } } diff --git a/homeassistant/components/isy994/translations/cs.json b/homeassistant/components/isy994/translations/cs.json index f5024d177fd..e2d3dc4c883 100644 --- a/homeassistant/components/isy994/translations/cs.json +++ b/homeassistant/components/isy994/translations/cs.json @@ -6,6 +6,7 @@ "error": { "cannot_connect": "Nepoda\u0159ilo se p\u0159ipojit", "invalid_auth": "Neplatn\u00e9 ov\u011b\u0159en\u00ed", + "invalid_host": "Z\u00e1znam hostitele nebyl v \u00fapln\u00e9m form\u00e1tu URL, nap\u0159. http://192.168.10.100:80", "unknown": "Neo\u010dek\u00e1van\u00e1 chyba" }, "step": { @@ -13,8 +14,10 @@ "data": { "host": "URL", "password": "Heslo", + "tls": "Verze TLS ovlada\u010de ISY.", "username": "U\u017eivatelsk\u00e9 jm\u00e9no" }, + "description": "Polo\u017eka hostitele mus\u00ed b\u00fdt v \u00fapln\u00e9m form\u00e1tu URL, nap\u0159 http://192.168.10.100:80.", "title": "P\u0159ipojen\u00ed k ISY994" } } diff --git a/homeassistant/components/kodi/translations/cs.json b/homeassistant/components/kodi/translations/cs.json index ca5a30dec36..e21c08b0758 100644 --- a/homeassistant/components/kodi/translations/cs.json +++ b/homeassistant/components/kodi/translations/cs.json @@ -29,7 +29,8 @@ "host": "Hostitel", "port": "Port", "ssl": "Pou\u017e\u00edv\u00e1 SSL certifik\u00e1t" - } + }, + "description": "Informace o p\u0159ipojen\u00ed Kodi. Nezapome\u0148te povolit mo\u017enost \"Povolit ovl\u00e1d\u00e1n\u00ed Kodi prost\u0159ednictv\u00edm protokolu HTTP\" v Syst\u00e9m/Nastaven\u00ed/S\u00ed\u0165/Slu\u017eby." }, "ws_port": { "data": { diff --git a/homeassistant/components/konnected/translations/cs.json b/homeassistant/components/konnected/translations/cs.json index 8f575c34a51..f2cd8759a54 100644 --- a/homeassistant/components/konnected/translations/cs.json +++ b/homeassistant/components/konnected/translations/cs.json @@ -61,7 +61,8 @@ "5": "Z\u00f3na 5", "6": "Z\u00f3na 6", "7": "Z\u00f3na 7" - } + }, + "title": "Nastaven\u00ed vstupu/v\u00fdstupu" }, "options_io_ext": { "data": { diff --git a/homeassistant/components/lovelace/translations/ca.json b/homeassistant/components/lovelace/translations/ca.json new file mode 100644 index 00000000000..65408175090 --- /dev/null +++ b/homeassistant/components/lovelace/translations/ca.json @@ -0,0 +1,9 @@ +{ + "system_health": { + "info": { + "dashboards": "Panells", + "mode": "Mode", + "resources": "Recursos" + } + } +} \ No newline at end of file diff --git a/homeassistant/components/netatmo/translations/cs.json b/homeassistant/components/netatmo/translations/cs.json index 74a31f4199d..7857e345165 100644 --- a/homeassistant/components/netatmo/translations/cs.json +++ b/homeassistant/components/netatmo/translations/cs.json @@ -26,13 +26,17 @@ "lon_sw": "Zem\u011bpisn\u00e1 d\u00e9lka Jihoz\u00e1padn\u00ed roh", "mode": "V\u00fdpo\u010det", "show_on_map": "Zobrazit na map\u011b" - } + }, + "description": "Nastavte ve\u0159ejn\u00fd senzor po\u010das\u00ed pro oblast.", + "title": "Ve\u0159ejn\u00fd senzor po\u010das\u00ed Netatmo" }, "public_weather_areas": { "data": { "new_area": "Jm\u00e9no oblasti", "weather_areas": "Oblasti po\u010das\u00ed" - } + }, + "description": "Nastavte ve\u0159ejn\u00e9 senzory po\u010das\u00ed.", + "title": "Ve\u0159ejn\u00fd senzor po\u010das\u00ed Netatmo" } } } diff --git a/homeassistant/components/plex/translations/cs.json b/homeassistant/components/plex/translations/cs.json index bef1271888f..de85391a7d9 100644 --- a/homeassistant/components/plex/translations/cs.json +++ b/homeassistant/components/plex/translations/cs.json @@ -37,6 +37,9 @@ "title": "Plex Media Server" }, "user_advanced": { + "data": { + "setup_method": "Metoda nastaven\u00ed" + }, "title": "Plex Media Server" } } diff --git a/homeassistant/components/plugwise/translations/cs.json b/homeassistant/components/plugwise/translations/cs.json index 3ad7fad2a6b..c1c193e04a2 100644 --- a/homeassistant/components/plugwise/translations/cs.json +++ b/homeassistant/components/plugwise/translations/cs.json @@ -8,6 +8,7 @@ "invalid_auth": "Neplatn\u00e9 ov\u011b\u0159en\u00ed", "unknown": "Neo\u010dek\u00e1van\u00e1 chyba" }, + "flow_title": "Smile: {name}", "step": { "user": { "data": { @@ -19,6 +20,7 @@ "user_gateway": { "data": { "host": "IP adresa", + "password": "Smile ID", "port": "Port", "username": "U\u017eivatelsk\u00e9 jm\u00e9no Smile" }, diff --git a/homeassistant/components/rfxtrx/translations/cs.json b/homeassistant/components/rfxtrx/translations/cs.json index 5052e35fd1e..706d4499fb2 100644 --- a/homeassistant/components/rfxtrx/translations/cs.json +++ b/homeassistant/components/rfxtrx/translations/cs.json @@ -41,6 +41,7 @@ "invalid_event_code": "Neplatn\u00fd k\u00f3d ud\u00e1losti", "invalid_input_2262_off": "Neplatn\u00fd vstup pro vyp\u00ednac\u00ed p\u0159\u00edkaz", "invalid_input_2262_on": "Neplatn\u00fd vstup pro zap\u00ednac\u00ed p\u0159\u00edkaz", + "invalid_input_off_delay": "Neplatn\u00e1 hodnota pro zpo\u017ed\u011bn\u00ed vypnut\u00ed", "unknown": "Neo\u010dek\u00e1van\u00e1 chyba" }, "step": { @@ -49,13 +50,18 @@ "automatic_add": "Povolit automatick\u00e9 p\u0159id\u00e1n\u00ed", "debug": "Povolit lad\u011bn\u00ed", "device": "Vyberte za\u0159\u00edzen\u00ed, kter\u00e9 chcete nastavit", + "event_code": "Zadejte k\u00f3d ud\u00e1losti, kterou chcete p\u0159idat", "remove_device": "Vyberte za\u0159\u00edzen\u00ed, kter\u00e9 chcete odstranit" }, "title": "Mo\u017enosti Rfxtrx" }, "set_device_options": { "data": { - "replace_device": "Vyberte za\u0159\u00edzen\u00ed, kter\u00e9 chcete vym\u011bnit" + "fire_event": "Povolit ud\u00e1lost za\u0159\u00edzen\u00ed", + "off_delay": "Zpo\u017ed\u011bn\u00ed vypnut\u00ed", + "off_delay_enabled": "Povolit zpo\u017ed\u011bn\u00ed vypnut\u00ed", + "replace_device": "Vyberte za\u0159\u00edzen\u00ed, kter\u00e9 chcete vym\u011bnit", + "signal_repetitions": "Po\u010det opakov\u00e1n\u00ed sign\u00e1lu" }, "title": "Nastaven\u00ed mo\u017enost\u00ed za\u0159\u00edzen\u00ed" } diff --git a/homeassistant/components/roon/translations/cs.json b/homeassistant/components/roon/translations/cs.json index 9418fa39cbb..a15e75066a9 100644 --- a/homeassistant/components/roon/translations/cs.json +++ b/homeassistant/components/roon/translations/cs.json @@ -10,6 +10,7 @@ }, "step": { "link": { + "description": "Mus\u00edte povolit Home Assistant v Roon. Po kliknut\u00ed na Odeslat p\u0159ejd\u011bte do aplikace Roon Core, otev\u0159ete Nastaven\u00ed a na z\u00e1lo\u017ece Roz\u0161\u00ed\u0159en\u00ed povolte Home Assistant.", "title": "Autorizujte HomeAssistant v Roon" }, "user": { diff --git a/homeassistant/components/simplisafe/translations/cs.json b/homeassistant/components/simplisafe/translations/cs.json index 41487b69d78..7fd81a94391 100644 --- a/homeassistant/components/simplisafe/translations/cs.json +++ b/homeassistant/components/simplisafe/translations/cs.json @@ -11,12 +11,14 @@ }, "step": { "mfa": { + "description": "Zkontrolujte, zda v\u00e1m do e-mail p\u0159i\u0161el odkaz od SimpliSafe. Po ov\u011b\u0159en\u00ed odkazu se vra\u0165te sem a dokon\u010dete instalaci integrace.", "title": "V\u00edcefaktorov\u00e9 ov\u011b\u0159ov\u00e1n\u00ed SimpliSafe" }, "reauth_confirm": { "data": { "password": "Heslo" }, + "description": "Platnost va\u0161eho p\u0159\u00edstupov\u00e9ho tokenu vypr\u0161ela nebo byla zru\u0161ena. Chcete-li sv\u016fj \u00fa\u010det znovu propojit, zadejte sv\u00e9 heslo.", "title": "Znovu ov\u011b\u0159it integraci" }, "user": { diff --git a/homeassistant/components/smappee/translations/cs.json b/homeassistant/components/smappee/translations/cs.json index 015d2fda130..174da41205a 100644 --- a/homeassistant/components/smappee/translations/cs.json +++ b/homeassistant/components/smappee/translations/cs.json @@ -2,8 +2,10 @@ "config": { "abort": { "already_configured_device": "Za\u0159\u00edzen\u00ed je ji\u017e nastaveno", + "already_configured_local_device": "M\u00edstn\u00ed za\u0159\u00edzen\u00ed ji\u017e jsou nastavena. P\u0159ed nastaven\u00ed cloudov\u00e9ho za\u0159\u00edzen\u00ed je nejprve odstra\u0148te.", "authorize_url_timeout": "\u010casov\u00fd limit autoriza\u010dn\u00edho URL vypr\u0161el", "cannot_connect": "Nepoda\u0159ilo se p\u0159ipojit", + "invalid_mdns": "Nepodporovan\u00e9 za\u0159\u00edzen\u00ed pro integraci Smappee.", "missing_configuration": "Komponenta nen\u00ed nastavena. Postupujte podle dokumentace.", "no_url_available": "Nen\u00ed k dispozici \u017e\u00e1dn\u00e1 adresa URL. Informace o t\u00e9to chyb\u011b naleznete [v sekci n\u00e1pov\u011bdy]({docs_url})" }, diff --git a/homeassistant/components/smarthab/translations/cs.json b/homeassistant/components/smarthab/translations/cs.json index bb13d19ad93..1e862ff0069 100644 --- a/homeassistant/components/smarthab/translations/cs.json +++ b/homeassistant/components/smarthab/translations/cs.json @@ -9,7 +9,8 @@ "data": { "email": "E-mail", "password": "Heslo" - } + }, + "title": "Nastaven\u00ed SmartHab" } } } diff --git a/homeassistant/components/smartthings/translations/cs.json b/homeassistant/components/smartthings/translations/cs.json index a634bcceb0e..a9279722712 100644 --- a/homeassistant/components/smartthings/translations/cs.json +++ b/homeassistant/components/smartthings/translations/cs.json @@ -19,12 +19,14 @@ "data": { "access_token": "P\u0159\u00edstupov\u00fd token" }, + "description": "Zadejte [osobn\u00ed p\u0159\u00edstupov\u00fd token]({token_url}) SmartThings, kter\u00fd byl vytvo\u0159en podle [pokyn\u016f]({component_url}). Ten se pou\u017eije k vytvo\u0159en\u00ed integrace Home Assistant ve va\u0161em \u00fa\u010dtu SmartThings.", "title": "Zadejte osobn\u00ed p\u0159\u00edstupov\u00fd token" }, "select_location": { "data": { "location_id": "Um\u00edst\u011bn\u00ed" }, + "description": "Vyberte um\u00edst\u011bn\u00ed SmartThings, kter\u00e9 chcete p\u0159idat do Home Assistant. Pot\u00e9 otev\u0159eme nov\u00e9 okno a po\u017e\u00e1d\u00e1me v\u00e1s o p\u0159ihl\u00e1\u0161en\u00ed a autorizaci instalace integrace Home Assistant do vybran\u00e9ho um\u00edst\u011bn\u00ed.", "title": "Vyberte um\u00edst\u011bn\u00ed" }, "user": { diff --git a/homeassistant/components/soma/translations/cs.json b/homeassistant/components/soma/translations/cs.json index eeee574cf20..5a27562df71 100644 --- a/homeassistant/components/soma/translations/cs.json +++ b/homeassistant/components/soma/translations/cs.json @@ -4,7 +4,8 @@ "already_setup": "M\u016f\u017eete nastavit pouze jeden \u00fa\u010det Soma.", "authorize_url_timeout": "\u010casov\u00fd limit autoriza\u010dn\u00edho URL vypr\u0161el", "connection_error": "P\u0159ipojen\u00ed k za\u0159\u00edzen\u00ed SOMA Connect se nezda\u0159ilo.", - "missing_configuration": "Integrace Soma nen\u00ed nastavena. Postupujte podle dokumentace." + "missing_configuration": "Integrace Soma nen\u00ed nastavena. Postupujte podle dokumentace.", + "result_error": "SOMA Connect odpov\u011bd\u011blo chybov\u00fdm stavem." }, "create_entry": { "default": "\u00dasp\u011b\u0161n\u011b ov\u011b\u0159eno pomoc\u00ed Soma." diff --git a/homeassistant/components/syncthru/translations/cs.json b/homeassistant/components/syncthru/translations/cs.json index 7527e6d81c8..d34668146a3 100644 --- a/homeassistant/components/syncthru/translations/cs.json +++ b/homeassistant/components/syncthru/translations/cs.json @@ -3,6 +3,9 @@ "abort": { "already_configured": "Za\u0159\u00edzen\u00ed je ji\u017e nastaveno" }, + "error": { + "invalid_url": "Neplatn\u00e1 URL adresa" + }, "flow_title": "Tisk\u00e1rna Samsung SyncThru: {name}", "step": { "confirm": { diff --git a/homeassistant/components/toon/translations/cs.json b/homeassistant/components/toon/translations/cs.json index 3039fa9f061..52a2f7b5742 100644 --- a/homeassistant/components/toon/translations/cs.json +++ b/homeassistant/components/toon/translations/cs.json @@ -1,6 +1,7 @@ { "config": { "abort": { + "authorize_url_fail": "Nezn\u00e1m\u00e1 chyba p\u0159i generov\u00e1n\u00ed autoriza\u010dn\u00ed URL adresy.", "authorize_url_timeout": "\u010casov\u00fd limit autoriza\u010dn\u00edho URL vypr\u0161el", "missing_configuration": "Komponenta nen\u00ed nastavena. Postupujte podle dokumentace.", "no_url_available": "Nen\u00ed k dispozici \u017e\u00e1dn\u00e1 adresa URL. Informace o t\u00e9to chyb\u011b naleznete [v sekci n\u00e1pov\u011bdy]({docs_url})" diff --git a/homeassistant/components/transmission/translations/cs.json b/homeassistant/components/transmission/translations/cs.json index 73995f2eece..8ad9e051064 100644 --- a/homeassistant/components/transmission/translations/cs.json +++ b/homeassistant/components/transmission/translations/cs.json @@ -25,6 +25,7 @@ "init": { "data": { "limit": "Limit", + "order": "Po\u0159ad\u00ed", "scan_interval": "Frekvence aktualizac\u00ed" }, "title": "Nakonfigurujte mo\u017enosti pro Transmission" diff --git a/homeassistant/components/vera/translations/cs.json b/homeassistant/components/vera/translations/cs.json index c1cf289ae08..df93575a945 100644 --- a/homeassistant/components/vera/translations/cs.json +++ b/homeassistant/components/vera/translations/cs.json @@ -22,6 +22,7 @@ "exclude": "ID za\u0159\u00edzen\u00ed Vera, kter\u00e1 chcete vylou\u010dit z Home Assistant.", "lights": "ID za\u0159\u00edzen\u00ed Vera, se kter\u00fdmi m\u00e1 Home Assistant zach\u00e1zet jako se sv\u011btly." }, + "description": "Podrobnosti o voliteln\u00fdch parametrech najdete v dokumentaci vera: https://www.home-assistant.io/integrations/vera/. Pozn\u00e1mka: Jak\u00e9koli zm\u011bny zde budou vy\u017eadovat restart serveru Home Assistant. Chcete-li vymazat hodnoty, zadejte mezeru.", "title": "Mo\u017enosti ovlada\u010de Vera" } } diff --git a/homeassistant/components/vilfo/translations/cs.json b/homeassistant/components/vilfo/translations/cs.json index 8b423a73518..b6735bd64cb 100644 --- a/homeassistant/components/vilfo/translations/cs.json +++ b/homeassistant/components/vilfo/translations/cs.json @@ -14,6 +14,7 @@ "access_token": "P\u0159\u00edstupov\u00fd token", "host": "Hostitel" }, + "description": "Nastaven\u00ed integrace routeru Vilfo. Pot\u0159ebujete n\u00e1zev hostitele/IP adresu routeru Vilfo a p\u0159\u00edstupov\u00fd API token. Dal\u0161\u00ed informace o t\u00e9to integraci a o tom, jak tyto podrobnosti z\u00edskat, najdete na adrese: https://www.home-assistant.io/integrations/vilfo", "title": "P\u0159ipojen\u00ed k routeru Vilfo" } } diff --git a/homeassistant/components/vizio/translations/cs.json b/homeassistant/components/vizio/translations/cs.json index 963461737bb..23fec08499b 100644 --- a/homeassistant/components/vizio/translations/cs.json +++ b/homeassistant/components/vizio/translations/cs.json @@ -5,7 +5,8 @@ "updated_entry": "Tato polo\u017eka ji\u017e byla nastavena, ale jm\u00e9no, aplikace nebo mo\u017enosti definovan\u00e9 v konfiguraci neodpov\u00eddaj\u00ed d\u0159\u00edve importovan\u00e9 konfiguraci, tak\u017ee polo\u017eka konfigurace byla odpov\u00eddaj\u00edc\u00edm zp\u016fsobem aktualizov\u00e1na." }, "error": { - "cannot_connect": "Nepoda\u0159ilo se p\u0159ipojit" + "cannot_connect": "Nepoda\u0159ilo se p\u0159ipojit", + "existing_config_entry_found": "Za\u0159\u00edzen\u00ed VIZIO SmartCast se stejn\u00fdm s\u00e9riov\u00fdm \u010d\u00edslem ji\u017e bylo nastaveno. Chcete-li nastavit tuto polo\u017eku, mus\u00edte odstranit st\u00e1vaj\u00edc\u00ed polo\u017eku." }, "step": { "pair_tv": { diff --git a/homeassistant/components/wolflink/translations/cs.json b/homeassistant/components/wolflink/translations/cs.json index b66ca57cd44..e532b833851 100644 --- a/homeassistant/components/wolflink/translations/cs.json +++ b/homeassistant/components/wolflink/translations/cs.json @@ -12,7 +12,8 @@ "device": { "data": { "device_name": "Za\u0159\u00edzen\u00ed" - } + }, + "title": "Vyberte za\u0159\u00edzen\u00ed WOLF" }, "user": { "data": { diff --git a/homeassistant/components/wolflink/translations/sensor.cs.json b/homeassistant/components/wolflink/translations/sensor.cs.json index a295a04fb34..046fc4e6ed9 100644 --- a/homeassistant/components/wolflink/translations/sensor.cs.json +++ b/homeassistant/components/wolflink/translations/sensor.cs.json @@ -1,13 +1,27 @@ { "state": { "wolflink__state": { + "aktiviert": "Aktivov\u00e1no", + "aus": "Zak\u00e1z\u00e1no", "auto": "Automatika", + "automatik_aus": "Automatick\u00e9 vypnut\u00ed", + "automatik_ein": "Automatick\u00e9 zapnut\u00ed", "cooling": "Chlazen\u00ed", + "deaktiviert": "Neaktivn\u00ed", "eco": "Ekonomick\u00fd re\u017eim", "ein": "Povoleno", + "externe_deaktivierung": "Extern\u00ed deaktivace", + "frostschutz": "Ochrana proti mrazu", + "gasdruck": "Tlak plynu", "heizbetrieb": "Re\u017eim topen\u00ed", "heizung": "Topen\u00ed", + "initialisierung": "Inicializace", + "kalibration": "Kalibrace", "permanent": "Trval\u00fd", + "schornsteinfeger": "Zkou\u0161ka emis\u00ed", + "smart_grid": "SmartGrid", + "smart_home": "SmartHome", + "softstart": "M\u011bkk\u00fd start", "sparbetrieb": "Ekonomick\u00fd re\u017eim", "sparen": "Ekonomick\u00fd re\u017eim", "standby": "Pohotovostn\u00ed re\u017eim", diff --git a/homeassistant/components/xiaomi_aqara/translations/cs.json b/homeassistant/components/xiaomi_aqara/translations/cs.json index 2f8110f22e4..b344be8c647 100644 --- a/homeassistant/components/xiaomi_aqara/translations/cs.json +++ b/homeassistant/components/xiaomi_aqara/translations/cs.json @@ -2,9 +2,11 @@ "config": { "abort": { "already_configured": "Za\u0159\u00edzen\u00ed je ji\u017e nastaveno", - "already_in_progress": "Konfigurace ji\u017e prob\u00edh\u00e1" + "already_in_progress": "Konfigurace ji\u017e prob\u00edh\u00e1", + "not_xiaomi_aqara": "Za\u0159\u00edzen\u00ed nen\u00ed br\u00e1na Xiaomi Aqara, objeven\u00e9 za\u0159\u00edzen\u00ed neodpov\u00edd\u00e1 zn\u00e1m\u00fdm bran\u00e1m" }, "error": { + "discovery_error": "Nepoda\u0159ilo se naj\u00edt br\u00e1nu Xiaomi Aqara, zkuste jako rozhran\u00ed pou\u017e\u00edt IP adresu za\u0159\u00edzen\u00ed, na kter\u00e9m je spu\u0161t\u011bn HomeAssistant.", "invalid_host": "Neplatn\u00fd hostitel nebo IP adresa , viz https://www.home-assistant.io/integrations/xiaomi_aqara/#connection-problem", "invalid_interface": "Neplatn\u00e9 s\u00ed\u0165ov\u00e9 rozhran\u00ed", "invalid_key": "Neplatn\u00fd kl\u00ed\u010d br\u00e1ny", @@ -24,6 +26,7 @@ "key": "Kl\u00ed\u010d va\u0161\u00ed br\u00e1ny", "name": "Jm\u00e9no br\u00e1ny" }, + "description": "Kl\u00ed\u010d (heslo) lze z\u00edskat pomoc\u00ed tohoto n\u00e1vodu: https://www.domoticz.com/wiki/Xiaomi_Gateway_(Aqara)#Adding_the_Xiaomi_Gateway_to_Domoticz. Pokud kl\u00ed\u010d nen\u00ed k dispozici, budou p\u0159\u00edstupn\u00e9 pouze senzory", "title": "Br\u00e1na Xiaomi Aqara, voliteln\u00e1 nastaven\u00ed" }, "user": { diff --git a/homeassistant/components/zha/translations/cs.json b/homeassistant/components/zha/translations/cs.json index 119789e841e..1ac4c7c2d61 100644 --- a/homeassistant/components/zha/translations/cs.json +++ b/homeassistant/components/zha/translations/cs.json @@ -14,6 +14,7 @@ "title": "Nastaven\u00ed" }, "user": { + "description": "Vyberte s\u00e9riov\u00fd port pro r\u00e1dio Zigbee", "title": "ZHA" } } From 2bf15172bb484ffeca29918d78ea65a4e894199a Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Fri, 13 Nov 2020 00:10:16 +0000 Subject: [PATCH 18/73] [ci skip] Translation update --- .../components/aurora/translations/et.json | 26 +++++++++++++++++++ .../components/aurora/translations/no.json | 26 +++++++++++++++++++ .../components/aurora/translations/pl.json | 26 +++++++++++++++++++ .../components/aurora/translations/ru.json | 26 +++++++++++++++++++ .../components/broadlink/translations/ru.json | 4 +-- .../components/cloud/translations/pl.json | 3 +++ .../components/cloud/translations/ru.json | 13 ++++++++++ .../components/dsmr/translations/ru.json | 10 +++++++ .../components/hassio/translations/et.json | 16 ++++++++++++ .../components/hassio/translations/no.json | 16 ++++++++++++ .../components/hassio/translations/pl.json | 16 ++++++++++++ .../components/hassio/translations/ru.json | 13 ++++++++++ .../homeassistant/translations/et.json | 2 +- .../homeassistant/translations/no.json | 2 +- .../homeassistant/translations/pl.json | 7 ++--- .../homeassistant/translations/ru.json | 20 ++++++++++++++ .../components/locative/translations/ru.json | 2 +- .../components/lovelace/translations/ca.json | 3 ++- .../components/lovelace/translations/cs.json | 3 ++- .../components/lovelace/translations/en.json | 3 ++- .../components/lovelace/translations/et.json | 3 ++- .../components/lovelace/translations/no.json | 3 ++- .../components/lovelace/translations/ru.json | 9 +++++++ .../recollect_waste/translations/ca.json | 18 +++++++++++++ .../recollect_waste/translations/cs.json | 18 +++++++++++++ .../recollect_waste/translations/et.json | 18 +++++++++++++ .../recollect_waste/translations/no.json | 18 +++++++++++++ 27 files changed, 311 insertions(+), 13 deletions(-) create mode 100644 homeassistant/components/aurora/translations/et.json create mode 100644 homeassistant/components/aurora/translations/no.json create mode 100644 homeassistant/components/aurora/translations/pl.json create mode 100644 homeassistant/components/aurora/translations/ru.json create mode 100644 homeassistant/components/cloud/translations/ru.json create mode 100644 homeassistant/components/homeassistant/translations/ru.json create mode 100644 homeassistant/components/lovelace/translations/ru.json create mode 100644 homeassistant/components/recollect_waste/translations/ca.json create mode 100644 homeassistant/components/recollect_waste/translations/cs.json create mode 100644 homeassistant/components/recollect_waste/translations/et.json create mode 100644 homeassistant/components/recollect_waste/translations/no.json diff --git a/homeassistant/components/aurora/translations/et.json b/homeassistant/components/aurora/translations/et.json new file mode 100644 index 00000000000..80fb6b21736 --- /dev/null +++ b/homeassistant/components/aurora/translations/et.json @@ -0,0 +1,26 @@ +{ + "config": { + "error": { + "cannot_connect": "\u00dchendus nurjus" + }, + "step": { + "user": { + "data": { + "latitude": "Laiuskraad", + "longitude": "Pikkuskraad", + "name": "Nimi" + } + } + } + }, + "options": { + "step": { + "init": { + "data": { + "threshold": "L\u00e4vi (%)" + } + } + } + }, + "title": "NOAA Aurora andur" +} \ No newline at end of file diff --git a/homeassistant/components/aurora/translations/no.json b/homeassistant/components/aurora/translations/no.json new file mode 100644 index 00000000000..1d22d6cd08b --- /dev/null +++ b/homeassistant/components/aurora/translations/no.json @@ -0,0 +1,26 @@ +{ + "config": { + "error": { + "cannot_connect": "Tilkobling mislyktes" + }, + "step": { + "user": { + "data": { + "latitude": "Breddegrad", + "longitude": "Lengdegrad", + "name": "Navn" + } + } + } + }, + "options": { + "step": { + "init": { + "data": { + "threshold": "Terskel (%)" + } + } + } + }, + "title": "NOAA Aurora-sensor" +} \ No newline at end of file diff --git a/homeassistant/components/aurora/translations/pl.json b/homeassistant/components/aurora/translations/pl.json new file mode 100644 index 00000000000..f8786290458 --- /dev/null +++ b/homeassistant/components/aurora/translations/pl.json @@ -0,0 +1,26 @@ +{ + "config": { + "error": { + "cannot_connect": "Nie mo\u017cna nawi\u0105za\u0107 po\u0142\u0105czenia" + }, + "step": { + "user": { + "data": { + "latitude": "Szeroko\u015b\u0107 geograficzna", + "longitude": "D\u0142ugo\u015b\u0107 geograficzna", + "name": "Nazwa" + } + } + } + }, + "options": { + "step": { + "init": { + "data": { + "threshold": "Pr\u00f3g prawdopodobie\u0144stwa (%)" + } + } + } + }, + "title": "Sensor NOAA Aurora" +} \ No newline at end of file diff --git a/homeassistant/components/aurora/translations/ru.json b/homeassistant/components/aurora/translations/ru.json new file mode 100644 index 00000000000..20e8f4a184b --- /dev/null +++ b/homeassistant/components/aurora/translations/ru.json @@ -0,0 +1,26 @@ +{ + "config": { + "error": { + "cannot_connect": "\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f." + }, + "step": { + "user": { + "data": { + "latitude": "\u0428\u0438\u0440\u043e\u0442\u0430", + "longitude": "\u0414\u043e\u043b\u0433\u043e\u0442\u0430", + "name": "\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435" + } + } + } + }, + "options": { + "step": { + "init": { + "data": { + "threshold": "\u041f\u043e\u0440\u043e\u0433 (%)" + } + } + } + }, + "title": "NOAA Aurora Sensor" +} \ No newline at end of file diff --git a/homeassistant/components/broadlink/translations/ru.json b/homeassistant/components/broadlink/translations/ru.json index 617c508b8c2..19470d5a66d 100644 --- a/homeassistant/components/broadlink/translations/ru.json +++ b/homeassistant/components/broadlink/translations/ru.json @@ -25,14 +25,14 @@ "title": "\u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430" }, "reset": { - "description": "\u0412\u0430\u0448\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438. \u0421\u043b\u0435\u0434\u0443\u0439\u0442\u0435 \u0434\u0430\u043d\u043d\u044b\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e: \n 1. \u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u0431\u0440\u043e\u0441 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043d\u0430 \u0437\u0430\u0432\u043e\u0434\u0441\u043a\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438. \n 2. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0432 \u0412\u0430\u0448\u0443 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0443\u044e \u0441\u0435\u0442\u044c. \n 3. \u041d\u0435 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0438 \u0437\u0430\u043a\u0440\u043e\u0439\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \n 4. \u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c.", + "description": "\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e {name} ({model}, {host}) \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043e. \u0421\u043b\u0435\u0434\u0443\u0439\u0442\u0435 \u0434\u0430\u043d\u043d\u044b\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e: \n 1. \u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 Broadlink. \n 2. \u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e. \n 3. \u041d\u0430\u0436\u043c\u0438\u0442\u0435 `...` \u0432 \u043f\u0440\u0430\u0432\u043e\u043c \u0432\u0435\u0440\u0445\u043d\u0435\u043c \u0443\u0433\u043b\u0443. \n 4. \u041f\u0440\u043e\u043a\u0440\u0443\u0442\u0438\u0442\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0432\u043d\u0438\u0437.\n 5. \u041e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u0435 \u0437\u0430\u043c\u043e\u043a.", "title": "\u0420\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430" }, "unlock": { "data": { "unlock": "\u0414\u0430, \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e." }, - "description": "\u0412\u0430\u0448\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043e. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c \u0441 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439 \u0432 Home Assistant. \u0425\u043e\u0442\u0438\u0442\u0435 \u0435\u0433\u043e \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c?", + "description": "\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e {name} ({model}, {host}) \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043e. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c \u0441 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439 \u0432 Home Assistant. \u0425\u043e\u0442\u0438\u0442\u0435 \u0435\u0433\u043e \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c?", "title": "\u0420\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 (\u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e)" }, "user": { diff --git a/homeassistant/components/cloud/translations/pl.json b/homeassistant/components/cloud/translations/pl.json index b7f07c917b8..30aaeeb77d1 100644 --- a/homeassistant/components/cloud/translations/pl.json +++ b/homeassistant/components/cloud/translations/pl.json @@ -7,6 +7,9 @@ "can_reach_cloud_auth": "Dost\u0119p do serwera uwierzytelniania", "google_enabled": "Asystent Google w\u0142\u0105czony", "logged_in": "Zalogowany", + "relayer_connected": "Relayer pod\u0142\u0105czony", + "remote_connected": "Zdalny dost\u0119p pod\u0142\u0105czony", + "remote_enabled": "Zdalny dost\u0119p w\u0142\u0105czony", "subscription_expiration": "Wyga\u015bni\u0119cie subskrypcji" } } diff --git a/homeassistant/components/cloud/translations/ru.json b/homeassistant/components/cloud/translations/ru.json new file mode 100644 index 00000000000..b66e2ca51fa --- /dev/null +++ b/homeassistant/components/cloud/translations/ru.json @@ -0,0 +1,13 @@ +{ + "system_health": { + "info": { + "alexa_enabled": "\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 Alexa", + "can_reach_cert_server": "\u0414\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0432", + "can_reach_cloud": "\u0414\u043e\u0441\u0442\u0443\u043f \u043a Home Assistant Cloud", + "can_reach_cloud_auth": "\u0414\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438", + "google_enabled": "\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 Google", + "logged_in": "\u0412\u0445\u043e\u0434 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443", + "subscription_expiration": "\u0421\u0440\u043e\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438" + } + } +} \ No newline at end of file diff --git a/homeassistant/components/dsmr/translations/ru.json b/homeassistant/components/dsmr/translations/ru.json index 4ad85f691be..3bf0cf9f06f 100644 --- a/homeassistant/components/dsmr/translations/ru.json +++ b/homeassistant/components/dsmr/translations/ru.json @@ -3,5 +3,15 @@ "abort": { "already_configured": "\u042d\u0442\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0432 Home Assistant." } + }, + "options": { + "step": { + "init": { + "data": { + "time_between_update": "\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f (\u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445)" + }, + "title": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 DSMR" + } + } } } \ No newline at end of file diff --git a/homeassistant/components/hassio/translations/et.json b/homeassistant/components/hassio/translations/et.json index 981cb51c83a..9e5e776013f 100644 --- a/homeassistant/components/hassio/translations/et.json +++ b/homeassistant/components/hassio/translations/et.json @@ -1,3 +1,19 @@ { + "system_health": { + "info": { + "board": "Seade", + "disk_total": "Kettaruum kokku", + "disk_used": "Kasutatud kettaruum", + "docker_version": "Dockeri versioon", + "healthy": "Korras", + "host_os": "Host-i operatsioonis\u00fcsteem", + "installed_addons": "Paigaldatud lisandmoodulid", + "supervisor_api": "Superviisori API", + "supervisor_version": "Superviisori j\u00e4rk", + "supported": "Toetatud", + "update_channel": "V\u00e4rskenduskanal", + "version_api": "API versioon" + } + }, "title": "Hass.io" } \ No newline at end of file diff --git a/homeassistant/components/hassio/translations/no.json b/homeassistant/components/hassio/translations/no.json index d8a4c453015..2fb04f5156e 100644 --- a/homeassistant/components/hassio/translations/no.json +++ b/homeassistant/components/hassio/translations/no.json @@ -1,3 +1,19 @@ { + "system_health": { + "info": { + "board": "Styret", + "disk_total": "Disk totalt", + "disk_used": "Disk brukt", + "docker_version": "Docker-versjon", + "healthy": "Sunn", + "host_os": "Vertsoperativsystem", + "installed_addons": "Installerte tillegg", + "supervisor_api": "API for Supervisor", + "supervisor_version": "Supervisor versjon", + "supported": "St\u00f8ttet", + "update_channel": "Oppdater kanal", + "version_api": "Versjon API" + } + }, "title": "" } \ No newline at end of file diff --git a/homeassistant/components/hassio/translations/pl.json b/homeassistant/components/hassio/translations/pl.json index 981cb51c83a..10ee7c9d16c 100644 --- a/homeassistant/components/hassio/translations/pl.json +++ b/homeassistant/components/hassio/translations/pl.json @@ -1,3 +1,19 @@ { + "system_health": { + "info": { + "board": "Uk\u0142ad", + "disk_total": "Pojemno\u015b\u0107 dysku", + "disk_used": "Pojemno\u015b\u0107 u\u017cyta", + "docker_version": "Wersja Dockera", + "healthy": "Zdrowy", + "host_os": "System operacyjny hosta", + "installed_addons": "Zainstalowane dodatki", + "supervisor_api": "API Supervisora", + "supervisor_version": "Wersja Supervisora", + "supported": "Wspierany", + "update_channel": "Kana\u0142 aktualizacji", + "version_api": "Wersja API" + } + }, "title": "Hass.io" } \ No newline at end of file diff --git a/homeassistant/components/hassio/translations/ru.json b/homeassistant/components/hassio/translations/ru.json index 981cb51c83a..052e1ec21dd 100644 --- a/homeassistant/components/hassio/translations/ru.json +++ b/homeassistant/components/hassio/translations/ru.json @@ -1,3 +1,16 @@ { + "system_health": { + "info": { + "board": "\u041f\u043b\u0430\u0442\u0430", + "docker_version": "\u0412\u0435\u0440\u0441\u0438\u044f Docker", + "host_os": "\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0445\u043e\u0441\u0442\u0430", + "installed_addons": "\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f", + "supervisor_api": "Supervisor API", + "supervisor_version": "\u0412\u0435\u0440\u0441\u0438\u044f Supervisor", + "supported": "\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f", + "update_channel": "\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043a\u0430\u043d\u0430\u043b", + "version_api": "\u0412\u0435\u0440\u0441\u0438\u044f API" + } + }, "title": "Hass.io" } \ No newline at end of file diff --git a/homeassistant/components/homeassistant/translations/et.json b/homeassistant/components/homeassistant/translations/et.json index 3c355213899..7bdecd0178f 100644 --- a/homeassistant/components/homeassistant/translations/et.json +++ b/homeassistant/components/homeassistant/translations/et.json @@ -8,7 +8,7 @@ "docker_version": "Docker", "host_os": "Home Assistant OS", "installation_type": "Paigalduse t\u00fc\u00fcp", - "os_name": "Operatsioonis\u00fcsteemi nimi", + "os_name": "Operatsioonis\u00fcsteemi j\u00e4rk", "os_version": "Operatsioonis\u00fcsteemi versioon", "python_version": "Pythoni versioon", "supervisor": "Haldur", diff --git a/homeassistant/components/homeassistant/translations/no.json b/homeassistant/components/homeassistant/translations/no.json index 1962bba483a..72bba59116c 100644 --- a/homeassistant/components/homeassistant/translations/no.json +++ b/homeassistant/components/homeassistant/translations/no.json @@ -8,7 +8,7 @@ "docker_version": "", "host_os": "", "installation_type": "Installasjonstype", - "os_name": "Operativsystemnavn", + "os_name": "Familie for operativsystem", "os_version": "Operativsystemversjon", "python_version": "Python versjon", "supervisor": "", diff --git a/homeassistant/components/homeassistant/translations/pl.json b/homeassistant/components/homeassistant/translations/pl.json index 014657a9e3b..e65756cfc83 100644 --- a/homeassistant/components/homeassistant/translations/pl.json +++ b/homeassistant/components/homeassistant/translations/pl.json @@ -2,12 +2,13 @@ "system_health": { "info": { "arch": "Architektura procesora", - "dev": "Rozw\u00f3j", + "chassis": "Wersja komputera", + "dev": "Wersja rozwojowa", "docker": "Docker", "docker_version": "Wersja Dockera", - "host_os": "Home Assistant OS", + "host_os": "System operacyjny HA", "installation_type": "Typ instalacji", - "os_name": "Nazwa systemu operacyjnego", + "os_name": "Rodzina systemu operacyjnego", "os_version": "Wersja systemu operacyjnego", "python_version": "Wersja Pythona", "supervisor": "Supervisor", diff --git a/homeassistant/components/homeassistant/translations/ru.json b/homeassistant/components/homeassistant/translations/ru.json new file mode 100644 index 00000000000..76af5da7d13 --- /dev/null +++ b/homeassistant/components/homeassistant/translations/ru.json @@ -0,0 +1,20 @@ +{ + "system_health": { + "info": { + "arch": "\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0426\u041f", + "chassis": "\u0428\u0430\u0441\u0441\u0438", + "dev": "\u0421\u0440\u0435\u0434\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438", + "docker": "Docker", + "docker_version": "Docker", + "host_os": "Home Assistant OS", + "installation_type": "\u0422\u0438\u043f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438", + "os_name": "\u0421\u0435\u043c\u0435\u0439\u0441\u0442\u0432\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c", + "os_version": "\u0412\u0435\u0440\u0441\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b", + "python_version": "\u0412\u0435\u0440\u0441\u0438\u044f Python", + "supervisor": "Supervisor", + "timezone": "\u0427\u0430\u0441\u043e\u0432\u043e\u0439 \u043f\u043e\u044f\u0441", + "version": "\u0412\u0435\u0440\u0441\u0438\u044f", + "virtualenv": "\u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435" + } + } +} \ No newline at end of file diff --git a/homeassistant/components/locative/translations/ru.json b/homeassistant/components/locative/translations/ru.json index a255f7d158f..c9fc9cfd36a 100644 --- a/homeassistant/components/locative/translations/ru.json +++ b/homeassistant/components/locative/translations/ru.json @@ -9,7 +9,7 @@ }, "step": { "user": { - "description": "\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c Locative?", + "description": "\u0425\u043e\u0442\u0438\u0442\u0435 \u043d\u0430\u0447\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443?", "title": "Locative" } } diff --git a/homeassistant/components/lovelace/translations/ca.json b/homeassistant/components/lovelace/translations/ca.json index 65408175090..7d24e63c329 100644 --- a/homeassistant/components/lovelace/translations/ca.json +++ b/homeassistant/components/lovelace/translations/ca.json @@ -3,7 +3,8 @@ "info": { "dashboards": "Panells", "mode": "Mode", - "resources": "Recursos" + "resources": "Recursos", + "views": "Visualitzacions" } } } \ No newline at end of file diff --git a/homeassistant/components/lovelace/translations/cs.json b/homeassistant/components/lovelace/translations/cs.json index 32504fa14f4..5c4dc738c6c 100644 --- a/homeassistant/components/lovelace/translations/cs.json +++ b/homeassistant/components/lovelace/translations/cs.json @@ -3,7 +3,8 @@ "info": { "dashboards": "Dashboardy", "mode": "Re\u017eim", - "resources": "Zdroje" + "resources": "Zdroje", + "views": "Zobrazen\u00ed" } } } \ No newline at end of file diff --git a/homeassistant/components/lovelace/translations/en.json b/homeassistant/components/lovelace/translations/en.json index a1acdafac6a..53c919f51bc 100644 --- a/homeassistant/components/lovelace/translations/en.json +++ b/homeassistant/components/lovelace/translations/en.json @@ -3,7 +3,8 @@ "info": { "dashboards": "Dashboards", "mode": "Mode", - "resources": "Resources" + "resources": "Resources", + "views": "Views" } } } \ No newline at end of file diff --git a/homeassistant/components/lovelace/translations/et.json b/homeassistant/components/lovelace/translations/et.json index dcc16725ca3..15c253dd4d4 100644 --- a/homeassistant/components/lovelace/translations/et.json +++ b/homeassistant/components/lovelace/translations/et.json @@ -3,7 +3,8 @@ "info": { "dashboards": "Vaated", "mode": "Re\u017eiim", - "resources": "Ressursid" + "resources": "Ressursid", + "views": "Vaated" } } } \ No newline at end of file diff --git a/homeassistant/components/lovelace/translations/no.json b/homeassistant/components/lovelace/translations/no.json index 09b5322e061..d4b6d939561 100644 --- a/homeassistant/components/lovelace/translations/no.json +++ b/homeassistant/components/lovelace/translations/no.json @@ -3,7 +3,8 @@ "info": { "dashboards": "Dashboards", "mode": "Modus", - "resources": "Ressurser" + "resources": "Ressurser", + "views": "Visninger" } } } \ No newline at end of file diff --git a/homeassistant/components/lovelace/translations/ru.json b/homeassistant/components/lovelace/translations/ru.json new file mode 100644 index 00000000000..c677c4e7ece --- /dev/null +++ b/homeassistant/components/lovelace/translations/ru.json @@ -0,0 +1,9 @@ +{ + "system_health": { + "info": { + "dashboards": "\u041f\u0430\u043d\u0435\u043b\u0438", + "mode": "\u0420\u0435\u0436\u0438\u043c", + "resources": "\u0420\u0435\u0441\u0443\u0440\u0441\u044b" + } + } +} \ No newline at end of file diff --git a/homeassistant/components/recollect_waste/translations/ca.json b/homeassistant/components/recollect_waste/translations/ca.json new file mode 100644 index 00000000000..395fe5b9daa --- /dev/null +++ b/homeassistant/components/recollect_waste/translations/ca.json @@ -0,0 +1,18 @@ +{ + "config": { + "abort": { + "already_configured": "El dispositiu ja est\u00e0 configurat" + }, + "error": { + "invalid_place_or_service_id": "ID de lloc o de servei inv\u00e0lid" + }, + "step": { + "user": { + "data": { + "place_id": "ID de lloc", + "service_id": "ID de servei" + } + } + } + } +} \ No newline at end of file diff --git a/homeassistant/components/recollect_waste/translations/cs.json b/homeassistant/components/recollect_waste/translations/cs.json new file mode 100644 index 00000000000..57bdeaa80da --- /dev/null +++ b/homeassistant/components/recollect_waste/translations/cs.json @@ -0,0 +1,18 @@ +{ + "config": { + "abort": { + "already_configured": "Za\u0159\u00edzen\u00ed je ji\u017e nastaveno" + }, + "error": { + "invalid_place_or_service_id": "Neplatn\u00e9 m\u00edsto nebo ID slu\u017eby" + }, + "step": { + "user": { + "data": { + "place_id": "ID m\u00edsta", + "service_id": "ID slu\u017eby" + } + } + } + } +} \ No newline at end of file diff --git a/homeassistant/components/recollect_waste/translations/et.json b/homeassistant/components/recollect_waste/translations/et.json new file mode 100644 index 00000000000..e1402d12e42 --- /dev/null +++ b/homeassistant/components/recollect_waste/translations/et.json @@ -0,0 +1,18 @@ +{ + "config": { + "abort": { + "already_configured": "Seade on juba h\u00e4\u00e4lestatud" + }, + "error": { + "invalid_place_or_service_id": "Sobimatu asukoha v\u00f5i teenuse ID" + }, + "step": { + "user": { + "data": { + "place_id": "Asukoha ID", + "service_id": "Teenuse ID" + } + } + } + } +} \ No newline at end of file diff --git a/homeassistant/components/recollect_waste/translations/no.json b/homeassistant/components/recollect_waste/translations/no.json new file mode 100644 index 00000000000..6c4932505ba --- /dev/null +++ b/homeassistant/components/recollect_waste/translations/no.json @@ -0,0 +1,18 @@ +{ + "config": { + "abort": { + "already_configured": "Enheten er allerede konfigurert" + }, + "error": { + "invalid_place_or_service_id": "Ugyldig sted eller tjeneste ID" + }, + "step": { + "user": { + "data": { + "place_id": "Sted ID", + "service_id": "Tjeneste ID" + } + } + } + } +} \ No newline at end of file From c8a104d6028c9d9a3afcbffebcafb2c7a0025f42 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 13 Nov 2020 09:39:04 +0000 Subject: [PATCH 19/73] Bumped version to 0.118.0b1 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 8adf37bb817..7a5825560aa 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 118 -PATCH_VERSION = "0b0" +PATCH_VERSION = "0b1" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 1) From 239cc23b9b06c8a81012b8a30935a36dd4f8ad96 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 13 Nov 2020 10:40:51 +0100 Subject: [PATCH 20/73] Update translations --- .../components/aurora/translations/es.json | 26 +++++++++++++++++++ .../components/dsmr/translations/es.json | 10 +++++++ .../components/hassio/translations/es.json | 15 +++++++++++ .../homeassistant/translations/en.json | 3 ++- .../homeassistant/translations/es.json | 1 + .../components/lovelace/translations/es.json | 3 ++- .../components/lovelace/translations/pl.json | 3 ++- .../components/lovelace/translations/ru.json | 3 ++- .../recollect_waste/translations/es.json | 18 +++++++++++++ .../recollect_waste/translations/pl.json | 18 +++++++++++++ .../recollect_waste/translations/ru.json | 18 +++++++++++++ .../components/shelly/translations/pl.json | 4 +-- 12 files changed, 116 insertions(+), 6 deletions(-) create mode 100644 homeassistant/components/aurora/translations/es.json create mode 100644 homeassistant/components/recollect_waste/translations/es.json create mode 100644 homeassistant/components/recollect_waste/translations/pl.json create mode 100644 homeassistant/components/recollect_waste/translations/ru.json diff --git a/homeassistant/components/aurora/translations/es.json b/homeassistant/components/aurora/translations/es.json new file mode 100644 index 00000000000..c722c95ef6f --- /dev/null +++ b/homeassistant/components/aurora/translations/es.json @@ -0,0 +1,26 @@ +{ + "config": { + "error": { + "cannot_connect": "No se pudo conectar" + }, + "step": { + "user": { + "data": { + "latitude": "Latitud", + "longitude": "Longitud", + "name": "Nombre" + } + } + } + }, + "options": { + "step": { + "init": { + "data": { + "threshold": "Umbral (%)" + } + } + } + }, + "title": "Sensor Aurora NOAA" +} \ No newline at end of file diff --git a/homeassistant/components/dsmr/translations/es.json b/homeassistant/components/dsmr/translations/es.json index e8e23bf8343..364953d39d6 100644 --- a/homeassistant/components/dsmr/translations/es.json +++ b/homeassistant/components/dsmr/translations/es.json @@ -3,5 +3,15 @@ "abort": { "already_configured": "El dispositivo ya est\u00e1 configurado" } + }, + "options": { + "step": { + "init": { + "data": { + "time_between_update": "Tiempo m\u00ednimo entre actualizaciones de entidad [s]" + }, + "title": "Opciones DSMR" + } + } } } \ No newline at end of file diff --git a/homeassistant/components/hassio/translations/es.json b/homeassistant/components/hassio/translations/es.json index 981cb51c83a..4c8223f606b 100644 --- a/homeassistant/components/hassio/translations/es.json +++ b/homeassistant/components/hassio/translations/es.json @@ -1,3 +1,18 @@ { + "system_health": { + "info": { + "board": "Placa", + "disk_total": "Disco total", + "disk_used": "Disco usado", + "docker_version": "Versi\u00f3n de Docker", + "host_os": "Sistema operativo host", + "installed_addons": "Complementos instalados", + "supervisor_api": "API del Supervisor", + "supervisor_version": "Versi\u00f3n del Supervisor", + "supported": "Soportado", + "update_channel": "Actualizar canal", + "version_api": "Versi\u00f3n del API" + } + }, "title": "Hass.io" } \ No newline at end of file diff --git a/homeassistant/components/homeassistant/translations/en.json b/homeassistant/components/homeassistant/translations/en.json index 3eb1f91eefc..ee029772d21 100644 --- a/homeassistant/components/homeassistant/translations/en.json +++ b/homeassistant/components/homeassistant/translations/en.json @@ -6,6 +6,7 @@ "dev": "Development", "docker": "Docker", "docker_version": "Docker", + "hassio": "Supervisor", "host_os": "Home Assistant OS", "installation_type": "Installation Type", "os_name": "Operating System Family", @@ -17,4 +18,4 @@ "virtualenv": "Virtual Environment" } } -} \ No newline at end of file +} diff --git a/homeassistant/components/homeassistant/translations/es.json b/homeassistant/components/homeassistant/translations/es.json index 13d1c5edcde..1829d16d510 100644 --- a/homeassistant/components/homeassistant/translations/es.json +++ b/homeassistant/components/homeassistant/translations/es.json @@ -6,6 +6,7 @@ "dev": "Desarrollo", "docker": "Docker", "docker_version": "Docker", + "hassio": "Supervisor", "host_os": "SO Home Assistant", "installation_type": "Tipo de instalaci\u00f3n", "os_name": "Nombre del Sistema Operativo", diff --git a/homeassistant/components/lovelace/translations/es.json b/homeassistant/components/lovelace/translations/es.json index 108d4f881f0..575610c96e0 100644 --- a/homeassistant/components/lovelace/translations/es.json +++ b/homeassistant/components/lovelace/translations/es.json @@ -3,7 +3,8 @@ "info": { "dashboards": "Paneles de control", "mode": "Modo", - "resources": "Recursos" + "resources": "Recursos", + "views": "Vistas" } } } \ No newline at end of file diff --git a/homeassistant/components/lovelace/translations/pl.json b/homeassistant/components/lovelace/translations/pl.json index 62f000982ea..3c87f145220 100644 --- a/homeassistant/components/lovelace/translations/pl.json +++ b/homeassistant/components/lovelace/translations/pl.json @@ -3,7 +3,8 @@ "info": { "dashboards": "Dashboardy", "mode": "Tryb", - "resources": "Zasoby" + "resources": "Zasoby", + "views": "Widoki" } } } \ No newline at end of file diff --git a/homeassistant/components/lovelace/translations/ru.json b/homeassistant/components/lovelace/translations/ru.json index c677c4e7ece..856237d9b1f 100644 --- a/homeassistant/components/lovelace/translations/ru.json +++ b/homeassistant/components/lovelace/translations/ru.json @@ -3,7 +3,8 @@ "info": { "dashboards": "\u041f\u0430\u043d\u0435\u043b\u0438", "mode": "\u0420\u0435\u0436\u0438\u043c", - "resources": "\u0420\u0435\u0441\u0443\u0440\u0441\u044b" + "resources": "\u0420\u0435\u0441\u0443\u0440\u0441\u044b", + "views": "\u0412\u043a\u043b\u0430\u0434\u043a\u0438" } } } \ No newline at end of file diff --git a/homeassistant/components/recollect_waste/translations/es.json b/homeassistant/components/recollect_waste/translations/es.json new file mode 100644 index 00000000000..5771c9da9a9 --- /dev/null +++ b/homeassistant/components/recollect_waste/translations/es.json @@ -0,0 +1,18 @@ +{ + "config": { + "abort": { + "already_configured": "El dispositivo ya est\u00e1 configurado" + }, + "error": { + "invalid_place_or_service_id": "ID de servicio o lugar no v\u00e1lidos" + }, + "step": { + "user": { + "data": { + "place_id": "ID de lugar", + "service_id": "ID de servicio" + } + } + } + } +} \ No newline at end of file diff --git a/homeassistant/components/recollect_waste/translations/pl.json b/homeassistant/components/recollect_waste/translations/pl.json new file mode 100644 index 00000000000..013d0028790 --- /dev/null +++ b/homeassistant/components/recollect_waste/translations/pl.json @@ -0,0 +1,18 @@ +{ + "config": { + "abort": { + "already_configured": "Urz\u0105dzenie jest ju\u017c skonfigurowane" + }, + "error": { + "invalid_place_or_service_id": "Nieprawid\u0142owy identyfikator \"Place\" lub \"Service\"" + }, + "step": { + "user": { + "data": { + "place_id": "Identyfikator \"Place\" (place_id)", + "service_id": "Identyfikator \"Service\" (service_id)" + } + } + } + } +} \ No newline at end of file diff --git a/homeassistant/components/recollect_waste/translations/ru.json b/homeassistant/components/recollect_waste/translations/ru.json new file mode 100644 index 00000000000..21e926ec9e1 --- /dev/null +++ b/homeassistant/components/recollect_waste/translations/ru.json @@ -0,0 +1,18 @@ +{ + "config": { + "abort": { + "already_configured": "\u042d\u0442\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0432 Home Assistant." + }, + "error": { + "invalid_place_or_service_id": "\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 ID \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u0441\u043b\u0443\u0436\u0431\u044b." + }, + "step": { + "user": { + "data": { + "place_id": "ID \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f", + "service_id": "ID \u0441\u043b\u0443\u0436\u0431\u044b" + } + } + } + } +} \ No newline at end of file diff --git a/homeassistant/components/shelly/translations/pl.json b/homeassistant/components/shelly/translations/pl.json index 4021ac79772..ebf6041d4ba 100644 --- a/homeassistant/components/shelly/translations/pl.json +++ b/homeassistant/components/shelly/translations/pl.json @@ -12,7 +12,7 @@ "flow_title": "{name}", "step": { "confirm_discovery": { - "description": "Czy chcesz skonfigurowa\u0107 {model} ({host})?\n\nPrzed konfiguracj\u0105, urz\u0105dzenia zasilane bateryjnie nale\u017cy wybudzi\u0107, naciskaj\u0105c przycisk na urz\u0105dzeniu." + "description": "Czy chcesz skonfigurowa\u0107 {model} ({host})?\n\nPrzed skonfigurowaniem urz\u0105dzenia zasilane bateryjnie nale\u017cy, wybudzi\u0107 naciskaj\u0105c przycisk na urz\u0105dzeniu." }, "credentials": { "data": { @@ -24,7 +24,7 @@ "data": { "host": "Nazwa hosta lub adres IP" }, - "description": "Przed konfiguracj\u0105, urz\u0105dzenia zasilane bateryjnie nale\u017cy wybudzi\u0107, naciskaj\u0105c przycisk na urz\u0105dzeniu." + "description": "Przed skonfigurowaniem urz\u0105dzenia zasilane bateryjnie nale\u017cy, wybudzi\u0107 naciskaj\u0105c przycisk na urz\u0105dzeniu." } } } From 33d5e7930187e89021edeba9df91496a2bda3caa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20RAMAGE?= Date: Fri, 13 Nov 2020 14:35:41 +0100 Subject: [PATCH 21/73] update zigpy_zigate to v0.7.1 (#43159) --- homeassistant/components/zha/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/zha/manifest.json b/homeassistant/components/zha/manifest.json index aedb6126559..0a42b6b357e 100644 --- a/homeassistant/components/zha/manifest.json +++ b/homeassistant/components/zha/manifest.json @@ -11,7 +11,7 @@ "zigpy-deconz==0.11.0", "zigpy==0.27.0", "zigpy-xbee==0.13.0", - "zigpy-zigate==0.7.0", + "zigpy-zigate==0.7.1", "zigpy-znp==0.2.2" ], "codeowners": ["@dmulcahey", "@adminiuga"] diff --git a/requirements_all.txt b/requirements_all.txt index 4617e66fd97..8e13477dfe5 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2353,7 +2353,7 @@ zigpy-deconz==0.11.0 zigpy-xbee==0.13.0 # homeassistant.components.zha -zigpy-zigate==0.7.0 +zigpy-zigate==0.7.1 # homeassistant.components.zha zigpy-znp==0.2.2 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index c6c76947778..1f11b65ccda 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1131,7 +1131,7 @@ zigpy-deconz==0.11.0 zigpy-xbee==0.13.0 # homeassistant.components.zha -zigpy-zigate==0.7.0 +zigpy-zigate==0.7.1 # homeassistant.components.zha zigpy-znp==0.2.2 From 39493fd3eaa6d80680ab5b01e8e663c9f11e4866 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 13 Nov 2020 16:03:08 +0100 Subject: [PATCH 22/73] Prevent spider from doing I/O in the event loop (#43182) --- homeassistant/components/spider/__init__.py | 27 ++++++++++----------- homeassistant/components/spider/climate.py | 9 ++++--- homeassistant/components/spider/switch.py | 10 +++++--- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/homeassistant/components/spider/__init__.py b/homeassistant/components/spider/__init__.py index f2e9a06fb94..b0c34ae5a08 100644 --- a/homeassistant/components/spider/__init__.py +++ b/homeassistant/components/spider/__init__.py @@ -2,11 +2,12 @@ import asyncio import logging -from spiderpy.spiderapi import SpiderApi, UnauthorizedException +from spiderpy.spiderapi import SpiderApi, SpiderApiException, UnauthorizedException import voluptuous as vol from homeassistant.config_entries import SOURCE_IMPORT from homeassistant.const import CONF_PASSWORD, CONF_SCAN_INTERVAL, CONF_USERNAME +from homeassistant.exceptions import ConfigEntryNotReady import homeassistant.helpers.config_validation as cv from .const import DEFAULT_SCAN_INTERVAL, DOMAIN, PLATFORMS @@ -29,16 +30,6 @@ CONFIG_SCHEMA = vol.Schema( ) -def _spider_startup_wrapper(entry): - """Startup wrapper for spider.""" - api = SpiderApi( - entry.data[CONF_USERNAME], - entry.data[CONF_PASSWORD], - entry.data[CONF_SCAN_INTERVAL], - ) - return api - - async def async_setup(hass, config): """Set up a config entry.""" hass.data[DOMAIN] = {} @@ -60,12 +51,20 @@ async def async_setup(hass, config): async def async_setup_entry(hass, entry): """Set up Spider via config entry.""" try: - hass.data[DOMAIN][entry.entry_id] = await hass.async_add_executor_job( - _spider_startup_wrapper, entry + api = await hass.async_add_executor_job( + SpiderApi, + entry.data[CONF_USERNAME], + entry.data[CONF_PASSWORD], + entry.data[CONF_SCAN_INTERVAL], ) except UnauthorizedException: - _LOGGER.error("Can't connect to the Spider API") + _LOGGER.error("Authorization failed") return False + except SpiderApiException as err: + _LOGGER.error("Can't connect to the Spider API: %s", err) + raise ConfigEntryNotReady from err + + hass.data[DOMAIN][entry.entry_id] = api for component in PLATFORMS: hass.async_create_task( diff --git a/homeassistant/components/spider/climate.py b/homeassistant/components/spider/climate.py index 234ae699bca..7730d8b34c4 100644 --- a/homeassistant/components/spider/climate.py +++ b/homeassistant/components/spider/climate.py @@ -28,9 +28,12 @@ async def async_setup_entry(hass, config, async_add_entities): """Initialize a Spider thermostat.""" api = hass.data[DOMAIN][config.entry_id] - entities = [SpiderThermostat(api, entity) for entity in api.get_thermostats()] - - async_add_entities(entities) + async_add_entities( + [ + SpiderThermostat(api, entity) + for entity in await hass.async_add_executor_job(api.get_thermostats) + ] + ) class SpiderThermostat(ClimateEntity): diff --git a/homeassistant/components/spider/switch.py b/homeassistant/components/spider/switch.py index 62f220bf805..1b0c86468ea 100644 --- a/homeassistant/components/spider/switch.py +++ b/homeassistant/components/spider/switch.py @@ -7,10 +7,12 @@ from .const import DOMAIN async def async_setup_entry(hass, config, async_add_entities): """Initialize a Spider thermostat.""" api = hass.data[DOMAIN][config.entry_id] - - entities = [SpiderPowerPlug(api, entity) for entity in api.get_power_plugs()] - - async_add_entities(entities) + async_add_entities( + [ + SpiderPowerPlug(api, entity) + for entity in await hass.async_add_executor_job(api.get_power_plugs) + ] + ) class SpiderPowerPlug(SwitchEntity): From 62e6a86432d8ff9db673b6ba8554e9ff690cb180 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 13 Nov 2020 15:52:15 +0100 Subject: [PATCH 23/73] Revert opensky flight latitude and longitude (#43185) This reverts commit 0f46916f9efec5832423ea7db8e477e34c1038d6. --- homeassistant/components/opensky/sensor.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/homeassistant/components/opensky/sensor.py b/homeassistant/components/opensky/sensor.py index c9a863f86ab..49edf8e7d0a 100644 --- a/homeassistant/components/opensky/sensor.py +++ b/homeassistant/components/opensky/sensor.py @@ -125,8 +125,6 @@ class OpenSkySensor(Entity): ATTR_CALLSIGN: flight, ATTR_ALTITUDE: altitude, ATTR_SENSOR: self._name, - ATTR_LONGITUDE: flight.get(ATTR_LONGITUDE), - ATTR_LATITUDE: flight.get(ATTR_LATITUDE), } self._hass.bus.fire(event, data) From a24263fc3027e2fa332f950e6c2aff30a5d134dc Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Fri, 13 Nov 2020 22:37:09 -0800 Subject: [PATCH 24/73] Catch the right nest stream refresh exception error (#43189) --- homeassistant/components/nest/camera_sdm.py | 4 ++-- tests/components/nest/camera_sdm_test.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/nest/camera_sdm.py b/homeassistant/components/nest/camera_sdm.py index ad4293fde5d..a8c5c86c4e8 100644 --- a/homeassistant/components/nest/camera_sdm.py +++ b/homeassistant/components/nest/camera_sdm.py @@ -4,10 +4,10 @@ import datetime import logging from typing import Optional +from aiohttp.client_exceptions import ClientError from google_nest_sdm.camera_traits import CameraImageTrait, CameraLiveStreamTrait from google_nest_sdm.device import Device from haffmpeg.tools import IMAGE_JPEG -import requests from homeassistant.components.camera import SUPPORT_STREAM, Camera from homeassistant.components.ffmpeg import async_get_image @@ -130,7 +130,7 @@ class NestCamera(Camera): self._stream_refresh_unsub = None try: self._stream = await self._stream.extend_rtsp_stream() - except requests.HTTPError as err: + except ClientError as err: _LOGGER.debug("Failed to extend stream: %s", err) # Next attempt to catch a url will get a new one self._stream = None diff --git a/tests/components/nest/camera_sdm_test.py b/tests/components/nest/camera_sdm_test.py index 40972d04351..e3397129ec9 100644 --- a/tests/components/nest/camera_sdm_test.py +++ b/tests/components/nest/camera_sdm_test.py @@ -8,9 +8,9 @@ pubsub subscriber. import datetime from typing import List +from aiohttp.client_exceptions import ClientConnectionError from google_nest_sdm.auth import AbstractAuth from google_nest_sdm.device import Device -from requests import HTTPError from homeassistant.components import camera from homeassistant.components.camera import STATE_IDLE @@ -315,8 +315,8 @@ async def test_refresh_expired_stream_failure(hass, aiohttp_client): }, } ), - # Extending the stream fails - FakeResponse(error=HTTPError(response="Some Error")), + # Extending the stream fails with arbitrary error + FakeResponse(error=ClientConnectionError()), # Next attempt to get a stream fetches a new url FakeResponse( { From c434afae2eaf55c5123744bde058518c2bed580f Mon Sep 17 00:00:00 2001 From: Aaron Bach Date: Fri, 13 Nov 2020 16:04:34 -0700 Subject: [PATCH 25/73] Revert "Remove YAML config for Tile (#43064)" (#43199) This reverts commit 19f48e180c7e6a34bd93d7a849147a8de491771c. --- homeassistant/components/tile/config_flow.py | 28 +++++++++----- .../components/tile/device_tracker.py | 26 ++++++++++++- tests/components/tile/test_config_flow.py | 38 +++++++++++++++++-- 3 files changed, 77 insertions(+), 15 deletions(-) diff --git a/homeassistant/components/tile/config_flow.py b/homeassistant/components/tile/config_flow.py index 932c948defe..87f58193e9d 100644 --- a/homeassistant/components/tile/config_flow.py +++ b/homeassistant/components/tile/config_flow.py @@ -9,10 +9,6 @@ from homeassistant.helpers import aiohttp_client from .const import DOMAIN # pylint: disable=unused-import -DATA_SCHEMA = vol.Schema( - {vol.Required(CONF_USERNAME): str, vol.Required(CONF_PASSWORD): str} -) - class TileFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): """Handle a Tile config flow.""" @@ -20,10 +16,26 @@ class TileFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): VERSION = 1 CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL + def __init__(self): + """Initialize the config flow.""" + self.data_schema = vol.Schema( + {vol.Required(CONF_USERNAME): str, vol.Required(CONF_PASSWORD): str} + ) + + async def _show_form(self, errors=None): + """Show the form to the user.""" + return self.async_show_form( + step_id="user", data_schema=self.data_schema, errors=errors or {} + ) + + 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.""" if not user_input: - return self.async_show_form(step_id="user", data_schema=DATA_SCHEMA) + return await self._show_form() await self.async_set_unique_id(user_input[CONF_USERNAME]) self._abort_if_unique_id_configured() @@ -35,10 +47,6 @@ class TileFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): user_input[CONF_USERNAME], user_input[CONF_PASSWORD], session=session ) except TileError: - return self.async_show_form( - step_id="user", - data_schema=DATA_SCHEMA, - errors={"base": "invalid_auth"}, - ) + return await self._show_form({"base": "invalid_auth"}) return self.async_create_entry(title=user_input[CONF_USERNAME], data=user_input) diff --git a/homeassistant/components/tile/device_tracker.py b/homeassistant/components/tile/device_tracker.py index 286ffa98869..5b0065b2c4e 100644 --- a/homeassistant/components/tile/device_tracker.py +++ b/homeassistant/components/tile/device_tracker.py @@ -3,6 +3,8 @@ import logging from homeassistant.components.device_tracker.config_entry import TrackerEntity from homeassistant.components.device_tracker.const import SOURCE_TYPE_GPS +from homeassistant.config_entries import SOURCE_IMPORT +from homeassistant.const import CONF_PASSWORD, CONF_USERNAME from homeassistant.core import callback from . import DATA_COORDINATOR, DOMAIN, TileEntity @@ -26,10 +28,32 @@ async def async_setup_entry(hass, config_entry, async_add_entities): [ TileDeviceTracker(coordinator, tile_uuid, tile) for tile_uuid, tile in coordinator.data.items() - ] + ], + True, ) +async def async_setup_scanner(hass, config, async_see, discovery_info=None): + """Detect a legacy configuration and import it.""" + hass.async_create_task( + hass.config_entries.flow.async_init( + DOMAIN, + context={"source": SOURCE_IMPORT}, + data={ + CONF_USERNAME: config[CONF_USERNAME], + CONF_PASSWORD: config[CONF_PASSWORD], + }, + ) + ) + + _LOGGER.info( + "Your Tile configuration has been imported into the UI; " + "please remove it from configuration.yaml" + ) + + return True + + class TileDeviceTracker(TileEntity, TrackerEntity): """Representation of a network infrastructure device.""" diff --git a/tests/components/tile/test_config_flow.py b/tests/components/tile/test_config_flow.py index edb95cc5b05..b9d4799dc2f 100644 --- a/tests/components/tile/test_config_flow.py +++ b/tests/components/tile/test_config_flow.py @@ -3,7 +3,7 @@ from pytile.errors import TileError from homeassistant import data_entry_flow from homeassistant.components.tile import DOMAIN -from homeassistant.config_entries import SOURCE_USER +from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_USER from homeassistant.const import CONF_PASSWORD, CONF_USERNAME from tests.async_mock import patch @@ -12,7 +12,10 @@ from tests.common import MockConfigEntry async def test_duplicate_error(hass): """Test that errors are shown when duplicates are added.""" - conf = {CONF_USERNAME: "user@host.com", CONF_PASSWORD: "123abc"} + conf = { + CONF_USERNAME: "user@host.com", + CONF_PASSWORD: "123abc", + } MockConfigEntry(domain=DOMAIN, unique_id="user@host.com", data=conf).add_to_hass( hass @@ -28,7 +31,10 @@ async def test_duplicate_error(hass): async def test_invalid_credentials(hass): """Test that invalid credentials key throws an error.""" - conf = {CONF_USERNAME: "user@host.com", CONF_PASSWORD: "123abc"} + conf = { + CONF_USERNAME: "user@host.com", + CONF_PASSWORD: "123abc", + } with patch( "homeassistant.components.tile.config_flow.async_login", @@ -41,9 +47,33 @@ async def test_invalid_credentials(hass): assert result["errors"] == {"base": "invalid_auth"} +async def test_step_import(hass): + """Test that the import step works.""" + conf = { + CONF_USERNAME: "user@host.com", + CONF_PASSWORD: "123abc", + } + + with patch( + "homeassistant.components.tile.async_setup_entry", return_value=True + ), patch("homeassistant.components.tile.config_flow.async_login"): + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_IMPORT}, data=conf + ) + assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY + assert result["title"] == "user@host.com" + assert result["data"] == { + CONF_USERNAME: "user@host.com", + CONF_PASSWORD: "123abc", + } + + async def test_step_user(hass): """Test that the user step works.""" - conf = {CONF_USERNAME: "user@host.com", CONF_PASSWORD: "123abc"} + conf = { + CONF_USERNAME: "user@host.com", + CONF_PASSWORD: "123abc", + } with patch( "homeassistant.components.tile.async_setup_entry", return_value=True From d24b74417a6a244a51fa8235f2df809991f547ea Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 14 Nov 2020 00:12:00 -1000 Subject: [PATCH 26/73] Fix typo in lw12wifi shoud_poll (#43213) --- homeassistant/components/lw12wifi/light.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/lw12wifi/light.py b/homeassistant/components/lw12wifi/light.py index 907e6b898d6..4b8fb2e9ee0 100644 --- a/homeassistant/components/lw12wifi/light.py +++ b/homeassistant/components/lw12wifi/light.py @@ -113,7 +113,7 @@ class LW12WiFi(LightEntity): return True @property - def shoud_poll(self) -> bool: + def should_poll(self) -> bool: """Return False to not poll the state of this entity.""" return False From bd6c63cae754d8a376d6f781ed57d5cd9e074bd7 Mon Sep 17 00:00:00 2001 From: Glenn Waters Date: Sat, 14 Nov 2020 12:13:37 -0500 Subject: [PATCH 27/73] Bump elkm1-lib to 0.8.8 (#43230) --- homeassistant/components/elkm1/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/elkm1/manifest.json b/homeassistant/components/elkm1/manifest.json index 1875ce4e970..769e5c37dd7 100644 --- a/homeassistant/components/elkm1/manifest.json +++ b/homeassistant/components/elkm1/manifest.json @@ -2,7 +2,7 @@ "domain": "elkm1", "name": "Elk-M1 Control", "documentation": "https://www.home-assistant.io/integrations/elkm1", - "requirements": ["elkm1-lib==0.8.7"], + "requirements": ["elkm1-lib==0.8.8"], "codeowners": ["@gwww", "@bdraco"], "config_flow": true } diff --git a/requirements_all.txt b/requirements_all.txt index 8e13477dfe5..67b38e1ce7c 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -541,7 +541,7 @@ elgato==0.2.0 eliqonline==1.2.2 # homeassistant.components.elkm1 -elkm1-lib==0.8.7 +elkm1-lib==0.8.8 # homeassistant.components.mobile_app emoji==0.5.4 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 1f11b65ccda..f23c831b430 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -281,7 +281,7 @@ eebrightbox==0.0.4 elgato==0.2.0 # homeassistant.components.elkm1 -elkm1-lib==0.8.7 +elkm1-lib==0.8.8 # homeassistant.components.mobile_app emoji==0.5.4 From 058733ae796ac2823f4ac6d1003bd7b6bea9c3f0 Mon Sep 17 00:00:00 2001 From: michaeldavie Date: Sat, 14 Nov 2020 15:16:14 -0500 Subject: [PATCH 28/73] Remove OpenCV dependecy from Environment Canada (#43235) * Bump env_canada to 0.2.2 * Revert PR #38731 --- homeassistant/components/environment_canada/manifest.json | 2 +- requirements_all.txt | 2 +- script/gen_requirements_all.py | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/environment_canada/manifest.json b/homeassistant/components/environment_canada/manifest.json index f89a7eb3e55..c605e92acd5 100644 --- a/homeassistant/components/environment_canada/manifest.json +++ b/homeassistant/components/environment_canada/manifest.json @@ -2,6 +2,6 @@ "domain": "environment_canada", "name": "Environment Canada", "documentation": "https://www.home-assistant.io/integrations/environment_canada", - "requirements": ["env_canada==0.2.0"], + "requirements": ["env_canada==0.2.2"], "codeowners": ["@michaeldavie"] } diff --git a/requirements_all.txt b/requirements_all.txt index 67b38e1ce7c..928920dc0c3 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -556,7 +556,7 @@ enocean==0.50 enturclient==0.2.1 # homeassistant.components.environment_canada -# env_canada==0.2.0 +env_canada==0.2.2 # homeassistant.components.envirophat # envirophat==0.0.6 diff --git a/script/gen_requirements_all.py b/script/gen_requirements_all.py index c3e489c1ebb..f627346c67b 100755 --- a/script/gen_requirements_all.py +++ b/script/gen_requirements_all.py @@ -24,7 +24,6 @@ COMMENT_REQUIREMENTS = ( "credstash", "decora", "decora_wifi", - "env_canada", "envirophat", "evdev", "face_recognition", From ec357081af358e48d76f1591d5fefded90ad5164 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 14 Nov 2020 21:07:16 +0000 Subject: [PATCH 29/73] Bumped version to 0.118.0b2 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 7a5825560aa..05b780ab3ec 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 118 -PATCH_VERSION = "0b1" +PATCH_VERSION = "0b2" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 1) From e7e167646893549c151efe100a75bff2ec8336aa Mon Sep 17 00:00:00 2001 From: uvjustin <46082645+uvjustin@users.noreply.github.com> Date: Tue, 17 Nov 2020 04:13:33 +0800 Subject: [PATCH 30/73] Remove pts adjustments in stream (#42399) * Remove unnecessary pts adjustments * Add comments * Use -inf for initial last_dts to be more clear * Use video first_pts as common adjuster in recorder * Remove seek(0) before av.open --- homeassistant/components/stream/recorder.py | 30 ++++++--- homeassistant/components/stream/worker.py | 72 +++++++++------------ 2 files changed, 50 insertions(+), 52 deletions(-) diff --git a/homeassistant/components/stream/recorder.py b/homeassistant/components/stream/recorder.py index d0b8789f602..420e7c654c5 100644 --- a/homeassistant/components/stream/recorder.py +++ b/homeassistant/components/stream/recorder.py @@ -25,12 +25,23 @@ def recorder_save_worker(file_out: str, segments: List[Segment], container_forma output_v = None output_a = None - for segment in segments: - # Seek to beginning and open segment - segment.segment.seek(0) + # Get first_pts values from first segment + if len(segments) > 0: + segment = segments[0] source = av.open(segment.segment, "r", format=container_format) source_v = source.streams.video[0] + first_pts["video"] = source_v.start_time + if len(source.streams.audio) > 0: + source_a = source.streams.audio[0] + first_pts["audio"] = int( + source_v.start_time * source_v.time_base / source_a.time_base + ) + source.close() + for segment in segments: + # Open segment + source = av.open(segment.segment, "r", format=container_format) + source_v = source.streams.video[0] # Add output streams if not output_v: output_v = output.add_stream(template=source_v) @@ -42,13 +53,12 @@ def recorder_save_worker(file_out: str, segments: List[Segment], container_forma # Remux video for packet in source.demux(): - if packet is not None and packet.dts is not None: - if first_pts[packet.stream.type] is None: - first_pts[packet.stream.type] = packet.pts - packet.pts -= first_pts[packet.stream.type] - packet.dts -= first_pts[packet.stream.type] - packet.stream = output_v if packet.stream.type == "video" else output_a - output.mux(packet) + if packet.dts is None: + continue + packet.pts -= first_pts[packet.stream.type] + packet.dts -= first_pts[packet.stream.type] + packet.stream = output_v if packet.stream.type == "video" else output_a + output.mux(packet) source.close() diff --git a/homeassistant/components/stream/worker.py b/homeassistant/components/stream/worker.py index aa6a5d350a9..68cbbc79726 100644 --- a/homeassistant/components/stream/worker.py +++ b/homeassistant/components/stream/worker.py @@ -102,11 +102,8 @@ def _stream_worker_internal(hass, stream, quit_event): # Iterator for demuxing container_packets = None - # The presentation timestamps of the first packet in each stream we receive - # Use to adjust before muxing or outputting, but we don't adjust internally - first_pts = {} # The decoder timestamps of the latest packet in each stream we processed - last_dts = None + last_dts = {video_stream: float("-inf"), audio_stream: float("-inf")} # Keep track of consecutive packets without a dts to detect end of stream. missing_dts = 0 # Holds the buffers for each stream provider @@ -123,21 +120,19 @@ def _stream_worker_internal(hass, stream, quit_event): # 2 - seeking can be problematic https://trac.ffmpeg.org/ticket/7815 def peek_first_pts(): - nonlocal first_pts, audio_stream, container_packets + """Initialize by peeking into the first few packets of the stream. + + Deal with problem #1 above (bad first packet pts/dts) by recalculating using pts/dts from second packet. + Also load the first video keyframe pts into segment_start_pts and check if the audio stream really exists. + """ + nonlocal segment_start_pts, audio_stream, container_packets missing_dts = 0 - - def empty_stream_dict(): - return { - video_stream: None, - **({audio_stream: None} if audio_stream else {}), - } - + found_audio = False try: container_packets = container.demux((video_stream, audio_stream)) - first_packet = empty_stream_dict() - first_pts = empty_stream_dict() + first_packet = None # Get to first video keyframe - while first_packet[video_stream] is None: + while first_packet is None: packet = next(container_packets) if ( packet.dts is None @@ -148,13 +143,17 @@ def _stream_worker_internal(hass, stream, quit_event): ) missing_dts += 1 continue - if packet.stream == video_stream and packet.is_keyframe: - first_packet[video_stream] = packet + if packet.stream == audio_stream: + found_audio = True + elif packet.is_keyframe: # video_keyframe + first_packet = packet initial_packets.append(packet) # Get first_pts from subsequent frame to first keyframe - while any( - [pts is None for pts in {**first_packet, **first_pts}.values()] - ) and (len(initial_packets) < PACKETS_TO_WAIT_FOR_AUDIO): + while segment_start_pts is None or ( + audio_stream + and not found_audio + and len(initial_packets) < PACKETS_TO_WAIT_FOR_AUDIO + ): packet = next(container_packets) if ( packet.dts is None @@ -165,24 +164,19 @@ def _stream_worker_internal(hass, stream, quit_event): ) missing_dts += 1 continue - if ( - first_packet[packet.stream] is None - ): # actually video already found above so only for audio - if packet.is_keyframe: - first_packet[packet.stream] = packet - else: # Discard leading non-keyframes - continue - else: # This is the second frame to calculate first_pts from - if first_pts[packet.stream] is None: - first_pts[packet.stream] = packet.dts - packet.duration - first_packet[packet.stream].pts = first_pts[packet.stream] - first_packet[packet.stream].dts = first_pts[packet.stream] + if packet.stream == audio_stream: + found_audio = True + elif ( + segment_start_pts is None + ): # This is the second video frame to calculate first_pts from + segment_start_pts = packet.dts - packet.duration + first_packet.pts = segment_start_pts + first_packet.dts = segment_start_pts initial_packets.append(packet) - if audio_stream and first_packet[audio_stream] is None: + if audio_stream and not found_audio: _LOGGER.warning( "Audio stream not found" ) # Some streams declare an audio stream and never send any packets - del first_pts[audio_stream] audio_stream = None except (av.AVError, StopIteration) as ex: @@ -212,9 +206,6 @@ def _stream_worker_internal(hass, stream, quit_event): ) def mux_video_packet(packet): - # adjust pts and dts before muxing - packet.pts -= first_pts[video_stream] - packet.dts -= first_pts[video_stream] # mux packets to each buffer for buffer, output_streams in outputs.values(): # Assign the packet to the new stream & mux @@ -223,9 +214,6 @@ def _stream_worker_internal(hass, stream, quit_event): def mux_audio_packet(packet): # almost the same as muxing video but add extra check - # adjust pts and dts before muxing - packet.pts -= first_pts[audio_stream] - packet.dts -= first_pts[audio_stream] for buffer, output_streams in outputs.values(): # Assign the packet to the new stream & mux if output_streams.get(audio_stream): @@ -241,8 +229,8 @@ def _stream_worker_internal(hass, stream, quit_event): if not peek_first_pts(): container.close() return - last_dts = {k: v - 1 for k, v in first_pts.items()} - initialize_segment(first_pts[video_stream]) + + initialize_segment(segment_start_pts) while not quit_event.is_set(): try: From 72a68bbf9c7565876c35dc38b1218c04a87769dd Mon Sep 17 00:00:00 2001 From: Martin Hjelmare Date: Thu, 12 Nov 2020 20:15:31 +0100 Subject: [PATCH 31/73] Bump hass-nabucasa to 0.37.2 (#43146) --- homeassistant/components/cloud/manifest.json | 2 +- homeassistant/package_constraints.txt | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/cloud/manifest.json b/homeassistant/components/cloud/manifest.json index 81986a3cf6d..f3c79a470ea 100644 --- a/homeassistant/components/cloud/manifest.json +++ b/homeassistant/components/cloud/manifest.json @@ -2,7 +2,7 @@ "domain": "cloud", "name": "Home Assistant Cloud", "documentation": "https://www.home-assistant.io/integrations/cloud", - "requirements": ["hass-nabucasa==0.37.1"], + "requirements": ["hass-nabucasa==0.37.2"], "dependencies": ["http", "webhook", "alexa"], "after_dependencies": ["google_assistant"], "codeowners": ["@home-assistant/cloud"] diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index 2feef83095d..0fb7dcd3274 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -12,7 +12,7 @@ cryptography==3.2 defusedxml==0.6.0 distro==1.5.0 emoji==0.5.4 -hass-nabucasa==0.37.1 +hass-nabucasa==0.37.2 home-assistant-frontend==20201111.0 httpx==0.16.1 importlib-metadata==1.6.0;python_version<'3.8' diff --git a/requirements_all.txt b/requirements_all.txt index 928920dc0c3..978c2233864 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -735,7 +735,7 @@ habitipy==0.2.0 hangups==0.4.11 # homeassistant.components.cloud -hass-nabucasa==0.37.1 +hass-nabucasa==0.37.2 # homeassistant.components.splunk hass_splunk==0.1.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index f23c831b430..557c4b963ce 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -373,7 +373,7 @@ ha-ffmpeg==2.0 hangups==0.4.11 # homeassistant.components.cloud -hass-nabucasa==0.37.1 +hass-nabucasa==0.37.2 # homeassistant.components.tasmota hatasmota==0.0.30 From 26a7773da82bb0c48f38aacb31a8b3a9f5cb7226 Mon Sep 17 00:00:00 2001 From: Clifford Roche Date: Sat, 14 Nov 2020 05:57:36 -0500 Subject: [PATCH 32/73] Update greeclimate to 0.10.2 (#43206) --- homeassistant/components/gree/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/gree/manifest.json b/homeassistant/components/gree/manifest.json index 26ad518bd74..2d2d293085b 100644 --- a/homeassistant/components/gree/manifest.json +++ b/homeassistant/components/gree/manifest.json @@ -3,6 +3,6 @@ "name": "Gree Climate", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/gree", - "requirements": ["greeclimate==0.9.6"], + "requirements": ["greeclimate==0.10.2"], "codeowners": ["@cmroche"] } \ No newline at end of file diff --git a/requirements_all.txt b/requirements_all.txt index 978c2233864..a2f1f70f3de 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -702,7 +702,7 @@ gpiozero==1.5.1 gps3==0.33.3 # homeassistant.components.gree -greeclimate==0.9.6 +greeclimate==0.10.2 # homeassistant.components.greeneye_monitor greeneye_monitor==2.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 557c4b963ce..0806d38238a 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -358,7 +358,7 @@ google-cloud-pubsub==2.1.0 google-nest-sdm==0.1.14 # homeassistant.components.gree -greeclimate==0.9.6 +greeclimate==0.10.2 # homeassistant.components.griddy griddypower==0.1.0 From f1ec34007e887182d7fefc87002fe13700ce0504 Mon Sep 17 00:00:00 2001 From: Clifford Roche Date: Sun, 15 Nov 2020 12:06:51 -0500 Subject: [PATCH 33/73] Update greeclimate to 0.10.3 (#43248) * Update greeclimate to 0.10.3 * Device search needs to be mocked in tests --- homeassistant/components/gree/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/gree/test_init.py | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/gree/manifest.json b/homeassistant/components/gree/manifest.json index 2d2d293085b..0d2bed3ff28 100644 --- a/homeassistant/components/gree/manifest.json +++ b/homeassistant/components/gree/manifest.json @@ -3,6 +3,6 @@ "name": "Gree Climate", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/gree", - "requirements": ["greeclimate==0.10.2"], + "requirements": ["greeclimate==0.10.3"], "codeowners": ["@cmroche"] } \ No newline at end of file diff --git a/requirements_all.txt b/requirements_all.txt index a2f1f70f3de..4d77cb612e6 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -702,7 +702,7 @@ gpiozero==1.5.1 gps3==0.33.3 # homeassistant.components.gree -greeclimate==0.10.2 +greeclimate==0.10.3 # homeassistant.components.greeneye_monitor greeneye_monitor==2.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 0806d38238a..23230af875c 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -358,7 +358,7 @@ google-cloud-pubsub==2.1.0 google-nest-sdm==0.1.14 # homeassistant.components.gree -greeclimate==0.10.2 +greeclimate==0.10.3 # homeassistant.components.griddy griddypower==0.1.0 diff --git a/tests/components/gree/test_init.py b/tests/components/gree/test_init.py index 1ea0727b220..ef693c9538a 100644 --- a/tests/components/gree/test_init.py +++ b/tests/components/gree/test_init.py @@ -8,7 +8,7 @@ from tests.async_mock import patch from tests.common import MockConfigEntry -async def test_setup_simple(hass): +async def test_setup_simple(hass, discovery, device): """Test gree integration is setup.""" await async_setup_component(hass, GREE_DOMAIN, {}) await hass.async_block_till_done() @@ -17,7 +17,7 @@ async def test_setup_simple(hass): assert len(hass.config_entries.flow.async_progress()) == 0 -async def test_unload_config_entry(hass): +async def test_unload_config_entry(hass, discovery, device): """Test that the async_unload_entry works.""" # As we have currently no configuration, we just to pass the domain here. entry = MockConfigEntry(domain=GREE_DOMAIN) From c6126ff6e4271516a19e15ebdcaf4d829d345294 Mon Sep 17 00:00:00 2001 From: michaeldavie Date: Mon, 16 Nov 2020 14:09:18 -0500 Subject: [PATCH 34/73] Bump env_canada to 0.2.4, fix config validation (#43251) --- homeassistant/components/environment_canada/camera.py | 2 +- homeassistant/components/environment_canada/manifest.json | 2 +- requirements_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/environment_canada/camera.py b/homeassistant/components/environment_canada/camera.py index 87677e85065..66079ac73ff 100644 --- a/homeassistant/components/environment_canada/camera.py +++ b/homeassistant/components/environment_canada/camera.py @@ -30,7 +30,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( vol.Optional(CONF_STATION): cv.matches_regex(r"^C[A-Z]{4}$|^[A-Z]{3}$"), vol.Inclusive(CONF_LATITUDE, "latlon"): cv.latitude, vol.Inclusive(CONF_LONGITUDE, "latlon"): cv.longitude, - vol.Optional(CONF_PRECIP_TYPE): ["RAIN", "SNOW"], + vol.Optional(CONF_PRECIP_TYPE): vol.In(["RAIN", "SNOW"]), } ) diff --git a/homeassistant/components/environment_canada/manifest.json b/homeassistant/components/environment_canada/manifest.json index c605e92acd5..2a51c6ffd83 100644 --- a/homeassistant/components/environment_canada/manifest.json +++ b/homeassistant/components/environment_canada/manifest.json @@ -2,6 +2,6 @@ "domain": "environment_canada", "name": "Environment Canada", "documentation": "https://www.home-assistant.io/integrations/environment_canada", - "requirements": ["env_canada==0.2.2"], + "requirements": ["env_canada==0.2.4"], "codeowners": ["@michaeldavie"] } diff --git a/requirements_all.txt b/requirements_all.txt index 4d77cb612e6..e5ea55cb92b 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -556,7 +556,7 @@ enocean==0.50 enturclient==0.2.1 # homeassistant.components.environment_canada -env_canada==0.2.2 +env_canada==0.2.4 # homeassistant.components.envirophat # envirophat==0.0.6 From bf2c10196d625f29090911c81ed0f7c9ddd36e2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20RAMAGE?= Date: Sun, 15 Nov 2020 18:40:45 +0100 Subject: [PATCH 35/73] Update zigpy-zigate to 0.7.2 (#43252) * update zigpy_zigate to v0.7.1 * bump zigpy-zigate to 0.7.2 --- homeassistant/components/zha/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/zha/manifest.json b/homeassistant/components/zha/manifest.json index 0a42b6b357e..0dfb9ab5098 100644 --- a/homeassistant/components/zha/manifest.json +++ b/homeassistant/components/zha/manifest.json @@ -11,7 +11,7 @@ "zigpy-deconz==0.11.0", "zigpy==0.27.0", "zigpy-xbee==0.13.0", - "zigpy-zigate==0.7.1", + "zigpy-zigate==0.7.2", "zigpy-znp==0.2.2" ], "codeowners": ["@dmulcahey", "@adminiuga"] diff --git a/requirements_all.txt b/requirements_all.txt index e5ea55cb92b..af2b053628d 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2353,7 +2353,7 @@ zigpy-deconz==0.11.0 zigpy-xbee==0.13.0 # homeassistant.components.zha -zigpy-zigate==0.7.1 +zigpy-zigate==0.7.2 # homeassistant.components.zha zigpy-znp==0.2.2 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 23230af875c..3c077c519f9 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1131,7 +1131,7 @@ zigpy-deconz==0.11.0 zigpy-xbee==0.13.0 # homeassistant.components.zha -zigpy-zigate==0.7.1 +zigpy-zigate==0.7.2 # homeassistant.components.zha zigpy-znp==0.2.2 From cabd730281a88c93f13f9064c2da4a284e86c7c1 Mon Sep 17 00:00:00 2001 From: Greg Dowling Date: Mon, 16 Nov 2020 12:16:49 +0000 Subject: [PATCH 36/73] Bump pyvera to 0.3.11 (#43262) --- homeassistant/components/vera/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/vera/manifest.json b/homeassistant/components/vera/manifest.json index b41d289e6b3..264f44782f5 100644 --- a/homeassistant/components/vera/manifest.json +++ b/homeassistant/components/vera/manifest.json @@ -3,6 +3,6 @@ "name": "Vera", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/vera", - "requirements": ["pyvera==0.3.10"], + "requirements": ["pyvera==0.3.11"], "codeowners": ["@vangorra"] } diff --git a/requirements_all.txt b/requirements_all.txt index af2b053628d..b8aaaa6cd04 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1867,7 +1867,7 @@ pyuptimerobot==0.0.5 # pyuserinput==0.1.11 # homeassistant.components.vera -pyvera==0.3.10 +pyvera==0.3.11 # homeassistant.components.versasense pyversasense==0.0.6 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 3c077c519f9..7430a9d50e8 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -902,7 +902,7 @@ pytraccar==0.9.0 pytradfri[async]==7.0.2 # homeassistant.components.vera -pyvera==0.3.10 +pyvera==0.3.11 # homeassistant.components.vesync pyvesync==1.2.0 From 1ba2e07609c07cc03f7c99d157f1b8f869916285 Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Mon, 16 Nov 2020 12:27:42 +0100 Subject: [PATCH 37/73] Bump requests to 2.25.0 (#43279) --- homeassistant/package_constraints.txt | 2 +- requirements.txt | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index 0fb7dcd3274..f80811b668f 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -24,7 +24,7 @@ pip>=8.0.3 python-slugify==4.0.1 pytz>=2020.1 pyyaml==5.3.1 -requests==2.24.0 +requests==2.25.0 ruamel.yaml==0.15.100 sqlalchemy==1.3.20 voluptuous-serialize==2.4.0 diff --git a/requirements.txt b/requirements.txt index 080a41a884b..3a376b6e7cc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,7 +17,7 @@ pip>=8.0.3 python-slugify==4.0.1 pytz>=2020.1 pyyaml==5.3.1 -requests==2.24.0 +requests==2.25.0 ruamel.yaml==0.15.100 voluptuous==0.12.0 voluptuous-serialize==2.4.0 diff --git a/setup.py b/setup.py index bb5d06b6acd..885d6e192d6 100755 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ REQUIRES = [ "python-slugify==4.0.1", "pytz>=2020.1", "pyyaml==5.3.1", - "requests==2.24.0", + "requests==2.25.0", "ruamel.yaml==0.15.100", "voluptuous==0.12.0", "voluptuous-serialize==2.4.0", From 10818e73aecdb1dad6009923bcd2969f35e828fc Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 16 Nov 2020 18:26:22 +0100 Subject: [PATCH 38/73] Update pytradfri to 7.0.3 (#43289) --- homeassistant/components/tradfri/manifest.json | 12 +++--------- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/tradfri/manifest.json b/homeassistant/components/tradfri/manifest.json index dace0f0739b..7b94bbf0bc0 100644 --- a/homeassistant/components/tradfri/manifest.json +++ b/homeassistant/components/tradfri/manifest.json @@ -3,15 +3,9 @@ "name": "IKEA TRÃ…DFRI", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/tradfri", - "requirements": [ - "pytradfri[async]==7.0.2" - ], + "requirements": ["pytradfri[async]==7.0.3"], "homekit": { - "models": [ - "TRADFRI" - ] + "models": ["TRADFRI"] }, - "codeowners": [ - "@ggravlingen" - ] + "codeowners": ["@ggravlingen"] } diff --git a/requirements_all.txt b/requirements_all.txt index b8aaaa6cd04..50e94ddae2f 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1851,7 +1851,7 @@ pytraccar==0.9.0 pytrackr==0.0.5 # homeassistant.components.tradfri -pytradfri[async]==7.0.2 +pytradfri[async]==7.0.3 # homeassistant.components.trafikverket_train # homeassistant.components.trafikverket_weatherstation diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 7430a9d50e8..28743171427 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -899,7 +899,7 @@ pytile==4.0.0 pytraccar==0.9.0 # homeassistant.components.tradfri -pytradfri[async]==7.0.2 +pytradfri[async]==7.0.3 # homeassistant.components.vera pyvera==0.3.11 From 1bb9792bfc759d5f7603f6c4612fdfe610c12d15 Mon Sep 17 00:00:00 2001 From: reaper7 Date: Mon, 16 Nov 2020 20:25:07 +0100 Subject: [PATCH 39/73] Fix Enigma2 available entity property (#43292) Available property should return self.e2_box.is_offlin negation fixes previous PR: https://github.com/home-assistant/core/pull/42407 --- homeassistant/components/enigma2/media_player.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/enigma2/media_player.py b/homeassistant/components/enigma2/media_player.py index cb58a3db333..8bb0486cd24 100644 --- a/homeassistant/components/enigma2/media_player.py +++ b/homeassistant/components/enigma2/media_player.py @@ -136,7 +136,7 @@ class Enigma2Device(MediaPlayerEntity): @property def available(self): """Return True if the device is available.""" - return self.e2_box.is_offline + return not self.e2_box.is_offline @property def supported_features(self): From e6955f50b5d4e3220c37fe74b7f34817b3e74e1c Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 16 Nov 2020 22:55:53 +0100 Subject: [PATCH 40/73] Update pytradfri to 7.0.4 (#43297) --- homeassistant/components/tradfri/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/tradfri/manifest.json b/homeassistant/components/tradfri/manifest.json index 7b94bbf0bc0..7ffa8ed24bf 100644 --- a/homeassistant/components/tradfri/manifest.json +++ b/homeassistant/components/tradfri/manifest.json @@ -3,7 +3,7 @@ "name": "IKEA TRÃ…DFRI", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/tradfri", - "requirements": ["pytradfri[async]==7.0.3"], + "requirements": ["pytradfri[async]==7.0.4"], "homekit": { "models": ["TRADFRI"] }, diff --git a/requirements_all.txt b/requirements_all.txt index 50e94ddae2f..39b5d986948 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1851,7 +1851,7 @@ pytraccar==0.9.0 pytrackr==0.0.5 # homeassistant.components.tradfri -pytradfri[async]==7.0.3 +pytradfri[async]==7.0.4 # homeassistant.components.trafikverket_train # homeassistant.components.trafikverket_weatherstation diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 28743171427..19f699c8f98 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -899,7 +899,7 @@ pytile==4.0.0 pytraccar==0.9.0 # homeassistant.components.tradfri -pytradfri[async]==7.0.3 +pytradfri[async]==7.0.4 # homeassistant.components.vera pyvera==0.3.11 From b9c395a64192605dc4d6f4df93efebe0e58c299f Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Mon, 16 Nov 2020 22:56:45 +0100 Subject: [PATCH 41/73] Updated frontend to 20201111.1 (#43298) --- homeassistant/components/frontend/manifest.json | 2 +- homeassistant/package_constraints.txt | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/frontend/manifest.json b/homeassistant/components/frontend/manifest.json index 7355b40381b..893683dfb88 100644 --- a/homeassistant/components/frontend/manifest.json +++ b/homeassistant/components/frontend/manifest.json @@ -2,7 +2,7 @@ "domain": "frontend", "name": "Home Assistant Frontend", "documentation": "https://www.home-assistant.io/integrations/frontend", - "requirements": ["home-assistant-frontend==20201111.0"], + "requirements": ["home-assistant-frontend==20201111.1"], "dependencies": [ "api", "auth", diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index f80811b668f..c39bb3cc9a4 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -13,7 +13,7 @@ defusedxml==0.6.0 distro==1.5.0 emoji==0.5.4 hass-nabucasa==0.37.2 -home-assistant-frontend==20201111.0 +home-assistant-frontend==20201111.1 httpx==0.16.1 importlib-metadata==1.6.0;python_version<'3.8' jinja2>=2.11.2 diff --git a/requirements_all.txt b/requirements_all.txt index 39b5d986948..72af3398326 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -768,7 +768,7 @@ hole==0.5.1 holidays==0.10.3 # homeassistant.components.frontend -home-assistant-frontend==20201111.0 +home-assistant-frontend==20201111.1 # homeassistant.components.zwave homeassistant-pyozw==0.1.10 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 19f699c8f98..6586280dc4a 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -394,7 +394,7 @@ hole==0.5.1 holidays==0.10.3 # homeassistant.components.frontend -home-assistant-frontend==20201111.0 +home-assistant-frontend==20201111.1 # homeassistant.components.zwave homeassistant-pyozw==0.1.10 From d6ea96ca444db4ae1bff8e145efe1dc6a451473c Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 16 Nov 2020 21:59:07 +0000 Subject: [PATCH 42/73] Bumped version to 0.118.0b3 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 05b780ab3ec..7530d0917a5 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 118 -PATCH_VERSION = "0b2" +PATCH_VERSION = "0b3" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 1) From 9920aaf1f7ec7e1c8b5b366e23ca3122c0813619 Mon Sep 17 00:00:00 2001 From: rikroe <42204099+rikroe@users.noreply.github.com> Date: Tue, 17 Nov 2020 00:31:54 +0100 Subject: [PATCH 43/73] Bump bimmer_connected to 0.7.13 (#43294) Co-authored-by: rikroe --- homeassistant/components/bmw_connected_drive/manifest.json | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/bmw_connected_drive/manifest.json b/homeassistant/components/bmw_connected_drive/manifest.json index ad073e55930..cb17459e105 100644 --- a/homeassistant/components/bmw_connected_drive/manifest.json +++ b/homeassistant/components/bmw_connected_drive/manifest.json @@ -2,6 +2,6 @@ "domain": "bmw_connected_drive", "name": "BMW Connected Drive", "documentation": "https://www.home-assistant.io/integrations/bmw_connected_drive", - "requirements": ["bimmer_connected==0.7.12"], + "requirements": ["bimmer_connected==0.7.13"], "codeowners": ["@gerard33", "@rikroe"] } diff --git a/requirements_all.txt b/requirements_all.txt index 72af3398326..f2afb19b054 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -345,7 +345,7 @@ beautifulsoup4==4.9.1 bellows==0.20.3 # homeassistant.components.bmw_connected_drive -bimmer_connected==0.7.12 +bimmer_connected==0.7.13 # homeassistant.components.bizkaibus bizkaibus==0.1.1 From 0e155f5240cf6b13b4a856bf4ed5b5ad3c0ad836 Mon Sep 17 00:00:00 2001 From: Aaron Bach Date: Mon, 16 Nov 2020 16:31:35 -0700 Subject: [PATCH 44/73] Bump aioguardian to 1.0.4 (#43299) --- homeassistant/components/guardian/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/guardian/manifest.json b/homeassistant/components/guardian/manifest.json index 31572a2ae49..f1fa9c73e5d 100644 --- a/homeassistant/components/guardian/manifest.json +++ b/homeassistant/components/guardian/manifest.json @@ -4,7 +4,7 @@ "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/guardian", "requirements": [ - "aioguardian==1.0.1" + "aioguardian==1.0.4" ], "zeroconf": [ "_api._udp.local." diff --git a/requirements_all.txt b/requirements_all.txt index f2afb19b054..dc675b20242 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -172,7 +172,7 @@ aiofreepybox==0.0.8 aioftp==0.12.0 # homeassistant.components.guardian -aioguardian==1.0.1 +aioguardian==1.0.4 # homeassistant.components.harmony aioharmony==0.2.6 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 6586280dc4a..1840110d5c4 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -103,7 +103,7 @@ aioflo==0.4.1 aiofreepybox==0.0.8 # homeassistant.components.guardian -aioguardian==1.0.1 +aioguardian==1.0.4 # homeassistant.components.harmony aioharmony==0.2.6 From 27707d9711badaae6a136ea10d71c171184a4566 Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Tue, 17 Nov 2020 01:11:42 -0500 Subject: [PATCH 45/73] Abort vizio discovery flow without unique ID (#43303) * abort vizio discovery flow if unique ID cant be found because it means we cant connect * add tests * fix abort call --- homeassistant/components/vizio/config_flow.py | 4 ++++ homeassistant/components/vizio/strings.json | 1 + tests/components/vizio/test_config_flow.py | 15 +++++++++++++++ 3 files changed, 20 insertions(+) diff --git a/homeassistant/components/vizio/config_flow.py b/homeassistant/components/vizio/config_flow.py index b6d6d9bfb05..40f71adda12 100644 --- a/homeassistant/components/vizio/config_flow.py +++ b/homeassistant/components/vizio/config_flow.py @@ -369,6 +369,10 @@ class VizioConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): discovery_info[CONF_DEVICE_CLASS], session=async_get_clientsession(self.hass, False), ) + + if not unique_id: + return self.async_abort(reason="cannot_connect") + await self.async_set_unique_id(unique_id=unique_id, raise_on_progress=True) self._abort_if_unique_id_configured() diff --git a/homeassistant/components/vizio/strings.json b/homeassistant/components/vizio/strings.json index da039b6a89e..adad8406da0 100644 --- a/homeassistant/components/vizio/strings.json +++ b/homeassistant/components/vizio/strings.json @@ -34,6 +34,7 @@ }, "abort": { "already_configured_device": "[%key:common::config_flow::abort::already_configured_device%]", + "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", "updated_entry": "This entry has already been setup but the name, apps, and/or options defined in the configuration do not match the previously imported configuration, so the configuration entry has been updated accordingly." } }, diff --git a/tests/components/vizio/test_config_flow.py b/tests/components/vizio/test_config_flow.py index 32469fabd05..e966188afd2 100644 --- a/tests/components/vizio/test_config_flow.py +++ b/tests/components/vizio/test_config_flow.py @@ -856,6 +856,21 @@ async def test_zeroconf_ignore( assert result["type"] == data_entry_flow.RESULT_TYPE_FORM +async def test_zeroconf_no_unique_id( + hass: HomeAssistantType, + vizio_no_unique_id: pytest.fixture, +) -> None: + """Test zeroconf discovery aborts when unique_id is None.""" + + discovery_info = MOCK_ZEROCONF_SERVICE_INFO.copy() + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_ZEROCONF}, data=discovery_info + ) + + assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT + assert result["reason"] == "cannot_connect" + + async def test_zeroconf_abort_when_ignored( hass: HomeAssistantType, vizio_connect: pytest.fixture, From d2a381118670fc4ac0cd22d5f374d14c7afc1e7e Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Tue, 17 Nov 2020 18:02:41 +0100 Subject: [PATCH 46/73] Bump hatasmota to 0.0.31 (#43319) --- .../components/tasmota/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- .../components/tasmota/test_binary_sensor.py | 104 +++++++++++++++--- 4 files changed, 89 insertions(+), 21 deletions(-) diff --git a/homeassistant/components/tasmota/manifest.json b/homeassistant/components/tasmota/manifest.json index 7892b0fc231..c270be6e633 100644 --- a/homeassistant/components/tasmota/manifest.json +++ b/homeassistant/components/tasmota/manifest.json @@ -3,7 +3,7 @@ "name": "Tasmota (beta)", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/tasmota", - "requirements": ["hatasmota==0.0.30"], + "requirements": ["hatasmota==0.0.31"], "dependencies": ["mqtt"], "mqtt": ["tasmota/discovery/#"], "codeowners": ["@emontnemery"] diff --git a/requirements_all.txt b/requirements_all.txt index dc675b20242..043ad551cf7 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -741,7 +741,7 @@ hass-nabucasa==0.37.2 hass_splunk==0.1.1 # homeassistant.components.tasmota -hatasmota==0.0.30 +hatasmota==0.0.31 # homeassistant.components.jewish_calendar hdate==0.9.12 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 1840110d5c4..0309afeb065 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -376,7 +376,7 @@ hangups==0.4.11 hass-nabucasa==0.37.2 # homeassistant.components.tasmota -hatasmota==0.0.30 +hatasmota==0.0.31 # homeassistant.components.jewish_calendar hdate==0.9.12 diff --git a/tests/components/tasmota/test_binary_sensor.py b/tests/components/tasmota/test_binary_sensor.py index 22bf533e18e..3f444e75bdc 100644 --- a/tests/components/tasmota/test_binary_sensor.py +++ b/tests/components/tasmota/test_binary_sensor.py @@ -51,12 +51,12 @@ async def test_controlling_state_via_mqtt(hass, mqtt_mock, setup_tasmota): ) await hass.async_block_till_done() - state = hass.states.get("binary_sensor.test") + state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") assert state.state == "unavailable" assert not state.attributes.get(ATTR_ASSUMED_STATE) async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/LWT", "Online") - state = hass.states.get("binary_sensor.test") + state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") assert state.state == STATE_OFF assert not state.attributes.get(ATTR_ASSUMED_STATE) @@ -64,35 +64,94 @@ async def test_controlling_state_via_mqtt(hass, mqtt_mock, setup_tasmota): async_fire_mqtt_message( hass, "tasmota_49A3BC/stat/RESULT", '{"Switch1":{"Action":"ON"}}' ) - state = hass.states.get("binary_sensor.test") + state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") assert state.state == STATE_ON async_fire_mqtt_message( hass, "tasmota_49A3BC/stat/RESULT", '{"Switch1":{"Action":"OFF"}}' ) - state = hass.states.get("binary_sensor.test") + state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") assert state.state == STATE_OFF # Test periodic state update async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/SENSOR", '{"Switch1":"ON"}') - state = hass.states.get("binary_sensor.test") + state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") assert state.state == STATE_ON async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/SENSOR", '{"Switch1":"OFF"}') - state = hass.states.get("binary_sensor.test") + state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") assert state.state == STATE_OFF # Test polled state update async_fire_mqtt_message( hass, "tasmota_49A3BC/stat/STATUS10", '{"StatusSNS":{"Switch1":"ON"}}' ) - state = hass.states.get("binary_sensor.test") + state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") assert state.state == STATE_ON async_fire_mqtt_message( hass, "tasmota_49A3BC/stat/STATUS10", '{"StatusSNS":{"Switch1":"OFF"}}' ) - state = hass.states.get("binary_sensor.test") + state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") + assert state.state == STATE_OFF + + +async def test_controlling_state_via_mqtt_switchname(hass, mqtt_mock, setup_tasmota): + """Test state update via MQTT.""" + config = copy.deepcopy(DEFAULT_CONFIG) + config["swc"][0] = 1 + config["swn"][0] = "Custom Name" + mac = config["mac"] + + async_fire_mqtt_message( + hass, + f"{DEFAULT_PREFIX}/{mac}/config", + json.dumps(config), + ) + await hass.async_block_till_done() + + state = hass.states.get("binary_sensor.custom_name") + assert state.state == "unavailable" + assert not state.attributes.get(ATTR_ASSUMED_STATE) + + async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/LWT", "Online") + state = hass.states.get("binary_sensor.custom_name") + assert state.state == STATE_OFF + assert not state.attributes.get(ATTR_ASSUMED_STATE) + + # Test normal state update + async_fire_mqtt_message( + hass, "tasmota_49A3BC/stat/RESULT", '{"Custom Name":{"Action":"ON"}}' + ) + state = hass.states.get("binary_sensor.custom_name") + assert state.state == STATE_ON + + async_fire_mqtt_message( + hass, "tasmota_49A3BC/stat/RESULT", '{"Custom Name":{"Action":"OFF"}}' + ) + state = hass.states.get("binary_sensor.custom_name") + assert state.state == STATE_OFF + + # Test periodic state update + async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/SENSOR", '{"Custom Name":"ON"}') + state = hass.states.get("binary_sensor.custom_name") + assert state.state == STATE_ON + + async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/SENSOR", '{"Custom Name":"OFF"}') + state = hass.states.get("binary_sensor.custom_name") + assert state.state == STATE_OFF + + # Test polled state update + async_fire_mqtt_message( + hass, "tasmota_49A3BC/stat/STATUS10", '{"StatusSNS":{"Custom Name":"ON"}}' + ) + state = hass.states.get("binary_sensor.custom_name") + assert state.state == STATE_ON + + async_fire_mqtt_message( + hass, "tasmota_49A3BC/stat/STATUS10", '{"StatusSNS":{"Custom Name":"OFF"}}' + ) + state = hass.states.get("binary_sensor.custom_name") assert state.state == STATE_OFF @@ -109,12 +168,12 @@ async def test_pushon_controlling_state_via_mqtt(hass, mqtt_mock, setup_tasmota) ) await hass.async_block_till_done() - state = hass.states.get("binary_sensor.test") + state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") assert state.state == "unavailable" assert not state.attributes.get(ATTR_ASSUMED_STATE) async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/LWT", "Online") - state = hass.states.get("binary_sensor.test") + state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") assert state.state == STATE_OFF assert not state.attributes.get(ATTR_ASSUMED_STATE) @@ -122,34 +181,34 @@ async def test_pushon_controlling_state_via_mqtt(hass, mqtt_mock, setup_tasmota) async_fire_mqtt_message( hass, "tasmota_49A3BC/stat/RESULT", '{"Switch1":{"Action":"ON"}}' ) - state = hass.states.get("binary_sensor.test") + state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") assert state.state == STATE_ON async_fire_mqtt_message( hass, "tasmota_49A3BC/stat/RESULT", '{"Switch1":{"Action":"OFF"}}' ) - state = hass.states.get("binary_sensor.test") + state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") assert state.state == STATE_OFF # Test periodic state update is ignored async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/SENSOR", '{"Switch1":"ON"}') - state = hass.states.get("binary_sensor.test") + state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") assert state.state == STATE_OFF # Test polled state update is ignored async_fire_mqtt_message( hass, "tasmota_49A3BC/stat/STATUS10", '{"StatusSNS":{"Switch1":"ON"}}' ) - state = hass.states.get("binary_sensor.test") + state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") assert state.state == STATE_OFF async def test_friendly_names(hass, mqtt_mock, setup_tasmota): """Test state update via MQTT.""" config = copy.deepcopy(DEFAULT_CONFIG) - config["rl"][0] = 1 config["swc"][0] = 1 config["swc"][1] = 1 + config["swn"][1] = "Beer" mac = config["mac"] async_fire_mqtt_message( @@ -197,7 +256,7 @@ async def test_off_delay(hass, mqtt_mock, setup_tasmota): hass, "tasmota_49A3BC/stat/RESULT", '{"Switch1":{"Action":"ON"}}' ) await hass.async_block_till_done() - state = hass.states.get("binary_sensor.test") + state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") assert state.state == STATE_ON assert events == ["off", "on"] @@ -205,13 +264,13 @@ async def test_off_delay(hass, mqtt_mock, setup_tasmota): hass, "tasmota_49A3BC/stat/RESULT", '{"Switch1":{"Action":"ON"}}' ) await hass.async_block_till_done() - state = hass.states.get("binary_sensor.test") + state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") assert state.state == STATE_ON assert events == ["off", "on", "on"] async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=1)) await hass.async_block_till_done() - state = hass.states.get("binary_sensor.test") + state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") assert state.state == STATE_OFF assert events == ["off", "on", "on", "off"] @@ -222,6 +281,7 @@ async def test_availability_when_connection_lost( """Test availability after MQTT disconnection.""" config = copy.deepcopy(DEFAULT_CONFIG) config["swc"][0] = 1 + config["swn"][0] = "Test" await help_test_availability_when_connection_lost( hass, mqtt_client_mock, mqtt_mock, binary_sensor.DOMAIN, config ) @@ -231,6 +291,7 @@ async def test_availability(hass, mqtt_mock, setup_tasmota): """Test availability.""" config = copy.deepcopy(DEFAULT_CONFIG) config["swc"][0] = 1 + config["swn"][0] = "Test" await help_test_availability(hass, mqtt_mock, binary_sensor.DOMAIN, config) @@ -238,6 +299,7 @@ async def test_availability_discovery_update(hass, mqtt_mock, setup_tasmota): """Test availability discovery update.""" config = copy.deepcopy(DEFAULT_CONFIG) config["swc"][0] = 1 + config["swn"][0] = "Test" await help_test_availability_discovery_update( hass, mqtt_mock, binary_sensor.DOMAIN, config ) @@ -249,6 +311,7 @@ async def test_availability_poll_state( """Test polling after MQTT connection (re)established.""" config = copy.deepcopy(DEFAULT_CONFIG) config["swc"][0] = 1 + config["swn"][0] = "Test" poll_topic = "tasmota_49A3BC/cmnd/STATUS" await help_test_availability_poll_state( hass, @@ -267,6 +330,8 @@ async def test_discovery_removal_binary_sensor(hass, mqtt_mock, caplog, setup_ta config2 = copy.deepcopy(DEFAULT_CONFIG) config1["swc"][0] = 1 config2["swc"][0] = 0 + config1["swn"][0] = "Test" + config2["swn"][0] = "Test" await help_test_discovery_removal( hass, mqtt_mock, caplog, binary_sensor.DOMAIN, config1, config2 @@ -279,6 +344,7 @@ async def test_discovery_update_unchanged_binary_sensor( """Test update of discovered binary_sensor.""" config = copy.deepcopy(DEFAULT_CONFIG) config["swc"][0] = 1 + config["swn"][0] = "Test" with patch( "homeassistant.components.tasmota.binary_sensor.TasmotaBinarySensor.discovery_update" ) as discovery_update: @@ -301,6 +367,7 @@ async def test_entity_id_update_subscriptions(hass, mqtt_mock, setup_tasmota): """Test MQTT subscriptions are managed when entity_id is updated.""" config = copy.deepcopy(DEFAULT_CONFIG) config["swc"][0] = 1 + config["swn"][0] = "Test" topics = [ get_topic_stat_result(config), get_topic_tele_sensor(config), @@ -316,6 +383,7 @@ async def test_entity_id_update_discovery_update(hass, mqtt_mock, setup_tasmota) """Test MQTT discovery update when entity_id is updated.""" config = copy.deepcopy(DEFAULT_CONFIG) config["swc"][0] = 1 + config["swn"][0] = "Test" await help_test_entity_id_update_discovery_update( hass, mqtt_mock, binary_sensor.DOMAIN, config ) From ddd7fff6cdc5e682b25c6027cc1b64ee84c382b9 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 18 Nov 2020 08:24:25 +0100 Subject: [PATCH 47/73] Updated frontend to 20201111.2 (#43334) --- homeassistant/components/frontend/manifest.json | 2 +- homeassistant/package_constraints.txt | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/frontend/manifest.json b/homeassistant/components/frontend/manifest.json index 893683dfb88..aea1717ce6f 100644 --- a/homeassistant/components/frontend/manifest.json +++ b/homeassistant/components/frontend/manifest.json @@ -2,7 +2,7 @@ "domain": "frontend", "name": "Home Assistant Frontend", "documentation": "https://www.home-assistant.io/integrations/frontend", - "requirements": ["home-assistant-frontend==20201111.1"], + "requirements": ["home-assistant-frontend==20201111.2"], "dependencies": [ "api", "auth", diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index c39bb3cc9a4..ad46a8a36f4 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -13,7 +13,7 @@ defusedxml==0.6.0 distro==1.5.0 emoji==0.5.4 hass-nabucasa==0.37.2 -home-assistant-frontend==20201111.1 +home-assistant-frontend==20201111.2 httpx==0.16.1 importlib-metadata==1.6.0;python_version<'3.8' jinja2>=2.11.2 diff --git a/requirements_all.txt b/requirements_all.txt index 043ad551cf7..aaa443263bf 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -768,7 +768,7 @@ hole==0.5.1 holidays==0.10.3 # homeassistant.components.frontend -home-assistant-frontend==20201111.1 +home-assistant-frontend==20201111.2 # homeassistant.components.zwave homeassistant-pyozw==0.1.10 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 0309afeb065..4841444b7a0 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -394,7 +394,7 @@ hole==0.5.1 holidays==0.10.3 # homeassistant.components.frontend -home-assistant-frontend==20201111.1 +home-assistant-frontend==20201111.2 # homeassistant.components.zwave homeassistant-pyozw==0.1.10 From 462793f43cb78712e423c946493f868cb9e51552 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Wed, 18 Nov 2020 17:45:38 +0100 Subject: [PATCH 48/73] Bumped version to 0.118.0 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 7530d0917a5..9bcd046c7e6 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 118 -PATCH_VERSION = "0b3" +PATCH_VERSION = "0" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 1) From 59d6eaf856a3b91315bf8f315418af62477753cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Kr=C3=B3l?= Date: Thu, 19 Nov 2020 15:24:28 +0100 Subject: [PATCH 49/73] Bump wolf_smartset to 0.1.8 and handle server fetch error (#43351) --- homeassistant/components/wolflink/__init__.py | 6 +++++- homeassistant/components/wolflink/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/wolflink/__init__.py b/homeassistant/components/wolflink/__init__.py index 611fa7da315..d04cd7a56d4 100644 --- a/homeassistant/components/wolflink/__init__.py +++ b/homeassistant/components/wolflink/__init__.py @@ -4,7 +4,7 @@ import logging from httpcore import ConnectError, ConnectTimeout from wolf_smartset.token_auth import InvalidAuth -from wolf_smartset.wolf_client import WolfClient +from wolf_smartset.wolf_client import FetchFailed, WolfClient from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_PASSWORD, CONF_USERNAME @@ -56,6 +56,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): raise UpdateFailed( f"Error communicating with API: {exception}" ) from exception + except FetchFailed as exception: + raise UpdateFailed( + f"Could not fetch values from server due to: {exception}" + ) from exception except InvalidAuth as exception: raise UpdateFailed("Invalid authentication during update.") from exception diff --git a/homeassistant/components/wolflink/manifest.json b/homeassistant/components/wolflink/manifest.json index 633318f2f62..6d038d4fb29 100644 --- a/homeassistant/components/wolflink/manifest.json +++ b/homeassistant/components/wolflink/manifest.json @@ -3,6 +3,6 @@ "name": "Wolf SmartSet Service", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/wolflink", - "requirements": ["wolf_smartset==0.1.6"], + "requirements": ["wolf_smartset==0.1.8"], "codeowners": ["@adamkrol93"] } diff --git a/requirements_all.txt b/requirements_all.txt index aaa443263bf..15fc7c31f55 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2286,7 +2286,7 @@ withings-api==2.1.6 wled==0.4.4 # homeassistant.components.wolflink -wolf_smartset==0.1.6 +wolf_smartset==0.1.8 # homeassistant.components.xbee xbee-helper==0.0.7 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 4841444b7a0..1d87caff053 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1097,7 +1097,7 @@ withings-api==2.1.6 wled==0.4.4 # homeassistant.components.wolflink -wolf_smartset==0.1.6 +wolf_smartset==0.1.8 # homeassistant.components.xbox xbox-webapi==2.0.8 From 18fdf3a42908bc80c2c227fe827ea5d5f262b277 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Thu, 19 Nov 2020 09:07:35 +0100 Subject: [PATCH 50/73] Bump hatasmota to 0.0.32 (#43360) --- .../components/tasmota/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/tasmota/test_discovery.py | 19 +++++++++++++++++++ 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/tasmota/manifest.json b/homeassistant/components/tasmota/manifest.json index c270be6e633..6140de6025a 100644 --- a/homeassistant/components/tasmota/manifest.json +++ b/homeassistant/components/tasmota/manifest.json @@ -3,7 +3,7 @@ "name": "Tasmota (beta)", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/tasmota", - "requirements": ["hatasmota==0.0.31"], + "requirements": ["hatasmota==0.0.32"], "dependencies": ["mqtt"], "mqtt": ["tasmota/discovery/#"], "codeowners": ["@emontnemery"] diff --git a/requirements_all.txt b/requirements_all.txt index 15fc7c31f55..cb6921144d4 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -741,7 +741,7 @@ hass-nabucasa==0.37.2 hass_splunk==0.1.1 # homeassistant.components.tasmota -hatasmota==0.0.31 +hatasmota==0.0.32 # homeassistant.components.jewish_calendar hdate==0.9.12 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 1d87caff053..0686e049d61 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -376,7 +376,7 @@ hangups==0.4.11 hass-nabucasa==0.37.2 # homeassistant.components.tasmota -hatasmota==0.0.31 +hatasmota==0.0.32 # homeassistant.components.jewish_calendar hdate==0.9.12 diff --git a/tests/components/tasmota/test_discovery.py b/tests/components/tasmota/test_discovery.py index b6a51a38daf..40fecb6b695 100644 --- a/tests/components/tasmota/test_discovery.py +++ b/tests/components/tasmota/test_discovery.py @@ -22,6 +22,25 @@ async def test_subscribing_config_topic(hass, mqtt_mock, setup_tasmota): assert call_args[2] == 0 +async def test_future_discovery_message(hass, mqtt_mock, caplog): + """Test we handle backwards compatible discovery messages.""" + config = copy.deepcopy(DEFAULT_CONFIG) + config["future_option"] = "BEST_SINCE_SLICED_BREAD" + config["so"]["another_future_option"] = "EVEN_BETTER" + + with patch( + "homeassistant.components.tasmota.discovery.tasmota_get_device_config", + return_value={}, + ) as mock_tasmota_get_device_config: + await setup_tasmota_helper(hass) + + async_fire_mqtt_message( + hass, f"{DEFAULT_PREFIX}/00000049A3BC/config", json.dumps(config) + ) + await hass.async_block_till_done() + assert mock_tasmota_get_device_config.called + + async def test_valid_discovery_message(hass, mqtt_mock, caplog): """Test discovery callback called.""" config = copy.deepcopy(DEFAULT_CONFIG) From e15f3b7b8e9e1f981cf72e3dde7bd4019fad6a5e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 19 Nov 2020 01:10:23 -1000 Subject: [PATCH 51/73] Fix homekit bridges when no name was provided (#43364) --- homeassistant/components/homekit/__init__.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/homekit/__init__.py b/homeassistant/components/homekit/__init__.py index 2a0638642ed..1155d3ef18e 100644 --- a/homeassistant/components/homekit/__init__.py +++ b/homeassistant/components/homekit/__init__.py @@ -146,6 +146,14 @@ RESET_ACCESSORY_SERVICE_SCHEMA = vol.Schema( ) +def _async_get_entries_by_name(current_entries): + """Return a dict of the entries by name.""" + + # For backwards compat, its possible the first bridge is using the default + # name. + return {entry.data.get(CONF_NAME, BRIDGE_NAME): entry for entry in current_entries} + + async def async_setup(hass: HomeAssistant, config: dict): """Set up the HomeKit from yaml.""" hass.data.setdefault(DOMAIN, {}) @@ -156,8 +164,7 @@ async def async_setup(hass: HomeAssistant, config: dict): return True current_entries = hass.config_entries.async_entries(DOMAIN) - - entries_by_name = {entry.data[CONF_NAME]: entry for entry in current_entries} + entries_by_name = _async_get_entries_by_name(current_entries) for index, conf in enumerate(config[DOMAIN]): if _async_update_config_entry_if_from_yaml(hass, entries_by_name, conf): @@ -384,7 +391,7 @@ def _async_register_events_and_services(hass: HomeAssistant): return current_entries = hass.config_entries.async_entries(DOMAIN) - entries_by_name = {entry.data[CONF_NAME]: entry for entry in current_entries} + entries_by_name = _async_get_entries_by_name(current_entries) for conf in config[DOMAIN]: _async_update_config_entry_if_from_yaml(hass, entries_by_name, conf) From 0bfcfb859a0e89251a0a54891be5c2d56764fc94 Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Thu, 19 Nov 2020 02:46:20 -0500 Subject: [PATCH 52/73] Bump pyvizio to 0.1.57 (#43374) --- homeassistant/components/vizio/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/vizio/manifest.json b/homeassistant/components/vizio/manifest.json index 7aa544b4a0b..9e4bd712e0f 100644 --- a/homeassistant/components/vizio/manifest.json +++ b/homeassistant/components/vizio/manifest.json @@ -2,7 +2,7 @@ "domain": "vizio", "name": "VIZIO SmartCast", "documentation": "https://www.home-assistant.io/integrations/vizio", - "requirements": ["pyvizio==0.1.56"], + "requirements": ["pyvizio==0.1.57"], "codeowners": ["@raman325"], "config_flow": true, "zeroconf": ["_viziocast._tcp.local."], diff --git a/requirements_all.txt b/requirements_all.txt index cb6921144d4..cb8235a01cf 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1876,7 +1876,7 @@ pyversasense==0.0.6 pyvesync==1.2.0 # homeassistant.components.vizio -pyvizio==0.1.56 +pyvizio==0.1.57 # homeassistant.components.velux pyvlx==0.2.18 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 0686e049d61..45f37f2b18c 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -908,7 +908,7 @@ pyvera==0.3.11 pyvesync==1.2.0 # homeassistant.components.vizio -pyvizio==0.1.56 +pyvizio==0.1.57 # homeassistant.components.volumio pyvolumio==0.1.3 From 044edd3d9e6d14b8394a881fdb6389923e73545a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Thu, 19 Nov 2020 11:55:21 +0100 Subject: [PATCH 53/73] Add back system_health_info to the base of lovelace (#43382) --- homeassistant/components/lovelace/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/lovelace/__init__.py b/homeassistant/components/lovelace/__init__.py index 000c86567ca..7d0fe6574b9 100644 --- a/homeassistant/components/lovelace/__init__.py +++ b/homeassistant/components/lovelace/__init__.py @@ -37,6 +37,7 @@ from .const import ( STORAGE_DASHBOARD_UPDATE_FIELDS, url_slug, ) +from .system_health import system_health_info # NOQA _LOGGER = logging.getLogger(__name__) From 2741362b23a35e3806384882b61374af1e591957 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 19 Nov 2020 17:13:54 +0000 Subject: [PATCH 54/73] Bumped version to 0.118.1 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 9bcd046c7e6..8d520a15e6c 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 118 -PATCH_VERSION = "0" +PATCH_VERSION = "1" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 1) From 43c53f704317ed8f5710c2cae8af47a2b536f94b Mon Sep 17 00:00:00 2001 From: Brett Date: Fri, 20 Nov 2020 18:23:38 +1000 Subject: [PATCH 55/73] Increase Advantage Air retry limit for older systems (#43417) --- homeassistant/components/advantage_air/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/advantage_air/const.py b/homeassistant/components/advantage_air/const.py index 078c266bfb0..5c044481ca0 100644 --- a/homeassistant/components/advantage_air/const.py +++ b/homeassistant/components/advantage_air/const.py @@ -1,6 +1,6 @@ """Constants used by Advantage Air integration.""" DOMAIN = "advantage_air" -ADVANTAGE_AIR_RETRY = 5 +ADVANTAGE_AIR_RETRY = 10 ADVANTAGE_AIR_STATE_OPEN = "open" ADVANTAGE_AIR_STATE_CLOSE = "close" ADVANTAGE_AIR_STATE_ON = "on" From 9822cacbba96c9388f7de64b08ee2c844020f44d Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 20 Nov 2020 15:43:28 +0100 Subject: [PATCH 56/73] Fix time trigger based on entities ignoring entities if initially in the past (#43431) --- .../components/homeassistant/triggers/time.py | 7 +- .../homeassistant/triggers/test_time.py | 92 +++++++++++++++++++ 2 files changed, 96 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/homeassistant/triggers/time.py b/homeassistant/components/homeassistant/triggers/time.py index b636a7a3590..b0fced4d55d 100644 --- a/homeassistant/components/homeassistant/triggers/time.py +++ b/homeassistant/components/homeassistant/triggers/time.py @@ -143,9 +143,12 @@ async def async_attach_trigger(hass, config, action, automation_info): if remove: entities[entity_id] = remove + to_track = [] + for at_time in config[CONF_AT]: if isinstance(at_time, str): # entity + to_track.append(at_time) update_entity_trigger(at_time, new_state=hass.states.get(at_time)) else: # datetime.time @@ -161,9 +164,7 @@ async def async_attach_trigger(hass, config, action, automation_info): # Track state changes of any entities. removes.append( - async_track_state_change_event( - hass, list(entities), update_entity_trigger_event - ) + async_track_state_change_event(hass, to_track, update_entity_trigger_event) ) @callback diff --git a/tests/components/homeassistant/triggers/test_time.py b/tests/components/homeassistant/triggers/test_time.py index 673d0231912..a37be71102d 100644 --- a/tests/components/homeassistant/triggers/test_time.py +++ b/tests/components/homeassistant/triggers/test_time.py @@ -2,8 +2,10 @@ from datetime import timedelta import pytest +import voluptuous as vol from homeassistant.components import automation, sensor +from homeassistant.components.homeassistant.triggers import time from homeassistant.const import ATTR_DEVICE_CLASS, ATTR_ENTITY_ID, SERVICE_TURN_OFF from homeassistant.setup import async_setup_component import homeassistant.util.dt as dt_util @@ -492,3 +494,93 @@ async def test_if_fires_using_at_sensor(hass, calls): # We should not have listened to anything assert len(calls) == 2 + + +@pytest.mark.parametrize( + "conf", + [ + {"platform": "time", "at": "input_datetime.bla"}, + {"platform": "time", "at": "sensor.bla"}, + {"platform": "time", "at": "12:34"}, + ], +) +def test_schema_valid(conf): + """Make sure we don't accept number for 'at' value.""" + time.TRIGGER_SCHEMA(conf) + + +@pytest.mark.parametrize( + "conf", + [ + {"platform": "time", "at": "binary_sensor.bla"}, + {"platform": "time", "at": 745}, + {"platform": "time", "at": "25:00"}, + ], +) +def test_schema_invalid(conf): + """Make sure we don't accept number for 'at' value.""" + with pytest.raises(vol.Invalid): + time.TRIGGER_SCHEMA(conf) + + +async def test_datetime_in_past_on_load(hass, calls): + """Test time trigger works if input_datetime is in past.""" + await async_setup_component( + hass, + "input_datetime", + {"input_datetime": {"my_trigger": {"has_date": True, "has_time": True}}}, + ) + + now = dt_util.now() + past = now - timedelta(days=2) + future = now + timedelta(days=1) + + await hass.services.async_call( + "input_datetime", + "set_datetime", + { + ATTR_ENTITY_ID: "input_datetime.my_trigger", + "datetime": str(past.replace(tzinfo=None)), + }, + blocking=True, + ) + + assert await async_setup_component( + hass, + automation.DOMAIN, + { + automation.DOMAIN: { + "trigger": {"platform": "time", "at": "input_datetime.my_trigger"}, + "action": { + "service": "test.automation", + "data_template": { + "some": "{{ trigger.platform }}-{{ trigger.now.day }}-{{ trigger.now.hour }}-{{trigger.entity_id}}" + }, + }, + } + }, + ) + + async_fire_time_changed(hass, now) + await hass.async_block_till_done() + + assert len(calls) == 0 + + await hass.services.async_call( + "input_datetime", + "set_datetime", + { + ATTR_ENTITY_ID: "input_datetime.my_trigger", + "datetime": str(future.replace(tzinfo=None)), + }, + blocking=True, + ) + + async_fire_time_changed(hass, future + timedelta(seconds=1)) + await hass.async_block_till_done() + + assert len(calls) == 1 + assert ( + calls[0].data["some"] + == f"time-{future.day}-{future.hour}-input_datetime.my_trigger" + ) From f2e78d6ea05dca6d050c9b8b63c71d2373c92115 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 20 Nov 2020 16:54:21 +0000 Subject: [PATCH 57/73] Bumped version to 0.118.2 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 8d520a15e6c..81b8482d21d 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 118 -PATCH_VERSION = "1" +PATCH_VERSION = "2" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 1) From 92cd1373de6739a38a5bae8782160b555b5e5b85 Mon Sep 17 00:00:00 2001 From: Aaron Bach Date: Sun, 22 Nov 2020 20:15:38 -0700 Subject: [PATCH 58/73] Fix bug related to possibly missing task ID in Notion API data (#43330) * Fix bug related to possibly missing task ID in Notion API data * Calculate unique ID once * Code review * Simplify * Code review --- homeassistant/components/notion/__init__.py | 16 ++++++++++------ homeassistant/components/notion/binary_sensor.py | 4 ++-- homeassistant/components/notion/sensor.py | 2 +- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/notion/__init__.py b/homeassistant/components/notion/__init__.py index 296eb34934b..007f18525fe 100644 --- a/homeassistant/components/notion/__init__.py +++ b/homeassistant/components/notion/__init__.py @@ -163,14 +163,17 @@ class NotionEntity(CoordinatorEntity): self._sensor_id = sensor_id self._state = None self._system_id = system_id - self._task_id = task_id + self._unique_id = ( + f'{sensor_id}_{self.coordinator.data["tasks"][task_id]["task_type"]}' + ) + self.task_id = task_id @property def available(self) -> bool: """Return True if entity is available.""" return ( self.coordinator.last_update_success - and self._task_id in self.coordinator.data["tasks"] + and self.task_id in self.coordinator.data["tasks"] ) @property @@ -207,8 +210,7 @@ class NotionEntity(CoordinatorEntity): @property def unique_id(self) -> str: """Return a unique, unchanging string that represents this entity.""" - task = self.coordinator.data["tasks"][self._task_id] - return f'{self._sensor_id}_{task["task_type"]}' + return self._unique_id async def _async_update_bridge_id(self) -> None: """Update the entity's bridge ID if it has changed. @@ -249,8 +251,10 @@ class NotionEntity(CoordinatorEntity): @callback def _handle_coordinator_update(self): """Respond to a DataUpdateCoordinator update.""" - self.hass.async_create_task(self._async_update_bridge_id()) - self._async_update_from_latest_data() + if self.task_id in self.coordinator.data["tasks"]: + self.hass.async_create_task(self._async_update_bridge_id()) + self._async_update_from_latest_data() + self.async_write_ha_state() async def async_added_to_hass(self): diff --git a/homeassistant/components/notion/binary_sensor.py b/homeassistant/components/notion/binary_sensor.py index b8fd96fabc5..a198903b99a 100644 --- a/homeassistant/components/notion/binary_sensor.py +++ b/homeassistant/components/notion/binary_sensor.py @@ -77,7 +77,7 @@ class NotionBinarySensor(NotionEntity, BinarySensorEntity): @callback def _async_update_from_latest_data(self) -> None: """Fetch new state data for the sensor.""" - task = self.coordinator.data["tasks"][self._task_id] + task = self.coordinator.data["tasks"][self.task_id] if "value" in task["status"]: self._state = task["status"]["value"] @@ -87,7 +87,7 @@ class NotionBinarySensor(NotionEntity, BinarySensorEntity): @property def is_on(self) -> bool: """Return whether the sensor is on or off.""" - task = self.coordinator.data["tasks"][self._task_id] + task = self.coordinator.data["tasks"][self.task_id] if task["task_type"] == SENSOR_BATTERY: return self._state == "critical" diff --git a/homeassistant/components/notion/sensor.py b/homeassistant/components/notion/sensor.py index 091dcd324dc..8f7337d200f 100644 --- a/homeassistant/components/notion/sensor.py +++ b/homeassistant/components/notion/sensor.py @@ -79,7 +79,7 @@ class NotionSensor(NotionEntity): @callback def _async_update_from_latest_data(self) -> None: """Fetch new state data for the sensor.""" - task = self.coordinator.data["tasks"][self._task_id] + task = self.coordinator.data["tasks"][self.task_id] if task["task_type"] == SENSOR_TEMPERATURE: self._state = round(float(task["status"]["value"]), 1) From 882b1eb9411afd1461eee2b8c491c97ea2649726 Mon Sep 17 00:00:00 2001 From: Aaron Bach Date: Sun, 22 Nov 2020 05:59:23 -0700 Subject: [PATCH 59/73] Fix unhandled exception when IQVIA API fails to return data (#43359) --- homeassistant/components/iqvia/__init__.py | 3 +++ homeassistant/components/iqvia/sensor.py | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/homeassistant/components/iqvia/__init__.py b/homeassistant/components/iqvia/__init__.py index d730b406896..db0df3a073b 100644 --- a/homeassistant/components/iqvia/__init__.py +++ b/homeassistant/components/iqvia/__init__.py @@ -155,6 +155,9 @@ class IQVIAEntity(CoordinatorEntity): @callback def _handle_coordinator_update(self) -> None: """Handle updated data from the coordinator.""" + if not self.coordinator.last_update_success: + return + self.update_from_latest_data() self.async_write_ha_state() diff --git a/homeassistant/components/iqvia/sensor.py b/homeassistant/components/iqvia/sensor.py index e53ee96b1c4..48ec1cf97b1 100644 --- a/homeassistant/components/iqvia/sensor.py +++ b/homeassistant/components/iqvia/sensor.py @@ -105,6 +105,7 @@ class ForecastSensor(IQVIAEntity): def update_from_latest_data(self): """Update the sensor.""" data = self.coordinator.data.get("Location") + if not data or not data.get("periods"): return @@ -142,6 +143,9 @@ class IndexSensor(IQVIAEntity): @callback def update_from_latest_data(self): """Update the sensor.""" + if not self.coordinator.last_update_success: + return + try: if self._type in (TYPE_ALLERGY_TODAY, TYPE_ALLERGY_TOMORROW): data = self.coordinator.data.get("Location") From 99399cfd29872b25e10e35405c91f73f3a4701fd Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Sat, 21 Nov 2020 16:32:55 +0100 Subject: [PATCH 60/73] Ensure Plex content_id in play_on_sonos service is a string (#43483) --- homeassistant/components/plex/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/plex/__init__.py b/homeassistant/components/plex/__init__.py index 32ee5c56f64..e4f4f80dcfa 100644 --- a/homeassistant/components/plex/__init__.py +++ b/homeassistant/components/plex/__init__.py @@ -227,7 +227,7 @@ async def async_setup_entry(hass, entry): play_on_sonos_schema = vol.Schema( { vol.Required(ATTR_ENTITY_ID): cv.entity_id, - vol.Required(ATTR_MEDIA_CONTENT_ID): str, + vol.Required(ATTR_MEDIA_CONTENT_ID): cv.string, vol.Optional(ATTR_MEDIA_CONTENT_TYPE): vol.In("music"), } ) From e94111f7255c802eb6516b7dcd76deee4535178d Mon Sep 17 00:00:00 2001 From: On Freund Date: Sat, 21 Nov 2020 21:47:57 +0200 Subject: [PATCH 61/73] Gracefully handle no uuid in kodi discovery (#43494) --- homeassistant/components/kodi/config_flow.py | 5 ++++- homeassistant/components/kodi/strings.json | 3 ++- tests/components/kodi/test_config_flow.py | 11 +++++++++++ tests/components/kodi/util.py | 10 ++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/kodi/config_flow.py b/homeassistant/components/kodi/config_flow.py index c11255aba87..c48e4564f92 100644 --- a/homeassistant/components/kodi/config_flow.py +++ b/homeassistant/components/kodi/config_flow.py @@ -104,7 +104,10 @@ class KodiConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): self._host = discovery_info["host"] self._port = int(discovery_info["port"]) self._name = discovery_info["hostname"][: -len(".local.")] - uuid = discovery_info["properties"]["uuid"] + uuid = discovery_info["properties"].get("uuid") + if not uuid: + return self.async_abort(reason="no_uuid") + self._discovery_name = discovery_info["name"] await self.async_set_unique_id(uuid) diff --git a/homeassistant/components/kodi/strings.json b/homeassistant/components/kodi/strings.json index cf2f265f577..f1bb5342903 100644 --- a/homeassistant/components/kodi/strings.json +++ b/homeassistant/components/kodi/strings.json @@ -37,7 +37,8 @@ "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", "invalid_auth": "[%key:common::config_flow::error::invalid_auth%]", "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", - "unknown": "[%key:common::config_flow::error::unknown%]" + "unknown": "[%key:common::config_flow::error::unknown%]", + "no_uuid": "Kodi instance does not have a unique id. This is most likely due to an old Kodi version (17.x or below). You can configure the integration manually or upgrade to a more recent Kodi version." } }, "device_automation": { diff --git a/tests/components/kodi/test_config_flow.py b/tests/components/kodi/test_config_flow.py index 9b010f3ed42..9e892033786 100644 --- a/tests/components/kodi/test_config_flow.py +++ b/tests/components/kodi/test_config_flow.py @@ -11,6 +11,7 @@ from homeassistant.components.kodi.const import DEFAULT_TIMEOUT, DOMAIN from .util import ( TEST_CREDENTIALS, TEST_DISCOVERY, + TEST_DISCOVERY_WO_UUID, TEST_HOST, TEST_IMPORT, TEST_WS_PORT, @@ -573,6 +574,16 @@ async def test_discovery_updates_unique_id(hass): assert entry.data["name"] == "hostname" +async def test_discovery_without_unique_id(hass): + """Test a discovery flow with no unique id aborts.""" + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": "zeroconf"}, data=TEST_DISCOVERY_WO_UUID + ) + + assert result["type"] == "abort" + assert result["reason"] == "no_uuid" + + async def test_form_import(hass): """Test we get the form with import source.""" with patch( diff --git a/tests/components/kodi/util.py b/tests/components/kodi/util.py index 5a47ea88631..edd6950d76e 100644 --- a/tests/components/kodi/util.py +++ b/tests/components/kodi/util.py @@ -24,6 +24,16 @@ TEST_DISCOVERY = { } +TEST_DISCOVERY_WO_UUID = { + "host": "1.1.1.1", + "port": 8080, + "hostname": "hostname.local.", + "type": "_xbmc-jsonrpc-h._tcp.local.", + "name": "hostname._xbmc-jsonrpc-h._tcp.local.", + "properties": {}, +} + + TEST_IMPORT = { "name": "name", "host": "1.1.1.1", From a08f809c46b195c02d909145f50601c74f6069c3 Mon Sep 17 00:00:00 2001 From: ahertz Date: Sun, 22 Nov 2020 06:21:27 -0500 Subject: [PATCH 62/73] Bump sleepyq to 0.8.1 (#43505) --- homeassistant/components/sleepiq/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/sleepiq/manifest.json b/homeassistant/components/sleepiq/manifest.json index 44e519f57da..0f5064f3264 100644 --- a/homeassistant/components/sleepiq/manifest.json +++ b/homeassistant/components/sleepiq/manifest.json @@ -2,6 +2,6 @@ "domain": "sleepiq", "name": "SleepIQ", "documentation": "https://www.home-assistant.io/integrations/sleepiq", - "requirements": ["sleepyq==0.7"], + "requirements": ["sleepyq==0.8.1"], "codeowners": [] } diff --git a/requirements_all.txt b/requirements_all.txt index cb8235a01cf..fc26d7f9f91 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2033,7 +2033,7 @@ skybellpy==0.6.1 slackclient==2.5.0 # homeassistant.components.sleepiq -sleepyq==0.7 +sleepyq==0.8.1 # homeassistant.components.xmpp slixmpp==1.5.2 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 45f37f2b18c..f0ab950c6dd 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -978,7 +978,7 @@ simplisafe-python==9.6.0 slackclient==2.5.0 # homeassistant.components.sleepiq -sleepyq==0.7 +sleepyq==0.8.1 # homeassistant.components.smart_meter_texas smart-meter-texas==0.4.0 From 3955d64b6a4c77bae792a834c2f86685cfdfebd1 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Sun, 22 Nov 2020 22:39:07 +0100 Subject: [PATCH 63/73] Upgrade Docker base image to 2020.11.1 (#43538) --- build.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build.json b/build.json index 43e23d32094..31c6085480c 100644 --- a/build.json +++ b/build.json @@ -1,11 +1,11 @@ { "image": "homeassistant/{arch}-homeassistant", "build_from": { - "aarch64": "homeassistant/aarch64-homeassistant-base:2020.10.1", - "armhf": "homeassistant/armhf-homeassistant-base:2020.10.1", - "armv7": "homeassistant/armv7-homeassistant-base:2020.10.1", - "amd64": "homeassistant/amd64-homeassistant-base:2020.10.1", - "i386": "homeassistant/i386-homeassistant-base:2020.10.1" + "aarch64": "homeassistant/aarch64-homeassistant-base:2020.11.1", + "armhf": "homeassistant/armhf-homeassistant-base:2020.11.1", + "armv7": "homeassistant/armv7-homeassistant-base:2020.11.1", + "amd64": "homeassistant/amd64-homeassistant-base:2020.11.1", + "i386": "homeassistant/i386-homeassistant-base:2020.11.1" }, "labels": { "io.hass.type": "core" From f823fac45ce40db2061a6bfc21cd5564557ca275 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 23 Nov 2020 09:08:09 +0000 Subject: [PATCH 64/73] Bumped version to 0.118.3 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 81b8482d21d..927773be73d 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 118 -PATCH_VERSION = "2" +PATCH_VERSION = "3" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 1) From bb17d4552e11ae1a3c300ec34e2ab9a9171b5144 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Mon, 23 Nov 2020 13:10:30 +0100 Subject: [PATCH 65/73] Upgrade Docker base image to 2020.11.2 (#43560) --- build.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build.json b/build.json index 31c6085480c..49cee1ff280 100644 --- a/build.json +++ b/build.json @@ -1,11 +1,11 @@ { "image": "homeassistant/{arch}-homeassistant", "build_from": { - "aarch64": "homeassistant/aarch64-homeassistant-base:2020.11.1", - "armhf": "homeassistant/armhf-homeassistant-base:2020.11.1", - "armv7": "homeassistant/armv7-homeassistant-base:2020.11.1", - "amd64": "homeassistant/amd64-homeassistant-base:2020.11.1", - "i386": "homeassistant/i386-homeassistant-base:2020.11.1" + "aarch64": "homeassistant/aarch64-homeassistant-base:2020.11.2", + "armhf": "homeassistant/armhf-homeassistant-base:2020.11.2", + "armv7": "homeassistant/armv7-homeassistant-base:2020.11.2", + "amd64": "homeassistant/amd64-homeassistant-base:2020.11.2", + "i386": "homeassistant/i386-homeassistant-base:2020.11.2" }, "labels": { "io.hass.type": "core" From 18135bb1a16fd38f6edbe01d50b535804710ca73 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Mon, 16 Nov 2020 20:10:55 +0100 Subject: [PATCH 66/73] Make MQTT climate return PRESET_NONE when no preset is set (#43257) --- homeassistant/components/mqtt/climate.py | 2 +- tests/components/mqtt/test_climate.py | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/homeassistant/components/mqtt/climate.py b/homeassistant/components/mqtt/climate.py index 68579559e35..8b762a82f02 100644 --- a/homeassistant/components/mqtt/climate.py +++ b/homeassistant/components/mqtt/climate.py @@ -640,7 +640,7 @@ class MqttClimate( return self._hold if self._away: return PRESET_AWAY - return None + return PRESET_NONE @property def preset_modes(self): diff --git a/tests/components/mqtt/test_climate.py b/tests/components/mqtt/test_climate.py index 3c629a82012..4d049753f43 100644 --- a/tests/components/mqtt/test_climate.py +++ b/tests/components/mqtt/test_climate.py @@ -438,11 +438,11 @@ async def test_set_away_mode_pessimistic(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get(ENTITY_CLIMATE) - assert state.attributes.get("preset_mode") is None + assert state.attributes.get("preset_mode") == "none" await common.async_set_preset_mode(hass, "away", ENTITY_CLIMATE) state = hass.states.get(ENTITY_CLIMATE) - assert state.attributes.get("preset_mode") is None + assert state.attributes.get("preset_mode") == "none" async_fire_mqtt_message(hass, "away-state", "ON") state = hass.states.get(ENTITY_CLIMATE) @@ -450,11 +450,11 @@ async def test_set_away_mode_pessimistic(hass, mqtt_mock): async_fire_mqtt_message(hass, "away-state", "OFF") state = hass.states.get(ENTITY_CLIMATE) - assert state.attributes.get("preset_mode") is None + assert state.attributes.get("preset_mode") == "none" async_fire_mqtt_message(hass, "away-state", "nonsense") state = hass.states.get(ENTITY_CLIMATE) - assert state.attributes.get("preset_mode") is None + assert state.attributes.get("preset_mode") == "none" async def test_set_away_mode(hass, mqtt_mock): @@ -467,7 +467,7 @@ async def test_set_away_mode(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get(ENTITY_CLIMATE) - assert state.attributes.get("preset_mode") is None + assert state.attributes.get("preset_mode") == "none" await common.async_set_preset_mode(hass, "away", ENTITY_CLIMATE) mqtt_mock.async_publish.assert_called_once_with("away-mode-topic", "AN", 0, False) mqtt_mock.async_publish.reset_mock() @@ -477,7 +477,7 @@ async def test_set_away_mode(hass, mqtt_mock): await common.async_set_preset_mode(hass, PRESET_NONE, ENTITY_CLIMATE) mqtt_mock.async_publish.assert_called_once_with("away-mode-topic", "AUS", 0, False) state = hass.states.get(ENTITY_CLIMATE) - assert state.attributes.get("preset_mode") is None + assert state.attributes.get("preset_mode") == "none" await common.async_set_preset_mode(hass, "hold-on", ENTITY_CLIMATE) mqtt_mock.async_publish.reset_mock() @@ -525,7 +525,7 @@ async def test_set_hold_pessimistic(hass, mqtt_mock): async_fire_mqtt_message(hass, "hold-state", "off") state = hass.states.get(ENTITY_CLIMATE) - assert state.attributes.get("preset_mode") is None + assert state.attributes.get("preset_mode") == "none" async def test_set_hold(hass, mqtt_mock): @@ -534,7 +534,7 @@ async def test_set_hold(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get(ENTITY_CLIMATE) - assert state.attributes.get("preset_mode") is None + assert state.attributes.get("preset_mode") == "none" await common.async_set_preset_mode(hass, "hold-on", ENTITY_CLIMATE) mqtt_mock.async_publish.assert_called_once_with("hold-topic", "hold-on", 0, False) mqtt_mock.async_publish.reset_mock() @@ -550,7 +550,7 @@ async def test_set_hold(hass, mqtt_mock): await common.async_set_preset_mode(hass, PRESET_NONE, ENTITY_CLIMATE) mqtt_mock.async_publish.assert_called_once_with("hold-topic", "off", 0, False) state = hass.states.get(ENTITY_CLIMATE) - assert state.attributes.get("preset_mode") is None + assert state.attributes.get("preset_mode") == "none" async def test_set_preset_mode_twice(hass, mqtt_mock): @@ -559,7 +559,7 @@ async def test_set_preset_mode_twice(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get(ENTITY_CLIMATE) - assert state.attributes.get("preset_mode") is None + assert state.attributes.get("preset_mode") == "none" await common.async_set_preset_mode(hass, "hold-on", ENTITY_CLIMATE) mqtt_mock.async_publish.assert_called_once_with("hold-topic", "hold-on", 0, False) mqtt_mock.async_publish.reset_mock() @@ -735,7 +735,7 @@ async def test_set_with_templates(hass, mqtt_mock, caplog): assert state.attributes.get("temperature") == 1031 # Away Mode - assert state.attributes.get("preset_mode") is None + assert state.attributes.get("preset_mode") == "none" async_fire_mqtt_message(hass, "away-state", '"ON"') state = hass.states.get(ENTITY_CLIMATE) assert state.attributes.get("preset_mode") == "away" @@ -743,7 +743,7 @@ async def test_set_with_templates(hass, mqtt_mock, caplog): # Away Mode with JSON values async_fire_mqtt_message(hass, "away-state", "false") state = hass.states.get(ENTITY_CLIMATE) - assert state.attributes.get("preset_mode") is None + assert state.attributes.get("preset_mode") == "none" async_fire_mqtt_message(hass, "away-state", "true") state = hass.states.get(ENTITY_CLIMATE) From 94f7f70f2d196ee32be42f3b5c788dbb70b6376a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20RAMAGE?= Date: Fri, 20 Nov 2020 14:05:51 +0100 Subject: [PATCH 67/73] Update zigpy-zigate to 0.7.3 (#43427) * Update zigpy-zigate to 0.7.3 Fix probing pizigate * Update zigpy-zigate to 0.7.3 Fix probing pizigate --- homeassistant/components/zha/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/zha/manifest.json b/homeassistant/components/zha/manifest.json index 0dfb9ab5098..ffbdfdf386b 100644 --- a/homeassistant/components/zha/manifest.json +++ b/homeassistant/components/zha/manifest.json @@ -11,7 +11,7 @@ "zigpy-deconz==0.11.0", "zigpy==0.27.0", "zigpy-xbee==0.13.0", - "zigpy-zigate==0.7.2", + "zigpy-zigate==0.7.3", "zigpy-znp==0.2.2" ], "codeowners": ["@dmulcahey", "@adminiuga"] diff --git a/requirements_all.txt b/requirements_all.txt index fc26d7f9f91..4959f756c3e 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2353,7 +2353,7 @@ zigpy-deconz==0.11.0 zigpy-xbee==0.13.0 # homeassistant.components.zha -zigpy-zigate==0.7.2 +zigpy-zigate==0.7.3 # homeassistant.components.zha zigpy-znp==0.2.2 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index f0ab950c6dd..49f421ba3ba 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1131,7 +1131,7 @@ zigpy-deconz==0.11.0 zigpy-xbee==0.13.0 # homeassistant.components.zha -zigpy-zigate==0.7.2 +zigpy-zigate==0.7.3 # homeassistant.components.zha zigpy-znp==0.2.2 From 44c8fce33b042fb67c376956e4a93c4d3ce400e2 Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Tue, 24 Nov 2020 21:44:31 +0100 Subject: [PATCH 68/73] Fix duplicate check on onewire config flow (#43590) --- .../components/onewire/config_flow.py | 2 +- tests/components/onewire/__init__.py | 6 ++-- tests/components/onewire/test_config_flow.py | 33 +++++++++++++++++-- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/onewire/config_flow.py b/homeassistant/components/onewire/config_flow.py index f83431111d8..9ad4d5347f0 100644 --- a/homeassistant/components/onewire/config_flow.py +++ b/homeassistant/components/onewire/config_flow.py @@ -56,7 +56,7 @@ def is_duplicate_owserver_entry(hass: HomeAssistantType, user_input): if ( config_entry.data[CONF_TYPE] == CONF_TYPE_OWSERVER and config_entry.data[CONF_HOST] == user_input[CONF_HOST] - and config_entry.data[CONF_PORT] == str(user_input[CONF_PORT]) + and config_entry.data[CONF_PORT] == user_input[CONF_PORT] ): return True return False diff --git a/tests/components/onewire/__init__.py b/tests/components/onewire/__init__.py index eb9b42ea996..39a3c438cf9 100644 --- a/tests/components/onewire/__init__.py +++ b/tests/components/onewire/__init__.py @@ -48,9 +48,8 @@ async def setup_onewire_owserver_integration(hass): data={ CONF_TYPE: CONF_TYPE_OWSERVER, CONF_HOST: "1.2.3.4", - CONF_PORT: "1234", + CONF_PORT: 1234, }, - unique_id=f"{CONF_TYPE_OWSERVER}:1.2.3.4:1234", connection_class=CONN_CLASS_LOCAL_POLL, options={}, entry_id="2", @@ -74,12 +73,11 @@ async def setup_onewire_patched_owserver_integration(hass): data={ CONF_TYPE: CONF_TYPE_OWSERVER, CONF_HOST: "1.2.3.4", - CONF_PORT: "1234", + CONF_PORT: 1234, CONF_NAMES: { "10.111111111111": "My DS18B20", }, }, - unique_id=f"{CONF_TYPE_OWSERVER}:1.2.3.4:1234", connection_class=CONN_CLASS_LOCAL_POLL, options={}, entry_id="2", diff --git a/tests/components/onewire/test_config_flow.py b/tests/components/onewire/test_config_flow.py index dfb64a3846e..ba0ae090ed2 100644 --- a/tests/components/onewire/test_config_flow.py +++ b/tests/components/onewire/test_config_flow.py @@ -318,7 +318,7 @@ async def test_import_owserver_with_port(hass): data={ CONF_TYPE: CONF_TYPE_OWSERVER, CONF_HOST: "1.2.3.4", - CONF_PORT: "1234", + CONF_PORT: 1234, }, ) assert result["type"] == RESULT_TYPE_CREATE_ENTRY @@ -326,8 +326,37 @@ async def test_import_owserver_with_port(hass): assert result["data"] == { CONF_TYPE: CONF_TYPE_OWSERVER, CONF_HOST: "1.2.3.4", - CONF_PORT: "1234", + CONF_PORT: 1234, } await hass.async_block_till_done() assert len(mock_setup.mock_calls) == 1 assert len(mock_setup_entry.mock_calls) == 1 + + +async def test_import_owserver_duplicate(hass): + """Test OWServer flow.""" + # Initialise with single entry + with patch( + "homeassistant.components.onewire.async_setup", return_value=True + ) as mock_setup, patch( + "homeassistant.components.onewire.async_setup_entry", + return_value=True, + ) as mock_setup_entry: + await setup_onewire_owserver_integration(hass) + assert len(hass.config_entries.async_entries(DOMAIN)) == 1 + + # Import duplicate entry + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": SOURCE_IMPORT}, + data={ + CONF_TYPE: CONF_TYPE_OWSERVER, + CONF_HOST: "1.2.3.4", + CONF_PORT: 1234, + }, + ) + assert result["type"] == RESULT_TYPE_ABORT + assert result["reason"] == "already_configured" + await hass.async_block_till_done() + assert len(mock_setup.mock_calls) == 1 + assert len(mock_setup_entry.mock_calls) == 1 From 373ad447608718b6086e1fb1c8d7b6f32c902c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren?= Date: Wed, 25 Nov 2020 08:25:09 +0100 Subject: [PATCH 69/73] Bump avea to 1.5.1 (#43618) --- homeassistant/components/avea/manifest.json | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/avea/manifest.json b/homeassistant/components/avea/manifest.json index 8d39600ed46..bf2b1a6a6ec 100644 --- a/homeassistant/components/avea/manifest.json +++ b/homeassistant/components/avea/manifest.json @@ -3,5 +3,5 @@ "name": "Elgato Avea", "documentation": "https://www.home-assistant.io/integrations/avea", "codeowners": ["@pattyland"], - "requirements": ["avea==1.5"] + "requirements": ["avea==1.5.1"] } diff --git a/requirements_all.txt b/requirements_all.txt index 4959f756c3e..937d1671d5f 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -303,7 +303,7 @@ aurorapy==0.2.6 av==8.0.2 # homeassistant.components.avea -# avea==1.5 +# avea==1.5.1 # homeassistant.components.avion # avion==0.10 From c4108d4ef1c8240f149fb3104af2bdc07c632f3b Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 13 Nov 2020 13:22:29 +0100 Subject: [PATCH 70/73] Disable parsing scientific/complex number notation in template type (#43170) --- homeassistant/helpers/template.py | 16 +++++++++++++++- tests/helpers/test_template.py | 13 ++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/homeassistant/helpers/template.py b/homeassistant/helpers/template.py index c6efa717fa7..09a9170c79a 100644 --- a/homeassistant/helpers/template.py +++ b/homeassistant/helpers/template.py @@ -49,6 +49,8 @@ _RENDER_INFO = "template.render_info" _ENVIRONMENT = "template.environment" _RE_JINJA_DELIMITERS = re.compile(r"\{%|\{\{|\{#") +# Match "simple" ints and floats. -1.0, 1, +5, 5.0 +_IS_NUMERIC = re.compile(r"^[+-]?\d*(?:\.\d*)?$") _RESERVED_NAMES = {"contextfunction", "evalcontextfunction", "environmentfunction"} @@ -373,7 +375,19 @@ class Template: # render, by not returning right here. The evaluation of strings # resulting in strings impacts quotes, to avoid unexpected # output; use the original render instead of the evaluated one. - if not isinstance(result, str): + # Complex and scientific values are also unexpected. Filter them out. + if ( + # Filter out string and complex numbers + not isinstance(result, (str, complex)) + and ( + # Pass if not numeric and not a boolean + not isinstance(result, (int, float)) + # Or it's a boolean (inherit from int) + or isinstance(result, bool) + # Or if it's a digit + or _IS_NUMERIC.match(render_result) is not None + ) + ): return result except (ValueError, TypeError, SyntaxError, MemoryError): pass diff --git a/tests/helpers/test_template.py b/tests/helpers/test_template.py index fe2f23c0033..53186ed35a1 100644 --- a/tests/helpers/test_template.py +++ b/tests/helpers/test_template.py @@ -346,7 +346,7 @@ def test_tan(hass): (0, 0.0), (math.pi, -0.0), (math.pi / 180 * 45, 1.0), - (math.pi / 180 * 90, 1.633123935319537e16), + (math.pi / 180 * 90, "1.633123935319537e+16"), (math.pi / 180 * 135, -1.0), ("'error'", "error"), ] @@ -2416,5 +2416,16 @@ async def test_parse_result(hass): ('{{ "{{}}" }}', "{{}}"), ("not-something", "not-something"), ("2a", "2a"), + ("123E5", "123E5"), + ("1j", "1j"), + ("1e+100", "1e+100"), + ("0xface", "0xface"), + ("123", 123), + ("123.0", 123.0), + (".5", 0.5), + ("-1", -1), + ("-1.0", -1.0), + ("+1", 1), + ("5.", 5.0), ): assert template.Template(tpl, hass).async_render() == result From 793fdb53172ac8fe0c104b52a4b11c04b2e49a93 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 25 Nov 2020 16:10:33 +0100 Subject: [PATCH 71/73] Tweak template digit detection (#43621) --- homeassistant/helpers/template.py | 2 +- tests/helpers/test_template.py | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/homeassistant/helpers/template.py b/homeassistant/helpers/template.py index 09a9170c79a..fb3e6ba40b5 100644 --- a/homeassistant/helpers/template.py +++ b/homeassistant/helpers/template.py @@ -50,7 +50,7 @@ _ENVIRONMENT = "template.environment" _RE_JINJA_DELIMITERS = re.compile(r"\{%|\{\{|\{#") # Match "simple" ints and floats. -1.0, 1, +5, 5.0 -_IS_NUMERIC = re.compile(r"^[+-]?\d*(?:\.\d*)?$") +_IS_NUMERIC = re.compile(r"^[+-]?(?!0\d)\d*(?:\.\d*)?$") _RESERVED_NAMES = {"contextfunction", "evalcontextfunction", "environmentfunction"} diff --git a/tests/helpers/test_template.py b/tests/helpers/test_template.py index 53186ed35a1..c8a8bc0710c 100644 --- a/tests/helpers/test_template.py +++ b/tests/helpers/test_template.py @@ -2421,11 +2421,17 @@ async def test_parse_result(hass): ("1e+100", "1e+100"), ("0xface", "0xface"), ("123", 123), + ("10", 10), ("123.0", 123.0), (".5", 0.5), + ("0.5", 0.5), ("-1", -1), ("-1.0", -1.0), ("+1", 1), ("5.", 5.0), + ("123_123_123", "123_123_123"), + # ("+48100200300", "+48100200300"), # phone number + ("010", "010"), + ("0011101.00100001010001", "0011101.00100001010001"), ): assert template.Template(tpl, hass).async_render() == result From ecaa9d925b7479f658c7b10d30afaca32d9ca98a Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Thu, 26 Nov 2020 11:38:30 +0100 Subject: [PATCH 72/73] Fix deadlock if an integration from stage_1 fails (#43657) --- homeassistant/bootstrap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/bootstrap.py b/homeassistant/bootstrap.py index 0d63307a020..5299ac0d301 100644 --- a/homeassistant/bootstrap.py +++ b/homeassistant/bootstrap.py @@ -534,7 +534,7 @@ async def _async_set_up_integrations( _LOGGER.warning("Setup timed out for stage 1 - moving forward") # Enables after dependencies - async_set_domains_to_be_loaded(hass, stage_1_domains | stage_2_domains) + async_set_domains_to_be_loaded(hass, stage_2_domains) if stage_2_domains: _LOGGER.info("Setting up stage 2: %s", stage_2_domains) From 0ede3da686bdf95691c33623d2977cc63576d984 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 26 Nov 2020 16:02:28 +0000 Subject: [PATCH 73/73] Bumped version to 0.118.4 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 927773be73d..37b495d8c24 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 118 -PATCH_VERSION = "3" +PATCH_VERSION = "4" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 1)