]> pilppa.org Git - lib1wire.git/blob - src/W1Store.cc
d59e12121bf5999cb005cab53725f2e22f7f9296
[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 DataRange *data_range                   = NULL;
31
32 W1Store::W1Store(string device_id,
33                 Date *date_time) {
34         data_range      = NULL;
35         store_file_name = get_store_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         data_range      = NULL;
41         store_file_name = file_name_param;
42 }
43
44 W1Store::~W1Store() {
45         if (data_range != NULL) {
46                 delete(data_range);
47                 data_range      = NULL;
48         }
49 }
50
51 void W1Store::set_store_base_dir(string store_param) {
52         int     pos;
53         int     b_count;
54
55         pos     = store_param.find_last_of("/");
56         b_count = store_param.length();
57         if (pos == (b_count - 1)) {
58                 store_base_dir  = store_param;
59         }
60         else {
61                 store_base_dir  = store_param + "/";
62         }
63 }
64
65 string W1Store::get_store_base_dir() {
66         return store_base_dir;
67 }
68
69 string W1Store::get_store_dir_name(string device_id, Date *date_time) {
70         string  ret_val;
71         char    buffer[30];
72
73         snprintf(buffer, 30, "%d/%02d", date_time->year, date_time->month);
74         ret_val = W1Util::concat_paths(store_base_dir, device_id);
75         ret_val = ret_val + "/" + buffer;
76         return ret_val;
77 }
78
79 string W1Store::get_store_file_name(string device_id, Date *date_time) {
80         string  ret_val;
81         string  fname;
82         char    buffer[30];
83
84         snprintf(buffer, 30, "%d-%02d-%02d", date_time->year, date_time->month, date_time->day);
85         fname   = buffer;
86         fname   = fname + DATAFILE_SUFFIX;
87         ret_val = get_store_dir_name(device_id, date_time);
88         ret_val = W1Util::concat_paths(ret_val, fname);
89         return ret_val;
90 }
91
92 void W1Store::store(std::string device_id,
93                 std::list<std::string> *string_list) {
94         string          f_path;
95         string          line;
96         ofstream        *ostream;
97         Date            *date;
98
99         date    = new Date();
100         f_path  = get_store_file_name(device_id, date);
101         ostream = W1Util::open_for_writing(f_path.c_str());
102         // TODO: add mutex to protect string_list while it's read and emptied
103         if (ostream != NULL) {
104                 if (ostream->is_open()) {
105                         log_info("[%s] writing %d data values to file: %s\n", device_id.c_str(), string_list->size(), f_path.c_str());
106                         while(string_list->size() > 0) {
107                                 line    = string_list->front();
108                                 string_list->pop_front();
109                                 if (line.length() > 0) {
110                                         log_debug("storing line: %s\n", line.c_str());
111                                         *ostream << line << endl;
112                                 }
113                         }
114                         ostream->close();
115                 }
116                 else {
117                         log_error("[%s] Could not store data to file: %s\n", device_id.c_str(), f_path.c_str());
118                 }
119                 delete(ostream);
120         }
121         else {
122                 log_error("[%s] Could not store data to file: %s\n", device_id.c_str(), f_path.c_str());
123         }
124         delete(date);
125 }
126
127 void W1Store::load() {
128         Data            *data;
129         ifstream        in;
130         string          line;
131
132         if (data_range != NULL) {
133                 delete(data_range);
134                 data_range      = NULL;
135         }
136         in.open(store_file_name.c_str());
137         if (in.is_open() == true) {
138                 while (in.eof() == false) {
139                         getline(in, line);
140                         data    = W1Util::parse_data_line(line);
141                         if (data_range == NULL) {
142                                 data_range      = new DataRange(*data);
143                         }
144                         else {
145                                 data_range->add_data(*data);
146                         }
147                         delete(data);
148                 }
149         }
150 }
151
152 Data *W1Store::get_mean() {
153         int     d_count;
154         int     i_count;
155         double  avg;
156         double  new_val;
157         int     ii;
158         int     jj;
159         Date    *date;
160         Data    *data;
161         Data    *ret_val;
162
163         ret_val = NULL;
164         if (data_range == NULL) {
165                 load();
166         }
167         if (data_range != NULL) {
168                 d_count = data_range->get_data_row_count();
169                 log_debug("data row count: %d\n", d_count);
170                 if (d_count > 0) {
171                         i_count = data_range->get_data_column_count();
172                         log_debug("data item count per row: %d\n", i_count);
173                         ret_val = new Data(i_count);
174                         if (i_count > 0) {
175                                 for (ii = 0; ii < d_count - 1; ii++) {
176                                         data    = data_range->get_data(ii);
177                                         for (jj = 0; jj < i_count; jj++) {
178                                                 new_val                 = data->value_arr[jj];
179                                                 ret_val->value_arr[jj]  = ret_val->value_arr[jj] + new_val;
180                                         }
181                                         if (ii < (d_count - 2)) {
182                                                 delete(data);
183                                         }
184                                         //log_debug("new val: %f, sum: %f\n", new_val, sum);
185                                 }
186                                 for (ii = 0; ii < i_count; ii++) {
187                                         ret_val->value_arr[ii]  = ret_val->value_arr[ii] / d_count;
188                                         log_debug("avg: %f\n", ret_val->value_arr[ii]);
189                                 }
190                         }
191                         ret_val->set_date(data->get_date());
192                         delete(data);
193                 }
194         }
195         return ret_val;
196 }
197
198 Data *W1Store::load_first_data_row() {
199         Data            *ret_val;
200         ifstream        in;
201         string          line;
202
203         ret_val = NULL;
204         in.open(store_file_name.c_str());
205         if (in.eof() == false) {
206                 getline(in, line);
207                 ret_val = W1Util::parse_data_line(line);
208         }
209         return ret_val;
210 }
211
212 Data *W1Store::load_last_data_row() {
213         Data            *ret_val;
214         ifstream        in;
215         string          line;
216         string          prev_line;
217
218         ret_val = NULL;
219         in.open(store_file_name.c_str());
220         while (in.eof() == false) {
221                 getline(in, line);
222                 if (line.empty() == false) {
223                         prev_line       = line;
224                 }
225         }
226         if (prev_line.empty() == false) {
227                 ret_val = W1Util::parse_data_line(prev_line);
228         }
229         return ret_val;
230 }