Compare commits

..

1 Commits

Author SHA1 Message Date
Erik 813fa922e2 Include issue tracker link in custom integration analytics data 2026-04-30 10:24:44 +02:00
7479 changed files with 18535 additions and 16944 deletions
@@ -15,15 +15,11 @@ description: Everything you need to know to build, test and review Home Assistan
- 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.
- Integrations should not implement fixes or workarounds for limitations in libraries. Instead, the library should be updated to fix the issue.
The following platforms have extra guidelines:
- **Diagnostics**: [`platform-diagnostics.md`](platform-diagnostics.md) for diagnostic data collection
- **Repairs**: [`platform-repairs.md`](platform-repairs.md) for user-actionable repair issues
## Entity platforms
- Ensure `async_added_to_hass()` and `async_will_remove_from_hass()` have symmetrical behavior. For example, if a subscription is created in `async_added_to_hass()`, it should be unsubscribed in `async_will_remove_from_hass()`. Also, if something is torn down in `async_will_remove_from_hass()`, it should be set up in `async_added_to_hass()`.
## Integration Quality Scale
+7 -12
View File
@@ -6,7 +6,6 @@
- Start review comments with a short, one-sentence summary of the suggested fix.
- Do not comment on code style, formatting or linting issues.
- A Pull Request with a dependency version bump should only contain changes required for the version bump. If the PR includes other changes, request that they are removed from the PR.
# GitHub Copilot & Claude Code Instructions
@@ -22,20 +21,16 @@ This repository contains the core of Home Assistant, a Python 3 based home autom
## Python Syntax Notes
- Home Assistant officially supports Python 3.14 as its minimum version. Do not flag syntax or features that require Python 3.14 as issues, and do not suggest workarounds for older Python versions.
- Python 3.14 explicitly allows `except TypeA, TypeB:` without parentheses. Never flag this as an issue.
- Python 3.14 evaluates annotations lazily (PEP 649). Forward references in annotations do not need to be quoted — annotations can reference names defined later in the module without quoting them or using `from __future__ import annotations`. Do not flag unquoted forward references in annotations as issues.
- Python 3.14 explicitly allows `except TypeA, TypeB:` without parentheses. Never flag this as an issue since Home Assistant officially supports Python 3.14.
## Testing
- When writing or modifying tests, ensure all test function parameters have type annotations.
- Prefer concrete types (for example, `HomeAssistant`, `MockConfigEntry`, etc.) over `Any`.
- Avoid using conditions/branching in tests. Instead, either split tests or adjust the test parametrization to cover all cases without branching.
- If multiple tests share most of their code, use `pytest.mark.parametrize` to merge them into a single parameterized test instead of duplicating the body.
When writing or modifying tests, ensure all test function parameters have type annotations.
Prefer concrete types (for example, `HomeAssistant`, `MockConfigEntry`, etc.) over `Any`.
## Good practices
- Integrations with Platinum or Gold level in the Integration Quality Scale reflect a high standard of code quality and maintainability. When looking for examples of something, these are good places to start. The level is indicated in the manifest.json of the integration.
- When reviewing entity actions, do not suggest extra defensive checks for input fields that are already validated by Home Assistant's service/action schemas and entity selection filters. Suggest additional guards only when data bypasses those validators or is transformed into a less-safe form.
- When validation guarantees a dict key exists, prefer direct key access (`data["key"]`) instead of `.get("key")` so contract violations are surfaced instead of silently masked.
- Do not add comments that just restate the code on the following line(s) (e.g. `# Check if initialized` above `if self.initialized:`). Comments should only explain why — non-obvious constraints, surprising behavior, or workarounds — never what.
Integrations with Platinum or Gold level in the Integration Quality Scale reflect a high standard of code quality and maintainability. When looking for examples of something, these are good places to start. The level is indicated in the manifest.json of the integration.
When reviewing entity actions, do not suggest extra defensive checks for input fields that are already validated by Home Assistant's service/action schemas and entity selection filters. Suggest additional guards only when data bypasses those validators or is transformed into a less-safe form.
When validation guarantees a dict key exists, prefer direct key access (`data["key"]`) instead of `.get("key")` so contract violations are surfaced instead of silently masked.
@@ -18,15 +18,11 @@ excludeAgent: "cloud-agent"
- 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.
- Integrations should not implement fixes or workarounds for limitations in libraries. Instead, the library should be updated to fix the issue.
The following platforms have extra guidelines:
- **Diagnostics**: [`platform-diagnostics.md`](platform-diagnostics.md) for diagnostic data collection
- **Repairs**: [`platform-repairs.md`](platform-repairs.md) for user-actionable repair issues
## Entity platforms
- Ensure `async_added_to_hass()` and `async_will_remove_from_hass()` have symmetrical behavior. For example, if a subscription is created in `async_added_to_hass()`, it should be unsubscribed in `async_will_remove_from_hass()`. Also, if something is torn down in `async_will_remove_from_hass()`, it should be set up in `async_added_to_hass()`.
## Integration Quality Scale
+3 -3
View File
@@ -14,7 +14,7 @@ env:
UV_HTTP_TIMEOUT: 60
UV_SYSTEM_PYTHON: "true"
# Base image version from https://github.com/home-assistant/docker
BASE_IMAGE_VERSION: "2026.04.0"
BASE_IMAGE_VERSION: "2026.01.0"
ARCHITECTURES: '["amd64", "aarch64"]'
permissions: {}
@@ -108,7 +108,7 @@ jobs:
- name: Download nightly wheels of frontend
if: needs.init.outputs.channel == 'dev'
uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21
uses: dawidd6/action-download-artifact@8305c0f1062bb0d184d09ef4493ecb9288447732 # v20
with:
github_token: ${{secrets.GITHUB_TOKEN}}
repo: home-assistant/frontend
@@ -119,7 +119,7 @@ jobs:
- name: Download nightly wheels of intents
if: needs.init.outputs.channel == 'dev'
uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21
uses: dawidd6/action-download-artifact@8305c0f1062bb0d184d09ef4493ecb9288447732 # v20
with:
github_token: ${{secrets.GITHUB_TOKEN}}
repo: OHF-Voice/intents-package
+31 -26
View File
@@ -38,8 +38,9 @@ on:
env:
CACHE_VERSION: 3
UV_CACHE_VERSION: 1
MYPY_CACHE_VERSION: 1
HA_SHORT_VERSION: "2026.6"
HA_SHORT_VERSION: "2026.5"
ADDITIONAL_PYTHON_VERSIONS: "[]"
# 10.3 is the oldest supported version
# - 10.3.32 is the version currently shipped with Synology (as of 17 Feb 2022)
@@ -281,7 +282,7 @@ jobs:
echo "::add-matcher::.github/workflows/matchers/check-executables-have-shebangs.json"
echo "::add-matcher::.github/workflows/matchers/codespell.json"
- name: Run prek
uses: j178/prek-action@6ad80277337ad479fe43bd70701c3f7f8aa74db3 # v2.0.3
uses: j178/prek-action@cbc2f23eb5539cf20d82d1aabd0d0ecbcc56f4e3 # v2.0.2
env:
PREK_SKIP: no-commit-to-branch,mypy,pylint,gen_requirements_all,hassfest,hassfest-metadata,hassfest-mypy-config,zizmor
RUFF_OUTPUT_FORMAT: github
@@ -302,7 +303,7 @@ jobs:
with:
persist-credentials: false
- name: Run zizmor
uses: j178/prek-action@6ad80277337ad479fe43bd70701c3f7f8aa74db3 # v2.0.3
uses: j178/prek-action@cbc2f23eb5539cf20d82d1aabd0d0ecbcc56f4e3 # v2.0.2
with:
extra-args: --all-files zizmor
@@ -357,6 +358,12 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
check-latest: true
- name: Generate partial uv restore key
id: generate-uv-key
run: |
uv_version=$(cat requirements.txt | grep uv | cut -d '=' -f 3)
echo "version=${uv_version}" >> $GITHUB_OUTPUT
echo "key=uv-${UV_CACHE_VERSION}-${uv_version}-${HA_SHORT_VERSION}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
@@ -365,25 +372,19 @@ jobs:
key: >-
${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Generate partial uv restore key
if: steps.cache-venv.outputs.cache-hit != 'true'
id: generate-uv-key
env:
RUNNER_OS: ${{ runner.os }}
RUNNER_ARCH: ${{ runner.arch }}
PYTHON_VERSION: ${{ steps.python.outputs.python-version }}
HASH_FILES: ${{ hashFiles('requirements.txt', 'requirements_all.txt', 'requirements_test.txt', 'homeassistant/package_constraints.txt') }}
run: |
partial_key="${RUNNER_OS}-${RUNNER_ARCH}-${PYTHON_VERSION}-uv-"
echo "partial_key=${partial_key}" >> $GITHUB_OUTPUT
echo "full_key=${partial_key}${HASH_FILES}" >> $GITHUB_OUTPUT
- name: Restore uv wheel cache
if: steps.cache-venv.outputs.cache-hit != 'true'
id: cache-uv
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ${{ env.UV_CACHE_DIR }}
key: ${{ steps.generate-uv-key.outputs.full_key }}
restore-keys: ${{ steps.generate-uv-key.outputs.partial_key }}
key: >-
${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{
steps.generate-uv-key.outputs.key }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-uv-${{
env.UV_CACHE_VERSION }}-${{ steps.generate-uv-key.outputs.version }}-${{
env.HA_SHORT_VERSION }}-
- name: Check if apt cache exists
id: cache-apt-check
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
@@ -453,7 +454,8 @@ jobs:
pip install "$(grep '^uv' < requirements.txt)"
uv pip install -U "pip>=25.2"
uv pip install -r requirements.txt
uv pip install -r requirements_all.txt -r requirements_test.txt
python -m script.gen_requirements_all ci
uv pip install -r requirements_all_pytest.txt -r requirements_test.txt
uv pip install -e . --config-settings editable_mode=compat
- name: Dump pip freeze
run: |
@@ -469,21 +471,24 @@ jobs:
overwrite: true
- name: Remove pip_freeze
run: rm pip_freeze.txt
- name: Remove generated requirements_all
if: steps.cache-venv.outputs.cache-hit != 'true'
run: rm requirements_all_pytest.txt requirements_all_wheels_*.txt
- name: Check dirty
run: |
./script/check_dirty
- name: Prune uv cache
if: steps.cache-venv.outputs.cache-hit != 'true'
id: prune-uv-cache
run: |
. venv/bin/activate
uv cache prune --ci
- name: Save uv wheel cache
if: steps.cache-venv.outputs.cache-hit != 'true'
if: |
(success() && steps.cache-venv.outputs.cache-hit != 'true')
|| (always()
&& steps.create-venv.outcome == 'success'
&& steps.cache-uv.outputs.cache-matched-key == '')
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ${{ env.UV_CACHE_DIR }}
key: ${{ steps.generate-uv-key.outputs.full_key }}
key: >-
${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{
steps.generate-uv-key.outputs.key }}
- name: Save base Python virtual environment
if: always() && steps.create-venv.outcome == 'success'
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+1 -1
View File
@@ -1 +1 @@
3.14.4
3.14.2
-1
View File
@@ -442,7 +442,6 @@ homeassistant.components.private_ble_device.*
homeassistant.components.prometheus.*
homeassistant.components.proximity.*
homeassistant.components.prusalink.*
homeassistant.components.ptdevices.*
homeassistant.components.pure_energie.*
homeassistant.components.purpleair.*
homeassistant.components.pushbullet.*
+7 -11
View File
@@ -12,20 +12,16 @@ This repository contains the core of Home Assistant, a Python 3 based home autom
## Python Syntax Notes
- Home Assistant officially supports Python 3.14 as its minimum version. Do not flag syntax or features that require Python 3.14 as issues, and do not suggest workarounds for older Python versions.
- Python 3.14 explicitly allows `except TypeA, TypeB:` without parentheses. Never flag this as an issue.
- Python 3.14 evaluates annotations lazily (PEP 649). Forward references in annotations do not need to be quoted — annotations can reference names defined later in the module without quoting them or using `from __future__ import annotations`. Do not flag unquoted forward references in annotations as issues.
- Python 3.14 explicitly allows `except TypeA, TypeB:` without parentheses. Never flag this as an issue since Home Assistant officially supports Python 3.14.
## Testing
- When writing or modifying tests, ensure all test function parameters have type annotations.
- Prefer concrete types (for example, `HomeAssistant`, `MockConfigEntry`, etc.) over `Any`.
- Avoid using conditions/branching in tests. Instead, either split tests or adjust the test parametrization to cover all cases without branching.
- If multiple tests share most of their code, use `pytest.mark.parametrize` to merge them into a single parameterized test instead of duplicating the body.
When writing or modifying tests, ensure all test function parameters have type annotations.
Prefer concrete types (for example, `HomeAssistant`, `MockConfigEntry`, etc.) over `Any`.
## Good practices
- Integrations with Platinum or Gold level in the Integration Quality Scale reflect a high standard of code quality and maintainability. When looking for examples of something, these are good places to start. The level is indicated in the manifest.json of the integration.
- When reviewing entity actions, do not suggest extra defensive checks for input fields that are already validated by Home Assistant's service/action schemas and entity selection filters. Suggest additional guards only when data bypasses those validators or is transformed into a less-safe form.
- When validation guarantees a dict key exists, prefer direct key access (`data["key"]`) instead of `.get("key")` so contract violations are surfaced instead of silently masked.
- Do not add comments that just restate the code on the following line(s) (e.g. `# Check if initialized` above `if self.initialized:`). Comments should only explain why — non-obvious constraints, surprising behavior, or workarounds — never what.
Integrations with Platinum or Gold level in the Integration Quality Scale reflect a high standard of code quality and maintainability. When looking for examples of something, these are good places to start. The level is indicated in the manifest.json of the integration.
When reviewing entity actions, do not suggest extra defensive checks for input fields that are already validated by Home Assistant's service/action schemas and entity selection filters. Suggest additional guards only when data bypasses those validators or is transformed into a less-safe form.
When validation guarantees a dict key exists, prefer direct key access (`data["key"]`) instead of `.get("key")` so contract violations are surfaced instead of silently masked.
Generated
+2 -6
View File
@@ -851,8 +851,8 @@ CLAUDE.md @home-assistant/core
/tests/components/input_select/ @home-assistant/core
/homeassistant/components/input_text/ @home-assistant/core
/tests/components/input_text/ @home-assistant/core
/homeassistant/components/insteon/ @teharris1 @ssyrell
/tests/components/insteon/ @teharris1 @ssyrell
/homeassistant/components/insteon/ @teharris1
/tests/components/insteon/ @teharris1
/homeassistant/components/integration/ @dgomes
/tests/components/integration/ @dgomes
/homeassistant/components/intelliclima/ @dvdinth
@@ -1092,8 +1092,6 @@ CLAUDE.md @home-assistant/core
/tests/components/minecraft_server/ @elmurato @zachdeibert
/homeassistant/components/minio/ @tkislan
/tests/components/minio/ @tkislan
/homeassistant/components/mitsubishi_comfort/ @nikolairahimi
/tests/components/mitsubishi_comfort/ @nikolairahimi
/homeassistant/components/moat/ @bdraco
/tests/components/moat/ @bdraco
/homeassistant/components/mobile_app/ @home-assistant/core
@@ -1380,8 +1378,6 @@ CLAUDE.md @home-assistant/core
/tests/components/proxmoxve/ @Corbeno @erwindouna @CoMPaTech
/homeassistant/components/ps4/ @ktnrg45
/tests/components/ps4/ @ktnrg45
/homeassistant/components/ptdevices/ @ParemTech-Inc @frogman85978
/tests/components/ptdevices/ @ParemTech-Inc @frogman85978
/homeassistant/components/pterodactyl/ @elmurato
/tests/components/pterodactyl/ @elmurato
/homeassistant/components/pure_energie/ @klaasnicolaas
+2
View File
@@ -1,5 +1,7 @@
"""Start Home Assistant."""
from __future__ import annotations
import argparse
from contextlib import suppress
import faulthandler
+2
View File
@@ -1,5 +1,7 @@
"""Provide an authentication layer for Home Assistant."""
from __future__ import annotations
import asyncio
from collections import OrderedDict
from collections.abc import Mapping
+2
View File
@@ -1,5 +1,7 @@
"""Storage for auth models."""
from __future__ import annotations
from datetime import timedelta
import hmac
import itertools
+2
View File
@@ -5,6 +5,8 @@ we can cache the result of the decode of valid tokens
to speed up the process.
"""
from __future__ import annotations
from collections.abc import Container, Iterable, Sequence
from datetime import timedelta
from functools import lru_cache
@@ -1,5 +1,7 @@
"""Pluggable auth modules for Home Assistant."""
from __future__ import annotations
import logging
import types
from typing import Any
@@ -1,5 +1,7 @@
"""Example auth module."""
from __future__ import annotations
from typing import Any
import voluptuous as vol
+2
View File
@@ -3,6 +3,8 @@
Sending HOTP through notify service
"""
from __future__ import annotations
import asyncio
import logging
from typing import Any, cast
+2
View File
@@ -1,5 +1,7 @@
"""Time-based One Time Password auth module."""
from __future__ import annotations
import asyncio
from io import BytesIO
from typing import Any, cast
+2
View File
@@ -1,5 +1,7 @@
"""Auth models."""
from __future__ import annotations
from datetime import datetime, timedelta
from ipaddress import IPv4Address, IPv6Address
import secrets
@@ -1,5 +1,7 @@
"""Permissions for Home Assistant."""
from __future__ import annotations
from collections.abc import Callable, Iterable
from typing import TYPE_CHECKING
@@ -1,5 +1,7 @@
"""Entity permissions."""
from __future__ import annotations
from collections import OrderedDict
from collections.abc import Callable
+2
View File
@@ -1,5 +1,7 @@
"""Permission for events."""
from __future__ import annotations
from typing import Any, Final
from homeassistant.const import (
+2
View File
@@ -1,5 +1,7 @@
"""Merging of policies."""
from __future__ import annotations
from typing import cast
from .types import CategoryType, PolicyType
+2
View File
@@ -1,5 +1,7 @@
"""Models for permissions."""
from __future__ import annotations
from typing import TYPE_CHECKING
import attr
+2
View File
@@ -1,5 +1,7 @@
"""Helpers to deal with permissions."""
from __future__ import annotations
from collections.abc import Callable
from functools import wraps
from typing import cast
+2
View File
@@ -1,5 +1,7 @@
"""Auth providers for Home Assistant."""
from __future__ import annotations
from collections.abc import Mapping
import logging
import types
@@ -1,5 +1,7 @@
"""Auth provider that validates credentials via an external command."""
from __future__ import annotations
import asyncio
from collections.abc import Mapping
import logging
@@ -1,5 +1,7 @@
"""Home Assistant auth provider."""
from __future__ import annotations
import asyncio
import base64
from collections.abc import Mapping
@@ -1,5 +1,7 @@
"""Example auth provider."""
from __future__ import annotations
from collections.abc import Mapping
import hmac
@@ -4,6 +4,8 @@ It shows list of users if access from trusted network.
Abort login flow if not access from trusted network.
"""
from __future__ import annotations
from collections.abc import Mapping
from ipaddress import (
IPv4Address,
+2
View File
@@ -1,5 +1,7 @@
"""Home Assistant module to handle restoring backups."""
from __future__ import annotations
from collections.abc import Iterable
from dataclasses import dataclass
import json
+2
View File
@@ -1,5 +1,7 @@
"""Provide methods to bootstrap a Home Assistant instance."""
from __future__ import annotations
import asyncio
from collections import defaultdict
import contextlib
-5
View File
@@ -1,5 +0,0 @@
{
"domain": "sensereo",
"name": "Sensereo",
"iot_standards": ["matter"]
}
-5
View File
@@ -1,5 +0,0 @@
{
"domain": "zunzunbee",
"name": "Zunzunbee",
"iot_standards": ["zigbee"]
}
@@ -1,5 +1,7 @@
"""Support for the Abode Security System."""
from __future__ import annotations
from dataclasses import dataclass, field
from functools import partial
from pathlib import Path
@@ -1,5 +1,7 @@
"""Support for Abode Security System alarm control panels."""
from __future__ import annotations
from jaraco.abode.devices.alarm import Alarm
from homeassistant.components.alarm_control_panel import (
@@ -1,5 +1,7 @@
"""Support for Abode Security System binary sensors."""
from __future__ import annotations
from typing import cast
from jaraco.abode.devices.binary_sensor import BinarySensor
+2
View File
@@ -1,5 +1,7 @@
"""Support for Abode Security System cameras."""
from __future__ import annotations
from datetime import timedelta
from typing import Any, cast
@@ -1,5 +1,7 @@
"""Config flow for the Abode Security System component."""
from __future__ import annotations
from collections.abc import Mapping
from http import HTTPStatus
from typing import Any, cast
+2
View File
@@ -1,5 +1,7 @@
"""Constants for the Abode Security System component."""
from __future__ import annotations
import logging
LOGGER = logging.getLogger(__package__)
+2
View File
@@ -1,5 +1,7 @@
"""Support for Abode Security System lights."""
from __future__ import annotations
from math import ceil
from typing import Any
+2
View File
@@ -1,5 +1,7 @@
"""Support for Abode Security System sensors."""
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from typing import cast
@@ -1,5 +1,7 @@
"""Support for the Abode Security System."""
from __future__ import annotations
from typing import TYPE_CHECKING
from jaraco.abode.exceptions import Exception as AbodeException
+2
View File
@@ -1,5 +1,7 @@
"""Support for Abode Security System switches."""
from __future__ import annotations
from typing import Any, cast
from jaraco.abode.devices.switch import Switch
@@ -1,5 +1,7 @@
"""Coordinator for Acaia integration."""
from __future__ import annotations
from datetime import timedelta
import logging
@@ -1,5 +1,7 @@
"""Diagnostics support for Acaia."""
from __future__ import annotations
from dataclasses import asdict
from typing import Any
@@ -1,5 +1,7 @@
"""The AccuWeather component."""
from __future__ import annotations
import asyncio
import logging
@@ -1,5 +1,7 @@
"""Adds config flow for AccuWeather."""
from __future__ import annotations
from asyncio import timeout
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any
@@ -1,5 +1,7 @@
"""Constants for AccuWeather integration."""
from __future__ import annotations
from datetime import timedelta
from typing import Final
@@ -1,5 +1,7 @@
"""The AccuWeather coordinator."""
from __future__ import annotations
from asyncio import timeout
from collections.abc import Awaitable, Callable
from dataclasses import dataclass
@@ -1,5 +1,7 @@
"""Diagnostics support for AccuWeather."""
from __future__ import annotations
from typing import Any
from homeassistant.components.diagnostics import async_redact_data
@@ -1,5 +1,7 @@
"""Support for the AccuWeather service."""
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from typing import Any, cast
@@ -1,5 +1,7 @@
"""Provide info to system health."""
from __future__ import annotations
from typing import Any
from accuweather.const import ENDPOINT
@@ -1,5 +1,7 @@
"""Support for the AccuWeather service."""
from __future__ import annotations
from typing import cast
from homeassistant.components.weather import (
@@ -1,5 +1,7 @@
"""Use serial protocol of Acer projector to obtain state of the projector."""
from __future__ import annotations
from typing import Final
from homeassistant.const import STATE_OFF, STATE_ON
@@ -5,5 +5,5 @@
"documentation": "https://www.home-assistant.io/integrations/acer_projector",
"iot_class": "local_polling",
"quality_scale": "legacy",
"requirements": ["serialx==1.7.0"]
"requirements": ["serialx==1.4.1"]
}
@@ -1,5 +1,7 @@
"""Use serial protocol of Acer projector to obtain state of the projector."""
from __future__ import annotations
import logging
import re
from typing import Any
@@ -1,5 +1,7 @@
"""Config flow for Rollease Acmeda Automate Pulse Hub."""
from __future__ import annotations
from asyncio import timeout
from contextlib import suppress
from typing import Any
+2
View File
@@ -1,5 +1,7 @@
"""Support for Acmeda Roller Blinds."""
from __future__ import annotations
from typing import Any
from homeassistant.components.cover import (
@@ -1,5 +1,7 @@
"""Base class for Acmeda Roller Blinds."""
from __future__ import annotations
import aiopulse
from homeassistant.core import callback
@@ -1,5 +1,7 @@
"""Helper functions for Acmeda Pulse."""
from __future__ import annotations
from typing import TYPE_CHECKING
from aiopulse import Roller
+2
View File
@@ -1,5 +1,7 @@
"""Code to handle a Pulse Hub."""
from __future__ import annotations
import asyncio
from collections.abc import Callable
@@ -1,5 +1,7 @@
"""Support for Acmeda Roller Blind Batteries."""
from __future__ import annotations
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
from homeassistant.const import PERCENTAGE
from homeassistant.core import HomeAssistant, callback
@@ -1,5 +1,7 @@
"""Support for Actiontec MI424WR (Verizon FIOS) routers."""
from __future__ import annotations
import re
from typing import Final
@@ -1,5 +1,7 @@
"""Support for Actiontec MI424WR (Verizon FIOS) routers."""
from __future__ import annotations
import logging
from typing import Final
@@ -147,7 +147,7 @@ class ActronSystemClimate(ActronAirAcEntity, ActronAirClimateEntity):
@property
def target_temperature(self) -> float:
"""Return the target temperature."""
return self._status.user_aircon_settings.current_setpoint
return self._status.user_aircon_settings.temperature_setpoint_cool_c
@actron_air_command
async def async_set_fan_mode(self, fan_mode: str) -> None:
@@ -239,7 +239,7 @@ class ActronZoneClimate(ActronAirZoneEntity, ActronAirClimateEntity):
@property
def target_temperature(self) -> float | None:
"""Return the target temperature."""
return self._zone.current_setpoint
return self._zone.temperature_setpoint_cool_c
@actron_air_command
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
@@ -6,12 +6,7 @@ from typing import Any
from actron_neo_api import ActronAirAPI, ActronAirAuthError
from homeassistant.config_entries import (
SOURCE_REAUTH,
SOURCE_RECONFIGURE,
ConfigFlow,
ConfigFlowResult,
)
from homeassistant.config_entries import SOURCE_REAUTH, ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_API_TOKEN
from homeassistant.exceptions import HomeAssistantError
@@ -110,14 +105,6 @@ class ActronAirConfigFlow(ConfigFlow, domain=DOMAIN):
data_updates={CONF_API_TOKEN: self._api.refresh_token_value},
)
# Check if this is a reconfigure flow
if self.source == SOURCE_RECONFIGURE:
self._abort_if_unique_id_mismatch(reason="wrong_account")
return self.async_update_reload_and_abort(
self._get_reconfigure_entry(),
data_updates={CONF_API_TOKEN: self._api.refresh_token_value},
)
self._abort_if_unique_id_configured()
return self.async_create_entry(
title=user_data.email,
@@ -151,20 +138,6 @@ class ActronAirConfigFlow(ConfigFlow, domain=DOMAIN):
return self.async_show_form(step_id="reauth_confirm")
async def async_step_reconfigure(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle reconfiguration request."""
return await self.async_step_reconfigure_confirm()
async def async_step_reconfigure_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Confirm reconfiguration dialog."""
if user_input is not None:
return await self.async_step_user()
return self.async_show_form(step_id="reconfigure_confirm")
async def async_step_connection_error(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
@@ -1,5 +1,7 @@
"""Coordinator for Actron Air integration."""
from __future__ import annotations
from dataclasses import dataclass
from datetime import timedelta
@@ -1,5 +1,7 @@
"""Diagnostics support for Actron Air."""
from __future__ import annotations
from typing import Any
from homeassistant.components.diagnostics import async_redact_data
@@ -60,7 +60,7 @@ rules:
entity-translations: done
exception-translations: done
icon-translations: done
reconfiguration-flow: done
reconfiguration-flow: todo
repair-issues:
status: exempt
comment: This integration does not have any known issues that require repair.
@@ -4,8 +4,7 @@
"already_configured": "[%key:common::config_flow::abort::already_configured_account%]",
"oauth2_error": "Failed to start authentication flow",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]",
"wrong_account": "You must authenticate with the same Actron Air account that was originally configured."
"wrong_account": "You must reauthenticate with the same Actron Air account that was originally configured."
},
"error": {
"oauth2_error": "Failed to start authentication flow. Please try again later."
@@ -23,10 +22,6 @@
"description": "Your Actron Air authentication has expired. Select continue to reauthenticate with your Actron Air account. You will be prompted to log in again to restore the connection.",
"title": "Authentication expired"
},
"reconfigure_confirm": {
"description": "Reconfigure your Actron Air account. You will be prompted to log in again. Note: you must use the same account that was originally configured.",
"title": "Reconfigure Actron Air"
},
"timeout": {
"data": {},
"description": "The authentication process timed out. Please try again.",
@@ -1,5 +1,7 @@
"""The Adax integration."""
from __future__ import annotations
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
+2
View File
@@ -1,5 +1,7 @@
"""Support for Adax wifi-enabled home heaters."""
from __future__ import annotations
from typing import Any, cast
from adax import Adax
@@ -1,5 +1,7 @@
"""Config flow for Adax integration."""
from __future__ import annotations
import logging
from typing import Any
+2
View File
@@ -1,5 +1,7 @@
"""Support for Adax energy sensors."""
from __future__ import annotations
from dataclasses import dataclass
from typing import cast
@@ -1,5 +1,7 @@
"""Support for AdGuard Home."""
from __future__ import annotations
from dataclasses import dataclass
from adguardhome import AdGuardHome, AdGuardHomeConnectionError
@@ -1,5 +1,7 @@
"""Config flow to configure the AdGuard Home integration."""
from __future__ import annotations
from typing import Any
from adguardhome import AdGuardHome, AdGuardHomeConnectionError
@@ -1,5 +1,7 @@
"""AdGuard Home base entity."""
from __future__ import annotations
from adguardhome import AdGuardHomeError
from homeassistant.config_entries import SOURCE_HASSIO
@@ -1,5 +1,7 @@
"""Support for AdGuard Home sensors."""
from __future__ import annotations
from collections.abc import Callable, Coroutine
from dataclasses import dataclass
from datetime import timedelta
@@ -1,5 +1,7 @@
"""Support for AdGuard Home switches."""
from __future__ import annotations
from collections.abc import Callable, Coroutine
from dataclasses import dataclass
from datetime import timedelta
@@ -1,5 +1,7 @@
"""AdGuard Home Update platform."""
from __future__ import annotations
from datetime import timedelta
from typing import Any
@@ -1,5 +1,7 @@
"""Support for ADS binary sensors."""
from __future__ import annotations
import pyads
import voluptuous as vol
+2
View File
@@ -1,5 +1,7 @@
"""Support for Automation Device Specification (ADS)."""
from __future__ import annotations
from enum import StrEnum
from typing import TYPE_CHECKING
+2
View File
@@ -1,5 +1,7 @@
"""Support for ADS covers."""
from __future__ import annotations
from typing import Any
import pyads
+2
View File
@@ -1,5 +1,7 @@
"""Support for ADS light sources."""
from __future__ import annotations
from typing import Any
import pyads
+2
View File
@@ -1,5 +1,7 @@
"""Support for ADS select entities."""
from __future__ import annotations
import pyads
import voluptuous as vol
+2
View File
@@ -1,5 +1,7 @@
"""Support for ADS sensors."""
from __future__ import annotations
import voluptuous as vol
from homeassistant.components.sensor import (
+2
View File
@@ -1,5 +1,7 @@
"""Support for ADS switch platform."""
from __future__ import annotations
from typing import Any
import pyads
+2
View File
@@ -1,5 +1,7 @@
"""Support for ADS valves."""
from __future__ import annotations
import pyads
import voluptuous as vol
@@ -1,5 +1,7 @@
"""Binary Sensor platform for Advantage Air integration."""
from __future__ import annotations
from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
@@ -1,5 +1,7 @@
"""Climate platform for Advantage Air integration."""
from __future__ import annotations
from decimal import Decimal
import logging
from typing import Any
@@ -1,5 +1,7 @@
"""Config Flow for Advantage Air integration."""
from __future__ import annotations
from typing import Any
from advantage_air import ApiError, advantage_air
@@ -1,5 +1,7 @@
"""Coordinator for the Advantage Air integration."""
from __future__ import annotations
from datetime import timedelta
import logging
from typing import Any
@@ -1,5 +1,7 @@
"""Provides diagnostics for Advantage Air."""
from __future__ import annotations
from typing import Any
from homeassistant.components.diagnostics import async_redact_data
@@ -1,5 +1,7 @@
"""Sensor platform for Advantage Air integration."""
from __future__ import annotations
from decimal import Decimal
from typing import Any
@@ -1,5 +1,7 @@
"""Services for Advantage Air integration."""
from __future__ import annotations
import voluptuous as vol
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
@@ -1,5 +1,7 @@
"""Config flow for AEMET OpenData."""
from __future__ import annotations
from typing import Any
from aemet_opendata.exceptions import AuthError
+2
View File
@@ -1,5 +1,7 @@
"""Constant values for the AEMET OpenData component."""
from __future__ import annotations
from aemet_opendata.const import (
AOD_COND_CLEAR_NIGHT,
AOD_COND_CLOUDY,
@@ -1,5 +1,7 @@
"""Weather data coordinator for the AEMET OpenData service."""
from __future__ import annotations
from asyncio import timeout
from dataclasses import dataclass
from datetime import timedelta
@@ -1,5 +1,7 @@
"""Support for the AEMET OpenData diagnostics."""
from __future__ import annotations
from typing import Any
from aemet_opendata.const import AOD_COORDS, AOD_IMG_BYTES
+2
View File
@@ -1,5 +1,7 @@
"""Entity classes for the AEMET OpenData integration."""
from __future__ import annotations
from typing import Any
from aemet_opendata.helpers import dict_nested_value

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