Handle battery services that only report low battery in HomeKit Controller (#79072)

This commit is contained in:
J. Nick Koston 2022-09-25 12:08:28 -10:00 committed by GitHub
parent b70027aec1
commit 917cf674de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 485 additions and 5 deletions

View File

@ -10,9 +10,11 @@ from homeassistant.components.binary_sensor import (
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import KNOWN_DEVICES from . import KNOWN_DEVICES
from .connection import HKDevice
from .entity import HomeKitEntity from .entity import HomeKitEntity
@ -106,6 +108,29 @@ class HomeKitLeakSensor(HomeKitEntity, BinarySensorEntity):
return self.service.value(CharacteristicsTypes.LEAK_DETECTED) == 1 return self.service.value(CharacteristicsTypes.LEAK_DETECTED) == 1
class HomeKitBatteryLowSensor(HomeKitEntity, BinarySensorEntity):
"""Representation of a Homekit battery low sensor."""
_attr_device_class = BinarySensorDeviceClass.BATTERY
_attr_entity_category = EntityCategory.DIAGNOSTIC
def get_characteristic_types(self) -> list[str]:
"""Define the homekit characteristics the entity is tracking."""
return [CharacteristicsTypes.STATUS_LO_BATT]
@property
def name(self) -> str:
"""Return the name of the sensor."""
if name := self.accessory.name:
return f"{name} Low Battery"
return "Low Battery"
@property
def is_on(self) -> bool:
"""Return true if low battery is detected from the binary sensor."""
return self.service.value(CharacteristicsTypes.STATUS_LO_BATT) == 1
ENTITY_TYPES = { ENTITY_TYPES = {
ServicesTypes.MOTION_SENSOR: HomeKitMotionSensor, ServicesTypes.MOTION_SENSOR: HomeKitMotionSensor,
ServicesTypes.CONTACT_SENSOR: HomeKitContactSensor, ServicesTypes.CONTACT_SENSOR: HomeKitContactSensor,
@ -113,6 +138,17 @@ ENTITY_TYPES = {
ServicesTypes.CARBON_MONOXIDE_SENSOR: HomeKitCarbonMonoxideSensor, ServicesTypes.CARBON_MONOXIDE_SENSOR: HomeKitCarbonMonoxideSensor,
ServicesTypes.OCCUPANCY_SENSOR: HomeKitOccupancySensor, ServicesTypes.OCCUPANCY_SENSOR: HomeKitOccupancySensor,
ServicesTypes.LEAK_SENSOR: HomeKitLeakSensor, ServicesTypes.LEAK_SENSOR: HomeKitLeakSensor,
ServicesTypes.BATTERY_SERVICE: HomeKitBatteryLowSensor,
}
# Only create the entity if it has the required characteristic
REQUIRED_CHAR_BY_TYPE = {
ServicesTypes.BATTERY_SERVICE: CharacteristicsTypes.STATUS_LO_BATT,
}
# Reject the service as another platform can represent it better
# if it has a specific characteristic
REJECT_CHAR_BY_TYPE = {
ServicesTypes.BATTERY_SERVICE: CharacteristicsTypes.BATTERY_LEVEL,
} }
@ -123,12 +159,20 @@ async def async_setup_entry(
) -> None: ) -> None:
"""Set up Homekit lighting.""" """Set up Homekit lighting."""
hkid = config_entry.data["AccessoryPairingID"] hkid = config_entry.data["AccessoryPairingID"]
conn = hass.data[KNOWN_DEVICES][hkid] conn: HKDevice = hass.data[KNOWN_DEVICES][hkid]
@callback @callback
def async_add_service(service: Service) -> bool: def async_add_service(service: Service) -> bool:
if not (entity_class := ENTITY_TYPES.get(service.type)): if not (entity_class := ENTITY_TYPES.get(service.type)):
return False return False
if (
required_char := REQUIRED_CHAR_BY_TYPE.get(service.type)
) and not service.has(required_char):
return False
if (reject_char := REJECT_CHAR_BY_TYPE.get(service.type)) and service.has(
reject_char
):
return False
info = {"aid": service.accessory.aid, "iid": service.iid} info = {"aid": service.accessory.aid, "iid": service.iid}
async_add_entities([entity_class(conn, info)], True) async_add_entities([entity_class(conn, info)], True)
return True return True

View File

@ -60,7 +60,7 @@ async def async_setup_entry(
) -> None: ) -> None:
"""Set up Homekit numbers.""" """Set up Homekit numbers."""
hkid = config_entry.data["AccessoryPairingID"] hkid = config_entry.data["AccessoryPairingID"]
conn = hass.data[KNOWN_DEVICES][hkid] conn: HKDevice = hass.data[KNOWN_DEVICES][hkid]
@callback @callback
def async_add_characteristic(char: Characteristic) -> bool: def async_add_characteristic(char: Characteristic) -> bool:

View File

@ -410,6 +410,7 @@ class HomeKitBatterySensor(HomeKitSensor):
_attr_device_class = SensorDeviceClass.BATTERY _attr_device_class = SensorDeviceClass.BATTERY
_attr_native_unit_of_measurement = PERCENTAGE _attr_native_unit_of_measurement = PERCENTAGE
_attr_entity_category = EntityCategory.DIAGNOSTIC
def get_characteristic_types(self) -> list[str]: def get_characteristic_types(self) -> list[str]:
"""Define the homekit characteristics the entity is tracking.""" """Define the homekit characteristics the entity is tracking."""
@ -517,6 +518,11 @@ ENTITY_TYPES = {
ServicesTypes.BATTERY_SERVICE: HomeKitBatterySensor, ServicesTypes.BATTERY_SERVICE: HomeKitBatterySensor,
} }
# Only create the entity if it has the required characteristic
REQUIRED_CHAR_BY_TYPE = {
ServicesTypes.BATTERY_SERVICE: CharacteristicsTypes.BATTERY_LEVEL,
}
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
@ -531,6 +537,10 @@ async def async_setup_entry(
def async_add_service(service: Service) -> bool: def async_add_service(service: Service) -> bool:
if not (entity_class := ENTITY_TYPES.get(service.type)): if not (entity_class := ENTITY_TYPES.get(service.type)):
return False return False
if (
required_char := REQUIRED_CHAR_BY_TYPE.get(service.type)
) and not service.has(required_char):
return False
info = {"aid": service.accessory.aid, "iid": service.iid} info = {"aid": service.accessory.aid, "iid": service.iid}
async_add_entities([entity_class(conn, info)], True) async_add_entities([entity_class(conn, info)], True)
return True return True

View File

@ -0,0 +1,362 @@
[
{
"aid": 1,
"services": [
{
"iid": 1,
"type": "000000A2-0000-1000-8000-0026BB765291",
"characteristics": [
{
"type": "00000037-0000-1000-8000-0026BB765291",
"iid": 19,
"perms": ["pr"],
"format": "string",
"value": "2.2.0",
"description": "Version",
"maxLen": 64
},
{
"type": "000000A5-0000-1000-8000-0026BB765291",
"iid": 18,
"perms": ["pr"],
"format": "data",
"value": ""
}
]
},
{
"iid": 4,
"type": "EA22EA53-6227-55EA-AC24-73ACF3EEA0E8",
"characteristics": [
{
"type": "000000A5-0000-1000-8000-0026BB765291",
"iid": 340,
"perms": ["pr"],
"format": "data",
"value": ""
},
{
"type": "00F44C18-042E-5C4E-9A4C-561D44DCD804",
"iid": 339,
"perms": ["pr", "hd"],
"format": "string",
"value": "g8d8a6c",
"maxLen": 64
}
]
},
{
"iid": 7,
"type": "0000003E-0000-1000-8000-0026BB765291",
"characteristics": [
{
"type": "00000023-0000-1000-8000-0026BB765291",
"iid": 2,
"perms": ["pr"],
"format": "string",
"value": "Smart CO Alarm",
"description": "Name",
"maxLen": 64
},
{
"type": "00000014-0000-1000-8000-0026BB765291",
"iid": 3,
"perms": ["pw"],
"format": "bool",
"description": "Identify"
},
{
"type": "00000053-0000-1000-8000-0026BB765291",
"iid": 8,
"perms": ["pr"],
"format": "string",
"value": "0",
"description": "Hardware Revision",
"maxLen": 64
},
{
"type": "00000020-0000-1000-8000-0026BB765291",
"iid": 4,
"perms": ["pr"],
"format": "string",
"value": "Netatmo",
"description": "Manufacturer",
"maxLen": 64
},
{
"type": "00000030-0000-1000-8000-0026BB765291",
"iid": 6,
"perms": ["pr"],
"format": "string",
"value": "1234",
"description": "Serial Number",
"maxLen": 64
},
{
"type": "00000021-0000-1000-8000-0026BB765291",
"iid": 5,
"perms": ["pr"],
"format": "string",
"value": "Smart CO Alarm",
"description": "Model",
"maxLen": 64
},
{
"type": "00000052-0000-1000-8000-0026BB765291",
"iid": 7,
"perms": ["pr"],
"format": "string",
"value": "1.0.3",
"description": "Firmware Revision",
"maxLen": 64
},
{
"type": "34AB8811-AC7F-4340-BAC3-FD6A85F9943B",
"iid": 47,
"perms": ["pr", "hd"],
"format": "string",
"value": "4.1;Sep 27 2021 12:54:49",
"maxLen": 64
},
{
"type": "00000220-0000-1000-8000-0026BB765291",
"iid": 325,
"perms": ["pr", "hd"],
"format": "data",
"value": "fa7beb3a4566c1fb"
}
]
},
{
"iid": 17,
"type": "00000055-0000-1000-8000-0026BB765291",
"characteristics": [
{
"type": "0000004C-0000-1000-8000-0026BB765291",
"iid": 203,
"perms": [],
"format": "data",
"description": "Pair Setup"
},
{
"type": "0000004F-0000-1000-8000-0026BB765291",
"iid": 205,
"perms": [],
"format": "uint8",
"description": "Pairing Features"
},
{
"type": "0000004E-0000-1000-8000-0026BB765291",
"iid": 204,
"perms": [],
"format": "data",
"description": "Pair Verify"
},
{
"type": "00000050-0000-1000-8000-0026BB765291",
"iid": 206,
"perms": ["pr", "pw"],
"format": "data",
"value": null,
"description": "Pairing Pairings"
}
]
},
{
"iid": 22,
"type": "0000007F-0000-1000-8000-0026BB765291",
"characteristics": [
{
"type": "00000075-0000-1000-8000-0026BB765291",
"iid": 230,
"perms": ["pr", "ev"],
"format": "bool",
"value": true,
"description": "Status Active"
},
{
"type": "00000077-0000-1000-8000-0026BB765291",
"iid": 231,
"perms": ["pr", "ev"],
"format": "uint8",
"value": 0,
"description": "Status Fault",
"minValue": 0,
"maxValue": 1
},
{
"type": "00000023-0000-1000-8000-0026BB765291",
"iid": 42,
"perms": ["pr"],
"format": "string",
"value": "Carbon Monoxide Sensor",
"description": "Name",
"maxLen": 64
},
{
"type": "00000091-0000-1000-8000-0026BB765291",
"iid": 41,
"perms": ["pr", "ev"],
"format": "float",
"value": 0.0,
"description": "Carbon Monoxide Peak Level",
"minValue": 0.0,
"maxValue": 1000.0
},
{
"type": "00000019-4DDB-598F-A73F-006513F2DB6B",
"iid": 333,
"perms": ["pr", "ev"],
"format": "uint8",
"value": 0,
"minValue": 0,
"maxValue": 3
},
{
"type": "00000090-0000-1000-8000-0026BB765291",
"iid": 40,
"perms": ["pr", "ev"],
"format": "float",
"value": 0.0,
"description": "Carbon Monoxide Level",
"minValue": 0.0,
"maxValue": 1000.0
},
{
"type": "0000000C-4DDB-598F-A73F-006513F2DB6B",
"iid": 326,
"perms": ["pr", "ev"],
"format": "bool",
"value": false
},
{
"type": "0000007A-0000-1000-8000-0026BB765291",
"iid": 45,
"perms": ["pr", "ev"],
"format": "uint8",
"value": 0,
"description": "Status Tampered",
"minValue": 0,
"maxValue": 1
},
{
"type": "00000001-4DDB-598F-A73F-006513F2DB6B",
"iid": 327,
"perms": ["pr", "pw", "ev"],
"format": "bool",
"value": false
},
{
"type": "00000012-4DDB-598F-A73F-006513F2DB6B",
"iid": 328,
"perms": ["pr", "ev"],
"format": "uint8",
"value": 0,
"minValue": 0,
"maxValue": 3
},
{
"type": "000000A5-0000-1000-8000-0026BB765291",
"iid": 43,
"perms": ["pr"],
"format": "data",
"value": ""
},
{
"type": "00000069-0000-1000-8000-0026BB765291",
"iid": 229,
"perms": ["pr", "ev"],
"format": "uint8",
"value": 0,
"description": "Carbon Monoxide Detected",
"minValue": 0,
"maxValue": 1
}
]
},
{
"iid": 35,
"type": "00001801-0000-1000-8000-00805F9B34FB",
"characteristics": []
},
{
"iid": 36,
"type": "00000096-0000-1000-8000-0026BB765291",
"characteristics": [
{
"type": "00000023-0000-1000-8000-0026BB765291",
"iid": 336,
"perms": ["pr"],
"format": "string",
"value": "Battery Service",
"description": "Name",
"maxLen": 64
},
{
"type": "00000079-0000-1000-8000-0026BB765291",
"iid": 337,
"perms": ["pr", "ev"],
"format": "uint8",
"value": 0,
"description": "Status Low Battery",
"minValue": 0,
"maxValue": 1
},
{
"type": "00000002-4DDB-598F-A73F-006513F2DB6B",
"iid": 335,
"perms": ["pr", "ev"],
"format": "uint8",
"value": 0,
"minValue": 0,
"maxValue": 4
}
]
},
{
"iid": 40,
"type": "00000004-4DDB-598F-A73F-006513F2DB6B",
"characteristics": [
{
"type": "00000007-4DDB-598F-A73F-006513F2DB6B",
"iid": 187,
"perms": ["pr", "ev"],
"format": "uint8",
"value": 0,
"minValue": 0,
"maxValue": 14
},
{
"type": "000000A5-0000-1000-8000-0026BB765291",
"iid": 183,
"perms": ["pr"],
"format": "data",
"value": ""
},
{
"type": "00000009-4DDB-598F-A73F-006513F2DB6B",
"iid": 184,
"perms": ["pw", "hd"],
"format": "uint8",
"minValue": 0,
"maxValue": 1
},
{
"type": "00000006-4DDB-598F-A73F-006513F2DB6B",
"iid": 188,
"perms": ["pr"],
"format": "data",
"value": "0000000000000000"
},
{
"type": "0000000A-4DDB-598F-A73F-006513F2DB6B",
"iid": 324,
"perms": ["pr", "ev"],
"format": "uint32",
"value": 3
}
]
}
]
}
]

View File

@ -9,6 +9,7 @@ https://github.com/home-assistant/core/pull/39090
from homeassistant.components.sensor import SensorStateClass from homeassistant.components.sensor import SensorStateClass
from homeassistant.const import PERCENTAGE from homeassistant.const import PERCENTAGE
from homeassistant.helpers.entity import EntityCategory
from ..common import ( from ..common import (
HUB_TEST_ACCESSORY_ID, HUB_TEST_ACCESSORY_ID,
@ -43,6 +44,7 @@ async def test_aqara_switch_setup(hass):
friendly_name="Programmable Switch Battery Sensor", friendly_name="Programmable Switch Battery Sensor",
unique_id="homekit-111a1111a1a111-5", unique_id="homekit-111a1111a1a111-5",
capabilities={"state_class": SensorStateClass.MEASUREMENT}, capabilities={"state_class": SensorStateClass.MEASUREMENT},
entity_category=EntityCategory.DIAGNOSTIC,
unit_of_measurement=PERCENTAGE, unit_of_measurement=PERCENTAGE,
state="100", state="100",
), ),

View File

@ -2,6 +2,7 @@
from homeassistant.components.sensor import SensorStateClass from homeassistant.components.sensor import SensorStateClass
from homeassistant.const import PERCENTAGE, TEMP_CELSIUS from homeassistant.const import PERCENTAGE, TEMP_CELSIUS
from homeassistant.helpers.entity import EntityCategory
from ..common import ( from ..common import (
HUB_TEST_ACCESSORY_ID, HUB_TEST_ACCESSORY_ID,
@ -46,6 +47,7 @@ async def test_arlo_baby_setup(hass):
entity_id="sensor.arlobabya0_battery", entity_id="sensor.arlobabya0_battery",
unique_id="homekit-00A0000000000-700", unique_id="homekit-00A0000000000-700",
friendly_name="ArloBabyA0 Battery", friendly_name="ArloBabyA0 Battery",
entity_category=EntityCategory.DIAGNOSTIC,
capabilities={"state_class": SensorStateClass.MEASUREMENT}, capabilities={"state_class": SensorStateClass.MEASUREMENT},
unit_of_measurement=PERCENTAGE, unit_of_measurement=PERCENTAGE,
state="82", state="82",

View File

@ -60,6 +60,7 @@ async def test_eve_degree_setup(hass):
entity_id="sensor.eve_degree_aa11_battery", entity_id="sensor.eve_degree_aa11_battery",
unique_id="homekit-AA00A0A00000-17", unique_id="homekit-AA00A0A00000-17",
friendly_name="Eve Degree AA11 Battery", friendly_name="Eve Degree AA11 Battery",
entity_category=EntityCategory.DIAGNOSTIC,
capabilities={"state_class": SensorStateClass.MEASUREMENT}, capabilities={"state_class": SensorStateClass.MEASUREMENT},
unit_of_measurement=PERCENTAGE, unit_of_measurement=PERCENTAGE,
state="65", state="65",

View File

@ -2,6 +2,7 @@
from homeassistant.components.sensor import SensorStateClass from homeassistant.components.sensor import SensorStateClass
from homeassistant.const import PERCENTAGE from homeassistant.const import PERCENTAGE
from homeassistant.helpers.entity import EntityCategory
from ..common import ( from ..common import (
HUB_TEST_ACCESSORY_ID, HUB_TEST_ACCESSORY_ID,
@ -44,6 +45,7 @@ async def test_hue_bridge_setup(hass):
entity_id="sensor.hue_dimmer_switch_battery", entity_id="sensor.hue_dimmer_switch_battery",
capabilities={"state_class": SensorStateClass.MEASUREMENT}, capabilities={"state_class": SensorStateClass.MEASUREMENT},
friendly_name="Hue dimmer switch battery", friendly_name="Hue dimmer switch battery",
entity_category=EntityCategory.DIAGNOSTIC,
unique_id="homekit-6623462389072572-644245094400", unique_id="homekit-6623462389072572-644245094400",
unit_of_measurement=PERCENTAGE, unit_of_measurement=PERCENTAGE,
state="100", state="100",

View File

@ -0,0 +1,50 @@
"""
Regression tests for Netamo Smart CO Alarm.
https://github.com/home-assistant/core/issues/78903
"""
from homeassistant.helpers.entity import EntityCategory
from ..common import (
HUB_TEST_ACCESSORY_ID,
DeviceTestInfo,
EntityTestInfo,
assert_devices_and_entities_created,
setup_accessories_from_file,
setup_test_accessories,
)
async def test_netamo_smart_co_alarm_setup(hass):
"""Test that a Netamo Smart CO Alarm can be correctly setup in HA."""
accessories = await setup_accessories_from_file(hass, "netamo_smart_co_alarm.json")
await setup_test_accessories(hass, accessories)
await assert_devices_and_entities_created(
hass,
DeviceTestInfo(
unique_id=HUB_TEST_ACCESSORY_ID,
name="Smart CO Alarm",
model="Smart CO Alarm",
manufacturer="Netatmo",
sw_version="1.0.3",
hw_version="0",
serial_number="1234",
devices=[],
entities=[
EntityTestInfo(
entity_id="binary_sensor.smart_co_alarm_carbon_monoxide_sensor",
friendly_name="Smart CO Alarm Carbon Monoxide Sensor",
unique_id="homekit-1234-22",
state="off",
),
EntityTestInfo(
entity_id="binary_sensor.smart_co_alarm_low_battery",
friendly_name="Smart CO Alarm Low Battery",
entity_category=EntityCategory.DIAGNOSTIC,
unique_id="homekit-1234-36",
state="off",
),
],
),
)

View File

@ -3,6 +3,7 @@
from homeassistant.components.cover import CoverEntityFeature from homeassistant.components.cover import CoverEntityFeature
from homeassistant.components.sensor import SensorStateClass from homeassistant.components.sensor import SensorStateClass
from homeassistant.const import PERCENTAGE from homeassistant.const import PERCENTAGE
from homeassistant.helpers.entity import EntityCategory
from ..common import ( from ..common import (
HUB_TEST_ACCESSORY_ID, HUB_TEST_ACCESSORY_ID,
@ -53,6 +54,7 @@ async def test_ryse_smart_bridge_setup(hass):
EntityTestInfo( EntityTestInfo(
entity_id="sensor.master_bath_south_ryse_shade_battery", entity_id="sensor.master_bath_south_ryse_shade_battery",
friendly_name="Master Bath South RYSE Shade Battery", friendly_name="Master Bath South RYSE Shade Battery",
entity_category=EntityCategory.DIAGNOSTIC,
capabilities={"state_class": SensorStateClass.MEASUREMENT}, capabilities={"state_class": SensorStateClass.MEASUREMENT},
unique_id="homekit-00:00:00:00:00:00-2-64", unique_id="homekit-00:00:00:00:00:00-2-64",
unit_of_measurement=PERCENTAGE, unit_of_measurement=PERCENTAGE,
@ -80,6 +82,7 @@ async def test_ryse_smart_bridge_setup(hass):
EntityTestInfo( EntityTestInfo(
entity_id="sensor.ryse_smartshade_ryse_shade_battery", entity_id="sensor.ryse_smartshade_ryse_shade_battery",
friendly_name="RYSE SmartShade RYSE Shade Battery", friendly_name="RYSE SmartShade RYSE Shade Battery",
entity_category=EntityCategory.DIAGNOSTIC,
capabilities={"state_class": SensorStateClass.MEASUREMENT}, capabilities={"state_class": SensorStateClass.MEASUREMENT},
unique_id="homekit-00:00:00:00:00:00-3-64", unique_id="homekit-00:00:00:00:00:00-3-64",
unit_of_measurement=PERCENTAGE, unit_of_measurement=PERCENTAGE,
@ -130,6 +133,7 @@ async def test_ryse_smart_bridge_four_shades_setup(hass):
EntityTestInfo( EntityTestInfo(
entity_id="sensor.lr_left_ryse_shade_battery", entity_id="sensor.lr_left_ryse_shade_battery",
friendly_name="LR Left RYSE Shade Battery", friendly_name="LR Left RYSE Shade Battery",
entity_category=EntityCategory.DIAGNOSTIC,
capabilities={"state_class": SensorStateClass.MEASUREMENT}, capabilities={"state_class": SensorStateClass.MEASUREMENT},
unique_id="homekit-00:00:00:00:00:00-2-64", unique_id="homekit-00:00:00:00:00:00-2-64",
unit_of_measurement=PERCENTAGE, unit_of_measurement=PERCENTAGE,
@ -157,6 +161,7 @@ async def test_ryse_smart_bridge_four_shades_setup(hass):
EntityTestInfo( EntityTestInfo(
entity_id="sensor.lr_right_ryse_shade_battery", entity_id="sensor.lr_right_ryse_shade_battery",
friendly_name="LR Right RYSE Shade Battery", friendly_name="LR Right RYSE Shade Battery",
entity_category=EntityCategory.DIAGNOSTIC,
capabilities={"state_class": SensorStateClass.MEASUREMENT}, capabilities={"state_class": SensorStateClass.MEASUREMENT},
unique_id="homekit-00:00:00:00:00:00-3-64", unique_id="homekit-00:00:00:00:00:00-3-64",
unit_of_measurement=PERCENTAGE, unit_of_measurement=PERCENTAGE,
@ -184,6 +189,7 @@ async def test_ryse_smart_bridge_four_shades_setup(hass):
EntityTestInfo( EntityTestInfo(
entity_id="sensor.br_left_ryse_shade_battery", entity_id="sensor.br_left_ryse_shade_battery",
friendly_name="BR Left RYSE Shade Battery", friendly_name="BR Left RYSE Shade Battery",
entity_category=EntityCategory.DIAGNOSTIC,
capabilities={"state_class": SensorStateClass.MEASUREMENT}, capabilities={"state_class": SensorStateClass.MEASUREMENT},
unique_id="homekit-00:00:00:00:00:00-4-64", unique_id="homekit-00:00:00:00:00:00-4-64",
unit_of_measurement=PERCENTAGE, unit_of_measurement=PERCENTAGE,
@ -210,6 +216,7 @@ async def test_ryse_smart_bridge_four_shades_setup(hass):
), ),
EntityTestInfo( EntityTestInfo(
entity_id="sensor.rzss_ryse_shade_battery", entity_id="sensor.rzss_ryse_shade_battery",
entity_category=EntityCategory.DIAGNOSTIC,
capabilities={"state_class": SensorStateClass.MEASUREMENT}, capabilities={"state_class": SensorStateClass.MEASUREMENT},
friendly_name="RZSS RYSE Shade Battery", friendly_name="RZSS RYSE Shade Battery",
unique_id="homekit-00:00:00:00:00:00-5-64", unique_id="homekit-00:00:00:00:00:00-5-64",

View File

@ -98,7 +98,7 @@ async def test_enumerate_remote(hass, utcnow):
"entity_id": "sensor.testdevice_battery", "entity_id": "sensor.testdevice_battery",
"platform": "device", "platform": "device",
"type": "battery_level", "type": "battery_level",
"metadata": {"secondary": False}, "metadata": {"secondary": True},
}, },
{ {
"device_id": device.id, "device_id": device.id,
@ -146,7 +146,7 @@ async def test_enumerate_button(hass, utcnow):
"entity_id": "sensor.testdevice_battery", "entity_id": "sensor.testdevice_battery",
"platform": "device", "platform": "device",
"type": "battery_level", "type": "battery_level",
"metadata": {"secondary": False}, "metadata": {"secondary": True},
}, },
{ {
"device_id": device.id, "device_id": device.id,
@ -193,7 +193,7 @@ async def test_enumerate_doorbell(hass, utcnow):
"entity_id": "sensor.testdevice_battery", "entity_id": "sensor.testdevice_battery",
"platform": "device", "platform": "device",
"type": "battery_level", "type": "battery_level",
"metadata": {"secondary": False}, "metadata": {"secondary": True},
}, },
{ {
"device_id": device.id, "device_id": device.id,