Add RSSI sensor to HomeKit Controller (#78906)

This commit is contained in:
J. Nick Koston
2022-09-25 15:31:56 -10:00
committed by GitHub
parent c1bc26b413
commit 92612c9fe3
4 changed files with 133 additions and 17 deletions

View File

@@ -26,6 +26,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, State, callback
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.service_info.bluetooth import BluetoothServiceInfo
from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util
@@ -42,6 +43,19 @@ logger = logging.getLogger(__name__)
# Root device in test harness always has an accessory id of this
HUB_TEST_ACCESSORY_ID: Final[str] = "00:00:00:00:00:00:aid:1"
TEST_ACCESSORY_ADDRESS = "AA:BB:CC:DD:EE:FF"
TEST_DEVICE_SERVICE_INFO = BluetoothServiceInfo(
name="test_accessory",
address=TEST_ACCESSORY_ADDRESS,
rssi=-56,
manufacturer_data={},
service_uuids=["0000ec88-0000-1000-8000-00805f9b34fb"],
service_data={},
source="local",
)
@dataclass
class EntityTestInfo:
@@ -182,15 +196,17 @@ async def setup_platform(hass):
return await async_get_controller(hass)
async def setup_test_accessories(hass, accessories):
async def setup_test_accessories(hass, accessories, connection=None):
"""Load a fake homekit device based on captured JSON profile."""
fake_controller = await setup_platform(hass)
return await setup_test_accessories_with_controller(
hass, accessories, fake_controller
hass, accessories, fake_controller, connection
)
async def setup_test_accessories_with_controller(hass, accessories, fake_controller):
async def setup_test_accessories_with_controller(
hass, accessories, fake_controller, connection=None
):
"""Load a fake homekit device based on captured JSON profile."""
pairing_id = "00:00:00:00:00:00"
@@ -200,11 +216,16 @@ async def setup_test_accessories_with_controller(hass, accessories, fake_control
accessories_obj.add_accessory(accessory)
pairing = await fake_controller.add_paired_device(accessories_obj, pairing_id)
data = {"AccessoryPairingID": pairing_id}
if connection == "BLE":
data["Connection"] = "BLE"
data["AccessoryAddress"] = TEST_ACCESSORY_ADDRESS
config_entry = MockConfigEntry(
version=1,
domain="homekit_controller",
entry_id="TestData",
data={"AccessoryPairingID": pairing_id},
data=data,
title="test",
)
config_entry.add_to_hass(hass)
@@ -250,7 +271,9 @@ async def device_config_changed(hass, accessories):
await hass.async_block_till_done()
async def setup_test_component(hass, setup_accessory, capitalize=False, suffix=None):
async def setup_test_component(
hass, setup_accessory, capitalize=False, suffix=None, connection=None
):
"""Load a fake homekit accessory based on a homekit accessory model.
If capitalize is True, property names will be in upper case.
@@ -271,7 +294,7 @@ async def setup_test_component(hass, setup_accessory, capitalize=False, suffix=N
assert domain, "Cannot map test homekit services to Home Assistant domain"
config_entry, pairing = await setup_test_accessories(hass, [accessory])
config_entry, pairing = await setup_test_accessories(hass, [accessory], connection)
entity = "testdevice" if suffix is None else f"testdevice_{suffix}"
return Helper(hass, ".".join((domain, entity)), pairing, accessory, config_entry)

View File

@@ -1,8 +1,12 @@
"""Basic checks for HomeKit sensor."""
from unittest.mock import patch
from aiohomekit.model import Transport
from aiohomekit.model.characteristics import CharacteristicsTypes
from aiohomekit.model.characteristics.const import ThreadNodeCapabilities, ThreadStatus
from aiohomekit.model.services import ServicesTypes
from aiohomekit.protocol.statuscodes import HapStatusCode
from aiohomekit.testing import FakePairing
from homeassistant.components.homekit_controller.sensor import (
thread_node_capability_to_str,
@@ -10,7 +14,9 @@ from homeassistant.components.homekit_controller.sensor import (
)
from homeassistant.components.sensor import SensorDeviceClass, SensorStateClass
from .common import Helper, setup_test_component
from .common import TEST_DEVICE_SERVICE_INFO, Helper, setup_test_component
from tests.components.bluetooth import inject_bluetooth_service_info
def create_temperature_sensor_service(accessory):
@@ -349,3 +355,26 @@ def test_thread_status_to_str():
assert thread_status_to_str(ThreadStatus.JOINING) == "joining"
assert thread_status_to_str(ThreadStatus.DETACHED) == "detached"
assert thread_status_to_str(ThreadStatus.DISABLED) == "disabled"
async def test_rssi_sensor(
hass, utcnow, entity_registry_enabled_by_default, enable_bluetooth
):
"""Test an rssi sensor."""
inject_bluetooth_service_info(hass, TEST_DEVICE_SERVICE_INFO)
class FakeBLEPairing(FakePairing):
"""Fake BLE pairing."""
@property
def transport(self):
return Transport.BLE
with patch("aiohomekit.testing.FakePairing", FakeBLEPairing):
# Any accessory will do for this test, but we need at least
# one or the rssi sensor will not be created
await setup_test_component(
hass, create_battery_level_sensor, suffix="battery", connection="BLE"
)
assert hass.states.get("sensor.testdevice_signal_strength").state == "-56"