2015-09-15 00:02:54 -07:00
|
|
|
"""
|
2016-03-07 20:20:07 +01:00
|
|
|
Offer sun based automation rules.
|
2015-10-13 21:08:34 +02:00
|
|
|
|
|
|
|
For more details about this automation rule, please refer to the documentation
|
2015-11-09 13:12:18 +01:00
|
|
|
at https://home-assistant.io/components/automation/#sun-trigger
|
2015-09-15 00:02:54 -07:00
|
|
|
"""
|
|
|
|
from datetime import timedelta
|
2016-04-04 12:18:58 -07:00
|
|
|
import logging
|
|
|
|
|
|
|
|
import voluptuous as vol
|
2015-09-15 00:02:54 -07:00
|
|
|
|
2016-04-04 12:18:58 -07:00
|
|
|
from homeassistant.const import CONF_PLATFORM
|
2016-02-18 21:27:50 -08:00
|
|
|
import homeassistant.util.dt as dt_util
|
2015-09-15 00:02:54 -07:00
|
|
|
from homeassistant.components import sun
|
2016-01-24 15:07:09 -05:00
|
|
|
from homeassistant.helpers.event import track_sunrise, track_sunset
|
2016-04-04 12:18:58 -07:00
|
|
|
import homeassistant.helpers.config_validation as cv
|
2015-09-15 00:02:54 -07:00
|
|
|
|
|
|
|
DEPENDENCIES = ['sun']
|
|
|
|
|
|
|
|
CONF_OFFSET = 'offset'
|
|
|
|
CONF_EVENT = 'event'
|
2015-12-21 16:09:27 -07:00
|
|
|
CONF_BEFORE = "before"
|
|
|
|
CONF_BEFORE_OFFSET = "before_offset"
|
|
|
|
CONF_AFTER = "after"
|
|
|
|
CONF_AFTER_OFFSET = "after_offset"
|
2015-09-15 00:02:54 -07:00
|
|
|
|
|
|
|
EVENT_SUNSET = 'sunset'
|
|
|
|
EVENT_SUNRISE = 'sunrise'
|
|
|
|
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
2016-04-04 12:18:58 -07:00
|
|
|
_SUN_EVENT = vol.All(vol.Lower, vol.Any(EVENT_SUNRISE, EVENT_SUNSET))
|
|
|
|
|
|
|
|
TRIGGER_SCHEMA = vol.Schema({
|
|
|
|
vol.Required(CONF_PLATFORM): 'sun',
|
|
|
|
vol.Required(CONF_EVENT): _SUN_EVENT,
|
|
|
|
vol.Required(CONF_OFFSET, default=timedelta(0)): cv.time_offset,
|
|
|
|
})
|
2015-09-15 00:02:54 -07:00
|
|
|
|
2016-04-04 12:18:58 -07:00
|
|
|
IF_ACTION_SCHEMA = vol.All(
|
|
|
|
vol.Schema({
|
|
|
|
vol.Required(CONF_PLATFORM): 'sun',
|
|
|
|
CONF_BEFORE: _SUN_EVENT,
|
|
|
|
CONF_AFTER: _SUN_EVENT,
|
|
|
|
vol.Required(CONF_BEFORE_OFFSET, default=timedelta(0)): cv.time_offset,
|
|
|
|
vol.Required(CONF_AFTER_OFFSET, default=timedelta(0)): cv.time_offset,
|
|
|
|
}),
|
|
|
|
cv.has_at_least_one_key(CONF_BEFORE, CONF_AFTER),
|
|
|
|
)
|
2015-09-15 00:02:54 -07:00
|
|
|
|
|
|
|
|
2016-04-04 12:18:58 -07:00
|
|
|
def trigger(hass, config, action):
|
|
|
|
"""Listen for events based on configuration."""
|
|
|
|
event = config.get(CONF_EVENT)
|
|
|
|
offset = config.get(CONF_OFFSET)
|
2015-09-15 00:02:54 -07:00
|
|
|
|
2016-04-21 13:59:42 -07:00
|
|
|
def call_action():
|
|
|
|
"""Call action with right context."""
|
|
|
|
action({
|
|
|
|
'trigger': {
|
|
|
|
'platform': 'sun',
|
|
|
|
'event': event,
|
|
|
|
'offset': offset,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2015-09-15 00:02:54 -07:00
|
|
|
# Do something to call action
|
|
|
|
if event == EVENT_SUNRISE:
|
2016-04-21 13:59:42 -07:00
|
|
|
track_sunrise(hass, call_action, offset)
|
2015-09-15 00:02:54 -07:00
|
|
|
else:
|
2016-04-21 13:59:42 -07:00
|
|
|
track_sunset(hass, call_action, offset)
|
2015-09-15 00:02:54 -07:00
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
2015-12-21 16:09:27 -07:00
|
|
|
def if_action(hass, config):
|
2016-03-07 20:20:07 +01:00
|
|
|
"""Wrap action method with sun based condition."""
|
2015-12-21 16:09:27 -07:00
|
|
|
before = config.get(CONF_BEFORE)
|
|
|
|
after = config.get(CONF_AFTER)
|
2016-04-04 12:18:58 -07:00
|
|
|
before_offset = config.get(CONF_BEFORE_OFFSET)
|
|
|
|
after_offset = config.get(CONF_AFTER_OFFSET)
|
2015-12-21 16:09:27 -07:00
|
|
|
|
|
|
|
if before is None:
|
2016-01-12 21:53:27 -08:00
|
|
|
def before_func():
|
|
|
|
"""Return no point in time."""
|
|
|
|
return None
|
2015-12-21 16:09:27 -07:00
|
|
|
elif before == EVENT_SUNRISE:
|
2016-01-12 21:53:27 -08:00
|
|
|
def before_func():
|
|
|
|
"""Return time before sunrise."""
|
|
|
|
return sun.next_rising(hass) + before_offset
|
2015-12-21 16:09:27 -07:00
|
|
|
else:
|
2016-01-12 21:53:27 -08:00
|
|
|
def before_func():
|
|
|
|
"""Return time before sunset."""
|
|
|
|
return sun.next_setting(hass) + before_offset
|
2015-12-21 16:09:27 -07:00
|
|
|
|
|
|
|
if after is None:
|
2016-01-12 21:53:27 -08:00
|
|
|
def after_func():
|
|
|
|
"""Return no point in time."""
|
|
|
|
return None
|
2015-12-21 16:09:27 -07:00
|
|
|
elif after == EVENT_SUNRISE:
|
2016-01-12 21:53:27 -08:00
|
|
|
def after_func():
|
|
|
|
"""Return time after sunrise."""
|
|
|
|
return sun.next_rising(hass) + after_offset
|
2015-12-21 16:09:27 -07:00
|
|
|
else:
|
2016-01-12 21:53:27 -08:00
|
|
|
def after_func():
|
|
|
|
"""Return time after sunset."""
|
|
|
|
return sun.next_setting(hass) + after_offset
|
2015-12-21 16:09:27 -07:00
|
|
|
|
2016-04-21 13:59:42 -07:00
|
|
|
def time_if(variables):
|
2016-03-07 17:14:55 +01:00
|
|
|
"""Validate time based if-condition."""
|
2016-01-03 00:36:22 -07:00
|
|
|
now = dt_util.now()
|
2015-12-21 16:09:27 -07:00
|
|
|
before = before_func()
|
|
|
|
after = after_func()
|
|
|
|
|
|
|
|
if before is not None and now > now.replace(hour=before.hour,
|
|
|
|
minute=before.minute):
|
|
|
|
return False
|
|
|
|
|
|
|
|
if after is not None and now < now.replace(hour=after.hour,
|
|
|
|
minute=after.minute):
|
|
|
|
return False
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
return time_if
|