From 1f82fbe0196a2fca9f6698423d22a4493979ba24 Mon Sep 17 00:00:00 2001 From: corneyl Date: Mon, 27 Dec 2021 17:44:45 +0100 Subject: [PATCH 01/13] Fix picnic sensor time unit (#62437) --- homeassistant/components/picnic/const.py | 30 ++++++++++++++------ homeassistant/components/picnic/sensor.py | 9 +++--- tests/components/picnic/test_sensor.py | 34 ++++++++++++++++++----- 3 files changed, 53 insertions(+), 20 deletions(-) diff --git a/homeassistant/components/picnic/const.py b/homeassistant/components/picnic/const.py index 228983d8189..be2b403b3b8 100644 --- a/homeassistant/components/picnic/const.py +++ b/homeassistant/components/picnic/const.py @@ -3,11 +3,13 @@ from __future__ import annotations from collections.abc import Callable from dataclasses import dataclass +from datetime import datetime from typing import Any, Literal from homeassistant.components.sensor import SensorEntityDescription from homeassistant.const import CURRENCY_EURO, DEVICE_CLASS_TIMESTAMP from homeassistant.helpers.typing import StateType +from homeassistant.util import dt as dt_util DOMAIN = "picnic" @@ -42,7 +44,7 @@ class PicnicRequiredKeysMixin: """Mixin for required keys.""" data_type: Literal["cart_data", "slot_data", "last_order_data"] - value_fn: Callable[[Any], StateType] + value_fn: Callable[[Any], StateType | datetime] @dataclass @@ -73,7 +75,7 @@ SENSOR_TYPES: tuple[PicnicSensorEntityDescription, ...] = ( icon="mdi:calendar-start", entity_registry_enabled_default=True, data_type="slot_data", - value_fn=lambda slot: slot.get("window_start"), + value_fn=lambda slot: dt_util.parse_datetime(str(slot.get("window_start"))), ), PicnicSensorEntityDescription( key=SENSOR_SELECTED_SLOT_END, @@ -81,7 +83,7 @@ SENSOR_TYPES: tuple[PicnicSensorEntityDescription, ...] = ( icon="mdi:calendar-end", entity_registry_enabled_default=True, data_type="slot_data", - value_fn=lambda slot: slot.get("window_end"), + value_fn=lambda slot: dt_util.parse_datetime(str(slot.get("window_end"))), ), PicnicSensorEntityDescription( key=SENSOR_SELECTED_SLOT_MAX_ORDER_TIME, @@ -89,7 +91,7 @@ SENSOR_TYPES: tuple[PicnicSensorEntityDescription, ...] = ( icon="mdi:clock-alert-outline", entity_registry_enabled_default=True, data_type="slot_data", - value_fn=lambda slot: slot.get("cut_off_time"), + value_fn=lambda slot: dt_util.parse_datetime(str(slot.get("cut_off_time"))), ), PicnicSensorEntityDescription( key=SENSOR_SELECTED_SLOT_MIN_ORDER_VALUE, @@ -108,14 +110,18 @@ SENSOR_TYPES: tuple[PicnicSensorEntityDescription, ...] = ( device_class=DEVICE_CLASS_TIMESTAMP, icon="mdi:calendar-start", data_type="last_order_data", - value_fn=lambda last_order: last_order.get("slot", {}).get("window_start"), + value_fn=lambda last_order: dt_util.parse_datetime( + str(last_order.get("slot", {}).get("window_start")) + ), ), PicnicSensorEntityDescription( key=SENSOR_LAST_ORDER_SLOT_END, device_class=DEVICE_CLASS_TIMESTAMP, icon="mdi:calendar-end", data_type="last_order_data", - value_fn=lambda last_order: last_order.get("slot", {}).get("window_end"), + value_fn=lambda last_order: dt_util.parse_datetime( + str(last_order.get("slot", {}).get("window_end")) + ), ), PicnicSensorEntityDescription( key=SENSOR_LAST_ORDER_STATUS, @@ -129,7 +135,9 @@ SENSOR_TYPES: tuple[PicnicSensorEntityDescription, ...] = ( icon="mdi:clock-start", entity_registry_enabled_default=True, data_type="last_order_data", - value_fn=lambda last_order: last_order.get("eta", {}).get("start"), + value_fn=lambda last_order: dt_util.parse_datetime( + str(last_order.get("eta", {}).get("start")) + ), ), PicnicSensorEntityDescription( key=SENSOR_LAST_ORDER_ETA_END, @@ -137,7 +145,9 @@ SENSOR_TYPES: tuple[PicnicSensorEntityDescription, ...] = ( icon="mdi:clock-end", entity_registry_enabled_default=True, data_type="last_order_data", - value_fn=lambda last_order: last_order.get("eta", {}).get("end"), + value_fn=lambda last_order: dt_util.parse_datetime( + str(last_order.get("eta", {}).get("end")) + ), ), PicnicSensorEntityDescription( key=SENSOR_LAST_ORDER_DELIVERY_TIME, @@ -145,7 +155,9 @@ SENSOR_TYPES: tuple[PicnicSensorEntityDescription, ...] = ( icon="mdi:timeline-clock", entity_registry_enabled_default=True, data_type="last_order_data", - value_fn=lambda last_order: last_order.get("delivery_time", {}).get("start"), + value_fn=lambda last_order: dt_util.parse_datetime( + str(last_order.get("delivery_time", {}).get("start")) + ), ), PicnicSensorEntityDescription( key=SENSOR_LAST_ORDER_TOTAL_PRICE, diff --git a/homeassistant/components/picnic/sensor.py b/homeassistant/components/picnic/sensor.py index 95612e7b272..8e64283c5f0 100644 --- a/homeassistant/components/picnic/sensor.py +++ b/homeassistant/components/picnic/sensor.py @@ -1,6 +1,7 @@ """Definition of Picnic sensors.""" from __future__ import annotations +from datetime import datetime from typing import Any, cast from homeassistant.components.sensor import SensorEntity @@ -62,8 +63,8 @@ class PicnicSensor(SensorEntity, CoordinatorEntity): self._attr_unique_id = f"{config_entry.unique_id}.{description.key}" @property - def native_value(self) -> StateType: - """Return the state of the entity.""" + def native_value(self) -> StateType | datetime: + """Return the value reported by the sensor.""" data_set = ( self.coordinator.data.get(self.entity_description.data_type, {}) if self.coordinator.data is not None @@ -73,8 +74,8 @@ class PicnicSensor(SensorEntity, CoordinatorEntity): @property def available(self) -> bool: - """Return True if entity is available.""" - return self.coordinator.last_update_success and self.state is not None + """Return True if last update was successful.""" + return self.coordinator.last_update_success @property def device_info(self) -> DeviceInfo: diff --git a/tests/components/picnic/test_sensor.py b/tests/components/picnic/test_sensor.py index b0d12f1f080..4067d7e101f 100644 --- a/tests/components/picnic/test_sensor.py +++ b/tests/components/picnic/test_sensor.py @@ -1,6 +1,7 @@ """The tests for the Picnic sensor platform.""" import copy from datetime import timedelta +from typing import Dict import unittest from unittest.mock import patch @@ -15,6 +16,7 @@ from homeassistant.const import ( CURRENCY_EURO, DEVICE_CLASS_TIMESTAMP, STATE_UNAVAILABLE, + STATE_UNKNOWN, ) from homeassistant.helpers.device_registry import DeviceEntryType from homeassistant.util import dt @@ -103,6 +105,7 @@ class TestPicnicSensor(unittest.IsolatedAsyncioTestCase): # Patch the api client self.picnic_patcher = patch("homeassistant.components.picnic.PicnicAPI") self.picnic_mock = self.picnic_patcher.start() + self.picnic_mock().session.auth_token = "3q29fpwhulzes" # Add a config entry and setup the integration config_data = { @@ -281,13 +284,11 @@ class TestPicnicSensor(unittest.IsolatedAsyncioTestCase): await self._setup_platform() # Assert sensors are unknown - self._assert_sensor("sensor.picnic_selected_slot_start", STATE_UNAVAILABLE) - self._assert_sensor("sensor.picnic_selected_slot_end", STATE_UNAVAILABLE) + self._assert_sensor("sensor.picnic_selected_slot_start", STATE_UNKNOWN) + self._assert_sensor("sensor.picnic_selected_slot_end", STATE_UNKNOWN) + self._assert_sensor("sensor.picnic_selected_slot_max_order_time", STATE_UNKNOWN) self._assert_sensor( - "sensor.picnic_selected_slot_max_order_time", STATE_UNAVAILABLE - ) - self._assert_sensor( - "sensor.picnic_selected_slot_min_order_value", STATE_UNAVAILABLE + "sensor.picnic_selected_slot_min_order_value", STATE_UNKNOWN ) async def test_sensors_last_order_in_future(self): @@ -304,7 +305,7 @@ class TestPicnicSensor(unittest.IsolatedAsyncioTestCase): await self._setup_platform() # Assert delivery time is not available, but eta is - self._assert_sensor("sensor.picnic_last_order_delivery_time", STATE_UNAVAILABLE) + self._assert_sensor("sensor.picnic_last_order_delivery_time", STATE_UNKNOWN) self._assert_sensor( "sensor.picnic_last_order_eta_start", "2021-02-26T19:54:00+00:00" ) @@ -312,6 +313,25 @@ class TestPicnicSensor(unittest.IsolatedAsyncioTestCase): "sensor.picnic_last_order_eta_end", "2021-02-26T20:14:00+00:00" ) + async def test_sensors_eta_date_malformed(self): + """Test sensor states when last order eta dates are malformed.""" + # Set-up platform with default mock responses + await self._setup_platform(use_default_responses=True) + + # Set non-datetime strings as eta + eta_dates: Dict[str, str] = { + "start": "wrong-time", + "end": "other-malformed-datetime", + } + delivery_response = copy.deepcopy(DEFAULT_DELIVERY_RESPONSE) + delivery_response["eta2"] = eta_dates + self.picnic_mock().get_deliveries.return_value = [delivery_response] + await self._coordinator.async_refresh() + + # Assert eta times are not available due to malformed date strings + self._assert_sensor("sensor.picnic_last_order_eta_start", STATE_UNKNOWN) + self._assert_sensor("sensor.picnic_last_order_eta_end", STATE_UNKNOWN) + async def test_sensors_use_detailed_eta_if_available(self): """Test sensor states when last order is not yet delivered.""" # Set-up platform with default mock responses From 3de9c425f636627caf3ff423bf0e5df8a522cde0 Mon Sep 17 00:00:00 2001 From: jjlawren Date: Thu, 23 Dec 2021 14:07:29 -0500 Subject: [PATCH 02/13] Bump soco to 0.25.2 (#62691) --- homeassistant/components/sonos/manifest.json | 2 +- homeassistant/components/sonos/speaker.py | 4 ++-- homeassistant/components/sonos/switch.py | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/sonos/conftest.py | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/sonos/manifest.json b/homeassistant/components/sonos/manifest.json index 00006ab4e90..d4fce01fd78 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": ["soco==0.25.1"], + "requirements": ["soco==0.25.2"], "dependencies": ["ssdp"], "after_dependencies": ["plex", "zeroconf"], "zeroconf": ["_sonos._tcp.local."], diff --git a/homeassistant/components/sonos/speaker.py b/homeassistant/components/sonos/speaker.py index 8cd2abcf2b2..ffc0d08a1b4 100644 --- a/homeassistant/components/sonos/speaker.py +++ b/homeassistant/components/sonos/speaker.py @@ -482,7 +482,7 @@ class SonosSpeaker: for bool_var in ( "dialog_level", - "night_mode", + "night_level", "sub_enabled", "surround_enabled", ): @@ -965,7 +965,7 @@ class SonosSpeaker: self.volume = self.soco.volume self.muted = self.soco.mute self.night_mode = self.soco.night_mode - self.dialog_level = self.soco.dialog_mode + self.dialog_level = self.soco.dialog_level self.bass = self.soco.bass self.treble = self.soco.treble diff --git a/homeassistant/components/sonos/switch.py b/homeassistant/components/sonos/switch.py index e92263991ab..ad98523258a 100644 --- a/homeassistant/components/sonos/switch.py +++ b/homeassistant/components/sonos/switch.py @@ -36,7 +36,7 @@ ATTR_INCLUDE_LINKED_ZONES = "include_linked_zones" ATTR_CROSSFADE = "cross_fade" ATTR_NIGHT_SOUND = "night_mode" -ATTR_SPEECH_ENHANCEMENT = "dialog_mode" +ATTR_SPEECH_ENHANCEMENT = "dialog_level" ATTR_STATUS_LIGHT = "status_light" ATTR_SUB_ENABLED = "sub_enabled" ATTR_SURROUND_ENABLED = "surround_enabled" diff --git a/requirements_all.txt b/requirements_all.txt index f19a9aa6e6c..6fd2af8cc74 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2185,7 +2185,7 @@ smhi-pkg==1.0.15 snapcast==2.1.3 # homeassistant.components.sonos -soco==0.25.1 +soco==0.25.2 # homeassistant.components.solaredge_local solaredge-local==0.2.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index a4bee163175..97e821bb4ef 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1291,7 +1291,7 @@ smarthab==0.21 smhi-pkg==1.0.15 # homeassistant.components.sonos -soco==0.25.1 +soco==0.25.2 # homeassistant.components.solaredge solaredge==0.0.2 diff --git a/tests/components/sonos/conftest.py b/tests/components/sonos/conftest.py index f7f8d67589f..18c5366d4ae 100644 --- a/tests/components/sonos/conftest.py +++ b/tests/components/sonos/conftest.py @@ -68,7 +68,7 @@ def soco_fixture(music_library, speaker_info, battery_info, alarm_clock): mock_soco.alarmClock = alarm_clock mock_soco.mute = False mock_soco.night_mode = True - mock_soco.dialog_mode = True + mock_soco.dialog_level = True mock_soco.volume = 19 mock_soco.bass = 1 mock_soco.treble = -1 From c4fe1d57d91c4ff6f93b86dd2dcf7305cd2de850 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 24 Dec 2021 02:26:07 -1000 Subject: [PATCH 03/13] Bump zeroconf to 0.38.1 (#62720) --- homeassistant/components/zeroconf/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/zeroconf/manifest.json b/homeassistant/components/zeroconf/manifest.json index 338456ca576..16a8a8ff26e 100644 --- a/homeassistant/components/zeroconf/manifest.json +++ b/homeassistant/components/zeroconf/manifest.json @@ -2,7 +2,7 @@ "domain": "zeroconf", "name": "Zero-configuration networking (zeroconf)", "documentation": "https://www.home-assistant.io/integrations/zeroconf", - "requirements": ["zeroconf==0.37.0"], + "requirements": ["zeroconf==0.38.1"], "dependencies": ["network", "api"], "codeowners": ["@bdraco"], "quality_scale": "internal", diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index 5ea2198a3aa..c17acc7e436 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -33,7 +33,7 @@ sqlalchemy==1.4.27 voluptuous-serialize==2.5.0 voluptuous==0.12.2 yarl==1.6.3 -zeroconf==0.37.0 +zeroconf==0.38.1 pycryptodome>=3.6.6 diff --git a/requirements_all.txt b/requirements_all.txt index 6fd2af8cc74..cef7ed280b7 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2484,7 +2484,7 @@ youtube_dl==2021.06.06 zengge==0.2 # homeassistant.components.zeroconf -zeroconf==0.37.0 +zeroconf==0.38.1 # homeassistant.components.zha zha-quirks==0.0.65 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 97e821bb4ef..c43f4c246a5 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1473,7 +1473,7 @@ yeelight==0.7.8 youless-api==0.15 # homeassistant.components.zeroconf -zeroconf==0.37.0 +zeroconf==0.38.1 # homeassistant.components.zha zha-quirks==0.0.65 From fb26398ea7f1f2e5f70b9b01379fe8cc871fe6e1 Mon Sep 17 00:00:00 2001 From: htmltiger <1429451+htmltiger@users.noreply.github.com> Date: Mon, 27 Dec 2021 19:55:43 +0000 Subject: [PATCH 04/13] Fix TypeError of vacuum battery level None (#62722) Co-authored-by: Franck Nijhof --- homeassistant/components/google_assistant/trait.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/homeassistant/components/google_assistant/trait.py b/homeassistant/components/google_assistant/trait.py index 30ea244bac9..843ebfee87a 100644 --- a/homeassistant/components/google_assistant/trait.py +++ b/homeassistant/components/google_assistant/trait.py @@ -641,6 +641,8 @@ class EnergyStorageTrait(_Trait): def query_attributes(self): """Return EnergyStorage query attributes.""" battery_level = self.state.attributes.get(ATTR_BATTERY_LEVEL) + if battery_level is None: + return {} if battery_level == 100: descriptive_capacity_remaining = "FULL" elif 75 <= battery_level < 100: From 117fb8ef4c72e26b702ee7c2b1f3bff22b1e6471 Mon Sep 17 00:00:00 2001 From: flfue Date: Mon, 27 Dec 2021 08:31:51 +0100 Subject: [PATCH 05/13] Add return for certified devices to not apply availability check (#62728) --- homeassistant/components/hue/v2/entity.py | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/hue/v2/entity.py b/homeassistant/components/hue/v2/entity.py index 69b299d574f..8253d4ffbef 100644 --- a/homeassistant/components/hue/v2/entity.py +++ b/homeassistant/components/hue/v2/entity.py @@ -145,6 +145,7 @@ class HueBaseEntity(Entity): if self.device.product_data.certified: # certified products report their state correctly self._ignore_availability = False + return # some (3th party) Hue lights report their connection status incorrectly # causing the zigbee availability to report as disconnected while in fact # it can be controlled. Although this is in fact something the device manufacturer From e8bb0eceed2d141d31c53658310094cfd0124910 Mon Sep 17 00:00:00 2001 From: Evgeny Date: Fri, 24 Dec 2021 21:34:49 +0100 Subject: [PATCH 06/13] Bump roombapy to 1.6.4 (#62741) --- homeassistant/components/roomba/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/roomba/manifest.json b/homeassistant/components/roomba/manifest.json index 907026fd77e..ad5857aa630 100644 --- a/homeassistant/components/roomba/manifest.json +++ b/homeassistant/components/roomba/manifest.json @@ -3,7 +3,7 @@ "name": "iRobot Roomba and Braava", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/roomba", - "requirements": ["roombapy==1.6.4"], + "requirements": ["roombapy==1.6.5"], "codeowners": ["@pschmitt", "@cyr-ius", "@shenxn"], "dhcp": [ { diff --git a/requirements_all.txt b/requirements_all.txt index cef7ed280b7..e0113d5d593 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2074,7 +2074,7 @@ rocketchat-API==0.6.1 rokuecp==0.8.4 # homeassistant.components.roomba -roombapy==1.6.4 +roombapy==1.6.5 # homeassistant.components.roon roonapi==0.0.38 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index c43f4c246a5..37af6f3d26d 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1236,7 +1236,7 @@ ring_doorbell==0.7.2 rokuecp==0.8.4 # homeassistant.components.roomba -roombapy==1.6.4 +roombapy==1.6.5 # homeassistant.components.roon roonapi==0.0.38 From 2e10432075f36f696b5e580a1a33be8fcc01f265 Mon Sep 17 00:00:00 2001 From: Simone Chemelli Date: Sun, 26 Dec 2021 21:26:24 +0100 Subject: [PATCH 07/13] Add missing entity category for gen2 devices (#62812) --- homeassistant/components/shelly/sensor.py | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/shelly/sensor.py b/homeassistant/components/shelly/sensor.py index 7fcf456b658..51cb462fa48 100644 --- a/homeassistant/components/shelly/sensor.py +++ b/homeassistant/components/shelly/sensor.py @@ -283,6 +283,7 @@ RPC_SENSORS: Final = { device_class=sensor.DEVICE_CLASS_TEMPERATURE, state_class=sensor.STATE_CLASS_MEASUREMENT, default_enabled=False, + entity_category=EntityCategory.DIAGNOSTIC, ), "rssi": RpcAttributeDescription( key="wifi", From 34ca39855e41a12bf27470067e599f165226eccd Mon Sep 17 00:00:00 2001 From: gjong Date: Mon, 27 Dec 2021 12:32:25 +0100 Subject: [PATCH 08/13] Upgrade youless library to version 0.16 (#62837) --- homeassistant/components/youless/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/youless/manifest.json b/homeassistant/components/youless/manifest.json index 49a5b6187e6..f5713c51680 100644 --- a/homeassistant/components/youless/manifest.json +++ b/homeassistant/components/youless/manifest.json @@ -3,7 +3,7 @@ "name": "YouLess", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/youless", - "requirements": ["youless-api==0.15"], + "requirements": ["youless-api==0.16"], "codeowners": ["@gjong"], "iot_class": "local_polling" } diff --git a/requirements_all.txt b/requirements_all.txt index e0113d5d593..4b456a35796 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2475,7 +2475,7 @@ yeelight==0.7.8 yeelightsunflower==0.0.10 # homeassistant.components.youless -youless-api==0.15 +youless-api==0.16 # homeassistant.components.media_extractor youtube_dl==2021.06.06 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 37af6f3d26d..594a779e833 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1470,7 +1470,7 @@ yalexs==1.1.13 yeelight==0.7.8 # homeassistant.components.youless -youless-api==0.15 +youless-api==0.16 # homeassistant.components.zeroconf zeroconf==0.38.1 From bfe4f52c2deec3086d9006cd9d7aaa3a59fe7782 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Mon, 27 Dec 2021 20:58:33 +0100 Subject: [PATCH 09/13] Update tuya-iot-py-sdk to 0.6.6 (#62858) --- homeassistant/components/tuya/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/tuya/manifest.json b/homeassistant/components/tuya/manifest.json index c48771b85be..1b8772a36df 100644 --- a/homeassistant/components/tuya/manifest.json +++ b/homeassistant/components/tuya/manifest.json @@ -2,7 +2,7 @@ "domain": "tuya", "name": "Tuya", "documentation": "https://www.home-assistant.io/integrations/tuya", - "requirements": ["tuya-iot-py-sdk==0.6.3"], + "requirements": ["tuya-iot-py-sdk==0.6.6"], "dependencies": ["ffmpeg"], "codeowners": ["@Tuya", "@zlinoliver", "@METISU", "@frenck"], "config_flow": true, diff --git a/requirements_all.txt b/requirements_all.txt index 4b456a35796..a6c47bb1fdc 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2339,7 +2339,7 @@ tp-connected==0.0.4 transmissionrpc==0.11 # homeassistant.components.tuya -tuya-iot-py-sdk==0.6.3 +tuya-iot-py-sdk==0.6.6 # homeassistant.components.twentemilieu twentemilieu==0.5.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 594a779e833..a0d5c7bf183 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1376,7 +1376,7 @@ total_connect_client==2021.12 transmissionrpc==0.11 # homeassistant.components.tuya -tuya-iot-py-sdk==0.6.3 +tuya-iot-py-sdk==0.6.6 # homeassistant.components.twentemilieu twentemilieu==0.5.0 From 315864acbc8058688aae7b0578df86bc25569511 Mon Sep 17 00:00:00 2001 From: corneyl Date: Mon, 27 Dec 2021 20:31:35 +0100 Subject: [PATCH 10/13] Fix keyerror when no previous Picnic orders exist (#62870) --- homeassistant/components/picnic/coordinator.py | 13 +++++++------ tests/components/picnic/test_sensor.py | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/picnic/coordinator.py b/homeassistant/components/picnic/coordinator.py index bcd4e79a098..71a6559975c 100644 --- a/homeassistant/components/picnic/coordinator.py +++ b/homeassistant/components/picnic/coordinator.py @@ -60,11 +60,11 @@ class PicnicUpdateCoordinator(DataUpdateCoordinator): """Fetch the data from the Picnic API and return a flat dict with only needed sensor data.""" # Fetch from the API and pre-process the data cart = self.picnic_api_client.get_cart() - last_order = self._get_last_order() - if not cart or not last_order: + if not cart: raise UpdateFailed("API response doesn't contain expected data.") + last_order = self._get_last_order() slot_data = self._get_slot_data(cart) return { @@ -102,11 +102,12 @@ class PicnicUpdateCoordinator(DataUpdateCoordinator): """Get data of the last order from the list of deliveries.""" # Get the deliveries deliveries = self.picnic_api_client.get_deliveries(summary=True) - if not deliveries: - return {} - # Determine the last order - last_order = copy.deepcopy(deliveries[0]) + # Determine the last order and return an empty dict if there is none + try: + last_order = copy.deepcopy(deliveries[0]) + except KeyError: + return {} # Get the position details if the order is not delivered yet delivery_position = {} diff --git a/tests/components/picnic/test_sensor.py b/tests/components/picnic/test_sensor.py index 4067d7e101f..83653945d8c 100644 --- a/tests/components/picnic/test_sensor.py +++ b/tests/components/picnic/test_sensor.py @@ -387,6 +387,21 @@ class TestPicnicSensor(unittest.IsolatedAsyncioTestCase): self._assert_sensor("sensor.picnic_last_order_eta_end", STATE_UNAVAILABLE) self._assert_sensor("sensor.picnic_last_order_delivery_time", STATE_UNAVAILABLE) + async def test_sensors_malformed_delivery_data(self): + """Test sensor states when the delivery api returns not a list.""" + # Setup platform with default responses + await self._setup_platform(use_default_responses=True) + + # Change mock responses to empty data and refresh the coordinator + self.picnic_mock().get_deliveries.return_value = {"error": "message"} + await self._coordinator.async_refresh() + + # Assert all last-order sensors have STATE_UNAVAILABLE because the delivery info fetch failed + assert self._coordinator.last_update_success is True + self._assert_sensor("sensor.picnic_last_order_eta_start", STATE_UNKNOWN) + self._assert_sensor("sensor.picnic_last_order_eta_end", STATE_UNKNOWN) + self._assert_sensor("sensor.picnic_last_order_delivery_time", STATE_UNKNOWN) + async def test_sensors_malformed_response(self): """Test coordinator update fails when API yields ValueError.""" # Setup platform with default responses From 12fefe4c31201556a331e5390839439e9a9a1e92 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Mon, 27 Dec 2021 21:37:21 +0100 Subject: [PATCH 11/13] Update frontend to 20211227.0 (#62874) --- 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 6ae1709e418..a2c7e49f6e6 100644 --- a/homeassistant/components/frontend/manifest.json +++ b/homeassistant/components/frontend/manifest.json @@ -3,7 +3,7 @@ "name": "Home Assistant Frontend", "documentation": "https://www.home-assistant.io/integrations/frontend", "requirements": [ - "home-assistant-frontend==20211220.0" + "home-assistant-frontend==20211227.0" ], "dependencies": [ "api", diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index c17acc7e436..19b764ee32f 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -16,7 +16,7 @@ ciso8601==2.2.0 cryptography==35.0.0 emoji==1.5.0 hass-nabucasa==0.50.0 -home-assistant-frontend==20211220.0 +home-assistant-frontend==20211227.0 httpx==0.21.0 ifaddr==0.1.7 jinja2==3.0.3 diff --git a/requirements_all.txt b/requirements_all.txt index a6c47bb1fdc..41318a26a28 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -820,7 +820,7 @@ hole==0.7.0 holidays==0.11.3.1 # homeassistant.components.frontend -home-assistant-frontend==20211220.0 +home-assistant-frontend==20211227.0 # homeassistant.components.zwave homeassistant-pyozw==0.1.10 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index a0d5c7bf183..f2e191885c9 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -515,7 +515,7 @@ hole==0.7.0 holidays==0.11.3.1 # homeassistant.components.frontend -home-assistant-frontend==20211220.0 +home-assistant-frontend==20211227.0 # homeassistant.components.zwave homeassistant-pyozw==0.1.10 From 3af82b551c3a1815b48613b90a2b480ca5045328 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Mon, 27 Dec 2021 21:48:25 +0100 Subject: [PATCH 12/13] Bumped version to 2021.12.6 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 814089c45b3..f20d78f9224 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -7,7 +7,7 @@ from homeassistant.backports.enum import StrEnum MAJOR_VERSION: Final = 2021 MINOR_VERSION: Final = 12 -PATCH_VERSION: Final = "5" +PATCH_VERSION: Final = "6" __short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__: Final = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 8, 0) From e54e35367649ff875934795ed1cac3c73d044981 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Mon, 27 Dec 2021 22:33:56 +0100 Subject: [PATCH 13/13] Temporary Shelly hotfix for 2021.12.6 patch release (#62885) --- homeassistant/components/shelly/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/shelly/sensor.py b/homeassistant/components/shelly/sensor.py index 51cb462fa48..bd9041d3344 100644 --- a/homeassistant/components/shelly/sensor.py +++ b/homeassistant/components/shelly/sensor.py @@ -283,7 +283,7 @@ RPC_SENSORS: Final = { device_class=sensor.DEVICE_CLASS_TEMPERATURE, state_class=sensor.STATE_CLASS_MEASUREMENT, default_enabled=False, - entity_category=EntityCategory.DIAGNOSTIC, + entity_category=ENTITY_CATEGORY_DIAGNOSTIC, ), "rssi": RpcAttributeDescription( key="wifi",