|
@@ -1,9 +1,10 @@
|
1
|
1
|
#!/usr/bin/env python
|
2
|
2
|
# -*- coding: utf-8 -*-
|
3
|
3
|
#
|
|
4
|
+from base import common_base
|
4
|
5
|
import config
|
5
|
6
|
import geo
|
6
|
|
-import inspect
|
|
7
|
+import task
|
7
|
8
|
import time
|
8
|
9
|
|
9
|
10
|
|
|
@@ -11,9 +12,104 @@ def now():
|
11
|
12
|
return time.mktime(time.localtime())
|
12
|
13
|
|
13
|
14
|
|
14
|
|
-def sunrise_time(time_offs_min=30):
|
15
|
|
- return time.mktime(geo.sun.sunrise(config.GEO_POSITION)) + time_offs_min * 60
|
|
15
|
+def next_sunrise_time(time_offs_min=30):
|
|
16
|
+ tm = now()
|
|
17
|
+ rv = time.mktime(geo.sun.sunrise(config.GEO_POSITION)) + time_offs_min * 60
|
|
18
|
+ if tm > rv:
|
|
19
|
+ rv = time.mktime(geo.sun.sunrise(config.GEO_POSITION, date=time.localtime(tm + 24 * 60 * 60))) + time_offs_min * 60
|
|
20
|
+ return rv
|
16
|
21
|
|
17
|
22
|
|
18
|
|
-def sunset_time(time_offs_min=-30):
|
19
|
|
- return time.mktime(geo.sun.sunset(config.GEO_POSITION)) + time_offs_min * 60
|
|
23
|
+def next_sunset_time(time_offs_min=-30):
|
|
24
|
+ tm = now()
|
|
25
|
+ rv = time.mktime(geo.sun.sunset(config.GEO_POSITION)) + time_offs_min * 60
|
|
26
|
+ if tm > rv:
|
|
27
|
+ rv = time.mktime(geo.sun.sunset(config.GEO_POSITION, date=time.localtime(tm + 24 * 60 * 60))) + time_offs_min * 60
|
|
28
|
+ return rv
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+def next_user_time(hh, mm):
|
|
32
|
+ ts = time.localtime()
|
|
33
|
+ tm = time.mktime(ts)
|
|
34
|
+ ut_ts = list(ts)
|
|
35
|
+ ut_ts[3] = hh
|
|
36
|
+ ut_ts[4] = mm
|
|
37
|
+ ut = time.mktime(time.struct_time(list(ts[:3]) + [hh, mm, 0] + list(ts[6:])))
|
|
38
|
+ if ts[3] > hh or (ts[3] == hh and ts[4] >= mm):
|
|
39
|
+ ut += 24 * 60 * 60
|
|
40
|
+ #
|
|
41
|
+ return ut
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+class day_state(common_base):
|
|
45
|
+ """
|
|
46
|
+ Class to subscribe day events as a callback (see add_callback)
|
|
47
|
+
|
|
48
|
+ :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.
|
|
49
|
+ :type time_start_of_day: tuple
|
|
50
|
+ :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.
|
|
51
|
+ :type time_start_of_night: tuple
|
|
52
|
+ :param time_offset_sunrise: time offset for sunrise in minutes (negative values lead to earlier sunrise state) or None for no sunrise state.
|
|
53
|
+ :type time_start_of_day: int
|
|
54
|
+ :param time_offset_sunset: time offset for sunset in minutes (negative values lead to earlier sunset state) or None for no sunrise state.
|
|
55
|
+ :type time_start_of_day: int
|
|
56
|
+ """
|
|
57
|
+ KEY_SUNRISE = 'sunrise'
|
|
58
|
+ KEY_SUNSET = 'sunset'
|
|
59
|
+ KEY_START_OF_NIGHT = 'start_of_night'
|
|
60
|
+ KEY_START_OF_DAY = 'start_of_day'
|
|
61
|
+ #
|
|
62
|
+ STATES = (KEY_START_OF_DAY, KEY_SUNRISE, KEY_SUNSET, KEY_START_OF_NIGHT)
|
|
63
|
+
|
|
64
|
+ def __init__(self, time_start_of_day, time_start_of_night, time_offset_sunrise, time_offset_sunset):
|
|
65
|
+ self.__time_start_of_day__ = time_start_of_day
|
|
66
|
+ self.__time_start_of_night__ = time_start_of_night
|
|
67
|
+ self.__time_offset_sunrise__ = time_offset_sunrise
|
|
68
|
+ self.__time_offset_sunset__ = time_offset_sunset
|
|
69
|
+ super().__init__()
|
|
70
|
+ #
|
|
71
|
+
|
|
72
|
+ def get_state(self):
|
|
73
|
+ tm = {}
|
|
74
|
+ if self.__time_offset_sunrise__ is not None:
|
|
75
|
+ tm[next_sunrise_time(self.__time_offset_sunrise__)] = self.KEY_SUNRISE
|
|
76
|
+ if self.__time_start_of_day__ is not None:
|
|
77
|
+ tm[next_user_time(*(self.__time_start_of_day__))] = self.KEY_START_OF_DAY
|
|
78
|
+ if self.__time_offset_sunset__ is not None:
|
|
79
|
+ tm[next_sunset_time(self.__time_offset_sunset__)] = self.KEY_SUNSET
|
|
80
|
+ if self.__time_start_of_night__ is not None:
|
|
81
|
+ tm[next_user_time(*(self.__time_start_of_night__))] = self.KEY_START_OF_NIGHT
|
|
82
|
+ #
|
|
83
|
+ tms = list(tm.keys())
|
|
84
|
+ tms.sort()
|
|
85
|
+ return tm[tms[-1]]
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+class day_event(day_state):
|
|
89
|
+ """
|
|
90
|
+ Class to subscribe day events as a callback (see add_callback)
|
|
91
|
+
|
|
92
|
+ :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.
|
|
93
|
+ :type time_start_of_day: tuple
|
|
94
|
+ :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.
|
|
95
|
+ :type time_start_of_night: tuple
|
|
96
|
+ :param time_offset_sunrise: time offset for sunrise in seconds (negative values lead to earlier sunrise state) or None for no sunrise state.
|
|
97
|
+ :type time_start_of_day: int
|
|
98
|
+ :param time_offset_sunset: time offset for sunset in seconds (negative values lead to earlier sunset state) or None for no sunrise state.
|
|
99
|
+ :type time_start_of_day: int
|
|
100
|
+ """
|
|
101
|
+
|
|
102
|
+ def __init__(self, time_start_of_day=(6, 0), time_start_of_night=(22, 0), time_offset_sunrise=30, time_offset_sunset=-30):
|
|
103
|
+ super().__init__(time_start_of_day, time_start_of_night, time_offset_sunrise, time_offset_sunset)
|
|
104
|
+ #
|
|
105
|
+ current_day_state = self.get_state()
|
|
106
|
+ for key in self.STATES:
|
|
107
|
+ self[key] = current_day_state == key
|
|
108
|
+ #
|
|
109
|
+ cyclic = task.periodic(30, self.__cyclic__)
|
|
110
|
+ cyclic.run()
|
|
111
|
+
|
|
112
|
+ def __cyclic__(self, a):
|
|
113
|
+ current_day_state = self.get_state()
|
|
114
|
+ for key in self.STATES:
|
|
115
|
+ self.set(key, current_day_state == key)
|