mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 08:47:57 +00:00
Add prometheus fan handler (#119805)
Co-authored-by: Anton Tolchanov <1687799+knyar@users.noreply.github.com>
This commit is contained in:
parent
e2141dc208
commit
275a7499b1
@ -26,6 +26,15 @@ from homeassistant.components.cover import (
|
||||
ATTR_CURRENT_POSITION,
|
||||
ATTR_CURRENT_TILT_POSITION,
|
||||
)
|
||||
from homeassistant.components.fan import (
|
||||
ATTR_DIRECTION,
|
||||
ATTR_OSCILLATING,
|
||||
ATTR_PERCENTAGE,
|
||||
ATTR_PRESET_MODE,
|
||||
ATTR_PRESET_MODES,
|
||||
DIRECTION_FORWARD,
|
||||
DIRECTION_REVERSE,
|
||||
)
|
||||
from homeassistant.components.http import KEY_HASS, HomeAssistantView
|
||||
from homeassistant.components.humidifier import ATTR_AVAILABLE_MODES, ATTR_HUMIDITY
|
||||
from homeassistant.components.light import ATTR_BRIGHTNESS
|
||||
@ -684,6 +693,63 @@ class PrometheusMetrics:
|
||||
|
||||
self._handle_attributes(state)
|
||||
|
||||
def _handle_fan(self, state: State) -> None:
|
||||
metric = self._metric(
|
||||
"fan_state", prometheus_client.Gauge, "State of the fan (0/1)"
|
||||
)
|
||||
|
||||
try:
|
||||
value = self.state_as_number(state)
|
||||
metric.labels(**self._labels(state)).set(value)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
fan_speed_percent = state.attributes.get(ATTR_PERCENTAGE)
|
||||
if fan_speed_percent is not None:
|
||||
fan_speed_metric = self._metric(
|
||||
"fan_speed_percent",
|
||||
prometheus_client.Gauge,
|
||||
"Fan speed percent (0-100)",
|
||||
)
|
||||
fan_speed_metric.labels(**self._labels(state)).set(float(fan_speed_percent))
|
||||
|
||||
fan_is_oscillating = state.attributes.get(ATTR_OSCILLATING)
|
||||
if fan_is_oscillating is not None:
|
||||
fan_oscillating_metric = self._metric(
|
||||
"fan_is_oscillating",
|
||||
prometheus_client.Gauge,
|
||||
"Whether the fan is oscillating (0/1)",
|
||||
)
|
||||
fan_oscillating_metric.labels(**self._labels(state)).set(
|
||||
float(fan_is_oscillating)
|
||||
)
|
||||
|
||||
fan_preset_mode = state.attributes.get(ATTR_PRESET_MODE)
|
||||
available_modes = state.attributes.get(ATTR_PRESET_MODES)
|
||||
if fan_preset_mode and available_modes:
|
||||
fan_preset_metric = self._metric(
|
||||
"fan_preset_mode",
|
||||
prometheus_client.Gauge,
|
||||
"Fan preset mode enum",
|
||||
["mode"],
|
||||
)
|
||||
for mode in available_modes:
|
||||
fan_preset_metric.labels(**dict(self._labels(state), mode=mode)).set(
|
||||
float(mode == fan_preset_mode)
|
||||
)
|
||||
|
||||
fan_direction = state.attributes.get(ATTR_DIRECTION)
|
||||
if fan_direction is not None:
|
||||
fan_direction_metric = self._metric(
|
||||
"fan_direction_reversed",
|
||||
prometheus_client.Gauge,
|
||||
"Fan direction reversed (bool)",
|
||||
)
|
||||
if fan_direction == DIRECTION_FORWARD:
|
||||
fan_direction_metric.labels(**self._labels(state)).set(0)
|
||||
elif fan_direction == DIRECTION_REVERSE:
|
||||
fan_direction_metric.labels(**self._labels(state)).set(1)
|
||||
|
||||
def _handle_zwave(self, state: State) -> None:
|
||||
self._battery(state)
|
||||
|
||||
|
@ -16,6 +16,7 @@ from homeassistant.components import (
|
||||
counter,
|
||||
cover,
|
||||
device_tracker,
|
||||
fan,
|
||||
humidifier,
|
||||
input_boolean,
|
||||
input_number,
|
||||
@ -35,6 +36,15 @@ from homeassistant.components.climate import (
|
||||
ATTR_TARGET_TEMP_HIGH,
|
||||
ATTR_TARGET_TEMP_LOW,
|
||||
)
|
||||
from homeassistant.components.fan import (
|
||||
ATTR_DIRECTION,
|
||||
ATTR_OSCILLATING,
|
||||
ATTR_PERCENTAGE,
|
||||
ATTR_PRESET_MODE,
|
||||
ATTR_PRESET_MODES,
|
||||
DIRECTION_FORWARD,
|
||||
DIRECTION_REVERSE,
|
||||
)
|
||||
from homeassistant.components.humidifier import ATTR_AVAILABLE_MODES
|
||||
from homeassistant.components.sensor import SensorDeviceClass
|
||||
from homeassistant.const import (
|
||||
@ -562,6 +572,51 @@ async def test_lock(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("namespace", [""])
|
||||
async def test_fan(
|
||||
client: ClientSessionGenerator, fan_entities: dict[str, er.RegistryEntry]
|
||||
) -> None:
|
||||
"""Test prometheus metrics for fan."""
|
||||
body = await generate_latest_metrics(client)
|
||||
|
||||
assert (
|
||||
'fan_state{domain="fan",'
|
||||
'entity="fan.fan_1",'
|
||||
'friendly_name="Fan 1"} 1.0' in body
|
||||
)
|
||||
|
||||
assert (
|
||||
'fan_speed_percent{domain="fan",'
|
||||
'entity="fan.fan_1",'
|
||||
'friendly_name="Fan 1"} 33.0' in body
|
||||
)
|
||||
|
||||
assert (
|
||||
'fan_is_oscillating{domain="fan",'
|
||||
'entity="fan.fan_1",'
|
||||
'friendly_name="Fan 1"} 1.0' in body
|
||||
)
|
||||
|
||||
assert (
|
||||
'fan_direction_reversed{domain="fan",'
|
||||
'entity="fan.fan_1",'
|
||||
'friendly_name="Fan 1"} 0.0' in body
|
||||
)
|
||||
|
||||
assert (
|
||||
'fan_preset_mode{domain="fan",'
|
||||
'entity="fan.fan_1",'
|
||||
'friendly_name="Fan 1",'
|
||||
'mode="LO"} 1.0' in body
|
||||
)
|
||||
|
||||
assert (
|
||||
'fan_direction_reversed{domain="fan",'
|
||||
'entity="fan.fan_2",'
|
||||
'friendly_name="Reverse Fan"} 1.0' in body
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("namespace", [""])
|
||||
async def test_cover(
|
||||
client: ClientSessionGenerator, cover_entities: dict[str, er.RegistryEntry]
|
||||
@ -1788,6 +1843,46 @@ async def switch_fixture(
|
||||
return data
|
||||
|
||||
|
||||
@pytest.fixture(name="fan_entities")
|
||||
async def fan_fixture(
|
||||
hass: HomeAssistant, entity_registry: er.EntityRegistry
|
||||
) -> dict[str, er.RegistryEntry]:
|
||||
"""Simulate fan entities."""
|
||||
data = {}
|
||||
fan_1 = entity_registry.async_get_or_create(
|
||||
domain=fan.DOMAIN,
|
||||
platform="test",
|
||||
unique_id="fan_1",
|
||||
suggested_object_id="fan_1",
|
||||
original_name="Fan 1",
|
||||
)
|
||||
fan_1_attributes = {
|
||||
ATTR_DIRECTION: DIRECTION_FORWARD,
|
||||
ATTR_OSCILLATING: True,
|
||||
ATTR_PERCENTAGE: 33,
|
||||
ATTR_PRESET_MODE: "LO",
|
||||
ATTR_PRESET_MODES: ["LO", "OFF", "HI"],
|
||||
}
|
||||
set_state_with_entry(hass, fan_1, STATE_ON, fan_1_attributes)
|
||||
data["fan_1"] = fan_1
|
||||
data["fan_1_attributes"] = fan_1_attributes
|
||||
|
||||
fan_2 = entity_registry.async_get_or_create(
|
||||
domain=fan.DOMAIN,
|
||||
platform="test",
|
||||
unique_id="fan_2",
|
||||
suggested_object_id="fan_2",
|
||||
original_name="Reverse Fan",
|
||||
)
|
||||
fan_2_attributes = {ATTR_DIRECTION: DIRECTION_REVERSE}
|
||||
set_state_with_entry(hass, fan_2, STATE_ON, fan_2_attributes)
|
||||
data["fan_2"] = fan_2
|
||||
data["fan_2_attributes"] = fan_2_attributes
|
||||
|
||||
await hass.async_block_till_done()
|
||||
return data
|
||||
|
||||
|
||||
@pytest.fixture(name="person_entities")
|
||||
async def person_fixture(
|
||||
hass: HomeAssistant, entity_registry: er.EntityRegistry
|
||||
|
Loading…
x
Reference in New Issue
Block a user