mirror of
https://github.com/home-assistant/core.git
synced 2025-07-28 07:37:34 +00:00
Add diagnostics for bosch alam integration (#142165)
* add diagnostics to bosch_alarm * use snapshot
This commit is contained in:
parent
934e81db43
commit
7a9a4db8d7
73
homeassistant/components/bosch_alarm/diagnostics.py
Normal file
73
homeassistant/components/bosch_alarm/diagnostics.py
Normal file
@ -0,0 +1,73 @@
|
||||
"""Diagnostics for bosch alarm."""
|
||||
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.diagnostics import async_redact_data
|
||||
from homeassistant.const import CONF_PASSWORD
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from . import BoschAlarmConfigEntry
|
||||
from .const import CONF_INSTALLER_CODE, CONF_USER_CODE
|
||||
|
||||
TO_REDACT = [CONF_INSTALLER_CODE, CONF_USER_CODE, CONF_PASSWORD]
|
||||
|
||||
|
||||
async def async_get_config_entry_diagnostics(
|
||||
hass: HomeAssistant, entry: BoschAlarmConfigEntry
|
||||
) -> dict[str, Any]:
|
||||
"""Return diagnostics for a config entry."""
|
||||
|
||||
return {
|
||||
"entry_data": async_redact_data(entry.data, TO_REDACT),
|
||||
"data": {
|
||||
"model": entry.runtime_data.model,
|
||||
"serial_number": entry.runtime_data.serial_number,
|
||||
"protocol_version": entry.runtime_data.protocol_version,
|
||||
"firmware_version": entry.runtime_data.firmware_version,
|
||||
"areas": [
|
||||
{
|
||||
"id": area_id,
|
||||
"name": area.name,
|
||||
"all_ready": area.all_ready,
|
||||
"part_ready": area.part_ready,
|
||||
"faults": area.faults,
|
||||
"alarms": area.alarms,
|
||||
"disarmed": area.is_disarmed(),
|
||||
"arming": area.is_arming(),
|
||||
"pending": area.is_pending(),
|
||||
"part_armed": area.is_part_armed(),
|
||||
"all_armed": area.is_all_armed(),
|
||||
"armed": area.is_armed(),
|
||||
"triggered": area.is_triggered(),
|
||||
}
|
||||
for area_id, area in entry.runtime_data.areas.items()
|
||||
],
|
||||
"points": [
|
||||
{
|
||||
"id": point_id,
|
||||
"name": point.name,
|
||||
"open": point.is_open(),
|
||||
"normal": point.is_normal(),
|
||||
}
|
||||
for point_id, point in entry.runtime_data.points.items()
|
||||
],
|
||||
"doors": [
|
||||
{
|
||||
"id": door_id,
|
||||
"name": door.name,
|
||||
"open": door.is_open(),
|
||||
"locked": door.is_locked(),
|
||||
}
|
||||
for door_id, door in entry.runtime_data.doors.items()
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"id": output_id,
|
||||
"name": output.name,
|
||||
"active": output.is_active(),
|
||||
}
|
||||
for output_id, output in entry.runtime_data.outputs.items()
|
||||
],
|
||||
"history_events": entry.runtime_data.events,
|
||||
},
|
||||
}
|
@ -4,7 +4,7 @@ from collections.abc import Generator
|
||||
from typing import Any
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from bosch_alarm_mode2.panel import Area
|
||||
from bosch_alarm_mode2.panel import Area, Door, Output, Point
|
||||
from bosch_alarm_mode2.utils import Observable
|
||||
import pytest
|
||||
|
||||
@ -78,14 +78,65 @@ def mock_setup_entry() -> Generator[AsyncMock]:
|
||||
yield mock_setup_entry
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def points() -> Generator[dict[int, Point]]:
|
||||
"""Define a mocked door."""
|
||||
names = [
|
||||
"Window",
|
||||
"Door",
|
||||
"Motion Detector",
|
||||
"CO Detector",
|
||||
"Smoke Detector",
|
||||
"Glassbreak Sensor",
|
||||
"Bedroom",
|
||||
]
|
||||
points = {}
|
||||
for i, name in enumerate(names):
|
||||
mock = AsyncMock(spec=Point)
|
||||
mock.name = name
|
||||
mock.status_observer = AsyncMock(spec=Observable)
|
||||
mock.is_open.return_value = False
|
||||
mock.is_normal.return_value = True
|
||||
points[i] = mock
|
||||
return points
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def output() -> Generator[Output]:
|
||||
"""Define a mocked output."""
|
||||
mock = AsyncMock(spec=Output)
|
||||
mock.name = "Output A"
|
||||
mock.status_observer = AsyncMock(spec=Observable)
|
||||
mock.is_active.return_value = False
|
||||
return mock
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def door() -> Generator[Door]:
|
||||
"""Define a mocked door."""
|
||||
mock = AsyncMock(spec=Door)
|
||||
mock.name = "Main Door"
|
||||
mock.status_observer = AsyncMock(spec=Observable)
|
||||
mock.is_open.return_value = False
|
||||
mock.is_locked.return_value = True
|
||||
return mock
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def area() -> Generator[Area]:
|
||||
"""Define a mocked area."""
|
||||
mock = AsyncMock(spec=Area)
|
||||
mock.name = "Area1"
|
||||
mock.status_observer = AsyncMock(spec=Observable)
|
||||
mock.alarm_observer = AsyncMock(spec=Observable)
|
||||
mock.ready_observer = AsyncMock(spec=Observable)
|
||||
mock.alarms = []
|
||||
mock.faults = []
|
||||
mock.all_ready = True
|
||||
mock.part_ready = True
|
||||
mock.is_triggered.return_value = False
|
||||
mock.is_disarmed.return_value = True
|
||||
mock.is_armed.return_value = False
|
||||
mock.is_arming.return_value = False
|
||||
mock.is_pending.return_value = False
|
||||
mock.is_part_armed.return_value = False
|
||||
@ -95,7 +146,12 @@ def area() -> Generator[Area]:
|
||||
|
||||
@pytest.fixture
|
||||
def mock_panel(
|
||||
area: AsyncMock, model_name: str, serial_number: str | None
|
||||
area: AsyncMock,
|
||||
door: AsyncMock,
|
||||
output: AsyncMock,
|
||||
points: dict[int, AsyncMock],
|
||||
model_name: str,
|
||||
serial_number: str | None,
|
||||
) -> Generator[AsyncMock]:
|
||||
"""Define a fixture to set up Bosch Alarm."""
|
||||
with (
|
||||
@ -106,10 +162,18 @@ def mock_panel(
|
||||
):
|
||||
client = mock_panel.return_value
|
||||
client.areas = {1: area}
|
||||
client.doors = {1: door}
|
||||
client.outputs = {1: output}
|
||||
client.points = points
|
||||
client.model = model_name
|
||||
client.faults = []
|
||||
client.events = []
|
||||
client.firmware_version = "1.0.0"
|
||||
client.protocol_version = "1.0.0"
|
||||
client.serial_number = serial_number
|
||||
client.connection_status_observer = AsyncMock(spec=Observable)
|
||||
client.faults_observer = AsyncMock(spec=Observable)
|
||||
client.history_observer = AsyncMock(spec=Observable)
|
||||
yield client
|
||||
|
||||
|
||||
|
290
tests/components/bosch_alarm/snapshots/test_diagnostics.ambr
Normal file
290
tests/components/bosch_alarm/snapshots/test_diagnostics.ambr
Normal file
@ -0,0 +1,290 @@
|
||||
# serializer version: 1
|
||||
# name: test_diagnostics[amax_3000]
|
||||
dict({
|
||||
'data': dict({
|
||||
'areas': list([
|
||||
dict({
|
||||
'alarms': list([
|
||||
]),
|
||||
'all_armed': False,
|
||||
'all_ready': True,
|
||||
'armed': False,
|
||||
'arming': False,
|
||||
'disarmed': True,
|
||||
'faults': list([
|
||||
]),
|
||||
'id': 1,
|
||||
'name': 'Area1',
|
||||
'part_armed': False,
|
||||
'part_ready': True,
|
||||
'pending': False,
|
||||
'triggered': False,
|
||||
}),
|
||||
]),
|
||||
'doors': list([
|
||||
dict({
|
||||
'id': 1,
|
||||
'locked': True,
|
||||
'name': 'Main Door',
|
||||
'open': False,
|
||||
}),
|
||||
]),
|
||||
'firmware_version': '1.0.0',
|
||||
'history_events': list([
|
||||
]),
|
||||
'model': 'AMAX 3000',
|
||||
'outputs': list([
|
||||
dict({
|
||||
'active': False,
|
||||
'id': 1,
|
||||
'name': 'Output A',
|
||||
}),
|
||||
]),
|
||||
'points': list([
|
||||
dict({
|
||||
'id': 0,
|
||||
'name': 'Window',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 1,
|
||||
'name': 'Door',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 2,
|
||||
'name': 'Motion Detector',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 3,
|
||||
'name': 'CO Detector',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 4,
|
||||
'name': 'Smoke Detector',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 5,
|
||||
'name': 'Glassbreak Sensor',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 6,
|
||||
'name': 'Bedroom',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
]),
|
||||
'protocol_version': '1.0.0',
|
||||
'serial_number': None,
|
||||
}),
|
||||
'entry_data': dict({
|
||||
'host': '0.0.0.0',
|
||||
'installer_code': '**REDACTED**',
|
||||
'model': 'AMAX 3000',
|
||||
'password': '**REDACTED**',
|
||||
'port': 7700,
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
# name: test_diagnostics[b5512]
|
||||
dict({
|
||||
'data': dict({
|
||||
'areas': list([
|
||||
dict({
|
||||
'alarms': list([
|
||||
]),
|
||||
'all_armed': False,
|
||||
'all_ready': True,
|
||||
'armed': False,
|
||||
'arming': False,
|
||||
'disarmed': True,
|
||||
'faults': list([
|
||||
]),
|
||||
'id': 1,
|
||||
'name': 'Area1',
|
||||
'part_armed': False,
|
||||
'part_ready': True,
|
||||
'pending': False,
|
||||
'triggered': False,
|
||||
}),
|
||||
]),
|
||||
'doors': list([
|
||||
dict({
|
||||
'id': 1,
|
||||
'locked': True,
|
||||
'name': 'Main Door',
|
||||
'open': False,
|
||||
}),
|
||||
]),
|
||||
'firmware_version': '1.0.0',
|
||||
'history_events': list([
|
||||
]),
|
||||
'model': 'B5512 (US1B)',
|
||||
'outputs': list([
|
||||
dict({
|
||||
'active': False,
|
||||
'id': 1,
|
||||
'name': 'Output A',
|
||||
}),
|
||||
]),
|
||||
'points': list([
|
||||
dict({
|
||||
'id': 0,
|
||||
'name': 'Window',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 1,
|
||||
'name': 'Door',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 2,
|
||||
'name': 'Motion Detector',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 3,
|
||||
'name': 'CO Detector',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 4,
|
||||
'name': 'Smoke Detector',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 5,
|
||||
'name': 'Glassbreak Sensor',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 6,
|
||||
'name': 'Bedroom',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
]),
|
||||
'protocol_version': '1.0.0',
|
||||
'serial_number': None,
|
||||
}),
|
||||
'entry_data': dict({
|
||||
'host': '0.0.0.0',
|
||||
'model': 'B5512 (US1B)',
|
||||
'password': '**REDACTED**',
|
||||
'port': 7700,
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
# name: test_diagnostics[solution_3000]
|
||||
dict({
|
||||
'data': dict({
|
||||
'areas': list([
|
||||
dict({
|
||||
'alarms': list([
|
||||
]),
|
||||
'all_armed': False,
|
||||
'all_ready': True,
|
||||
'armed': False,
|
||||
'arming': False,
|
||||
'disarmed': True,
|
||||
'faults': list([
|
||||
]),
|
||||
'id': 1,
|
||||
'name': 'Area1',
|
||||
'part_armed': False,
|
||||
'part_ready': True,
|
||||
'pending': False,
|
||||
'triggered': False,
|
||||
}),
|
||||
]),
|
||||
'doors': list([
|
||||
dict({
|
||||
'id': 1,
|
||||
'locked': True,
|
||||
'name': 'Main Door',
|
||||
'open': False,
|
||||
}),
|
||||
]),
|
||||
'firmware_version': '1.0.0',
|
||||
'history_events': list([
|
||||
]),
|
||||
'model': 'Solution 3000',
|
||||
'outputs': list([
|
||||
dict({
|
||||
'active': False,
|
||||
'id': 1,
|
||||
'name': 'Output A',
|
||||
}),
|
||||
]),
|
||||
'points': list([
|
||||
dict({
|
||||
'id': 0,
|
||||
'name': 'Window',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 1,
|
||||
'name': 'Door',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 2,
|
||||
'name': 'Motion Detector',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 3,
|
||||
'name': 'CO Detector',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 4,
|
||||
'name': 'Smoke Detector',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 5,
|
||||
'name': 'Glassbreak Sensor',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 6,
|
||||
'name': 'Bedroom',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
]),
|
||||
'protocol_version': '1.0.0',
|
||||
'serial_number': '1234567890',
|
||||
}),
|
||||
'entry_data': dict({
|
||||
'host': '0.0.0.0',
|
||||
'model': 'Solution 3000',
|
||||
'port': 7700,
|
||||
'user_code': '**REDACTED**',
|
||||
}),
|
||||
})
|
||||
# ---
|
32
tests/components/bosch_alarm/test_diagnostics.py
Normal file
32
tests/components/bosch_alarm/test_diagnostics.py
Normal file
@ -0,0 +1,32 @@
|
||||
"""Test the Bosch Alarm diagnostics."""
|
||||
|
||||
from typing import Any
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from . import setup_integration
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.components.diagnostics import get_diagnostics_for_config_entry
|
||||
from tests.typing import ClientSessionGenerator
|
||||
|
||||
|
||||
async def test_diagnostics(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
mock_panel: AsyncMock,
|
||||
area: AsyncMock,
|
||||
model_name: str,
|
||||
serial_number: str,
|
||||
snapshot: SnapshotAssertion,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
config_flow_data: dict[str, Any],
|
||||
) -> None:
|
||||
"""Test generating diagnostics for bosch alarm."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
diag = await get_diagnostics_for_config_entry(hass, hass_client, mock_config_entry)
|
||||
assert diag == snapshot
|
Loading…
x
Reference in New Issue
Block a user