From 8c010c8df434f63680579db6fcbeba20483159ed Mon Sep 17 00:00:00 2001 From: Philip Lundrigan Date: Mon, 21 Dec 2015 16:09:27 -0700 Subject: [PATCH 1/5] Add ability to use sun as condition in automation --- homeassistant/components/automation/sun.py | 114 +++++++++++++++++---- 1 file changed, 94 insertions(+), 20 deletions(-) diff --git a/homeassistant/components/automation/sun.py b/homeassistant/components/automation/sun.py index 84334493d0f..cf14d220fb0 100644 --- a/homeassistant/components/automation/sun.py +++ b/homeassistant/components/automation/sun.py @@ -17,6 +17,10 @@ DEPENDENCIES = ['sun'] CONF_OFFSET = 'offset' CONF_EVENT = 'event' +CONF_BEFORE = "before" +CONF_BEFORE_OFFSET = "before_offset" +CONF_AFTER = "after" +CONF_AFTER_OFFSET = "after_offset" EVENT_SUNSET = 'sunset' EVENT_SUNRISE = 'sunrise' @@ -37,26 +41,9 @@ def trigger(hass, config, action): _LOGGER.error("Invalid value for %s: %s", CONF_EVENT, event) return False - if CONF_OFFSET in config: - raw_offset = config.get(CONF_OFFSET) - - negative_offset = False - if raw_offset.startswith('-'): - negative_offset = True - raw_offset = raw_offset[1:] - - try: - (hour, minute, second) = [int(x) for x in raw_offset.split(':')] - except ValueError: - _LOGGER.error('Could not parse offset %s', raw_offset) - return False - - offset = timedelta(hours=hour, minutes=minute, seconds=second) - - if negative_offset: - offset *= -1 - else: - offset = timedelta(0) + offset = _parse_offset(config.get(CONF_OFFSET)) + if offset is False: + return False # Do something to call action if event == EVENT_SUNRISE: @@ -67,6 +54,70 @@ def trigger(hass, config, action): return True +def if_action(hass, config): + """ Wraps action method with sun based condition. """ + before = config.get(CONF_BEFORE) + after = config.get(CONF_AFTER) + + # Make sure required configuration keys are present + if before is None and after is None: + logging.getLogger(__name__).error( + "Missing if-condition configuration key %s or %s", + CONF_BEFORE, CONF_AFTER) + return None + + # Make sure configuration keys have the right value + if before is not None and before not in (EVENT_SUNRISE, EVENT_SUNSET) or \ + after is not None and after not in (EVENT_SUNRISE, EVENT_SUNSET): + logging.getLogger(__name__).error( + "%s and %s can only be set to %s or %s", + CONF_BEFORE, CONF_AFTER, EVENT_SUNRISE, EVENT_SUNSET) + return None + + before_offset = _parse_offset(config.get(CONF_BEFORE_OFFSET)) + after_offset = _parse_offset(config.get(CONF_AFTER_OFFSET)) + if before_offset is False or after_offset is False: + return None + + if before is None: + before_func = lambda: None + elif before == EVENT_SUNRISE: + before_func = lambda: sun.next_rising_utc(hass) + before_offset + else: + before_func = lambda: sun.next_setting_utc(hass) + before_offset + + if after is None: + after_func = lambda: None + elif after == EVENT_SUNRISE: + after_func = lambda: sun.next_rising_utc(hass) + after_offset + else: + after_func = lambda: sun.next_setting_utc(hass) + after_offset + + # This is needed for testing + time_func = dt_util.utcnow + + def time_if(): + """ Validate time based if-condition """ + + # This is needed for testing. + nonlocal time_func + now = time_func() + before = before_func() + after = after_func() + + if before is not None and now > now.replace(hour=before.hour, + minute=before.minute): + return False + + if after is not None and now < now.replace(hour=after.hour, + minute=after.minute): + return False + + return True + + return time_if + + def trigger_sunrise(hass, action, offset): """ Trigger action at next sun rise. """ def next_rise(): @@ -103,3 +154,26 @@ def trigger_sunset(hass, action, offset): action() track_point_in_utc_time(hass, sunset_automation_listener, next_set()) + + +def _parse_offset(raw_offset): + if raw_offset is None: + return timedelta(0) + + negative_offset = False + if raw_offset.startswith('-'): + negative_offset = True + raw_offset = raw_offset[1:] + + try: + (hour, minute, second) = [int(x) for x in raw_offset.split(':')] + except ValueError: + _LOGGER.error('Could not parse offset %s', raw_offset) + return False + + offset = timedelta(hours=hour, minutes=minute, seconds=second) + + if negative_offset: + offset *= -1 + + return offset From 110d721c76a227093b1cc3128f301367e0e76d2d Mon Sep 17 00:00:00 2001 From: Philip Lundrigan Date: Mon, 21 Dec 2015 16:09:51 -0700 Subject: [PATCH 2/5] Add tests --- tests/components/automation/test_sun.py | 248 ++++++++++++++++++++++++ 1 file changed, 248 insertions(+) diff --git a/tests/components/automation/test_sun.py b/tests/components/automation/test_sun.py index de8b2f8121b..3c4b2783c72 100644 --- a/tests/components/automation/test_sun.py +++ b/tests/components/automation/test_sun.py @@ -139,3 +139,251 @@ class TestAutomationSun(unittest.TestCase): fire_time_changed(self.hass, trigger_time) self.hass.pool.block_till_done() self.assertEqual(1, len(self.calls)) + + def test_if_action_before_before(self): + self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { + sun.STATE_ATTR_NEXT_RISING: '14:00:00 16-09-2015', + }) + + now = datetime(2015, 9, 16, 10, tzinfo=dt_util.UTC) + entity_id = 'domain.test_entity' + + with patch('homeassistant.components.automation.sun.dt_util.utcnow', + return_value=now): + automation.setup(self.hass, { + automation.DOMAIN: { + 'trigger': { + 'platform': 'event', + 'event_type': 'test_event', + }, + 'condition': { + 'platform': 'sun', + 'before': 'sunrise', + }, + 'action': { + 'service': 'test.automation' + } + } + }) + + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(1, len(self.calls)) + + def test_if_action_after_before(self): + self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { + sun.STATE_ATTR_NEXT_RISING: '14:00:00 16-09-2015', + }) + + now = datetime(2015, 9, 16, 15, tzinfo=dt_util.UTC) + entity_id = 'domain.test_entity' + + with patch('homeassistant.components.automation.sun.dt_util.utcnow', + return_value=now): + automation.setup(self.hass, { + automation.DOMAIN: { + 'trigger': { + 'platform': 'event', + 'event_type': 'test_event', + }, + 'condition': { + 'platform': 'sun', + 'before': 'sunrise', + }, + 'action': { + 'service': 'test.automation' + } + } + }) + + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(0, len(self.calls)) + + def test_if_action_before_after(self): + self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { + sun.STATE_ATTR_NEXT_RISING: '14:00:00 16-09-2015', + }) + + now = datetime(2015, 9, 16, 13, tzinfo=dt_util.UTC) + entity_id = 'domain.test_entity' + + with patch('homeassistant.components.automation.sun.dt_util.utcnow', + return_value=now): + automation.setup(self.hass, { + automation.DOMAIN: { + 'trigger': { + 'platform': 'event', + 'event_type': 'test_event', + }, + 'condition': { + 'platform': 'sun', + 'after': 'sunrise', + }, + 'action': { + 'service': 'test.automation' + } + } + }) + + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(0, len(self.calls)) + + def test_if_action_before_and_after_during(self): + self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { + sun.STATE_ATTR_NEXT_RISING: '10:00:00 16-09-2015', + sun.STATE_ATTR_NEXT_SETTING: '15:00:00 16-09-2015', + }) + + now = datetime(2015, 9, 16, 12, tzinfo=dt_util.UTC) + entity_id = 'domain.test_entity' + + with patch('homeassistant.components.automation.sun.dt_util.utcnow', + return_value=now): + automation.setup(self.hass, { + automation.DOMAIN: { + 'trigger': { + 'platform': 'event', + 'event_type': 'test_event', + }, + 'condition': { + 'platform': 'sun', + 'after': 'sunrise', + 'before': 'sunset' + }, + 'action': { + 'service': 'test.automation' + } + } + }) + + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(1, len(self.calls)) + + def test_if_action_before_and_after_before(self): + self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { + sun.STATE_ATTR_NEXT_RISING: '10:00:00 16-09-2015', + sun.STATE_ATTR_NEXT_SETTING: '15:00:00 16-09-2015', + }) + + now = datetime(2015, 9, 16, 8, tzinfo=dt_util.UTC) + entity_id = 'domain.test_entity' + + with patch('homeassistant.components.automation.sun.dt_util.utcnow', + return_value=now): + automation.setup(self.hass, { + automation.DOMAIN: { + 'trigger': { + 'platform': 'event', + 'event_type': 'test_event', + }, + 'condition': { + 'platform': 'sun', + 'after': 'sunrise', + 'before': 'sunset' + }, + 'action': { + 'service': 'test.automation' + } + } + }) + + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(0, len(self.calls)) + + def test_if_action_before_and_after_after(self): + self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { + sun.STATE_ATTR_NEXT_RISING: '10:00:00 16-09-2015', + sun.STATE_ATTR_NEXT_SETTING: '15:00:00 16-09-2015', + }) + + now = datetime(2015, 9, 16, 16, tzinfo=dt_util.UTC) + entity_id = 'domain.test_entity' + + with patch('homeassistant.components.automation.sun.dt_util.utcnow', + return_value=now): + automation.setup(self.hass, { + automation.DOMAIN: { + 'trigger': { + 'platform': 'event', + 'event_type': 'test_event', + }, + 'condition': { + 'platform': 'sun', + 'after': 'sunrise', + 'before': 'sunset' + }, + 'action': { + 'service': 'test.automation' + } + } + }) + + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(0, len(self.calls)) + + def test_if_action_offset_before(self): + self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { + sun.STATE_ATTR_NEXT_RISING: '14:00:00 16-09-2015', + }) + + now = datetime(2015, 9, 16, 14, 59, tzinfo=dt_util.UTC) + entity_id = 'domain.test_entity' + + with patch('homeassistant.components.automation.sun.dt_util.utcnow', + return_value=now): + automation.setup(self.hass, { + automation.DOMAIN: { + 'trigger': { + 'platform': 'event', + 'event_type': 'test_event', + }, + 'condition': { + 'platform': 'sun', + 'before': 'sunrise', + 'before_offset': '+1:00:00' + }, + 'action': { + 'service': 'test.automation' + } + } + }) + + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(1, len(self.calls)) + + def test_if_action_offset_after(self): + self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { + sun.STATE_ATTR_NEXT_RISING: '14:00:00 16-09-2015', + }) + + now = datetime(2015, 9, 16, 15, tzinfo=dt_util.UTC) + entity_id = 'domain.test_entity' + + with patch('homeassistant.components.automation.sun.dt_util.utcnow', + return_value=now): + automation.setup(self.hass, { + automation.DOMAIN: { + 'trigger': { + 'platform': 'event', + 'event_type': 'test_event', + }, + 'condition': { + 'platform': 'sun', + 'after': 'sunrise', + 'after_offset': '+1:00:00' + }, + 'action': { + 'service': 'test.automation' + } + } + }) + + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(1, len(self.calls)) From ff8f22854c96e7f807161ebbf373cd88eaefbc68 Mon Sep 17 00:00:00 2001 From: Philip Lundrigan Date: Mon, 21 Dec 2015 16:28:26 -0700 Subject: [PATCH 3/5] Add test --- tests/components/automation/test_sun.py | 30 +++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/components/automation/test_sun.py b/tests/components/automation/test_sun.py index 3c4b2783c72..87f04a325e8 100644 --- a/tests/components/automation/test_sun.py +++ b/tests/components/automation/test_sun.py @@ -230,6 +230,36 @@ class TestAutomationSun(unittest.TestCase): self.hass.pool.block_till_done() self.assertEqual(0, len(self.calls)) + def test_if_action_after_after(self): + self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { + sun.STATE_ATTR_NEXT_SETTING: '14:00:00 16-09-2015', + }) + + now = datetime(2015, 9, 16, 15, tzinfo=dt_util.UTC) + entity_id = 'domain.test_entity' + + with patch('homeassistant.components.automation.sun.dt_util.utcnow', + return_value=now): + automation.setup(self.hass, { + automation.DOMAIN: { + 'trigger': { + 'platform': 'event', + 'event_type': 'test_event', + }, + 'condition': { + 'platform': 'sun', + 'after': 'sunset', + }, + 'action': { + 'service': 'test.automation' + } + } + }) + + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(1, len(self.calls)) + def test_if_action_before_and_after_during(self): self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { sun.STATE_ATTR_NEXT_RISING: '10:00:00 16-09-2015', From 2606e4d641d0f16e48fd4c2321adc6a918300e0e Mon Sep 17 00:00:00 2001 From: Philip Lundrigan Date: Thu, 24 Dec 2015 00:38:49 -0700 Subject: [PATCH 4/5] Simplify if statement --- homeassistant/components/automation/sun.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/automation/sun.py b/homeassistant/components/automation/sun.py index cf14d220fb0..a5035c8936a 100644 --- a/homeassistant/components/automation/sun.py +++ b/homeassistant/components/automation/sun.py @@ -67,8 +67,8 @@ def if_action(hass, config): return None # Make sure configuration keys have the right value - if before is not None and before not in (EVENT_SUNRISE, EVENT_SUNSET) or \ - after is not None and after not in (EVENT_SUNRISE, EVENT_SUNSET): + if before not in (None, EVENT_SUNRISE, EVENT_SUNSET) or \ + after not in (None, EVENT_SUNRISE, EVENT_SUNSET): logging.getLogger(__name__).error( "%s and %s can only be set to %s or %s", CONF_BEFORE, CONF_AFTER, EVENT_SUNRISE, EVENT_SUNSET) From add24915a3d8791bb86788fe3758de8e39592f65 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 26 Dec 2015 17:48:20 -0800 Subject: [PATCH 5/5] ps - clean up sun automation tests --- homeassistant/components/automation/sun.py | 7 +- tests/components/automation/test_sun.py | 394 ++++++++------------- 2 files changed, 152 insertions(+), 249 deletions(-) diff --git a/homeassistant/components/automation/sun.py b/homeassistant/components/automation/sun.py index a5035c8936a..394dc904be1 100644 --- a/homeassistant/components/automation/sun.py +++ b/homeassistant/components/automation/sun.py @@ -93,15 +93,10 @@ def if_action(hass, config): else: after_func = lambda: sun.next_setting_utc(hass) + after_offset - # This is needed for testing - time_func = dt_util.utcnow - def time_if(): """ Validate time based if-condition """ - # This is needed for testing. - nonlocal time_func - now = time_func() + now = dt_util.utcnow() before = before_func() after = after_func() diff --git a/tests/components/automation/test_sun.py b/tests/components/automation/test_sun.py index 87f04a325e8..26ecc26c72a 100644 --- a/tests/components/automation/test_sun.py +++ b/tests/components/automation/test_sun.py @@ -140,125 +140,147 @@ class TestAutomationSun(unittest.TestCase): self.hass.pool.block_till_done() self.assertEqual(1, len(self.calls)) - def test_if_action_before_before(self): + def test_if_action_before(self): self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { sun.STATE_ATTR_NEXT_RISING: '14:00:00 16-09-2015', }) - now = datetime(2015, 9, 16, 10, tzinfo=dt_util.UTC) - entity_id = 'domain.test_entity' - - with patch('homeassistant.components.automation.sun.dt_util.utcnow', - return_value=now): - automation.setup(self.hass, { - automation.DOMAIN: { - 'trigger': { - 'platform': 'event', - 'event_type': 'test_event', - }, - 'condition': { - 'platform': 'sun', - 'before': 'sunrise', - }, - 'action': { - 'service': 'test.automation' - } + automation.setup(self.hass, { + automation.DOMAIN: { + 'trigger': { + 'platform': 'event', + 'event_type': 'test_event', + }, + 'condition': { + 'platform': 'sun', + 'before': 'sunrise', + }, + 'action': { + 'service': 'test.automation' } - }) - - self.hass.bus.fire('test_event') - self.hass.pool.block_till_done() - self.assertEqual(1, len(self.calls)) - - def test_if_action_after_before(self): - self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { - sun.STATE_ATTR_NEXT_RISING: '14:00:00 16-09-2015', + } }) now = datetime(2015, 9, 16, 15, tzinfo=dt_util.UTC) - entity_id = 'domain.test_entity' - with patch('homeassistant.components.automation.sun.dt_util.utcnow', return_value=now): - automation.setup(self.hass, { - automation.DOMAIN: { - 'trigger': { - 'platform': 'event', - 'event_type': 'test_event', - }, - 'condition': { - 'platform': 'sun', - 'before': 'sunrise', - }, - 'action': { - 'service': 'test.automation' - } - } - }) + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(0, len(self.calls)) - self.hass.bus.fire('test_event') - self.hass.pool.block_till_done() - self.assertEqual(0, len(self.calls)) + now = datetime(2015, 9, 16, 10, tzinfo=dt_util.UTC) + with patch('homeassistant.components.automation.sun.dt_util.utcnow', + return_value=now): + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(1, len(self.calls)) - def test_if_action_before_after(self): + def test_if_action_after(self): self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { sun.STATE_ATTR_NEXT_RISING: '14:00:00 16-09-2015', }) + automation.setup(self.hass, { + automation.DOMAIN: { + 'trigger': { + 'platform': 'event', + 'event_type': 'test_event', + }, + 'condition': { + 'platform': 'sun', + 'after': 'sunrise', + }, + 'action': { + 'service': 'test.automation' + } + } + }) + now = datetime(2015, 9, 16, 13, tzinfo=dt_util.UTC) - entity_id = 'domain.test_entity' - with patch('homeassistant.components.automation.sun.dt_util.utcnow', return_value=now): - automation.setup(self.hass, { - automation.DOMAIN: { - 'trigger': { - 'platform': 'event', - 'event_type': 'test_event', - }, - 'condition': { - 'platform': 'sun', - 'after': 'sunrise', - }, - 'action': { - 'service': 'test.automation' - } - } - }) - - self.hass.bus.fire('test_event') - self.hass.pool.block_till_done() - self.assertEqual(0, len(self.calls)) - - def test_if_action_after_after(self): - self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { - sun.STATE_ATTR_NEXT_SETTING: '14:00:00 16-09-2015', - }) + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(0, len(self.calls)) now = datetime(2015, 9, 16, 15, tzinfo=dt_util.UTC) - entity_id = 'domain.test_entity' - with patch('homeassistant.components.automation.sun.dt_util.utcnow', return_value=now): - automation.setup(self.hass, { - automation.DOMAIN: { - 'trigger': { - 'platform': 'event', - 'event_type': 'test_event', - }, - 'condition': { - 'platform': 'sun', - 'after': 'sunset', - }, - 'action': { - 'service': 'test.automation' - } - } - }) + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(1, len(self.calls)) - self.hass.bus.fire('test_event') - self.hass.pool.block_till_done() - self.assertEqual(1, len(self.calls)) + def test_if_action_before_with_offset(self): + self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { + sun.STATE_ATTR_NEXT_RISING: '14:00:00 16-09-2015', + }) + + automation.setup(self.hass, { + automation.DOMAIN: { + 'trigger': { + 'platform': 'event', + 'event_type': 'test_event', + }, + 'condition': { + 'platform': 'sun', + 'before': 'sunrise', + 'before_offset': '+1:00:00' + }, + 'action': { + 'service': 'test.automation' + } + } + }) + + now = datetime(2015, 9, 16, 15, 1, tzinfo=dt_util.UTC) + with patch('homeassistant.components.automation.sun.dt_util.utcnow', + return_value=now): + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(0, len(self.calls)) + + now = datetime(2015, 9, 16, 15, tzinfo=dt_util.UTC) + with patch('homeassistant.components.automation.sun.dt_util.utcnow', + return_value=now): + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(1, len(self.calls)) + + def test_if_action_after_with_offset(self): + self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { + sun.STATE_ATTR_NEXT_RISING: '14:00:00 16-09-2015', + }) + + automation.setup(self.hass, { + automation.DOMAIN: { + 'trigger': { + 'platform': 'event', + 'event_type': 'test_event', + }, + 'condition': { + 'platform': 'sun', + 'after': 'sunrise', + 'after_offset': '+1:00:00' + }, + 'action': { + 'service': 'test.automation' + } + } + }) + + now = datetime(2015, 9, 16, 14, 59, tzinfo=dt_util.UTC) + with patch('homeassistant.components.automation.sun.dt_util.utcnow', + return_value=now): + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(0, len(self.calls)) + + now = datetime(2015, 9, 16, 15, tzinfo=dt_util.UTC) + with patch('homeassistant.components.automation.sun.dt_util.utcnow', + return_value=now): + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(1, len(self.calls)) def test_if_action_before_and_after_during(self): self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { @@ -266,154 +288,40 @@ class TestAutomationSun(unittest.TestCase): sun.STATE_ATTR_NEXT_SETTING: '15:00:00 16-09-2015', }) + automation.setup(self.hass, { + automation.DOMAIN: { + 'trigger': { + 'platform': 'event', + 'event_type': 'test_event', + }, + 'condition': { + 'platform': 'sun', + 'after': 'sunrise', + 'before': 'sunset' + }, + 'action': { + 'service': 'test.automation' + } + } + }) + + now = datetime(2015, 9, 16, 9, 59, tzinfo=dt_util.UTC) + with patch('homeassistant.components.automation.sun.dt_util.utcnow', + return_value=now): + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(0, len(self.calls)) + + now = datetime(2015, 9, 16, 15, 1, tzinfo=dt_util.UTC) + with patch('homeassistant.components.automation.sun.dt_util.utcnow', + return_value=now): + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(0, len(self.calls)) + now = datetime(2015, 9, 16, 12, tzinfo=dt_util.UTC) - entity_id = 'domain.test_entity' - with patch('homeassistant.components.automation.sun.dt_util.utcnow', return_value=now): - automation.setup(self.hass, { - automation.DOMAIN: { - 'trigger': { - 'platform': 'event', - 'event_type': 'test_event', - }, - 'condition': { - 'platform': 'sun', - 'after': 'sunrise', - 'before': 'sunset' - }, - 'action': { - 'service': 'test.automation' - } - } - }) - - self.hass.bus.fire('test_event') - self.hass.pool.block_till_done() - self.assertEqual(1, len(self.calls)) - - def test_if_action_before_and_after_before(self): - self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { - sun.STATE_ATTR_NEXT_RISING: '10:00:00 16-09-2015', - sun.STATE_ATTR_NEXT_SETTING: '15:00:00 16-09-2015', - }) - - now = datetime(2015, 9, 16, 8, tzinfo=dt_util.UTC) - entity_id = 'domain.test_entity' - - with patch('homeassistant.components.automation.sun.dt_util.utcnow', - return_value=now): - automation.setup(self.hass, { - automation.DOMAIN: { - 'trigger': { - 'platform': 'event', - 'event_type': 'test_event', - }, - 'condition': { - 'platform': 'sun', - 'after': 'sunrise', - 'before': 'sunset' - }, - 'action': { - 'service': 'test.automation' - } - } - }) - - self.hass.bus.fire('test_event') - self.hass.pool.block_till_done() - self.assertEqual(0, len(self.calls)) - - def test_if_action_before_and_after_after(self): - self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { - sun.STATE_ATTR_NEXT_RISING: '10:00:00 16-09-2015', - sun.STATE_ATTR_NEXT_SETTING: '15:00:00 16-09-2015', - }) - - now = datetime(2015, 9, 16, 16, tzinfo=dt_util.UTC) - entity_id = 'domain.test_entity' - - with patch('homeassistant.components.automation.sun.dt_util.utcnow', - return_value=now): - automation.setup(self.hass, { - automation.DOMAIN: { - 'trigger': { - 'platform': 'event', - 'event_type': 'test_event', - }, - 'condition': { - 'platform': 'sun', - 'after': 'sunrise', - 'before': 'sunset' - }, - 'action': { - 'service': 'test.automation' - } - } - }) - - self.hass.bus.fire('test_event') - self.hass.pool.block_till_done() - self.assertEqual(0, len(self.calls)) - - def test_if_action_offset_before(self): - self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { - sun.STATE_ATTR_NEXT_RISING: '14:00:00 16-09-2015', - }) - - now = datetime(2015, 9, 16, 14, 59, tzinfo=dt_util.UTC) - entity_id = 'domain.test_entity' - - with patch('homeassistant.components.automation.sun.dt_util.utcnow', - return_value=now): - automation.setup(self.hass, { - automation.DOMAIN: { - 'trigger': { - 'platform': 'event', - 'event_type': 'test_event', - }, - 'condition': { - 'platform': 'sun', - 'before': 'sunrise', - 'before_offset': '+1:00:00' - }, - 'action': { - 'service': 'test.automation' - } - } - }) - - self.hass.bus.fire('test_event') - self.hass.pool.block_till_done() - self.assertEqual(1, len(self.calls)) - - def test_if_action_offset_after(self): - self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, { - sun.STATE_ATTR_NEXT_RISING: '14:00:00 16-09-2015', - }) - - now = datetime(2015, 9, 16, 15, tzinfo=dt_util.UTC) - entity_id = 'domain.test_entity' - - with patch('homeassistant.components.automation.sun.dt_util.utcnow', - return_value=now): - automation.setup(self.hass, { - automation.DOMAIN: { - 'trigger': { - 'platform': 'event', - 'event_type': 'test_event', - }, - 'condition': { - 'platform': 'sun', - 'after': 'sunrise', - 'after_offset': '+1:00:00' - }, - 'action': { - 'service': 'test.automation' - } - } - }) - - self.hass.bus.fire('test_event') - self.hass.pool.block_till_done() - self.assertEqual(1, len(self.calls)) + self.hass.bus.fire('test_event') + self.hass.pool.block_till_done() + self.assertEqual(1, len(self.calls))