New and improved handling of the matching! Kudos to @balloob

This commit is contained in:
magnusknutas 2016-01-26 18:37:19 +01:00
parent 6ae57b5aaf
commit 726637b867
2 changed files with 29 additions and 8 deletions

View file

@ -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

View file

@ -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))