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 Helpers for listening to events
""" """
from datetime import timedelta from calendar import monthrange
from datetime import timedelta, date
import functools as ft import functools as ft
from ..util import convert 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 pmp = _process_match_param
year, month, day = pmp(year), pmp(month), pmp(day) 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) @ft.wraps(action)
def pattern_time_change_listener(event): 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: if local:
now = dt_util.as_local(now) now = dt_util.as_local(now)
mat = _matcher mat = _matcher
# pylint: disable=too-many-boolean-expressions # pylint: disable=too-many-boolean-expressions
@ -196,13 +196,10 @@ def track_time_change(hass, action, year=None, month=None, day=None,
local=True) 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. """ """ Wraps parameter in a tuple if it is not one and returns it. """
if parameter is None or parameter == MATCH_ALL: if parameter is None or parameter == MATCH_ALL:
return 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__'): elif isinstance(parameter, str) or not hasattr(parameter, '__iter__'):
return (parameter,) return (parameter,)
else: else:
@ -214,4 +211,10 @@ def _matcher(subject, pattern):
Pattern is either a tuple of allowed subjects or a `MATCH_ALL`. 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 return MATCH_ALL == pattern or subject in pattern

View File

@ -220,7 +220,7 @@ class TestEventHelpers(unittest.TestCase):
""" Send a time changed event. """ """ Send a time changed event. """
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: now}) 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 = [] specific_runs = []
track_utc_time_change( track_utc_time_change(
@ -263,3 +263,21 @@ class TestEventHelpers(unittest.TestCase):
self._send_time_changed(datetime(2014, 5, 25, 2, 0, 0)) self._send_time_changed(datetime(2014, 5, 25, 2, 0, 0))
self.hass.pool.block_till_done() self.hass.pool.block_till_done()
self.assertEqual(3, len(specific_runs)) 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))