mirror of
https://github.com/home-assistant/core.git
synced 2026-08-24 02:24:51 -05:00
Adapt bosch_alarm to set via_device_id in DeviceInfo (#177709)
Co-authored-by: Markus Tuominen <3738613+Markus98@users.noreply.github.com>
This commit is contained in:
co-authored by
Markus Tuominen
parent
132e0bf011
commit
62fa51cc52
@@ -26,9 +26,11 @@ async def async_setup_entry(
|
||||
|
||||
async_add_entities(
|
||||
AreaAlarmControlPanel(
|
||||
hass,
|
||||
panel,
|
||||
area_id,
|
||||
config_entry.unique_id or config_entry.entry_id,
|
||||
config_entry.entry_id,
|
||||
)
|
||||
for area_id in panel.areas
|
||||
)
|
||||
@@ -48,9 +50,18 @@ class AreaAlarmControlPanel(BoschAlarmAreaEntity, AlarmControlPanelEntity):
|
||||
_attr_code_arm_required = False
|
||||
_attr_name = None
|
||||
|
||||
def __init__(self, panel: Panel, area_id: int, unique_id: str) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
panel: Panel,
|
||||
area_id: int,
|
||||
unique_id: str,
|
||||
config_entry_id: str,
|
||||
) -> None:
|
||||
"""Initialise a Bosch Alarm control panel entity."""
|
||||
super().__init__(panel, area_id, unique_id, True, False, True)
|
||||
super().__init__(
|
||||
hass, panel, area_id, unique_id, config_entry_id, True, False, True
|
||||
)
|
||||
self._attr_unique_id = self._area_unique_id
|
||||
|
||||
@property
|
||||
|
||||
@@ -116,16 +116,17 @@ async def async_setup_entry(
|
||||
) -> None:
|
||||
"""Set up binary sensors for alarm points and the connection status."""
|
||||
panel = config_entry.runtime_data
|
||||
unique_id = config_entry.unique_id or config_entry.entry_id
|
||||
|
||||
entities: list[BinarySensorEntity] = [
|
||||
PointSensor(panel, point_id, config_entry.unique_id or config_entry.entry_id)
|
||||
PointSensor(hass, panel, point_id, unique_id, config_entry.entry_id)
|
||||
for point_id in panel.points
|
||||
]
|
||||
|
||||
entities.extend(
|
||||
PanelFaultsSensor(
|
||||
panel,
|
||||
config_entry.unique_id or config_entry.entry_id,
|
||||
unique_id,
|
||||
fault_type,
|
||||
)
|
||||
for fault_type in FAULT_TYPES
|
||||
@@ -133,14 +134,14 @@ async def async_setup_entry(
|
||||
|
||||
entities.extend(
|
||||
AreaReadyToArmSensor(
|
||||
panel, area_id, config_entry.unique_id or config_entry.entry_id, "away"
|
||||
hass, panel, area_id, unique_id, config_entry.entry_id, "away"
|
||||
)
|
||||
for area_id in panel.areas
|
||||
)
|
||||
|
||||
entities.extend(
|
||||
AreaReadyToArmSensor(
|
||||
panel, area_id, config_entry.unique_id or config_entry.entry_id, "home"
|
||||
hass, panel, area_id, unique_id, config_entry.entry_id, "home"
|
||||
)
|
||||
for area_id in panel.areas
|
||||
)
|
||||
@@ -182,10 +183,18 @@ class AreaReadyToArmSensor(BoschAlarmAreaEntity, BinarySensorEntity):
|
||||
_attr_entity_category = EntityCategory.DIAGNOSTIC
|
||||
|
||||
def __init__(
|
||||
self, panel: Panel, area_id: int, unique_id: str, arm_type: str
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
panel: Panel,
|
||||
area_id: int,
|
||||
unique_id: str,
|
||||
config_entry_id: str,
|
||||
arm_type: str,
|
||||
) -> None:
|
||||
"""Set up a binary sensor for arming status in a bosch panel."""
|
||||
super().__init__(panel, area_id, unique_id, False, False, True)
|
||||
super().__init__(
|
||||
hass, panel, area_id, unique_id, config_entry_id, False, False, True
|
||||
)
|
||||
self.panel = panel
|
||||
self._arm_type = arm_type
|
||||
self._attr_translation_key = f"area_ready_to_arm_{arm_type}"
|
||||
@@ -207,9 +216,16 @@ class PointSensor(BoschAlarmPointEntity, BinarySensorEntity):
|
||||
|
||||
_attr_name = None
|
||||
|
||||
def __init__(self, panel: Panel, point_id: int, unique_id: str) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
panel: Panel,
|
||||
point_id: int,
|
||||
unique_id: str,
|
||||
config_entry_id: str,
|
||||
) -> None:
|
||||
"""Set up a binary sensor entity for a point in a bosch alarm panel."""
|
||||
super().__init__(panel, point_id, unique_id)
|
||||
super().__init__(hass, panel, point_id, unique_id, config_entry_id)
|
||||
self._attr_unique_id = self._point_unique_id
|
||||
|
||||
@property
|
||||
|
||||
@@ -5,6 +5,8 @@ from typing import override
|
||||
from bosch_alarm_mode2 import Panel
|
||||
|
||||
from homeassistant.components.sensor import Entity
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
|
||||
from .const import DOMAIN
|
||||
@@ -56,9 +58,11 @@ class BoschAlarmAreaEntity(BoschAlarmEntity):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
panel: Panel,
|
||||
area_id: int,
|
||||
unique_id: str,
|
||||
config_entry_id: str,
|
||||
observe_alarms: bool,
|
||||
observe_ready: bool,
|
||||
observe_status: bool,
|
||||
@@ -75,7 +79,9 @@ class BoschAlarmAreaEntity(BoschAlarmEntity):
|
||||
identifiers={(DOMAIN, self._area_unique_id)},
|
||||
name=self._area.name,
|
||||
manufacturer="Bosch Security Systems",
|
||||
via_device=(DOMAIN, unique_id),
|
||||
via_device_id=dr.async_get_device_id_by_identifier(
|
||||
hass, (DOMAIN, unique_id), config_entry_id=config_entry_id
|
||||
),
|
||||
)
|
||||
|
||||
@override
|
||||
@@ -104,7 +110,14 @@ class BoschAlarmAreaEntity(BoschAlarmEntity):
|
||||
class BoschAlarmPointEntity(BoschAlarmEntity):
|
||||
"""A base entity for point related entities within a bosch alarm panel."""
|
||||
|
||||
def __init__(self, panel: Panel, point_id: int, unique_id: str) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
panel: Panel,
|
||||
point_id: int,
|
||||
unique_id: str,
|
||||
config_entry_id: str,
|
||||
) -> None:
|
||||
"""Set up a area related entity for a bosch alarm panel."""
|
||||
super().__init__(panel, unique_id)
|
||||
self._point_id = point_id
|
||||
@@ -114,7 +127,9 @@ class BoschAlarmPointEntity(BoschAlarmEntity):
|
||||
identifiers={(DOMAIN, self._point_unique_id)},
|
||||
name=self._point.name,
|
||||
manufacturer="Bosch Security Systems",
|
||||
via_device=(DOMAIN, unique_id),
|
||||
via_device_id=dr.async_get_device_id_by_identifier(
|
||||
hass, (DOMAIN, unique_id), config_entry_id=config_entry_id
|
||||
),
|
||||
)
|
||||
|
||||
@override
|
||||
@@ -133,7 +148,14 @@ class BoschAlarmPointEntity(BoschAlarmEntity):
|
||||
class BoschAlarmDoorEntity(BoschAlarmEntity):
|
||||
"""A base entity for area related entities within a bosch alarm panel."""
|
||||
|
||||
def __init__(self, panel: Panel, door_id: int, unique_id: str) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
panel: Panel,
|
||||
door_id: int,
|
||||
unique_id: str,
|
||||
config_entry_id: str,
|
||||
) -> None:
|
||||
"""Set up a area related entity for a bosch alarm panel."""
|
||||
super().__init__(panel, unique_id)
|
||||
self._door_id = door_id
|
||||
@@ -143,7 +165,9 @@ class BoschAlarmDoorEntity(BoschAlarmEntity):
|
||||
identifiers={(DOMAIN, self._door_unique_id)},
|
||||
name=self._door.name,
|
||||
manufacturer="Bosch Security Systems",
|
||||
via_device=(DOMAIN, unique_id),
|
||||
via_device_id=dr.async_get_device_id_by_identifier(
|
||||
hass, (DOMAIN, unique_id), config_entry_id=config_entry_id
|
||||
),
|
||||
)
|
||||
|
||||
@override
|
||||
@@ -162,7 +186,14 @@ class BoschAlarmDoorEntity(BoschAlarmEntity):
|
||||
class BoschAlarmOutputEntity(BoschAlarmEntity):
|
||||
"""A base entity for area related entities within a bosch alarm panel."""
|
||||
|
||||
def __init__(self, panel: Panel, output_id: int, unique_id: str) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
panel: Panel,
|
||||
output_id: int,
|
||||
unique_id: str,
|
||||
config_entry_id: str,
|
||||
) -> None:
|
||||
"""Set up a output related entity for a bosch alarm panel."""
|
||||
super().__init__(panel, unique_id)
|
||||
self._output_id = output_id
|
||||
@@ -172,7 +203,9 @@ class BoschAlarmOutputEntity(BoschAlarmEntity):
|
||||
identifiers={(DOMAIN, self._output_unique_id)},
|
||||
name=self._output.name,
|
||||
manufacturer="Bosch Security Systems",
|
||||
via_device=(DOMAIN, unique_id),
|
||||
via_device_id=dr.async_get_device_id_by_identifier(
|
||||
hass, (DOMAIN, unique_id), config_entry_id=config_entry_id
|
||||
),
|
||||
)
|
||||
|
||||
@override
|
||||
|
||||
@@ -82,7 +82,9 @@ async def async_setup_entry(
|
||||
unique_id = config_entry.unique_id or config_entry.entry_id
|
||||
|
||||
async_add_entities(
|
||||
BoschAreaSensor(panel, area_id, unique_id, template)
|
||||
BoschAreaSensor(
|
||||
hass, panel, area_id, unique_id, config_entry.entry_id, template
|
||||
)
|
||||
for area_id in panel.areas
|
||||
for template in SENSOR_TYPES
|
||||
)
|
||||
@@ -98,16 +100,20 @@ class BoschAreaSensor(BoschAlarmAreaEntity, SensorEntity):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
panel: Panel,
|
||||
area_id: int,
|
||||
unique_id: str,
|
||||
config_entry_id: str,
|
||||
entity_description: BoschAlarmSensorEntityDescription,
|
||||
) -> None:
|
||||
"""Set up an area sensor entity for a bosch alarm panel."""
|
||||
super().__init__(
|
||||
hass,
|
||||
panel,
|
||||
area_id,
|
||||
unique_id,
|
||||
config_entry_id,
|
||||
entity_description.observe_alarms,
|
||||
entity_description.observe_ready,
|
||||
entity_description.observe_status,
|
||||
|
||||
@@ -59,18 +59,19 @@ async def async_setup_entry(
|
||||
"""Set up switch entities for outputs."""
|
||||
|
||||
panel = config_entry.runtime_data
|
||||
unique_id = config_entry.unique_id or config_entry.entry_id
|
||||
entities: list[SwitchEntity] = [
|
||||
PanelOutputEntity(
|
||||
panel, output_id, config_entry.unique_id or config_entry.entry_id
|
||||
)
|
||||
PanelOutputEntity(hass, panel, output_id, unique_id, config_entry.entry_id)
|
||||
for output_id in panel.outputs
|
||||
]
|
||||
|
||||
entities.extend(
|
||||
PanelDoorEntity(
|
||||
hass,
|
||||
panel,
|
||||
door_id,
|
||||
config_entry.unique_id or config_entry.entry_id,
|
||||
unique_id,
|
||||
config_entry.entry_id,
|
||||
entity_description,
|
||||
)
|
||||
for door_id in panel.doors
|
||||
@@ -90,13 +91,15 @@ class PanelDoorEntity(BoschAlarmDoorEntity, SwitchEntity):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
panel: Panel,
|
||||
door_id: int,
|
||||
unique_id: str,
|
||||
config_entry_id: str,
|
||||
entity_description: BoschAlarmSwitchEntityDescription,
|
||||
) -> None:
|
||||
"""Set up a switch entity for a door on a bosch alarm panel."""
|
||||
super().__init__(panel, door_id, unique_id)
|
||||
super().__init__(hass, panel, door_id, unique_id, config_entry_id)
|
||||
self.entity_description = entity_description
|
||||
self._attr_unique_id = f"{self._door_unique_id}_{entity_description.key}"
|
||||
|
||||
@@ -134,9 +137,16 @@ class PanelOutputEntity(BoschAlarmOutputEntity, SwitchEntity):
|
||||
|
||||
_attr_name = None
|
||||
|
||||
def __init__(self, panel: Panel, output_id: int, unique_id: str) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
panel: Panel,
|
||||
output_id: int,
|
||||
unique_id: str,
|
||||
config_entry_id: str,
|
||||
) -> None:
|
||||
"""Set up an output entity for a bosch alarm panel."""
|
||||
super().__init__(panel, output_id, unique_id)
|
||||
super().__init__(hass, panel, output_id, unique_id, config_entry_id)
|
||||
self._attr_unique_id = self._output_unique_id
|
||||
|
||||
@property
|
||||
|
||||
@@ -7,9 +7,10 @@ from bosch_alarm_mode2.const import ALARM_PANEL_FAULTS
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.bosch_alarm.const import DOMAIN
|
||||
from homeassistant.const import STATE_OFF, STATE_ON, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
|
||||
from . import call_observable, setup_integration
|
||||
|
||||
@@ -76,3 +77,30 @@ async def test_area_ready_to_arm(
|
||||
await call_observable(hass, area.status_observer)
|
||||
assert hass.states.get(entity_id).state == STATE_OFF
|
||||
assert hass.states.get(entity_id_2).state == STATE_OFF
|
||||
|
||||
|
||||
@pytest.mark.parametrize("model", ["b5512"])
|
||||
@pytest.mark.usefixtures("mock_panel")
|
||||
async def test_point_via_device_id(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test that a point's device links to the panel device via via_device_id."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
entity_entry = entity_registry.async_get("binary_sensor.window")
|
||||
assert entity_entry
|
||||
assert entity_entry.device_id
|
||||
|
||||
point_device = device_registry.async_get(entity_entry.device_id)
|
||||
assert point_device
|
||||
|
||||
panel_device = device_registry.async_get_device_by_identifier(
|
||||
(DOMAIN, mock_config_entry.unique_id),
|
||||
mock_config_entry.entry_id,
|
||||
)
|
||||
assert panel_device
|
||||
|
||||
assert point_device.via_device_id == panel_device.id
|
||||
|
||||
Reference in New Issue
Block a user