mirror of
https://github.com/home-assistant/core.git
synced 2026-09-26 09:23:17 -04:00
Add brightness_pct beside brightness in the LLM live context (#182571)
This commit is contained in:
@@ -7,6 +7,7 @@ from typing import Any, override
|
||||
|
||||
import probatio
|
||||
|
||||
from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
|
||||
from homeassistant.components.llm import LLMTools
|
||||
from homeassistant.components.sensor import (
|
||||
DOMAIN as SENSOR_DOMAIN,
|
||||
@@ -172,6 +173,14 @@ def async_get_exposed_entities(
|
||||
if attr_name in interesting_attributes
|
||||
}
|
||||
):
|
||||
# Tools take brightness as a 0-100 percentage; the attribute is 0-255.
|
||||
if state.domain == LIGHT_DOMAIN and isinstance(
|
||||
brightness := state.attributes.get("brightness"), int
|
||||
):
|
||||
pct = round(brightness / 255 * 100)
|
||||
attributes["brightness_pct"] = str(
|
||||
max(pct, 1) if brightness > 0 else pct
|
||||
)
|
||||
info["attributes"] = attributes
|
||||
|
||||
entities[state.entity_id] = info
|
||||
|
||||
@@ -412,3 +412,45 @@ async def test_get_live_context_schema(
|
||||
schema = to_openapi(tool.parameters, custom_serializer=api.custom_serializer)
|
||||
|
||||
assert schema == snapshot
|
||||
|
||||
|
||||
async def test_get_exposed_entities_brightness_percentage(hass: HomeAssistant) -> None:
|
||||
"""Test that a light's brightness is also rendered as a percentage."""
|
||||
hass.states.async_set(
|
||||
ENTITY_ID, "on", {"friendly_name": "Kitchen Light", "brightness": 128}
|
||||
)
|
||||
async_expose_entity(hass, "conversation", ENTITY_ID, True)
|
||||
|
||||
exposed = async_get_exposed_entities(hass, "conversation", include_state=True)
|
||||
attributes = exposed[ENTITY_ID]["attributes"]
|
||||
|
||||
# The raw attribute is unchanged, so anything reading it keeps working.
|
||||
assert attributes["brightness"] == "128"
|
||||
# The percentage is the inverse of the percentage-to-brightness conversion.
|
||||
assert attributes["brightness_pct"] == "50"
|
||||
|
||||
hass.states.async_set(
|
||||
ENTITY_ID, "on", {"friendly_name": "Kitchen Light", "brightness": 255}
|
||||
)
|
||||
exposed = async_get_exposed_entities(hass, "conversation", include_state=True)
|
||||
assert exposed[ENTITY_ID]["attributes"]["brightness_pct"] == "100"
|
||||
|
||||
# A lit light never rounds down to nothing.
|
||||
hass.states.async_set(
|
||||
ENTITY_ID, "on", {"friendly_name": "Kitchen Light", "brightness": 1}
|
||||
)
|
||||
exposed = async_get_exposed_entities(hass, "conversation", include_state=True)
|
||||
assert exposed[ENTITY_ID]["attributes"]["brightness_pct"] == "1"
|
||||
|
||||
hass.states.async_set(ENTITY_ID, "off", {"friendly_name": "Kitchen Light"})
|
||||
exposed = async_get_exposed_entities(hass, "conversation", include_state=True)
|
||||
assert "brightness_pct" not in exposed[ENTITY_ID].get("attributes", {})
|
||||
|
||||
# Only lights get the percentage, whatever attribute another domain carries.
|
||||
hass.states.async_set(
|
||||
"fan.kitchen", "on", {"friendly_name": "Kitchen Fan", "brightness": 128}
|
||||
)
|
||||
async_expose_entity(hass, "conversation", "fan.kitchen", True)
|
||||
exposed = async_get_exposed_entities(hass, "conversation", include_state=True)
|
||||
assert exposed["fan.kitchen"]["attributes"]["brightness"] == "128"
|
||||
assert "brightness_pct" not in exposed["fan.kitchen"]["attributes"]
|
||||
|
||||
Reference in New Issue
Block a user