mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 15:17:35 +00:00
Times of The Day Binary Sensor (#20068)
* First commit * Times of the Day binary sensor added * Python 3.5 fixes and logging removed * Code refactored according to reviewer's suggestions * Fixed config template with friendly name support * Finall pep8 fixes * Removed async_generate_entity_id and moved initial calculation to async_added_to_hass * Change the configuration schema to follow the current requirements * Update according latest suggestsion * Fix typos and minor changes * Fix lint issue
This commit is contained in:
parent
f3786e2f2b
commit
7b19428279
217
homeassistant/components/binary_sensor/tod.py
Normal file
217
homeassistant/components/binary_sensor/tod.py
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
"""Support for representing current time of the day as binary sensors."""
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import pytz
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.components.binary_sensor import (
|
||||||
|
PLATFORM_SCHEMA, BinarySensorDevice)
|
||||||
|
from homeassistant.const import (
|
||||||
|
CONF_AFTER, CONF_BEFORE, CONF_NAME, SUN_EVENT_SUNRISE, SUN_EVENT_SUNSET)
|
||||||
|
from homeassistant.core import callback
|
||||||
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
from homeassistant.helpers.event import async_track_point_in_utc_time
|
||||||
|
from homeassistant.helpers.sun import (
|
||||||
|
get_astral_event_date, get_astral_event_next)
|
||||||
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
ATTR_AFTER = 'after'
|
||||||
|
ATTR_BEFORE = 'before'
|
||||||
|
ATTR_NEXT_UPDATE = 'next_update'
|
||||||
|
|
||||||
|
CONF_AFTER_OFFSET = 'after_offset'
|
||||||
|
CONF_BEFORE_OFFSET = 'before_offset'
|
||||||
|
|
||||||
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||||
|
vol.Required(CONF_AFTER):
|
||||||
|
vol.Any(cv.time, vol.All(vol.Lower, cv.sun_event)),
|
||||||
|
vol.Required(CONF_BEFORE):
|
||||||
|
vol.Any(cv.time, vol.All(vol.Lower, cv.sun_event)),
|
||||||
|
vol.Required(CONF_NAME): cv.string,
|
||||||
|
vol.Optional(CONF_AFTER_OFFSET, default=timedelta(0)): cv.time_period,
|
||||||
|
vol.Optional(CONF_BEFORE_OFFSET, default=timedelta(0)): cv.time_period,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_platform(
|
||||||
|
hass, config, async_add_entities, discovery_info=None):
|
||||||
|
"""Set up the ToD sensors."""
|
||||||
|
if hass.config.time_zone is None:
|
||||||
|
_LOGGER.error("Timezone is not set in Home Assistant configuration")
|
||||||
|
return
|
||||||
|
|
||||||
|
after = config[CONF_AFTER]
|
||||||
|
after_offset = config[CONF_AFTER_OFFSET]
|
||||||
|
before = config[CONF_BEFORE]
|
||||||
|
before_offset = config[CONF_BEFORE_OFFSET]
|
||||||
|
name = config[CONF_NAME]
|
||||||
|
sensor = TodSensor(name, after, after_offset, before, before_offset)
|
||||||
|
|
||||||
|
async_add_entities([sensor])
|
||||||
|
|
||||||
|
|
||||||
|
def is_sun_event(event):
|
||||||
|
"""Return true if event is sun event not time."""
|
||||||
|
return event in (SUN_EVENT_SUNRISE, SUN_EVENT_SUNSET)
|
||||||
|
|
||||||
|
|
||||||
|
class TodSensor(BinarySensorDevice):
|
||||||
|
"""Time of the Day Sensor."""
|
||||||
|
|
||||||
|
def __init__(self, name, after, after_offset, before, before_offset):
|
||||||
|
"""Init the ToD Sensor..."""
|
||||||
|
self._name = name
|
||||||
|
self._time_before = self._time_after = self._next_update = None
|
||||||
|
self._after_offset = after_offset
|
||||||
|
self._before_offset = before_offset
|
||||||
|
self._before = before
|
||||||
|
self._after = after
|
||||||
|
|
||||||
|
@property
|
||||||
|
def should_poll(self):
|
||||||
|
"""Sensor does not need to be polled."""
|
||||||
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""Return the name of the sensor."""
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def after(self):
|
||||||
|
"""Return the timestamp for the begining of the period."""
|
||||||
|
return self._time_after
|
||||||
|
|
||||||
|
@property
|
||||||
|
def before(self):
|
||||||
|
"""Return the timestamp for the end of the period."""
|
||||||
|
return self._time_before
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self):
|
||||||
|
"""Return True is sensor is on."""
|
||||||
|
if self.after < self.before:
|
||||||
|
return self.after <= self.current_datetime < self.before
|
||||||
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_datetime(self):
|
||||||
|
"""Return local current datetime according to hass configuration."""
|
||||||
|
return dt_util.utcnow()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def next_update(self):
|
||||||
|
"""Return the next update point in the UTC time."""
|
||||||
|
return self._next_update
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_state_attributes(self):
|
||||||
|
"""Return the state attributes of the sensor."""
|
||||||
|
return {
|
||||||
|
ATTR_AFTER: self.after.astimezone(
|
||||||
|
self.hass.config.time_zone).isoformat(),
|
||||||
|
ATTR_BEFORE: self.before.astimezone(
|
||||||
|
self.hass.config.time_zone).isoformat(),
|
||||||
|
ATTR_NEXT_UPDATE: self.next_update.astimezone(
|
||||||
|
self.hass.config.time_zone).isoformat(),
|
||||||
|
}
|
||||||
|
|
||||||
|
def _calculate_initial_boudary_time(self):
|
||||||
|
"""Calculate internal absolute time boudaries."""
|
||||||
|
nowutc = self.current_datetime
|
||||||
|
# If after value is a sun event instead of absolute time
|
||||||
|
if is_sun_event(self._after):
|
||||||
|
# Calculate the today's event utc time or
|
||||||
|
# if not available take next
|
||||||
|
after_event_date = \
|
||||||
|
get_astral_event_date(self.hass, self._after, nowutc) or \
|
||||||
|
get_astral_event_next(self.hass, self._after, nowutc)
|
||||||
|
else:
|
||||||
|
# Convert local time provided to UTC today
|
||||||
|
# datetime.combine(date, time, tzinfo) is not supported
|
||||||
|
# in python 3.5. The self._after is provided
|
||||||
|
# with hass configured TZ not system wide
|
||||||
|
after_event_date = datetime.combine(
|
||||||
|
nowutc, self._after.replace(
|
||||||
|
tzinfo=self.hass.config.time_zone)).astimezone(tz=pytz.UTC)
|
||||||
|
|
||||||
|
self._time_after = after_event_date
|
||||||
|
|
||||||
|
# If before value is a sun event instead of absolute time
|
||||||
|
if is_sun_event(self._before):
|
||||||
|
# Calculate the today's event utc time or if not available take
|
||||||
|
# next
|
||||||
|
before_event_date = \
|
||||||
|
get_astral_event_date(self.hass, self._before, nowutc) or \
|
||||||
|
get_astral_event_next(self.hass, self._before, nowutc)
|
||||||
|
# Before is earlier than after
|
||||||
|
if before_event_date < after_event_date:
|
||||||
|
# Take next day for before
|
||||||
|
before_event_date = get_astral_event_next(
|
||||||
|
self.hass, self._before, after_event_date)
|
||||||
|
else:
|
||||||
|
# Convert local time provided to UTC today, see above
|
||||||
|
before_event_date = datetime.combine(
|
||||||
|
nowutc, self._before.replace(
|
||||||
|
tzinfo=self.hass.config.time_zone)).astimezone(tz=pytz.UTC)
|
||||||
|
|
||||||
|
# It is safe to add timedelta days=1 to UTC as there is no DST
|
||||||
|
if before_event_date < after_event_date + self._after_offset:
|
||||||
|
before_event_date += timedelta(days=1)
|
||||||
|
|
||||||
|
self._time_before = before_event_date
|
||||||
|
|
||||||
|
# Add offset to utc boundaries according to the configuration
|
||||||
|
self._time_after += self._after_offset
|
||||||
|
self._time_before += self._before_offset
|
||||||
|
|
||||||
|
def _turn_to_next_day(self):
|
||||||
|
"""Turn to to the next day."""
|
||||||
|
if is_sun_event(self._after):
|
||||||
|
self._time_after = get_astral_event_next(
|
||||||
|
self.hass, self._after,
|
||||||
|
self._time_after - self._after_offset)
|
||||||
|
self._time_after += self._after_offset
|
||||||
|
else:
|
||||||
|
# Offset is already there
|
||||||
|
self._time_after += timedelta(days=1)
|
||||||
|
|
||||||
|
if is_sun_event(self._before):
|
||||||
|
self._time_before = get_astral_event_next(
|
||||||
|
self.hass, self._before,
|
||||||
|
self._time_before - self._before_offset)
|
||||||
|
self._time_before += self._before_offset
|
||||||
|
else:
|
||||||
|
# Offset is already there
|
||||||
|
self._time_before += timedelta(days=1)
|
||||||
|
|
||||||
|
async def async_added_to_hass(self):
|
||||||
|
"""Call when entity about to be added to Home Assistant."""
|
||||||
|
await super().async_added_to_hass()
|
||||||
|
self._calculate_initial_boudary_time()
|
||||||
|
self._calculate_next_update()
|
||||||
|
self._point_in_time_listener(dt_util.now())
|
||||||
|
|
||||||
|
def _calculate_next_update(self):
|
||||||
|
"""Datetime when the next update to the state."""
|
||||||
|
now = self.current_datetime
|
||||||
|
if now < self.after:
|
||||||
|
self._next_update = self.after
|
||||||
|
return
|
||||||
|
if now < self.before:
|
||||||
|
self._next_update = self.before
|
||||||
|
return
|
||||||
|
self._turn_to_next_day()
|
||||||
|
self._next_update = self.after
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _point_in_time_listener(self, now):
|
||||||
|
"""Run when the state of the sensor should be updated."""
|
||||||
|
self._calculate_next_update()
|
||||||
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
|
async_track_point_in_utc_time(
|
||||||
|
self.hass, self._point_in_time_listener, self.next_update)
|
839
tests/components/binary_sensor/test_tod.py
Normal file
839
tests/components/binary_sensor/test_tod.py
Normal file
@ -0,0 +1,839 @@
|
|||||||
|
"""Test Times of the Day Binary Sensor."""
|
||||||
|
import unittest
|
||||||
|
from unittest.mock import patch
|
||||||
|
from datetime import timedelta, datetime
|
||||||
|
import pytz
|
||||||
|
|
||||||
|
from homeassistant import setup
|
||||||
|
import homeassistant.core as ha
|
||||||
|
from homeassistant.const import STATE_OFF, STATE_ON
|
||||||
|
import homeassistant.util.dt as dt_util
|
||||||
|
from homeassistant.setup import setup_component
|
||||||
|
from tests.common import (
|
||||||
|
get_test_home_assistant, assert_setup_component)
|
||||||
|
from homeassistant.helpers.sun import (
|
||||||
|
get_astral_event_date, get_astral_event_next)
|
||||||
|
|
||||||
|
|
||||||
|
class TestBinarySensorTod(unittest.TestCase):
|
||||||
|
"""Test for Binary sensor tod platform."""
|
||||||
|
|
||||||
|
hass = None
|
||||||
|
# pylint: disable=invalid-name
|
||||||
|
|
||||||
|
def setup_method(self, method):
|
||||||
|
"""Set up things to be run when tests are started."""
|
||||||
|
self.hass = get_test_home_assistant()
|
||||||
|
self.hass.config.latitute = 50.27583
|
||||||
|
self.hass.config.longitude = 18.98583
|
||||||
|
|
||||||
|
def teardown_method(self, method):
|
||||||
|
"""Stop everything that was started."""
|
||||||
|
self.hass.stop()
|
||||||
|
|
||||||
|
def test_setup(self):
|
||||||
|
"""Test the setup."""
|
||||||
|
config = {
|
||||||
|
'binary_sensor': [
|
||||||
|
{
|
||||||
|
'platform': 'tod',
|
||||||
|
'name': 'Early Morning',
|
||||||
|
'after': 'sunrise',
|
||||||
|
'after_offset': '-02:00',
|
||||||
|
'before': '7:00',
|
||||||
|
'before_offset': '1:00'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'platform': 'tod',
|
||||||
|
'name': 'Morning',
|
||||||
|
'after': 'sunrise',
|
||||||
|
'before': '12:00'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
with assert_setup_component(2):
|
||||||
|
assert setup.setup_component(
|
||||||
|
self.hass, 'binary_sensor', config)
|
||||||
|
|
||||||
|
def test_setup_no_sensors(self):
|
||||||
|
"""Test setup with no sensors."""
|
||||||
|
with assert_setup_component(0):
|
||||||
|
assert setup.setup_component(self.hass, 'binary_sensor', {
|
||||||
|
'binary_sensor': {
|
||||||
|
'platform': 'tod'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
def test_in_period_on_start(self):
|
||||||
|
"""Test simple setting."""
|
||||||
|
test_time = datetime(
|
||||||
|
2019, 1, 10, 18, 43, 0, tzinfo=self.hass.config.time_zone)
|
||||||
|
config = {
|
||||||
|
'binary_sensor': [
|
||||||
|
{
|
||||||
|
'platform': 'tod',
|
||||||
|
'name': 'Evening',
|
||||||
|
'after': '18:00',
|
||||||
|
'before': '22:00'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=test_time):
|
||||||
|
setup_component(self.hass, 'binary_sensor', config)
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
state = self.hass.states.get('binary_sensor.evening')
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
def test_midnight_turnover_before_midnight_inside_period(self):
|
||||||
|
"""Test midnight turnover setting before midnight inside period ."""
|
||||||
|
test_time = datetime(
|
||||||
|
2019, 1, 10, 22, 30, 0, tzinfo=self.hass.config.time_zone)
|
||||||
|
config = {
|
||||||
|
'binary_sensor': [
|
||||||
|
{
|
||||||
|
'platform': 'tod',
|
||||||
|
'name': 'Night',
|
||||||
|
'after': '22:00',
|
||||||
|
'before': '5:00'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=test_time):
|
||||||
|
setup_component(self.hass, 'binary_sensor', config)
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
state = self.hass.states.get('binary_sensor.night')
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
def test_midnight_turnover_after_midnight_inside_period(self):
|
||||||
|
"""Test midnight turnover setting before midnight inside period ."""
|
||||||
|
test_time = datetime(
|
||||||
|
2019, 1, 10, 21, 00, 0, tzinfo=self.hass.config.time_zone)
|
||||||
|
config = {
|
||||||
|
'binary_sensor': [
|
||||||
|
{
|
||||||
|
'platform': 'tod',
|
||||||
|
'name': 'Night',
|
||||||
|
'after': '22:00',
|
||||||
|
'before': '5:00'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=test_time):
|
||||||
|
setup_component(self.hass, 'binary_sensor', config)
|
||||||
|
|
||||||
|
state = self.hass.states.get('binary_sensor.night')
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=test_time + timedelta(hours=1)):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: test_time + timedelta(hours=1)})
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
state = self.hass.states.get('binary_sensor.night')
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
def test_midnight_turnover_before_midnight_outside_period(self):
|
||||||
|
"""Test midnight turnover setting before midnight outside period."""
|
||||||
|
test_time = datetime(
|
||||||
|
2019, 1, 10, 20, 30, 0, tzinfo=self.hass.config.time_zone)
|
||||||
|
config = {
|
||||||
|
'binary_sensor': [
|
||||||
|
{
|
||||||
|
'platform': 'tod',
|
||||||
|
'name': 'Night',
|
||||||
|
'after': '22:00',
|
||||||
|
'before': '5:00'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=test_time):
|
||||||
|
setup_component(self.hass, 'binary_sensor', config)
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
state = self.hass.states.get('binary_sensor.night')
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
def test_midnight_turnover_after_midnight_outside_period(self):
|
||||||
|
"""Test midnight turnover setting before midnight inside period ."""
|
||||||
|
test_time = datetime(
|
||||||
|
2019, 1, 10, 20, 0, 0, tzinfo=self.hass.config.time_zone)
|
||||||
|
config = {
|
||||||
|
'binary_sensor': [
|
||||||
|
{
|
||||||
|
'platform': 'tod',
|
||||||
|
'name': 'Night',
|
||||||
|
'after': '22:00',
|
||||||
|
'before': '5:00'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=test_time):
|
||||||
|
setup_component(self.hass, 'binary_sensor', config)
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
state = self.hass.states.get('binary_sensor.night')
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
switchover_time = datetime(
|
||||||
|
2019, 1, 11, 4, 59, 0, tzinfo=self.hass.config.time_zone)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=switchover_time):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: switchover_time})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
state = self.hass.states.get('binary_sensor.night')
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=switchover_time + timedelta(
|
||||||
|
minutes=1, seconds=1)):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: switchover_time + timedelta(
|
||||||
|
minutes=1, seconds=1)})
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
state = self.hass.states.get('binary_sensor.night')
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
def test_from_sunrise_to_sunset(self):
|
||||||
|
"""Test period from sunrise to sunset."""
|
||||||
|
test_time = datetime(
|
||||||
|
2019, 1, 12, tzinfo=self.hass.config.time_zone)
|
||||||
|
sunrise = dt_util.as_local(get_astral_event_date(
|
||||||
|
self.hass, 'sunrise', dt_util.as_utc(test_time)))
|
||||||
|
sunset = dt_util.as_local(get_astral_event_date(
|
||||||
|
self.hass, 'sunset', dt_util.as_utc(test_time)))
|
||||||
|
config = {
|
||||||
|
'binary_sensor': [
|
||||||
|
{
|
||||||
|
'platform': 'tod',
|
||||||
|
'name': 'Day',
|
||||||
|
'after': 'sunrise',
|
||||||
|
'before': 'sunset'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
entity_id = 'binary_sensor.day'
|
||||||
|
testtime = sunrise + timedelta(seconds=-1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
setup_component(self.hass, 'binary_sensor', config)
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
testtime = sunrise
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
testtime = sunrise + timedelta(seconds=1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
testtime = sunset + timedelta(seconds=-1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
testtime = sunset
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
testtime = sunset + timedelta(seconds=1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
def test_from_sunset_to_sunrise(self):
|
||||||
|
"""Test period from sunset to sunrise."""
|
||||||
|
test_time = datetime(
|
||||||
|
2019, 1, 12, tzinfo=self.hass.config.time_zone)
|
||||||
|
sunset = dt_util.as_local(get_astral_event_date(
|
||||||
|
self.hass, 'sunset', test_time))
|
||||||
|
sunrise = dt_util.as_local(get_astral_event_next(
|
||||||
|
self.hass, 'sunrise', sunset))
|
||||||
|
# assert sunset == sunrise
|
||||||
|
config = {
|
||||||
|
'binary_sensor': [
|
||||||
|
{
|
||||||
|
'platform': 'tod',
|
||||||
|
'name': 'Night',
|
||||||
|
'after': 'sunset',
|
||||||
|
'before': 'sunrise'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
entity_id = 'binary_sensor.night'
|
||||||
|
testtime = sunset + timedelta(minutes=-1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
setup_component(self.hass, 'binary_sensor', config)
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
testtime = sunset
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
testtime = sunset + timedelta(minutes=1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
testtime = sunrise + timedelta(minutes=-1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
testtime = sunrise
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
self.hass.block_till_done()
|
||||||
|
# assert state == "dupa"
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
testtime = sunrise + timedelta(minutes=1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
def test_offset(self):
|
||||||
|
"""Test offset."""
|
||||||
|
after = datetime(
|
||||||
|
2019, 1, 10, 18, 0, 0,
|
||||||
|
tzinfo=self.hass.config.time_zone) + \
|
||||||
|
timedelta(hours=1, minutes=34)
|
||||||
|
before = datetime(
|
||||||
|
2019, 1, 10, 22, 0, 0,
|
||||||
|
tzinfo=self.hass.config.time_zone) + \
|
||||||
|
timedelta(hours=1, minutes=45)
|
||||||
|
entity_id = 'binary_sensor.evening'
|
||||||
|
config = {
|
||||||
|
'binary_sensor': [
|
||||||
|
{
|
||||||
|
'platform': 'tod',
|
||||||
|
'name': 'Evening',
|
||||||
|
'after': '18:00',
|
||||||
|
'after_offset': '1:34',
|
||||||
|
'before': '22:00',
|
||||||
|
'before_offset': '1:45'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
testtime = after + timedelta(seconds=-1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
setup_component(self.hass, 'binary_sensor', config)
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
testtime = after
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
testtime = before + timedelta(seconds=-1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
testtime = before
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
testtime = before + timedelta(seconds=1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
def test_offset_overnight(self):
|
||||||
|
"""Test offset overnight."""
|
||||||
|
after = datetime(
|
||||||
|
2019, 1, 10, 18, 0, 0,
|
||||||
|
tzinfo=self.hass.config.time_zone) + \
|
||||||
|
timedelta(hours=1, minutes=34)
|
||||||
|
entity_id = 'binary_sensor.evening'
|
||||||
|
config = {
|
||||||
|
'binary_sensor': [
|
||||||
|
{
|
||||||
|
'platform': 'tod',
|
||||||
|
'name': 'Evening',
|
||||||
|
'after': '18:00',
|
||||||
|
'after_offset': '1:34',
|
||||||
|
'before': '22:00',
|
||||||
|
'before_offset': '3:00'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
testtime = after + timedelta(seconds=-1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
setup_component(self.hass, 'binary_sensor', config)
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
testtime = after
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
def test_norwegian_case_winter(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
|
||||||
|
|
||||||
|
test_time = datetime(2010, 1, 1, tzinfo=self.hass.config.time_zone)
|
||||||
|
sunrise = dt_util.as_local(get_astral_event_next(
|
||||||
|
self.hass, 'sunrise', dt_util.as_utc(test_time)))
|
||||||
|
sunset = dt_util.as_local(get_astral_event_next(
|
||||||
|
self.hass, 'sunset', dt_util.as_utc(test_time)))
|
||||||
|
config = {
|
||||||
|
'binary_sensor': [
|
||||||
|
{
|
||||||
|
'platform': 'tod',
|
||||||
|
'name': 'Day',
|
||||||
|
'after': 'sunrise',
|
||||||
|
'before': 'sunset'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
entity_id = 'binary_sensor.day'
|
||||||
|
testtime = test_time
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
setup_component(self.hass, 'binary_sensor', config)
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
testtime = sunrise + timedelta(seconds=-1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
testtime = sunrise
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
testtime = sunrise + timedelta(seconds=1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
testtime = sunset + timedelta(seconds=-1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
testtime = sunset
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
testtime = sunset + timedelta(seconds=1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
def test_norwegian_case_summer(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
|
||||||
|
|
||||||
|
test_time = datetime(2010, 6, 1, tzinfo=self.hass.config.time_zone)
|
||||||
|
sunrise = dt_util.as_local(get_astral_event_next(
|
||||||
|
self.hass, 'sunrise', dt_util.as_utc(test_time)))
|
||||||
|
sunset = dt_util.as_local(get_astral_event_next(
|
||||||
|
self.hass, 'sunset', dt_util.as_utc(test_time)))
|
||||||
|
print(sunrise)
|
||||||
|
print(sunset)
|
||||||
|
config = {
|
||||||
|
'binary_sensor': [
|
||||||
|
{
|
||||||
|
'platform': 'tod',
|
||||||
|
'name': 'Day',
|
||||||
|
'after': 'sunrise',
|
||||||
|
'before': 'sunset'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
entity_id = 'binary_sensor.day'
|
||||||
|
testtime = test_time
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
setup_component(self.hass, 'binary_sensor', config)
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
testtime = sunrise + timedelta(seconds=-1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
testtime = sunrise
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
testtime = sunrise + timedelta(seconds=1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
testtime = sunset + timedelta(seconds=-1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
testtime = sunset
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
testtime = sunset + timedelta(seconds=1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
def test_sun_offset(self):
|
||||||
|
"""Test sun event with offset."""
|
||||||
|
test_time = datetime(
|
||||||
|
2019, 1, 12, tzinfo=self.hass.config.time_zone)
|
||||||
|
sunrise = dt_util.as_local(get_astral_event_date(
|
||||||
|
self.hass, 'sunrise', dt_util.as_utc(test_time)) +
|
||||||
|
timedelta(hours=-1, minutes=-30))
|
||||||
|
sunset = dt_util.as_local(get_astral_event_date(
|
||||||
|
self.hass, 'sunset', dt_util.as_utc(test_time)) +
|
||||||
|
timedelta(hours=1, minutes=30))
|
||||||
|
config = {
|
||||||
|
'binary_sensor': [
|
||||||
|
{
|
||||||
|
'platform': 'tod',
|
||||||
|
'name': 'Day',
|
||||||
|
'after': 'sunrise',
|
||||||
|
'after_offset': '-1:30',
|
||||||
|
'before': 'sunset',
|
||||||
|
'before_offset': '1:30'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
entity_id = 'binary_sensor.day'
|
||||||
|
testtime = sunrise + timedelta(seconds=-1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
setup_component(self.hass, 'binary_sensor', config)
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
testtime = sunrise
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
testtime = sunrise + timedelta(seconds=1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
testtime = sunset + timedelta(seconds=-1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
testtime = sunset
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
testtime = sunset + timedelta(seconds=1)
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
test_time = test_time + timedelta(days=1)
|
||||||
|
sunrise = dt_util.as_local(get_astral_event_date(
|
||||||
|
self.hass, 'sunrise', dt_util.as_utc(test_time)) +
|
||||||
|
timedelta(hours=-1, minutes=-30))
|
||||||
|
testtime = sunrise
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
|
||||||
|
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {
|
||||||
|
ha.ATTR_NOW: testtime})
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
def test_dst(self):
|
||||||
|
"""Test sun event with offset."""
|
||||||
|
self.hass.config.time_zone = pytz.timezone('CET')
|
||||||
|
test_time = datetime(
|
||||||
|
2019, 3, 30, 3, 0, 0, tzinfo=self.hass.config.time_zone)
|
||||||
|
config = {
|
||||||
|
'binary_sensor': [
|
||||||
|
{
|
||||||
|
'platform': 'tod',
|
||||||
|
'name': 'Day',
|
||||||
|
'after': '2:30',
|
||||||
|
'before': '2:40'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
# after 2019-03-30 03:00 CET the next update should ge scheduled
|
||||||
|
# at 3:30 not 2:30 local time
|
||||||
|
# Internally the
|
||||||
|
entity_id = 'binary_sensor.day'
|
||||||
|
testtime = test_time
|
||||||
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
|
return_value=testtime):
|
||||||
|
setup_component(self.hass, 'binary_sensor', config)
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
state = self.hass.states.get(entity_id)
|
||||||
|
state.attributes['after'] == '2019-03-31T03:30:00+02:00'
|
||||||
|
state.attributes['before'] == '2019-03-31T03:40:00+02:00'
|
||||||
|
state.attributes['next_update'] == '2019-03-31T03:30:00+02:00'
|
||||||
|
assert state.state == STATE_OFF
|
Loading…
x
Reference in New Issue
Block a user