Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions homeassistant/auth/auth_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ async def async_create_user(

new_user = models.User(**kwargs)

while new_user.id in self._users:
new_user = models.User(**kwargs)

self._users[new_user.id] = new_user

if credentials is None:
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/caldav/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/caldav",
"iot_class": "cloud_polling",
"loggers": ["caldav", "vobject"],
"requirements": ["caldav==1.6.0", "icalendar==6.1.0"]
"requirements": ["caldav==1.6.0", "icalendar==6.3.1"]
}
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.11", "deebot-client==13.5.0"]
"requirements": ["py-sucks==0.9.11", "deebot-client==13.6.0"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/husqvarna_automower/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
"iot_class": "cloud_push",
"loggers": ["aioautomower"],
"quality_scale": "silver",
"requirements": ["aioautomower==2.1.1"]
"requirements": ["aioautomower==2.1.2"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/knx/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"requirements": [
"xknx==3.8.0",
"xknxproject==3.8.2",
"knx-frontend==2025.7.23.50952"
"knx-frontend==2025.8.4.154919"
],
"single_config_entry": true
}
4 changes: 3 additions & 1 deletion homeassistant/components/matter/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,9 @@ def _update_from_device(self) -> None:
native_min_value=0.5,
native_step=0.5,
device_to_ha=(
lambda x: None if x is None else x / 2 # Matter range (1-200)
lambda x: None
if x is None
else min(x, 200) / 2 # Matter range (1-200, capped at 200)
),
ha_to_device=lambda x: round(x * 2), # HA range 0.5–100.0%
mode=NumberMode.SLIDER,
Expand Down
10 changes: 6 additions & 4 deletions homeassistant/components/tuya/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
"ks",
}

_SWITCH_DP_CODES = (DPCode.SWITCH_FAN, DPCode.FAN_SWITCH, DPCode.SWITCH)


async def async_setup_entry(
hass: HomeAssistant,
Expand All @@ -60,7 +62,9 @@ def async_discover_device(device_ids: list[str]) -> None:
entities: list[TuyaFanEntity] = []
for device_id in device_ids:
device = hass_data.manager.device_map[device_id]
if device and device.category in TUYA_SUPPORT_TYPE:
if device.category in TUYA_SUPPORT_TYPE and any(
code in device.status for code in _SWITCH_DP_CODES
):
entities.append(TuyaFanEntity(device, hass_data.manager))
async_add_entities(entities)

Expand Down Expand Up @@ -90,9 +94,7 @@ def __init__(
"""Init Tuya Fan Device."""
super().__init__(device, device_manager)

self._switch = self.find_dpcode(
(DPCode.SWITCH_FAN, DPCode.FAN_SWITCH, DPCode.SWITCH), prefer_function=True
)
self._switch = self.find_dpcode(_SWITCH_DP_CODES, prefer_function=True)

self._attr_preset_modes = []
if enum_type := self.find_dpcode(
Expand Down
58 changes: 33 additions & 25 deletions homeassistant/components/zwave_js/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ async def async_on_node_added(self, node: ZwaveNode) -> None:
)
)

await self.async_check_preprovisioned_device(node)
await self.async_check_pre_provisioned_device(node)

if node.is_controller_node:
# Create a controller status sensor for each device
Expand Down Expand Up @@ -637,8 +637,8 @@ def async_on_identify(self, event: dict) -> None:
f"{DOMAIN}.identify_controller.{dev_id[1]}",
)

async def async_check_preprovisioned_device(self, node: ZwaveNode) -> None:
"""Check if the node was preprovisioned and update the device registry."""
async def async_check_pre_provisioned_device(self, node: ZwaveNode) -> None:
"""Check if the node was pre-provisioned and update the device registry."""
provisioning_entry = (
await self.driver_events.driver.controller.async_get_provisioning_entry(
node.node_id
Expand All @@ -648,29 +648,37 @@ async def async_check_preprovisioned_device(self, node: ZwaveNode) -> None:
provisioning_entry
and provisioning_entry.additional_properties
and "device_id" in provisioning_entry.additional_properties
):
preprovisioned_device = self.dev_reg.async_get(
provisioning_entry.additional_properties["device_id"]
and (
pre_provisioned_device := self.dev_reg.async_get(
provisioning_entry.additional_properties["device_id"]
)
)

if preprovisioned_device:
dsk = provisioning_entry.dsk
dsk_identifier = (DOMAIN, f"provision_{dsk}")

# If the pre-provisioned device has the DSK identifier, remove it
if dsk_identifier in preprovisioned_device.identifiers:
driver = self.driver_events.driver
device_id = get_device_id(driver, node)
device_id_ext = get_device_id_ext(driver, node)
new_identifiers = preprovisioned_device.identifiers.copy()
new_identifiers.remove(dsk_identifier)
new_identifiers.add(device_id)
if device_id_ext:
new_identifiers.add(device_id_ext)
self.dev_reg.async_update_device(
preprovisioned_device.id,
new_identifiers=new_identifiers,
)
and (dsk_identifier := (DOMAIN, f"provision_{provisioning_entry.dsk}"))
in pre_provisioned_device.identifiers
):
driver = self.driver_events.driver
device_id = get_device_id(driver, node)
device_id_ext = get_device_id_ext(driver, node)
new_identifiers = pre_provisioned_device.identifiers.copy()
new_identifiers.remove(dsk_identifier)
new_identifiers.add(device_id)
if device_id_ext:
new_identifiers.add(device_id_ext)

if self.dev_reg.async_get_device(identifiers=new_identifiers):
# If a device entry is registered with the node ID based identifiers,
# just remove the device entry with the DSK identifier.
self.dev_reg.async_update_device(
pre_provisioned_device.id,
remove_config_entry_id=self.config_entry.entry_id,
)
else:
# Add the node ID based identifiers to the device entry
# with the DSK identifier and remove the DSK identifier.
self.dev_reg.async_update_device(
pre_provisioned_device.id,
new_identifiers=new_identifiers,
)

async def async_register_node_in_dev_reg(self, node: ZwaveNode) -> dr.DeviceEntry:
"""Register node in dev reg."""
Expand Down
8 changes: 4 additions & 4 deletions requirements_all.txt

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

8 changes: 4 additions & 4 deletions requirements_test_all.txt

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

16 changes: 15 additions & 1 deletion tests/auth/test_auth_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import asyncio
from typing import Any
from unittest.mock import patch
from unittest.mock import PropertyMock, patch

from freezegun.api import FrozenDateTimeFactory
import pytest
Expand Down Expand Up @@ -300,6 +300,20 @@ async def test_loading_does_not_write_right_away(
assert hass_storage[auth_store.STORAGE_KEY] != {}


async def test_duplicate_uuid(
hass: HomeAssistant, hass_storage: dict[str, Any]
) -> None:
"""Test we don't override user if we have a duplicate user ID."""
hass_storage[auth_store.STORAGE_KEY] = MOCK_STORAGE_DATA
store = auth_store.AuthStore(hass)
await store.async_load()
with patch("uuid.UUID.hex", new_callable=PropertyMock) as hex_mock:
hex_mock.side_effect = ["user-id", "new-id"]
user = await store.async_create_user("Test User")
assert len(hex_mock.mock_calls) == 2
assert user.id == "new-id"


async def test_add_remove_user_affects_tokens(
hass: HomeAssistant, hass_storage: dict[str, Any]
) -> None:
Expand Down
2 changes: 1 addition & 1 deletion tests/components/matter/fixtures/nodes/pump.json
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@
"1/6/65528": [],
"1/6/65529": [0, 1, 2],
"1/6/65531": [0, 65532, 65533, 65528, 65529, 65531],
"1/8/0": 254,
"1/8/0": 200,
"1/8/15": 0,
"1/8/17": 0,
"1/8/65532": 0,
Expand Down
2 changes: 1 addition & 1 deletion tests/components/matter/snapshots/test_number.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -2189,7 +2189,7 @@
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '127.0',
'state': '100.0',
})
# ---
# name: test_numbers[silabs_laundrywasher][number.laundrywasher_temperature_setpoint-entry]
Expand Down
2 changes: 1 addition & 1 deletion tests/components/matter/test_number.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ async def test_pump_level(
# CurrentLevel on LevelControl cluster
state = hass.states.get("number.mock_pump_setpoint")
assert state
assert state.state == "127.0"
assert state.state == "100.0"

set_node_attribute(matter_node, 1, 8, 0, 100)
await trigger_subscription_callback(hass, matter_client)
Expand Down
15 changes: 14 additions & 1 deletion tests/components/tuya/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
],
"cs_vmxuxszzjwp5smli": [
# https://github.com/home-assistant/core/issues/119865
Platform.FAN,
# Platform.FAN, missing DPCodes in device status
Platform.HUMIDIFIER,
],
"cs_zibqa9dutqyaxym2": [
Expand Down Expand Up @@ -214,6 +214,10 @@
# https://github.com/home-assistant/core/issues/143499
Platform.SENSOR,
],
"fs_ibytpo6fpnugft1c": [
# https://github.com/home-assistant/core/issues/135541
# Platform.FAN, missing DPCodes in device status
],
"gyd_lgekqfxdabipm3tn": [
# https://github.com/home-assistant/core/issues/133173
Platform.LIGHT,
Expand Down Expand Up @@ -294,6 +298,15 @@
Platform.BINARY_SENSOR,
Platform.SENSOR,
],
"sd_lr33znaodtyarrrz": [
# https://github.com/home-assistant/core/issues/141278
Platform.BUTTON,
Platform.NUMBER,
Platform.SELECT,
Platform.SENSOR,
Platform.SWITCH,
Platform.VACUUM,
],
"sfkzq_o6dagifntoafakst": [
# https://github.com/home-assistant/core/issues/148116
Platform.SWITCH,
Expand Down
2 changes: 1 addition & 1 deletion tests/components/tuya/fixtures/clkg_nhyj64w2.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"endpoint": "https://apigw.tuyaeu.com",
"terminal_id": "1729466466688hgsTp2",
"terminal_id": "REDACTED",
"mqtt_connected": true,
"disabled_by": null,
"disabled_polling": false,
Expand Down
2 changes: 1 addition & 1 deletion tests/components/tuya/fixtures/co2bj_yrr3eiyiacm31ski.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"endpoint": "https://apigw.tuyaus.com",
"terminal_id": "1732306182276g6jQLp",
"terminal_id": "REDACTED",
"mqtt_connected": true,
"disabled_by": null,
"disabled_polling": false,
Expand Down
2 changes: 1 addition & 1 deletion tests/components/tuya/fixtures/cs_ka2wfrdoogpvgzfi.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"endpoint": "https://apigw.tuyaeu.com",
"terminal_id": "mock_terminal_id",
"terminal_id": "REDACTED",
"mqtt_connected": true,
"disabled_by": null,
"disabled_polling": false,
Expand Down
2 changes: 1 addition & 1 deletion tests/components/tuya/fixtures/cs_vmxuxszzjwp5smli.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"endpoint": "https://apigw.tuyaeu.com",
"terminal_id": "mock_terminal_id",
"terminal_id": "REDACTED",
"mqtt_connected": true,
"disabled_by": null,
"disabled_polling": false,
Expand Down
2 changes: 1 addition & 1 deletion tests/components/tuya/fixtures/cwjwq_agwu93lr.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"endpoint": "https://apigw.tuyaeu.com",
"terminal_id": "1750837476328i3TNXQ",
"terminal_id": "REDACTED",
"mqtt_connected": true,
"disabled_by": null,
"disabled_polling": false,
Expand Down
2 changes: 1 addition & 1 deletion tests/components/tuya/fixtures/cwwsq_wfkzyy0evslzsmoi.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"endpoint": "https://apigw.tuyaeu.com",
"terminal_id": "1747045731408d0tb5M",
"terminal_id": "REDACTED",
"mqtt_connected": true,
"disabled_by": null,
"disabled_polling": false,
Expand Down
2 changes: 1 addition & 1 deletion tests/components/tuya/fixtures/cwysj_z3rpyvznfcch99aa.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"endpoint": "https://apigw.tuyaeu.com",
"terminal_id": "1751729689584Vh0VoL",
"terminal_id": "REDACTED",
"mqtt_connected": true,
"disabled_by": null,
"disabled_polling": false,
Expand Down
2 changes: 1 addition & 1 deletion tests/components/tuya/fixtures/cz_2jxesipczks0kdct.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"endpoint": "https://apigw.tuyaus.com",
"terminal_id": "1742695000703Ozq34h",
"terminal_id": "REDACTED",
"mqtt_connected": true,
"disabled_by": null,
"disabled_polling": false,
Expand Down
2 changes: 1 addition & 1 deletion tests/components/tuya/fixtures/dlq_kxdr6su0c55p7bbo.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"endpoint": "https://apigw.tuyaeu.com",
"terminal_id": "1733006572651YokbqV",
"terminal_id": "REDACTED",
"mqtt_connected": null,
"disabled_by": null,
"disabled_polling": false,
Expand Down
Loading
Loading