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