Add Hyperion sensor to report active priority on each instance (#102333)
* Implement code review comments * Update homeassistant/components/hyperion/sensor.py --------- Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
parent
0134715e2b
commit
58d0420a6b
6 changed files with 408 additions and 1 deletions
|
@ -32,7 +32,7 @@ from .const import (
|
||||||
SIGNAL_INSTANCE_REMOVE,
|
SIGNAL_INSTANCE_REMOVE,
|
||||||
)
|
)
|
||||||
|
|
||||||
PLATFORMS = [Platform.CAMERA, Platform.LIGHT, Platform.SWITCH]
|
PLATFORMS = [Platform.CAMERA, Platform.LIGHT, Platform.SENSOR, Platform.SWITCH]
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -28,3 +28,6 @@ SIGNAL_ENTITY_REMOVE = f"{DOMAIN}_entity_remove_signal.{{}}"
|
||||||
TYPE_HYPERION_CAMERA = "hyperion_camera"
|
TYPE_HYPERION_CAMERA = "hyperion_camera"
|
||||||
TYPE_HYPERION_LIGHT = "hyperion_light"
|
TYPE_HYPERION_LIGHT = "hyperion_light"
|
||||||
TYPE_HYPERION_COMPONENT_SWITCH_BASE = "hyperion_component_switch"
|
TYPE_HYPERION_COMPONENT_SWITCH_BASE = "hyperion_component_switch"
|
||||||
|
|
||||||
|
TYPE_HYPERION_SENSOR_BASE = "hyperion_sensor"
|
||||||
|
TYPE_HYPERION_SENSOR_VISIBLE_PRIORITY = "visible_priority"
|
||||||
|
|
210
homeassistant/components/hyperion/sensor.py
Normal file
210
homeassistant/components/hyperion/sensor.py
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|
"""Sensor platform for Hyperion."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import functools
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from hyperion import client
|
||||||
|
from hyperion.const import (
|
||||||
|
KEY_COMPONENTID,
|
||||||
|
KEY_ORIGIN,
|
||||||
|
KEY_OWNER,
|
||||||
|
KEY_PRIORITIES,
|
||||||
|
KEY_PRIORITY,
|
||||||
|
KEY_RGB,
|
||||||
|
KEY_UPDATE,
|
||||||
|
KEY_VALUE,
|
||||||
|
KEY_VISIBLE,
|
||||||
|
)
|
||||||
|
|
||||||
|
from homeassistant.components.sensor import SensorEntity, SensorEntityDescription
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.core import HomeAssistant, callback
|
||||||
|
from homeassistant.helpers.device_registry import DeviceInfo
|
||||||
|
from homeassistant.helpers.dispatcher import (
|
||||||
|
async_dispatcher_connect,
|
||||||
|
async_dispatcher_send,
|
||||||
|
)
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
|
from . import (
|
||||||
|
get_hyperion_device_id,
|
||||||
|
get_hyperion_unique_id,
|
||||||
|
listen_for_instance_updates,
|
||||||
|
)
|
||||||
|
from .const import (
|
||||||
|
CONF_INSTANCE_CLIENTS,
|
||||||
|
DOMAIN,
|
||||||
|
HYPERION_MANUFACTURER_NAME,
|
||||||
|
HYPERION_MODEL_NAME,
|
||||||
|
SIGNAL_ENTITY_REMOVE,
|
||||||
|
TYPE_HYPERION_SENSOR_BASE,
|
||||||
|
TYPE_HYPERION_SENSOR_VISIBLE_PRIORITY,
|
||||||
|
)
|
||||||
|
|
||||||
|
SENSORS = [TYPE_HYPERION_SENSOR_VISIBLE_PRIORITY]
|
||||||
|
PRIORITY_SENSOR_DESCRIPTION = SensorEntityDescription(
|
||||||
|
key="visible_priority",
|
||||||
|
translation_key="visible_priority",
|
||||||
|
icon="mdi:lava-lamp",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _sensor_unique_id(server_id: str, instance_num: int, suffix: str) -> str:
|
||||||
|
"""Calculate a sensor's unique_id."""
|
||||||
|
return get_hyperion_unique_id(
|
||||||
|
server_id,
|
||||||
|
instance_num,
|
||||||
|
f"{TYPE_HYPERION_SENSOR_BASE}_{suffix}",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up a Hyperion platform from config entry."""
|
||||||
|
entry_data = hass.data[DOMAIN][config_entry.entry_id]
|
||||||
|
server_id = config_entry.unique_id
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def instance_add(instance_num: int, instance_name: str) -> None:
|
||||||
|
"""Add entities for a new Hyperion instance."""
|
||||||
|
assert server_id
|
||||||
|
sensors = [
|
||||||
|
HyperionVisiblePrioritySensor(
|
||||||
|
server_id,
|
||||||
|
instance_num,
|
||||||
|
instance_name,
|
||||||
|
entry_data[CONF_INSTANCE_CLIENTS][instance_num],
|
||||||
|
PRIORITY_SENSOR_DESCRIPTION,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
async_add_entities(sensors)
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def instance_remove(instance_num: int) -> None:
|
||||||
|
"""Remove entities for an old Hyperion instance."""
|
||||||
|
assert server_id
|
||||||
|
|
||||||
|
for sensor in SENSORS:
|
||||||
|
async_dispatcher_send(
|
||||||
|
hass,
|
||||||
|
SIGNAL_ENTITY_REMOVE.format(
|
||||||
|
_sensor_unique_id(server_id, instance_num, sensor),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
listen_for_instance_updates(hass, config_entry, instance_add, instance_remove)
|
||||||
|
|
||||||
|
|
||||||
|
class HyperionSensor(SensorEntity):
|
||||||
|
"""Sensor class."""
|
||||||
|
|
||||||
|
_attr_has_entity_name = True
|
||||||
|
_attr_should_poll = False
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
server_id: str,
|
||||||
|
instance_num: int,
|
||||||
|
instance_name: str,
|
||||||
|
hyperion_client: client.HyperionClient,
|
||||||
|
entity_description: SensorEntityDescription,
|
||||||
|
) -> None:
|
||||||
|
"""Initialize the sensor."""
|
||||||
|
self.entity_description = entity_description
|
||||||
|
self._client = hyperion_client
|
||||||
|
self._attr_native_value = None
|
||||||
|
self._client_callbacks: dict[str, Any] = {}
|
||||||
|
|
||||||
|
device_id = get_hyperion_device_id(server_id, instance_num)
|
||||||
|
|
||||||
|
self._attr_device_info = DeviceInfo(
|
||||||
|
identifiers={(DOMAIN, device_id)},
|
||||||
|
manufacturer=HYPERION_MANUFACTURER_NAME,
|
||||||
|
model=HYPERION_MODEL_NAME,
|
||||||
|
name=instance_name,
|
||||||
|
configuration_url=self._client.remote_url,
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available(self) -> bool:
|
||||||
|
"""Return server availability."""
|
||||||
|
return bool(self._client.has_loaded_state)
|
||||||
|
|
||||||
|
async def async_added_to_hass(self) -> None:
|
||||||
|
"""Register callbacks when entity added to hass."""
|
||||||
|
self.async_on_remove(
|
||||||
|
async_dispatcher_connect(
|
||||||
|
self.hass,
|
||||||
|
SIGNAL_ENTITY_REMOVE.format(self._attr_unique_id),
|
||||||
|
functools.partial(self.async_remove, force_remove=True),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self._client.add_callbacks(self._client_callbacks)
|
||||||
|
|
||||||
|
async def async_will_remove_from_hass(self) -> None:
|
||||||
|
"""Cleanup prior to hass removal."""
|
||||||
|
self._client.remove_callbacks(self._client_callbacks)
|
||||||
|
|
||||||
|
|
||||||
|
class HyperionVisiblePrioritySensor(HyperionSensor):
|
||||||
|
"""Class that displays the visible priority of a Hyperion instance."""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
server_id: str,
|
||||||
|
instance_num: int,
|
||||||
|
instance_name: str,
|
||||||
|
hyperion_client: client.HyperionClient,
|
||||||
|
entity_description: SensorEntityDescription,
|
||||||
|
) -> None:
|
||||||
|
"""Initialize the sensor."""
|
||||||
|
|
||||||
|
super().__init__(
|
||||||
|
server_id, instance_num, instance_name, hyperion_client, entity_description
|
||||||
|
)
|
||||||
|
|
||||||
|
self._attr_unique_id = _sensor_unique_id(
|
||||||
|
server_id, instance_num, TYPE_HYPERION_SENSOR_VISIBLE_PRIORITY
|
||||||
|
)
|
||||||
|
|
||||||
|
self._client_callbacks = {
|
||||||
|
f"{KEY_PRIORITIES}-{KEY_UPDATE}": self._update_priorities
|
||||||
|
}
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _update_priorities(self, _: dict[str, Any] | None = None) -> None:
|
||||||
|
"""Update Hyperion priorities."""
|
||||||
|
state_value = None
|
||||||
|
attrs = {}
|
||||||
|
|
||||||
|
for priority in self._client.priorities or []:
|
||||||
|
if not (KEY_VISIBLE in priority and priority[KEY_VISIBLE] is True):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if priority[KEY_COMPONENTID] == "COLOR":
|
||||||
|
state_value = priority[KEY_VALUE][KEY_RGB]
|
||||||
|
else:
|
||||||
|
state_value = priority[KEY_OWNER]
|
||||||
|
|
||||||
|
attrs = {
|
||||||
|
"component_id": priority[KEY_COMPONENTID],
|
||||||
|
"origin": priority[KEY_ORIGIN],
|
||||||
|
"priority": priority[KEY_PRIORITY],
|
||||||
|
"owner": priority[KEY_OWNER],
|
||||||
|
}
|
||||||
|
|
||||||
|
if priority[KEY_COMPONENTID] == "COLOR":
|
||||||
|
attrs["color"] = priority[KEY_VALUE]
|
||||||
|
else:
|
||||||
|
attrs["color"] = None
|
||||||
|
|
||||||
|
self._attr_native_value = state_value
|
||||||
|
self._attr_extra_state_attributes = attrs
|
||||||
|
|
||||||
|
self.async_write_ha_state()
|
|
@ -80,6 +80,11 @@
|
||||||
"usb_capture": {
|
"usb_capture": {
|
||||||
"name": "Component USB capture"
|
"name": "Component USB capture"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"sensor": {
|
||||||
|
"visible_priority": {
|
||||||
|
"name": "Visible priority"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -338,6 +338,7 @@ async def test_light_async_turn_on(hass: HomeAssistant) -> None:
|
||||||
const.KEY_PRIORITY: TEST_PRIORITY,
|
const.KEY_PRIORITY: TEST_PRIORITY,
|
||||||
const.KEY_COMPONENTID: const.KEY_COMPONENTID_COLOR,
|
const.KEY_COMPONENTID: const.KEY_COMPONENTID_COLOR,
|
||||||
const.KEY_VALUE: {const.KEY_RGB: (0, 255, 255)},
|
const.KEY_VALUE: {const.KEY_RGB: (0, 255, 255)},
|
||||||
|
const.KEY_OWNER: "System",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -432,6 +433,7 @@ async def test_light_async_turn_on(hass: HomeAssistant) -> None:
|
||||||
const.KEY_PRIORITY: TEST_PRIORITY,
|
const.KEY_PRIORITY: TEST_PRIORITY,
|
||||||
const.KEY_COMPONENTID: const.KEY_COMPONENTID_COLOR,
|
const.KEY_COMPONENTID: const.KEY_COMPONENTID_COLOR,
|
||||||
const.KEY_VALUE: {const.KEY_RGB: (0, 0, 255)},
|
const.KEY_VALUE: {const.KEY_RGB: (0, 0, 255)},
|
||||||
|
const.KEY_OWNER: "System",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
call_registered_callback(client, "priorities-update")
|
call_registered_callback(client, "priorities-update")
|
||||||
|
@ -564,6 +566,8 @@ async def test_light_async_updates_from_hyperion_client(
|
||||||
const.KEY_PRIORITY: TEST_PRIORITY,
|
const.KEY_PRIORITY: TEST_PRIORITY,
|
||||||
const.KEY_COMPONENTID: const.KEY_COMPONENTID_EFFECT,
|
const.KEY_COMPONENTID: const.KEY_COMPONENTID_EFFECT,
|
||||||
const.KEY_OWNER: effect,
|
const.KEY_OWNER: effect,
|
||||||
|
const.KEY_VISIBLE: True,
|
||||||
|
const.KEY_ORIGIN: "System",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -581,6 +585,9 @@ async def test_light_async_updates_from_hyperion_client(
|
||||||
const.KEY_PRIORITY: TEST_PRIORITY,
|
const.KEY_PRIORITY: TEST_PRIORITY,
|
||||||
const.KEY_COMPONENTID: const.KEY_COMPONENTID_COLOR,
|
const.KEY_COMPONENTID: const.KEY_COMPONENTID_COLOR,
|
||||||
const.KEY_VALUE: {const.KEY_RGB: rgb},
|
const.KEY_VALUE: {const.KEY_RGB: rgb},
|
||||||
|
const.KEY_VISIBLE: True,
|
||||||
|
const.KEY_ORIGIN: "System",
|
||||||
|
const.KEY_OWNER: "System",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -625,6 +632,9 @@ async def test_light_async_updates_from_hyperion_client(
|
||||||
const.KEY_PRIORITY: TEST_PRIORITY,
|
const.KEY_PRIORITY: TEST_PRIORITY,
|
||||||
const.KEY_COMPONENTID: const.KEY_COMPONENTID_COLOR,
|
const.KEY_COMPONENTID: const.KEY_COMPONENTID_COLOR,
|
||||||
const.KEY_VALUE: {const.KEY_RGB: rgb},
|
const.KEY_VALUE: {const.KEY_RGB: rgb},
|
||||||
|
const.KEY_VISIBLE: True,
|
||||||
|
const.KEY_ORIGIN: "System",
|
||||||
|
const.KEY_OWNER: "System",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
call_registered_callback(client, "client-update", {"loaded-state": True})
|
call_registered_callback(client, "client-update", {"loaded-state": True})
|
||||||
|
@ -645,6 +655,7 @@ async def test_full_state_loaded_on_start(hass: HomeAssistant) -> None:
|
||||||
const.KEY_PRIORITY: TEST_PRIORITY,
|
const.KEY_PRIORITY: TEST_PRIORITY,
|
||||||
const.KEY_COMPONENTID: const.KEY_COMPONENTID_COLOR,
|
const.KEY_COMPONENTID: const.KEY_COMPONENTID_COLOR,
|
||||||
const.KEY_VALUE: {const.KEY_RGB: (0, 100, 100)},
|
const.KEY_VALUE: {const.KEY_RGB: (0, 100, 100)},
|
||||||
|
const.KEY_OWNER: "System",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
client.effects = [{const.KEY_NAME: "One"}, {const.KEY_NAME: "Two"}]
|
client.effects = [{const.KEY_NAME: "One"}, {const.KEY_NAME: "Two"}]
|
||||||
|
|
178
tests/components/hyperion/test_sensor.py
Normal file
178
tests/components/hyperion/test_sensor.py
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
"""Tests for the Hyperion integration."""
|
||||||
|
|
||||||
|
from hyperion.const import (
|
||||||
|
KEY_ACTIVE,
|
||||||
|
KEY_COMPONENTID,
|
||||||
|
KEY_ORIGIN,
|
||||||
|
KEY_OWNER,
|
||||||
|
KEY_PRIORITY,
|
||||||
|
KEY_RGB,
|
||||||
|
KEY_VALUE,
|
||||||
|
KEY_VISIBLE,
|
||||||
|
)
|
||||||
|
|
||||||
|
from homeassistant.components.hyperion import get_hyperion_device_id
|
||||||
|
from homeassistant.components.hyperion.const import (
|
||||||
|
DOMAIN,
|
||||||
|
HYPERION_MANUFACTURER_NAME,
|
||||||
|
HYPERION_MODEL_NAME,
|
||||||
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||||
|
from homeassistant.util import slugify
|
||||||
|
|
||||||
|
from . import (
|
||||||
|
TEST_CONFIG_ENTRY_ID,
|
||||||
|
TEST_INSTANCE,
|
||||||
|
TEST_INSTANCE_1,
|
||||||
|
TEST_SYSINFO_ID,
|
||||||
|
call_registered_callback,
|
||||||
|
create_mock_client,
|
||||||
|
setup_test_config_entry,
|
||||||
|
)
|
||||||
|
|
||||||
|
TEST_COMPONENTS = [
|
||||||
|
{"enabled": True, "name": "VISIBLE_PRIORITY"},
|
||||||
|
]
|
||||||
|
|
||||||
|
TEST_SENSOR_BASE_ENTITY_ID = "sensor.test_instance_1"
|
||||||
|
TEST_VISIBLE_EFFECT_SENSOR_ID = "sensor.test_instance_1_visible_priority"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_sensor_has_correct_entities(hass: HomeAssistant) -> None:
|
||||||
|
"""Test that the correct sensor entities are created."""
|
||||||
|
client = create_mock_client()
|
||||||
|
client.components = TEST_COMPONENTS
|
||||||
|
await setup_test_config_entry(hass, hyperion_client=client)
|
||||||
|
|
||||||
|
for component in TEST_COMPONENTS:
|
||||||
|
name = slugify(component["name"])
|
||||||
|
entity_id = f"{TEST_SENSOR_BASE_ENTITY_ID}_{name}"
|
||||||
|
entity_state = hass.states.get(entity_id)
|
||||||
|
assert entity_state, f"Couldn't find entity: {entity_id}"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_device_info(hass: HomeAssistant) -> None:
|
||||||
|
"""Verify device information includes expected details."""
|
||||||
|
client = create_mock_client()
|
||||||
|
client.components = TEST_COMPONENTS
|
||||||
|
await setup_test_config_entry(hass, hyperion_client=client)
|
||||||
|
|
||||||
|
device_identifer = get_hyperion_device_id(TEST_SYSINFO_ID, TEST_INSTANCE)
|
||||||
|
device_registry = dr.async_get(hass)
|
||||||
|
|
||||||
|
device = device_registry.async_get_device(identifiers={(DOMAIN, device_identifer)})
|
||||||
|
assert device
|
||||||
|
assert device.config_entries == {TEST_CONFIG_ENTRY_ID}
|
||||||
|
assert device.identifiers == {(DOMAIN, device_identifer)}
|
||||||
|
assert device.manufacturer == HYPERION_MANUFACTURER_NAME
|
||||||
|
assert device.model == HYPERION_MODEL_NAME
|
||||||
|
assert device.name == TEST_INSTANCE_1["friendly_name"]
|
||||||
|
|
||||||
|
entity_registry = er.async_get(hass)
|
||||||
|
entities_from_device = [
|
||||||
|
entry.entity_id
|
||||||
|
for entry in er.async_entries_for_device(entity_registry, device.id)
|
||||||
|
]
|
||||||
|
|
||||||
|
for component in TEST_COMPONENTS:
|
||||||
|
name = slugify(component["name"])
|
||||||
|
entity_id = TEST_SENSOR_BASE_ENTITY_ID + "_" + name
|
||||||
|
assert entity_id in entities_from_device
|
||||||
|
|
||||||
|
|
||||||
|
async def test_visible_effect_state_changes(hass: HomeAssistant) -> None:
|
||||||
|
"""Verify that state changes are processed as expected for visible effect sensor."""
|
||||||
|
client = create_mock_client()
|
||||||
|
client.components = TEST_COMPONENTS
|
||||||
|
await setup_test_config_entry(hass, hyperion_client=client)
|
||||||
|
|
||||||
|
# Simulate a platform grabber effect state callback from Hyperion.
|
||||||
|
client.priorities = [
|
||||||
|
{
|
||||||
|
KEY_ACTIVE: True,
|
||||||
|
KEY_COMPONENTID: "GRABBER",
|
||||||
|
KEY_ORIGIN: "System",
|
||||||
|
KEY_OWNER: "X11",
|
||||||
|
KEY_PRIORITY: 250,
|
||||||
|
KEY_VISIBLE: True,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
call_registered_callback(client, "priorities-update")
|
||||||
|
entity_state = hass.states.get(TEST_VISIBLE_EFFECT_SENSOR_ID)
|
||||||
|
assert entity_state
|
||||||
|
assert entity_state.state == client.priorities[0][KEY_OWNER]
|
||||||
|
assert (
|
||||||
|
entity_state.attributes["component_id"] == client.priorities[0][KEY_COMPONENTID]
|
||||||
|
)
|
||||||
|
assert entity_state.attributes["origin"] == client.priorities[0][KEY_ORIGIN]
|
||||||
|
assert entity_state.attributes["priority"] == client.priorities[0][KEY_PRIORITY]
|
||||||
|
|
||||||
|
# Simulate an effect state callback from Hyperion.
|
||||||
|
client.priorities = [
|
||||||
|
{
|
||||||
|
KEY_ACTIVE: True,
|
||||||
|
KEY_COMPONENTID: "EFFECT",
|
||||||
|
KEY_ORIGIN: "System",
|
||||||
|
KEY_OWNER: "Warm mood blobs",
|
||||||
|
KEY_PRIORITY: 250,
|
||||||
|
KEY_VISIBLE: True,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
call_registered_callback(client, "priorities-update")
|
||||||
|
entity_state = hass.states.get(TEST_VISIBLE_EFFECT_SENSOR_ID)
|
||||||
|
assert entity_state
|
||||||
|
assert entity_state.state == client.priorities[0][KEY_OWNER]
|
||||||
|
assert (
|
||||||
|
entity_state.attributes["component_id"] == client.priorities[0][KEY_COMPONENTID]
|
||||||
|
)
|
||||||
|
assert entity_state.attributes["origin"] == client.priorities[0][KEY_ORIGIN]
|
||||||
|
assert entity_state.attributes["priority"] == client.priorities[0][KEY_PRIORITY]
|
||||||
|
|
||||||
|
# Simulate a USB Capture state callback from Hyperion.
|
||||||
|
client.priorities = [
|
||||||
|
{
|
||||||
|
KEY_ACTIVE: True,
|
||||||
|
KEY_COMPONENTID: "V4L",
|
||||||
|
KEY_ORIGIN: "System",
|
||||||
|
KEY_OWNER: "V4L2",
|
||||||
|
KEY_PRIORITY: 250,
|
||||||
|
KEY_VISIBLE: True,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
call_registered_callback(client, "priorities-update")
|
||||||
|
entity_state = hass.states.get(TEST_VISIBLE_EFFECT_SENSOR_ID)
|
||||||
|
assert entity_state
|
||||||
|
assert entity_state.state == client.priorities[0][KEY_OWNER]
|
||||||
|
assert (
|
||||||
|
entity_state.attributes["component_id"] == client.priorities[0][KEY_COMPONENTID]
|
||||||
|
)
|
||||||
|
assert entity_state.attributes["origin"] == client.priorities[0][KEY_ORIGIN]
|
||||||
|
assert entity_state.attributes["priority"] == client.priorities[0][KEY_PRIORITY]
|
||||||
|
|
||||||
|
# Simulate a color effect state callback from Hyperion.
|
||||||
|
client.priorities = [
|
||||||
|
{
|
||||||
|
KEY_ACTIVE: True,
|
||||||
|
KEY_COMPONENTID: "COLOR",
|
||||||
|
KEY_ORIGIN: "System",
|
||||||
|
KEY_OWNER: "System",
|
||||||
|
KEY_PRIORITY: 250,
|
||||||
|
KEY_VALUE: {KEY_RGB: [0, 0, 0]},
|
||||||
|
KEY_VISIBLE: True,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
call_registered_callback(client, "priorities-update")
|
||||||
|
entity_state = hass.states.get(TEST_VISIBLE_EFFECT_SENSOR_ID)
|
||||||
|
assert entity_state
|
||||||
|
assert entity_state.state == str(client.priorities[0][KEY_VALUE][KEY_RGB])
|
||||||
|
assert (
|
||||||
|
entity_state.attributes["component_id"] == client.priorities[0][KEY_COMPONENTID]
|
||||||
|
)
|
||||||
|
assert entity_state.attributes["origin"] == client.priorities[0][KEY_ORIGIN]
|
||||||
|
assert entity_state.attributes["priority"] == client.priorities[0][KEY_PRIORITY]
|
||||||
|
assert entity_state.attributes["color"] == client.priorities[0][KEY_VALUE]
|
Loading…
Add table
Add a link
Reference in a new issue