mirror of
https://github.com/home-assistant/core.git
synced 2026-09-24 15:31:52 -05:00
Refactor sun component for correctness (#7295)
* Refactor sun component for correctness * Convert datetimes to dates for astral * Fix tests for updated code * Fix times now that calcs are fixed * Move sun functions to helpers * Fix flake on new file * Additional tweaks from review * Update requirements
This commit is contained in:
committed by
Paulus Schoutsen
parent
419d97fc06
commit
40d27cde0e
+1
-16
@@ -3,7 +3,6 @@ import asyncio
|
||||
import functools as ft
|
||||
import os
|
||||
import sys
|
||||
from datetime import timedelta
|
||||
from unittest.mock import patch, MagicMock, Mock
|
||||
from io import StringIO
|
||||
import logging
|
||||
@@ -25,7 +24,7 @@ from homeassistant.const import (
|
||||
STATE_ON, STATE_OFF, DEVICE_DEFAULT_NAME, EVENT_TIME_CHANGED,
|
||||
EVENT_STATE_CHANGED, EVENT_PLATFORM_DISCOVERED, ATTR_SERVICE,
|
||||
ATTR_DISCOVERED, SERVER_PORT, EVENT_HOMEASSISTANT_CLOSE)
|
||||
from homeassistant.components import sun, mqtt, recorder
|
||||
from homeassistant.components import mqtt, recorder
|
||||
from homeassistant.components.http.auth import auth_middleware
|
||||
from homeassistant.components.http.const import (
|
||||
KEY_USE_X_FORWARDED_FOR, KEY_BANS_ENABLED, KEY_TRUSTED_NETWORKS)
|
||||
@@ -213,20 +212,6 @@ def fire_service_discovered(hass, service, info):
|
||||
})
|
||||
|
||||
|
||||
def ensure_sun_risen(hass):
|
||||
"""Trigger sun to rise if below horizon."""
|
||||
if sun.is_on(hass):
|
||||
return
|
||||
fire_time_changed(hass, sun.next_rising_utc(hass) + timedelta(seconds=10))
|
||||
|
||||
|
||||
def ensure_sun_set(hass):
|
||||
"""Trigger sun to set if above horizon."""
|
||||
if not sun.is_on(hass):
|
||||
return
|
||||
fire_time_changed(hass, sun.next_setting_utc(hass) + timedelta(seconds=10))
|
||||
|
||||
|
||||
def load_fixture(filename):
|
||||
"""Load a fixture."""
|
||||
path = os.path.join(os.path.dirname(__file__), 'fixtures', filename)
|
||||
|
||||
@@ -22,7 +22,8 @@ class TestAutomationSun(unittest.TestCase):
|
||||
"""Setup things to be run when tests are started."""
|
||||
self.hass = get_test_home_assistant()
|
||||
mock_component(self.hass, 'group')
|
||||
mock_component(self.hass, 'sun')
|
||||
setup_component(self.hass, sun.DOMAIN, {
|
||||
sun.DOMAIN: {sun.CONF_ELEVATION: 0}})
|
||||
|
||||
self.calls = []
|
||||
|
||||
@@ -39,10 +40,6 @@ class TestAutomationSun(unittest.TestCase):
|
||||
|
||||
def test_sunset_trigger(self):
|
||||
"""Test the sunset trigger."""
|
||||
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
|
||||
sun.STATE_ATTR_NEXT_SETTING: '2015-09-16T02:00:00Z',
|
||||
})
|
||||
|
||||
now = datetime(2015, 9, 15, 23, tzinfo=dt_util.UTC)
|
||||
trigger_time = datetime(2015, 9, 16, 2, tzinfo=dt_util.UTC)
|
||||
|
||||
@@ -78,10 +75,6 @@ class TestAutomationSun(unittest.TestCase):
|
||||
|
||||
def test_sunrise_trigger(self):
|
||||
"""Test the sunrise trigger."""
|
||||
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
|
||||
sun.STATE_ATTR_NEXT_RISING: '2015-09-16T14:00:00Z',
|
||||
})
|
||||
|
||||
now = datetime(2015, 9, 13, 23, tzinfo=dt_util.UTC)
|
||||
trigger_time = datetime(2015, 9, 16, 14, tzinfo=dt_util.UTC)
|
||||
|
||||
@@ -105,10 +98,6 @@ class TestAutomationSun(unittest.TestCase):
|
||||
|
||||
def test_sunset_trigger_with_offset(self):
|
||||
"""Test the sunset trigger with offset."""
|
||||
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
|
||||
sun.STATE_ATTR_NEXT_SETTING: '2015-09-16T02:00:00Z',
|
||||
})
|
||||
|
||||
now = datetime(2015, 9, 15, 23, tzinfo=dt_util.UTC)
|
||||
trigger_time = datetime(2015, 9, 16, 2, 30, tzinfo=dt_util.UTC)
|
||||
|
||||
@@ -139,10 +128,6 @@ class TestAutomationSun(unittest.TestCase):
|
||||
|
||||
def test_sunrise_trigger_with_offset(self):
|
||||
"""Test the runrise trigger with offset."""
|
||||
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
|
||||
sun.STATE_ATTR_NEXT_RISING: '2015-09-16T14:00:00Z',
|
||||
})
|
||||
|
||||
now = datetime(2015, 9, 13, 23, tzinfo=dt_util.UTC)
|
||||
trigger_time = datetime(2015, 9, 16, 13, 30, tzinfo=dt_util.UTC)
|
||||
|
||||
@@ -167,10 +152,6 @@ class TestAutomationSun(unittest.TestCase):
|
||||
|
||||
def test_if_action_before(self):
|
||||
"""Test if action was before."""
|
||||
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
|
||||
sun.STATE_ATTR_NEXT_RISING: '2015-09-16T14:00:00Z',
|
||||
})
|
||||
|
||||
setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
@@ -188,14 +169,14 @@ class TestAutomationSun(unittest.TestCase):
|
||||
})
|
||||
|
||||
now = datetime(2015, 9, 16, 15, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.now',
|
||||
with patch('homeassistant.util.dt.utcnow',
|
||||
return_value=now):
|
||||
self.hass.bus.fire('test_event')
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(0, len(self.calls))
|
||||
|
||||
now = datetime(2015, 9, 16, 10, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.now',
|
||||
with patch('homeassistant.util.dt.utcnow',
|
||||
return_value=now):
|
||||
self.hass.bus.fire('test_event')
|
||||
self.hass.block_till_done()
|
||||
@@ -203,10 +184,6 @@ class TestAutomationSun(unittest.TestCase):
|
||||
|
||||
def test_if_action_after(self):
|
||||
"""Test if action was after."""
|
||||
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
|
||||
sun.STATE_ATTR_NEXT_RISING: '2015-09-16T14:00:00Z',
|
||||
})
|
||||
|
||||
setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
@@ -224,14 +201,14 @@ class TestAutomationSun(unittest.TestCase):
|
||||
})
|
||||
|
||||
now = datetime(2015, 9, 16, 13, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.now',
|
||||
with patch('homeassistant.util.dt.utcnow',
|
||||
return_value=now):
|
||||
self.hass.bus.fire('test_event')
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(0, len(self.calls))
|
||||
|
||||
now = datetime(2015, 9, 16, 15, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.now',
|
||||
with patch('homeassistant.util.dt.utcnow',
|
||||
return_value=now):
|
||||
self.hass.bus.fire('test_event')
|
||||
self.hass.block_till_done()
|
||||
@@ -239,10 +216,6 @@ class TestAutomationSun(unittest.TestCase):
|
||||
|
||||
def test_if_action_before_with_offset(self):
|
||||
"""Test if action was before offset."""
|
||||
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
|
||||
sun.STATE_ATTR_NEXT_RISING: '2015-09-16T14:00:00Z',
|
||||
})
|
||||
|
||||
setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
@@ -260,15 +233,15 @@ class TestAutomationSun(unittest.TestCase):
|
||||
}
|
||||
})
|
||||
|
||||
now = datetime(2015, 9, 16, 15, 1, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.now',
|
||||
now = datetime(2015, 9, 16, 14, 32, 44, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.utcnow',
|
||||
return_value=now):
|
||||
self.hass.bus.fire('test_event')
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(0, len(self.calls))
|
||||
|
||||
now = datetime(2015, 9, 16, 15, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.now',
|
||||
now = datetime(2015, 9, 16, 14, 32, 43, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.utcnow',
|
||||
return_value=now):
|
||||
self.hass.bus.fire('test_event')
|
||||
self.hass.block_till_done()
|
||||
@@ -276,10 +249,6 @@ class TestAutomationSun(unittest.TestCase):
|
||||
|
||||
def test_if_action_after_with_offset(self):
|
||||
"""Test if action was after offset."""
|
||||
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
|
||||
sun.STATE_ATTR_NEXT_RISING: '2015-09-16T14:00:00Z',
|
||||
})
|
||||
|
||||
setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
@@ -297,15 +266,15 @@ class TestAutomationSun(unittest.TestCase):
|
||||
}
|
||||
})
|
||||
|
||||
now = datetime(2015, 9, 16, 14, 59, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.now',
|
||||
now = datetime(2015, 9, 16, 14, 32, 42, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.utcnow',
|
||||
return_value=now):
|
||||
self.hass.bus.fire('test_event')
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(0, len(self.calls))
|
||||
|
||||
now = datetime(2015, 9, 16, 15, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.now',
|
||||
now = datetime(2015, 9, 16, 14, 32, 43, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.utcnow',
|
||||
return_value=now):
|
||||
self.hass.bus.fire('test_event')
|
||||
self.hass.block_till_done()
|
||||
@@ -313,11 +282,6 @@ class TestAutomationSun(unittest.TestCase):
|
||||
|
||||
def test_if_action_before_and_after_during(self):
|
||||
"""Test if action was before and after during."""
|
||||
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
|
||||
sun.STATE_ATTR_NEXT_RISING: '2015-09-16T10:00:00Z',
|
||||
sun.STATE_ATTR_NEXT_SETTING: '2015-09-16T15:00:00Z',
|
||||
})
|
||||
|
||||
setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
@@ -335,62 +299,22 @@ class TestAutomationSun(unittest.TestCase):
|
||||
}
|
||||
})
|
||||
|
||||
now = datetime(2015, 9, 16, 9, 59, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.now',
|
||||
now = datetime(2015, 9, 16, 13, 8, 51, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.utcnow',
|
||||
return_value=now):
|
||||
self.hass.bus.fire('test_event')
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(0, len(self.calls))
|
||||
|
||||
now = datetime(2015, 9, 16, 15, 1, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.now',
|
||||
now = datetime(2015, 9, 17, 2, 25, 18, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.utcnow',
|
||||
return_value=now):
|
||||
self.hass.bus.fire('test_event')
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(0, len(self.calls))
|
||||
|
||||
now = datetime(2015, 9, 16, 12, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.now',
|
||||
return_value=now):
|
||||
self.hass.bus.fire('test_event')
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(1, len(self.calls))
|
||||
|
||||
def test_if_action_after_different_tz(self):
|
||||
"""Test if action was after in a different timezone."""
|
||||
import pytz
|
||||
|
||||
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
|
||||
sun.STATE_ATTR_NEXT_SETTING: '2015-09-16T17:30:00Z',
|
||||
})
|
||||
|
||||
setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
'platform': 'event',
|
||||
'event_type': 'test_event',
|
||||
},
|
||||
'condition': {
|
||||
'condition': 'sun',
|
||||
'after': 'sunset',
|
||||
},
|
||||
'action': {
|
||||
'service': 'test.automation'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
# Before
|
||||
now = datetime(2015, 9, 16, 17, tzinfo=pytz.timezone('US/Mountain'))
|
||||
with patch('homeassistant.util.dt.now',
|
||||
return_value=now):
|
||||
self.hass.bus.fire('test_event')
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(0, len(self.calls))
|
||||
|
||||
# After
|
||||
now = datetime(2015, 9, 16, 18, tzinfo=pytz.timezone('US/Mountain'))
|
||||
with patch('homeassistant.util.dt.now',
|
||||
now = datetime(2015, 9, 16, 16, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.utcnow',
|
||||
return_value=now):
|
||||
self.hass.bus.fire('test_event')
|
||||
self.hass.block_till_done()
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
"""The tests for the Flux switch platform."""
|
||||
from datetime import timedelta
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
@@ -86,28 +85,30 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
self.assertIsNone(state.attributes.get('xy_color'))
|
||||
self.assertIsNone(state.attributes.get('brightness'))
|
||||
|
||||
test_time = dt_util.now().replace(hour=10, minute=30,
|
||||
second=0)
|
||||
sunset_time = test_time.replace(hour=17, minute=0,
|
||||
second=0)
|
||||
sunrise_time = test_time.replace(hour=5, minute=0,
|
||||
second=0) + timedelta(days=1)
|
||||
test_time = dt_util.now().replace(hour=10, minute=30, second=0)
|
||||
sunset_time = test_time.replace(hour=17, minute=0, second=0)
|
||||
sunrise_time = test_time.replace(hour=5, minute=0, second=0)
|
||||
|
||||
def event_date(hass, event, now=None):
|
||||
if event == 'sunrise':
|
||||
return sunrise_time
|
||||
else:
|
||||
return sunset_time
|
||||
|
||||
with patch('homeassistant.util.dt.now', return_value=test_time):
|
||||
with patch('homeassistant.components.sun.next_rising',
|
||||
return_value=sunrise_time):
|
||||
with patch('homeassistant.components.sun.next_setting',
|
||||
return_value=sunset_time):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id]
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
with patch('homeassistant.helpers.sun.get_astral_event_date',
|
||||
side_effect=event_date):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id]
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(0, len(turn_on_calls))
|
||||
|
||||
def test_flux_before_sunrise(self):
|
||||
@@ -126,30 +127,32 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
self.assertIsNone(state.attributes.get('xy_color'))
|
||||
self.assertIsNone(state.attributes.get('brightness'))
|
||||
|
||||
test_time = dt_util.now().replace(hour=2, minute=30,
|
||||
second=0)
|
||||
sunset_time = test_time.replace(hour=17, minute=0,
|
||||
second=0)
|
||||
sunrise_time = test_time.replace(hour=5, minute=0,
|
||||
second=0) + timedelta(days=1)
|
||||
test_time = dt_util.now().replace(hour=2, minute=30, second=0)
|
||||
sunset_time = test_time.replace(hour=17, minute=0, second=0)
|
||||
sunrise_time = test_time.replace(hour=5, minute=0, second=0)
|
||||
|
||||
def event_date(hass, event, now=None):
|
||||
if event == 'sunrise':
|
||||
return sunrise_time
|
||||
else:
|
||||
return sunset_time
|
||||
|
||||
with patch('homeassistant.util.dt.now', return_value=test_time):
|
||||
with patch('homeassistant.components.sun.next_rising',
|
||||
return_value=sunrise_time):
|
||||
with patch('homeassistant.components.sun.next_setting',
|
||||
return_value=sunset_time):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id]
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
switch.turn_on(self.hass, 'switch.flux')
|
||||
self.hass.block_till_done()
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
with patch('homeassistant.helpers.sun.get_astral_event_date',
|
||||
side_effect=event_date):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id]
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
switch.turn_on(self.hass, 'switch.flux')
|
||||
self.hass.block_till_done()
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
call = turn_on_calls[-1]
|
||||
self.assertEqual(call.data[light.ATTR_BRIGHTNESS], 119)
|
||||
self.assertEqual(call.data[light.ATTR_XY_COLOR], [0.591, 0.395])
|
||||
@@ -173,28 +176,30 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
test_time = dt_util.now().replace(hour=8, minute=30, second=0)
|
||||
sunset_time = test_time.replace(hour=17, minute=0, second=0)
|
||||
sunrise_time = test_time.replace(hour=5,
|
||||
minute=0,
|
||||
second=0) + timedelta(days=1)
|
||||
sunrise_time = test_time.replace(hour=5, minute=0, second=0)
|
||||
|
||||
def event_date(hass, event, now=None):
|
||||
if event == 'sunrise':
|
||||
return sunrise_time
|
||||
else:
|
||||
return sunset_time
|
||||
|
||||
with patch('homeassistant.util.dt.now', return_value=test_time):
|
||||
with patch('homeassistant.components.sun.next_rising',
|
||||
return_value=sunrise_time):
|
||||
with patch('homeassistant.components.sun.next_setting',
|
||||
return_value=sunset_time):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id]
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
switch.turn_on(self.hass, 'switch.flux')
|
||||
self.hass.block_till_done()
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
with patch('homeassistant.helpers.sun.get_astral_event_date',
|
||||
side_effect=event_date):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id]
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
switch.turn_on(self.hass, 'switch.flux')
|
||||
self.hass.block_till_done()
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
call = turn_on_calls[-1]
|
||||
self.assertEqual(call.data[light.ATTR_BRIGHTNESS], 180)
|
||||
self.assertEqual(call.data[light.ATTR_XY_COLOR], [0.431, 0.38])
|
||||
@@ -218,28 +223,30 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
test_time = dt_util.now().replace(hour=17, minute=30, second=0)
|
||||
sunset_time = test_time.replace(hour=17, minute=0, second=0)
|
||||
sunrise_time = test_time.replace(hour=5,
|
||||
minute=0,
|
||||
second=0) + timedelta(days=1)
|
||||
sunrise_time = test_time.replace(hour=5, minute=0, second=0)
|
||||
|
||||
def event_date(hass, event, now=None):
|
||||
if event == 'sunrise':
|
||||
return sunrise_time
|
||||
else:
|
||||
return sunset_time
|
||||
|
||||
with patch('homeassistant.util.dt.now', return_value=test_time):
|
||||
with patch('homeassistant.components.sun.next_rising',
|
||||
return_value=sunrise_time):
|
||||
with patch('homeassistant.components.sun.next_setting',
|
||||
return_value=sunset_time):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id]
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
switch.turn_on(self.hass, 'switch.flux')
|
||||
self.hass.block_till_done()
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
with patch('homeassistant.helpers.sun.get_astral_event_date',
|
||||
side_effect=event_date):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id]
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
switch.turn_on(self.hass, 'switch.flux')
|
||||
self.hass.block_till_done()
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
call = turn_on_calls[-1]
|
||||
self.assertEqual(call.data[light.ATTR_BRIGHTNESS], 153)
|
||||
self.assertEqual(call.data[light.ATTR_XY_COLOR], [0.496, 0.397])
|
||||
@@ -263,28 +270,30 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
test_time = dt_util.now().replace(hour=23, minute=30, second=0)
|
||||
sunset_time = test_time.replace(hour=17, minute=0, second=0)
|
||||
sunrise_time = test_time.replace(hour=5,
|
||||
minute=0,
|
||||
second=0) + timedelta(days=1)
|
||||
sunrise_time = test_time.replace(hour=5, minute=0, second=0)
|
||||
|
||||
def event_date(hass, event, now=None):
|
||||
if event == 'sunrise':
|
||||
return sunrise_time
|
||||
else:
|
||||
return sunset_time
|
||||
|
||||
with patch('homeassistant.util.dt.now', return_value=test_time):
|
||||
with patch('homeassistant.components.sun.next_rising',
|
||||
return_value=sunrise_time):
|
||||
with patch('homeassistant.components.sun.next_setting',
|
||||
return_value=sunset_time):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id]
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
switch.turn_on(self.hass, 'switch.flux')
|
||||
self.hass.block_till_done()
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
with patch('homeassistant.helpers.sun.get_astral_event_date',
|
||||
side_effect=event_date):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id]
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
switch.turn_on(self.hass, 'switch.flux')
|
||||
self.hass.block_till_done()
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
call = turn_on_calls[-1]
|
||||
self.assertEqual(call.data[light.ATTR_BRIGHTNESS], 119)
|
||||
self.assertEqual(call.data[light.ATTR_XY_COLOR], [0.591, 0.395])
|
||||
@@ -308,30 +317,32 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
test_time = dt_util.now().replace(hour=17, minute=30, second=0)
|
||||
sunset_time = test_time.replace(hour=17, minute=0, second=0)
|
||||
sunrise_time = test_time.replace(hour=5,
|
||||
minute=0,
|
||||
second=0) + timedelta(days=1)
|
||||
sunrise_time = test_time.replace(hour=5, minute=0, second=0)
|
||||
|
||||
def event_date(hass, event, now=None):
|
||||
if event == 'sunrise':
|
||||
return sunrise_time
|
||||
else:
|
||||
return sunset_time
|
||||
|
||||
with patch('homeassistant.util.dt.now', return_value=test_time):
|
||||
with patch('homeassistant.components.sun.next_rising',
|
||||
return_value=sunrise_time):
|
||||
with patch('homeassistant.components.sun.next_setting',
|
||||
return_value=sunset_time):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id],
|
||||
'start_time': '6:00',
|
||||
'stop_time': '23:30'
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
switch.turn_on(self.hass, 'switch.flux')
|
||||
self.hass.block_till_done()
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
with patch('homeassistant.helpers.sun.get_astral_event_date',
|
||||
side_effect=event_date):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id],
|
||||
'start_time': '6:00',
|
||||
'stop_time': '23:30'
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
switch.turn_on(self.hass, 'switch.flux')
|
||||
self.hass.block_till_done()
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
call = turn_on_calls[-1]
|
||||
self.assertEqual(call.data[light.ATTR_BRIGHTNESS], 154)
|
||||
self.assertEqual(call.data[light.ATTR_XY_COLOR], [0.494, 0.397])
|
||||
@@ -355,30 +366,32 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
test_time = dt_util.now().replace(hour=17, minute=30, second=0)
|
||||
sunset_time = test_time.replace(hour=17, minute=0, second=0)
|
||||
sunrise_time = test_time.replace(hour=5,
|
||||
minute=0,
|
||||
second=0) + timedelta(days=1)
|
||||
sunrise_time = test_time.replace(hour=5, minute=0, second=0)
|
||||
|
||||
def event_date(hass, event, now=None):
|
||||
if event == 'sunrise':
|
||||
return sunrise_time
|
||||
else:
|
||||
return sunset_time
|
||||
|
||||
with patch('homeassistant.util.dt.now', return_value=test_time):
|
||||
with patch('homeassistant.components.sun.next_rising',
|
||||
return_value=sunrise_time):
|
||||
with patch('homeassistant.components.sun.next_setting',
|
||||
return_value=sunset_time):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id],
|
||||
'start_colortemp': '1000',
|
||||
'stop_colortemp': '6000'
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
switch.turn_on(self.hass, 'switch.flux')
|
||||
self.hass.block_till_done()
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
with patch('homeassistant.helpers.sun.get_astral_event_date',
|
||||
side_effect=event_date):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id],
|
||||
'start_colortemp': '1000',
|
||||
'stop_colortemp': '6000'
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
switch.turn_on(self.hass, 'switch.flux')
|
||||
self.hass.block_till_done()
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
call = turn_on_calls[-1]
|
||||
self.assertEqual(call.data[light.ATTR_BRIGHTNESS], 167)
|
||||
self.assertEqual(call.data[light.ATTR_XY_COLOR], [0.461, 0.389])
|
||||
@@ -402,29 +415,31 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
test_time = dt_util.now().replace(hour=17, minute=30, second=0)
|
||||
sunset_time = test_time.replace(hour=17, minute=0, second=0)
|
||||
sunrise_time = test_time.replace(hour=5,
|
||||
minute=0,
|
||||
second=0) + timedelta(days=1)
|
||||
sunrise_time = test_time.replace(hour=5, minute=0, second=0)
|
||||
|
||||
def event_date(hass, event, now=None):
|
||||
if event == 'sunrise':
|
||||
return sunrise_time
|
||||
else:
|
||||
return sunset_time
|
||||
|
||||
with patch('homeassistant.util.dt.now', return_value=test_time):
|
||||
with patch('homeassistant.components.sun.next_rising',
|
||||
return_value=sunrise_time):
|
||||
with patch('homeassistant.components.sun.next_setting',
|
||||
return_value=sunset_time):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id],
|
||||
'brightness': 255
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
switch.turn_on(self.hass, 'switch.flux')
|
||||
self.hass.block_till_done()
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
with patch('homeassistant.helpers.sun.get_astral_event_date',
|
||||
side_effect=event_date):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id],
|
||||
'brightness': 255
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
switch.turn_on(self.hass, 'switch.flux')
|
||||
self.hass.block_till_done()
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
call = turn_on_calls[-1]
|
||||
self.assertEqual(call.data[light.ATTR_BRIGHTNESS], 255)
|
||||
self.assertEqual(call.data[light.ATTR_XY_COLOR], [0.496, 0.397])
|
||||
@@ -460,30 +475,34 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
test_time = dt_util.now().replace(hour=12, minute=0, second=0)
|
||||
sunset_time = test_time.replace(hour=17, minute=0, second=0)
|
||||
sunrise_time = test_time.replace(hour=5,
|
||||
minute=0,
|
||||
second=0) + timedelta(days=1)
|
||||
sunrise_time = test_time.replace(hour=5, minute=0, second=0)
|
||||
|
||||
def event_date(hass, event, now=None):
|
||||
if event == 'sunrise':
|
||||
print('sunrise {}'.format(sunrise_time))
|
||||
return sunrise_time
|
||||
else:
|
||||
print('sunset {}'.format(sunset_time))
|
||||
return sunset_time
|
||||
|
||||
with patch('homeassistant.util.dt.now', return_value=test_time):
|
||||
with patch('homeassistant.components.sun.next_rising',
|
||||
return_value=sunrise_time):
|
||||
with patch('homeassistant.components.sun.next_setting',
|
||||
return_value=sunset_time):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id,
|
||||
dev2.entity_id,
|
||||
dev3.entity_id]
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
switch.turn_on(self.hass, 'switch.flux')
|
||||
self.hass.block_till_done()
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
with patch('homeassistant.helpers.sun.get_astral_event_date',
|
||||
side_effect=event_date):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id,
|
||||
dev2.entity_id,
|
||||
dev3.entity_id]
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
switch.turn_on(self.hass, 'switch.flux')
|
||||
self.hass.block_till_done()
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
call = turn_on_calls[-1]
|
||||
self.assertEqual(call.data[light.ATTR_BRIGHTNESS], 171)
|
||||
self.assertEqual(call.data[light.ATTR_XY_COLOR], [0.452, 0.386])
|
||||
@@ -511,28 +530,30 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
test_time = dt_util.now().replace(hour=8, minute=30, second=0)
|
||||
sunset_time = test_time.replace(hour=17, minute=0, second=0)
|
||||
sunrise_time = test_time.replace(hour=5,
|
||||
minute=0,
|
||||
second=0) + timedelta(days=1)
|
||||
sunrise_time = test_time.replace(hour=5, minute=0, second=0)
|
||||
|
||||
def event_date(hass, event, now=None):
|
||||
if event == 'sunrise':
|
||||
return sunrise_time
|
||||
else:
|
||||
return sunset_time
|
||||
|
||||
with patch('homeassistant.util.dt.now', return_value=test_time):
|
||||
with patch('homeassistant.components.sun.next_rising',
|
||||
return_value=sunrise_time):
|
||||
with patch('homeassistant.components.sun.next_setting',
|
||||
return_value=sunset_time):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id],
|
||||
'mode': 'mired'
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
switch.turn_on(self.hass, 'switch.flux')
|
||||
self.hass.block_till_done()
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
with patch('homeassistant.helpers.sun.get_astral_event_date',
|
||||
side_effect=event_date):
|
||||
assert setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'flux',
|
||||
'name': 'flux',
|
||||
'lights': [dev1.entity_id],
|
||||
'mode': 'mired'
|
||||
}
|
||||
})
|
||||
turn_on_calls = mock_service(
|
||||
self.hass, light.DOMAIN, SERVICE_TURN_ON)
|
||||
switch.turn_on(self.hass, 'switch.flux')
|
||||
self.hass.block_till_done()
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
call = turn_on_calls[-1]
|
||||
self.assertEqual(call.data[light.ATTR_COLOR_TEMP], 269)
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
"""The tests device sun light trigger component."""
|
||||
# pylint: disable=protected-access
|
||||
from datetime import datetime
|
||||
import os
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.setup import setup_component
|
||||
import homeassistant.loader as loader
|
||||
from homeassistant.const import CONF_PLATFORM, STATE_HOME, STATE_NOT_HOME
|
||||
from homeassistant.components import (
|
||||
device_tracker, light, sun, device_sun_light_trigger)
|
||||
device_tracker, light, device_sun_light_trigger)
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from tests.common import (
|
||||
get_test_config_dir, get_test_home_assistant, ensure_sun_risen,
|
||||
ensure_sun_set)
|
||||
get_test_config_dir, get_test_home_assistant, fire_time_changed)
|
||||
|
||||
|
||||
KNOWN_DEV_YAML_PATH = os.path.join(get_test_config_dir(),
|
||||
@@ -61,26 +63,26 @@ class TestDeviceSunLightTrigger(unittest.TestCase):
|
||||
light.DOMAIN: {CONF_PLATFORM: 'test'}
|
||||
}))
|
||||
|
||||
self.assertTrue(setup_component(self.hass, sun.DOMAIN, {
|
||||
sun.DOMAIN: {sun.CONF_ELEVATION: 0}}))
|
||||
|
||||
def tearDown(self): # pylint: disable=invalid-name
|
||||
"""Stop everything that was started."""
|
||||
self.hass.stop()
|
||||
|
||||
def test_lights_on_when_sun_sets(self):
|
||||
"""Test lights go on when there is someone home and the sun sets."""
|
||||
self.assertTrue(setup_component(
|
||||
self.hass, device_sun_light_trigger.DOMAIN, {
|
||||
device_sun_light_trigger.DOMAIN: {}}))
|
||||
test_time = datetime(2017, 4, 5, 1, 2, 3, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.utcnow', return_value=test_time):
|
||||
self.assertTrue(setup_component(
|
||||
self.hass, device_sun_light_trigger.DOMAIN, {
|
||||
device_sun_light_trigger.DOMAIN: {}}))
|
||||
|
||||
ensure_sun_risen(self.hass)
|
||||
light.turn_off(self.hass)
|
||||
|
||||
self.hass.block_till_done()
|
||||
|
||||
ensure_sun_set(self.hass)
|
||||
self.hass.block_till_done()
|
||||
test_time = test_time.replace(hour=3)
|
||||
with patch('homeassistant.util.dt.utcnow', return_value=test_time):
|
||||
fire_time_changed(self.hass, test_time)
|
||||
self.hass.block_till_done()
|
||||
|
||||
self.assertTrue(light.is_on(self.hass))
|
||||
|
||||
@@ -105,17 +107,17 @@ class TestDeviceSunLightTrigger(unittest.TestCase):
|
||||
def test_lights_turn_on_when_coming_home_after_sun_set(self): \
|
||||
# pylint: disable=invalid-name
|
||||
"""Test lights turn on when coming home after sun set."""
|
||||
light.turn_off(self.hass)
|
||||
ensure_sun_set(self.hass)
|
||||
test_time = datetime(2017, 4, 5, 3, 2, 3, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.util.dt.utcnow', return_value=test_time):
|
||||
light.turn_off(self.hass)
|
||||
self.hass.block_till_done()
|
||||
|
||||
self.hass.block_till_done()
|
||||
self.assertTrue(setup_component(
|
||||
self.hass, device_sun_light_trigger.DOMAIN, {
|
||||
device_sun_light_trigger.DOMAIN: {}}))
|
||||
|
||||
self.assertTrue(setup_component(
|
||||
self.hass, device_sun_light_trigger.DOMAIN, {
|
||||
device_sun_light_trigger.DOMAIN: {}}))
|
||||
self.hass.states.set(
|
||||
device_tracker.ENTITY_ID_FORMAT.format('device_2'), STATE_HOME)
|
||||
|
||||
self.hass.states.set(
|
||||
device_tracker.ENTITY_ID_FORMAT.format('device_2'), STATE_HOME)
|
||||
|
||||
self.hass.block_till_done()
|
||||
self.hass.block_till_done()
|
||||
self.assertTrue(light.is_on(self.hass))
|
||||
|
||||
@@ -24,118 +24,111 @@ class TestSun(unittest.TestCase):
|
||||
"""Stop everything that was started."""
|
||||
self.hass.stop()
|
||||
|
||||
def test_is_on(self):
|
||||
"""Test is_on method."""
|
||||
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON)
|
||||
self.assertTrue(sun.is_on(self.hass))
|
||||
self.hass.states.set(sun.ENTITY_ID, sun.STATE_BELOW_HORIZON)
|
||||
self.assertFalse(sun.is_on(self.hass))
|
||||
|
||||
def test_setting_rising(self):
|
||||
"""Test retrieving sun setting and rising."""
|
||||
setup_component(self.hass, sun.DOMAIN, {
|
||||
sun.DOMAIN: {sun.CONF_ELEVATION: 0}})
|
||||
utc_now = datetime(2016, 11, 1, 8, 0, 0, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.helpers.condition.dt_util.utcnow',
|
||||
return_value=utc_now):
|
||||
setup_component(self.hass, sun.DOMAIN, {
|
||||
sun.DOMAIN: {sun.CONF_ELEVATION: 0}})
|
||||
|
||||
self.hass.block_till_done()
|
||||
state = self.hass.states.get(sun.ENTITY_ID)
|
||||
|
||||
from astral import Astral
|
||||
|
||||
astral = Astral()
|
||||
utc_now = dt_util.utcnow()
|
||||
utc_today = utc_now.date()
|
||||
|
||||
latitude = self.hass.config.latitude
|
||||
longitude = self.hass.config.longitude
|
||||
|
||||
mod = -1
|
||||
while True:
|
||||
next_dawn = (astral.dawn_utc(utc_now +
|
||||
timedelta(days=mod), latitude, longitude))
|
||||
next_dawn = (astral.dawn_utc(
|
||||
utc_today + timedelta(days=mod), latitude, longitude))
|
||||
if next_dawn > utc_now:
|
||||
break
|
||||
mod += 1
|
||||
|
||||
mod = -1
|
||||
while True:
|
||||
next_dusk = (astral.dusk_utc(utc_now +
|
||||
timedelta(days=mod), latitude, longitude))
|
||||
next_dusk = (astral.dusk_utc(
|
||||
utc_today + timedelta(days=mod), latitude, longitude))
|
||||
if next_dusk > utc_now:
|
||||
break
|
||||
mod += 1
|
||||
|
||||
mod = -1
|
||||
while True:
|
||||
next_midnight = (astral.solar_midnight_utc(utc_now +
|
||||
timedelta(days=mod), longitude))
|
||||
next_midnight = (astral.solar_midnight_utc(
|
||||
utc_today + timedelta(days=mod), longitude))
|
||||
if next_midnight > utc_now:
|
||||
break
|
||||
mod += 1
|
||||
|
||||
mod = -1
|
||||
while True:
|
||||
next_noon = (astral.solar_noon_utc(utc_now +
|
||||
timedelta(days=mod), longitude))
|
||||
next_noon = (astral.solar_noon_utc(
|
||||
utc_today + timedelta(days=mod), longitude))
|
||||
if next_noon > utc_now:
|
||||
break
|
||||
mod += 1
|
||||
|
||||
mod = -1
|
||||
while True:
|
||||
next_rising = (astral.sunrise_utc(utc_now +
|
||||
timedelta(days=mod), latitude, longitude))
|
||||
next_rising = (astral.sunrise_utc(
|
||||
utc_today + timedelta(days=mod), latitude, longitude))
|
||||
if next_rising > utc_now:
|
||||
break
|
||||
mod += 1
|
||||
|
||||
mod = -1
|
||||
while True:
|
||||
next_setting = (astral.sunset_utc(utc_now +
|
||||
timedelta(days=mod), latitude, longitude))
|
||||
next_setting = (astral.sunset_utc(
|
||||
utc_today + timedelta(days=mod), latitude, longitude))
|
||||
if next_setting > utc_now:
|
||||
break
|
||||
mod += 1
|
||||
|
||||
self.assertEqual(next_dawn, sun.next_dawn_utc(self.hass))
|
||||
self.assertEqual(next_dusk, sun.next_dusk_utc(self.hass))
|
||||
self.assertEqual(next_midnight, sun.next_midnight_utc(self.hass))
|
||||
self.assertEqual(next_noon, sun.next_noon_utc(self.hass))
|
||||
self.assertEqual(next_rising, sun.next_rising_utc(self.hass))
|
||||
self.assertEqual(next_setting, sun.next_setting_utc(self.hass))
|
||||
|
||||
# Point it at a state without the proper attributes
|
||||
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON)
|
||||
self.assertIsNone(sun.next_dawn(self.hass))
|
||||
self.assertIsNone(sun.next_dusk(self.hass))
|
||||
self.assertIsNone(sun.next_midnight(self.hass))
|
||||
self.assertIsNone(sun.next_noon(self.hass))
|
||||
self.assertIsNone(sun.next_rising(self.hass))
|
||||
self.assertIsNone(sun.next_setting(self.hass))
|
||||
|
||||
# Point it at a non-existing state
|
||||
self.assertIsNone(sun.next_dawn(self.hass, 'non.existing'))
|
||||
self.assertIsNone(sun.next_dusk(self.hass, 'non.existing'))
|
||||
self.assertIsNone(sun.next_midnight(self.hass, 'non.existing'))
|
||||
self.assertIsNone(sun.next_noon(self.hass, 'non.existing'))
|
||||
self.assertIsNone(sun.next_rising(self.hass, 'non.existing'))
|
||||
self.assertIsNone(sun.next_setting(self.hass, 'non.existing'))
|
||||
self.assertEqual(next_dawn, dt_util.parse_datetime(
|
||||
state.attributes[sun.STATE_ATTR_NEXT_DAWN]))
|
||||
self.assertEqual(next_dusk, dt_util.parse_datetime(
|
||||
state.attributes[sun.STATE_ATTR_NEXT_DUSK]))
|
||||
self.assertEqual(next_midnight, dt_util.parse_datetime(
|
||||
state.attributes[sun.STATE_ATTR_NEXT_MIDNIGHT]))
|
||||
self.assertEqual(next_noon, dt_util.parse_datetime(
|
||||
state.attributes[sun.STATE_ATTR_NEXT_NOON]))
|
||||
self.assertEqual(next_rising, dt_util.parse_datetime(
|
||||
state.attributes[sun.STATE_ATTR_NEXT_RISING]))
|
||||
self.assertEqual(next_setting, dt_util.parse_datetime(
|
||||
state.attributes[sun.STATE_ATTR_NEXT_SETTING]))
|
||||
|
||||
def test_state_change(self):
|
||||
"""Test if the state changes at next setting/rising."""
|
||||
setup_component(self.hass, sun.DOMAIN, {
|
||||
sun.DOMAIN: {sun.CONF_ELEVATION: 0}})
|
||||
now = datetime(2016, 6, 1, 8, 0, 0, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.helpers.condition.dt_util.utcnow',
|
||||
return_value=now):
|
||||
setup_component(self.hass, sun.DOMAIN, {
|
||||
sun.DOMAIN: {sun.CONF_ELEVATION: 0}})
|
||||
|
||||
if sun.is_on(self.hass):
|
||||
test_state = sun.STATE_BELOW_HORIZON
|
||||
test_time = sun.next_setting(self.hass)
|
||||
else:
|
||||
test_state = sun.STATE_ABOVE_HORIZON
|
||||
test_time = sun.next_rising(self.hass)
|
||||
self.hass.block_till_done()
|
||||
|
||||
test_time = dt_util.parse_datetime(
|
||||
self.hass.states.get(sun.ENTITY_ID)
|
||||
.attributes[sun.STATE_ATTR_NEXT_RISING])
|
||||
self.assertIsNotNone(test_time)
|
||||
|
||||
self.assertEqual(sun.STATE_BELOW_HORIZON,
|
||||
self.hass.states.get(sun.ENTITY_ID).state)
|
||||
|
||||
self.hass.bus.fire(ha.EVENT_TIME_CHANGED,
|
||||
{ha.ATTR_NOW: test_time + timedelta(seconds=5)})
|
||||
|
||||
self.hass.block_till_done()
|
||||
|
||||
self.assertEqual(test_state, self.hass.states.get(sun.ENTITY_ID).state)
|
||||
self.assertEqual(sun.STATE_ABOVE_HORIZON,
|
||||
self.hass.states.get(sun.ENTITY_ID).state)
|
||||
|
||||
def test_norway_in_june(self):
|
||||
"""Test location in Norway where the sun doesn't set in summer."""
|
||||
@@ -150,9 +143,11 @@ class TestSun(unittest.TestCase):
|
||||
sun.DOMAIN: {sun.CONF_ELEVATION: 0}})
|
||||
|
||||
state = self.hass.states.get(sun.ENTITY_ID)
|
||||
|
||||
assert state is not None
|
||||
assert sun.next_rising_utc(self.hass) == \
|
||||
|
||||
assert dt_util.parse_datetime(
|
||||
state.attributes[sun.STATE_ATTR_NEXT_RISING]) == \
|
||||
datetime(2016, 7, 25, 23, 23, 39, tzinfo=dt_util.UTC)
|
||||
assert sun.next_setting_utc(self.hass) == \
|
||||
assert dt_util.parse_datetime(
|
||||
state.attributes[sun.STATE_ATTR_NEXT_SETTING]) == \
|
||||
datetime(2016, 7, 26, 22, 19, 1, tzinfo=dt_util.UTC)
|
||||
|
||||
+23
-15
@@ -25,6 +25,7 @@ from homeassistant.components import sun
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from tests.common import get_test_home_assistant
|
||||
from unittest.mock import patch
|
||||
|
||||
|
||||
class TestEventHelpers(unittest.TestCase):
|
||||
@@ -302,24 +303,27 @@ class TestEventHelpers(unittest.TestCase):
|
||||
|
||||
# Get next sunrise/sunset
|
||||
astral = Astral()
|
||||
utc_now = dt_util.utcnow()
|
||||
utc_now = datetime(2014, 5, 24, 12, 0, 0, tzinfo=dt_util.UTC)
|
||||
utc_today = utc_now.date()
|
||||
|
||||
mod = -1
|
||||
while True:
|
||||
next_rising = (astral.sunrise_utc(utc_now +
|
||||
timedelta(days=mod), latitude, longitude))
|
||||
next_rising = (astral.sunrise_utc(
|
||||
utc_today + timedelta(days=mod), latitude, longitude))
|
||||
if next_rising > utc_now:
|
||||
break
|
||||
mod += 1
|
||||
|
||||
# Track sunrise
|
||||
runs = []
|
||||
unsub = track_sunrise(self.hass, lambda: runs.append(1))
|
||||
with patch('homeassistant.util.dt.utcnow', return_value=utc_now):
|
||||
unsub = track_sunrise(self.hass, lambda: runs.append(1))
|
||||
|
||||
offset_runs = []
|
||||
offset = timedelta(minutes=30)
|
||||
unsub2 = track_sunrise(self.hass, lambda: offset_runs.append(1),
|
||||
offset)
|
||||
with patch('homeassistant.util.dt.utcnow', return_value=utc_now):
|
||||
unsub2 = track_sunrise(self.hass, lambda: offset_runs.append(1),
|
||||
offset)
|
||||
|
||||
# run tests
|
||||
self._send_time_changed(next_rising - offset)
|
||||
@@ -334,7 +338,7 @@ class TestEventHelpers(unittest.TestCase):
|
||||
|
||||
self._send_time_changed(next_rising + offset)
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(2, len(runs))
|
||||
self.assertEqual(1, len(runs))
|
||||
self.assertEqual(1, len(offset_runs))
|
||||
|
||||
unsub()
|
||||
@@ -342,7 +346,7 @@ class TestEventHelpers(unittest.TestCase):
|
||||
|
||||
self._send_time_changed(next_rising + offset)
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(2, len(runs))
|
||||
self.assertEqual(1, len(runs))
|
||||
self.assertEqual(1, len(offset_runs))
|
||||
|
||||
def test_track_sunset(self):
|
||||
@@ -358,23 +362,27 @@ class TestEventHelpers(unittest.TestCase):
|
||||
|
||||
# Get next sunrise/sunset
|
||||
astral = Astral()
|
||||
utc_now = dt_util.utcnow()
|
||||
utc_now = datetime(2014, 5, 24, 12, 0, 0, tzinfo=dt_util.UTC)
|
||||
utc_today = utc_now.date()
|
||||
|
||||
mod = -1
|
||||
while True:
|
||||
next_setting = (astral.sunset_utc(utc_now +
|
||||
timedelta(days=mod), latitude, longitude))
|
||||
next_setting = (astral.sunset_utc(
|
||||
utc_today + timedelta(days=mod), latitude, longitude))
|
||||
if next_setting > utc_now:
|
||||
break
|
||||
mod += 1
|
||||
|
||||
# Track sunset
|
||||
runs = []
|
||||
unsub = track_sunset(self.hass, lambda: runs.append(1))
|
||||
with patch('homeassistant.util.dt.utcnow', return_value=utc_now):
|
||||
unsub = track_sunset(self.hass, lambda: runs.append(1))
|
||||
|
||||
offset_runs = []
|
||||
offset = timedelta(minutes=30)
|
||||
unsub2 = track_sunset(self.hass, lambda: offset_runs.append(1), offset)
|
||||
with patch('homeassistant.util.dt.utcnow', return_value=utc_now):
|
||||
unsub2 = track_sunset(
|
||||
self.hass, lambda: offset_runs.append(1), offset)
|
||||
|
||||
# Run tests
|
||||
self._send_time_changed(next_setting - offset)
|
||||
@@ -389,7 +397,7 @@ class TestEventHelpers(unittest.TestCase):
|
||||
|
||||
self._send_time_changed(next_setting + offset)
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(2, len(runs))
|
||||
self.assertEqual(1, len(runs))
|
||||
self.assertEqual(1, len(offset_runs))
|
||||
|
||||
unsub()
|
||||
@@ -397,7 +405,7 @@ class TestEventHelpers(unittest.TestCase):
|
||||
|
||||
self._send_time_changed(next_setting + offset)
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(2, len(runs))
|
||||
self.assertEqual(1, len(runs))
|
||||
self.assertEqual(1, len(offset_runs))
|
||||
|
||||
def _send_time_changed(self, now):
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
"""The tests for the Sun helpers."""
|
||||
# pylint: disable=protected-access
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
from datetime import timedelta, datetime
|
||||
|
||||
import homeassistant.util.dt as dt_util
|
||||
import homeassistant.helpers.sun as sun
|
||||
|
||||
from tests.common import get_test_home_assistant
|
||||
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
class TestSun(unittest.TestCase):
|
||||
"""Test the sun helpers."""
|
||||
|
||||
def setUp(self):
|
||||
"""Setup things to be run when tests are started."""
|
||||
self.hass = get_test_home_assistant()
|
||||
|
||||
def tearDown(self):
|
||||
"""Stop everything that was started."""
|
||||
self.hass.stop()
|
||||
|
||||
def test_next_events(self):
|
||||
"""Test retrieving next sun events."""
|
||||
utc_now = datetime(2016, 11, 1, 8, 0, 0, tzinfo=dt_util.UTC)
|
||||
from astral import Astral
|
||||
|
||||
astral = Astral()
|
||||
utc_today = utc_now.date()
|
||||
|
||||
latitude = self.hass.config.latitude
|
||||
longitude = self.hass.config.longitude
|
||||
|
||||
mod = -1
|
||||
while True:
|
||||
next_dawn = (astral.dawn_utc(
|
||||
utc_today + timedelta(days=mod), latitude, longitude))
|
||||
if next_dawn > utc_now:
|
||||
break
|
||||
mod += 1
|
||||
|
||||
mod = -1
|
||||
while True:
|
||||
next_dusk = (astral.dusk_utc(
|
||||
utc_today + timedelta(days=mod), latitude, longitude))
|
||||
if next_dusk > utc_now:
|
||||
break
|
||||
mod += 1
|
||||
|
||||
mod = -1
|
||||
while True:
|
||||
next_midnight = (astral.solar_midnight_utc(
|
||||
utc_today + timedelta(days=mod), longitude))
|
||||
if next_midnight > utc_now:
|
||||
break
|
||||
mod += 1
|
||||
|
||||
mod = -1
|
||||
while True:
|
||||
next_noon = (astral.solar_noon_utc(
|
||||
utc_today + timedelta(days=mod), longitude))
|
||||
if next_noon > utc_now:
|
||||
break
|
||||
mod += 1
|
||||
|
||||
mod = -1
|
||||
while True:
|
||||
next_rising = (astral.sunrise_utc(
|
||||
utc_today + timedelta(days=mod), latitude, longitude))
|
||||
if next_rising > utc_now:
|
||||
break
|
||||
mod += 1
|
||||
|
||||
mod = -1
|
||||
while True:
|
||||
next_setting = (astral.sunset_utc(
|
||||
utc_today + timedelta(days=mod), latitude, longitude))
|
||||
if next_setting > utc_now:
|
||||
break
|
||||
mod += 1
|
||||
|
||||
with patch('homeassistant.helpers.condition.dt_util.utcnow',
|
||||
return_value=utc_now):
|
||||
self.assertEqual(next_dawn, sun.get_astral_event_next(
|
||||
self.hass, 'dawn'))
|
||||
self.assertEqual(next_dusk, sun.get_astral_event_next(
|
||||
self.hass, 'dusk'))
|
||||
self.assertEqual(next_midnight, sun.get_astral_event_next(
|
||||
self.hass, 'solar_midnight'))
|
||||
self.assertEqual(next_noon, sun.get_astral_event_next(
|
||||
self.hass, 'solar_noon'))
|
||||
self.assertEqual(next_rising, sun.get_astral_event_next(
|
||||
self.hass, 'sunrise'))
|
||||
self.assertEqual(next_setting, sun.get_astral_event_next(
|
||||
self.hass, 'sunset'))
|
||||
|
||||
def test_date_events(self):
|
||||
"""Test retrieving next sun events."""
|
||||
utc_now = datetime(2016, 11, 1, 8, 0, 0, tzinfo=dt_util.UTC)
|
||||
from astral import Astral
|
||||
|
||||
astral = Astral()
|
||||
utc_today = utc_now.date()
|
||||
|
||||
latitude = self.hass.config.latitude
|
||||
longitude = self.hass.config.longitude
|
||||
|
||||
dawn = astral.dawn_utc(utc_today, latitude, longitude)
|
||||
dusk = astral.dusk_utc(utc_today, latitude, longitude)
|
||||
midnight = astral.solar_midnight_utc(utc_today, longitude)
|
||||
noon = astral.solar_noon_utc(utc_today, longitude)
|
||||
sunrise = astral.sunrise_utc(utc_today, latitude, longitude)
|
||||
sunset = astral.sunset_utc(utc_today, latitude, longitude)
|
||||
|
||||
self.assertEqual(dawn, sun.get_astral_event_date(
|
||||
self.hass, 'dawn', utc_today))
|
||||
self.assertEqual(dusk, sun.get_astral_event_date(
|
||||
self.hass, 'dusk', utc_today))
|
||||
self.assertEqual(midnight, sun.get_astral_event_date(
|
||||
self.hass, 'solar_midnight', utc_today))
|
||||
self.assertEqual(noon, sun.get_astral_event_date(
|
||||
self.hass, 'solar_noon', utc_today))
|
||||
self.assertEqual(sunrise, sun.get_astral_event_date(
|
||||
self.hass, 'sunrise', utc_today))
|
||||
self.assertEqual(sunset, sun.get_astral_event_date(
|
||||
self.hass, 'sunset', utc_today))
|
||||
|
||||
def test_date_events_default_date(self):
|
||||
"""Test retrieving next sun events."""
|
||||
utc_now = datetime(2016, 11, 1, 8, 0, 0, tzinfo=dt_util.UTC)
|
||||
from astral import Astral
|
||||
|
||||
astral = Astral()
|
||||
utc_today = utc_now.date()
|
||||
|
||||
latitude = self.hass.config.latitude
|
||||
longitude = self.hass.config.longitude
|
||||
|
||||
dawn = astral.dawn_utc(utc_today, latitude, longitude)
|
||||
dusk = astral.dusk_utc(utc_today, latitude, longitude)
|
||||
midnight = astral.solar_midnight_utc(utc_today, longitude)
|
||||
noon = astral.solar_noon_utc(utc_today, longitude)
|
||||
sunrise = astral.sunrise_utc(utc_today, latitude, longitude)
|
||||
sunset = astral.sunset_utc(utc_today, latitude, longitude)
|
||||
|
||||
with patch('homeassistant.util.dt.now', return_value=utc_now):
|
||||
self.assertEqual(dawn, sun.get_astral_event_date(
|
||||
self.hass, 'dawn', utc_today))
|
||||
self.assertEqual(dusk, sun.get_astral_event_date(
|
||||
self.hass, 'dusk', utc_today))
|
||||
self.assertEqual(midnight, sun.get_astral_event_date(
|
||||
self.hass, 'solar_midnight', utc_today))
|
||||
self.assertEqual(noon, sun.get_astral_event_date(
|
||||
self.hass, 'solar_noon', utc_today))
|
||||
self.assertEqual(sunrise, sun.get_astral_event_date(
|
||||
self.hass, 'sunrise', utc_today))
|
||||
self.assertEqual(sunset, sun.get_astral_event_date(
|
||||
self.hass, 'sunset', utc_today))
|
||||
|
||||
def test_date_events_accepts_datetime(self):
|
||||
"""Test retrieving next sun events."""
|
||||
utc_now = datetime(2016, 11, 1, 8, 0, 0, tzinfo=dt_util.UTC)
|
||||
from astral import Astral
|
||||
|
||||
astral = Astral()
|
||||
utc_today = utc_now.date()
|
||||
|
||||
latitude = self.hass.config.latitude
|
||||
longitude = self.hass.config.longitude
|
||||
|
||||
dawn = astral.dawn_utc(utc_today, latitude, longitude)
|
||||
dusk = astral.dusk_utc(utc_today, latitude, longitude)
|
||||
midnight = astral.solar_midnight_utc(utc_today, longitude)
|
||||
noon = astral.solar_noon_utc(utc_today, longitude)
|
||||
sunrise = astral.sunrise_utc(utc_today, latitude, longitude)
|
||||
sunset = astral.sunset_utc(utc_today, latitude, longitude)
|
||||
|
||||
self.assertEqual(dawn, sun.get_astral_event_date(
|
||||
self.hass, 'dawn', utc_now))
|
||||
self.assertEqual(dusk, sun.get_astral_event_date(
|
||||
self.hass, 'dusk', utc_now))
|
||||
self.assertEqual(midnight, sun.get_astral_event_date(
|
||||
self.hass, 'solar_midnight', utc_now))
|
||||
self.assertEqual(noon, sun.get_astral_event_date(
|
||||
self.hass, 'solar_noon', utc_now))
|
||||
self.assertEqual(sunrise, sun.get_astral_event_date(
|
||||
self.hass, 'sunrise', utc_now))
|
||||
self.assertEqual(sunset, sun.get_astral_event_date(
|
||||
self.hass, 'sunset', utc_now))
|
||||
|
||||
def test_is_up(self):
|
||||
"""Test retrieving next sun events."""
|
||||
utc_now = datetime(2016, 11, 1, 12, 0, 0, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.helpers.condition.dt_util.utcnow',
|
||||
return_value=utc_now):
|
||||
self.assertFalse(sun.is_up(self.hass))
|
||||
|
||||
utc_now = datetime(2016, 11, 1, 18, 0, 0, tzinfo=dt_util.UTC)
|
||||
with patch('homeassistant.helpers.condition.dt_util.utcnow',
|
||||
return_value=utc_now):
|
||||
self.assertTrue(sun.is_up(self.hass))
|
||||
|
||||
def test_norway_in_june(self):
|
||||
"""Test location in Norway where the sun doesn't set in summer."""
|
||||
self.hass.config.latitude = 69.6
|
||||
self.hass.config.longitude = 18.8
|
||||
|
||||
june = datetime(2016, 6, 1, tzinfo=dt_util.UTC)
|
||||
|
||||
print(sun.get_astral_event_date(self.hass, 'sunrise',
|
||||
datetime(2017, 7, 25)))
|
||||
print(sun.get_astral_event_date(self.hass, 'sunset',
|
||||
datetime(2017, 7, 25)))
|
||||
|
||||
print(sun.get_astral_event_date(self.hass, 'sunrise',
|
||||
datetime(2017, 7, 26)))
|
||||
print(sun.get_astral_event_date(self.hass, 'sunset',
|
||||
datetime(2017, 7, 26)))
|
||||
|
||||
assert sun.get_astral_event_next(self.hass, 'sunrise', june) == \
|
||||
datetime(2016, 7, 25, 23, 23, 39, tzinfo=dt_util.UTC)
|
||||
assert sun.get_astral_event_next(self.hass, 'sunset', june) == \
|
||||
datetime(2016, 7, 26, 22, 19, 1, tzinfo=dt_util.UTC)
|
||||
assert sun.get_astral_event_date(self.hass, 'sunrise', june) is None
|
||||
assert sun.get_astral_event_date(self.hass, 'sunset', june) is None
|
||||
Reference in New Issue
Block a user