Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3dc8013
Fix missing f-string prefix in local_todo error message (#182361)
David-Wu1119 Sep 16, 2026
a09f39b
Add my-PV reauth flow (#181674)
rrooggiieerr Sep 16, 2026
d7dc840
Do not log the tracked location in NWS (#182350)
frenck Sep 16, 2026
5fd9901
Fix missing f-string prefix in wiz error message (#182363)
David-Wu1119 Sep 16, 2026
4e2e79a
Remove workarounds for copilot skills (#182353)
abmantis Sep 16, 2026
b796ade
Fix missing f-string prefix in local_calendar error message (#182360)
David-Wu1119 Sep 16, 2026
9a69397
Fix missing f-string prefix in prowl error message (#182362)
David-Wu1119 Sep 16, 2026
5dc13f3
Fix missing f-string prefix in egauge error message (#182359)
David-Wu1119 Sep 16, 2026
79efc68
Update pnpm to 12.4.0 (#182357)
renovate[bot] Sep 16, 2026
e583ba1
Do not log IBANs and account numbers in FinTS (#182342)
frenck Sep 16, 2026
f529a36
Update uv to 0.12.11 (#182355)
renovate[bot] Sep 16, 2026
4ddbfcb
Bump voip-utils (#182339)
synesthesiam Sep 16, 2026
5dae5ff
Bump aioaxlevpp to 0.1.1 (#182336)
Herbertmt978 Sep 16, 2026
365fef6
Write the backup store with private=True so the backup password is no…
dbl-0 Sep 16, 2026
c72b4e3
Bump yarl to 1.25.1 (#182345)
bdraco Sep 16, 2026
4543184
Do not log the Start.ca API key (#182279)
frenck Sep 16, 2026
7f991e0
Bump aioipp to 0.19.3 and log IPP parse errors at warning level (#182…
brianegge Sep 16, 2026
7819e3a
Bump teslemetry-stream to 0.13.2 (#182311)
Bre77 Sep 16, 2026
32ad04c
Add missing stabilized binary sensor description for Xiaomi BLE scale…
rasadregmi Sep 16, 2026
89b4a9a
KNX: Validate entity_category for read-only platforms (#182141)
farmio Sep 16, 2026
0dd1bd0
Do not log the Xiaomi router password (#182370)
frenck Sep 16, 2026
b11318c
Bump neopool-modbus to 4.8.0 (#182349)
svasek Sep 16, 2026
ce63d1d
Add second Salda Smarty code owner (#182379)
marcodutto Sep 16, 2026
7fd85f5
Add async_retry_migration to Config Entries (#182054)
gjohansson-ST Sep 16, 2026
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
1 change: 1 addition & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- Start review comments with a short, one-sentence summary of the suggested fix.
- Do not comment on code style, formatting or linting issues.
- When reviewing changes under `homeassistant/components/` or `tests/components/`, use the `ha-integration-knowledge` skill as the primary reference.
- Flag comments that over-explain straightforward code, narrate the obvious, or read like AI commentary (multi-sentence justifications for a single line).
- 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.
- Check that the PR description is complete and filled in according to the PR template included below. Every section and checklist item from the template must be present, except the `## Breaking change` section which is optional. No content from the template should be missing, except for HTML comments and Markdown link reference definitions (lines of the form `[name]: url`), which do not render and cannot be verified from the description. Even unchecked checkboxes or empty sections must be present. This is a hard requirement.
Expand Down
51 changes: 0 additions & 51 deletions .github/instructions/integrations.instructions.md

This file was deleted.

2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ repos:
pass_filenames: false
language: script
types: [text]
files: ^(AGENTS\.md|\.claude/skills/(?!github-pr-reviewer/).+/SKILL\.md|\.github/copilot-instructions\.md|script/gen_copilot_instructions\.py)$
files: ^(AGENTS\.md|\.github/copilot-instructions\.md|script/gen_copilot_instructions\.py)$
- id: hassfest
name: hassfest
entry: script/run-in-env.sh python3 -m script.hassfest
Expand Down
4 changes: 2 additions & 2 deletions CODEOWNERS

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion homeassistant/components/axle_energy/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
"integration_type": "service",
"iot_class": "cloud_polling",
"quality_scale": "bronze",
"requirements": ["aioaxlevpp==0.1.0"]
"requirements": ["aioaxlevpp==0.1.1"]
}
7 changes: 6 additions & 1 deletion homeassistant/components/backup/store.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
STORE_DELAY_SAVE = 30
STORAGE_KEY = DOMAIN
STORAGE_VERSION = 1
STORAGE_VERSION_MINOR = 7
STORAGE_VERSION_MINOR = 8


class StoredBackupData(TypedDict):
Expand All @@ -39,6 +39,8 @@ def __init__(self, hass: HomeAssistant) -> None:
STORAGE_KEY,
max_readable_version=self._MAX_READABLE_VERSION,
minor_version=STORAGE_VERSION_MINOR,
# The store persists the automatic backup password in plaintext.
private=True,
)

@override
Expand Down Expand Up @@ -85,6 +87,9 @@ async def _async_migrate_func(
for backup in data["backups"]:
backup["failed_addons"] = []
backup["failed_folders"] = []
# Version 1.8 does not change the data. The minor version was bumped
# so that stores written before the store was made private are
# rewritten once, with mode 0600, on the first load.

# Note: We allow reading data with major version 2 in which the unused key
# data["config"]["schedule"]["state"] will be removed. The bump to 2 is
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/egauge/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ async def _async_update_data(self) -> EgaugeData:
EgaugeException,
) as err:
# will raise ConfigEntryAuthFailed once reauth is implemented
raise ConfigEntryError("Error fetching device info: {err}") from err
raise ConfigEntryError(f"Error fetching device info: {err}") from err
except ConnectError as err:
raise UpdateFailed(f"Error fetching device info: {err}") from err

Expand Down
16 changes: 5 additions & 11 deletions homeassistant/components/fints/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,28 +87,24 @@ def setup_platform(

for account in balance_accounts:
if config[CONF_ACCOUNTS] and account.iban not in account_config:
_LOGGER.debug("Skipping account %s for bank %s", account.iban, fints_name)
_LOGGER.debug("Skipping account for bank %s", fints_name)
continue

if not (account_name := account_config.get(account.iban)):
account_name = f"{fints_name} - {account.iban}"
accounts.append(FinTsAccount(client, account, account_name))
_LOGGER.debug("Creating account %s for bank %s", account.iban, fints_name)
_LOGGER.debug("Creating account for bank %s", fints_name)

for account in holdings_accounts:
if config[CONF_HOLDINGS] and account.accountnumber not in holdings_config:
_LOGGER.debug(
"Skipping holdings %s for bank %s", account.accountnumber, fints_name
)
_LOGGER.debug("Skipping holdings for bank %s", fints_name)
continue

account_name = holdings_config.get(account.accountnumber)
if not account_name:
account_name = f"{fints_name} - {account.accountnumber}"
accounts.append(FinTsHoldingsAccount(client, account, account_name))
_LOGGER.debug(
"Creating holdings %s for bank %s", account.accountnumber, fints_name
)
_LOGGER.debug("Creating holdings for bank %s", fints_name)

add_entities(accounts, True)

Expand Down Expand Up @@ -216,9 +212,7 @@ def detect_accounts(self) -> tuple[list, list]:

else:
_LOGGER.warning(
"Could not determine type of account %s from %s",
account.iban,
self.client.user_id,
"Could not determine type of account for bank %s", self.name
)

return balance_accounts, holdings_accounts
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/ipp/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ async def async_step_user(
_LOGGER.debug("IPP Connection/Response Error", exc_info=True)
return self._show_setup_form({"base": "cannot_connect"})
except IPPParseError:
_LOGGER.debug("IPP Parse Error", exc_info=True)
_LOGGER.warning("IPP Parse Error", exc_info=True)
return self.async_abort(reason="parse_error")
except IPPVersionNotSupportedError:
return self.async_abort(reason="ipp_version_error")
Expand Down Expand Up @@ -147,7 +147,7 @@ async def async_step_zeroconf(
_LOGGER.debug("IPP Connection/Response Error", exc_info=True)
return self.async_abort(reason="cannot_connect")
except IPPParseError:
_LOGGER.debug("IPP Parse Error", exc_info=True)
_LOGGER.warning("IPP Parse Error", exc_info=True)
return self.async_abort(reason="parse_error")
except IPPVersionNotSupportedError:
return self.async_abort(reason="ipp_version_error")
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/ipp/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
"integration_type": "device",
"iot_class": "local_polling",
"loggers": ["deepmerge", "pyipp"],
"requirements": ["aioipp==0.19.0"],
"requirements": ["aioipp==0.19.3"],
"zeroconf": ["_ipps._tcp.local.", "_ipp._tcp.local."]
}
5 changes: 5 additions & 0 deletions homeassistant/components/knx/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@ class FanZeroMode(StrEnum):
Platform.WEATHER,
}

# read-only platforms raising when added with `EntityCategory.CONFIG`
PLATFORMS_WITHOUT_CONFIG_CATEGORY: Final = frozenset(
{Platform.BINARY_SENSOR, Platform.SENSOR}
)

SUPPORTED_PLATFORMS_UI: Final = {
Platform.BINARY_SENSOR,
Platform.BUTTON,
Expand Down
6 changes: 4 additions & 2 deletions homeassistant/components/knx/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
Platform,
)
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity import ENTITY_CATEGORIES_SCHEMA
from homeassistant.util import slugify

from .const import (
Expand Down Expand Up @@ -78,6 +77,7 @@
from .validation import (
backwards_compatible_xknx_climate_enum_member,
dpt_base_type_validator,
entity_category_validator,
ga_list_validator,
ga_validator,
numeric_type_validator,
Expand Down Expand Up @@ -260,7 +260,9 @@ def _entity_base_schema(platform: Platform) -> probatio.Schema:
probatio.Optional(CONF_DEFAULT_ENTITY_ID): probatio.All(
cv.entity_id, cv.entity_domain(platform)
),
probatio.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
probatio.Optional(CONF_ENTITY_CATEGORY): entity_category_validator(
platform
),
probatio.Optional(CONF_UNIQUE_ID): probatio.All(
cv.string, probatio.Length(min=1)
),
Expand Down
6 changes: 5 additions & 1 deletion homeassistant/components/knx/storage/config_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
_LOGGER = logging.getLogger(__name__)

STORAGE_VERSION: Final = 2
STORAGE_VERSION_MINOR: Final = 4
STORAGE_VERSION_MINOR: Final = 5
STORAGE_KEY: Final = f"{DOMAIN}/config_store.json"

type KNXPlatformStoreModel = dict[str, dict[str, Any]] # unique_id: configuration
Expand Down Expand Up @@ -80,6 +80,10 @@ async def _async_migrate_func(
# version 2.4 introduced in 2026.5
migration.migrate_2_3_to_2_4(old_data)

if old_major_version <= 2 and old_minor_version < 5:
# version 2.5 introduced in 2026.10
migration.migrate_2_4_to_2_5(old_data)

return old_data


Expand Down
60 changes: 34 additions & 26 deletions homeassistant/components/knx/storage/entity_store_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
Platform,
)
from homeassistant.helpers import selector
from homeassistant.helpers.entity import ENTITY_CATEGORIES_SCHEMA
from homeassistant.helpers.typing import VolDictType

from ..const import (
Expand All @@ -54,7 +53,11 @@
SelectConf,
)
from ..dpt import get_supported_dpts, raw_payload_length
from ..validation import validate_number_attributes, validate_sensor_attributes
from ..validation import (
entity_category_validator,
validate_number_attributes,
validate_sensor_attributes,
)
from .const import (
CONF_ALWAYS_CALLBACK,
CONF_COLOR,
Expand Down Expand Up @@ -140,30 +143,33 @@
SyncStateSelector,
)

BASE_ENTITY_SCHEMA = probatio.All(
{
probatio.Optional(CONF_NAME, default=None): probatio.Maybe(str),
probatio.Optional(CONF_DEVICE_INFO, default=None): probatio.Maybe(str),
probatio.Optional(CONF_ENTITY_CATEGORY, default=None): probatio.Any(
ENTITY_CATEGORIES_SCHEMA, probatio.SetTo(None)
),
},
probatio.Any(
probatio.Schema(
{
probatio.Required(CONF_NAME): probatio.All(str, probatio.IsTrue()),
},
extra=probatio.ALLOW_EXTRA,
),
probatio.Schema(
{
probatio.Required(CONF_DEVICE_INFO): str,
},
extra=probatio.ALLOW_EXTRA,

def base_entity_schema(platform: Platform) -> probatio.All:
"""Return the base entity schema for a platform."""
return probatio.All(
{
probatio.Optional(CONF_NAME, default=None): probatio.Maybe(str),
probatio.Optional(CONF_DEVICE_INFO, default=None): probatio.Maybe(str),
probatio.Optional(
CONF_ENTITY_CATEGORY, default=None
): entity_category_validator(platform),
},
probatio.Any(
probatio.Schema(
{
probatio.Required(CONF_NAME): probatio.All(str, probatio.IsTrue()),
},
extra=probatio.ALLOW_EXTRA,
),
probatio.Schema(
{
probatio.Required(CONF_DEVICE_INFO): str,
},
extra=probatio.ALLOW_EXTRA,
),
msg="One of `Device` or `Name` is required",
),
msg="One of `Device` or `Name` is required",
),
)
)


BINARY_SENSOR_KNX_SCHEMA = probatio.Schema(
Expand Down Expand Up @@ -1045,7 +1051,9 @@ def _sensor_attribute_sub_validator(config: dict) -> dict:
{
probatio.Required(CONF_DATA): probatio.Schema(
{
probatio.Required(CONF_ENTITY): BASE_ENTITY_SCHEMA,
probatio.Required(CONF_ENTITY): base_entity_schema(
platform
),
probatio.Required(DOMAIN): knx_schema,
},
extra=probatio.PREVENT_EXTRA, # restrict in data key for yaml edit
Expand Down
15 changes: 13 additions & 2 deletions homeassistant/components/knx/storage/migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

from typing import Any

from homeassistant.const import Platform
from homeassistant.const import CONF_ENTITY_CATEGORY, EntityCategory, Platform

from ..const import CONF_RESPOND_TO_READ
from ..const import CONF_RESPOND_TO_READ, PLATFORMS_WITHOUT_CONFIG_CATEGORY
from . import const as store_const


Expand Down Expand Up @@ -60,3 +60,14 @@ def migrate_2_2_to_2_3(data: dict[str, Any]) -> None:
def migrate_2_3_to_2_4(data: dict[str, Any]) -> None:
"""Migrate from schema 2.3 to schema 2.4."""
data.setdefault("expose", {})


def migrate_2_4_to_2_5(data: dict[str, Any]) -> None:
"""Migrate from schema 2.4 to schema 2.5."""
for platform in PLATFORMS_WITHOUT_CONFIG_CATEGORY:
for entity in data.get("entities", {}).get(platform, {}).values():
# `EntityCategory.CONFIG` is not valid for these platforms
# so these entities were never set up
entity_data = entity[store_const.CONF_ENTITY]
if entity_data.get(CONF_ENTITY_CATEGORY) == EntityCategory.CONFIG:
entity_data[CONF_ENTITY_CATEGORY] = EntityCategory.DIAGNOSTIC
Loading
Loading