From e5309e89ea8d91f0b02ae3441b88abff34605a07 Mon Sep 17 00:00:00 2001 From: jjlawren Date: Sun, 30 May 2021 23:03:53 -0500 Subject: [PATCH] Skip processed Sonos alarm updates (#51217) * Skip processed Sonos alarm updates * Fix bad conflict merge --- homeassistant/components/sonos/__init__.py | 3 ++- homeassistant/components/sonos/speaker.py | 10 ++++++++++ tests/components/sonos/conftest.py | 11 ++++++++++- tests/components/sonos/test_switch.py | 1 + 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/sonos/__init__.py b/homeassistant/components/sonos/__init__.py index b7997a63571..d26d7d0c47a 100644 --- a/homeassistant/components/sonos/__init__.py +++ b/homeassistant/components/sonos/__init__.py @@ -2,7 +2,7 @@ from __future__ import annotations import asyncio -from collections import OrderedDict +from collections import OrderedDict, deque import datetime import logging import socket @@ -76,6 +76,7 @@ class SonosData: self.discovered: OrderedDict[str, SonosSpeaker] = OrderedDict() self.favorites: dict[str, SonosFavorites] = {} self.alarms: dict[str, Alarm] = {} + self.processed_alarm_events = deque(maxlen=5) self.topology_condition = asyncio.Condition() self.hosts_heartbeat = None self.ssdp_known: set[str] = set() diff --git a/homeassistant/components/sonos/speaker.py b/homeassistant/components/sonos/speaker.py index 20a6aa794a1..0d7efae1877 100644 --- a/homeassistant/components/sonos/speaker.py +++ b/homeassistant/components/sonos/speaker.py @@ -2,6 +2,7 @@ from __future__ import annotations import asyncio +from collections import deque from collections.abc import Coroutine import contextlib import datetime @@ -282,6 +283,11 @@ class SonosSpeaker: """Return true if player is a coordinator.""" return self.coordinator is None + @property + def processed_alarm_events(self) -> deque[str]: + """Return the container of processed alarm events.""" + return self.hass.data[DATA_SONOS].processed_alarm_events + @property def subscription_address(self) -> str | None: """Return the current subscription callback address if any.""" @@ -366,6 +372,10 @@ class SonosSpeaker: @callback def async_dispatch_alarms(self, event: SonosEvent) -> None: """Create a task to update alarms from an event.""" + update_id = event.variables["alarm_list_version"] + if update_id in self.processed_alarm_events: + return + self.processed_alarm_events.append(update_id) self.hass.async_add_executor_job(self.update_alarms) @callback diff --git a/tests/components/sonos/conftest.py b/tests/components/sonos/conftest.py index 81ad0e6c8ef..7c5b4ac91ef 100644 --- a/tests/components/sonos/conftest.py +++ b/tests/components/sonos/conftest.py @@ -31,6 +31,15 @@ class SonosMockEvent: self.service = service self.variables = variables + def increment_variable(self, var_name): + """Increment the value of the var_name key in variables dict attribute. + + Assumes value has a format of :. + """ + base, count = self.variables[var_name].split(":") + newcount = int(count) + 1 + self.variables[var_name] = ":".join([base, str(newcount)]) + @pytest.fixture(name="config_entry") def config_entry_fixture(): @@ -174,7 +183,7 @@ def alarm_event_fixture(soco): "time_zone": "ffc40a000503000003000502ffc4", "time_server": "0.sonostime.pool.ntp.org,1.sonostime.pool.ntp.org,2.sonostime.pool.ntp.org,3.sonostime.pool.ntp.org", "time_generation": "20000001", - "alarm_list_version": "RINCON_test", + "alarm_list_version": "RINCON_test:1", "time_format": "INV", "date_format": "INV", "daily_index_refresh_time": None, diff --git a/tests/components/sonos/test_switch.py b/tests/components/sonos/test_switch.py index d4448d22b32..41cb241d377 100644 --- a/tests/components/sonos/test_switch.py +++ b/tests/components/sonos/test_switch.py @@ -68,6 +68,7 @@ async def test_alarm_create_delete( assert "switch.sonos_alarm_15" in entity_registry.entities alarm_clock_extended.ListAlarms.return_value = alarm_clock.ListAlarms.return_value + alarm_event.increment_variable("alarm_list_version") sub_callback(event=alarm_event) await hass.async_block_till_done()