Skip to content

Commit

Permalink
2024.2.2 (#110720)
Browse files Browse the repository at this point in the history
  • Loading branch information
frenck committed Feb 16, 2024
2 parents cfd1f78 + b55b2c8 commit 7aa14e2
Show file tree
Hide file tree
Showing 80 changed files with 544 additions and 278 deletions.
7 changes: 4 additions & 3 deletions homeassistant/components/august/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,10 +249,11 @@ def async_pubnub_message(
device = self.get_device_detail(device_id)
activities = activities_from_pubnub_message(device, date_time, message)
activity_stream = self.activity_stream
if activities:
activity_stream.async_process_newer_device_activities(activities)
if activities and activity_stream.async_process_newer_device_activities(
activities
):
self.async_signal_device_id_update(device.device_id)
activity_stream.async_schedule_house_id_refresh(device.house_id)
activity_stream.async_schedule_house_id_refresh(device.house_id)

@callback
def async_stop(self) -> None:
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/august/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@
"documentation": "https://www.home-assistant.io/integrations/august",
"iot_class": "cloud_push",
"loggers": ["pubnub", "yalexs"],
"requirements": ["yalexs==1.10.0", "yalexs-ble==2.4.1"]
"requirements": ["yalexs==1.11.2", "yalexs-ble==2.4.1"]
}
3 changes: 3 additions & 0 deletions homeassistant/components/co2signal/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
ElectricityMaps,
ElectricityMapsError,
ElectricityMapsInvalidTokenError,
ElectricityMapsNoDataError,
)
import voluptuous as vol

Expand Down Expand Up @@ -151,6 +152,8 @@ async def _validate_and_create(
await fetch_latest_carbon_intensity(self.hass, em, data)
except ElectricityMapsInvalidTokenError:
errors["base"] = "invalid_auth"
except ElectricityMapsNoDataError:
errors["base"] = "no_data"
except ElectricityMapsError:
errors["base"] = "unknown"
else:
Expand Down
5 changes: 1 addition & 4 deletions homeassistant/components/co2signal/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,9 @@
"error": {
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"unknown": "[%key:common::config_flow::error::unknown%]",
"api_ratelimit": "API Ratelimit exceeded"
"no_data": "No data is available for the location you have selected."
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"unknown": "[%key:common::config_flow::error::unknown%]",
"api_ratelimit": "[%key:component::co2signal::config::error::api_ratelimit%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
}
},
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/dlna_dmr/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"documentation": "https://www.home-assistant.io/integrations/dlna_dmr",
"iot_class": "local_push",
"loggers": ["async_upnp_client"],
"requirements": ["async-upnp-client==0.38.1", "getmac==0.9.4"],
"requirements": ["async-upnp-client==0.38.2", "getmac==0.9.4"],
"ssdp": [
{
"deviceType": "urn:schemas-upnp-org:device:MediaRenderer:1",
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/dlna_dms/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"documentation": "https://www.home-assistant.io/integrations/dlna_dms",
"iot_class": "local_polling",
"quality_scale": "platinum",
"requirements": ["async-upnp-client==0.38.1"],
"requirements": ["async-upnp-client==0.38.2"],
"ssdp": [
{
"deviceType": "urn:schemas-upnp-org:device:MediaServer:1",
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/ecovacs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/ecovacs",
"iot_class": "cloud_push",
"loggers": ["sleekxmppfs", "sucks", "deebot_client"],
"requirements": ["py-sucks==0.9.8", "deebot-client==5.1.1"]
"requirements": ["py-sucks==0.9.9", "deebot-client==5.2.1"]
}
28 changes: 18 additions & 10 deletions homeassistant/components/elkm1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from typing import Any

from elkm1_lib.elements import Element
from elkm1_lib.elk import Elk
from elkm1_lib.elk import Elk, Panel
from elkm1_lib.util import parse_url
import voluptuous as vol

Expand Down Expand Up @@ -398,22 +398,30 @@ def sync_complete() -> None:
return success


@callback
def _async_get_elk_panel(hass: HomeAssistant, service: ServiceCall) -> Panel:
"""Get the ElkM1 panel from a service call."""
prefix = service.data["prefix"]
elk = _find_elk_by_prefix(hass, prefix)
if elk is None:
raise HomeAssistantError(f"No ElkM1 with prefix '{prefix}' found")
return elk.panel


def _create_elk_services(hass: HomeAssistant) -> None:
def _getelk(service: ServiceCall) -> Elk:
prefix = service.data["prefix"]
elk = _find_elk_by_prefix(hass, prefix)
if elk is None:
raise HomeAssistantError(f"No ElkM1 with prefix '{prefix}' found")
return elk
"""Create ElkM1 services."""

@callback
def _speak_word_service(service: ServiceCall) -> None:
_getelk(service).panel.speak_word(service.data["number"])
_async_get_elk_panel(hass, service).speak_word(service.data["number"])

@callback
def _speak_phrase_service(service: ServiceCall) -> None:
_getelk(service).panel.speak_phrase(service.data["number"])
_async_get_elk_panel(hass, service).speak_phrase(service.data["number"])

@callback
def _set_time_service(service: ServiceCall) -> None:
_getelk(service).panel.set_time(dt_util.now())
_async_get_elk_panel(hass, service).set_time(dt_util.now())

hass.services.async_register(
DOMAIN, "speak_word", _speak_word_service, SPEAK_SERVICE_SCHEMA
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/evohome/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"documentation": "https://www.home-assistant.io/integrations/evohome",
"iot_class": "cloud_polling",
"loggers": ["evohomeasync", "evohomeasync2"],
"requirements": ["evohome-async==0.4.18"]
"requirements": ["evohome-async==0.4.19"]
}
4 changes: 2 additions & 2 deletions homeassistant/components/freebox/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from homeassistant.data_entry_flow import FlowResult

from .const import DOMAIN
from .router import get_api
from .router import get_api, get_hosts_list_if_supported

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -69,7 +69,7 @@ async def async_step_link(

# Check permissions
await fbx.system.get_config()
await fbx.lan.get_hosts_list()
await get_hosts_list_if_supported(fbx)

# Close connection
await fbx.close()
Expand Down
51 changes: 30 additions & 21 deletions homeassistant/components/freebox/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,33 @@ async def get_api(hass: HomeAssistant, host: str) -> Freepybox:
return Freepybox(APP_DESC, token_file, API_VERSION)


async def get_hosts_list_if_supported(
fbx_api: Freepybox,
) -> tuple[bool, list[dict[str, Any]]]:
"""Hosts list is not supported when freebox is configured in bridge mode."""
supports_hosts: bool = True
fbx_devices: list[dict[str, Any]] = []
try:
fbx_devices = await fbx_api.lan.get_hosts_list() or []
except HttpRequestError as err:
if (
(matcher := re.search(r"Request failed \(APIResponse: (.+)\)", str(err)))
and is_json(json_str := matcher.group(1))
and (json_resp := json.loads(json_str)).get("error_code") == "nodev"
):
# No need to retry, Host list not available
supports_hosts = False
_LOGGER.debug(
"Host list is not available using bridge mode (%s)",
json_resp.get("msg"),
)

else:
raise err

return supports_hosts, fbx_devices


class FreeboxRouter:
"""Representation of a Freebox router."""

Expand Down Expand Up @@ -111,27 +138,9 @@ async def update_device_trackers(self) -> None:

# Access to Host list not available in bridge mode, API return error_code 'nodev'
if self.supports_hosts:
try:
fbx_devices = await self._api.lan.get_hosts_list()
except HttpRequestError as err:
if (
(
matcher := re.search(
r"Request failed \(APIResponse: (.+)\)", str(err)
)
)
and is_json(json_str := matcher.group(1))
and (json_resp := json.loads(json_str)).get("error_code") == "nodev"
):
# No need to retry, Host list not available
self.supports_hosts = False
_LOGGER.debug(
"Host list is not available using bridge mode (%s)",
json_resp.get("msg"),
)

else:
raise err
self.supports_hosts, fbx_devices = await get_hosts_list_if_supported(
self._api
)

# Adds the Freebox itself
fbx_devices.append(
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/group/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ def _calculate_state_class(
translation_placeholders={
"entity_id": self.entity_id,
"source_entities": ", ".join(self._entity_ids),
"state_classes:": ", ".join(state_classes),
"state_classes": ", ".join(state_classes),
},
)
return None
Expand Down Expand Up @@ -519,7 +519,7 @@ def _calculate_device_class(
translation_placeholders={
"entity_id": self.entity_id,
"source_entities": ", ".join(self._entity_ids),
"device_classes:": ", ".join(device_classes),
"device_classes": ", ".join(device_classes),
},
)
return None
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/group/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@
},
"state_classes_not_matching": {
"title": "State classes is not correct",
"description": "Device classes `{state_classes}` on source entities `{source_entities}` needs to be same for sensor group `{entity_id}`.\n\nPlease correct the state classes on the source entities and reload the group sensor to fix this issue."
"description": "State classes `{state_classes}` on source entities `{source_entities}` needs to be same for sensor group `{entity_id}`.\n\nPlease correct the state classes on the source entities and reload the group sensor to fix this issue."
}
}
}
2 changes: 1 addition & 1 deletion homeassistant/components/knx/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"quality_scale": "platinum",
"requirements": [
"xknx==2.12.0",
"xknxproject==3.5.0",
"xknxproject==3.6.0",
"knx-frontend==2024.1.20.105944"
]
}
6 changes: 3 additions & 3 deletions homeassistant/components/linear_garage_door/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
from typing import Any

from linear_garage_door import Linear
from linear_garage_door.errors import InvalidLoginError, ResponseError
from linear_garage_door.errors import InvalidLoginError

from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -55,6 +56,7 @@ async def _async_update_data(self) -> dict[str, Any]:
email=self._email,
password=self._password,
device_id=self._device_id,
client_session=async_get_clientsession(self.hass),
)
except InvalidLoginError as err:
if (
Expand All @@ -63,8 +65,6 @@ async def _async_update_data(self) -> dict[str, Any]:
):
raise ConfigEntryAuthFailed from err
raise ConfigEntryNotReady from err
except ResponseError as err:
raise ConfigEntryNotReady from err

if not self._devices:
self._devices = await linear.get_devices(self._site_id)
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/linear_garage_door/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/linear_garage_door",
"iot_class": "cloud_polling",
"requirements": ["linear-garage-door==0.2.7"]
"requirements": ["linear-garage-door==0.2.9"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/lutron/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/lutron",
"iot_class": "local_polling",
"loggers": ["pylutron"],
"requirements": ["pylutron==0.2.8"]
"requirements": ["pylutron==0.2.12"]
}
12 changes: 3 additions & 9 deletions homeassistant/components/metoffice/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
import asyncio
import logging
import re
import sys
from typing import Any

import datapoint

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
CONF_API_KEY,
Expand All @@ -16,7 +17,7 @@
Platform,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import ConfigEntryNotReady, HomeAssistantError
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import TimestampDataUpdateCoordinator
Expand All @@ -34,20 +35,13 @@
from .data import MetOfficeData
from .helpers import fetch_data, fetch_site

if sys.version_info < (3, 12):
import datapoint

_LOGGER = logging.getLogger(__name__)

PLATFORMS = [Platform.SENSOR, Platform.WEATHER]


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up a Met Office entry."""
if sys.version_info >= (3, 12):
raise HomeAssistantError(
"Met Office is not supported on Python 3.12. Please use Python 3.11."
)

latitude = entry.data[CONF_LATITUDE]
longitude = entry.data[CONF_LONGITUDE]
Expand Down
8 changes: 3 additions & 5 deletions homeassistant/components/metoffice/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@
from __future__ import annotations

from dataclasses import dataclass
import sys

if sys.version_info < (3, 12):
from datapoint.Forecast import Forecast
from datapoint.Site import Site
from datapoint.Timestep import Timestep
from datapoint.Forecast import Forecast
from datapoint.Site import Site
from datapoint.Timestep import Timestep


@dataclass
Expand Down
11 changes: 4 additions & 7 deletions homeassistant/components/metoffice/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,16 @@
from __future__ import annotations

import logging
import sys

import datapoint
from datapoint.Site import Site

from homeassistant.helpers.update_coordinator import UpdateFailed
from homeassistant.util.dt import utcnow

from .const import MODE_3HOURLY
from .data import MetOfficeData

if sys.version_info < (3, 12):
import datapoint
from datapoint.Site import Site


_LOGGER = logging.getLogger(__name__)


Expand All @@ -34,7 +31,7 @@ def fetch_site(
def fetch_data(connection: datapoint.Manager, site: Site, mode: str) -> MetOfficeData:
"""Fetch weather and forecast from Datapoint API."""
try:
forecast = connection.get_forecast_for_site(site.id, mode)
forecast = connection.get_forecast_for_site(site.location_id, mode)
except (ValueError, datapoint.exceptions.APIException) as err:
_LOGGER.error("Check Met Office connection: %s", err.args)
raise UpdateFailed from err
Expand Down
3 changes: 1 addition & 2 deletions homeassistant/components/metoffice/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
"name": "Met Office",
"codeowners": ["@MrHarcombe", "@avee87"],
"config_flow": true,
"disabled": "Integration library not compatible with Python 3.12",
"documentation": "https://www.home-assistant.io/integrations/metoffice",
"iot_class": "cloud_polling",
"loggers": ["datapoint"],
"requirements": ["datapoint==0.9.8;python_version<'3.12'"]
"requirements": ["datapoint==0.9.9"]
}

0 comments on commit 7aa14e2

Please sign in to comment.