]> pilppa.org Git - lib1wire.git/blob - src/DeviceData.cc
Started defining generic device type base classes that could be used
[lib1wire.git] / src / DeviceData.cc
1 /*
2  * DeviceData.cc
3  *
4  *  Created on: Nov 7, 2010
5  *      Author: lamikr
6  */
7 #include <sstream>
8
9 #include <dirent.h>
10 #include <malloc.h>
11 #include <errno.h>
12 #include <string.h>
13
14 #include "W1Util.hh"
15 #include "DeviceData.hh"
16 #include "StoreDay.hh"
17 #include "StoreCache.hh"
18 #include "DeviceConfig.hh"
19 #include "Factory.hh"
20
21 #include "plp/log.h"
22
23 using namespace w1;
24 using namespace std;
25 using namespace plp;
26
27 template <class NumberDataType>
28 bool string_to_number(NumberDataType& result,
29                  const std::string& string_param,
30                  std::ios_base& (*format)(std::ios_base&))
31 {
32         istringstream iss(string_param);
33         return !(iss >> format >> result).fail();
34 }
35
36 DeviceData::DeviceData(string device_id_param) {
37         string  base_dir;
38
39         device_config   = NULL;
40         device_id       = device_id_param;
41         base_dir        = DeviceConfig::get_base_dir_name();
42         device_dir      = W1Util::concat_paths(base_dir, device_id);
43         device_ch_dir   = W1Util::concat_paths(base_dir, "cache");
44         device_ch_dir   = W1Util::concat_paths(device_ch_dir, device_id);
45 }
46
47 DeviceData::~DeviceData() {
48         if (device_config != NULL) {
49                 delete(device_config);
50                 device_config   = NULL;
51         }
52 }
53
54 Data *DeviceData::find_newest_data(vector<string> year_name_vector_param) {
55         string  year_name;
56         int     size;
57         Data    *ret_val;
58         Date    date;
59         int     val_int;
60
61         ret_val = NULL;
62         size    = year_name_vector_param.size();
63         if (size > 0) {
64                 // dirs are alphabetically sorted
65                 year_name       = year_name_vector_param.at(size - 1);
66                 string_to_number<int>(val_int, year_name, dec);
67                 date.year       = val_int;
68                 ret_val         = StoreCache::get_newest_data(&date, device_id, PERIOD_YEARLY);
69         }
70         return ret_val;
71 }
72
73 Data *DeviceData::find_oldest_data(vector<string> year_name_vector_param) {
74         int     size;
75         string  year_name;
76         Data    *ret_val;
77         Date    date;
78         int     val_int;
79
80         ret_val = NULL;
81         size    = year_name_vector_param.size();
82         if (size > 0) {
83                 // dirs are alphabetically sorted
84                 year_name       = year_name_vector_param.at(0);
85                 string_to_number<int>(val_int, year_name, dec);
86                 date.year       = val_int;
87                 ret_val         = StoreCache::get_oldest_data(&date, device_id, PERIOD_YEARLY);
88         }
89         return ret_val;
90 }
91
92 DataRange *DeviceData::get_data_range() {
93         DataRange       *ret_val;
94         vector<string>  y_list;
95         Data            *o_data;
96         Data            *n_data;
97
98         ret_val = NULL;
99         y_list  = W1Util::get_subdirectories(device_dir);
100         o_data  = find_oldest_data(y_list);
101         if (o_data != NULL) {
102                 n_data  = find_newest_data(y_list);
103                 if (n_data != NULL) {
104                         ret_val = new DataRange(o_data);
105                         ret_val->add(n_data);
106                         delete(n_data);
107                 }
108                 delete(o_data);
109         }
110         return ret_val;
111 }
112
113 EnumSummaryPeriod get_period_type(Date *start_date,
114                         Date *end_date) {
115         int                     diff;
116         EnumSummaryPeriod       ret_val;
117
118         ret_val = PERIOD_YEARLY;
119         diff    = end_date->year - start_date->year;
120         if (diff != 0) {
121                 ret_val = PERIOD_YEARLY;
122         }
123         else {
124                 diff    = end_date->month - start_date->month;
125                 if (diff != 0) {
126                         ret_val = PERIOD_MONTHLY;
127                 }
128                 else {
129                         diff    = end_date->day - start_date->day;
130                         if (diff != 0) {
131                                 ret_val = PERIOD_DAILY;
132                         }
133                         else {
134                                 diff    = end_date->hour - start_date->hour;
135                                 if (diff != 0) {
136                                         ret_val = PERIOD_HOURLY;
137                                 }
138                                 else {
139                                         diff    = end_date->min - start_date->min;
140                                         if (diff != 0) {
141                                                 ret_val = PERIOD_MINUTELY;
142                                         }
143                                         else {
144                                                 ret_val = PERIOD_SECONDLY;
145                                         }
146                                 }
147                         }
148                 }
149         }
150         return ret_val;
151 }
152
153 DataRange *DeviceData::get_summary(Date *date_param,
154                                 EnumSummaryCalculationType calc_type_param,
155                                 EnumSummaryPeriod period_type_param) {
156         DataRange       *ret_val;
157         StoreCache      *store;
158
159         ret_val = NULL;
160         //store = new StoreDay(device_id, date_param);
161         store   = new StoreCache(device_id, date_param);
162         if (store != NULL) {
163                 switch(calc_type_param) {
164                         case SUM:
165                                 ret_val = store->get_sum(period_type_param);
166                                 break;
167                         case DELTA:
168                                 ret_val = store->get_delta(period_type_param);
169                                 break;
170                         case MAX:
171                                 ret_val = store->get_max(period_type_param);
172                                 break;
173                         case MIN:
174                                 ret_val = store->get_min(period_type_param);
175                                 break;
176                         case MEAN:
177                         default:
178                                 ret_val = store->get_mean(period_type_param);
179                                 break;
180                 }
181                 if (ret_val != NULL) {
182                         ret_val->printout();
183                 }
184                 else {
185                         log_error("Could not read data log for device: %s\n", device_id.c_str());
186                 }
187         }
188         else {
189                 log_error("Could not read data log for device: %s\n", device_id.c_str());
190         }
191         delete(store);
192         return ret_val;
193 }
194
195 DataRange *DeviceData::get_yearly_summary(Date *date,
196                                 EnumSummaryCalculationType calc_type_param) {
197         return get_summary(date, calc_type_param, PERIOD_YEARLY);
198 }
199
200 DataRange *DeviceData::get_yearly_summary(Date *date) {
201         DataRange       *ret_val;
202
203         if (device_config == NULL) {
204                 device_config           = Factory::get_device_config(device_id);
205                 summary_calc_type       = device_config->get_summary_calculation_type();
206         }
207         ret_val = get_yearly_summary(date, summary_calc_type);
208         return ret_val;
209 }
210
211 DataRange *DeviceData::get_yearly_summary(Date *start_date,
212                                         Date *end_date) {
213         DataRange       *ret_val;
214         DataRange       *data;
215         Date            *date;
216
217         ret_val = NULL;
218         date    = start_date->clone();
219         while(date->before_or_equal_year(end_date)) {
220                 data    = get_yearly_summary(date);
221                 if (data != NULL) {
222                         if (ret_val == NULL) {
223                                 ret_val = new DataRange(data);
224                         }
225                         else {
226                                 ret_val->add(data);
227                         }
228                         delete(data);
229                 }
230                 date->next_year();
231         }
232         delete(date);
233         return ret_val;
234 }
235
236 DataRange *DeviceData::get_monthly_summary(Date *date,
237                                 EnumSummaryCalculationType calc_type_param) {
238         return get_summary(date, calc_type_param, PERIOD_MONTHLY);
239 }
240
241 DataRange *DeviceData::get_monthly_summary(Date *date) {
242         DataRange       *ret_val;
243
244         if (device_config == NULL) {
245                 device_config           = Factory::get_device_config(device_id);
246                 summary_calc_type       = device_config->get_summary_calculation_type();
247         }
248         ret_val = get_monthly_summary(date, summary_calc_type);
249         return ret_val;
250 }
251
252 DataRange *DeviceData::get_monthly_summary(Date *start_date,
253                                         Date *end_date) {
254         DataRange       *ret_val;
255         DataRange       *data;
256         Date            *date;
257
258         ret_val = NULL;
259         date    = start_date->clone();
260         while(date->before_or_equal_month(end_date)) {
261                 data    = get_monthly_summary(date);
262                 if (data != NULL) {
263                         if (ret_val == NULL) {
264                                 ret_val = new DataRange(data);
265                         }
266                         else {
267                                 ret_val->add(data);
268                         }
269                         delete(data);
270                 }
271                 date->next_month();
272         }
273         delete(date);
274         return ret_val;
275 }
276
277 DataRange *DeviceData::get_daily_summary(Date *date,
278                                 EnumSummaryCalculationType calc_type_param) {
279         return get_summary(date, calc_type_param, PERIOD_DAILY);
280 }
281
282 DataRange *DeviceData::get_daily_summary(Date *date) {
283         DataRange       *ret_val;
284
285         if (device_config == NULL) {
286                 device_config           = Factory::get_device_config(device_id);
287                 summary_calc_type       = device_config->get_summary_calculation_type();
288         }
289         ret_val = get_daily_summary(date, summary_calc_type);
290         return ret_val;
291 }
292
293 DataRange *DeviceData::get_daily_summary(Date *start_date,
294                                         Date *end_date) {
295         DataRange       *ret_val;
296         DataRange       *data;
297         Date            *date;
298
299         ret_val = NULL;
300         date    = start_date->clone();
301         while(date->before_or_equal_day(end_date)) {
302                 data    = get_daily_summary(date);
303                 if (data != NULL) {
304                         if (ret_val == NULL) {
305                                 ret_val = new DataRange(data);
306                         }
307                         else {
308                                 ret_val->add(data);
309                         }
310                         delete(data);
311                 }
312                 date->next_day();
313         }
314         delete(date);
315         return ret_val;
316 }
317
318 DataRange *DeviceData::get_hourly_summary(Date *date,
319                 EnumSummaryCalculationType calc_type_param) {
320         return get_summary(date, calc_type_param, PERIOD_HOURLY);
321 }
322
323 DataRange *DeviceData::get_hourly_summary(Date *date) {
324         DataRange       *ret_val;
325
326         if (device_config == NULL) {
327                 device_config           = Factory::get_device_config(device_id);
328                 summary_calc_type       = device_config->get_summary_calculation_type();
329         }
330         ret_val = get_hourly_summary(date, summary_calc_type);
331         return ret_val;
332 }
333
334 DataRange *DeviceData::get_hourly_summary(Date *start_date,
335                                         Date *end_date) {
336         DataRange       *ret_val;
337         DataRange       *dta_lst;
338         Data            *data;
339         Date            *date;
340         int             cnt;
341         int             ii;
342
343         ret_val = NULL;
344         date    = start_date->clone();
345         while(date->before_or_equal_hour(end_date)) {
346                 dta_lst = get_hourly_summary(date);
347                 cnt     = dta_lst->get_count();
348                 for(ii = 0; ii < cnt; ii++) {
349                         data    = dta_lst->get(ii);
350                         if (data != NULL) {
351                                 if (ret_val == NULL) {
352                                         ret_val = new DataRange(data);
353                                 }
354                                 else {
355                                         ret_val->add(data);
356                                 }
357                                 delete(data);
358                         }
359                 }
360                 date->next_day();
361         }
362         delete(date);
363         return ret_val;
364 }
365
366 DataRange *DeviceData::get_data(Date *start_date,
367                                 Date *end_date) {
368         DataRange               *ret_val;
369         EnumSummaryPeriod       period;
370
371         ret_val = NULL;
372         start_date->printout();
373         end_date->printout();
374         period  = get_period_type(start_date, end_date);
375         switch(period) {
376                 case PERIOD_YEARLY:
377                         log_debug("get yearly summary: %s - %s\n", start_date->to_string().c_str(), end_date->to_string().c_str());
378                         ret_val = get_yearly_summary(start_date, end_date);
379                         break;
380                 case PERIOD_MONTHLY:
381                         log_debug("get monthly summary\n");
382                         ret_val = get_monthly_summary(start_date, end_date);
383                         break;
384                 case PERIOD_DAILY:
385                         log_debug("get daily summary\n");
386                         ret_val = get_daily_summary(start_date, end_date);
387                         break;
388                 case PERIOD_HOURLY:
389                         log_debug("get hourly summary\n");
390                         ret_val = get_hourly_summary(start_date, end_date);
391                         break;
392                 case PERIOD_MINUTELY:
393                         log_debug("get minute summary data\n");
394                         break;
395                 case PERIOD_SECONDLY:
396                 default:
397                         log_debug("get second summary data\n");
398                         break;
399         }
400         return ret_val;
401 }