Skip to content

Commit

Permalink
2024.4.4 (#116045)
Browse files Browse the repository at this point in the history
  • Loading branch information
frenck committed Apr 23, 2024
2 parents efe9181 + 4d551d6 commit 60be2af
Show file tree
Hide file tree
Showing 46 changed files with 935 additions and 285 deletions.
8 changes: 8 additions & 0 deletions homeassistant/components/airthings/sensor.py
Expand Up @@ -157,3 +157,11 @@ def __init__(
def native_value(self) -> StateType:
"""Return the value reported by the sensor."""
return self.coordinator.data[self._id].sensors[self.entity_description.key] # type: ignore[no-any-return]

@property
def available(self) -> bool:
"""Check if device and sensor is available in data."""
return (
super().available
and self.entity_description.key in self.coordinator.data[self._id].sensors
)
2 changes: 1 addition & 1 deletion homeassistant/components/doods/manifest.json
Expand Up @@ -5,5 +5,5 @@
"documentation": "https://www.home-assistant.io/integrations/doods",
"iot_class": "local_polling",
"loggers": ["pydoods"],
"requirements": ["pydoods==1.0.2", "Pillow==10.2.0"]
"requirements": ["pydoods==1.0.2", "Pillow==10.3.0"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/generic/manifest.json
Expand Up @@ -6,5 +6,5 @@
"dependencies": ["http"],
"documentation": "https://www.home-assistant.io/integrations/generic",
"iot_class": "local_push",
"requirements": ["ha-av==10.1.1", "Pillow==10.2.0"]
"requirements": ["ha-av==10.1.1", "Pillow==10.3.0"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/google/manifest.json
Expand Up @@ -7,5 +7,5 @@
"documentation": "https://www.home-assistant.io/integrations/calendar.google",
"iot_class": "cloud_polling",
"loggers": ["googleapiclient"],
"requirements": ["gcal-sync==6.0.4", "oauth2client==4.1.3", "ical==7.0.3"]
"requirements": ["gcal-sync==6.0.4", "oauth2client==4.1.3", "ical==8.0.0"]
}
12 changes: 2 additions & 10 deletions homeassistant/components/homeworks/config_flow.py
Expand Up @@ -93,7 +93,7 @@
}


validate_addr = cv.matches_regex(r"\[\d\d:\d\d:\d\d:\d\d\]")
validate_addr = cv.matches_regex(r"\[(?:\d\d:)?\d\d:\d\d:\d\d\]")


async def validate_add_controller(
Expand Down Expand Up @@ -565,15 +565,7 @@ async def async_step_import(self, config: dict[str, Any]) -> ConfigFlowResult:
CONF_KEYPADS: [
{
CONF_ADDR: keypad[CONF_ADDR],
CONF_BUTTONS: [
{
CONF_LED: button[CONF_LED],
CONF_NAME: button[CONF_NAME],
CONF_NUMBER: button[CONF_NUMBER],
CONF_RELEASE_DELAY: button[CONF_RELEASE_DELAY],
}
for button in keypad[CONF_BUTTONS]
],
CONF_BUTTONS: [],
CONF_NAME: keypad[CONF_NAME],
}
for keypad in config[CONF_KEYPADS]
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/hyperion/sensor.py
Expand Up @@ -191,13 +191,13 @@ def _update_priorities(self, _: dict[str, Any] | None = None) -> None:
if priority[KEY_COMPONENTID] == "COLOR":
state_value = priority[KEY_VALUE][KEY_RGB]
else:
state_value = priority[KEY_OWNER]
state_value = priority.get(KEY_OWNER)

attrs = {
"component_id": priority[KEY_COMPONENTID],
"origin": priority[KEY_ORIGIN],
"priority": priority[KEY_PRIORITY],
"owner": priority[KEY_OWNER],
"owner": priority.get(KEY_OWNER),
}

if priority[KEY_COMPONENTID] == "COLOR":
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/image_upload/manifest.json
Expand Up @@ -7,5 +7,5 @@
"documentation": "https://www.home-assistant.io/integrations/image_upload",
"integration_type": "system",
"quality_scale": "internal",
"requirements": ["Pillow==10.2.0"]
"requirements": ["Pillow==10.3.0"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/local_calendar/manifest.json
Expand Up @@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/local_calendar",
"iot_class": "local_polling",
"loggers": ["ical"],
"requirements": ["ical==7.0.3"]
"requirements": ["ical==8.0.0"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/local_todo/manifest.json
Expand Up @@ -5,5 +5,5 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/local_todo",
"iot_class": "local_polling",
"requirements": ["ical==7.0.3"]
"requirements": ["ical==8.0.0"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/matrix/manifest.json
Expand Up @@ -5,5 +5,5 @@
"documentation": "https://www.home-assistant.io/integrations/matrix",
"iot_class": "cloud_push",
"loggers": ["matrix_client"],
"requirements": ["matrix-nio==0.24.0", "Pillow==10.2.0"]
"requirements": ["matrix-nio==0.24.0", "Pillow==10.3.0"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/modbus/manifest.json
Expand Up @@ -6,5 +6,5 @@
"iot_class": "local_polling",
"loggers": ["pymodbus"],
"quality_scale": "platinum",
"requirements": ["pymodbus==3.6.7"]
"requirements": ["pymodbus==3.6.8"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/plex/manifest.json
Expand Up @@ -8,7 +8,7 @@
"iot_class": "local_push",
"loggers": ["plexapi", "plexwebsocket"],
"requirements": [
"PlexAPI==4.15.11",
"PlexAPI==4.15.12",
"plexauth==0.0.6",
"plexwebsocket==0.0.14"
],
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/proxy/manifest.json
Expand Up @@ -3,5 +3,5 @@
"name": "Camera Proxy",
"codeowners": [],
"documentation": "https://www.home-assistant.io/integrations/proxy",
"requirements": ["Pillow==10.2.0"]
"requirements": ["Pillow==10.3.0"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/qrcode/manifest.json
Expand Up @@ -5,5 +5,5 @@
"documentation": "https://www.home-assistant.io/integrations/qrcode",
"iot_class": "calculated",
"loggers": ["pyzbar"],
"requirements": ["Pillow==10.2.0", "pyzbar==0.1.7"]
"requirements": ["Pillow==10.3.0", "pyzbar==0.1.7"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/renault/manifest.json
Expand Up @@ -8,5 +8,5 @@
"iot_class": "cloud_polling",
"loggers": ["renault_api"],
"quality_scale": "platinum",
"requirements": ["renault-api==0.2.1"]
"requirements": ["renault-api==0.2.2"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/renault/select.py
Expand Up @@ -71,6 +71,6 @@ async def async_select_option(self, option: str) -> None:
coordinator="charge_mode",
data_key="chargeMode",
translation_key="charge_mode",
options=["always", "always_charging", "schedule_mode"],
options=["always", "always_charging", "schedule_mode", "scheduled"],
),
)
14 changes: 8 additions & 6 deletions homeassistant/components/samsungtv/media_player.py
Expand Up @@ -46,15 +46,17 @@
SOURCES = {"TV": "KEY_TV", "HDMI": "KEY_HDMI"}

SUPPORT_SAMSUNGTV = (
MediaPlayerEntityFeature.PAUSE
| MediaPlayerEntityFeature.VOLUME_STEP
| MediaPlayerEntityFeature.VOLUME_MUTE
MediaPlayerEntityFeature.NEXT_TRACK
| MediaPlayerEntityFeature.PAUSE
| MediaPlayerEntityFeature.PLAY
| MediaPlayerEntityFeature.PLAY_MEDIA
| MediaPlayerEntityFeature.PREVIOUS_TRACK
| MediaPlayerEntityFeature.SELECT_SOURCE
| MediaPlayerEntityFeature.NEXT_TRACK
| MediaPlayerEntityFeature.STOP
| MediaPlayerEntityFeature.TURN_OFF
| MediaPlayerEntityFeature.PLAY
| MediaPlayerEntityFeature.PLAY_MEDIA
| MediaPlayerEntityFeature.VOLUME_MUTE
| MediaPlayerEntityFeature.VOLUME_SET
| MediaPlayerEntityFeature.VOLUME_STEP
)


Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/seven_segments/manifest.json
Expand Up @@ -4,5 +4,5 @@
"codeowners": ["@fabaff"],
"documentation": "https://www.home-assistant.io/integrations/seven_segments",
"iot_class": "local_polling",
"requirements": ["Pillow==10.2.0"]
"requirements": ["Pillow==10.3.0"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/sighthound/manifest.json
Expand Up @@ -5,5 +5,5 @@
"documentation": "https://www.home-assistant.io/integrations/sighthound",
"iot_class": "cloud_polling",
"loggers": ["simplehound"],
"requirements": ["Pillow==10.2.0", "simplehound==0.3"]
"requirements": ["Pillow==10.3.0", "simplehound==0.3"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/sql/manifest.json
Expand Up @@ -5,5 +5,5 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/sql",
"iot_class": "local_polling",
"requirements": ["SQLAlchemy==2.0.29", "sqlparse==0.4.4"]
"requirements": ["SQLAlchemy==2.0.29", "sqlparse==0.5.0"]
}
9 changes: 2 additions & 7 deletions homeassistant/components/squeezebox/media_player.py
Expand Up @@ -28,7 +28,6 @@
CONF_PASSWORD,
CONF_PORT,
CONF_USERNAME,
EVENT_HOMEASSISTANT_START,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import (
Expand All @@ -44,6 +43,7 @@
)
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.event import async_call_later
from homeassistant.helpers.start import async_at_start
from homeassistant.util.dt import utcnow

from .browse_media import (
Expand Down Expand Up @@ -207,12 +207,7 @@ async def _discovered_player(player):
platform.async_register_entity_service(SERVICE_UNSYNC, None, "async_unsync")

# Start server discovery task if not already running
if hass.is_running:
hass.async_create_task(start_server_discovery(hass))
else:
hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_START, start_server_discovery(hass)
)
config_entry.async_on_unload(async_at_start(hass, start_server_discovery))


class SqueezeBoxEntity(MediaPlayerEntity):
Expand Down
6 changes: 3 additions & 3 deletions homeassistant/components/tankerkoenig/sensor.py
Expand Up @@ -91,7 +91,7 @@ def __init__(
self._fuel_type = fuel_type
self._attr_translation_key = fuel_type
self._attr_unique_id = f"{station.id}_{fuel_type}"
attrs = {
attrs: dict[str, int | str | float | None] = {
ATTR_BRAND: station.brand,
ATTR_FUEL_TYPE: fuel_type,
ATTR_STATION_NAME: station.name,
Expand All @@ -102,8 +102,8 @@ def __init__(
}

if coordinator.show_on_map:
attrs[ATTR_LATITUDE] = str(station.lat)
attrs[ATTR_LONGITUDE] = str(station.lng)
attrs[ATTR_LATITUDE] = station.lat
attrs[ATTR_LONGITUDE] = station.lng
self._attr_extra_state_attributes = attrs

@property
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/tensorflow/manifest.json
Expand Up @@ -10,6 +10,6 @@
"tf-models-official==2.5.0",
"pycocotools==2.0.6",
"numpy==1.26.0",
"Pillow==10.2.0"
"Pillow==10.3.0"
]
}
8 changes: 7 additions & 1 deletion homeassistant/components/teslemetry/sensor.py
Expand Up @@ -58,7 +58,7 @@
class TeslemetrySensorEntityDescription(SensorEntityDescription):
"""Describes Teslemetry Sensor entity."""

value_fn: Callable[[StateType], StateType | datetime] = lambda x: x
value_fn: Callable[[StateType], StateType] = lambda x: x


VEHICLE_DESCRIPTIONS: tuple[TeslemetrySensorEntityDescription, ...] = (
Expand Down Expand Up @@ -447,8 +447,14 @@ def __init__(
description: TeslemetrySensorEntityDescription,
) -> None:
"""Initialize the sensor."""
self.entity_description = description
super().__init__(vehicle, description.key)

@property
def native_value(self) -> StateType:
"""Return the state of the sensor."""
return self.entity_description.value_fn(self._value)


class TeslemetryVehicleTimeSensorEntity(TeslemetryVehicleEntity, SensorEntity):
"""Base class for Teslemetry vehicle metric sensors."""
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/unifi/manifest.json
Expand Up @@ -8,7 +8,7 @@
"iot_class": "local_push",
"loggers": ["aiounifi"],
"quality_scale": "platinum",
"requirements": ["aiounifi==74"],
"requirements": ["aiounifi==75"],
"ssdp": [
{
"manufacturer": "Ubiquiti Networks",
Expand Down
7 changes: 6 additions & 1 deletion homeassistant/components/withings/__init__.py
Expand Up @@ -12,6 +12,7 @@
from datetime import timedelta
from typing import TYPE_CHECKING, Any, cast

from aiohttp import ClientError
from aiohttp.hdrs import METH_POST
from aiohttp.web import Request, Response
from aiowithings import NotificationCategory, WithingsClient
Expand Down Expand Up @@ -340,7 +341,11 @@ async def register_webhook(

async def async_unsubscribe_webhooks(client: WithingsClient) -> None:
"""Unsubscribe to all Withings webhooks."""
current_webhooks = await client.list_notification_configurations()
try:
current_webhooks = await client.list_notification_configurations()
except ClientError:
LOGGER.exception("Error when unsubscribing webhooks")
return

for webhook_configuration in current_webhooks:
LOGGER.debug(
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/xmpp/manifest.json
Expand Up @@ -5,5 +5,5 @@
"documentation": "https://www.home-assistant.io/integrations/xmpp",
"iot_class": "cloud_push",
"loggers": ["pyasn1", "slixmpp"],
"requirements": ["slixmpp==1.8.4", "emoji==2.8.0"]
"requirements": ["slixmpp==1.8.5", "emoji==2.8.0"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/zeroconf/manifest.json
Expand Up @@ -8,5 +8,5 @@
"iot_class": "local_push",
"loggers": ["zeroconf"],
"quality_scale": "internal",
"requirements": ["zeroconf==0.132.0"]
"requirements": ["zeroconf==0.132.2"]
}
2 changes: 1 addition & 1 deletion homeassistant/const.py
Expand Up @@ -18,7 +18,7 @@
APPLICATION_NAME: Final = "HomeAssistant"
MAJOR_VERSION: Final = 2024
MINOR_VERSION: Final = 4
PATCH_VERSION: Final = "3"
PATCH_VERSION: Final = "4"
__short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}"
__version__: Final = f"{__short_version__}.{PATCH_VERSION}"
REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 12, 0)
Expand Down
25 changes: 20 additions & 5 deletions homeassistant/helpers/script.py
Expand Up @@ -656,6 +656,12 @@ async def _async_wait_template_step(self):
# check if condition already okay
if condition.async_template(self._hass, wait_template, self._variables, False):
self._variables["wait"]["completed"] = True
self._changed()
return

if timeout == 0:
self._changed()
self._async_handle_timeout()
return

futures, timeout_handle, timeout_future = self._async_futures_with_timeout(
Expand Down Expand Up @@ -1085,6 +1091,11 @@ async def _async_wait_for_trigger_step(self):
self._variables["wait"] = {"remaining": timeout, "trigger": None}
trace_set_result(wait=self._variables["wait"])

if timeout == 0:
self._changed()
self._async_handle_timeout()
return

futures, timeout_handle, timeout_future = self._async_futures_with_timeout(
timeout
)
Expand Down Expand Up @@ -1115,6 +1126,14 @@ def log_cb(level, msg, **kwargs):
futures, timeout_handle, timeout_future, remove_triggers
)

def _async_handle_timeout(self) -> None:
"""Handle timeout."""
self._variables["wait"]["remaining"] = 0.0
if not self._action.get(CONF_CONTINUE_ON_TIMEOUT, True):
self._log(_TIMEOUT_MSG)
trace_set_result(wait=self._variables["wait"], timeout=True)
raise _AbortScript from TimeoutError()

async def _async_wait_with_optional_timeout(
self,
futures: list[asyncio.Future[None]],
Expand All @@ -1125,11 +1144,7 @@ async def _async_wait_with_optional_timeout(
try:
await asyncio.wait(futures, return_when=asyncio.FIRST_COMPLETED)
if timeout_future and timeout_future.done():
self._variables["wait"]["remaining"] = 0.0
if not self._action.get(CONF_CONTINUE_ON_TIMEOUT, True):
self._log(_TIMEOUT_MSG)
trace_set_result(wait=self._variables["wait"], timeout=True)
raise _AbortScript from TimeoutError()
self._async_handle_timeout()
finally:
if timeout_future and not timeout_future.done() and timeout_handle:
timeout_handle.cancel()
Expand Down

0 comments on commit 60be2af

Please sign in to comment.