From 726637b8675c25c0e20c49fb450356cc78be5023 Mon Sep 17 00:00:00 2001 From: magnusknutas Date: Tue, 26 Jan 2016 18:37:19 +0100 Subject: [PATCH] New and improved handling of the matching! Kudos to @balloob --- homeassistant/helpers/event.py | 17 ++++++++++------- tests/helpers/test_event.py | 20 +++++++++++++++++++- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/homeassistant/helpers/event.py b/homeassistant/helpers/event.py index 419c80189eb..e079fbcc444 100644 --- a/homeassistant/helpers/event.py +++ b/homeassistant/helpers/event.py @@ -1,7 +1,8 @@ """ Helpers for listening to events """ -from datetime import timedelta +from calendar import monthrange +from datetime import timedelta, date import functools as ft from ..util import convert @@ -162,7 +163,7 @@ def track_utc_time_change(hass, action, year=None, month=None, day=None, pmp = _process_match_param year, month, day = pmp(year), pmp(month), pmp(day) - hour, minute, second = pmp(hour, rang=24), pmp(minute), pmp(second) + hour, minute, second = pmp(hour), pmp(minute), pmp(second) @ft.wraps(action) def pattern_time_change_listener(event): @@ -171,7 +172,6 @@ def track_utc_time_change(hass, action, year=None, month=None, day=None, if local: now = dt_util.as_local(now) - mat = _matcher # pylint: disable=too-many-boolean-expressions @@ -196,13 +196,10 @@ def track_time_change(hass, action, year=None, month=None, day=None, local=True) -def _process_match_param(parameter, rang=None): +def _process_match_param(parameter): """ Wraps parameter in a tuple if it is not one and returns it. """ if parameter is None or parameter == MATCH_ALL: return MATCH_ALL - elif isinstance(parameter, str) and parameter.startswith('/'): - rang = rang or 60 - return tuple(range(0, rang, convert(parameter.lstrip('/'), int))) elif isinstance(parameter, str) or not hasattr(parameter, '__iter__'): return (parameter,) else: @@ -214,4 +211,10 @@ def _matcher(subject, pattern): Pattern is either a tuple of allowed subjects or a `MATCH_ALL`. """ + if isinstance(pattern, tuple) \ + and isinstance(pattern[0], str) and pattern[0].startswith('/'): + try: + return subject % float(pattern[0].lstrip('/')) == 0 + except ValueError: + return False return MATCH_ALL == pattern or subject in pattern diff --git a/tests/helpers/test_event.py b/tests/helpers/test_event.py index 4b8f984b32e..3e57e357f9c 100644 --- a/tests/helpers/test_event.py +++ b/tests/helpers/test_event.py @@ -220,7 +220,7 @@ class TestEventHelpers(unittest.TestCase): """ Send a time changed event. """ self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: now}) - def test_periodic_task(self): + def test_periodic_task_minute(self): specific_runs = [] track_utc_time_change( @@ -263,3 +263,21 @@ class TestEventHelpers(unittest.TestCase): self._send_time_changed(datetime(2014, 5, 25, 2, 0, 0)) self.hass.pool.block_till_done() self.assertEqual(3, len(specific_runs)) + + def test_periodic_task_day(self): + specific_runs = [] + + track_utc_time_change( + self.hass, lambda x: specific_runs.append(1), day='/2') + + self._send_time_changed(datetime(2014, 5, 2, 0, 0, 0)) + self.hass.pool.block_till_done() + self.assertEqual(1, len(specific_runs)) + + self._send_time_changed(datetime(2014, 5, 3, 12, 0, 0)) + self.hass.pool.block_till_done() + self.assertEqual(1, len(specific_runs)) + + self._send_time_changed(datetime(2014, 5, 4, 0, 0, 0)) + self.hass.pool.block_till_done() + self.assertEqual(2, len(specific_runs))