]> pilppa.org Git - lib1wire.git/blob - src/W1Store.cc
Support for querying the list devices having data stored.
[lib1wire.git] / src / W1Store.cc
1 /*
2  * W1Store.cc
3  *
4  *  Created on: Oct 31, 2010
5  *      Author: lamikr
6  */
7
8 #include <list>
9 #include <string>
10 #include <fstream>
11 #include <valarray>
12 #include <limits>
13
14 #include <time.h>
15 #include <dirent.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <unistd.h>
19
20 #include <plp/log.h>
21
22 #include "DeviceConfig.hh"
23 #include "W1Configure.hh"
24 #include "W1Store.hh"
25 #include "W1Util.hh"
26
27 using namespace std;
28 using namespace w1;
29 using namespace plp;
30
31 W1Store::W1Store(string device_id,
32                 Date *date_time) {
33         store_data      = NULL;
34         range_data      = NULL;
35         store_file_name = get_file_name(device_id, date_time);
36         log_debug("data file name: %s\n", store_file_name.c_str());
37 }
38
39 W1Store::W1Store(string file_name_param) {
40         store_data      = NULL;
41         range_data      = NULL;
42         store_file_name = file_name_param;
43 }
44
45 W1Store::~W1Store() {
46         if (store_data != NULL) {
47                 delete(store_data);
48                 store_data      = NULL;
49         }
50 }
51
52 string W1Store::get_dir_name(string device_id, Date *date_time) {
53         string  ret_val;
54         char    buffer[30];
55         string  d_name;
56
57         d_name  = DeviceConfig::get_base_dir_name();
58         snprintf(buffer, 30, "%d/%02d", date_time->year, date_time->month);
59         ret_val = W1Util::concat_paths(d_name, device_id);
60         ret_val = ret_val + "/" + buffer;
61         return ret_val;
62 }
63
64 string W1Store::get_file_name(string device_id, Date *date_time) {
65         string  ret_val;
66         string  fname;
67         char    buffer[30];
68
69         snprintf(buffer, 30, "%d-%02d-%02d", date_time->year, date_time->month, date_time->day);
70         fname   = buffer;
71         fname   = fname + DATAFILE_SUFFIX;
72         ret_val = get_dir_name(device_id, date_time);
73         ret_val = W1Util::concat_paths(ret_val, fname);
74         return ret_val;
75 }
76
77 void W1Store::store(std::string device_id,
78                 std::list<std::string> *string_list) {
79         string          f_path;
80         string          line;
81         ofstream        *ostream;
82         Date            *date;
83
84         date    = new Date();
85         f_path  = get_file_name(device_id, date);
86         ostream = W1Util::open_for_writing(f_path.c_str());
87         // TODO: add mutex to protect string_list while it's read and emptied
88         if (ostream != NULL) {
89                 if (ostream->is_open()) {
90                         log_info("[%s] writing %d data values to file: %s\n", device_id.c_str(), string_list->size(), f_path.c_str());
91                         while(string_list->size() > 0) {
92                                 line    = string_list->front();
93                                 string_list->pop_front();
94                                 if (line.length() > 0) {
95                                         log_debug("storing line: %s\n", line.c_str());
96                                         *ostream << line << endl;
97                                 }
98                         }
99                         ostream->close();
100                 }
101                 else {
102                         log_error("[%s] Could not store data to file: %s\n", device_id.c_str(), f_path.c_str());
103                 }
104                 delete(ostream);
105         }
106         else {
107                 log_error("[%s] Could not store data to file: %s\n", device_id.c_str(), f_path.c_str());
108         }
109         delete(date);
110 }
111
112 void W1Store::load() {
113         Data            *data;
114         ifstream        in;
115         string          line;
116
117         if (store_data != NULL) {
118                 delete(store_data);
119                 store_data      = NULL;
120         }
121         in.open(store_file_name.c_str());
122         if (in.is_open() == true) {
123                 while (in.eof() == false) {
124                         getline(in, line);
125                         data    = Data::parse_data_string(line);
126                         if (store_data == NULL) {
127                                 store_data      = new DataRange(*data);
128                         }
129                         else {
130                                 store_data->add_data(*data);
131                         }
132                         delete(data);
133                 }
134         }
135 }
136
137 Data *W1Store::get_sum() {
138         int     row_count;
139         int     col_count;
140         double  new_val;
141         int     ii;
142         int     jj;
143         Data    *data;
144         Data    *ret_val;
145
146         ret_val = NULL;
147         data    = NULL;
148         if (store_data == NULL) {
149                 load();
150         }
151         if (store_data != NULL) {
152                 row_count       = store_data->get_data_row_count();
153                 log_debug("data row count: %d\n", row_count);
154                 if (row_count > 0) {
155                         col_count       = store_data->get_data_column_count();
156                         log_debug("data item count per row: %d\n", col_count);
157                         ret_val         = new Data(col_count);
158                         if (col_count > 0) {
159                                 for (ii = 0; ii < row_count - 1; ii++) {
160                                         data    = store_data->get_data(ii);
161                                         for (jj = 0; jj < col_count; jj++) {
162                                                 new_val                 = data->value_arr[jj];
163                                                 ret_val->value_arr[jj]  = ret_val->value_arr[jj] + new_val;
164                                         }
165                                         if (ii < (row_count - 2)) {
166                                                 delete(data);
167                                                 data    = NULL;
168                                         }
169                                         //log_debug("new val: %f, sum: %f\n", new_val, sum);
170                                 }
171                         }
172                         ret_val->set_date(data->get_date());
173                         if (data != NULL) {
174                                 delete(data);
175                         }
176                 }
177         }
178         return ret_val;
179 }
180
181 Data *W1Store::get_delta() {
182         int             row_count;
183         int             col_count;
184         Data            *o_data;
185         Data            *n_data;
186         Data            *ret_val;
187         int             ii;
188         DataRange       *dr;
189
190         ret_val = NULL;
191         dr      = get_oldest_and_newest_data();
192         if (dr != NULL) {
193                 row_count       = dr->get_data_row_count();
194                 if (row_count == 2) {
195                         o_data          = dr->get_data(0);
196                         n_data          = dr->get_data(1);
197                         col_count       = dr->get_data_column_count();
198                         ret_val         = new Data(col_count);
199                         if (col_count > 0) {
200                                 for (ii = 0; ii < col_count; ii++) {
201                                         ret_val->value_arr[ii]  = n_data->value_arr[ii] - o_data->value_arr[ii];
202                                 }
203                         }
204                         ret_val->set_date(n_data->get_date());
205                         delete(o_data);
206                         delete(n_data);
207                 }
208                 delete(dr);
209         }
210         return ret_val;
211 }
212
213 Data *W1Store::get_mean() {
214         int     row_count;
215         int     col_count;
216         int     ii;
217         Data    *ret_val;
218
219         ret_val = NULL;
220         if (store_data == NULL) {
221                 load();
222         }
223         if (store_data != NULL) {
224                 row_count       = store_data->get_data_row_count();
225                 if (row_count > 0) {
226                         col_count       = store_data->get_data_column_count();
227                         ret_val         = get_sum();
228                         if (col_count > 0) {
229                                 for (ii = 0; ii < col_count; ii++) {
230                                         ret_val->value_arr[ii]  = ret_val->value_arr[ii] / row_count;
231                                         log_debug("avg: %f\n", ret_val->value_arr[ii]);
232                                 }
233                         }
234                 }
235         }
236         return ret_val;
237 }
238
239 Data *W1Store::get_max() {
240         int     row_count;
241         int     col_count;
242         double  new_val;
243         int     ii;
244         int     jj;
245         Data    *data;
246         Data    *ret_val;
247         double  min_val;
248
249         ret_val = NULL;
250         data    = NULL;
251         if (store_data == NULL) {
252                 load();
253         }
254         if (store_data != NULL) {
255                 row_count       = store_data->get_data_row_count();
256                 log_debug("data row count: %d\n", row_count);
257                 if (row_count > 0) {
258                         col_count       = store_data->get_data_column_count();
259                         log_debug("data item count per row: %d\n", col_count);
260                         min_val         = numeric_limits<double>::min();
261                         ret_val         = new Data(col_count, min_val);
262                         if (col_count > 0) {
263                                 for (ii = 0; ii < row_count - 1; ii++) {
264                                         data    = store_data->get_data(ii);
265                                         for (jj = 0; jj < col_count; jj++) {
266                                                 new_val = data->value_arr[jj];
267                                                 if (new_val > ret_val->value_arr[jj]) {
268                                                         ret_val->value_arr[jj]  = new_val;
269                                                 }
270                                         }
271                                         if (ii < (row_count - 2)) {
272                                                 delete(data);
273                                                 data    = NULL;
274                                         }
275                                 }
276                         }
277                         ret_val->set_date(data->get_date());
278                         if (data != NULL) {
279                                 delete(data);
280                         }
281                 }
282         }
283         return ret_val;
284 }
285
286 Data *W1Store::get_min() {
287         int     row_count;
288         int     col_count;
289         double  new_val;
290         int     ii;
291         int     jj;
292         Data    *data;
293         Data    *ret_val;
294         double  max_val;
295
296         ret_val = NULL;
297         data    = NULL;
298         if (store_data == NULL) {
299                 load();
300         }
301         if (store_data != NULL) {
302                 row_count       = store_data->get_data_row_count();
303                 log_debug("data row count: %d\n", row_count);
304                 if (row_count > 0) {
305                         col_count       = store_data->get_data_column_count();
306                         log_debug("data item count per row: %d\n", col_count);
307                         max_val         = numeric_limits<double>::max();
308                         ret_val         = new Data(col_count, max_val);
309                         if (col_count > 0) {
310                                 for (ii = 0; ii < row_count - 1; ii++) {
311                                         data    = store_data->get_data(ii);
312                                         for (jj = 0; jj < col_count; jj++) {
313                                                 new_val = data->value_arr[jj];
314                                                 if (new_val < ret_val->value_arr[jj]) {
315                                                         ret_val->value_arr[jj]  = new_val;
316                                                 }
317                                         }
318                                         if (ii < (row_count - 2)) {
319                                                 delete(data);
320                                                 data    = NULL;
321                                         }
322                                 }
323                         }
324                         ret_val->set_date(data->get_date());
325                         if (data != NULL) {
326                                 delete(data);
327                         }
328                 }
329         }
330         return ret_val;
331 }
332
333 DataRange *W1Store::get_oldest_and_newest_data() {
334         DataRange       *ret_val;
335         ifstream        in;
336         Data            *o_data;
337         Data            *n_data;
338         string          latest;
339         int             row_count;
340         string          line;
341         string          prev_line;
342
343         ret_val = NULL;
344         o_data  = NULL;
345         n_data  = NULL;
346         if (store_data != NULL) {
347                 row_count       = store_data->get_data_row_count();
348                 if (row_count > 0) {
349                         o_data          = store_data->get_data(0);
350                         n_data          = store_data->get_data(row_count - 1);
351                 }
352         }
353         else {
354                 if (range_data != NULL) {
355                         row_count       = range_data->get_data_row_count();
356                         if (row_count > 0) {
357                                 o_data          = range_data->get_data(0);
358                                 n_data          = range_data->get_data(row_count - 1);
359                         }
360                 }
361                 else {
362                         in.open(store_file_name.c_str());
363                         while (in.eof() == false) {
364                                 getline(in, line);
365                                 if (line.empty() == false) {
366                                         if (o_data == NULL) {
367                                                 o_data  = Data::parse_data_string(line);
368                                         }
369                                         prev_line       = line;
370                                 }
371                         }
372                         if (prev_line.empty() == false) {
373                                 n_data  = Data::parse_data_string(prev_line);
374                         }
375                 }
376         }
377         if ((o_data != NULL) &&
378             (n_data != NULL)) {
379                 ret_val = new DataRange(*o_data);
380                 ret_val->add_data(*n_data);
381                 if (range_data != NULL) {
382                         range_data      = new DataRange(*o_data);
383                         range_data->add_data(*n_data);
384                 }
385         }
386         if (o_data != NULL) {
387                 delete(o_data);
388         }
389         if (n_data != NULL) {
390                 delete(n_data);
391         }
392         return ret_val;
393 }
394
395 Data *W1Store::get_oldest_data() {
396         int             row_count;
397         Data            *ret_val;
398         DataRange       *dr;
399
400         ret_val = NULL;
401         dr      = get_oldest_and_newest_data();
402         if (dr != NULL) {
403                 row_count       = dr->get_data_row_count();
404                 if (row_count >= 1) {
405                         ret_val = dr->get_data(0);
406                 }
407                 delete(dr);
408         }
409         return ret_val;
410 }
411
412 Data *W1Store::get_newest_data() {
413         int             row_count;
414         Data            *ret_val;
415         DataRange       *dr;
416
417         ret_val = NULL;
418         dr      = get_oldest_and_newest_data();
419         if (dr != NULL) {
420                 row_count       = dr->get_data_row_count();
421                 if (row_count == 2) {
422                         ret_val = dr->get_data(1);
423                 }
424                 delete(dr);
425         }
426         return ret_val;
427 }