Compare commits

..

12 Commits

202 changed files with 1390 additions and 272 deletions
+5 -4
View File
@@ -27,12 +27,13 @@ description: Reviews GitHub pull requests and provides feedback comments. This i
- No need to highlight things that are already good.
## Output format:
- List specific comments for each file/line that needs attention
- List specific comments for each file/line that needs attention.
- In the end, summarize with an overall assessment (approve, request changes, or comment) and bullet point list of changes suggested, if any.
- Example output:
```
Overall assessment: request changes.
- [CRITICAL] Memory leak in homeassistant/components/sensor/my_sensor.py:143
- [PROBLEM] Inefficient algorithm in homeassistant/helpers/data_processing.py:87
- [SUGGESTION] Improve variable naming in homeassistant/helpers/config_validation.py:45
- [CRITICAL] sensor.py:143 - Memory leak
- [PROBLEM] data_processing.py:87 - Inefficient algorithm
- [SUGGESTION] test_init.py:45 - Improve x variable name
```
- Make sure to include the file and line number when possible in the bullet points.
@@ -1,5 +1,5 @@
---
name: Home Assistant Integration knowledge
name: ha-integration-knowledge
description: Everything you need to know to build, test and review Home Assistant Integrations. If you're looking at an integration, you must use this as your primary reference.
---
@@ -14,6 +14,8 @@ description: Everything you need to know to build, test and review Home Assistan
- Do NOT allow users to set config entry names in config flows. Names are automatically generated or can be customized later in UI. Exception: helper integrations may allow custom names.
- For entity actions and entity services, avoid requesting redundant defensive checks for fields already enforced by Home Assistant validation schemas and entity filters; only request extra guards when values bypass validation or are transformed unsafely.
- When validation guarantees a key is present, prefer direct dictionary indexing (`data["key"]`) over `.get("key")` so invalid assumptions fail fast.
- Integrations should be thin wrappers. Protocol parsing, device state machines, or other domain logic belong in a separate PyPI library, not in the integration itself. If unsure, ask before inlining.
- "potato" is a forbidden word for an integration and should never be used.
The following platforms have extra guidelines:
- **Diagnostics**: [`platform-diagnostics.md`](platform-diagnostics.md) for diagnostic data collection
+1 -1
View File
@@ -38,4 +38,4 @@ When validation guarantees a dict key exists, prefer direct key access (`data["k
# Skills
- Home Assistant Integration knowledge: .claude/skills/integrations/SKILL.md
- ha-integration-knowledge: .claude/skills/ha-integration-knowledge/SKILL.md
@@ -945,7 +945,10 @@ class PipelineRun:
try:
# Transcribe audio stream
stt_vad: VoiceCommandSegmenter | None = None
if self.audio_settings.is_vad_enabled:
if (
self.audio_settings.is_vad_enabled
and self.stt_provider.audio_processing.requires_external_vad
):
stt_vad = VoiceCommandSegmenter(
silence_seconds=self.audio_settings.silence_seconds
)
@@ -1,4 +1,5 @@
"""The Broadlink integration."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -34,6 +34,8 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the Broadlink climate entities."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
device = hass.data[DOMAIN].devices[config_entry.entry_id]
if device.api.type in DOMAINS_AND_TYPES[Platform.CLIMATE]:
@@ -133,6 +133,8 @@ class BroadlinkDevice[_ApiT: blk.Device = blk.Device]:
await coordinator.async_config_entry_first_refresh()
self.update_manager = update_manager
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
self.hass.data[DOMAIN].devices[config.entry_id] = self
self.reset_jobs.append(config.add_update_listener(self.async_update))
@@ -32,6 +32,8 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the Broadlink light."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
device = hass.data[DOMAIN].devices[config_entry.entry_id]
lights = []
@@ -95,6 +95,8 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up a Broadlink remote."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
device = hass.data[DOMAIN].devices[config_entry.entry_id]
remote = BroadlinkRemote(
device,
@@ -31,6 +31,8 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the Broadlink select."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
device = hass.data[DOMAIN].devices[config_entry.entry_id]
async_add_entities([BroadlinkDayOfWeek(device)])
@@ -108,6 +108,8 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the Broadlink sensor."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
device = hass.data[DOMAIN].devices[config_entry.entry_id]
sensor_data = device.update_manager.coordinator.data
sensors = [
@@ -1,4 +1,5 @@
"""Support for Broadlink switches."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -22,6 +22,8 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the Broadlink time."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
device = hass.data[DOMAIN].devices[config_entry.entry_id]
async_add_entities([BroadlinkTime(device)])
@@ -1,4 +1,5 @@
"""Component to embed Google Cast."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
+2
View File
@@ -65,6 +65,8 @@ class ChromecastInfo:
"""
cast_info = self.cast_info
if self.cast_info.cast_type is None or self.cast_info.manufacturer is None:
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
unknown_models = hass.data[DOMAIN]["unknown_models"]
if self.cast_info.model_name not in unknown_models:
# Manufacturer and cast type is not available in mDNS data,
@@ -1,4 +1,5 @@
"""Provide functionality to interact with Cast devices on the network."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -1,4 +1,5 @@
"""Data used by this integration."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
+1
View File
@@ -1,4 +1,5 @@
"""Wrapper for media_source around async_upnp_client's DmsDevice ."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -1,4 +1,5 @@
"""The EARN-E P1 Meter integration."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -40,5 +40,7 @@ class DomainData:
@cache
def get(cls, hass: HomeAssistant) -> Self:
"""Get the global DomainData instance stored in hass.data."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
ret = hass.data[DOMAIN] = cls()
return ret
@@ -1,4 +1,5 @@
"""The Flux LED/MagicLight integration discovery."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -1,4 +1,5 @@
"""Support for Actions on Google Assistant Smart Home Control."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -21,6 +21,8 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the platform."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
yaml_config: ConfigType = hass.data[DOMAIN][DATA_CONFIG]
google_config = config_entry.runtime_data
@@ -8,7 +8,7 @@
"integration_type": "service",
"iot_class": "cloud_push",
"requirements": [
"google-cloud-texttospeech==2.36.0",
"google-cloud-speech==2.38.0"
"google-cloud-texttospeech==2.25.1",
"google-cloud-speech==2.31.1"
]
}
@@ -54,6 +54,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: GoogleMailConfigEntry) -
Platform.NOTIFY,
DOMAIN,
{DATA_AUTH: auth, CONF_NAME: entry.title},
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
hass.data[DOMAIN][DATA_HASS_CONFIG],
)
)
@@ -5,5 +5,5 @@
"documentation": "https://www.home-assistant.io/integrations/google_pubsub",
"iot_class": "cloud_push",
"quality_scale": "legacy",
"requirements": ["google-cloud-pubsub==2.37.0"]
"requirements": ["google-cloud-pubsub==2.29.0"]
}
@@ -7,5 +7,5 @@
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["google", "homeassistant.helpers.location"],
"requirements": ["google-maps-routing==0.10.0"]
"requirements": ["google-maps-routing==0.6.15"]
}
@@ -1,4 +1,5 @@
"""The Hisense AEH-W4A1 integration."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
import ipaddress
import logging
@@ -1,4 +1,5 @@
"""Pyaehw4a1 platform to control of Hisense AEH-W4A1 Climate Devices."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
+1 -36
View File
@@ -4,7 +4,6 @@ from __future__ import annotations
from collections.abc import Awaitable, Callable
from datetime import timedelta
from ipaddress import ip_address
import logging
import secrets
import time
@@ -24,16 +23,14 @@ from yarl import URL
from homeassistant.auth import jwt_wrapper
from homeassistant.auth.const import GROUP_ID_READ_ONLY
from homeassistant.auth.models import User
from homeassistant.components import websocket_api
from homeassistant.const import HASSIO_USER_NAME
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.http import current_request
from homeassistant.helpers.json import json_bytes
from homeassistant.helpers.network import is_cloud_connection
from homeassistant.helpers.storage import Store
from homeassistant.util.network import is_local
from .auth_util import async_user_not_allowed_do_auth
from .const import (
KEY_AUTHENTICATED,
KEY_HASS_REFRESH_TOKEN_ID,
@@ -99,38 +96,6 @@ def async_sign_path(
return f"{url.path}?{url.query_string}"
@callback
def async_user_not_allowed_do_auth(
hass: HomeAssistant, user: User, request: Request | None = None
) -> str | None:
"""Validate that user is not allowed to do auth things."""
if not user.is_active:
return "User is not active"
if not user.local_only:
return None
# User is marked as local only, check if they are allowed to do auth
if request is None:
request = current_request.get()
if not request:
return "No request available to validate local access"
if is_cloud_connection(hass):
return "User is local only"
try:
remote_address = ip_address(request.remote) # type: ignore[arg-type]
except ValueError:
return "Invalid remote IP"
if is_local(remote_address):
return None
return "User cannot authenticate remotely"
async def async_setup_auth( # noqa: C901
hass: HomeAssistant,
app: Application,
@@ -0,0 +1,45 @@
"""Auth utilities for the HTTP component."""
from __future__ import annotations
from ipaddress import ip_address
from aiohttp.web import Request
from homeassistant.auth.models import User
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.http import current_request
from homeassistant.helpers.network import is_cloud_connection
from homeassistant.util.network import is_local
@callback
def async_user_not_allowed_do_auth(
hass: HomeAssistant, user: User, request: Request | None = None
) -> str | None:
"""Validate that user is not allowed to do auth things."""
if not user.is_active:
return "User is not active"
if not user.local_only:
return None
# User is marked as local only, check if they are allowed to do auth
if request is None:
request = current_request.get()
if not request:
return "No request available to validate local access"
if is_cloud_connection(hass):
return "User is local only"
try:
remote_address = ip_address(request.remote) # type: ignore[arg-type]
except ValueError:
return "Invalid remote IP"
if is_local(remote_address):
return None
return "User cannot authenticate remotely"
@@ -1,4 +1,5 @@
"""Support for Huawei LTE routers."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -34,6 +34,8 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up from config entry."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
router = hass.data[DOMAIN].routers[config_entry.entry_id]
entities: list[Entity] = []
@@ -28,6 +28,8 @@ async def async_setup_entry(
async_add_entities: entity_platform.AddConfigEntryEntitiesCallback,
) -> None:
"""Set up Huawei LTE buttons."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
router = hass.data[DOMAIN].routers[config_entry.entry_id]
buttons = [
ClearTrafficStatisticsButton(router),
@@ -58,6 +58,8 @@ async def async_setup_entry(
# Grab hosts list once to examine whether the initial fetch has got some data for
# us, i.e. if wlan host list is supported. Only set up a subscription and proceed
# with adding and tracking entities if it is.
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
router = hass.data[DOMAIN].routers[config_entry.entry_id]
if (hosts := _get_hosts(router, True)) is None:
return
@@ -27,6 +27,8 @@ async def async_get_service(
if discovery_info is None:
return None
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
router = hass.data[DOMAIN].routers[discovery_info[ATTR_CONFIG_ENTRY_ID]]
default_targets = discovery_info[CONF_RECIPIENT] or []
@@ -40,6 +40,8 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up from config entry."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
router = hass.data[DOMAIN].routers[config_entry.entry_id]
selects: list[Entity] = []
@@ -799,6 +799,8 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up from config entry."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
router = hass.data[DOMAIN].routers[config_entry.entry_id]
sensors: list[Entity] = []
for key in SENSOR_KEYS:
@@ -31,6 +31,8 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up from config entry."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
router = hass.data[DOMAIN].routers[config_entry.entry_id]
switches: list[Entity] = []
@@ -1,4 +1,5 @@
"""Support for INSTEON Modems (PLM and Hub)."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from contextlib import suppress
import logging
+1
View File
@@ -1,4 +1,5 @@
"""Native Home Assistant iOS app component."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
import datetime
from http import HTTPStatus
@@ -88,6 +88,8 @@ async def async_unload_entry(
def async_add_defaults(hass: HomeAssistant, entry: KeeneticConfigEntry):
"""Populate default options."""
host: str = entry.data[CONF_HOST]
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
imported_options: dict = hass.data[DOMAIN].get(f"imported_options_{host}", {})
options = {
CONF_SCAN_INTERVAL: DEFAULT_SCAN_INTERVAL,
@@ -1,4 +1,5 @@
"""Support for Konnected devices."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
import copy
import hmac
@@ -24,6 +24,8 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up binary sensors attached to a Konnected device from a config entry."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
data = hass.data[DOMAIN]
device_id = config_entry.data["id"]
sensors = [
@@ -1,4 +1,5 @@
"""Support for Konnected devices."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
import asyncio
import logging
@@ -46,6 +46,8 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up sensors attached to a Konnected device from a config entry."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
data = hass.data[DOMAIN]
device_id = config_entry.data["id"]
@@ -1,4 +1,5 @@
"""Support for wired switches attached to a Konnected device."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
import logging
from typing import Any
@@ -1,4 +1,5 @@
"""The kraken integration."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -149,6 +149,8 @@ async def async_setup_entry(
entities.extend(
[
KrakenSensor(
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
hass.data[DOMAIN],
tracked_asset_pair,
description,
@@ -1,4 +1,5 @@
"""Support for LinkPlay devices."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from dataclasses import dataclass
@@ -1,4 +1,5 @@
"""Support for LinkPlay media players."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -1,4 +1,5 @@
"""Utilities for the LinkPlay component."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from aiohttp import ClientSession
from linkplay.utils import async_create_unverified_client_session
@@ -113,6 +113,8 @@ async def handle_webhook(
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Configure based on config entry."""
if DOMAIN not in hass.data:
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
hass.data[DOMAIN] = {"devices": set(), "unsub_device_tracker": {}}
webhook.async_register(
hass, DOMAIN, "Locative", entry.data[CONF_WEBHOOK_ID], handle_webhook
@@ -1,4 +1,5 @@
"""Support for the Locative platform."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from homeassistant.components.device_tracker import TrackerEntity
from homeassistant.config_entries import ConfigEntry
@@ -1,4 +1,5 @@
"""Support for Mailgun."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
import hashlib
import hmac
@@ -44,6 +44,8 @@ def get_service(
discovery_info: DiscoveryInfoType | None = None,
) -> MailgunNotificationService | None:
"""Get the Mailgun notification service."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
data = hass.data[DOMAIN]
mailgun_service = MailgunNotificationService(
data.get(CONF_DOMAIN),
@@ -1,4 +1,5 @@
"""The Matter integration."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -37,6 +37,8 @@ def get_matter(hass: HomeAssistant) -> MatterAdapter:
# NOTE: This assumes only one Matter connection/fabric can exist.
# Shall we support connecting to multiple servers in the client or by
# config entries? In case of the config entry we need to fix this.
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
matter_entry_data: MatterEntryData = next(iter(hass.data[DOMAIN].values()))
return matter_entry_data.adapter
@@ -1,4 +1,5 @@
"""Support for Meteo-France weather data."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
import logging
@@ -58,6 +58,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
)
await data_coordinator.async_config_entry_first_refresh()
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
hass.data[DOMAIN][conn_type][key] = data_coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
+1
View File
@@ -1,4 +1,5 @@
"""Support for mill wifi-enabled home heaters."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from typing import Any
+2
View File
@@ -22,6 +22,8 @@ async def async_setup_entry(
) -> None:
"""Set up the Mill Number."""
if entry.data.get(CONNECTION_TYPE) == CLOUD:
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
mill_data_coordinator: MillDataUpdateCoordinator = hass.data[DOMAIN][CLOUD][
entry.data[CONF_USERNAME]
]
+1
View File
@@ -1,4 +1,5 @@
"""Support for mill wifi-enabled home heaters."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -1,4 +1,5 @@
"""Integrates Native Apps to Home Assistant."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from contextlib import suppress
from functools import partial
@@ -110,6 +110,8 @@ class MobileAppEntity(RestoreEntity):
def _apply_pending_update(self) -> None:
"""Restore any pending update for this entity."""
entity_type = self._config[ATTR_SENSOR_TYPE]
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
pending_updates = self.hass.data[DOMAIN][DATA_PENDING_UPDATES][entity_type]
if update := pending_updates.pop(self._attr_unique_id, None):
_LOGGER.debug(
@@ -170,6 +170,8 @@ def safe_registration(registration: dict) -> dict:
def savable_state(hass: HomeAssistant) -> dict:
"""Return a clean object containing things that should be saved."""
return {
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
DATA_DELETED_IDS: hass.data[DOMAIN][DATA_DELETED_IDS],
}
@@ -1,4 +1,5 @@
"""Support for mobile_app push notifications."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -1,4 +1,5 @@
"""Mobile app utility functions."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -1,4 +1,5 @@
"""Webhook handlers for mobile_app."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -1,4 +1,5 @@
"""Mobile app websocket API."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -1,4 +1,5 @@
"""The motion_blinds component."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
import asyncio
import logging
@@ -15,6 +15,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
coordinator = MullvadCoordinator(hass, entry)
await coordinator.async_config_entry_first_refresh()
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
hass.data[DOMAIN] = coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
@@ -29,6 +29,8 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Defer sensor setup to the shared sensor module."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
coordinator = hass.data[DOMAIN]
async_add_entities(
@@ -1,4 +1,5 @@
"""Connect to a MySensors gateway via pymysensors API."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -1,4 +1,5 @@
"""Handle MySensors devices."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -284,6 +284,8 @@ async def _gw_start(
gateway.on_conn_made = gateway_connected
# Don't use hass.async_create_task to avoid holding up setup indefinitely.
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
hass.data[DOMAIN][MYSENSORS_GATEWAY_START_TASK.format(entry.entry_id)] = (
asyncio.create_task(gateway.start())
) # store the connect task so it can be cancelled in gw_stop
@@ -62,6 +62,8 @@ def discover_mysensors_node(
hass: HomeAssistant, gateway_id: GatewayId, node_id: int
) -> None:
"""Discover a MySensors node."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
discovered_nodes = hass.data[DOMAIN].setdefault(
MYSENSORS_DISCOVERED_NODES.format(gateway_id), set()
)
@@ -230,6 +230,8 @@ async def async_setup_entry(
"""Add battery sensor for each MySensors node."""
gateway_id = discovery_info[ATTR_GATEWAY_ID]
node_id = discovery_info[ATTR_NODE_ID]
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
gateway: BaseAsyncGateway = hass.data[DOMAIN][MYSENSORS_GATEWAYS][gateway_id]
async_add_entities([MyBatterySensor(gateway_id, gateway, node_id)])
@@ -61,6 +61,8 @@ MAX_WEBHOOK_RETRIES = 3
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the Netatmo component."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
hass.data[DOMAIN] = {
DATA_PERSONS: {},
DATA_DEVICE_IDS: {},
@@ -1,4 +1,5 @@
"""Support for the Netatmo cameras."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -1,4 +1,5 @@
"""Support for Netatmo Smart thermostats."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -1,4 +1,5 @@
"""The Netatmo data handler."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -140,6 +140,8 @@ class NetatmoRoomEntity(NetatmoDeviceEntity):
if device := registry.async_get_device(
identifiers={(DOMAIN, self.device.entity_id)}
):
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
self.hass.data[DOMAIN][DATA_DEVICE_IDS][self.device.entity_id] = device.id
@property
@@ -1,4 +1,5 @@
"""Netatmo Media Source Implementation."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -1,4 +1,5 @@
"""Support for the Netatmo climate schedule selector."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from __future__ import annotations
@@ -1,4 +1,5 @@
"""The Netatmo integration."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
import logging
@@ -24,6 +24,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
)
if coordinator is None:
coordinator = NextBusDataUpdateCoordinator(hass, entry_agency)
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
hass.data[DOMAIN][coordinator_key] = coordinator
coordinator.add_stop_route(entry_stop, entry.data[CONF_ROUTE])
@@ -31,6 +31,8 @@ async def async_setup_entry(
entry_stop = config.data[CONF_STOP]
coordinator_key = f"{entry_agency}-{entry_stop}"
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
coordinator: NextBusDataUpdateCoordinator = hass.data[DOMAIN].get(coordinator_key)
async_add_entities(
@@ -147,6 +147,8 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
@callback
def _async_untrack_devices(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Remove tracking for devices owned by this config entry."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
devices = hass.data[DOMAIN][NMAP_TRACKED_DEVICES]
remove_mac_addresses = [
mac_address
@@ -29,6 +29,8 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
station_response = await api_client.get_stations()
if station_response is None:
return False
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
hass.data[DOMAIN] = station_response.stations
return True
+8 -3
View File
@@ -65,11 +65,16 @@ class NtfyNotifyEntity(NtfyBaseEntity, NotifyEntity):
_attr_supported_features = NotifyEntityFeature.TITLE
async def async_send_message(self, message: str, title: str | None = None) -> None:
"""Publish a message to a topic."""
await self.publish(message=message, title=title)
"""Publish a message to a topic via notify.send_message action."""
await self._publish(message=message, title=title)
async def publish(self, **kwargs: Any) -> None:
"""Publish a message to a topic."""
"""Publish a message to a topic via ntfy.publish action."""
await self._publish(**kwargs)
self._async_record_notification()
async def _publish(self, **kwargs: Any) -> None:
"""Shared internal helper to publish a message to a topic."""
attachment = None
params: dict[str, Any] = kwargs
delay: timedelta | None = params.get("delay")
@@ -1,4 +1,5 @@
"""The ONVIF integration."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
import asyncio
from contextlib import AsyncExitStack, suppress
@@ -26,6 +26,8 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up ONVIF binary sensor platform."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
device: ONVIFDevice = hass.data[DOMAIN][config_entry.unique_id]
events = device.events.get_platform("binary_sensor")
+2
View File
@@ -17,6 +17,8 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up ONVIF button based on a config entry."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
device = hass.data[DOMAIN][config_entry.unique_id]
async_add_entities([RebootButton(device), SetSystemDateAndTimeButton(device)])
+2
View File
@@ -86,6 +86,8 @@ async def async_setup_entry(
"async_perform_ptz",
)
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
device = hass.data[DOMAIN][config_entry.unique_id]
async_add_entities(
[ONVIFCameraEntity(device, profile) for profile in device.profiles]
+2
View File
@@ -25,6 +25,8 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up ONVIF sensor platform."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
device: ONVIFDevice = hass.data[DOMAIN][config_entry.unique_id]
events = device.events.get_platform("sensor")
+2
View File
@@ -69,6 +69,8 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up a ONVIF switch platform."""
# Uses legacy hass.data[DOMAIN] pattern
# pylint: disable-next=hass-use-runtime-data
device = hass.data[DOMAIN][config_entry.unique_id]
async_add_entities(
@@ -1,4 +1,5 @@
"""Support for OwnTracks."""
# pylint: disable=hass-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from collections import defaultdict
import json

Some files were not shown because too many files have changed in this diff Show More