4 * Created on: Oct 31, 2010
15 #include <sys/types.h>
20 #include "DeviceConfig.hh"
21 #include "StoreDay.hh"
22 #include "FileUtil.hh"
27 StoreDay::StoreDay(string device_id_param,
28 Date *date_time_param): Store(device_id_param, date_time_param) {
29 store_fname = get_file_name(device_id_param, date_time_param);
32 StoreDay::StoreDay(string fname_param): Store("", NULL) {
35 store_fname = fname_param;
38 StoreDay::~StoreDay() {
39 if (store_data != NULL) {
45 string StoreDay::get_dir_name(string device_id, Date *date_time_param) {
50 snprintf(buffer, 30, "%d/%02d", date_time_param->year, date_time_param->month);
51 bd_name = DeviceConfig::get_base_dir_name();
52 bd_name = FileUtil::concat_paths(bd_name, device_id);
53 ret_val = bd_name + "/" + buffer;
57 string StoreDay::get_file_name(string device_id, Date *date_time_param) {
62 snprintf(buffer, 30, "%d-%02d-%02d", date_time_param->year, date_time_param->month, date_time_param->day);
64 fname = fname + DATAFILE_SUFFIX;
65 ret_val = get_dir_name(device_id, date_time_param);
66 ret_val = FileUtil::concat_paths(ret_val, fname);
70 void StoreDay::save(string device_id,
71 std::list<Data *> *data_list,
79 list<Data *>::iterator iter;
83 /* needs to be casted to long unsigned int value is "unsigned int" in some
84 toolchains and that would otherwise cause an warning/error
86 log_info("[%s] writing %lu data values to save.\n", device_id.c_str(),
87 (long unsigned int)data_list->size());
88 // TODO: add mutex to protect string_list while it's read and emptied
89 for(iter = data_list->begin(); iter != data_list->end(); iter++) {
91 date = data->get_date();
92 n_path = get_file_name(device_id, &date);
93 if (n_path.compare(f_path) != 0) {
94 if (ostream != NULL) {
99 log_info("[%s] Opening file for save: %s\n", device_id.c_str(), f_path.c_str());
100 ostream = FileUtil::open_for_writing(f_path.c_str());
102 if ((ostream != NULL) &&
103 (ostream->is_open() == true)) {
104 line = data->to_string(dec_precision);
105 if (line.length() > 0) {
106 log_debug("storing line: %s\n", line.c_str());
107 *ostream << line << endl;
111 log_error("[%s] File open for data save failed: %s\n", device_id.c_str(), f_path.c_str());
114 if (ostream != NULL) {
120 bool StoreDay::load() {
121 return Store::load(store_fname);
124 bool StoreDay::exist(string fname_param) {
126 ret_val = (access(fname_param.c_str(), F_OK) == 0);
130 bool StoreDay::exist() {
131 return exist(store_fname);
134 static int get_summary_period_as_freq_seconds(EnumSummaryPeriod period_type_param) {
138 switch(period_type_param) {
139 case PERIOD_SECONDLY:
142 case PERIOD_MINUTELY:
152 // -1 as freq means that show all data from the current store
159 plp::DataRange *StoreDay::get_sum(EnumSummaryPeriod period_type_param) {
171 ret_val = new DataRange();
174 frq_sec = get_summary_period_as_freq_seconds(period_type_param);
175 if (store_data == NULL) {
178 if (store_data != NULL) {
179 row_count = store_data->get_count();
181 col_count = store_data->get_data_item_value_count();
183 for (ii = 0; ii < row_count; ii++) {
184 data = store_data->get(ii);
187 calc = data->clone();
188 limit_d = data->get_date().clone();
191 limit_d->inc_seconds(frq_sec);
194 date = data->get_date();
195 if ((ii <= (row_count -1)) &&
196 ((frq_sec == -1) || (date.before(limit_d)))) {
197 for (jj = 0; jj < col_count; jj++) {
198 calc->value_arr[jj] = calc->value_arr[jj] + data->value_arr[jj];
201 if ((ii >= (row_count -1)) ||
202 ((frq_sec != -1) && (date.before(limit_d) == false))) {
205 calc = data->clone();
206 if (limit_d != NULL) {
209 limit_d = data->get_date().clone();
212 limit_d->inc_seconds(frq_sec);
222 if (limit_d != NULL) {
231 plp::DataRange *StoreDay::get_mean(EnumSummaryPeriod period_type_param) {
244 ret_val = new DataRange();
248 frq_sec = get_summary_period_as_freq_seconds(period_type_param);
249 if (store_data == NULL) {
252 if (store_data != NULL) {
253 row_count = store_data->get_count();
255 col_count = store_data->get_data_item_value_count();
257 for (ii = 0; ii < row_count; ii++) {
258 data = store_data->get(ii);
262 calc = data->clone();
263 limit_d = data->get_date().clone();
266 limit_d->inc_seconds(frq_sec);
269 date = data->get_date();
270 if ((ii <= (row_count -1)) &&
271 ((frq_sec == -1) || (date.before(limit_d)))) {
272 for (jj = 0; jj < col_count; jj++) {
273 calc->value_arr[jj] = calc->value_arr[jj] + data->value_arr[jj];
277 if ((ii >= (row_count -1)) ||
278 ((frq_sec != -1) && (date.before(limit_d) == false))) {
279 for (jj = 0; jj < col_count; jj++) {
280 calc->value_arr[jj] = calc->value_arr[jj] / d_count;
285 calc = data->clone();
286 if (limit_d != NULL) {
289 limit_d = data->get_date().clone();
292 limit_d->inc_seconds(frq_sec);
302 if (limit_d != NULL) {
311 plp::DataRange *StoreDay::get_delta(EnumSummaryPeriod period_type_param) {
324 ret_val = new DataRange();
328 frq_sec = get_summary_period_as_freq_seconds(period_type_param);
329 if (store_data == NULL) {
332 if (store_data != NULL) {
333 row_count = store_data->get_count();
335 col_count = store_data->get_data_item_value_count();
337 for (ii = 0; ii < row_count; ii++) {
338 data = store_data->get(ii);
341 calc1 = data->clone();
342 limit_d = data->get_date().clone();
345 limit_d->inc_seconds(frq_sec);
352 date = data->get_date();
353 if ((ii <= (row_count -1)) &&
354 ((frq_sec == -1) || (date.before(limit_d)))) {
358 calc2 = data->clone();
360 if ((ii >= (row_count -1)) ||
361 ((frq_sec != -1) && (date.before(limit_d) == false))) {
363 calc2 = calc1->clone();
365 for (jj = 0; jj < col_count; jj++) {
366 calc2->value_arr[jj] = calc2->value_arr[jj] - calc1->value_arr[jj];
370 calc1 = data->clone();
373 if (limit_d != NULL) {
376 limit_d = data->get_date().clone();
379 limit_d->inc_seconds(frq_sec);
393 if (limit_d != NULL) {
402 plp::DataRange *StoreDay::get_max_or_min(EnumSummaryPeriod period_type_param, bool max) {
414 ret_val = new DataRange();
417 frq_sec = get_summary_period_as_freq_seconds(period_type_param);
418 if (store_data == NULL) {
421 if (store_data != NULL) {
422 row_count = store_data->get_count();
424 col_count = store_data->get_data_item_value_count();
426 for (ii = 0; ii < row_count; ii++) {
427 data = store_data->get(ii);
430 calc = data->clone();
431 limit_d = data->get_date().clone();
434 limit_d->inc_seconds(frq_sec);
437 date = data->get_date();
438 if ((ii <= (row_count -1)) &&
439 ((frq_sec == -1) || (date.before(limit_d)))) {
442 for (jj = 0; jj < col_count; jj++) {
443 if (calc->value_arr[jj] < data->value_arr[jj]) {
444 calc->value_arr[jj] = data->value_arr[jj];
450 for (jj = 0; jj < col_count; jj++) {
451 if (data->value_arr[jj] < calc->value_arr[jj]) {
452 calc->value_arr[jj] = data->value_arr[jj];
460 new_date = data->get_date();
461 calc->set_date(&new_date);
464 if ((ii >= (row_count -1)) ||
465 ((frq_sec != -1) && (date.before(limit_d) == false))) {
468 calc = data->clone();
469 if (limit_d != NULL) {
472 limit_d = data->get_date().clone();
475 limit_d->inc_seconds(frq_sec);
485 if (limit_d != NULL) {
494 plp::DataRange *StoreDay::get_max(EnumSummaryPeriod period_type_param) {
497 ret_val = get_max_or_min(period_type_param, true);
501 plp::DataRange *StoreDay::get_min(EnumSummaryPeriod period_type_param) {
504 ret_val = get_max_or_min(period_type_param, false);
508 DataRange *StoreDay::get_oldest_and_latest_data(string fname_param) {
521 if (store_data != NULL) {
522 row_count = store_data->get_count();
524 o_data = store_data->get(0);
525 n_data = store_data->get(row_count - 1);
529 if (range_data != NULL) {
530 row_count = range_data->get_count();
532 o_data = range_data->get(0);
533 n_data = range_data->get(row_count - 1);
537 in.open(fname_param.c_str());
538 if (in.is_open() == true) {
539 while (in.eof() == false) {
541 if (line.empty() == false) {
542 if (o_data == NULL) {
543 o_data = Data::parse_string(line);
548 if (prev_line.empty() == false) {
549 n_data = Data::parse_string(prev_line);
554 if ((o_data != NULL) &&
556 ret_val = new DataRange(o_data);
557 ret_val->add(n_data);
558 if (range_data != NULL) {
559 range_data = new DataRange(o_data);
560 range_data->add(n_data);
563 if (o_data != NULL) {
566 if (n_data != NULL) {
572 DataRange *StoreDay::get_oldest_and_latest_data() {
573 return get_oldest_and_latest_data(store_fname);
576 Data *StoreDay::get_oldest_data() {
582 dr = get_oldest_and_latest_data();
584 row_count = dr->get_count();
585 if (row_count >= 1) {
586 ret_val = dr->get(0);
593 Data *StoreDay::get_latest_data() {
599 dr = get_oldest_and_latest_data();
601 row_count = dr->get_count();
602 if (row_count == 2) {
603 ret_val = dr->get(1);