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
2 changes: 1 addition & 1 deletion homeassistant/components/analytics/analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,7 @@ async def _async_snapshot_payload(hass: HomeAssistant) -> dict: # noqa: C901
removed_devices: set[str] = set()

# Get device list
for device_entry in (*dev_reg.devices.values(), *dev_reg.child_devices.values()):
for device_entry in (*dev_reg.devices, *dev_reg.child_devices.values()):
config_entry = hass.config_entries.async_get_entry(device_entry.config_entry_id)

if config_entry is None:
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/config/device_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def websocket_list_composite_splits(
None,
),
}
for composite_id, devices in registry.devices.get_composite_splits().items()
for composite_id, devices in registry._devices.get_composite_splits().items() # noqa: SLF001
},
)

Expand All @@ -92,7 +92,7 @@ def websocket_list_devices(
inner = b",".join(
[
entry.json_repr
for container in (registry.devices, registry.child_devices)
for container in (registry._devices, registry.child_devices) # noqa: SLF001
for entry in container.values()
if entry.json_repr is not None
]
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/device_automation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ async def async_get_device_automations(
entity_registry = er.async_get(hass)
domain_devices: dict[str, set[str]] = {}
device_entities_domains: dict[str, set[str]] = {}
match_device_ids = set(device_ids or device_registry.devices)
match_device_ids = set(device_ids or device_registry._devices) # noqa: SLF001
combined_results: dict[str, list[dict[str, Any]]] = {}

for device_id in match_device_ids:
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/ecobee/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ def remote_sensor_ids_names(self) -> list:
"id": device.id,
"name_by_user": device.name_by_user or device.name,
}
for device in device_registry.devices.values()
for device in device_registry.devices
for sensor_info in sensors_info
if device.name == sensor_info["name"]
and any(identifier[0] == DOMAIN for identifier in device.identifiers)
Expand Down Expand Up @@ -830,7 +830,7 @@ def _sensor_devices_in_preset_mode(self, preset_mode: str | None) -> list[str]:
return sorted(
[
device.name_by_user or device.name
for device in device_registry.devices.values()
for device in device_registry.devices
for sensor_name in sensor_names
if device.name == sensor_name
and any(identifier[0] == DOMAIN for identifier in device.identifiers)
Expand Down
5 changes: 3 additions & 2 deletions homeassistant/components/homematicip_cloud/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,9 @@ def async_remove_from_registries(self) -> None:
if device_id := self.registry_entry.device_id:
# Remove from device registry.
device_registry = dr.async_get(self.hass)
if device_id in device_registry.devices:
# This will also remove associated entities from entity registry.
# This will also remove associated entities from entity registry,
# ignore an already removed device.
with contextlib.suppress(KeyError):
device_registry.async_remove_device(device_id)
else: # noqa: PLR5501
# Remove from entity registry.
Expand Down
38 changes: 38 additions & 0 deletions homeassistant/components/hotspring/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.selector import TextSelector
from homeassistant.helpers.service_info.zeroconf import ZeroconfServiceInfo

from .const import DOMAIN

Expand All @@ -38,6 +39,9 @@ class HotSpringConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Hot Spring."""

VERSION = 1
discovered_host: str
discovered_spa: Spa
discovered_title: str

@override
async def async_step_user(
Expand Down Expand Up @@ -86,3 +90,37 @@ async def async_step_reconfigure(
) -> ConfigFlowResult:
"""Handle reconfiguration of the Hot Spring spa."""
return await self.async_step_user(user_input)

@override
async def async_step_zeroconf(
self, discovery_info: ZeroconfServiceInfo
) -> ConfigFlowResult:
"""Handle zeroconf discovery."""
self.discovered_host = discovery_info.host
try:
self.discovered_spa = await validate_input(
self.hass, {CONF_HOST: discovery_info.host}
)
except HotSpringConnectionError, HotSpringError:
return self.async_abort(reason="cannot_connect")

await self.async_set_unique_id(self.discovered_spa.info.mac_address)
self._abort_if_unique_id_configured(updates={CONF_HOST: discovery_info.host})

self.discovered_title = self.discovered_spa.info.hostname or "Hot Spring Spa"
self.context["title_placeholders"] = {"name": self.discovered_title}

self._set_confirm_only()
return self.async_show_form(
step_id="zeroconf_confirm",
description_placeholders={"name": self.discovered_title},
)

async def async_step_zeroconf_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle a flow initiated by zeroconf."""
return self.async_create_entry(
title=self.discovered_title,
data={CONF_HOST: self.discovered_host},
)
8 changes: 7 additions & 1 deletion homeassistant/components/hotspring/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,11 @@
"iot_class": "local_polling",
"loggers": ["hotspring"],
"quality_scale": "silver",
"requirements": ["python-hotspring==1.3.0"]
"requirements": ["python-hotspring==1.3.0"],
"zeroconf": [
{
"name": "watkins_spa*",
"type": "_ws._tcp.local."
}
]
}
4 changes: 2 additions & 2 deletions homeassistant/components/hotspring/quality_scale.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ rules:
# Gold
devices: done
diagnostics: todo
discovery-update-info: todo
discovery: todo
discovery-update-info: done
discovery: done
docs-data-update: done
docs-examples: done
docs-known-limitations: done
Expand Down
4 changes: 4 additions & 0 deletions homeassistant/components/hotspring/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
"host": "Hostname or IP address of your Hot Spring Home Network Adapter (HNA)."
},
"description": "Set up your Hot Spring Home Network Adapter (HNA) to integrate with Home Assistant."
},
"zeroconf_confirm": {
"description": "Do you want to add the Hot Spring spa named `{name}` to Home Assistant?",
"title": "Discovered Hot Spring spa"
}
}
},
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/openevse/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
"iot_class": "local_push",
"loggers": ["openevsehttp"],
"quality_scale": "silver",
"requirements": ["python-openevse-http==1.0.1"],
"requirements": ["python-openevse-http==1.5.0"],
"zeroconf": ["_openevse._tcp.local."]
}
2 changes: 1 addition & 1 deletion homeassistant/components/volvo/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
"iot_class": "cloud_polling",
"loggers": ["volvocarsapi"],
"quality_scale": "platinum",
"requirements": ["volvocarsapi==0.4.3"]
"requirements": ["volvocarsapi==0.4.4"]
}
6 changes: 6 additions & 0 deletions homeassistant/generated/zeroconf.py

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

Loading
Loading