#!/usr/bin/env python # -*- coding: utf-8 -*- # from base import common_base import config import geo import task import time def now(): return time.mktime(time.localtime()) def next_sunrise_time(time_offs_min=30): tm = now() rv = time.mktime(geo.sun.sunrise(config.GEO_POSITION)) + time_offs_min * 60 if tm > rv: rv = time.mktime(geo.sun.sunrise(config.GEO_POSITION, date=time.localtime(tm + 24 * 60 * 60))) + time_offs_min * 60 return rv def next_sunset_time(time_offs_min=-30): tm = now() rv = time.mktime(geo.sun.sunset(config.GEO_POSITION)) + time_offs_min * 60 if tm > rv: rv = time.mktime(geo.sun.sunset(config.GEO_POSITION, date=time.localtime(tm + 24 * 60 * 60))) + time_offs_min * 60 return rv def next_user_time(hh, mm): ts = time.localtime() tm = time.mktime(ts) ut_ts = list(ts) ut_ts[3] = hh ut_ts[4] = mm ut = time.mktime(time.struct_time(list(ts[:3]) + [hh, mm, 0] + list(ts[6:]))) if ts[3] > hh or (ts[3] == hh and ts[4] >= mm): ut += 24 * 60 * 60 # return ut class day_state(common_base): """ Class to subscribe day events as a callback (see add_callback) :param time_start_of_day: Time of a day (tuple including hour and minute) for start of day or None for no start of day state. :type time_start_of_day: tuple :param time_start_of_night: Time of a day (tuple including hour and minute) for start of night or None for no end of day state. :type time_start_of_night: tuple :param time_offset_sunrise: time offset for sunrise in minutes (negative values lead to earlier sunrise state) or None for no sunrise state. :type time_start_of_day: int :param time_offset_sunset: time offset for sunset in minutes (negative values lead to earlier sunset state) or None for no sunrise state. :type time_start_of_day: int """ KEY_SUNRISE = 'sunrise' KEY_SUNSET = 'sunset' KEY_START_OF_NIGHT = 'start_of_night' KEY_START_OF_DAY = 'start_of_day' # STATES = (KEY_START_OF_DAY, KEY_SUNRISE, KEY_SUNSET, KEY_START_OF_NIGHT) def __init__(self, time_start_of_day, time_start_of_night, time_offset_sunrise, time_offset_sunset): self.__time_start_of_day__ = time_start_of_day self.__time_start_of_night__ = time_start_of_night self.__time_offset_sunrise__ = time_offset_sunrise self.__time_offset_sunset__ = time_offset_sunset super().__init__() # def get_state(self): tm = {} if self.__time_offset_sunrise__ is not None: tm[next_sunrise_time(self.__time_offset_sunrise__)] = self.KEY_SUNRISE if self.__time_start_of_day__ is not None: tm[next_user_time(*(self.__time_start_of_day__))] = self.KEY_START_OF_DAY if self.__time_offset_sunset__ is not None: tm[next_sunset_time(self.__time_offset_sunset__)] = self.KEY_SUNSET if self.__time_start_of_night__ is not None: tm[next_user_time(*(self.__time_start_of_night__))] = self.KEY_START_OF_NIGHT # tms = list(tm.keys()) tms.sort() return tm[tms[-1]] class day_event(day_state): """ Class to subscribe day events as a callback (see add_callback) :param time_start_of_day: Time of a day (tuple including hour and minute) for start of day or None for no start of day state. :type time_start_of_day: tuple :param time_start_of_night: Time of a day (tuple including hour and minute) for start of night or None for no end of day state. :type time_start_of_night: tuple :param time_offset_sunrise: time offset for sunrise in seconds (negative values lead to earlier sunrise state) or None for no sunrise state. :type time_start_of_day: int :param time_offset_sunset: time offset for sunset in seconds (negative values lead to earlier sunset state) or None for no sunrise state. :type time_start_of_day: int """ def __init__(self, time_start_of_day=(5, 0), time_start_of_night=(22, 0), time_offset_sunrise=30, time_offset_sunset=-30): super().__init__(time_start_of_day, time_start_of_night, time_offset_sunrise, time_offset_sunset) # current_day_state = self.get_state() for key in self.STATES: self[key] = current_day_state == key # cyclic = task.periodic(30, self.__cyclic__) cyclic.run() def __cyclic__(self, a): current_day_state = self.get_state() for key in self.STATES: self.set(key, current_day_state == key)