]> pilppa.org Git - libplp.git/blob - src/DataReader.cc
e6f184a050637fec945d9363924ebc0a7c9a9bea
[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                 delete(data);
314         }
315         return ret_val;
316 }
317
318 DataRange *DataReader::get_daily_summary(Date *date,
319                                 EnumSummaryCalculationType calc_type_param) {
320         return get_summary(date, calc_type_param, PERIOD_DAILY);
321 }
322
323 DataRange *DataReader::get_daily_summary(Date *date) {
324         DataRange       *ret_val;
325
326         if (device_config == NULL) {
327                 device_config           = DeviceConfig::get_device_config(device_id);
328                 summary_calc_type       = device_config->get_summary_calculation_type();
329         }
330         ret_val = get_daily_summary(date, summary_calc_type);
331         return ret_val;
332 }
333
334 DataRange *DataReader::get_daily_summary(Date *start_date,
335                                         Date *end_date) {
336         DataRange       *ret_val;
337         DataRange       *data;
338         Date            *date;
339
340         ret_val = NULL;
341         date    = start_date->clone();
342         while(date->before_or_equal_day(end_date)) {
343                 data    = get_daily_summary(date);
344                 if (data != NULL) {
345                         if (ret_val == NULL) {
346                                 ret_val = new DataRange(data);
347                         }
348                         else {
349                                 ret_val->add(data);
350                         }
351                         delete(data);
352                 }
353                 date->next_day();
354         }
355         delete(date);
356         return ret_val;
357 }
358
359 DataRange *DataReader::get_hourly_summary(Date *date,
360                 EnumSummaryCalculationType calc_type_param) {
361         return get_summary(date, calc_type_param, PERIOD_HOURLY);
362 }
363
364 DataRange *DataReader::get_hourly_summary(Date *date) {
365         DataRange       *ret_val;
366
367         if (device_config == NULL) {
368                 device_config           = DeviceConfig::get_device_config(device_id);
369                 summary_calc_type       = device_config->get_summary_calculation_type();
370         }
371         ret_val = get_hourly_summary(date, summary_calc_type);
372         return ret_val;
373 }
374
375 DataRange *DataReader::get_hourly_summary(Date *start_date,
376                                         Date *end_date) {
377         DataRange       *ret_val;
378         DataRange       *dta_lst;
379         Data            *data;
380         Date            *date;
381         int             cnt;
382         int             ii;
383
384         ret_val = NULL;
385         date    = start_date->clone();
386         while(date->before_or_equal_hour(end_date)) {
387                 dta_lst = get_hourly_summary(date);
388                 cnt     = dta_lst->get_count();
389                 for(ii = 0; ii < cnt; ii++) {
390                         data    = dta_lst->get(ii);
391                         if (data != NULL) {
392                                 if (ret_val == NULL) {
393                                         ret_val = new DataRange(data);
394                                 }
395                                 else {
396                                         ret_val->add(data);
397                                 }
398                                 delete(data);
399                         }
400                 }
401                 date->next_day();
402         }
403         delete(date);
404         return ret_val;
405 }
406
407 DataRange *DataReader::get_data(Date *start_date,
408                                 Date *end_date) {
409         DataRange               *ret_val;
410         EnumSummaryPeriod       period;
411
412         ret_val = NULL;
413         period  = get_period_type(start_date, end_date);
414         switch(period) {
415                 case PERIOD_YEARLY:
416                         log_debug("get yearly summary: %s - %s\n", start_date->to_string().c_str(), end_date->to_string().c_str());
417                         ret_val = get_yearly_summary(start_date, end_date);
418                         break;
419                 case PERIOD_MONTHLY:
420                         log_debug("get monthly summary\n");
421                         ret_val = get_monthly_summary(start_date, end_date);
422                         break;
423                 case PERIOD_DAILY:
424                         log_debug("get daily summary\n");
425                         ret_val = get_daily_summary(start_date, end_date);
426                         break;
427                 case PERIOD_HOURLY:
428                         log_debug("get hourly summary\n");
429                         ret_val = get_hourly_summary(start_date, end_date);
430                         break;
431                 case PERIOD_MINUTELY:
432                         log_debug("get minute summary data\n");
433                         break;
434                 case PERIOD_SECONDLY:
435                 default:
436                         log_debug("get second summary data\n");
437                         break;
438         }
439         return ret_val;
440 }
441
442 string DataReader::get_device_id() {
443         return device_id;
444 }
445
446 /**
447  * Read device type from the device specific config file.
448  *
449  * @rerurn string representing device type.
450  * In the case of error, an empty string is returned.
451  */
452 bool DataReader::get_device_type(string& type_param) {
453         bool    ret_val;
454
455         ret_val = false;
456         if (device_config == NULL) {
457                 device_config   = DeviceConfig::get_device_config(device_id);
458         }
459         if (device_config != NULL) {
460                 ret_val = device_config->get_config_value(DEVICE_CONFIG_VALUE_KEY__TYPE, type_param);
461         }
462         return ret_val;
463 }