]> pilppa.org Git - lib1wire.git/blob - src/DeviceData.cc
d13287c3c087796da6a654b7e14090a4071f1211
[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           = Factory::get_device_config(device_id_param);
29         summary_calc_type       = device_config->get_summary_calculation_type();
30         device_id               = device_id_param;
31         base_dir                = DeviceConfig::get_base_dir_name();
32         device_dir              = W1Util::concat_paths(base_dir, device_id);
33         device_ch_dir           = W1Util::concat_paths(base_dir, "cache");
34         device_ch_dir           = W1Util::concat_paths(device_ch_dir, device_id);
35 }
36
37 DeviceData::~DeviceData() {
38         delete(device_config);
39 }
40
41 Data *DeviceData::find_oldest_data(vector<string> year_vector) {
42         unsigned int    ii;
43         string          year_dr;
44         string          mon_dr;
45         vector<string>  mon_vcr;
46         vector<string>  dta_vcr;
47         string          f_name;
48         StoreDay        *store;
49         Data            *ret_val;
50
51         ret_val = NULL;
52         if (year_vector.size() > 0) {
53                 // dirs are alphabetically sorted
54                 year_dr = year_vector.at(0);
55                 year_dr = W1Util::concat_paths(device_dir, year_dr);
56                 mon_vcr = W1Util::get_subdirectories(year_dr);
57                 for (ii = 0; ii < mon_vcr.size(); 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                         dta_vcr = W1Util::get_data_files(mon_dr);
62                         if (dta_vcr.size() > 0) {
63                                 f_name  = dta_vcr.at(0);
64                                 f_name  = W1Util::concat_paths(mon_dr, f_name);
65                                 store   = new StoreDay(f_name);
66                                 ret_val = store->get_oldest_data();
67                                 delete(store);
68                                 break;
69                         }
70                 }
71         }
72         return ret_val;
73 }
74
75 Data *DeviceData::find_newest_data(vector<string> year_vector) {
76         int             ii;
77         string          year_dr;
78         string          mon_dr;
79         vector<string>  mon_vcr;
80         vector<string>  d_vcr;
81         string          f_name;
82         Data            *ret_val;
83         int             size;
84         StoreDay                *store;
85
86         ret_val = NULL;
87         size    = year_vector.size();
88         if (size > 0) {
89                 // dirs are alphabetically sorted
90                 year_dr = year_vector.at(size - 1);
91                 year_dr = W1Util::concat_paths(device_dir, year_dr);
92                 mon_vcr = W1Util::get_subdirectories(year_dr);
93                 for (ii = mon_vcr.size() - 1; ii >= 0; ii--) {
94                         mon_dr  = mon_vcr.at(ii);
95                         mon_dr  = W1Util::concat_paths(year_dr, mon_dr);
96                         // scan data files from month dir
97                         d_vcr   = W1Util::get_data_files(mon_dr);
98                         size    = d_vcr.size();
99                         if (size > 0) {
100                                 f_name  = d_vcr.at(size - 1);
101                                 f_name  = W1Util::concat_paths(mon_dr, f_name);
102                                 store   = new StoreDay(f_name);
103                                 ret_val = store->get_newest_data();
104                                 delete(store);
105                                 break;
106                         }
107                 }
108         }
109         return ret_val;
110 }
111
112 DataRange *DeviceData::get_data_range() {
113         DataRange       *ret_val;
114         vector<string>  y_list;
115         Data            *o_data;
116         Data            *n_data;
117
118         ret_val = NULL;
119         y_list  = W1Util::get_subdirectories(device_dir);
120         o_data  = find_oldest_data(y_list);
121         if (o_data != NULL) {
122                 n_data  = find_newest_data(y_list);
123                 if (n_data != NULL) {
124                         ret_val = new DataRange(o_data);
125                         ret_val->add(n_data);
126                         delete(n_data);
127                 }
128                 delete(o_data);
129         }
130         return ret_val;
131 }
132
133 EnumSummaryPeriod get_period_type(Date *start_date,
134                         Date *end_date) {
135         int                     diff;
136         EnumSummaryPeriod       ret_val;
137
138         ret_val = PERIOD_YEARLY;
139         diff    = end_date->year - start_date->year;
140         if (diff != 0) {
141                 ret_val = PERIOD_YEARLY;
142         }
143         else {
144                 diff    = end_date->month - start_date->month;
145                 if (diff != 0) {
146                         ret_val = PERIOD_MONTHLY;
147                 }
148                 else {
149                         diff    = end_date->day - start_date->day;
150                         if (diff != 0) {
151                                 ret_val = PERIOD_DAILY;
152                         }
153                         else {
154                                 diff    = end_date->hour - start_date->hour;
155                                 if (diff != 0) {
156                                         ret_val = PERIOD_HOURLY;
157                                 }
158                                 else {
159                                         diff    = end_date->min - start_date->min;
160                                         if (diff != 0) {
161                                                 ret_val = PERIOD_MINUTELY;
162                                         }
163                                         else {
164                                                 ret_val = PERIOD_SECONDLY;
165                                         }
166                                 }
167                         }
168                 }
169         }
170         return ret_val;
171 }
172
173 DataRange *DeviceData::get_summary(Date *date_param,
174                                 EnumSummaryCalculationType calc_type_param,
175                                 EnumSummaryPeriod period_type_param) {
176         DataRange       *ret_val;
177         StoreCache      *store;
178
179         ret_val = NULL;
180         //store = new StoreDay(device_id, date_param);
181         store   = new StoreCache(device_id, date_param);
182         if (store != NULL) {
183                 switch(calc_type_param) {
184                         case SUM:
185                                 ret_val = store->get_sum(period_type_param);
186                                 break;
187                         case DELTA:
188                                 ret_val = store->get_delta(period_type_param);
189                                 break;
190                         case MAX:
191                                 ret_val = store->get_max(period_type_param);
192                                 break;
193                         case MIN:
194                                 ret_val = store->get_min(period_type_param);
195                                 break;
196                         case MEAN:
197                         default:
198                                 ret_val = store->get_mean(period_type_param);
199                                 break;
200                 }
201                 if (ret_val != NULL) {
202                         ret_val->printout();
203                 }
204                 else {
205                         log_error("Could not read data log for device: %s\n", device_id.c_str());
206                 }
207         }
208         else {
209                 log_error("Could not read data log for device: %s\n", device_id.c_str());
210         }
211         delete(store);
212         return ret_val;
213 }
214
215 DataRange *DeviceData::get_monthly_summary(Date *date,
216                                 EnumSummaryCalculationType calc_type_param) {
217         return get_summary(date, calc_type_param, PERIOD_MONTHLY);
218 }
219
220 DataRange *DeviceData::get_monthly_summary(Date *date) {
221         DataRange       *ret_val;
222
223         ret_val = get_monthly_summary(date, summary_calc_type);
224         return ret_val;
225 }
226
227 DataRange *DeviceData::get_monthly_summary(Date *start_date,
228                                         Date *end_date) {
229         DataRange       *ret_val;
230         DataRange       *data;
231         Date            *date;
232
233         ret_val = NULL;
234         date    = start_date->clone();
235         while(date->before_or_equal_month(end_date)) {
236                 data    = get_monthly_summary(date);
237                 if (data != NULL) {
238                         if (ret_val == NULL) {
239                                 ret_val = new DataRange(data);
240                         }
241                         else {
242                                 ret_val->add(data);
243                         }
244                         delete(data);
245                 }
246                 date->next_month();
247         }
248         delete(date);
249         return ret_val;
250 }
251
252 DataRange *DeviceData::get_daily_summary(Date *date,
253                                 EnumSummaryCalculationType calc_type_param) {
254         return get_summary(date, calc_type_param, PERIOD_DAILY);
255 }
256
257 DataRange *DeviceData::get_daily_summary(Date *date) {
258         DataRange       *ret_val;
259
260         ret_val = get_daily_summary(date, summary_calc_type);
261         return ret_val;
262 }
263
264 DataRange *DeviceData::get_daily_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_day(end_date)) {
273                 data    = get_daily_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_day();
284         }
285         delete(date);
286         return ret_val;
287 }
288
289 DataRange *DeviceData::get_hourly_summary(Date *date,
290                 EnumSummaryCalculationType calc_type_param) {
291         return get_summary(date, calc_type_param, PERIOD_HOURLY);
292 }
293
294 DataRange *DeviceData::get_hourly_summary(Date *date) {
295         DataRange       *ret_val;
296
297         ret_val = get_hourly_summary(date, summary_calc_type);
298         return ret_val;
299 }
300
301 DataRange *DeviceData::get_hourly_summary(Date *start_date,
302                                         Date *end_date) {
303         DataRange       *ret_val;
304         DataRange       *dta_lst;
305         Data            *data;
306         Date            *date;
307         int             cnt;
308         int             ii;
309
310         ret_val = NULL;
311         date    = start_date->clone();
312         while(date->before_or_equal_hour(end_date)) {
313                 dta_lst = get_hourly_summary(date);
314                 cnt     = dta_lst->get_count();
315                 for(ii = 0; ii < cnt; ii++) {
316                         data    = dta_lst->get(ii);
317                         if (data != NULL) {
318                                 if (ret_val == NULL) {
319                                         ret_val = new DataRange(data);
320                                 }
321                                 else {
322                                         ret_val->add(data);
323                                 }
324                                 delete(data);
325                         }
326                 }
327                 date->next_day();
328         }
329         delete(date);
330         return ret_val;
331 }
332
333 DataRange *DeviceData::get_data(Date *start_date,
334                                 Date *end_date) {
335         DataRange               *ret_val;
336         EnumSummaryPeriod       period;
337
338         ret_val = NULL;
339         start_date->printout();
340         end_date->printout();
341         period  = get_period_type(start_date, end_date);
342         switch(period) {
343                 case PERIOD_YEARLY:
344                         log_debug("get yearly summary: %s - %s\n", start_date->to_string().c_str(), end_date->to_string().c_str());
345                         ret_val = get_monthly_summary(start_date, end_date);
346                         break;
347                 case PERIOD_MONTHLY:
348                         log_debug("get monthly summary\n");
349                         ret_val = get_monthly_summary(start_date, end_date);
350                         break;
351                 case PERIOD_DAILY:
352                         log_debug("get daily summary\n");
353                         ret_val = get_daily_summary(start_date, end_date);
354                         break;
355                 case PERIOD_HOURLY:
356                         log_debug("get hourly summary\n");
357                         ret_val = get_hourly_summary(start_date, end_date);
358                         break;
359                 case PERIOD_MINUTELY:
360                         log_debug("get minute summary data\n");
361                         break;
362                 case PERIOD_SECONDLY:
363                 default:
364                         log_debug("get second summary data\n");
365                         break;
366         }
367         return ret_val;
368 }