1 /*
2     LinKNX KNX home automation platform
3     Copyright (C) 2007 Jean-François Meessen <linknx@ouaye.net>
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19 
20 #ifndef TIMERMANAGER_H
21 #define TIMERMANAGER_H
22 
23 #include <list>
24 #include <string>
25 #include <map>
26 #include "config.h"
27 #include "logger.h"
28 #include "threads.h"
29 #include "ticpp.h"
30 #include "objectcontroller.h"
31 
32 class TimerTask
33 {
34 public:
~TimerTask()35     virtual ~TimerTask() {};
36     virtual void onTimer(time_t time) = 0;
37     virtual void reschedule(time_t from = 0) = 0;
38     virtual time_t getExecTime() = 0;
39     virtual void statusXml(ticpp::Element* pStatus) = 0;
40 };
41 
42 class TimeSpec
43 {
44 public:
45     enum ExceptionDays
46     {
47         No,
48         Yes,
49         DontCare
50     };
51 
52     enum WeekDays
53     {
54         Mon = 0x01,
55         Tue = 0x02,
56         Wed = 0x04,
57         Thu = 0x08,
58         Fri = 0x10,
59         Sat = 0x20,
60         Sun = 0x40,
61         All = 0x00
62     };
63 
64     TimeSpec();
65     TimeSpec(int min, int hour, int mday, int mon, int year);
66     TimeSpec(int min, int hour, int wdays=All, ExceptionDays exception=DontCare);
~TimeSpec()67     virtual ~TimeSpec() {};
68 
69     static TimeSpec* create(ticpp::Element* pConfig, ChangeListener* cl);
70     static TimeSpec* create(const std::string& type, ChangeListener* cl);
71 
72     virtual void importXml(ticpp::Element* pConfig);
73     virtual void exportXml(ticpp::Element* pConfig);
74 
75     virtual void getData(int *min, int *hour, int *mday, int *mon, int *year, int *wdays, ExceptionDays *exception, const struct tm * timeinfo);
adjustTime(struct tm * timeinfo)76     virtual bool adjustTime(struct tm * timeinfo) { return false; };
77 protected:
78     //		int sec_m;
79     int min_m;
80     int hour_m;
81     int mday_m;
82     int mon_m;
83     int year_m;
84     int wdays_m;
85     ExceptionDays exception_m;
86 
87 };
88 
89 class VariableTimeSpec : public TimeSpec
90 {
91 public:
92     VariableTimeSpec(ChangeListener* cl);
93     virtual ~VariableTimeSpec();
94 
95     virtual void importXml(ticpp::Element* pConfig);
96     virtual void exportXml(ticpp::Element* pConfig);
97 
98     virtual void getData(int *min, int *hour, int *mday, int *mon, int *year, int *wdays, ExceptionDays *exception, const struct tm * timeinfo);
99 protected:
100     TimeObject* time_m;
101     DateObject* date_m;
102     ChangeListener* cl_m;
103     int offset_m;
104 };
105 
106 class PeriodicTask : public TimerTask, public ChangeListener
107 {
108 public:
109     PeriodicTask(ChangeListener* cl);
110     virtual ~PeriodicTask();
111 
112     virtual void onTimer(time_t time);
113     virtual void reschedule(time_t from);
getExecTime()114     virtual time_t getExecTime() { return nextExecTime_m; };
115     virtual void statusXml(ticpp::Element* pStatus);
116 
setAt(TimeSpec * at)117     void setAt(TimeSpec* at) { at_m = at; };
setUntil(TimeSpec * until)118     void setUntil(TimeSpec* until) { until_m = until; };
setDuring(int during)119     void setDuring(int during) { during_m = during; };
120     virtual void onChange(Object* object);
121 
122 protected:
123     TimeSpec *at_m, *until_m;
124     int during_m, after_m;
125     time_t nextExecTime_m;
126     ChangeListener* cl_m;
127     bool value_m;
128 
129     time_t findNext(time_t start, TimeSpec* next);
130     time_t mktimeNoDst(struct tm * timeinfo);
131     static Logger& logger_m;
132 };
133 
134 class FixedTimeTask : public TimerTask
135 {
136 public:
137     FixedTimeTask();
138     virtual ~FixedTimeTask();
139 
140     virtual void onTimer(time_t time) = 0;
141     virtual void reschedule(time_t from);
getExecTime()142     virtual time_t getExecTime() { return execTime_m; };
143     virtual void statusXml(ticpp::Element* pStatus);
144 
145 protected:
146     time_t execTime_m;
147     static Logger& logger_m;
148 };
149 
150 class TimerManager : protected Thread
151 {
152 public:
153     enum TimerCheck
154     {
155         Immediate,
156         Short,
157         Long
158     };
159 
160     TimerManager();
161     virtual ~TimerManager();
162 
163     TimerCheck checkTaskList(time_t now);
164 
165     void addTask(TimerTask* task);
166     void removeTask(TimerTask* task);
167 
startManager()168     void startManager() { Start(); };
stopManager()169     void stopManager() { Stop(); };
170 
171     virtual void statusXml(ticpp::Element* pStatus);
172 
173 private:
174     void Run (pth_sem_t * stop);
175 
176     typedef std::list<TimerTask*> TaskList_t;
177     TaskList_t taskList_m;
178     static Logger& logger_m;
179 };
180 
181 class DaySpec
182 {
183 public:
DaySpec()184     DaySpec() : mday_m(-1), mon_m(-1), year_m(-1) {};
185 
186     void importXml(ticpp::Element* pConfig);
187     void exportXml(ticpp::Element* pConfig);
188 
189     int mday_m;
190     int mon_m;
191     int year_m;
192 };
193 
194 class ExceptionDays
195 {
196 public:
197     ExceptionDays();
198     virtual ~ExceptionDays();
199 
200     void clear();
201     void addDay(DaySpec* date);
202     void removeDay(DaySpec* date);
203 
204     void importXml(ticpp::Element* pConfig);
205     void exportXml(ticpp::Element* pConfig);
206 
207     bool isException(time_t time);
208 
209 private:
210     typedef std::list<DaySpec*> DaysList_t;
211     DaysList_t daysList_m;
212     static ExceptionDays* instance_m;
213 };
214 
215 #endif
216