diff --git a/homeassistant/components/prometheus/__init__.py b/homeassistant/components/prometheus/__init__.py index f7037a685a6..8cc0a8f4b6a 100644 --- a/homeassistant/components/prometheus/__init__.py +++ b/homeassistant/components/prometheus/__init__.py @@ -51,6 +51,16 @@ from homeassistant.const import ( CONTENT_TYPE_TEXT_PLAIN, EVENT_STATE_CHANGED, PERCENTAGE, + STATE_ALARM_ARMED_AWAY, + STATE_ALARM_ARMED_CUSTOM_BYPASS, + STATE_ALARM_ARMED_HOME, + STATE_ALARM_ARMED_NIGHT, + STATE_ALARM_ARMED_VACATION, + STATE_ALARM_ARMING, + STATE_ALARM_DISARMED, + STATE_ALARM_DISARMING, + STATE_ALARM_PENDING, + STATE_ALARM_TRIGGERED, STATE_CLOSED, STATE_CLOSING, STATE_ON, @@ -807,6 +817,35 @@ class PrometheusMetrics: value = self.state_as_number(state) metric.labels(**self._labels(state)).set(value) + def _handle_alarm_control_panel(self, state: State) -> None: + current_state = state.state + + if current_state: + metric = self._metric( + "alarm_control_panel_state", + prometheus_client.Gauge, + "State of the alarm control panel (0/1)", + ["state"], + ) + + alarm_states = [ + STATE_ALARM_ARMED_AWAY, + STATE_ALARM_ARMED_CUSTOM_BYPASS, + STATE_ALARM_ARMED_HOME, + STATE_ALARM_ARMED_NIGHT, + STATE_ALARM_ARMED_VACATION, + STATE_ALARM_DISARMED, + STATE_ALARM_TRIGGERED, + STATE_ALARM_PENDING, + STATE_ALARM_ARMING, + STATE_ALARM_DISARMING, + ] + + for alarm_state in alarm_states: + metric.labels(**dict(self._labels(state), state=alarm_state)).set( + float(alarm_state == current_state) + ) + class PrometheusView(HomeAssistantView): """Handle Prometheus requests.""" diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 12643c39dfa..0dfa3210671 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -11,6 +11,7 @@ import prometheus_client import pytest from homeassistant.components import ( + alarm_control_panel, binary_sensor, climate, counter, @@ -61,6 +62,8 @@ from homeassistant.const import ( CONTENT_TYPE_TEXT_PLAIN, DEGREE, PERCENTAGE, + STATE_ALARM_ARMED_AWAY, + STATE_ALARM_ARMED_HOME, STATE_CLOSED, STATE_CLOSING, STATE_HOME, @@ -632,6 +635,43 @@ async def test_fan( ) +@pytest.mark.parametrize("namespace", [""]) +async def test_alarm_control_panel( + client: ClientSessionGenerator, + alarm_control_panel_entities: dict[str, er.RegistryEntry], +) -> None: + """Test prometheus metrics for alarm control panel.""" + body = await generate_latest_metrics(client) + + assert ( + 'alarm_control_panel_state{domain="alarm_control_panel",' + 'entity="alarm_control_panel.alarm_control_panel_1",' + 'friendly_name="Alarm Control Panel 1",' + 'state="armed_away"} 1.0' in body + ) + + assert ( + 'alarm_control_panel_state{domain="alarm_control_panel",' + 'entity="alarm_control_panel.alarm_control_panel_1",' + 'friendly_name="Alarm Control Panel 1",' + 'state="disarmed"} 0.0' in body + ) + + assert ( + 'alarm_control_panel_state{domain="alarm_control_panel",' + 'entity="alarm_control_panel.alarm_control_panel_2",' + 'friendly_name="Alarm Control Panel 2",' + 'state="armed_home"} 1.0' in body + ) + + assert ( + 'alarm_control_panel_state{domain="alarm_control_panel",' + 'entity="alarm_control_panel.alarm_control_panel_2",' + 'friendly_name="Alarm Control Panel 2",' + 'state="armed_away"} 0.0' in body + ) + + @pytest.mark.parametrize("namespace", [""]) async def test_cover( client: ClientSessionGenerator, cover_entities: dict[str, er.RegistryEntry] @@ -1903,6 +1943,36 @@ async def fan_fixture( return data +@pytest.fixture(name="alarm_control_panel_entities") +async def alarm_control_panel_fixture( + hass: HomeAssistant, entity_registry: er.EntityRegistry +) -> dict[str, er.RegistryEntry]: + """Simulate alarm control panel entities.""" + data = {} + alarm_control_panel_1 = entity_registry.async_get_or_create( + domain=alarm_control_panel.DOMAIN, + platform="test", + unique_id="alarm_control_panel_1", + suggested_object_id="alarm_control_panel_1", + original_name="Alarm Control Panel 1", + ) + set_state_with_entry(hass, alarm_control_panel_1, STATE_ALARM_ARMED_AWAY) + data["alarm_control_panel_1"] = alarm_control_panel_1 + + alarm_control_panel_2 = entity_registry.async_get_or_create( + domain=alarm_control_panel.DOMAIN, + platform="test", + unique_id="alarm_control_panel_2", + suggested_object_id="alarm_control_panel_2", + original_name="Alarm Control Panel 2", + ) + set_state_with_entry(hass, alarm_control_panel_2, STATE_ALARM_ARMED_HOME) + data["alarm_control_panel_2"] = alarm_control_panel_2 + + await hass.async_block_till_done() + return data + + @pytest.fixture(name="person_entities") async def person_fixture( hass: HomeAssistant, entity_registry: er.EntityRegistry