Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add significant Change support for alarm control panel #106021

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""Helper to test significant Alarm Control Panel state changes."""
from __future__ import annotations

from typing import Any

from homeassistant.core import HomeAssistant, callback

from . import ATTR_CHANGED_BY, ATTR_CODE_ARM_REQUIRED

SIGNIFICANT_ATTRIBUTES: set[str] = {
ATTR_CHANGED_BY,
ATTR_CODE_ARM_REQUIRED,
}


@callback
def async_check_significant_change(
hass: HomeAssistant,
old_state: str,
old_attrs: dict,
new_state: str,
new_attrs: dict,
**kwargs: Any,
) -> bool | None:
"""Test if state significantly changed."""
if old_state != new_state:
return True

old_attrs_s = set(old_attrs.items())
new_attrs_s = set(new_attrs.items())
changed_attrs: set[str] = {item[0] for item in old_attrs_s ^ new_attrs_s}

for attr_name in changed_attrs:
if attr_name in SIGNIFICANT_ATTRIBUTES:
return True

# no significant attribute change detected
return False
51 changes: 51 additions & 0 deletions tests/components/alarm_control_panel/test_significant_change.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"""Test the Alarm Control Panel significant change platform."""
import pytest

from homeassistant.components.alarm_control_panel import (
ATTR_CHANGED_BY,
ATTR_CODE_ARM_REQUIRED,
ATTR_CODE_FORMAT,
)
from homeassistant.components.alarm_control_panel.significant_change import (
async_check_significant_change,
)


async def test_significant_state_change() -> None:
"""Detect Alarm Control Panel significant state changes."""
attrs = {}
assert not async_check_significant_change(None, "on", attrs, "on", attrs)
assert async_check_significant_change(None, "on", attrs, "off", attrs)


@pytest.mark.parametrize(
("old_attrs", "new_attrs", "expected_result"),
[
({ATTR_CHANGED_BY: "old_value"}, {ATTR_CHANGED_BY: "old_value"}, False),
({ATTR_CHANGED_BY: "old_value"}, {ATTR_CHANGED_BY: "new_value"}, True),
(
{ATTR_CODE_ARM_REQUIRED: "old_value"},
{ATTR_CODE_ARM_REQUIRED: "new_value"},
True,
),
# multiple attributes
(
{ATTR_CHANGED_BY: "old_value", ATTR_CODE_ARM_REQUIRED: "old_value"},
{ATTR_CHANGED_BY: "new_value", ATTR_CODE_ARM_REQUIRED: "old_value"},
True,
),
# insignificant attributes
({ATTR_CODE_FORMAT: "old_value"}, {ATTR_CODE_FORMAT: "old_value"}, False),
({ATTR_CODE_FORMAT: "old_value"}, {ATTR_CODE_FORMAT: "new_value"}, False),
({"unknown_attr": "old_value"}, {"unknown_attr": "old_value"}, False),
({"unknown_attr": "old_value"}, {"unknown_attr": "new_value"}, False),
],
)
async def test_significant_atributes_change(
old_attrs: dict, new_attrs: dict, expected_result: bool
) -> None:
"""Detect Humidifier significant attribute changes."""
assert (
async_check_significant_change(None, "state", old_attrs, "state", new_attrs)
== expected_result
)