]> pilppa.org Git - lib1wire.git/blob - src/W1Store.cc
23adbb02da5b57d9769da7f88c2f7ccd46bd7038
[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
13 #include <time.h>
14 #include <dirent.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <unistd.h>
18
19 #include <plp/log.h>
20
21 #include "W1Configure.hh"
22 #include "W1Store.hh"
23 #include "W1Util.hh"
24
25 using namespace std;
26 using namespace w1;
27 using namespace plp;
28
29 std::string W1Store::store_base_dir     = DEFAULT_STORAGE_BASE_DIR;
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 void W1Store::set_base_dir_name(string store_param) {
53         int     pos;
54         int     b_count;
55
56         pos     = store_param.find_last_of("/");
57         b_count = store_param.length();
58         if (pos == (b_count - 1)) {
59                 store_base_dir  = store_param;
60         }
61         else {
62                 store_base_dir  = store_param + "/";
63         }
64 }
65
66 string W1Store::get_base_dir_name() {
67         return store_base_dir;
68 }
69
70 string W1Store::get_dir_name(string device_id, Date *date_time) {
71         string  ret_val;
72         char    buffer[30];
73
74         snprintf(buffer, 30, "%d/%02d", date_time->year, date_time->month);
75         ret_val = W1Util::concat_paths(store_base_dir, device_id);
76         ret_val = ret_val + "/" + buffer;
77         return ret_val;
78 }
79
80 string W1Store::get_file_name(string device_id, Date *date_time) {
81         string  ret_val;
82         string  fname;
83         char    buffer[30];
84
85         snprintf(buffer, 30, "%d-%02d-%02d", date_time->year, date_time->month, date_time->day);
86         fname   = buffer;
87         fname   = fname + DATAFILE_SUFFIX;
88         ret_val = get_dir_name(device_id, date_time);
89         ret_val = W1Util::concat_paths(ret_val, fname);
90         return ret_val;
91 }
92
93 void W1Store::store(std::string device_id,
94                 std::list<std::string> *string_list) {
95         string          f_path;
96         string          line;
97         ofstream        *ostream;
98         Date            *date;
99
100         date    = new Date();
101         f_path  = get_file_name(device_id, date);
102         ostream = W1Util::open_for_writing(f_path.c_str());
103         // TODO: add mutex to protect string_list while it's read and emptied
104         if (ostream != NULL) {
105                 if (ostream->is_open()) {
106                         log_info("[%s] writing %d data values to file: %s\n", device_id.c_str(), string_list->size(), f_path.c_str());
107                         while(string_list->size() > 0) {
108                                 line    = string_list->front();
109                                 string_list->pop_front();
110                                 if (line.length() > 0) {
111                                         log_debug("storing line: %s\n", line.c_str());
112                                         *ostream << line << endl;
113                                 }
114                         }
115                         ostream->close();
116                 }
117                 else {
118                         log_error("[%s] Could not store data to file: %s\n", device_id.c_str(), f_path.c_str());
119                 }
120                 delete(ostream);
121         }
122         else {
123                 log_error("[%s] Could not store data to file: %s\n", device_id.c_str(), f_path.c_str());
124         }
125         delete(date);
126 }
127
128 void W1Store::load() {
129         Data            *data;
130         ifstream        in;
131         string          line;
132
133         if (store_data != NULL) {
134                 delete(store_data);
135                 store_data      = NULL;
136         }
137         in.open(store_file_name.c_str());
138         if (in.is_open() == true) {
139                 while (in.eof() == false) {
140                         getline(in, line);
141                         data    = Data::parse_data_string(line);
142                         if (store_data == NULL) {
143                                 store_data      = new DataRange(*data);
144                         }
145                         else {
146                                 store_data->add_data(*data);
147                         }
148                         delete(data);
149                 }
150         }
151 }
152
153 Data *W1Store::get_delta() {
154         int             row_count;
155         int             col_count;
156         Data            *o_data;
157         Data            *n_data;
158         Data            *ret_val;
159         int             ii;
160         DataRange       *dr;
161
162         ret_val = NULL;
163         dr      = get_oldest_and_newest_data();
164         if (dr != NULL) {
165                 row_count       = dr->get_data_row_count();
166                 if (row_count == 2) {
167                         o_data          = dr->get_data(0);
168                         n_data          = dr->get_data(1);
169                         col_count       = dr->get_data_column_count();
170                         ret_val         = new Data(col_count);
171                         if (col_count > 0) {
172                                 for (ii = 0; ii < col_count; ii++) {
173                                         ret_val->value_arr[ii]  = n_data->value_arr[ii] - o_data->value_arr[ii];
174                                 }
175                         }
176                         ret_val->set_date(n_data->get_date());
177                         delete(o_data);
178                         delete(n_data);
179                 }
180                 delete(dr);
181         }
182         return ret_val;
183 }
184
185 Data *W1Store::get_mean() {
186         int     row_count;
187         int     col_count;
188         double  avg;
189         double  new_val;
190         int     ii;
191         int     jj;
192         Date    *date;
193         Data    *data;
194         Data    *ret_val;
195
196         ret_val = NULL;
197         data    = NULL;
198         if (store_data == NULL) {
199                 load();
200         }
201         if (store_data != NULL) {
202                 row_count       = store_data->get_data_row_count();
203                 log_debug("data row count: %d\n", row_count);
204                 if (row_count > 0) {
205                         col_count       = store_data->get_data_column_count();
206                         log_debug("data item count per row: %d\n", col_count);
207                         ret_val         = new Data(col_count);
208                         if (col_count > 0) {
209                                 for (ii = 0; ii < row_count - 1; ii++) {
210                                         data    = store_data->get_data(ii);
211                                         for (jj = 0; jj < col_count; jj++) {
212                                                 new_val                 = data->value_arr[jj];
213                                                 ret_val->value_arr[jj]  = ret_val->value_arr[jj] + new_val;
214                                         }
215                                         if (ii < (row_count - 2)) {
216                                                 delete(data);
217                                                 data    = NULL;
218                                         }
219                                         //log_debug("new val: %f, sum: %f\n", new_val, sum);
220                                 }
221                                 for (ii = 0; ii < col_count; ii++) {
222                                         ret_val->value_arr[ii]  = ret_val->value_arr[ii] / row_count;
223                                         log_debug("avg: %f\n", ret_val->value_arr[ii]);
224                                 }
225                         }
226                         ret_val->set_date(data->get_date());
227                         if (data != NULL) {
228                                 delete(data);
229                         }
230                 }
231         }
232         return ret_val;
233 }
234
235 DataRange *W1Store::get_oldest_and_newest_data() {
236         DataRange       *ret_val;
237         ifstream        in;
238         Data            *o_data;
239         Data            *n_data;
240         string          latest;
241         int             row_count;
242         string          line;
243         string          prev_line;
244
245         ret_val = NULL;
246         o_data  = NULL;
247         n_data  = NULL;
248         if (store_data != NULL) {
249                 row_count       = store_data->get_data_row_count();
250                 if (row_count > 0) {
251                         o_data          = store_data->get_data(0);
252                         n_data          = store_data->get_data(row_count - 1);
253                 }
254         }
255         else {
256                 if (range_data != NULL) {
257                         row_count       = range_data->get_data_row_count();
258                         if (row_count > 0) {
259                                 o_data          = range_data->get_data(0);
260                                 n_data          = range_data->get_data(row_count - 1);
261                         }
262                 }
263                 else {
264                         in.open(store_file_name.c_str());
265                         while (in.eof() == false) {
266                                 getline(in, line);
267                                 if (line.empty() == false) {
268                                         if (o_data == NULL) {
269                                                 o_data  = Data::parse_data_string(line);
270                                         }
271                                         prev_line       = line;
272                                 }
273                         }
274                         if (prev_line.empty() == false) {
275                                 n_data  = Data::parse_data_string(prev_line);
276                         }
277                 }
278         }
279         if ((o_data != NULL) &&
280             (n_data != NULL)) {
281                 ret_val = new DataRange(*o_data);
282                 ret_val->add_data(*n_data);
283                 if (range_data != NULL) {
284                         range_data      = new DataRange(*o_data);
285                         range_data->add_data(*n_data);
286                 }
287         }
288         if (o_data != NULL) {
289                 delete(o_data);
290         }
291         if (n_data != NULL) {
292                 delete(n_data);
293         }
294         return ret_val;
295 }
296
297 Data *W1Store::get_oldest_data() {
298         int             row_count;
299         int             col_count;
300         Data            *ret_val;
301         DataRange       *dr;
302
303         ret_val = NULL;
304         dr      = get_oldest_and_newest_data();
305         if (dr != NULL) {
306                 row_count       = dr->get_data_row_count();
307                 if (row_count >= 1) {
308                         ret_val = dr->get_data(0);
309                 }
310                 delete(dr);
311         }
312         return ret_val;
313 }
314
315 Data *W1Store::get_newest_data() {
316         int             row_count;
317         int             col_count;
318         Data            *ret_val;
319         DataRange       *dr;
320
321         ret_val = NULL;
322         dr      = get_oldest_and_newest_data();
323         if (dr != NULL) {
324                 row_count       = dr->get_data_row_count();
325                 if (row_count == 2) {
326                         ret_val = dr->get_data(1);
327                 }
328                 delete(dr);
329         }
330         return ret_val;
331 }