Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2024.9.1 #125420

Merged
merged 21 commits into from
Sep 6, 2024
Merged

2024.9.1 #125420

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a14826d
Fix BTHome validate triggers for device with multiple buttons (#125183)
thecode Sep 4, 2024
3c13f4b
Improve play media support in LinkPlay (#125205)
silamon Sep 6, 2024
48fcf58
Revert #122676 Yamaha discovery (#125216)
joostlek Sep 6, 2024
6c15f25
Fix blocking call in yale_smart_alarm (#125255)
gjohansson-ST Sep 4, 2024
84c204a
Don't show input panel if default code provided in envisalink (#125256)
gjohansson-ST Sep 4, 2024
5c20734
Increase AquaCell timeout and handle timeout exception properly (#125…
Jordi1990 Sep 4, 2024
5c8b2cd
Bump aiorussound to 3.0.4 (#125285)
noahhusby Sep 6, 2024
4ed1849
Add follower to the PlayingMode enum (#125294)
silamon Sep 5, 2024
61ee3a9
Don't allow templating min, max, step in config entry template number…
emontnemery Sep 6, 2024
6c640d2
Fix for Hue sending effect None at turn_on command while no effect is…
marcelveldt Sep 6, 2024
7859d31
Lyric: fixed missed snake case conversions (#125382)
dalinicus Sep 6, 2024
edb7c76
Bump pysmlight to 0.0.14 (#125387)
tl-sl Sep 6, 2024
27dc2e1
Bump pypck to 0.7.22 (#125389)
alengwenus Sep 6, 2024
e80e189
Increase coordinator update_interval for fyta (#125393)
dontinelli Sep 6, 2024
973e43a
Fix controlling AC temperature in airtouch5 (#125394)
danzel Sep 6, 2024
a3f42e3
Bump sfrbox-api to 0.0.10 (#125405)
AlexT59 Sep 6, 2024
0b95cf1
Improve handling of old firmware versions (#125406)
tl-sl Sep 6, 2024
5cf89bf
Set min_power similar to max_power to support all inverters from apsy…
mawoka-myblock Sep 6, 2024
1c7c6d6
Update frontend to 20240906.0 (#125409)
piitaya Sep 6, 2024
b50d8fc
Bump pyatv to 0.15.1 (#125412)
postlund Sep 6, 2024
ed2d321
Bump version to 2024.9.1
balloob Sep 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion homeassistant/components/airtouch5/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@
_LOGGER.debug("Argument `temperature` is missing in set_temperature")
return

await self._control(temp=temp)
await self._control(setpoint=SetpointControl.CHANGE_SETPOINT, temp=temp)

Check warning on line 265 in homeassistant/components/airtouch5/climate.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/airtouch5/climate.py#L265

Added line #L265 was not covered by tests


class Airtouch5Zone(Airtouch5ClimateEntity):
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/apple_tv/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"documentation": "https://www.home-assistant.io/integrations/apple_tv",
"iot_class": "local_push",
"loggers": ["pyatv", "srptools"],
"requirements": ["pyatv==0.15.0"],
"requirements": ["pyatv==0.15.1"],
"zeroconf": [
"_mediaremotetv._tcp.local.",
"_companion-link._tcp.local.",
Expand Down
5 changes: 3 additions & 2 deletions homeassistant/components/apsystems/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ def __init__(self, hass: HomeAssistant, api: APsystemsEZ1M) -> None:

async def _async_setup(self) -> None:
try:
max_power = (await self.api.get_device_info()).maxPower
device_info = await self.api.get_device_info()
except (ConnectionError, TimeoutError):
raise UpdateFailed from None
self.api.max_power = max_power
self.api.max_power = device_info.maxPower
self.api.min_power = device_info.minPower

async def _async_update_data(self) -> ApSystemsSensorData:
output_data = await self.api.get_output_data()
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/apsystems/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
class ApSystemsMaxOutputNumber(ApSystemsEntity, NumberEntity):
"""Base sensor to be used with description."""

_attr_native_min_value = 30
_attr_native_step = 1
_attr_device_class = NumberDeviceClass.POWER
_attr_mode = NumberMode.BOX
Expand All @@ -42,6 +41,7 @@
self._api = data.coordinator.api
self._attr_unique_id = f"{data.device_id}_output_limit"
self._attr_native_max_value = data.coordinator.api.max_power
self._attr_native_min_value = data.coordinator.api.min_power

Check warning on line 44 in homeassistant/components/apsystems/number.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/apsystems/number.py#L44

Added line #L44 was not covered by tests

async def async_update(self) -> None:
"""Set the state with the value fetched from the inverter."""
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/aquacell/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ async def async_step_user(
refresh_token = await api.authenticate(
user_input[CONF_EMAIL], user_input[CONF_PASSWORD]
)
except ApiException:
except (ApiException, TimeoutError):
errors["base"] = "cannot_connect"
except AuthenticationFailed:
errors["base"] = "invalid_auth"
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/aquacell/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ async def _async_update_data(self) -> dict[str, Softener]:
so entities can quickly look up their data.
"""

async with asyncio.timeout(10):
async with asyncio.timeout(30):
# Check if the refresh token is expired
expiry_time = (
self.refresh_token_creation_time
Expand All @@ -72,7 +72,7 @@ async def _async_update_data(self) -> dict[str, Softener]:
softeners = await self.aquacell_api.get_all_softeners()
except AuthenticationFailed as err:
raise ConfigEntryError from err
except AquacellApiException as err:
except (AquacellApiException, TimeoutError) as err:
raise UpdateFailed(f"Error communicating with API: {err}") from err

return {softener.dsn: softener for softener in softeners}
Expand Down
56 changes: 36 additions & 20 deletions homeassistant/components/bthome/device_trigger.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
import voluptuous as vol

from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.components.device_automation.exceptions import (
InvalidDeviceAutomationConfig,
)
from homeassistant.components.homeassistant.triggers import event as event_trigger
from homeassistant.const import (
CONF_DEVICE_ID,
Expand Down Expand Up @@ -43,34 +46,47 @@
EVENT_CLASS_DIMMER: {"rotate_left", "rotate_right"},
}

SCHEMA_BY_EVENT_CLASS = {
EVENT_CLASS_BUTTON: DEVICE_TRIGGER_BASE_SCHEMA.extend(
{
vol.Required(CONF_TYPE): vol.In([EVENT_CLASS_BUTTON]),
vol.Required(CONF_SUBTYPE): vol.In(
TRIGGERS_BY_EVENT_CLASS[EVENT_CLASS_BUTTON]
),
}
),
EVENT_CLASS_DIMMER: DEVICE_TRIGGER_BASE_SCHEMA.extend(
{
vol.Required(CONF_TYPE): vol.In([EVENT_CLASS_DIMMER]),
vol.Required(CONF_SUBTYPE): vol.In(
TRIGGERS_BY_EVENT_CLASS[EVENT_CLASS_DIMMER]
),
}
),
}
TRIGGER_SCHEMA = DEVICE_TRIGGER_BASE_SCHEMA.extend(
{vol.Required(CONF_TYPE): str, vol.Required(CONF_SUBTYPE): str}
)


async def async_validate_trigger_config(
hass: HomeAssistant, config: ConfigType
) -> ConfigType:
"""Validate trigger config."""
return SCHEMA_BY_EVENT_CLASS.get(config[CONF_TYPE], DEVICE_TRIGGER_BASE_SCHEMA)( # type: ignore[no-any-return]
config
config = TRIGGER_SCHEMA(config)
event_class = config[CONF_TYPE]
event_type = config[CONF_SUBTYPE]

device_registry = dr.async_get(hass)
device = device_registry.async_get(config[CONF_DEVICE_ID])
assert device is not None
config_entries = [
hass.config_entries.async_get_entry(entry_id)
for entry_id in device.config_entries
]
bthome_config_entry = next(
iter(entry for entry in config_entries if entry and entry.domain == DOMAIN)
)
event_classes: list[str] = bthome_config_entry.data.get(
CONF_DISCOVERED_EVENT_CLASSES, []
)

if event_class not in event_classes:
raise InvalidDeviceAutomationConfig(
f"BTHome trigger {event_class} is not valid for device "
f"{device} ({config[CONF_DEVICE_ID]})"
)

if event_type not in TRIGGERS_BY_EVENT_CLASS.get(event_class.split("_")[0], ()):
raise InvalidDeviceAutomationConfig(
f"BTHome trigger {event_type} is not valid for device "
f"{device} ({config[CONF_DEVICE_ID]})"
)

return config


async def async_get_triggers(
hass: HomeAssistant, device_id: str
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/envisalink/alarm_control_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@
self._partition_number = partition_number
self._panic_type = panic_type
self._alarm_control_panel_option_default_code = code
self._attr_code_format = CodeFormat.NUMBER
self._attr_code_format = CodeFormat.NUMBER if not code else None

Check warning on line 122 in homeassistant/components/envisalink/alarm_control_panel.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/envisalink/alarm_control_panel.py#L122

Added line #L122 was not covered by tests

_LOGGER.debug("Setting up alarm: %s", alarm_name)
super().__init__(alarm_name, info, controller)
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/frontend/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@
"documentation": "https://www.home-assistant.io/integrations/frontend",
"integration_type": "system",
"quality_scale": "internal",
"requirements": ["home-assistant-frontend==20240904.0"]
"requirements": ["home-assistant-frontend==20240906.0"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/fyta/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def __init__(self, hass: HomeAssistant, fyta: FytaConnector) -> None:
hass,
_LOGGER,
name="FYTA Coordinator",
update_interval=timedelta(seconds=60),
update_interval=timedelta(minutes=4),
)
self.fyta = fyta

Expand Down
6 changes: 5 additions & 1 deletion homeassistant/components/hue/v2/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,11 @@ async def async_turn_on(self, **kwargs: Any) -> None:
flash = kwargs.get(ATTR_FLASH)
effect = effect_str = kwargs.get(ATTR_EFFECT)
if effect_str in (EFFECT_NONE, EFFECT_NONE.lower()):
effect = EffectStatus.NO_EFFECT
# ignore effect if set to "None" and we have no effect active
# the special effect "None" is only used to stop an active effect
# but sending it while no effect is active can actually result in issues
# https://github.com/home-assistant/core/issues/122165
effect = None if self.effect == EFFECT_NONE else EffectStatus.NO_EFFECT
elif effect_str is not None:
# work out if we got a regular effect or timed effect
effect = EffectStatus(effect_str)
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/lcn/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
"documentation": "https://www.home-assistant.io/integrations/lcn",
"iot_class": "local_push",
"loggers": ["pypck"],
"requirements": ["pypck==0.7.21", "lcn-frontend==0.1.6"]
"requirements": ["pypck==0.7.22", "lcn-frontend==0.1.6"]
}
16 changes: 12 additions & 4 deletions homeassistant/components/linkplay/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
MediaType,
RepeatMode,
)
from homeassistant.components.media_player.browse_media import (

Check warning on line 23 in homeassistant/components/linkplay/media_player.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/linkplay/media_player.py#L23

Added line #L23 was not covered by tests
async_process_play_media_url,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import device_registry as dr
Expand Down Expand Up @@ -59,6 +62,7 @@
PlayingMode.FM: "FM Radio",
PlayingMode.RCA: "RCA",
PlayingMode.UDISK: "USB",
PlayingMode.FOLLOWER: "Follower",
}

SOURCE_MAP_INV: dict[str, PlayingMode] = {v: k for k, v in SOURCE_MAP.items()}
Expand Down Expand Up @@ -233,10 +237,14 @@
self, media_type: MediaType | str, media_id: str, **kwargs: Any
) -> None:
"""Play a piece of media."""
media = await media_source.async_resolve_media(
self.hass, media_id, self.entity_id
)
await self._bridge.player.play(media.url)
if media_source.is_media_source_id(media_id):
play_item = await media_source.async_resolve_media(

Check warning on line 241 in homeassistant/components/linkplay/media_player.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/linkplay/media_player.py#L240-L241

Added lines #L240 - L241 were not covered by tests
self.hass, media_id, self.entity_id
)
media_id = play_item.url

Check warning on line 244 in homeassistant/components/linkplay/media_player.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/linkplay/media_player.py#L244

Added line #L244 was not covered by tests

url = async_process_play_media_url(self.hass, media_id)
await self._bridge.player.play(url)

Check warning on line 247 in homeassistant/components/linkplay/media_player.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/linkplay/media_player.py#L246-L247

Added lines #L246 - L247 were not covered by tests

def _update_properties(self) -> None:
"""Update the properties of the media player."""
Expand Down
26 changes: 13 additions & 13 deletions homeassistant/components/lyric/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,8 @@ async def async_set_temperature(self, **kwargs: Any) -> None:
await self._update_thermostat(
self.location,
device,
coolSetpoint=target_temp_high,
heatSetpoint=target_temp_low,
cool_setpoint=target_temp_high,
heat_setpoint=target_temp_low,
mode=mode,
)
except LYRIC_EXCEPTIONS as exception:
Expand All @@ -371,11 +371,11 @@ async def async_set_temperature(self, **kwargs: Any) -> None:
try:
if self.hvac_mode == HVACMode.COOL:
await self._update_thermostat(
self.location, device, coolSetpoint=temp
self.location, device, cool_setpoint=temp
)
else:
await self._update_thermostat(
self.location, device, heatSetpoint=temp
self.location, device, heat_setpoint=temp
)
except LYRIC_EXCEPTIONS as exception:
_LOGGER.error(exception)
Expand Down Expand Up @@ -410,7 +410,7 @@ async def _async_set_hvac_mode_tcc(self, hvac_mode: HVACMode) -> None:
self.location,
self.device,
mode=HVAC_MODES[LYRIC_HVAC_MODE_HEAT],
autoChangeoverActive=False,
auto_changeover_active=False,
)
# Sleep 3 seconds before proceeding
await asyncio.sleep(3)
Expand All @@ -422,29 +422,29 @@ async def _async_set_hvac_mode_tcc(self, hvac_mode: HVACMode) -> None:
self.location,
self.device,
mode=HVAC_MODES[LYRIC_HVAC_MODE_HEAT],
autoChangeoverActive=True,
auto_changeover_active=True,
)
else:
_LOGGER.debug(
"HVAC mode passed to lyric: %s",
HVAC_MODES[self.device.changeable_values.mode],
)
await self._update_thermostat(
self.location, self.device, autoChangeoverActive=True
self.location, self.device, auto_changeover_active=True
)
else:
_LOGGER.debug("HVAC mode passed to lyric: %s", LYRIC_HVAC_MODES[hvac_mode])
await self._update_thermostat(
self.location,
self.device,
mode=LYRIC_HVAC_MODES[hvac_mode],
autoChangeoverActive=False,
auto_changeover_active=False,
)

async def _async_set_hvac_mode_lcc(self, hvac_mode: HVACMode) -> None:
"""Set hvac mode for LCC devices (e.g., T5,6)."""
_LOGGER.debug("HVAC mode passed to lyric: %s", LYRIC_HVAC_MODES[hvac_mode])
# Set autoChangeoverActive to True if the mode being passed is Auto
# Set auto_changeover_active to True if the mode being passed is Auto
# otherwise leave unchanged.
if (
LYRIC_HVAC_MODES[hvac_mode] == LYRIC_HVAC_MODE_HEAT_COOL
Expand All @@ -458,15 +458,15 @@ async def _async_set_hvac_mode_lcc(self, hvac_mode: HVACMode) -> None:
self.location,
self.device,
mode=LYRIC_HVAC_MODES[hvac_mode],
autoChangeoverActive=auto_changeover,
auto_changeover_active=auto_changeover,
)

async def async_set_preset_mode(self, preset_mode: str) -> None:
"""Set preset (PermanentHold, HoldUntil, NoHold, VacationHold) mode."""
_LOGGER.debug("Set preset mode: %s", preset_mode)
try:
await self._update_thermostat(
self.location, self.device, thermostatSetpointStatus=preset_mode
self.location, self.device, thermostat_setpoint_status=preset_mode
)
except LYRIC_EXCEPTIONS as exception:
_LOGGER.error(exception)
Expand All @@ -479,8 +479,8 @@ async def async_set_hold_time(self, time_period: str) -> None:
await self._update_thermostat(
self.location,
self.device,
thermostatSetpointStatus=PRESET_HOLD_UNTIL,
nextPeriodTime=time_period,
thermostat_setpoint_status=PRESET_HOLD_UNTIL,
next_period_time=time_period,
)
except LYRIC_EXCEPTIONS as exception:
_LOGGER.error(exception)
Expand Down
10 changes: 4 additions & 6 deletions homeassistant/components/russound_rio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import asyncio
import logging

from aiorussound import Russound
from aiorussound import RussoundClient, RussoundTcpConnectionHandler

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PORT, Platform
Expand All @@ -16,15 +16,15 @@

_LOGGER = logging.getLogger(__name__)

type RussoundConfigEntry = ConfigEntry[Russound]
type RussoundConfigEntry = ConfigEntry[RussoundClient]


async def async_setup_entry(hass: HomeAssistant, entry: RussoundConfigEntry) -> bool:
"""Set up a config entry."""

host = entry.data[CONF_HOST]
port = entry.data[CONF_PORT]
russ = Russound(hass.loop, host, port)
russ = RussoundClient(RussoundTcpConnectionHandler(hass.loop, host, port))

Check warning on line 27 in homeassistant/components/russound_rio/__init__.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/russound_rio/__init__.py#L27

Added line #L27 was not covered by tests

@callback
def is_connected_updated(connected: bool) -> None:
Expand All @@ -37,14 +37,12 @@
port,
)

russ.add_connection_callback(is_connected_updated)

russ.connection_handler.add_connection_callback(is_connected_updated)

Check warning on line 40 in homeassistant/components/russound_rio/__init__.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/russound_rio/__init__.py#L40

Added line #L40 was not covered by tests
try:
async with asyncio.timeout(CONNECT_TIMEOUT):
await russ.connect()
except RUSSOUND_RIO_EXCEPTIONS as err:
raise ConfigEntryNotReady(f"Error while connecting to {host}:{port}") from err

entry.runtime_data = russ

await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
Expand Down
Loading
Loading