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