Add diagnostics to Comelit SimpleHome (#128794)
* Add diagnostics to Comelit SimpleHome * add test * add missing tests * introduce SnapshotAssertion * cleanup * exclude date based props
This commit is contained in:
parent
3e8f3cfb49
commit
e08e8641cb
4 changed files with 396 additions and 1 deletions
93
homeassistant/components/comelit/diagnostics.py
Normal file
93
homeassistant/components/comelit/diagnostics.py
Normal file
|
@ -0,0 +1,93 @@
|
|||
"""Diagnostics support for Comelit integration."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from aiocomelit import (
|
||||
ComelitSerialBridgeObject,
|
||||
ComelitVedoAreaObject,
|
||||
ComelitVedoZoneObject,
|
||||
)
|
||||
from aiocomelit.const import BRIDGE
|
||||
|
||||
from homeassistant.components.diagnostics import async_redact_data
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_PIN, CONF_TYPE
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from .const import DOMAIN
|
||||
from .coordinator import ComelitBaseCoordinator
|
||||
|
||||
TO_REDACT = {CONF_PIN}
|
||||
|
||||
|
||||
async def async_get_config_entry_diagnostics(
|
||||
hass: HomeAssistant, entry: ConfigEntry
|
||||
) -> dict[str, Any]:
|
||||
"""Return diagnostics for a config entry."""
|
||||
|
||||
coordinator: ComelitBaseCoordinator = hass.data[DOMAIN][entry.entry_id]
|
||||
|
||||
dev_list: list[dict[str, Any]] = []
|
||||
dev_type_list: list[dict[int, Any]] = []
|
||||
|
||||
for dev_type in coordinator.data:
|
||||
dev_type_list = []
|
||||
for sensor_data in coordinator.data[dev_type].values():
|
||||
if isinstance(sensor_data, ComelitSerialBridgeObject):
|
||||
dev_type_list.append(
|
||||
{
|
||||
sensor_data.index: {
|
||||
"name": sensor_data.name,
|
||||
"status": sensor_data.status,
|
||||
"human_status": sensor_data.human_status,
|
||||
"protected": sensor_data.protected,
|
||||
"val": sensor_data.val,
|
||||
"zone": sensor_data.zone,
|
||||
"power": sensor_data.power,
|
||||
"power_unit": sensor_data.power_unit,
|
||||
}
|
||||
}
|
||||
)
|
||||
if isinstance(sensor_data, ComelitVedoAreaObject):
|
||||
dev_type_list.append(
|
||||
{
|
||||
sensor_data.index: {
|
||||
"name": sensor_data.name,
|
||||
"human_status": sensor_data.human_status.value,
|
||||
"p1": sensor_data.p1,
|
||||
"p2": sensor_data.p2,
|
||||
"ready": sensor_data.ready,
|
||||
"armed": sensor_data.armed,
|
||||
"alarm": sensor_data.alarm,
|
||||
"alarm_memory": sensor_data.alarm_memory,
|
||||
"sabotage": sensor_data.sabotage,
|
||||
"anomaly": sensor_data.anomaly,
|
||||
"in_time": sensor_data.in_time,
|
||||
"out_time": sensor_data.out_time,
|
||||
}
|
||||
}
|
||||
)
|
||||
if isinstance(sensor_data, ComelitVedoZoneObject):
|
||||
dev_type_list.append(
|
||||
{
|
||||
sensor_data.index: {
|
||||
"name": sensor_data.name,
|
||||
"human_status": sensor_data.human_status.value,
|
||||
"status": sensor_data.status,
|
||||
"status_api": sensor_data.status_api,
|
||||
}
|
||||
}
|
||||
)
|
||||
dev_list.append({dev_type: dev_type_list})
|
||||
|
||||
return {
|
||||
"entry": async_redact_data(entry.as_dict(), TO_REDACT),
|
||||
"type": entry.data.get(CONF_TYPE, BRIDGE),
|
||||
"device_info": {
|
||||
"last_update success": coordinator.last_update_success,
|
||||
"last_exception": repr(coordinator.last_exception),
|
||||
"devices": dev_list,
|
||||
},
|
||||
}
|
|
@ -1,6 +1,19 @@
|
|||
"""Common stuff for Comelit SimpleHome tests."""
|
||||
|
||||
from aiocomelit.const import VEDO
|
||||
from aiocomelit import ComelitVedoAreaObject, ComelitVedoZoneObject
|
||||
from aiocomelit.api import ComelitSerialBridgeObject
|
||||
from aiocomelit.const import (
|
||||
CLIMATE,
|
||||
COVER,
|
||||
IRRIGATION,
|
||||
LIGHT,
|
||||
OTHER,
|
||||
SCENARIO,
|
||||
VEDO,
|
||||
WATT,
|
||||
AlarmAreaState,
|
||||
AlarmZoneState,
|
||||
)
|
||||
|
||||
from homeassistant.components.comelit.const import DOMAIN
|
||||
from homeassistant.const import CONF_DEVICES, CONF_HOST, CONF_PIN, CONF_PORT, CONF_TYPE
|
||||
|
@ -27,3 +40,67 @@ MOCK_USER_BRIDGE_DATA = MOCK_CONFIG[DOMAIN][CONF_DEVICES][0]
|
|||
MOCK_USER_VEDO_DATA = MOCK_CONFIG[DOMAIN][CONF_DEVICES][1]
|
||||
|
||||
FAKE_PIN = 5678
|
||||
|
||||
BRIDGE_DEVICE_QUERY = {
|
||||
CLIMATE: {},
|
||||
COVER: {
|
||||
0: ComelitSerialBridgeObject(
|
||||
index=0,
|
||||
name="Cover0",
|
||||
status=0,
|
||||
human_status="closed",
|
||||
type="cover",
|
||||
val=0,
|
||||
protected=0,
|
||||
zone="Open space",
|
||||
power=0.0,
|
||||
power_unit=WATT,
|
||||
)
|
||||
},
|
||||
LIGHT: {
|
||||
0: ComelitSerialBridgeObject(
|
||||
index=0,
|
||||
name="Light0",
|
||||
status=0,
|
||||
human_status="off",
|
||||
type="light",
|
||||
val=0,
|
||||
protected=0,
|
||||
zone="Bathroom",
|
||||
power=0.0,
|
||||
power_unit=WATT,
|
||||
)
|
||||
},
|
||||
OTHER: {},
|
||||
IRRIGATION: {},
|
||||
SCENARIO: {},
|
||||
}
|
||||
|
||||
VEDO_DEVICE_QUERY = {
|
||||
"aree": {
|
||||
0: ComelitVedoAreaObject(
|
||||
index=0,
|
||||
name="Area0",
|
||||
p1=True,
|
||||
p2=False,
|
||||
ready=False,
|
||||
armed=False,
|
||||
alarm=False,
|
||||
alarm_memory=False,
|
||||
sabotage=False,
|
||||
anomaly=False,
|
||||
in_time=False,
|
||||
out_time=False,
|
||||
human_status=AlarmAreaState.UNKNOWN,
|
||||
)
|
||||
},
|
||||
"zone": {
|
||||
0: ComelitVedoZoneObject(
|
||||
index=0,
|
||||
name="Zone0",
|
||||
status_api="0x000",
|
||||
status=0,
|
||||
human_status=AlarmZoneState.REST,
|
||||
)
|
||||
},
|
||||
}
|
||||
|
|
144
tests/components/comelit/snapshots/test_diagnostics.ambr
Normal file
144
tests/components/comelit/snapshots/test_diagnostics.ambr
Normal file
|
@ -0,0 +1,144 @@
|
|||
# serializer version: 1
|
||||
# name: test_entry_diagnostics_bridge
|
||||
dict({
|
||||
'device_info': dict({
|
||||
'devices': list([
|
||||
dict({
|
||||
'clima': list([
|
||||
]),
|
||||
}),
|
||||
dict({
|
||||
'shutter': list([
|
||||
dict({
|
||||
'0': dict({
|
||||
'human_status': 'closed',
|
||||
'name': 'Cover0',
|
||||
'power': 0.0,
|
||||
'power_unit': 'W',
|
||||
'protected': 0,
|
||||
'status': 0,
|
||||
'val': 0,
|
||||
'zone': 'Open space',
|
||||
}),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
dict({
|
||||
'light': list([
|
||||
dict({
|
||||
'0': dict({
|
||||
'human_status': 'off',
|
||||
'name': 'Light0',
|
||||
'power': 0.0,
|
||||
'power_unit': 'W',
|
||||
'protected': 0,
|
||||
'status': 0,
|
||||
'val': 0,
|
||||
'zone': 'Bathroom',
|
||||
}),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
dict({
|
||||
'other': list([
|
||||
]),
|
||||
}),
|
||||
dict({
|
||||
'irrigation': list([
|
||||
]),
|
||||
}),
|
||||
dict({
|
||||
'scenario': list([
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
'last_exception': 'None',
|
||||
'last_update success': True,
|
||||
}),
|
||||
'entry': dict({
|
||||
'data': dict({
|
||||
'host': 'fake_host',
|
||||
'pin': '**REDACTED**',
|
||||
'port': 80,
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'discovery_keys': dict({
|
||||
}),
|
||||
'domain': 'comelit',
|
||||
'minor_version': 1,
|
||||
'options': dict({
|
||||
}),
|
||||
'pref_disable_new_entities': False,
|
||||
'pref_disable_polling': False,
|
||||
'source': 'user',
|
||||
'title': 'Mock Title',
|
||||
'unique_id': None,
|
||||
'version': 1,
|
||||
}),
|
||||
'type': 'Serial bridge',
|
||||
})
|
||||
# ---
|
||||
# name: test_entry_diagnostics_vedo
|
||||
dict({
|
||||
'device_info': dict({
|
||||
'devices': list([
|
||||
dict({
|
||||
'aree': list([
|
||||
dict({
|
||||
'0': dict({
|
||||
'alarm': False,
|
||||
'alarm_memory': False,
|
||||
'anomaly': False,
|
||||
'armed': False,
|
||||
'human_status': 'unknown',
|
||||
'in_time': False,
|
||||
'name': 'Area0',
|
||||
'out_time': False,
|
||||
'p1': True,
|
||||
'p2': False,
|
||||
'ready': False,
|
||||
'sabotage': False,
|
||||
}),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
dict({
|
||||
'zone': list([
|
||||
dict({
|
||||
'0': dict({
|
||||
'human_status': 'rest',
|
||||
'name': 'Zone0',
|
||||
'status': 0,
|
||||
'status_api': '0x000',
|
||||
}),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
'last_exception': 'None',
|
||||
'last_update success': True,
|
||||
}),
|
||||
'entry': dict({
|
||||
'data': dict({
|
||||
'host': 'fake_vedo_host',
|
||||
'pin': '**REDACTED**',
|
||||
'port': 8080,
|
||||
'type': 'Vedo system',
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'discovery_keys': dict({
|
||||
}),
|
||||
'domain': 'comelit',
|
||||
'minor_version': 1,
|
||||
'options': dict({
|
||||
}),
|
||||
'pref_disable_new_entities': False,
|
||||
'pref_disable_polling': False,
|
||||
'source': 'user',
|
||||
'title': 'Mock Title',
|
||||
'unique_id': None,
|
||||
'version': 1,
|
||||
}),
|
||||
'type': 'Vedo system',
|
||||
})
|
||||
# ---
|
81
tests/components/comelit/test_diagnostics.py
Normal file
81
tests/components/comelit/test_diagnostics.py
Normal file
|
@ -0,0 +1,81 @@
|
|||
"""Tests for Comelit Simplehome diagnostics platform."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from syrupy import SnapshotAssertion
|
||||
from syrupy.filters import props
|
||||
|
||||
from homeassistant.components.comelit.const import DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from .const import (
|
||||
BRIDGE_DEVICE_QUERY,
|
||||
MOCK_USER_BRIDGE_DATA,
|
||||
MOCK_USER_VEDO_DATA,
|
||||
VEDO_DEVICE_QUERY,
|
||||
)
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.components.diagnostics import get_diagnostics_for_config_entry
|
||||
from tests.typing import ClientSessionGenerator
|
||||
|
||||
|
||||
async def test_entry_diagnostics_bridge(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test Bridge config entry diagnostics."""
|
||||
entry = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_BRIDGE_DATA)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
with (
|
||||
patch("aiocomelit.api.ComeliteSerialBridgeApi.login"),
|
||||
patch(
|
||||
"aiocomelit.api.ComeliteSerialBridgeApi.get_all_devices",
|
||||
return_value=BRIDGE_DEVICE_QUERY,
|
||||
),
|
||||
):
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state == ConfigEntryState.LOADED
|
||||
assert await get_diagnostics_for_config_entry(hass, hass_client, entry) == snapshot(
|
||||
exclude=props(
|
||||
"entry_id",
|
||||
"created_at",
|
||||
"modified_at",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
async def test_entry_diagnostics_vedo(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test Vedo System config entry diagnostics."""
|
||||
entry = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_VEDO_DATA)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
with (
|
||||
patch("aiocomelit.api.ComelitVedoApi.login"),
|
||||
patch(
|
||||
"aiocomelit.api.ComelitVedoApi.get_all_areas_and_zones",
|
||||
return_value=VEDO_DEVICE_QUERY,
|
||||
),
|
||||
):
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state == ConfigEntryState.LOADED
|
||||
assert await get_diagnostics_for_config_entry(hass, hass_client, entry) == snapshot(
|
||||
exclude=props(
|
||||
"entry_id",
|
||||
"created_at",
|
||||
"modified_at",
|
||||
)
|
||||
)
|
Loading…
Add table
Reference in a new issue