diff --git a/homeassistant/components/switchbot/diagnostics.py b/homeassistant/components/switchbot/diagnostics.py new file mode 100644 index 00000000000..71c913c6411 --- /dev/null +++ b/homeassistant/components/switchbot/diagnostics.py @@ -0,0 +1,30 @@ +"""Diagnostics support for switchbot integration.""" + +from __future__ import annotations + +from typing import Any + +from homeassistant.components import bluetooth +from homeassistant.components.diagnostics import async_redact_data +from homeassistant.core import HomeAssistant + +from .const import CONF_ENCRYPTION_KEY, CONF_KEY_ID +from .coordinator import SwitchbotConfigEntry + +TO_REDACT = [CONF_KEY_ID, CONF_ENCRYPTION_KEY] + + +async def async_get_config_entry_diagnostics( + hass: HomeAssistant, entry: SwitchbotConfigEntry +) -> dict[str, Any]: + """Return diagnostics for a config entry.""" + coordinator = entry.runtime_data + + service_info = bluetooth.async_last_service_info( + hass, coordinator.ble_device.address, connectable=coordinator.connectable + ) + + return { + "entry": async_redact_data(entry.as_dict(), TO_REDACT), + "service_info": service_info, + } diff --git a/tests/components/switchbot/snapshots/test_diagnostics.ambr b/tests/components/switchbot/snapshots/test_diagnostics.ambr new file mode 100644 index 00000000000..215a3c00aaa --- /dev/null +++ b/tests/components/switchbot/snapshots/test_diagnostics.ambr @@ -0,0 +1,81 @@ +# serializer version: 1 +# name: test_diagnostics + dict({ + 'entry': dict({ + 'data': dict({ + 'address': 'aa:bb:cc:dd:ee:ff', + 'encryption_key': '**REDACTED**', + 'key_id': '**REDACTED**', + 'name': 'test-name', + 'sensor_type': 'relay_switch_1pm', + }), + 'disabled_by': None, + 'discovery_keys': dict({ + }), + 'domain': 'switchbot', + 'minor_version': 1, + 'options': dict({ + 'retry_count': 3, + }), + 'pref_disable_new_entities': False, + 'pref_disable_polling': False, + 'source': 'user', + 'subentries': list([ + ]), + 'title': 'Mock Title', + 'unique_id': 'aabbccddeeaa', + 'version': 1, + }), + 'service_info': dict({ + 'address': 'AA:BB:CC:DD:EE:FF', + 'advertisement': list([ + 'W1080000', + dict({ + '2409': dict({ + '__type': "", + 'repr': "b'$X|\\x0866G\\x81\\x00\\x00\\x001\\x00\\x00\\x00\\x00'", + }), + }), + dict({ + '0000fd3d-0000-1000-8000-00805f9b34fb': dict({ + '__type': "", + 'repr': "b'<\\x00\\x00\\x00'", + }), + }), + list([ + 'cba20d00-224d-11e6-9fb8-0002a5d5c51b', + ]), + -127, + -60, + list([ + list([ + ]), + ]), + ]), + 'connectable': True, + 'device': dict({ + '__type': "", + 'repr': 'BLEDevice(AA:BB:CC:DD:EE:FF, W1080000)', + }), + 'manufacturer_data': dict({ + '2409': dict({ + '__type': "", + 'repr': "b'$X|\\x0866G\\x81\\x00\\x00\\x001\\x00\\x00\\x00\\x00'", + }), + }), + 'name': 'W1080000', + 'rssi': -60, + 'service_data': dict({ + '0000fd3d-0000-1000-8000-00805f9b34fb': dict({ + '__type': "", + 'repr': "b'<\\x00\\x00\\x00'", + }), + }), + 'service_uuids': list([ + 'cba20d00-224d-11e6-9fb8-0002a5d5c51b', + ]), + 'source': 'local', + 'tx_power': -127, + }), + }) +# --- diff --git a/tests/components/switchbot/test_diagnostics.py b/tests/components/switchbot/test_diagnostics.py new file mode 100644 index 00000000000..e5974459e09 --- /dev/null +++ b/tests/components/switchbot/test_diagnostics.py @@ -0,0 +1,63 @@ +"""Tests for the diagnostics data provided by the Switchbot integration.""" + +from unittest.mock import patch + +from syrupy import SnapshotAssertion +from syrupy.filters import props + +from homeassistant.components.switchbot.const import ( + CONF_ENCRYPTION_KEY, + CONF_KEY_ID, + CONF_RETRY_COUNT, + DEFAULT_RETRY_COUNT, + DOMAIN, +) +from homeassistant.config_entries import ConfigEntryState +from homeassistant.const import CONF_ADDRESS, CONF_NAME, CONF_SENSOR_TYPE +from homeassistant.core import HomeAssistant + +from . import WORELAY_SWITCH_1PM_SERVICE_INFO + +from tests.common import MockConfigEntry +from tests.components.bluetooth import inject_bluetooth_service_info +from tests.components.diagnostics import get_diagnostics_for_config_entry +from tests.typing import ClientSessionGenerator + + +async def test_diagnostics( + hass: HomeAssistant, + hass_client: ClientSessionGenerator, + snapshot: SnapshotAssertion, +) -> None: + """Test diagnostics for config entry.""" + + inject_bluetooth_service_info(hass, WORELAY_SWITCH_1PM_SERVICE_INFO) + + with patch( + "homeassistant.components.switchbot.switch.switchbot.SwitchbotRelaySwitch.update", + return_value=None, + ): + mock_config_entry = MockConfigEntry( + domain=DOMAIN, + data={ + CONF_ADDRESS: "aa:bb:cc:dd:ee:ff", + CONF_NAME: "test-name", + CONF_SENSOR_TYPE: "relay_switch_1pm", + CONF_KEY_ID: "ff", + CONF_ENCRYPTION_KEY: "ffffffffffffffffffffffffffffffff", + }, + unique_id="aabbccddeeaa", + options={CONF_RETRY_COUNT: DEFAULT_RETRY_COUNT}, + ) + mock_config_entry.add_to_hass(hass) + + await hass.config_entries.async_setup(mock_config_entry.entry_id) + await hass.async_block_till_done() + assert mock_config_entry.state is ConfigEntryState.LOADED + + result = await get_diagnostics_for_config_entry( + hass, hass_client, mock_config_entry + ) + assert result == snapshot( + exclude=props("created_at", "modified_at", "entry_id", "time") + )