Add geo_location entity support to Prometheus exporter (#170721)

This commit is contained in:
Dougal Matthews
2026-05-18 12:27:41 +02:00
committed by GitHub
parent 822a567ca9
commit 140fef6915
2 changed files with 96 additions and 1 deletions
@@ -58,6 +58,8 @@ from homeassistant.const import (
ATTR_BATTERY_LEVEL,
ATTR_DEVICE_CLASS,
ATTR_FRIENDLY_NAME,
ATTR_LATITUDE,
ATTR_LONGITUDE,
ATTR_MODE,
ATTR_TEMPERATURE,
ATTR_UNIT_OF_MEASUREMENT,
@@ -71,6 +73,7 @@ from homeassistant.const import (
STATE_OPENING,
STATE_UNAVAILABLE,
STATE_UNKNOWN,
UnitOfLength,
UnitOfTemperature,
)
from homeassistant.core import Event, EventStateChangedData, HomeAssistant, State
@@ -104,7 +107,7 @@ from homeassistant.helpers.floor_registry import (
)
from homeassistant.helpers.typing import ConfigType
from homeassistant.util.dt import as_timestamp
from homeassistant.util.unit_conversion import TemperatureConverter
from homeassistant.util.unit_conversion import DistanceConverter, TemperatureConverter
_LOGGER = logging.getLogger(__name__)
@@ -771,6 +774,33 @@ class PrometheusMetrics:
def _handle_person(self, state: State) -> None:
self._numeric_metric(state, "person", "person")
def _handle_geo_location(self, state: State) -> None:
labels = self._labels(state, {"source": state.attributes.get("source", "")})
if (value := self.state_as_number(state)) is not None:
unit = state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
if unit is not None:
value = DistanceConverter.convert(value, unit, UnitOfLength.METERS)
self._metric(
"geo_location_distance_meters",
prometheus_client.Gauge,
"Distance of the geo location event from home in meters",
labels,
).set(value)
if (latitude := state.attributes.get(ATTR_LATITUDE)) is not None:
self._metric(
"geo_location_latitude_degrees",
prometheus_client.Gauge,
"Latitude of the geo location event in degrees",
labels,
).set(latitude)
if (longitude := state.attributes.get(ATTR_LONGITUDE)) is not None:
self._metric(
"geo_location_longitude_degrees",
prometheus_client.Gauge,
"Longitude of the geo location event in degrees",
labels,
).set(longitude)
def _handle_lock(self, state: State) -> None:
self._numeric_metric(state, "lock", "lock")
+65
View File
@@ -19,6 +19,7 @@ from homeassistant.components import (
cover,
device_tracker,
fan,
geo_location,
humidifier,
input_boolean,
input_number,
@@ -90,6 +91,7 @@ from homeassistant.const import (
STATE_UNAVAILABLE,
STATE_UNKNOWN,
UnitOfEnergy,
UnitOfLength,
UnitOfTemperature,
)
from homeassistant.core import HomeAssistant
@@ -1341,6 +1343,39 @@ async def test_person(
).withValue(0.0).assert_in_metrics(body)
@pytest.mark.parametrize("namespace", [""])
async def test_geo_location(
client: ClientSessionGenerator,
geo_location_entities: dict[str, er.RegistryEntry],
) -> None:
"""Test prometheus metrics for geo_location."""
body = await generate_latest_metrics(client)
EntityMetric(
metric_name="geo_location_distance_meters",
domain="geo_location",
friendly_name="Earthquake",
entity="geo_location.earthquake",
source="usgs_earthquakes",
).withValue(25500.0).assert_in_metrics(body)
EntityMetric(
metric_name="geo_location_latitude_degrees",
domain="geo_location",
friendly_name="Earthquake",
entity="geo_location.earthquake",
source="usgs_earthquakes",
).withValue(34.05).assert_in_metrics(body)
EntityMetric(
metric_name="geo_location_longitude_degrees",
domain="geo_location",
friendly_name="Earthquake",
entity="geo_location.earthquake",
source="usgs_earthquakes",
).withValue(-118.25).assert_in_metrics(body)
@pytest.mark.parametrize("namespace", [""])
async def test_counter(
client: ClientSessionGenerator, counter_entities: dict[str, er.RegistryEntry]
@@ -2756,6 +2791,36 @@ async def device_tracker_fixture(
return data
@pytest.fixture(name="geo_location_entities")
async def geo_location_fixture(
hass: HomeAssistant, entity_registry: er.EntityRegistry
) -> dict[str, er.RegistryEntry]:
"""Simulate geo_location entities."""
data = {}
geo_location_1 = entity_registry.async_get_or_create(
domain=geo_location.DOMAIN,
platform="test",
unique_id="geo_location_1",
suggested_object_id="earthquake",
original_name="Earthquake",
)
set_state_with_entry(
hass,
geo_location_1,
25.5,
{
"source": "usgs_earthquakes",
"latitude": 34.05,
"longitude": -118.25,
"unit_of_measurement": UnitOfLength.KILOMETERS,
},
)
data["geo_location_1"] = geo_location_1
await hass.async_block_till_done()
return data
@pytest.fixture(name="counter_entities")
async def counter_fixture(
hass: HomeAssistant, entity_registry: er.EntityRegistry