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