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