Allow adding new devices to an Aqara hub via homekit_controller (#62600)
This commit is contained in:
parent
6e13605cad
commit
06eec7adfc
8 changed files with 869 additions and 10 deletions
|
@ -48,6 +48,9 @@ HOMEKIT_ACCESSORY_DISPATCH = {
|
|||
|
||||
CHARACTERISTIC_PLATFORMS = {
|
||||
CharacteristicsTypes.Vendor.AQARA_GATEWAY_VOLUME: "number",
|
||||
CharacteristicsTypes.Vendor.AQARA_E1_GATEWAY_VOLUME: "number",
|
||||
CharacteristicsTypes.Vendor.AQARA_PAIRING_MODE: "switch",
|
||||
CharacteristicsTypes.Vendor.AQARA_E1_PAIRING_MODE: "switch",
|
||||
CharacteristicsTypes.Vendor.EVE_ENERGY_WATT: "sensor",
|
||||
CharacteristicsTypes.Vendor.EVE_DEGREE_AIR_PRESSURE: "sensor",
|
||||
CharacteristicsTypes.Vendor.EVE_DEGREE_ELEVATION: "number",
|
||||
|
|
|
@ -75,10 +75,9 @@ class HomeKitNumber(CharacteristicEntity, NumberEntity):
|
|||
@property
|
||||
def name(self) -> str:
|
||||
"""Return the name of the device if any."""
|
||||
prefix = ""
|
||||
if name := super().name:
|
||||
prefix = f"{name} -"
|
||||
return f"{prefix} {self.entity_description.name}"
|
||||
if prefix := super().name:
|
||||
return f"{prefix} {self.entity_description.name}"
|
||||
return self.entity_description.name
|
||||
|
||||
def get_characteristic_types(self):
|
||||
"""Define the homekit characteristics the entity is tracking."""
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
"""Support for Homekit switches."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from aiohomekit.model.characteristics import (
|
||||
Characteristic,
|
||||
CharacteristicsTypes,
|
||||
InUseValues,
|
||||
IsConfiguredValues,
|
||||
)
|
||||
from aiohomekit.model.services import ServicesTypes
|
||||
|
||||
from homeassistant.components.switch import SwitchEntity
|
||||
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.entity import EntityCategory
|
||||
|
||||
from . import KNOWN_DEVICES, HomeKitEntity
|
||||
from . import KNOWN_DEVICES, CharacteristicEntity, HomeKitEntity
|
||||
|
||||
OUTLET_IN_USE = "outlet_in_use"
|
||||
|
||||
|
@ -18,6 +24,30 @@ ATTR_IS_CONFIGURED = "is_configured"
|
|||
ATTR_REMAINING_DURATION = "remaining_duration"
|
||||
|
||||
|
||||
@dataclass
|
||||
class DeclarativeSwitchEntityDescription(SwitchEntityDescription):
|
||||
"""Describes Homekit button."""
|
||||
|
||||
true_value: bool = True
|
||||
false_value: bool = False
|
||||
|
||||
|
||||
SWITCH_ENTITIES: dict[str, DeclarativeSwitchEntityDescription] = {
|
||||
CharacteristicsTypes.Vendor.AQARA_PAIRING_MODE: DeclarativeSwitchEntityDescription(
|
||||
key=CharacteristicsTypes.Vendor.AQARA_PAIRING_MODE,
|
||||
name="Pairing Mode",
|
||||
icon="mdi:lock-open",
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
),
|
||||
CharacteristicsTypes.Vendor.AQARA_E1_PAIRING_MODE: DeclarativeSwitchEntityDescription(
|
||||
key=CharacteristicsTypes.Vendor.AQARA_E1_PAIRING_MODE,
|
||||
name="Pairing Mode",
|
||||
icon="mdi:lock-open",
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
class HomeKitSwitch(HomeKitEntity, SwitchEntity):
|
||||
"""Representation of a Homekit switch."""
|
||||
|
||||
|
@ -96,6 +126,49 @@ class HomeKitValve(HomeKitEntity, SwitchEntity):
|
|||
return attrs
|
||||
|
||||
|
||||
class DeclarativeCharacteristicSwitch(CharacteristicEntity, SwitchEntity):
|
||||
"""Representation of a Homekit switch backed by a single characteristic."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
conn,
|
||||
info,
|
||||
char,
|
||||
description: DeclarativeSwitchEntityDescription,
|
||||
):
|
||||
"""Initialise a HomeKit switch."""
|
||||
self.entity_description = description
|
||||
super().__init__(conn, info, char)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Return the name of the device if any."""
|
||||
if prefix := super().name:
|
||||
return f"{prefix} {self.entity_description.name}"
|
||||
return self.entity_description.name
|
||||
|
||||
def get_characteristic_types(self):
|
||||
"""Define the homekit characteristics the entity cares about."""
|
||||
return [self._char.type]
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return true if device is on."""
|
||||
return self._char.value == self.entity_description.true_value
|
||||
|
||||
async def async_turn_on(self, **kwargs):
|
||||
"""Turn the specified switch on."""
|
||||
await self.async_put_characteristics(
|
||||
{self._char.type: self.entity_description.true_value}
|
||||
)
|
||||
|
||||
async def async_turn_off(self, **kwargs):
|
||||
"""Turn the specified switch off."""
|
||||
await self.async_put_characteristics(
|
||||
{self._char.type: self.entity_description.false_value}
|
||||
)
|
||||
|
||||
|
||||
ENTITY_TYPES = {
|
||||
ServicesTypes.SWITCH: HomeKitSwitch,
|
||||
ServicesTypes.OUTLET: HomeKitSwitch,
|
||||
|
@ -117,3 +190,16 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
return True
|
||||
|
||||
conn.add_listener(async_add_service)
|
||||
|
||||
@callback
|
||||
def async_add_characteristic(char: Characteristic):
|
||||
if not (description := SWITCH_ENTITIES.get(char.type)):
|
||||
return False
|
||||
|
||||
info = {"aid": char.service.accessory.aid, "iid": char.service.iid}
|
||||
async_add_entities(
|
||||
[DeclarativeCharacteristicSwitch(conn, info, char, description)], True
|
||||
)
|
||||
return True
|
||||
|
||||
conn.add_char_factory(async_add_characteristic)
|
||||
|
|
646
tests/components/homekit_controller/fixtures/aqara_e1.json
Normal file
646
tests/components/homekit_controller/fixtures/aqara_e1.json
Normal file
|
@ -0,0 +1,646 @@
|
|||
[
|
||||
{
|
||||
"aid": 1,
|
||||
"services": [
|
||||
{
|
||||
"iid": 1,
|
||||
"type": "0000003E-0000-1000-8000-0026BB765291",
|
||||
"primary": false,
|
||||
"hidden": false,
|
||||
"characteristics": [
|
||||
{
|
||||
"iid": 65537,
|
||||
"type": "00000014-0000-1000-8000-0026BB765291",
|
||||
"format": "bool",
|
||||
"perms": [
|
||||
"pw"
|
||||
]
|
||||
},
|
||||
{
|
||||
"iid": 65538,
|
||||
"type": "00000020-0000-1000-8000-0026BB765291",
|
||||
"format": "string",
|
||||
"value": "Aqara",
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false
|
||||
},
|
||||
{
|
||||
"iid": 65539,
|
||||
"type": "00000021-0000-1000-8000-0026BB765291",
|
||||
"format": "string",
|
||||
"value": "HE1-G01",
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false
|
||||
},
|
||||
{
|
||||
"iid": 65540,
|
||||
"type": "00000023-0000-1000-8000-0026BB765291",
|
||||
"format": "string",
|
||||
"value": "Aqara-Hub-E1-00A0",
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false
|
||||
},
|
||||
{
|
||||
"iid": 65541,
|
||||
"type": "00000030-0000-1000-8000-0026BB765291",
|
||||
"format": "string",
|
||||
"value": "00aa00000a0",
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false
|
||||
},
|
||||
{
|
||||
"iid": 65542,
|
||||
"type": "00000052-0000-1000-8000-0026BB765291",
|
||||
"format": "string",
|
||||
"value": "3.3.0",
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false
|
||||
},
|
||||
{
|
||||
"iid": 65543,
|
||||
"type": "00000053-0000-1000-8000-0026BB765291",
|
||||
"format": "string",
|
||||
"value": "1.0",
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false
|
||||
},
|
||||
{
|
||||
"iid": 65544,
|
||||
"type": "34AB8811-AC7F-4340-BAC3-FD6A85F9943B",
|
||||
"format": "string",
|
||||
"value": "5.0;dfeceb3a",
|
||||
"perms": [
|
||||
"pr",
|
||||
"hd"
|
||||
],
|
||||
"ev": false
|
||||
},
|
||||
{
|
||||
"iid": 65545,
|
||||
"type": "220",
|
||||
"format": "data",
|
||||
"value": "xDsGO4QdTEA=",
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false,
|
||||
"maxDataLen": 8
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"iid": 2,
|
||||
"type": "000000A2-0000-1000-8000-0026BB765291",
|
||||
"primary": false,
|
||||
"hidden": false,
|
||||
"characteristics": [
|
||||
{
|
||||
"iid": 131074,
|
||||
"type": "00000037-0000-1000-8000-0026BB765291",
|
||||
"format": "string",
|
||||
"value": "1.1.0",
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"iid": 4,
|
||||
"type": "22A",
|
||||
"primary": false,
|
||||
"hidden": false,
|
||||
"characteristics": [
|
||||
{
|
||||
"iid": 262145,
|
||||
"type": "22B",
|
||||
"format": "bool",
|
||||
"value": 1,
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false
|
||||
},
|
||||
{
|
||||
"iid": 262146,
|
||||
"type": "22C",
|
||||
"format": "uint32",
|
||||
"value": 9,
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false,
|
||||
"minValue": 0,
|
||||
"maxValue": 15,
|
||||
"minStep": 1
|
||||
},
|
||||
{
|
||||
"iid": 262147,
|
||||
"type": "22D",
|
||||
"format": "tlv8",
|
||||
"value": "",
|
||||
"perms": [
|
||||
"pr",
|
||||
"pw",
|
||||
"ev",
|
||||
"tw",
|
||||
"wr"
|
||||
],
|
||||
"ev": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"iid": 16,
|
||||
"type": "0000007E-0000-1000-8000-0026BB765291",
|
||||
"primary": true,
|
||||
"hidden": false,
|
||||
"characteristics": [
|
||||
{
|
||||
"iid": 1048578,
|
||||
"type": "00000023-0000-1000-8000-0026BB765291",
|
||||
"format": "string",
|
||||
"value": "Security System",
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false
|
||||
},
|
||||
{
|
||||
"iid": 1048579,
|
||||
"type": "00000066-0000-1000-8000-0026BB765291",
|
||||
"format": "uint8",
|
||||
"value": 3,
|
||||
"perms": [
|
||||
"pr",
|
||||
"ev"
|
||||
],
|
||||
"ev": true,
|
||||
"minValue": 0,
|
||||
"maxValue": 4,
|
||||
"minStep": 1,
|
||||
"valid-values": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4
|
||||
]
|
||||
},
|
||||
{
|
||||
"iid": 1048580,
|
||||
"type": "00000067-0000-1000-8000-0026BB765291",
|
||||
"format": "uint8",
|
||||
"value": 3,
|
||||
"perms": [
|
||||
"pr",
|
||||
"pw",
|
||||
"ev"
|
||||
],
|
||||
"ev": true,
|
||||
"minValue": 0,
|
||||
"maxValue": 3,
|
||||
"minStep": 1,
|
||||
"valid-values": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3
|
||||
]
|
||||
},
|
||||
{
|
||||
"iid": 1048581,
|
||||
"type": "60CDDE6C-42B6-4C72-9719-AB2740EABE2A",
|
||||
"format": "tlv8",
|
||||
"value": "AAA=",
|
||||
"perms": [
|
||||
"pr",
|
||||
"pw"
|
||||
],
|
||||
"ev": false,
|
||||
"description": "Stay Arm Trigger Devices"
|
||||
},
|
||||
{
|
||||
"iid": 1048582,
|
||||
"type": "4AB2460A-41E4-4F05-97C3-CCFDAE1BE324",
|
||||
"format": "tlv8",
|
||||
"value": "AAA=",
|
||||
"perms": [
|
||||
"pr",
|
||||
"pw"
|
||||
],
|
||||
"ev": false,
|
||||
"description": "Alarm Trigger Devices"
|
||||
},
|
||||
{
|
||||
"iid": 1048583,
|
||||
"type": "F8296386-5A30-4AA7-838C-ED0DA9D807DF",
|
||||
"format": "tlv8",
|
||||
"value": "AAA=",
|
||||
"perms": [
|
||||
"pr",
|
||||
"pw"
|
||||
],
|
||||
"ev": false,
|
||||
"description": "Night Arm Trigger Devices"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"iid": 17,
|
||||
"type": "9715BF53-AB63-4449-8DC7-2785D617390A",
|
||||
"primary": false,
|
||||
"hidden": true,
|
||||
"characteristics": [
|
||||
{
|
||||
"iid": 1114114,
|
||||
"type": "00000023-0000-1000-8000-0026BB765291",
|
||||
"format": "string",
|
||||
"value": "Gateway",
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false
|
||||
},
|
||||
{
|
||||
"iid": 1114115,
|
||||
"type": "4CB28907-66DF-4D9C-962C-9971ABF30EDC",
|
||||
"format": "string",
|
||||
"value": "1970-01-01 21:01:22+8",
|
||||
"perms": [
|
||||
"pr",
|
||||
"pw",
|
||||
"hd"
|
||||
],
|
||||
"ev": false,
|
||||
"description": "Date and Time"
|
||||
},
|
||||
{
|
||||
"iid": 1114116,
|
||||
"type": "EE56B186-B0D3-488E-8C79-C21FC9BCF437",
|
||||
"format": "int",
|
||||
"value": 40,
|
||||
"perms": [
|
||||
"pr",
|
||||
"pw",
|
||||
"ev",
|
||||
"hd"
|
||||
],
|
||||
"ev": false,
|
||||
"description": "Gateway Volume",
|
||||
"unit": "percentage",
|
||||
"minValue": 0,
|
||||
"maxValue": 100,
|
||||
"minStep": 1
|
||||
},
|
||||
{
|
||||
"iid": 1114117,
|
||||
"type": "B1C09E4C-E202-4827-B863-B0F32F727CFF",
|
||||
"format": "bool",
|
||||
"value": 0,
|
||||
"perms": [
|
||||
"pr",
|
||||
"pw",
|
||||
"ev",
|
||||
"hd"
|
||||
],
|
||||
"ev": false,
|
||||
"description": "New Accessory Permission"
|
||||
},
|
||||
{
|
||||
"iid": 1114118,
|
||||
"type": "2CB22739-1E4C-4798-A761-BC2FAF51AFC3",
|
||||
"format": "string",
|
||||
"value": "",
|
||||
"perms": [
|
||||
"pr",
|
||||
"ev",
|
||||
"hd"
|
||||
],
|
||||
"ev": false,
|
||||
"description": "Accessory Joined"
|
||||
},
|
||||
{
|
||||
"iid": 1114119,
|
||||
"type": "75D19FA9-218B-4943-997E-341E5D1C60CC",
|
||||
"format": "string",
|
||||
"perms": [
|
||||
"pw",
|
||||
"hd"
|
||||
],
|
||||
"description": "Remove Accessory"
|
||||
},
|
||||
{
|
||||
"iid": 1114120,
|
||||
"type": "7D943F6A-E052-4E96-A176-D17BF00E32CB",
|
||||
"format": "int",
|
||||
"value": -1,
|
||||
"perms": [
|
||||
"pr",
|
||||
"ev",
|
||||
"hd"
|
||||
],
|
||||
"ev": false,
|
||||
"description": "Firmware Update Status",
|
||||
"minValue": -65535,
|
||||
"maxValue": 65535,
|
||||
"minStep": 1
|
||||
},
|
||||
{
|
||||
"iid": 1114121,
|
||||
"type": "A45EFD52-0DB5-4C1A-9727-513FBCD8185F",
|
||||
"format": "string",
|
||||
"perms": [
|
||||
"pw",
|
||||
"hd"
|
||||
],
|
||||
"description": "Firmware Update URL",
|
||||
"maxLen": 256
|
||||
},
|
||||
{
|
||||
"iid": 1114122,
|
||||
"type": "40F0124A-579D-40E4-865E-0EF6740EA64B",
|
||||
"format": "string",
|
||||
"perms": [
|
||||
"pw",
|
||||
"hd"
|
||||
],
|
||||
"description": "Firmware Update Checksum"
|
||||
},
|
||||
{
|
||||
"iid": 1114123,
|
||||
"type": "E1C20B22-E3A7-4B92-8BA3-C16E778648A7",
|
||||
"format": "string",
|
||||
"value": "",
|
||||
"perms": [
|
||||
"pr",
|
||||
"ev",
|
||||
"hd"
|
||||
],
|
||||
"ev": false,
|
||||
"description": "Identify Accessory"
|
||||
},
|
||||
{
|
||||
"iid": 1114124,
|
||||
"type": "4CF1436A-755C-4377-BDB8-30BE29EB8620",
|
||||
"format": "string",
|
||||
"value": "Chinese",
|
||||
"perms": [
|
||||
"pr",
|
||||
"pw",
|
||||
"ev",
|
||||
"hd"
|
||||
],
|
||||
"ev": false,
|
||||
"description": "Language"
|
||||
},
|
||||
{
|
||||
"iid": 1114125,
|
||||
"type": "25D889CB-7135-4A29-B5B4-C1FFD6D2DD5C",
|
||||
"format": "string",
|
||||
"value": "",
|
||||
"perms": [
|
||||
"pr",
|
||||
"pw",
|
||||
"hd"
|
||||
],
|
||||
"ev": false,
|
||||
"description": "Country Domain"
|
||||
},
|
||||
{
|
||||
"iid": 1114126,
|
||||
"type": "C7EECAA7-91D9-40EB-AD0C-FFDDE3143CB9",
|
||||
"format": "string",
|
||||
"value": "lumi1.00aa00000a0",
|
||||
"perms": [
|
||||
"pr",
|
||||
"hd"
|
||||
],
|
||||
"ev": false,
|
||||
"description": "Lumi Did"
|
||||
},
|
||||
{
|
||||
"iid": 1114127,
|
||||
"type": "80FA747E-CB45-45A4-B7BE-AA7D9964859E",
|
||||
"format": "string",
|
||||
"perms": [
|
||||
"pw",
|
||||
"hd"
|
||||
],
|
||||
"description": "Lumi Bindkey"
|
||||
},
|
||||
{
|
||||
"iid": 1114128,
|
||||
"type": "C3B8A329-EF0C-4739-B773-E5B7AEA52C71",
|
||||
"format": "bool",
|
||||
"value": 0,
|
||||
"perms": [
|
||||
"pr",
|
||||
"hd"
|
||||
],
|
||||
"ev": false,
|
||||
"description": "Lumi Bindstate"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"aid": 33,
|
||||
"services": [
|
||||
{
|
||||
"iid": 1,
|
||||
"type": "0000003E-0000-1000-8000-0026BB765291",
|
||||
"primary": false,
|
||||
"hidden": false,
|
||||
"characteristics": [
|
||||
{
|
||||
"iid": 65537,
|
||||
"type": "00000014-0000-1000-8000-0026BB765291",
|
||||
"format": "bool",
|
||||
"perms": [
|
||||
"pw"
|
||||
]
|
||||
},
|
||||
{
|
||||
"iid": 65538,
|
||||
"type": "00000020-0000-1000-8000-0026BB765291",
|
||||
"format": "string",
|
||||
"value": "Aqara",
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false
|
||||
},
|
||||
{
|
||||
"iid": 65539,
|
||||
"type": "00000021-0000-1000-8000-0026BB765291",
|
||||
"format": "string",
|
||||
"value": "AS006",
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false
|
||||
},
|
||||
{
|
||||
"iid": 65540,
|
||||
"type": "00000023-0000-1000-8000-0026BB765291",
|
||||
"format": "string",
|
||||
"value": "Contact Sensor",
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false
|
||||
},
|
||||
{
|
||||
"iid": 65541,
|
||||
"type": "00000030-0000-1000-8000-0026BB765291",
|
||||
"format": "string",
|
||||
"value": "158d0007c59c6a",
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false
|
||||
},
|
||||
{
|
||||
"iid": 65542,
|
||||
"type": "00000052-0000-1000-8000-0026BB765291",
|
||||
"format": "string",
|
||||
"value": "0",
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false
|
||||
},
|
||||
{
|
||||
"iid": 65543,
|
||||
"type": "00000053-0000-1000-8000-0026BB765291",
|
||||
"format": "string",
|
||||
"value": "1.0",
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"iid": 4,
|
||||
"type": "00000080-0000-1000-8000-0026BB765291",
|
||||
"primary": true,
|
||||
"hidden": false,
|
||||
"characteristics": [
|
||||
{
|
||||
"iid": 262146,
|
||||
"type": "00000023-0000-1000-8000-0026BB765291",
|
||||
"format": "string",
|
||||
"value": "Contact Sensor",
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false
|
||||
},
|
||||
{
|
||||
"iid": 262147,
|
||||
"type": "0000006A-0000-1000-8000-0026BB765291",
|
||||
"format": "uint8",
|
||||
"value": 0,
|
||||
"perms": [
|
||||
"pr",
|
||||
"ev"
|
||||
],
|
||||
"ev": true,
|
||||
"minValue": 0,
|
||||
"maxValue": 1,
|
||||
"minStep": 1,
|
||||
"valid-values": [
|
||||
0,
|
||||
1
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"iid": 5,
|
||||
"type": "00000096-0000-1000-8000-0026BB765291",
|
||||
"primary": false,
|
||||
"hidden": false,
|
||||
"characteristics": [
|
||||
{
|
||||
"iid": 327682,
|
||||
"type": "00000023-0000-1000-8000-0026BB765291",
|
||||
"format": "string",
|
||||
"value": "Battery Sensor",
|
||||
"perms": [
|
||||
"pr"
|
||||
],
|
||||
"ev": false
|
||||
},
|
||||
{
|
||||
"iid": 327683,
|
||||
"type": "00000068-0000-1000-8000-0026BB765291",
|
||||
"format": "uint8",
|
||||
"value": 100,
|
||||
"perms": [
|
||||
"pr",
|
||||
"ev"
|
||||
],
|
||||
"ev": true,
|
||||
"unit": "percentage",
|
||||
"minValue": 0,
|
||||
"maxValue": 100,
|
||||
"minStep": 1
|
||||
},
|
||||
{
|
||||
"iid": 327685,
|
||||
"type": "00000079-0000-1000-8000-0026BB765291",
|
||||
"format": "uint8",
|
||||
"value": 0,
|
||||
"perms": [
|
||||
"pr",
|
||||
"ev"
|
||||
],
|
||||
"ev": true,
|
||||
"minValue": 0,
|
||||
"maxValue": 1,
|
||||
"minStep": 1,
|
||||
"valid-values": [
|
||||
0,
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"iid": 327684,
|
||||
"type": "0000008F-0000-1000-8000-0026BB765291",
|
||||
"format": "uint8",
|
||||
"value": 2,
|
||||
"perms": [
|
||||
"pr",
|
||||
"ev"
|
||||
],
|
||||
"ev": true,
|
||||
"minValue": 2,
|
||||
"maxValue": 2,
|
||||
"minStep": 1,
|
||||
"valid-values": [
|
||||
2
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -45,7 +45,14 @@ async def test_aqara_gateway_setup(hass):
|
|||
(
|
||||
"number.aqara_hub_1563_volume",
|
||||
"homekit-0000000123456789-aid:1-sid:65536-cid:65541",
|
||||
"Aqara Hub-1563 - Volume",
|
||||
"Aqara Hub-1563 Volume",
|
||||
None,
|
||||
EntityCategory.CONFIG,
|
||||
),
|
||||
(
|
||||
"switch.aqara_hub_1563_pairing_mode",
|
||||
"homekit-0000000123456789-aid:1-sid:65536-cid:65538",
|
||||
"Aqara Hub-1563 Pairing Mode",
|
||||
None,
|
||||
EntityCategory.CONFIG,
|
||||
),
|
||||
|
@ -80,3 +87,66 @@ async def test_aqara_gateway_setup(hass):
|
|||
|
||||
# All entities should be part of same device
|
||||
assert len(device_ids) == 1
|
||||
|
||||
|
||||
async def test_aqara_gateway_e1_setup(hass):
|
||||
"""Test that an Aqara E1 Gateway can be correctly setup in HA."""
|
||||
accessories = await setup_accessories_from_file(hass, "aqara_e1.json")
|
||||
config_entry, pairing = await setup_test_accessories(hass, accessories)
|
||||
|
||||
entity_registry = er.async_get(hass)
|
||||
device_registry = dr.async_get(hass)
|
||||
|
||||
sensors = [
|
||||
(
|
||||
"alarm_control_panel.aqara_hub_e1_00a0",
|
||||
"homekit-00aa00000a0-16",
|
||||
"Aqara-Hub-E1-00A0",
|
||||
SUPPORT_ALARM_ARM_NIGHT | SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY,
|
||||
None,
|
||||
),
|
||||
(
|
||||
"number.aqara_hub_e1_00a0_volume",
|
||||
"homekit-00aa00000a0-aid:1-sid:17-cid:1114116",
|
||||
"Aqara-Hub-E1-00A0 Volume",
|
||||
None,
|
||||
EntityCategory.CONFIG,
|
||||
),
|
||||
(
|
||||
"switch.aqara_hub_e1_00a0_pairing_mode",
|
||||
"homekit-00aa00000a0-aid:1-sid:17-cid:1114117",
|
||||
"Aqara-Hub-E1-00A0 Pairing Mode",
|
||||
None,
|
||||
EntityCategory.CONFIG,
|
||||
),
|
||||
]
|
||||
|
||||
device_ids = set()
|
||||
|
||||
for (entity_id, unique_id, friendly_name, supported_features, category) in sensors:
|
||||
entry = entity_registry.async_get(entity_id)
|
||||
assert entry.unique_id == unique_id
|
||||
assert entry.entity_category == category
|
||||
|
||||
helper = Helper(
|
||||
hass,
|
||||
entity_id,
|
||||
pairing,
|
||||
accessories[0],
|
||||
config_entry,
|
||||
)
|
||||
state = await helper.poll_and_get_state()
|
||||
assert state.attributes["friendly_name"] == friendly_name
|
||||
assert state.attributes.get("supported_features") == supported_features
|
||||
|
||||
device = device_registry.async_get(entry.device_id)
|
||||
assert device.manufacturer == "Aqara"
|
||||
assert device.name == "Aqara-Hub-E1-00A0"
|
||||
assert device.model == "HE1-G01"
|
||||
assert device.sw_version == "3.3.0"
|
||||
assert device.via_device_id is None
|
||||
|
||||
device_ids.add(entry.device_id)
|
||||
|
||||
# All entities should be part of same device
|
||||
assert len(device_ids) == 1
|
||||
|
|
|
@ -41,7 +41,7 @@ async def test_eve_degree_setup(hass):
|
|||
(
|
||||
"number.eve_degree_aa11_elevation",
|
||||
"homekit-AA00A0A00000-aid:1-sid:30-cid:33",
|
||||
"Eve Degree AA11 - Elevation",
|
||||
"Eve Degree AA11 Elevation",
|
||||
),
|
||||
]
|
||||
|
||||
|
|
|
@ -31,8 +31,7 @@ async def test_vocolinc_flowerbud_setup(hass):
|
|||
)
|
||||
state = await helper.poll_and_get_state()
|
||||
assert (
|
||||
state.attributes["friendly_name"]
|
||||
== "VOCOlinc-Flowerbud-0d324b - Spray Quantity"
|
||||
state.attributes["friendly_name"] == "VOCOlinc-Flowerbud-0d324b Spray Quantity"
|
||||
)
|
||||
|
||||
device = device_registry.async_get(entry.device_id)
|
||||
|
|
|
@ -38,6 +38,14 @@ def create_valve_service(accessory):
|
|||
remaining.value = 99
|
||||
|
||||
|
||||
def create_char_switch_service(accessory):
|
||||
"""Define swtch characteristics."""
|
||||
service = accessory.add_service(ServicesTypes.OUTLET)
|
||||
|
||||
on_char = service.add_char(CharacteristicsTypes.Vendor.AQARA_PAIRING_MODE)
|
||||
on_char.value = False
|
||||
|
||||
|
||||
async def test_switch_change_outlet_state(hass, utcnow):
|
||||
"""Test that we can turn a HomeKit outlet on and off again."""
|
||||
helper = await setup_test_component(hass, create_switch_service)
|
||||
|
@ -122,3 +130,51 @@ async def test_valve_read_state(hass, utcnow):
|
|||
helper.characteristics[("valve", "in-use")].value = InUseValues.NOT_IN_USE
|
||||
switch_1 = await helper.poll_and_get_state()
|
||||
assert switch_1.attributes["in_use"] is False
|
||||
|
||||
|
||||
async def test_char_switch_change_state(hass, utcnow):
|
||||
"""Test that we can turn a characteristic on and off again."""
|
||||
helper = await setup_test_component(
|
||||
hass, create_char_switch_service, suffix="pairing_mode"
|
||||
)
|
||||
svc = helper.accessory.services.first(service_type=ServicesTypes.OUTLET)
|
||||
pairing_mode = svc[CharacteristicsTypes.Vendor.AQARA_PAIRING_MODE]
|
||||
|
||||
await hass.services.async_call(
|
||||
"switch",
|
||||
"turn_on",
|
||||
{"entity_id": "switch.testdevice_pairing_mode"},
|
||||
blocking=True,
|
||||
)
|
||||
assert pairing_mode.value is True
|
||||
|
||||
await hass.services.async_call(
|
||||
"switch",
|
||||
"turn_off",
|
||||
{"entity_id": "switch.testdevice_pairing_mode"},
|
||||
blocking=True,
|
||||
)
|
||||
assert pairing_mode.value is False
|
||||
|
||||
|
||||
async def test_char_switch_read_state(hass, utcnow):
|
||||
"""Test that we can read the state of a HomeKit characteristic switch."""
|
||||
helper = await setup_test_component(
|
||||
hass, create_char_switch_service, suffix="pairing_mode"
|
||||
)
|
||||
svc = helper.accessory.services.first(service_type=ServicesTypes.OUTLET)
|
||||
pairing_mode = svc[CharacteristicsTypes.Vendor.AQARA_PAIRING_MODE]
|
||||
|
||||
# Initial state is that the switch is off
|
||||
switch_1 = await helper.poll_and_get_state()
|
||||
assert switch_1.state == "off"
|
||||
|
||||
# Simulate that someone switched on the device in the real world not via HA
|
||||
pairing_mode.set_value(True)
|
||||
switch_1 = await helper.poll_and_get_state()
|
||||
assert switch_1.state == "on"
|
||||
|
||||
# Simulate that device switched off in the real world not via HA
|
||||
pairing_mode.set_value(False)
|
||||
switch_1 = await helper.poll_and_get_state()
|
||||
assert switch_1.state == "off"
|
||||
|
|
Loading…
Add table
Reference in a new issue