async def test_track_sunrise_update_location(hass): """Test track the sunrise.""" # Setup sun component hass.config.latitude = 32.87336 hass.config.longitude = 117.22743 assert await async_setup_component(hass, sun.DOMAIN, {sun.DOMAIN: { sun.CONF_ELEVATION: 0 }}) # Get next sunrise astral = Astral() 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_today + timedelta(days=mod), hass.config.latitude, hass.config.longitude) if next_rising > utc_now: break mod += 1 # Track sunrise runs = [] with patch("homeassistant.util.dt.utcnow", return_value=utc_now): async_track_sunrise(hass, lambda: runs.append(1)) # Mimick sunrise _send_time_changed(hass, next_rising) await hass.async_block_till_done() assert len(runs) == 1 # Move! with patch("homeassistant.util.dt.utcnow", return_value=utc_now): await hass.config.async_update(latitude=40.755931, longitude=-73.984606) await hass.async_block_till_done() # Mimick sunrise _send_time_changed(hass, next_rising) await hass.async_block_till_done() # Did not increase assert len(runs) == 1 # Get next sunrise mod = -1 while True: next_rising = astral.sunrise_utc(utc_today + timedelta(days=mod), hass.config.latitude, hass.config.longitude) if next_rising > utc_now: break mod += 1 # Mimick sunrise at new location _send_time_changed(hass, next_rising) await hass.async_block_till_done() assert len(runs) == 2
def start_periodic_update(self): """Start periodic data polling.""" # Register API limit reset _LOGGER.debug("register API limit reset") async_track_utc_time_change(self._hass, self.reset_api_limit, hour=0, minute=0, second=0, local=True) @callback def sunrise_call_action(now=None): """Call action with right context.""" next_setting = get_location_astral_event_next( get_astral_location(self._hass), SUN_EVENT_SUNSET, dt_util.utcnow()) + timedelta(hours=1) _LOGGER.info( f"Good Morning! Time to prepare the day until the sun will set at {next_setting - timedelta(hours=1)}" ) remaining_api_calls = self.get_remaining_API_count() delay = (next_setting - dt_util.utcnow()) / (remaining_api_calls - 1) _LOGGER.info( f"During the day, there will be {remaining_api_calls} updates delayed by {delay} each" ) # Schedule updates over the day (starting on 0 to process early morning update) for i in range(0, remaining_api_calls): exec_delay = delay.total_seconds() * i exec_time = dt_util.utcnow() + timedelta(seconds=exec_delay) _LOGGER.info( f"History update scheduled update at {exec_time.isoformat()}" ) async_call_later(self._hass, exec_delay, self.update_history) # Initial sensor update if not self._disable_auto_history_fetching: _LOGGER.debug("register initial history update in 20 seconds") async_call_later(self._hass, 20, self.update_history) # Set periodical history update _LOGGER.debug("register history update at sunrise") # Run history update # TEST: async_call_later(self._hass, 30, sunrise_call_action) async_track_sunrise(self._hass, sunrise_call_action) # Set daily forecast update if not self._disable_auto_forecast_fetching: _LOGGER.debug("register daily forecast update at 00:00:00") async_track_utc_time_change(self._hass, self.update_forecast, hour=0, minute=0, second=0, local=True)
async def test_track_sunrise(hass): """Test track the sunrise.""" latitude = 32.87336 longitude = 117.22743 # Setup sun component hass.config.latitude = latitude hass.config.longitude = longitude assert await async_setup_component(hass, sun.DOMAIN, {sun.DOMAIN: { sun.CONF_ELEVATION: 0 }}) # Get next sunrise/sunset astral = Astral() 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_today + timedelta(days=mod), latitude, longitude) if next_rising > utc_now: break mod += 1 # Track sunrise runs = [] with patch("homeassistant.util.dt.utcnow", return_value=utc_now): unsub = async_track_sunrise(hass, lambda: runs.append(1)) offset_runs = [] offset = timedelta(minutes=30) with patch("homeassistant.util.dt.utcnow", return_value=utc_now): unsub2 = async_track_sunrise(hass, lambda: offset_runs.append(1), offset) # run tests _send_time_changed(hass, next_rising - offset) await hass.async_block_till_done() assert len(runs) == 0 assert len(offset_runs) == 0 _send_time_changed(hass, next_rising) await hass.async_block_till_done() assert len(runs) == 1 assert len(offset_runs) == 0 _send_time_changed(hass, next_rising + offset) await hass.async_block_till_done() assert len(runs) == 1 assert len(offset_runs) == 1 unsub() unsub2() _send_time_changed(hass, next_rising + offset) await hass.async_block_till_done() assert len(runs) == 1 assert len(offset_runs) == 1
def __init__( self, hass, min_colortemp, max_colortemp, sunrise_offset, sunset_offset, sunrise_time, sunset_time, latitude, longitude, elevation, interval, transition, ): self.hass = hass self._min_colortemp = min_colortemp self._max_colortemp = max_colortemp self._sunrise_offset = sunrise_offset self._sunset_offset = sunset_offset self._manual_sunset = sunset_time self._manual_sunrise = sunrise_time self._latitude = latitude self._longitude = longitude self._elevation = elevation self._transition = transition self._percent = self.calc_percent() self._colortemp = self.calc_colortemp() self._rgb_color = self.calc_rgb() self._xy_color = self.calc_xy() self._hs_color = self.calc_hs() if self._manual_sunrise is not None: async_track_time_change( self.hass, self.update, hour=self._manual_sunrise.hour, minute=self._manual_sunrise.minute, second=self._manual_sunrise.second, ) else: async_track_sunrise(self.hass, self.update, self._sunrise_offset) if self._manual_sunset is not None: async_track_time_change( self.hass, self.update, hour=self._manual_sunset.hour, minute=self._manual_sunset.minute, second=self._manual_sunset.second, ) else: async_track_sunset(self.hass, self.update, self._sunset_offset) async_track_time_interval(self.hass, self.update, interval)
async def async_attach_trigger(hass, config, action, automation_info): """Listen for events based on configuration.""" event = config.get(CONF_EVENT) offset = config.get(CONF_OFFSET) description = event if offset: description = f"{description} with offset" job = HassJob(action) @callback def call_action(): """Call action with right context.""" hass.async_run_hass_job( job, { "trigger": { "platform": "sun", "event": event, "offset": offset, "description": description, } }, ) if event == SUN_EVENT_SUNRISE: return async_track_sunrise(hass, call_action, offset) return async_track_sunset(hass, call_action, offset)
async def async_attach_trigger( hass: HomeAssistant, config: ConfigType, action: TriggerActionType, trigger_info: TriggerInfo, ) -> CALLBACK_TYPE: """Listen for events based on configuration.""" trigger_data = trigger_info["trigger_data"] event = config.get(CONF_EVENT) offset = config.get(CONF_OFFSET) description = event if offset: description = f"{description} with offset" job = HassJob(action) @callback def call_action(): """Call action with right context.""" hass.async_run_hass_job( job, { "trigger": { **trigger_data, "platform": "sun", "event": event, "offset": offset, "description": description, } }, ) if event == SUN_EVENT_SUNRISE: return async_track_sunrise(hass, call_action, offset) return async_track_sunset(hass, call_action, offset)
async def async_trigger(hass, config, action, automation_info): """Listen for events based on configuration.""" event = config.get(CONF_EVENT) offset = config.get(CONF_OFFSET) @callback def call_action(): """Call action with right context.""" hass.async_run_job( action, {"trigger": {"platform": "sun", "event": event, "offset": offset}} ) if event == SUN_EVENT_SUNRISE: return async_track_sunrise(hass, call_action, offset) return async_track_sunset(hass, call_action, offset)
def async_trigger(hass, config, action): """Listen for events based on configuration.""" event = config.get(CONF_EVENT) offset = config.get(CONF_OFFSET) @callback def call_action(): """Call action with right context.""" hass.async_run_job(action, { 'trigger': { 'platform': 'sun', 'event': event, 'offset': offset, }, }) if event == SUN_EVENT_SUNRISE: return async_track_sunrise(hass, call_action, offset) return async_track_sunset(hass, call_action, offset)
def async_trigger(hass, config, action): """Listen for events based on configuration.""" event = config.get(CONF_EVENT) offset = config.get(CONF_OFFSET) @callback def call_action(): """Call action with right context.""" hass.async_run_job(action, { 'trigger': { 'platform': 'sun', 'event': event, 'offset': offset, }, }) if event == SUN_EVENT_SUNRISE: return async_track_sunrise(hass, call_action, offset) return async_track_sunset(hass, call_action, offset)
def async_trigger(hass, config, action): """Listen for events based on configuration.""" event = config.get(CONF_EVENT) offset = config.get(CONF_OFFSET) @asyncio.coroutine def call_action(): """Call action with right context.""" hass.async_add_job(action, { 'trigger': { 'platform': 'sun', 'event': event, 'offset': offset, }, }) # Do something to call action if event == SUN_EVENT_SUNRISE: return async_track_sunrise(hass, call_action, offset) else: return async_track_sunset(hass, call_action, offset)