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