From 22e62fa61ab380ee4295ca929b45cd72909c9e8a Mon Sep 17 00:00:00 2001 From: jan iversen Date: Sun, 2 May 2021 00:03:52 +0200 Subject: [PATCH 01/18] Catch non payload modbus messages (#49910) --- homeassistant/components/modbus/modbus.py | 40 +++++++++-------------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/homeassistant/components/modbus/modbus.py b/homeassistant/components/modbus/modbus.py index f04c019e6a6..c1fbe7a9eb7 100644 --- a/homeassistant/components/modbus/modbus.py +++ b/homeassistant/components/modbus/modbus.py @@ -5,7 +5,6 @@ import threading from pymodbus.client.sync import ModbusSerialClient, ModbusTcpClient, ModbusUdpClient from pymodbus.constants import Defaults from pymodbus.exceptions import ModbusException -from pymodbus.pdu import ExceptionResponse, IllegalFunctionRequest from pymodbus.transaction import ModbusRtuFramer from homeassistant.const import ( @@ -237,8 +236,8 @@ class ModbusHub: result = self._client.read_coils(address, count, **kwargs) except ModbusException as exception_error: self._log_error(exception_error) - return None - if isinstance(result, (ExceptionResponse, IllegalFunctionRequest)): + result = exception_error + if not hasattr(result, "registers"): self._log_error(result) return None self._in_error = False @@ -251,9 +250,8 @@ class ModbusHub: try: result = self._client.read_discrete_inputs(address, count, **kwargs) except ModbusException as exception_error: - self._log_error(exception_error) - return None - if isinstance(result, (ExceptionResponse, IllegalFunctionRequest)): + result = exception_error + if not hasattr(result, "registers"): self._log_error(result) return None self._in_error = False @@ -266,9 +264,8 @@ class ModbusHub: try: result = self._client.read_input_registers(address, count, **kwargs) except ModbusException as exception_error: - self._log_error(exception_error) - return None - if isinstance(result, (ExceptionResponse, IllegalFunctionRequest)): + result = exception_error + if not hasattr(result, "registers"): self._log_error(result) return None self._in_error = False @@ -281,9 +278,8 @@ class ModbusHub: try: result = self._client.read_holding_registers(address, count, **kwargs) except ModbusException as exception_error: - self._log_error(exception_error) - return None - if isinstance(result, (ExceptionResponse, IllegalFunctionRequest)): + result = exception_error + if not hasattr(result, "registers"): self._log_error(result) return None self._in_error = False @@ -296,9 +292,8 @@ class ModbusHub: try: result = self._client.write_coil(address, value, **kwargs) except ModbusException as exception_error: - self._log_error(exception_error) - return False - if isinstance(result, (ExceptionResponse, IllegalFunctionRequest)): + result = exception_error + if not hasattr(result, "registers"): self._log_error(result) return False self._in_error = False @@ -311,9 +306,8 @@ class ModbusHub: try: result = self._client.write_coils(address, values, **kwargs) except ModbusException as exception_error: - self._log_error(exception_error) - return False - if isinstance(result, (ExceptionResponse, IllegalFunctionRequest)): + result = exception_error + if not hasattr(result, "registers"): self._log_error(result) return False self._in_error = False @@ -326,9 +320,8 @@ class ModbusHub: try: result = self._client.write_register(address, value, **kwargs) except ModbusException as exception_error: - self._log_error(exception_error) - return False - if isinstance(result, (ExceptionResponse, IllegalFunctionRequest)): + result = exception_error + if not hasattr(result, "registers"): self._log_error(result) return False self._in_error = False @@ -341,9 +334,8 @@ class ModbusHub: try: result = self._client.write_registers(address, values, **kwargs) except ModbusException as exception_error: - self._log_error(exception_error) - return False - if isinstance(result, (ExceptionResponse, IllegalFunctionRequest)): + result = exception_error + if not hasattr(result, "registers"): self._log_error(result) return False self._in_error = False From e482827975b58fe2ae9d0d246617fd5378716a28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Z=C3=A1hradn=C3=ADk?= Date: Sat, 8 May 2021 13:26:31 +0200 Subject: [PATCH 02/18] Fix incorrect attribute checks in Modbus hub (#50241) --- homeassistant/components/modbus/modbus.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/modbus/modbus.py b/homeassistant/components/modbus/modbus.py index c1fbe7a9eb7..6568f552fa6 100644 --- a/homeassistant/components/modbus/modbus.py +++ b/homeassistant/components/modbus/modbus.py @@ -237,7 +237,7 @@ class ModbusHub: except ModbusException as exception_error: self._log_error(exception_error) result = exception_error - if not hasattr(result, "registers"): + if not hasattr(result, "bits"): self._log_error(result) return None self._in_error = False @@ -251,7 +251,7 @@ class ModbusHub: result = self._client.read_discrete_inputs(address, count, **kwargs) except ModbusException as exception_error: result = exception_error - if not hasattr(result, "registers"): + if not hasattr(result, "bits"): self._log_error(result) return None self._in_error = False @@ -293,7 +293,7 @@ class ModbusHub: result = self._client.write_coil(address, value, **kwargs) except ModbusException as exception_error: result = exception_error - if not hasattr(result, "registers"): + if not hasattr(result, "value"): self._log_error(result) return False self._in_error = False @@ -307,7 +307,7 @@ class ModbusHub: result = self._client.write_coils(address, values, **kwargs) except ModbusException as exception_error: result = exception_error - if not hasattr(result, "registers"): + if not hasattr(result, "count"): self._log_error(result) return False self._in_error = False @@ -321,7 +321,7 @@ class ModbusHub: result = self._client.write_register(address, value, **kwargs) except ModbusException as exception_error: result = exception_error - if not hasattr(result, "registers"): + if not hasattr(result, "value"): self._log_error(result) return False self._in_error = False @@ -335,7 +335,7 @@ class ModbusHub: result = self._client.write_registers(address, values, **kwargs) except ModbusException as exception_error: result = exception_error - if not hasattr(result, "registers"): + if not hasattr(result, "count"): self._log_error(result) return False self._in_error = False From 1d5716b505615cb945fa756245dc993d73f77eab Mon Sep 17 00:00:00 2001 From: "Julien \"_FrnchFrgg_\" Rivaud" Date: Mon, 10 May 2021 19:49:08 +0200 Subject: [PATCH 03/18] Fix amcrest detection of sensor reset (#50249) Co-authored-by: Pascal Vizeli --- homeassistant/components/amcrest/__init__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/amcrest/__init__.py b/homeassistant/components/amcrest/__init__.py index f6ddc210415..8d274f12044 100644 --- a/homeassistant/components/amcrest/__init__.py +++ b/homeassistant/components/amcrest/__init__.py @@ -201,11 +201,15 @@ def _monitor_events(hass, name, api, event_codes): while True: api.available_flag.wait() try: - for code, start in api.event_actions("All", retries=5): - event_data = {"camera": name, "event": code, "payload": start} + for code, payload in api.event_actions("All", retries=5): + event_data = {"camera": name, "event": code, "payload": payload} hass.bus.fire("amcrest", event_data) if code in event_codes: signal = service_signal(SERVICE_EVENT, name, code) + start = any( + str(key).lower() == "action" and str(val).lower() == "start" + for key, val in payload.items() + ) _LOGGER.debug("Sending signal: '%s': %s", signal, start) dispatcher_send(hass, signal, start) except AmcrestError as error: From 83db35d2d6d7cf3cdb9224f07be4e87eba3bb5e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Mon, 10 May 2021 18:27:09 +0300 Subject: [PATCH 04/18] Skip Huawei LTE device registry setup with no identifiers or connections (#50261) Closes https://github.com/home-assistant/core/issues/50182 --- .../components/huawei_lte/__init__.py | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/homeassistant/components/huawei_lte/__init__.py b/homeassistant/components/huawei_lte/__init__.py index 690d9ed63a4..70fb051ce30 100644 --- a/homeassistant/components/huawei_lte/__init__.py +++ b/homeassistant/components/huawei_lte/__init__.py @@ -393,26 +393,29 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b router.subscriptions.clear() # Set up device registry - device_data = {} - sw_version = None - if router.data.get(KEY_DEVICE_INFORMATION): - device_info = router.data[KEY_DEVICE_INFORMATION] - sw_version = device_info.get("SoftwareVersion") - if device_info.get("DeviceName"): - device_data["model"] = device_info["DeviceName"] - if not sw_version and router.data.get(KEY_DEVICE_BASIC_INFORMATION): - sw_version = router.data[KEY_DEVICE_BASIC_INFORMATION].get("SoftwareVersion") - if sw_version: - device_data["sw_version"] = sw_version - device_registry = await dr.async_get_registry(hass) - device_registry.async_get_or_create( - config_entry_id=config_entry.entry_id, - connections=router.device_connections, - identifiers=router.device_identifiers, - name=router.device_name, - manufacturer="Huawei", - **device_data, - ) + if router.device_identifiers or router.device_connections: + device_data = {} + sw_version = None + if router.data.get(KEY_DEVICE_INFORMATION): + device_info = router.data[KEY_DEVICE_INFORMATION] + sw_version = device_info.get("SoftwareVersion") + if device_info.get("DeviceName"): + device_data["model"] = device_info["DeviceName"] + if not sw_version and router.data.get(KEY_DEVICE_BASIC_INFORMATION): + sw_version = router.data[KEY_DEVICE_BASIC_INFORMATION].get( + "SoftwareVersion" + ) + if sw_version: + device_data["sw_version"] = sw_version + device_registry = await dr.async_get_registry(hass) + device_registry.async_get_or_create( + config_entry_id=config_entry.entry_id, + connections=router.device_connections, + identifiers=router.device_identifiers, + name=router.device_name, + manufacturer="Huawei", + **device_data, + ) # Forward config entry setup to platforms hass.config_entries.async_setup_platforms(config_entry, CONFIG_ENTRY_PLATFORMS) From 2d3b8fb32998e4750760577388ee74ff3745be80 Mon Sep 17 00:00:00 2001 From: jjlawren Date: Sun, 9 May 2021 04:09:56 -0500 Subject: [PATCH 05/18] Fix Sonos polling bug (#50265) --- homeassistant/components/sonos/speaker.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/sonos/speaker.py b/homeassistant/components/sonos/speaker.py index 73704c61364..03cce67e4d8 100644 --- a/homeassistant/components/sonos/speaker.py +++ b/homeassistant/components/sonos/speaker.py @@ -4,6 +4,7 @@ from __future__ import annotations from asyncio import gather import contextlib import datetime +from functools import partial import logging from typing import Any, Callable @@ -223,7 +224,11 @@ class SonosSpeaker: return self._poll_timer = self.hass.helpers.event.async_track_time_interval( - async_dispatcher_send(self.hass, f"{SONOS_ENTITY_UPDATE}-{self.soco.uid}"), + partial( + async_dispatcher_send, + self.hass, + f"{SONOS_ENTITY_UPDATE}-{self.soco.uid}", + ), SCAN_INTERVAL, ) From 989cee662daccea84a27979126c654f1e0cc1c91 Mon Sep 17 00:00:00 2001 From: Aidan Timson Date: Sat, 8 May 2021 04:05:09 +0100 Subject: [PATCH 06/18] Update ovoenergy to 1.1.12 (#50268) --- homeassistant/components/ovo_energy/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/ovo_energy/manifest.json b/homeassistant/components/ovo_energy/manifest.json index 37950df84cc..ba559ffb41d 100644 --- a/homeassistant/components/ovo_energy/manifest.json +++ b/homeassistant/components/ovo_energy/manifest.json @@ -3,7 +3,7 @@ "name": "OVO Energy", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/ovo_energy", - "requirements": ["ovoenergy==1.1.11"], + "requirements": ["ovoenergy==1.1.12"], "codeowners": ["@timmo001"], "iot_class": "cloud_polling" } diff --git a/requirements_all.txt b/requirements_all.txt index 862119fd519..833b749a2da 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1088,7 +1088,7 @@ oru==0.1.11 orvibo==1.1.1 # homeassistant.components.ovo_energy -ovoenergy==1.1.11 +ovoenergy==1.1.12 # homeassistant.components.mqtt # homeassistant.components.shiftr diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 15f6ce2aa97..aa64973cd08 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -576,7 +576,7 @@ onvif-zeep-async==1.0.0 openerz-api==0.1.0 # homeassistant.components.ovo_energy -ovoenergy==1.1.11 +ovoenergy==1.1.12 # homeassistant.components.mqtt # homeassistant.components.shiftr From 0a1439d16bbf159b0f75ab227182186a289bd3e8 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 8 May 2021 17:53:08 +0200 Subject: [PATCH 07/18] Update denonavr to version 0.10.7 (#50288) --- homeassistant/components/denonavr/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/denonavr/manifest.json b/homeassistant/components/denonavr/manifest.json index 123eac5d2bf..ed6b94e207a 100644 --- a/homeassistant/components/denonavr/manifest.json +++ b/homeassistant/components/denonavr/manifest.json @@ -3,7 +3,7 @@ "name": "Denon AVR Network Receivers", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/denonavr", - "requirements": ["denonavr==0.10.6"], + "requirements": ["denonavr==0.10.7"], "codeowners": ["@scarface-4711", "@starkillerOG"], "ssdp": [ { diff --git a/requirements_all.txt b/requirements_all.txt index 833b749a2da..9bb6b9550c6 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -479,7 +479,7 @@ defusedxml==0.6.0 deluge-client==1.7.1 # homeassistant.components.denonavr -denonavr==0.10.6 +denonavr==0.10.7 # homeassistant.components.devolo_home_control devolo-home-control-api==0.17.3 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index aa64973cd08..c415382f18a 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -264,7 +264,7 @@ debugpy==1.2.1 defusedxml==0.6.0 # homeassistant.components.denonavr -denonavr==0.10.6 +denonavr==0.10.7 # homeassistant.components.devolo_home_control devolo-home-control-api==0.17.3 From 7acefbefb3d1fc92c5ade11175e3f20e5d4dc3b9 Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Sat, 8 May 2021 20:33:55 +0200 Subject: [PATCH 08/18] Bump ha-philipsjs to 2.7.3 (#50293) --- homeassistant/components/philips_js/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/philips_js/manifest.json b/homeassistant/components/philips_js/manifest.json index d41ac0881ba..9d1c4dbd04d 100644 --- a/homeassistant/components/philips_js/manifest.json +++ b/homeassistant/components/philips_js/manifest.json @@ -2,7 +2,7 @@ "domain": "philips_js", "name": "Philips TV", "documentation": "https://www.home-assistant.io/integrations/philips_js", - "requirements": ["ha-philipsjs==2.7.0"], + "requirements": ["ha-philipsjs==2.7.3"], "codeowners": ["@elupus"], "config_flow": true, "iot_class": "local_polling" diff --git a/requirements_all.txt b/requirements_all.txt index 9bb6b9550c6..7a32917366b 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -720,7 +720,7 @@ guppy3==3.1.0 ha-ffmpeg==3.0.2 # homeassistant.components.philips_js -ha-philipsjs==2.7.0 +ha-philipsjs==2.7.3 # homeassistant.components.habitica habitipy==0.2.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index c415382f18a..b60373e37b0 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -393,7 +393,7 @@ guppy3==3.1.0 ha-ffmpeg==3.0.2 # homeassistant.components.philips_js -ha-philipsjs==2.7.0 +ha-philipsjs==2.7.3 # homeassistant.components.habitica habitipy==0.2.0 From 03b786268eccf850e919e71acda68afc1cd186f8 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 8 May 2021 12:20:22 -0500 Subject: [PATCH 09/18] Fix tplink unloading when no switches are present (#50301) --- homeassistant/components/tplink/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/tplink/__init__.py b/homeassistant/components/tplink/__init__.py index e68c30f48b5..f424f90d6d3 100644 --- a/homeassistant/components/tplink/__init__.py +++ b/homeassistant/components/tplink/__init__.py @@ -111,7 +111,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigType): async def async_unload_entry(hass, entry): """Unload a config entry.""" - platforms = [platform for platform in PLATFORMS if platform in hass.data[DOMAIN]] + platforms = [platform for platform in PLATFORMS if hass.data[DOMAIN].get(platform)] unload_ok = await hass.config_entries.async_unload_platforms(entry, platforms) if unload_ok: hass.data[DOMAIN].clear() From e35fbde5fb12af1eff014bd79ef667d87c06dc16 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Sat, 8 May 2021 19:37:09 +0200 Subject: [PATCH 10/18] Fix ESPHome timestamp sensor (#50305) --- homeassistant/components/esphome/sensor.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/esphome/sensor.py b/homeassistant/components/esphome/sensor.py index ceb391f6bda..12319be8c40 100644 --- a/homeassistant/components/esphome/sensor.py +++ b/homeassistant/components/esphome/sensor.py @@ -6,10 +6,15 @@ import math from aioesphomeapi import SensorInfo, SensorState, TextSensorInfo, TextSensorState import voluptuous as vol -from homeassistant.components.sensor import DEVICE_CLASSES, SensorEntity +from homeassistant.components.sensor import ( + DEVICE_CLASS_TIMESTAMP, + DEVICE_CLASSES, + SensorEntity, +) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant import homeassistant.helpers.config_validation as cv +from homeassistant.util import dt from . import EsphomeEntity, esphome_state_property, platform_async_setup_entry @@ -74,6 +79,8 @@ class EsphomeSensor(EsphomeEntity, SensorEntity): return None if self._state.missing_state: return None + if self.device_class == DEVICE_CLASS_TIMESTAMP: + return dt.utc_from_timestamp(self._state.state).isoformat() return f"{self._state.state:.{self._static_info.accuracy_decimals}f}" @property From 3362ac24f622f25bcf855cfa9547cd2fff7772fd Mon Sep 17 00:00:00 2001 From: Brian Rogers Date: Sat, 8 May 2021 23:09:31 -0400 Subject: [PATCH 11/18] Revert Rachio to seconds instead of total_seconds (#50307) * revert seconds * Add comment * Update comment to include max runtime --- homeassistant/components/rachio/switch.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/rachio/switch.py b/homeassistant/components/rachio/switch.py index 41b253d97ee..fd17699f592 100644 --- a/homeassistant/components/rachio/switch.py +++ b/homeassistant/components/rachio/switch.py @@ -418,9 +418,8 @@ class RachioZone(RachioSwitch): CONF_MANUAL_RUN_MINS, DEFAULT_MANUAL_RUN_MINS ) ) - self._controller.rachio.zone.start( - self.zone_id, manual_run_time.total_seconds() - ) + # The API limit is 3 hours, and requires an int be passed + self._controller.rachio.zone.start(self.zone_id, manual_run_time.seconds) _LOGGER.debug( "Watering %s on %s for %s", self.name, From 0ce3bf08594d69d05aa1371aa6e3730bbc5b8b1c Mon Sep 17 00:00:00 2001 From: Colin Robbins Date: Mon, 10 May 2021 18:48:00 +0100 Subject: [PATCH 12/18] Support multiple disks in systemmonitor (#50362) * Fix #50158 - add support for multiple disks * Rework as a tuple --- .../components/systemmonitor/sensor.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/systemmonitor/sensor.py b/homeassistant/components/systemmonitor/sensor.py index 70fd8275bd7..bfaf7231945 100644 --- a/homeassistant/components/systemmonitor/sensor.py +++ b/homeassistant/components/systemmonitor/sensor.py @@ -203,7 +203,7 @@ async def async_setup_platform( ) -> None: """Set up the system monitor sensors.""" entities = [] - sensor_registry: dict[str, SensorData] = {} + sensor_registry: dict[tuple[str, str], SensorData] = {} for resource in config[CONF_RESOURCES]: type_ = resource[CONF_TYPE] @@ -225,7 +225,9 @@ async def async_setup_platform( _LOGGER.warning("Cannot read CPU / processor temperature information") continue - sensor_registry[type_] = SensorData(argument, None, None, None, None) + sensor_registry[(type_, argument)] = SensorData( + argument, None, None, None, None + ) entities.append(SystemMonitorSensor(sensor_registry, type_, argument)) scan_interval = config.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL) @@ -236,7 +238,7 @@ async def async_setup_platform( async def async_setup_sensor_registry_updates( hass: HomeAssistant, - sensor_registry: dict[str, SensorData], + sensor_registry: dict[tuple[str, str], SensorData], scan_interval: datetime.timedelta, ) -> None: """Update the registry and create polling.""" @@ -245,11 +247,11 @@ async def async_setup_sensor_registry_updates( def _update_sensors() -> None: """Update sensors and store the result in the registry.""" - for type_, data in sensor_registry.items(): + for (type_, argument), data in sensor_registry.items(): try: state, value, update_time = _update(type_, data) except Exception as ex: # pylint: disable=broad-except - _LOGGER.exception("Error updating sensor: %s", type_) + _LOGGER.exception("Error updating sensor: %s (%s)", type_, argument) data.last_exception = ex else: data.state = state @@ -295,7 +297,7 @@ class SystemMonitorSensor(SensorEntity): def __init__( self, - sensor_registry: dict[str, SensorData], + sensor_registry: dict[tuple[str, str], SensorData], sensor_type: str, argument: str = "", ) -> None: @@ -304,6 +306,7 @@ class SystemMonitorSensor(SensorEntity): self._name: str = f"{self.sensor_type[SENSOR_TYPE_NAME]} {argument}".rstrip() self._unique_id: str = slugify(f"{sensor_type}_{argument}") self._sensor_registry = sensor_registry + self._argument: str = argument @property def name(self) -> str: @@ -353,7 +356,7 @@ class SystemMonitorSensor(SensorEntity): @property def data(self) -> SensorData: """Return registry entry for the data.""" - return self._sensor_registry[self._type] + return self._sensor_registry[(self._type, self._argument)] async def async_added_to_hass(self) -> None: """When entity is added to hass.""" From 420161039e8f51b704219489def06f6dd3a98960 Mon Sep 17 00:00:00 2001 From: Jeff Irion Date: Sun, 9 May 2021 16:52:24 -0700 Subject: [PATCH 13/18] Bump androidtv to 0.0.59 (#50367) --- homeassistant/components/androidtv/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/androidtv/manifest.json b/homeassistant/components/androidtv/manifest.json index b86a6d9e40a..9ab02fec68a 100644 --- a/homeassistant/components/androidtv/manifest.json +++ b/homeassistant/components/androidtv/manifest.json @@ -4,7 +4,7 @@ "documentation": "https://www.home-assistant.io/integrations/androidtv", "requirements": [ "adb-shell[async]==0.3.1", - "androidtv[async]==0.0.58", + "androidtv[async]==0.0.59", "pure-python-adb[async]==0.3.0.dev0" ], "codeowners": ["@JeffLIrion"], diff --git a/requirements_all.txt b/requirements_all.txt index 7a32917366b..fc6d7fb9f45 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -254,7 +254,7 @@ ambiclimate==0.2.1 amcrest==1.7.2 # homeassistant.components.androidtv -androidtv[async]==0.0.58 +androidtv[async]==0.0.59 # homeassistant.components.anel_pwrctrl anel_pwrctrl-homeassistant==0.0.1.dev2 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index b60373e37b0..a512bc7261a 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -167,7 +167,7 @@ airly==1.1.0 ambiclimate==0.2.1 # homeassistant.components.androidtv -androidtv[async]==0.0.58 +androidtv[async]==0.0.59 # homeassistant.components.apns apns2==0.3.0 From 0dd247aed06f607302d44aba27ad8eba3dcf70ab Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Sun, 9 May 2021 21:57:27 +0200 Subject: [PATCH 14/18] Bump hatasmota to 0.2.12 (#50372) --- .../components/tasmota/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/tasmota/test_sensor.py | 120 ++++++++++++++++++ 4 files changed, 123 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/tasmota/manifest.json b/homeassistant/components/tasmota/manifest.json index b3a4bb09fea..a6e7a1d45a8 100644 --- a/homeassistant/components/tasmota/manifest.json +++ b/homeassistant/components/tasmota/manifest.json @@ -3,7 +3,7 @@ "name": "Tasmota", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/tasmota", - "requirements": ["hatasmota==0.2.11"], + "requirements": ["hatasmota==0.2.12"], "dependencies": ["mqtt"], "mqtt": ["tasmota/discovery/#"], "codeowners": ["@emontnemery"], diff --git a/requirements_all.txt b/requirements_all.txt index fc6d7fb9f45..8dfc4e88617 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -735,7 +735,7 @@ hass-nabucasa==0.43.0 hass_splunk==0.1.1 # homeassistant.components.tasmota -hatasmota==0.2.11 +hatasmota==0.2.12 # homeassistant.components.jewish_calendar hdate==0.10.2 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index a512bc7261a..c4dda2d537e 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -405,7 +405,7 @@ hangups==0.4.11 hass-nabucasa==0.43.0 # homeassistant.components.tasmota -hatasmota==0.2.11 +hatasmota==0.2.12 # homeassistant.components.jewish_calendar hdate==0.10.2 diff --git a/tests/components/tasmota/test_sensor.py b/tests/components/tasmota/test_sensor.py index 0d6820f2d34..425fa3f26f6 100644 --- a/tests/components/tasmota/test_sensor.py +++ b/tests/components/tasmota/test_sensor.py @@ -43,6 +43,15 @@ DEFAULT_SENSOR_CONFIG = { } } +BAD_INDEXED_SENSOR_CONFIG_3 = { + "sn": { + "Time": "2020-09-25T12:47:15", + "ENERGY": { + "ApparentPower": [7.84, 1.23, 2.34], + }, + } +} + INDEXED_SENSOR_CONFIG = { "sn": { "Time": "2020-09-25T12:47:15", @@ -224,6 +233,117 @@ async def test_indexed_sensor_state_via_mqtt(hass, mqtt_mock, setup_tasmota): assert state.state == "7.8" +async def test_bad_indexed_sensor_state_via_mqtt(hass, mqtt_mock, setup_tasmota): + """Test state update via MQTT where sensor is not matching configuration.""" + config = copy.deepcopy(DEFAULT_CONFIG) + sensor_config = copy.deepcopy(BAD_INDEXED_SENSOR_CONFIG_3) + mac = config["mac"] + + async_fire_mqtt_message( + hass, + f"{DEFAULT_PREFIX}/{mac}/config", + json.dumps(config), + ) + await hass.async_block_till_done() + async_fire_mqtt_message( + hass, + f"{DEFAULT_PREFIX}/{mac}/sensors", + json.dumps(sensor_config), + ) + await hass.async_block_till_done() + + state = hass.states.get("sensor.tasmota_energy_apparentpower_0") + assert state.state == "unavailable" + assert not state.attributes.get(ATTR_ASSUMED_STATE) + state = hass.states.get("sensor.tasmota_energy_apparentpower_1") + assert state.state == "unavailable" + assert not state.attributes.get(ATTR_ASSUMED_STATE) + state = hass.states.get("sensor.tasmota_energy_apparentpower_2") + 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("sensor.tasmota_energy_apparentpower_0") + assert state.state == STATE_UNKNOWN + assert not state.attributes.get(ATTR_ASSUMED_STATE) + state = hass.states.get("sensor.tasmota_energy_apparentpower_1") + assert state.state == STATE_UNKNOWN + assert not state.attributes.get(ATTR_ASSUMED_STATE) + state = hass.states.get("sensor.tasmota_energy_apparentpower_2") + assert state.state == STATE_UNKNOWN + assert not state.attributes.get(ATTR_ASSUMED_STATE) + + # Test periodic state update + async_fire_mqtt_message( + hass, "tasmota_49A3BC/tele/SENSOR", '{"ENERGY":{"ApparentPower":[1.2,3.4,5.6]}}' + ) + state = hass.states.get("sensor.tasmota_energy_apparentpower_0") + assert state.state == "1.2" + state = hass.states.get("sensor.tasmota_energy_apparentpower_1") + assert state.state == "3.4" + state = hass.states.get("sensor.tasmota_energy_apparentpower_2") + assert state.state == "5.6" + + # Test periodic state update with too few values + async_fire_mqtt_message( + hass, "tasmota_49A3BC/tele/SENSOR", '{"ENERGY":{"ApparentPower":[7.8,9.0]}}' + ) + state = hass.states.get("sensor.tasmota_energy_apparentpower_0") + assert state.state == "7.8" + state = hass.states.get("sensor.tasmota_energy_apparentpower_1") + assert state.state == "9.0" + state = hass.states.get("sensor.tasmota_energy_apparentpower_2") + assert state.state == STATE_UNKNOWN + + async_fire_mqtt_message( + hass, "tasmota_49A3BC/tele/SENSOR", '{"ENERGY":{"ApparentPower":2.3}}' + ) + state = hass.states.get("sensor.tasmota_energy_apparentpower_0") + assert state.state == "2.3" + state = hass.states.get("sensor.tasmota_energy_apparentpower_1") + assert state.state == STATE_UNKNOWN + state = hass.states.get("sensor.tasmota_energy_apparentpower_2") + assert state.state == STATE_UNKNOWN + + # Test polled state update + async_fire_mqtt_message( + hass, + "tasmota_49A3BC/stat/STATUS10", + '{"StatusSNS":{"ENERGY":{"ApparentPower":[1.2,3.4,5.6]}}}', + ) + state = hass.states.get("sensor.tasmota_energy_apparentpower_0") + assert state.state == "1.2" + state = hass.states.get("sensor.tasmota_energy_apparentpower_1") + assert state.state == "3.4" + state = hass.states.get("sensor.tasmota_energy_apparentpower_2") + assert state.state == "5.6" + + # Test polled state update with too few values + async_fire_mqtt_message( + hass, + "tasmota_49A3BC/stat/STATUS10", + '{"StatusSNS":{"ENERGY":{"ApparentPower":[7.8,9.0]}}}', + ) + state = hass.states.get("sensor.tasmota_energy_apparentpower_0") + assert state.state == "7.8" + state = hass.states.get("sensor.tasmota_energy_apparentpower_1") + assert state.state == "9.0" + state = hass.states.get("sensor.tasmota_energy_apparentpower_2") + assert state.state == STATE_UNKNOWN + + async_fire_mqtt_message( + hass, + "tasmota_49A3BC/stat/STATUS10", + '{"StatusSNS":{"ENERGY":{"ApparentPower":2.3}}}', + ) + state = hass.states.get("sensor.tasmota_energy_apparentpower_0") + assert state.state == "2.3" + state = hass.states.get("sensor.tasmota_energy_apparentpower_1") + assert state.state == STATE_UNKNOWN + state = hass.states.get("sensor.tasmota_energy_apparentpower_2") + assert state.state == STATE_UNKNOWN + + @pytest.mark.parametrize("status_sensor_disabled", [False]) async def test_status_sensor_state_via_mqtt(hass, mqtt_mock, setup_tasmota): """Test state update via MQTT.""" From 51c78e00855be9fc67135e4f82e0ca658303f6cc Mon Sep 17 00:00:00 2001 From: Alan Tse Date: Sun, 9 May 2021 14:30:38 -0700 Subject: [PATCH 15/18] Increase httpx timeout for Tesla (#50376) --- homeassistant/components/tesla/__init__.py | 2 +- homeassistant/components/tesla/config_flow.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/tesla/__init__.py b/homeassistant/components/tesla/__init__.py index 54e3bab3f44..d945d87243e 100644 --- a/homeassistant/components/tesla/__init__.py +++ b/homeassistant/components/tesla/__init__.py @@ -140,7 +140,7 @@ async def async_setup_entry(hass, config_entry): hass.data.setdefault(DOMAIN, {}) config = config_entry.data # Because users can have multiple accounts, we always create a new session so they have separate cookies - async_client = httpx.AsyncClient(headers={USER_AGENT: SERVER_SOFTWARE}) + async_client = httpx.AsyncClient(headers={USER_AGENT: SERVER_SOFTWARE}, timeout=60) email = config_entry.title if email in hass.data[DOMAIN] and CONF_SCAN_INTERVAL in hass.data[DOMAIN][email]: scan_interval = hass.data[DOMAIN][email][CONF_SCAN_INTERVAL] diff --git a/homeassistant/components/tesla/config_flow.py b/homeassistant/components/tesla/config_flow.py index bb0b434ae48..6ec696855cd 100644 --- a/homeassistant/components/tesla/config_flow.py +++ b/homeassistant/components/tesla/config_flow.py @@ -150,7 +150,7 @@ async def validate_input(hass: core.HomeAssistant, data): """ config = {} - async_client = httpx.AsyncClient(headers={USER_AGENT: SERVER_SOFTWARE}) + async_client = httpx.AsyncClient(headers={USER_AGENT: SERVER_SOFTWARE}, timeout=60) try: controller = TeslaAPI( From 6f9c21e1c0a096cd94b41ed8955640958a303273 Mon Sep 17 00:00:00 2001 From: jjlawren Date: Mon, 10 May 2021 07:49:11 -0500 Subject: [PATCH 16/18] Fix location of current_play_mode (#50386) --- homeassistant/components/sonos/media_player.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/sonos/media_player.py b/homeassistant/components/sonos/media_player.py index b179f480724..11f59f2f432 100644 --- a/homeassistant/components/sonos/media_player.py +++ b/homeassistant/components/sonos/media_player.py @@ -498,7 +498,9 @@ class SonosMediaPlayerEntity(SonosEntity, MediaPlayerEntity): if new_status == "TRANSITIONING": return - self._play_mode = event.current_play_mode if event else self.soco.play_mode + self._play_mode = ( + variables["current_play_mode"] if variables else self.soco.play_mode + ) self._uri = None self._media_duration = None self._media_image_url = None From a670156352b378bc0518fa75268bc66f48792362 Mon Sep 17 00:00:00 2001 From: jjlawren Date: Mon, 10 May 2021 10:56:18 -0500 Subject: [PATCH 17/18] Bump pysonos to 0.0.45 (#50407) --- 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 d31881959b3..a87280aaabd 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.44"], + "requirements": ["pysonos==0.0.45"], "after_dependencies": ["plex"], "ssdp": [ { diff --git a/requirements_all.txt b/requirements_all.txt index 8dfc4e88617..1e3328a6c3a 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1741,7 +1741,7 @@ pysnmp==4.4.12 pysoma==0.0.10 # homeassistant.components.sonos -pysonos==0.0.44 +pysonos==0.0.45 # homeassistant.components.spc pyspcwebgw==0.4.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index c4dda2d537e..f199871ff9f 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -959,7 +959,7 @@ pysmartthings==0.7.6 pysoma==0.0.10 # homeassistant.components.sonos -pysonos==0.0.44 +pysonos==0.0.45 # homeassistant.components.spc pyspcwebgw==0.4.0 From 88574034b75d4a24005fa59b16d60e0a7960d2f5 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 10 May 2021 10:50:07 -0700 Subject: [PATCH 18/18] Bumped version to 2021.5.2 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 56fe2b36e57..51f762ad026 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 2021 MINOR_VERSION = 5 -PATCH_VERSION = "1" +PATCH_VERSION = "2" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 8, 0)