mirror of
https://github.com/home-assistant/core.git
synced 2025-07-28 07:37:34 +00:00
Add binary sensors to bosch_alarm (#142147)
* Add binary sensors to bosch_alarm * make one device per sensor, remove device class guessing * fix tests * update tests * Apply suggested changes * add binary sensors * make fault sensors diagnostic * update tests * update binary sensors to use base entity * fix strings * fix icons * add state translations for area ready sensors * use constants in tests * apply changes from review * remove fault prefix, use default translation for battery low * update tests
This commit is contained in:
parent
460f02ede5
commit
dbdffbba23
@ -16,6 +16,7 @@ from .const import CONF_INSTALLER_CODE, CONF_USER_CODE, DOMAIN
|
|||||||
|
|
||||||
PLATFORMS: list[Platform] = [
|
PLATFORMS: list[Platform] = [
|
||||||
Platform.ALARM_CONTROL_PANEL,
|
Platform.ALARM_CONTROL_PANEL,
|
||||||
|
Platform.BINARY_SENSOR,
|
||||||
Platform.SENSOR,
|
Platform.SENSOR,
|
||||||
Platform.SWITCH,
|
Platform.SWITCH,
|
||||||
]
|
]
|
||||||
|
220
homeassistant/components/bosch_alarm/binary_sensor.py
Normal file
220
homeassistant/components/bosch_alarm/binary_sensor.py
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
"""Support for Bosch Alarm Panel binary sensors."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
from bosch_alarm_mode2 import Panel
|
||||||
|
from bosch_alarm_mode2.const import ALARM_PANEL_FAULTS
|
||||||
|
|
||||||
|
from homeassistant.components.binary_sensor import (
|
||||||
|
BinarySensorDeviceClass,
|
||||||
|
BinarySensorEntity,
|
||||||
|
BinarySensorEntityDescription,
|
||||||
|
)
|
||||||
|
from homeassistant.const import EntityCategory
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||||
|
|
||||||
|
from . import BoschAlarmConfigEntry
|
||||||
|
from .entity import BoschAlarmAreaEntity, BoschAlarmEntity, BoschAlarmPointEntity
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(kw_only=True, frozen=True)
|
||||||
|
class BoschAlarmFaultEntityDescription(BinarySensorEntityDescription):
|
||||||
|
"""Describes Bosch Alarm sensor entity."""
|
||||||
|
|
||||||
|
fault: int
|
||||||
|
|
||||||
|
|
||||||
|
FAULT_TYPES = [
|
||||||
|
BoschAlarmFaultEntityDescription(
|
||||||
|
key="panel_fault_battery_low",
|
||||||
|
entity_registry_enabled_default=True,
|
||||||
|
device_class=BinarySensorDeviceClass.BATTERY,
|
||||||
|
fault=ALARM_PANEL_FAULTS.BATTERY_LOW,
|
||||||
|
),
|
||||||
|
BoschAlarmFaultEntityDescription(
|
||||||
|
key="panel_fault_battery_mising",
|
||||||
|
translation_key="panel_fault_battery_mising",
|
||||||
|
entity_registry_enabled_default=True,
|
||||||
|
device_class=BinarySensorDeviceClass.PROBLEM,
|
||||||
|
fault=ALARM_PANEL_FAULTS.BATTERY_MISING,
|
||||||
|
),
|
||||||
|
BoschAlarmFaultEntityDescription(
|
||||||
|
key="panel_fault_ac_fail",
|
||||||
|
translation_key="panel_fault_ac_fail",
|
||||||
|
entity_registry_enabled_default=True,
|
||||||
|
device_class=BinarySensorDeviceClass.PROBLEM,
|
||||||
|
fault=ALARM_PANEL_FAULTS.AC_FAIL,
|
||||||
|
),
|
||||||
|
BoschAlarmFaultEntityDescription(
|
||||||
|
key="panel_fault_phone_line_failure",
|
||||||
|
translation_key="panel_fault_phone_line_failure",
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
device_class=BinarySensorDeviceClass.CONNECTIVITY,
|
||||||
|
fault=ALARM_PANEL_FAULTS.PHONE_LINE_FAILURE,
|
||||||
|
),
|
||||||
|
BoschAlarmFaultEntityDescription(
|
||||||
|
key="panel_fault_parameter_crc_fail_in_pif",
|
||||||
|
translation_key="panel_fault_parameter_crc_fail_in_pif",
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
device_class=BinarySensorDeviceClass.PROBLEM,
|
||||||
|
fault=ALARM_PANEL_FAULTS.PARAMETER_CRC_FAIL_IN_PIF,
|
||||||
|
),
|
||||||
|
BoschAlarmFaultEntityDescription(
|
||||||
|
key="panel_fault_communication_fail_since_rps_hang_up",
|
||||||
|
translation_key="panel_fault_communication_fail_since_rps_hang_up",
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
device_class=BinarySensorDeviceClass.PROBLEM,
|
||||||
|
fault=ALARM_PANEL_FAULTS.COMMUNICATION_FAIL_SINCE_RPS_HANG_UP,
|
||||||
|
),
|
||||||
|
BoschAlarmFaultEntityDescription(
|
||||||
|
key="panel_fault_sdi_fail_since_rps_hang_up",
|
||||||
|
translation_key="panel_fault_sdi_fail_since_rps_hang_up",
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
device_class=BinarySensorDeviceClass.PROBLEM,
|
||||||
|
fault=ALARM_PANEL_FAULTS.SDI_FAIL_SINCE_RPS_HANG_UP,
|
||||||
|
),
|
||||||
|
BoschAlarmFaultEntityDescription(
|
||||||
|
key="panel_fault_user_code_tamper_since_rps_hang_up",
|
||||||
|
translation_key="panel_fault_user_code_tamper_since_rps_hang_up",
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
device_class=BinarySensorDeviceClass.PROBLEM,
|
||||||
|
fault=ALARM_PANEL_FAULTS.USER_CODE_TAMPER_SINCE_RPS_HANG_UP,
|
||||||
|
),
|
||||||
|
BoschAlarmFaultEntityDescription(
|
||||||
|
key="panel_fault_fail_to_call_rps_since_rps_hang_up",
|
||||||
|
translation_key="panel_fault_fail_to_call_rps_since_rps_hang_up",
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
fault=ALARM_PANEL_FAULTS.FAIL_TO_CALL_RPS_SINCE_RPS_HANG_UP,
|
||||||
|
),
|
||||||
|
BoschAlarmFaultEntityDescription(
|
||||||
|
key="panel_fault_point_bus_fail_since_rps_hang_up",
|
||||||
|
translation_key="panel_fault_point_bus_fail_since_rps_hang_up",
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
device_class=BinarySensorDeviceClass.PROBLEM,
|
||||||
|
fault=ALARM_PANEL_FAULTS.POINT_BUS_FAIL_SINCE_RPS_HANG_UP,
|
||||||
|
),
|
||||||
|
BoschAlarmFaultEntityDescription(
|
||||||
|
key="panel_fault_log_overflow",
|
||||||
|
translation_key="panel_fault_log_overflow",
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
device_class=BinarySensorDeviceClass.PROBLEM,
|
||||||
|
fault=ALARM_PANEL_FAULTS.LOG_OVERFLOW,
|
||||||
|
),
|
||||||
|
BoschAlarmFaultEntityDescription(
|
||||||
|
key="panel_fault_log_threshold",
|
||||||
|
translation_key="panel_fault_log_threshold",
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
device_class=BinarySensorDeviceClass.PROBLEM,
|
||||||
|
fault=ALARM_PANEL_FAULTS.LOG_THRESHOLD,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: BoschAlarmConfigEntry,
|
||||||
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up binary sensors for alarm points and the connection status."""
|
||||||
|
panel = config_entry.runtime_data
|
||||||
|
|
||||||
|
entities: list[BinarySensorEntity] = [
|
||||||
|
PointSensor(panel, point_id, config_entry.unique_id or config_entry.entry_id)
|
||||||
|
for point_id in panel.points
|
||||||
|
]
|
||||||
|
|
||||||
|
entities.extend(
|
||||||
|
PanelFaultsSensor(
|
||||||
|
panel,
|
||||||
|
config_entry.unique_id or config_entry.entry_id,
|
||||||
|
fault_type,
|
||||||
|
)
|
||||||
|
for fault_type in FAULT_TYPES
|
||||||
|
)
|
||||||
|
|
||||||
|
entities.extend(
|
||||||
|
AreaReadyToArmSensor(
|
||||||
|
panel, area_id, config_entry.unique_id or 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"
|
||||||
|
)
|
||||||
|
for area_id in panel.areas
|
||||||
|
)
|
||||||
|
|
||||||
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
|
||||||
|
PARALLEL_UPDATES = 0
|
||||||
|
|
||||||
|
|
||||||
|
class PanelFaultsSensor(BoschAlarmEntity, BinarySensorEntity):
|
||||||
|
"""A binary sensor entity for each fault type in a bosch alarm panel."""
|
||||||
|
|
||||||
|
_attr_entity_category = EntityCategory.DIAGNOSTIC
|
||||||
|
entity_description: BoschAlarmFaultEntityDescription
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
panel: Panel,
|
||||||
|
unique_id: str,
|
||||||
|
entity_description: BoschAlarmFaultEntityDescription,
|
||||||
|
) -> None:
|
||||||
|
"""Set up a binary sensor entity for each fault type in a bosch alarm panel."""
|
||||||
|
super().__init__(panel, unique_id, True)
|
||||||
|
self.entity_description = entity_description
|
||||||
|
self._fault_type = entity_description.fault
|
||||||
|
self._attr_unique_id = f"{unique_id}_fault_{entity_description.key}"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self) -> bool:
|
||||||
|
"""Return if this fault has occurred."""
|
||||||
|
return self._fault_type in self.panel.panel_faults_ids
|
||||||
|
|
||||||
|
|
||||||
|
class AreaReadyToArmSensor(BoschAlarmAreaEntity, BinarySensorEntity):
|
||||||
|
"""A binary sensor entity showing if a panel is ready to arm."""
|
||||||
|
|
||||||
|
_attr_entity_category = EntityCategory.DIAGNOSTIC
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, panel: Panel, area_id: int, unique_id: str, arm_type: str
|
||||||
|
) -> None:
|
||||||
|
"""Set up a binary sensor entity for the arming status in a bosch alarm panel."""
|
||||||
|
super().__init__(panel, area_id, unique_id, False, False, True)
|
||||||
|
self.panel = panel
|
||||||
|
self._arm_type = arm_type
|
||||||
|
self._attr_translation_key = f"area_ready_to_arm_{arm_type}"
|
||||||
|
self._attr_unique_id = f"{self._area_unique_id}_ready_to_arm_{arm_type}"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self) -> bool:
|
||||||
|
"""Return if this panel is ready to arm."""
|
||||||
|
if self._arm_type == "away":
|
||||||
|
return self._area.all_ready
|
||||||
|
if self._arm_type == "home":
|
||||||
|
return self._area.all_ready or self._area.part_ready
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class PointSensor(BoschAlarmPointEntity, BinarySensorEntity):
|
||||||
|
"""A binary sensor entity for a point in a bosch alarm panel."""
|
||||||
|
|
||||||
|
_attr_name = None
|
||||||
|
|
||||||
|
def __init__(self, panel: Panel, point_id: int, unique_id: str) -> None:
|
||||||
|
"""Set up a binary sensor entity for a point in a bosch alarm panel."""
|
||||||
|
super().__init__(panel, point_id, unique_id)
|
||||||
|
self._attr_unique_id = self._point_unique_id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self) -> bool:
|
||||||
|
"""Return if this point sensor is on."""
|
||||||
|
return self._point.is_open()
|
@ -17,9 +17,13 @@ class BoschAlarmEntity(Entity):
|
|||||||
|
|
||||||
_attr_has_entity_name = True
|
_attr_has_entity_name = True
|
||||||
|
|
||||||
def __init__(self, panel: Panel, unique_id: str) -> None:
|
def __init__(
|
||||||
|
self, panel: Panel, unique_id: str, observe_faults: bool = False
|
||||||
|
) -> None:
|
||||||
"""Set up a entity for a bosch alarm panel."""
|
"""Set up a entity for a bosch alarm panel."""
|
||||||
self.panel = panel
|
self.panel = panel
|
||||||
|
self._observe_faults = observe_faults
|
||||||
|
self._attr_should_poll = False
|
||||||
self._attr_device_info = DeviceInfo(
|
self._attr_device_info = DeviceInfo(
|
||||||
identifiers={(DOMAIN, unique_id)},
|
identifiers={(DOMAIN, unique_id)},
|
||||||
name=f"Bosch {panel.model}",
|
name=f"Bosch {panel.model}",
|
||||||
@ -34,10 +38,14 @@ class BoschAlarmEntity(Entity):
|
|||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Observe state changes."""
|
"""Observe state changes."""
|
||||||
self.panel.connection_status_observer.attach(self.schedule_update_ha_state)
|
self.panel.connection_status_observer.attach(self.schedule_update_ha_state)
|
||||||
|
if self._observe_faults:
|
||||||
|
self.panel.faults_observer.attach(self.schedule_update_ha_state)
|
||||||
|
|
||||||
async def async_will_remove_from_hass(self) -> None:
|
async def async_will_remove_from_hass(self) -> None:
|
||||||
"""Stop observing state changes."""
|
"""Stop observing state changes."""
|
||||||
self.panel.connection_status_observer.detach(self.schedule_update_ha_state)
|
self.panel.connection_status_observer.detach(self.schedule_update_ha_state)
|
||||||
|
if self._observe_faults:
|
||||||
|
self.panel.faults_observer.attach(self.schedule_update_ha_state)
|
||||||
|
|
||||||
|
|
||||||
class BoschAlarmAreaEntity(BoschAlarmEntity):
|
class BoschAlarmAreaEntity(BoschAlarmEntity):
|
||||||
@ -88,6 +96,33 @@ class BoschAlarmAreaEntity(BoschAlarmEntity):
|
|||||||
self._area.status_observer.detach(self.schedule_update_ha_state)
|
self._area.status_observer.detach(self.schedule_update_ha_state)
|
||||||
|
|
||||||
|
|
||||||
|
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:
|
||||||
|
"""Set up a area related entity for a bosch alarm panel."""
|
||||||
|
super().__init__(panel, unique_id)
|
||||||
|
self._point_id = point_id
|
||||||
|
self._point_unique_id = f"{unique_id}_point_{point_id}"
|
||||||
|
self._point = panel.points[point_id]
|
||||||
|
self._attr_device_info = DeviceInfo(
|
||||||
|
identifiers={(DOMAIN, self._point_unique_id)},
|
||||||
|
name=self._point.name,
|
||||||
|
manufacturer="Bosch Security Systems",
|
||||||
|
via_device=(DOMAIN, unique_id),
|
||||||
|
)
|
||||||
|
|
||||||
|
async def async_added_to_hass(self) -> None:
|
||||||
|
"""Observe state changes."""
|
||||||
|
await super().async_added_to_hass()
|
||||||
|
self._point.status_observer.attach(self.schedule_update_ha_state)
|
||||||
|
|
||||||
|
async def async_will_remove_from_hass(self) -> None:
|
||||||
|
"""Stop observing state changes."""
|
||||||
|
await super().async_added_to_hass()
|
||||||
|
self._point.status_observer.detach(self.schedule_update_ha_state)
|
||||||
|
|
||||||
|
|
||||||
class BoschAlarmDoorEntity(BoschAlarmEntity):
|
class BoschAlarmDoorEntity(BoschAlarmEntity):
|
||||||
"""A base entity for area related entities within a bosch alarm panel."""
|
"""A base entity for area related entities within a bosch alarm panel."""
|
||||||
|
|
||||||
|
@ -24,6 +24,44 @@
|
|||||||
"on": "mdi:lock-open"
|
"on": "mdi:lock-open"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"binary_sensor": {
|
||||||
|
"panel_fault_parameter_crc_fail_in_pif": {
|
||||||
|
"default": "mdi:alert-circle"
|
||||||
|
},
|
||||||
|
"panel_fault_phone_line_failure": {
|
||||||
|
"default": "mdi:alert-circle"
|
||||||
|
},
|
||||||
|
"panel_fault_sdi_fail_since_rps_hang_up": {
|
||||||
|
"default": "mdi:alert-circle"
|
||||||
|
},
|
||||||
|
"panel_fault_user_code_tamper_since_rps_hang_up": {
|
||||||
|
"default": "mdi:alert-circle"
|
||||||
|
},
|
||||||
|
"panel_fault_fail_to_call_rps_since_rps_hang_up": {
|
||||||
|
"default": "mdi:alert-circle"
|
||||||
|
},
|
||||||
|
"panel_fault_point_bus_fail_since_rps_hang_up": {
|
||||||
|
"default": "mdi:alert-circle"
|
||||||
|
},
|
||||||
|
"panel_fault_log_overflow": {
|
||||||
|
"default": "mdi:alert-circle"
|
||||||
|
},
|
||||||
|
"panel_fault_log_threshold": {
|
||||||
|
"default": "mdi:alert-circle"
|
||||||
|
},
|
||||||
|
"area_ready_to_arm_away": {
|
||||||
|
"default": "mdi:shield",
|
||||||
|
"state": {
|
||||||
|
"on": "mdi:shield-lock"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"area_ready_to_arm_home": {
|
||||||
|
"default": "mdi:shield",
|
||||||
|
"state": {
|
||||||
|
"on": "mdi:shield-home"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,52 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"entity": {
|
"entity": {
|
||||||
|
"binary_sensor": {
|
||||||
|
"panel_fault_battery_mising": {
|
||||||
|
"name": "Battery missing"
|
||||||
|
},
|
||||||
|
"panel_fault_ac_fail": {
|
||||||
|
"name": "AC Failure"
|
||||||
|
},
|
||||||
|
"panel_fault_parameter_crc_fail_in_pif": {
|
||||||
|
"name": "CRC failure in panel configuration"
|
||||||
|
},
|
||||||
|
"panel_fault_phone_line_failure": {
|
||||||
|
"name": "Phone line failure"
|
||||||
|
},
|
||||||
|
"panel_fault_sdi_fail_since_rps_hang_up": {
|
||||||
|
"name": "SDI failure since RPS hang up"
|
||||||
|
},
|
||||||
|
"panel_fault_user_code_tamper_since_rps_hang_up": {
|
||||||
|
"name": "User code tamper since RPS hang up"
|
||||||
|
},
|
||||||
|
"panel_fault_fail_to_call_rps_since_rps_hang_up": {
|
||||||
|
"name": "Failure to call RPS since RPS hang up"
|
||||||
|
},
|
||||||
|
"panel_fault_point_bus_fail_since_rps_hang_up": {
|
||||||
|
"name": "Point bus failure since RPS hang up"
|
||||||
|
},
|
||||||
|
"panel_fault_log_overflow": {
|
||||||
|
"name": "Log overflow"
|
||||||
|
},
|
||||||
|
"panel_fault_log_threshold": {
|
||||||
|
"name": "Log threshold reached"
|
||||||
|
},
|
||||||
|
"area_ready_to_arm_away": {
|
||||||
|
"name": "Area ready to arm away",
|
||||||
|
"state": {
|
||||||
|
"on": "Ready",
|
||||||
|
"off": "Not ready"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"area_ready_to_arm_home": {
|
||||||
|
"name": "Area ready to arm home",
|
||||||
|
"state": {
|
||||||
|
"on": "Ready",
|
||||||
|
"off": "Not ready"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"switch": {
|
"switch": {
|
||||||
"secured": {
|
"secured": {
|
||||||
"name": "Secured"
|
"name": "Secured"
|
||||||
|
@ -171,6 +171,7 @@ def mock_panel(
|
|||||||
client.model = model_name
|
client.model = model_name
|
||||||
client.faults = []
|
client.faults = []
|
||||||
client.events = []
|
client.events = []
|
||||||
|
client.panel_faults_ids = []
|
||||||
client.firmware_version = "1.0.0"
|
client.firmware_version = "1.0.0"
|
||||||
client.protocol_version = "1.0.0"
|
client.protocol_version = "1.0.0"
|
||||||
client.serial_number = serial_number
|
client.serial_number = serial_number
|
||||||
|
2995
tests/components/bosch_alarm/snapshots/test_binary_sensor.ambr
Normal file
2995
tests/components/bosch_alarm/snapshots/test_binary_sensor.ambr
Normal file
File diff suppressed because it is too large
Load Diff
78
tests/components/bosch_alarm/test_binary_sensor.py
Normal file
78
tests/components/bosch_alarm/test_binary_sensor.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
"""Tests for Bosch Alarm component."""
|
||||||
|
|
||||||
|
from collections.abc import AsyncGenerator
|
||||||
|
from unittest.mock import AsyncMock, patch
|
||||||
|
|
||||||
|
from bosch_alarm_mode2.const import ALARM_PANEL_FAULTS
|
||||||
|
import pytest
|
||||||
|
from syrupy.assertion import SnapshotAssertion
|
||||||
|
|
||||||
|
from homeassistant.const import STATE_OFF, STATE_ON, Platform
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
|
||||||
|
from . import call_observable, setup_integration
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry, snapshot_platform
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
async def platforms() -> AsyncGenerator[None]:
|
||||||
|
"""Return the platforms to be loaded for this test."""
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.bosch_alarm.PLATFORMS", [Platform.BINARY_SENSOR]
|
||||||
|
):
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||||
|
async def test_binary_sensor(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entity_registry: er.EntityRegistry,
|
||||||
|
snapshot: SnapshotAssertion,
|
||||||
|
mock_panel: AsyncMock,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
) -> None:
|
||||||
|
"""Test the binary sensor state."""
|
||||||
|
await setup_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
|
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("model", ["b5512"])
|
||||||
|
async def test_panel_faults(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_panel: AsyncMock,
|
||||||
|
area: AsyncMock,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
) -> None:
|
||||||
|
"""Test that fault sensor state changes after inducing a fault."""
|
||||||
|
await setup_integration(hass, mock_config_entry)
|
||||||
|
entity_id = "binary_sensor.bosch_b5512_us1b_battery"
|
||||||
|
assert hass.states.get(entity_id).state == STATE_OFF
|
||||||
|
mock_panel.panel_faults_ids = [ALARM_PANEL_FAULTS.BATTERY_LOW]
|
||||||
|
await call_observable(hass, mock_panel.faults_observer)
|
||||||
|
assert hass.states.get(entity_id).state == STATE_ON
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("model", ["b5512"])
|
||||||
|
async def test_area_ready_to_arm(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_panel: AsyncMock,
|
||||||
|
area: AsyncMock,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
) -> None:
|
||||||
|
"""Test that fault sensor state changes after inducing a fault."""
|
||||||
|
await setup_integration(hass, mock_config_entry)
|
||||||
|
entity_id = "binary_sensor.area1_area_ready_to_arm_away"
|
||||||
|
entity_id_2 = "binary_sensor.area1_area_ready_to_arm_home"
|
||||||
|
assert hass.states.get(entity_id).state == STATE_ON
|
||||||
|
assert hass.states.get(entity_id_2).state == STATE_ON
|
||||||
|
area.all_ready = False
|
||||||
|
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_ON
|
||||||
|
area.part_ready = False
|
||||||
|
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
|
Loading…
x
Reference in New Issue
Block a user