mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Add a Thread network status sensor to homekit_controller (#76209)
This commit is contained in:
parent
d5695a2d86
commit
aa3097a3be
@ -5,7 +5,7 @@ from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
|
||||
from aiohomekit.model.characteristics import Characteristic, CharacteristicsTypes
|
||||
from aiohomekit.model.characteristics.const import ThreadNodeCapabilities
|
||||
from aiohomekit.model.characteristics.const import ThreadNodeCapabilities, ThreadStatus
|
||||
from aiohomekit.model.services import Service, ServicesTypes
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
@ -83,6 +83,54 @@ def thread_node_capability_to_str(char: Characteristic) -> str:
|
||||
return "none"
|
||||
|
||||
|
||||
def thread_status_to_str(char: Characteristic) -> str:
|
||||
"""
|
||||
Return the thread status as a string.
|
||||
|
||||
The underlying value is a bitmask, but we want to turn that to
|
||||
a human readable string. So we check the flags in order. E.g. BORDER_ROUTER implies
|
||||
ROUTER, so its more important to show that value.
|
||||
"""
|
||||
|
||||
val = ThreadStatus(char.value)
|
||||
|
||||
if val & ThreadStatus.BORDER_ROUTER:
|
||||
# Device has joined the Thread network and is participating
|
||||
# in routing between mesh nodes.
|
||||
# It's also the border router - bridging the thread network
|
||||
# to WiFI/Ethernet/etc
|
||||
return "border_router"
|
||||
|
||||
if val & ThreadStatus.LEADER:
|
||||
# Device has joined the Thread network and is participating
|
||||
# in routing between mesh nodes.
|
||||
# It's also the leader. There's only one leader and it manages
|
||||
# which nodes are routers.
|
||||
return "leader"
|
||||
|
||||
if val & ThreadStatus.ROUTER:
|
||||
# Device has joined the Thread network and is participating
|
||||
# in routing between mesh nodes.
|
||||
return "router"
|
||||
|
||||
if val & ThreadStatus.CHILD:
|
||||
# Device has joined the Thread network as a child
|
||||
# It's not participating in routing between mesh nodes
|
||||
return "child"
|
||||
|
||||
if val & ThreadStatus.JOINING:
|
||||
# Device is currently joining its Thread network
|
||||
return "joining"
|
||||
|
||||
if val & ThreadStatus.DETACHED:
|
||||
# Device is currently unable to reach its Thread network
|
||||
return "detached"
|
||||
|
||||
# Must be ThreadStatus.DISABLED
|
||||
# Device is not currently connected to Thread and will not try to.
|
||||
return "disabled"
|
||||
|
||||
|
||||
SIMPLE_SENSOR: dict[str, HomeKitSensorEntityDescription] = {
|
||||
CharacteristicsTypes.VENDOR_CONNECTSENSE_ENERGY_WATT: HomeKitSensorEntityDescription(
|
||||
key=CharacteristicsTypes.VENDOR_CONNECTSENSE_ENERGY_WATT,
|
||||
@ -243,6 +291,13 @@ SIMPLE_SENSOR: dict[str, HomeKitSensorEntityDescription] = {
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
format=thread_node_capability_to_str,
|
||||
),
|
||||
CharacteristicsTypes.THREAD_STATUS: HomeKitSensorEntityDescription(
|
||||
key=CharacteristicsTypes.THREAD_STATUS,
|
||||
name="Thread Status",
|
||||
device_class="homekit_controller__thread_status",
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
format=thread_status_to_str,
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
|
@ -7,6 +7,15 @@
|
||||
"minimal": "Minimal End Device",
|
||||
"sleepy": "Sleepy End Device",
|
||||
"none": "None"
|
||||
},
|
||||
"homekit_controller__thread_status": {
|
||||
"border_router": "Border Router",
|
||||
"leader": "Leader",
|
||||
"router": "Router",
|
||||
"child": "Child",
|
||||
"joining": "Joining",
|
||||
"detached": "Detached",
|
||||
"disabled": "Disabled"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,15 @@
|
||||
"none": "None",
|
||||
"router_eligible": "Router Eligible End Device",
|
||||
"sleepy": "Sleepy End Device"
|
||||
},
|
||||
"homekit_controller__thread_status": {
|
||||
"border_router": "Border Router",
|
||||
"child": "Child",
|
||||
"detached": "Detached",
|
||||
"disabled": "Disabled",
|
||||
"joining": "Joining",
|
||||
"leader": "Leader",
|
||||
"router": "Router"
|
||||
}
|
||||
}
|
||||
}
|
@ -57,6 +57,13 @@ async def test_nanoleaf_nl55_setup(hass):
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
state="border_router_capable",
|
||||
),
|
||||
EntityTestInfo(
|
||||
entity_id="sensor.nanoleaf_strip_3b32_thread_status",
|
||||
friendly_name="Nanoleaf Strip 3B32 Thread Status",
|
||||
unique_id="homekit-AAAA011111111111-aid:1-sid:31-cid:117",
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
state="border_router",
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""Basic checks for HomeKit sensor."""
|
||||
from aiohomekit.model.characteristics import CharacteristicsTypes
|
||||
from aiohomekit.model.characteristics.const import ThreadNodeCapabilities
|
||||
from aiohomekit.model.characteristics.const import ThreadNodeCapabilities, ThreadStatus
|
||||
from aiohomekit.model.services import ServicesTypes
|
||||
from aiohomekit.protocol.statuscodes import HapStatusCode
|
||||
|
||||
from homeassistant.components.homekit_controller.sensor import (
|
||||
thread_node_capability_to_str,
|
||||
thread_status_to_str,
|
||||
)
|
||||
from homeassistant.components.sensor import SensorDeviceClass, SensorStateClass
|
||||
|
||||
@ -337,3 +338,14 @@ def test_thread_node_caps_to_str():
|
||||
assert thread_node_capability_to_str(ThreadNodeCapabilities.MINIMAL) == "minimal"
|
||||
assert thread_node_capability_to_str(ThreadNodeCapabilities.SLEEPY) == "sleepy"
|
||||
assert thread_node_capability_to_str(ThreadNodeCapabilities(128)) == "none"
|
||||
|
||||
|
||||
def test_thread_status_to_str():
|
||||
"""Test all values of this enum get a translatable string."""
|
||||
assert thread_status_to_str(ThreadStatus.BORDER_ROUTER) == "border_router"
|
||||
assert thread_status_to_str(ThreadStatus.LEADER) == "leader"
|
||||
assert thread_status_to_str(ThreadStatus.ROUTER) == "router"
|
||||
assert thread_status_to_str(ThreadStatus.CHILD) == "child"
|
||||
assert thread_status_to_str(ThreadStatus.JOINING) == "joining"
|
||||
assert thread_status_to_str(ThreadStatus.DETACHED) == "detached"
|
||||
assert thread_status_to_str(ThreadStatus.DISABLED) == "disabled"
|
||||
|
Loading…
x
Reference in New Issue
Block a user