From dcc5fd94e2ec65898dd8bda440cb0539e1f60373 Mon Sep 17 00:00:00 2001 From: Mika Laitio Date: Mon, 27 Dec 2010 18:47:03 +0200 Subject: [PATCH] Several data read and store fixes. Fix for "month" number in month folder and file-names when storing data. Fixes for reading data, when the file containing data can not be opened. Memory leak fixes. Hourly data read fixes. Signed-off-by: Mika Laitio --- src/Data.cc | 23 ++++- src/Data.hh | 2 + src/Date.cc | 56 ++++++++++- src/Date.hh | 3 + src/DeviceConfig.cc | 2 +- src/DeviceData.cc | 108 +++++++++++++++++--- src/DeviceData.hh | 4 +- src/W1Store.cc | 168 ++++++++++++++++++++++++++++++- src/W1Store.hh | 7 +- src_test/test_w1_datalog_read.cc | 3 +- 10 files changed, 355 insertions(+), 21 deletions(-) diff --git a/src/Data.cc b/src/Data.cc index 29325b7..c964bc4 100644 --- a/src/Data.cc +++ b/src/Data.cc @@ -62,7 +62,6 @@ Data::Data(std::valarray value_arr_param, Date *date_param) { unsigned int ii; value_arr.resize(value_arr_param.size()); - for (ii = 0; ii < value_arr_param.size(); ii++) { value_arr[ii] = value_arr_param[ii]; } @@ -72,6 +71,13 @@ Data::Data(std::valarray value_arr_param, Date *date_param) { Data::~Data() { } +Data *Data::clone() { + Data *ret_val; + + ret_val = new Data(value_arr, &date_time); + return ret_val; +} + plp::Date Data::get_date() { return date_time; } @@ -207,3 +213,18 @@ Data *DataRange::get_first_data() { Data *DataRange::get_last_data() { return get_data(row_count - 1); } + +void DataRange::printout() { + int ii; + Data *data; + + log_debug("---- DataRange, number of data items: %d\n ----", row_count); + for (ii = 0; ii < row_count; ii++) { + data = get_data(ii); + if (data != NULL) { + data->printout(); + delete(data); + } + } + log_debug("---- DataRange printout done ----\n"); +} diff --git a/src/Data.hh b/src/Data.hh index 35af7c6..8a8a28a 100644 --- a/src/Data.hh +++ b/src/Data.hh @@ -22,6 +22,7 @@ namespace w1 { Data(std::vector vector_param, plp::Date *date_param); Data(std::valarray value_arr_param, plp::Date *date_param); virtual ~Data(); + Data *clone(); plp::Date get_date(); void set_date(plp::Date date); void printout(); @@ -42,6 +43,7 @@ namespace w1 { Data *get_last_data(); int get_data_row_count(); int get_data_column_count(); + void printout(); protected: double *val_matrix; std::vector date_list; diff --git a/src/Date.cc b/src/Date.cc index 8c03c5b..e82ee99 100644 --- a/src/Date.cc +++ b/src/Date.cc @@ -27,7 +27,7 @@ Date::Date() { time(&wtime); ltime = localtime(&wtime); year = 1900 + ltime->tm_year; - month = ltime->tm_mon; + month = ltime->tm_mon + 1; // ltime-month: values 0 - 11... day = ltime->tm_mday; hour = ltime->tm_hour; min = ltime->tm_min; @@ -137,6 +137,60 @@ void Date::tomorrow() { } } +void Date::next_hour() { + if ((hour >= 0) && + (hour <= 24)) { + hour++; + if (hour > 24) { + hour = 0; + tomorrow(); + } + } +} + +void Date::inc_minutes(int minutes) { + int day_c; + int hour_c; + int ii; + + day_c = minutes / 1440; + minutes = minutes - day_c * 1440; + hour_c = minutes / 60; + minutes = minutes - hour_c * 60; + for (ii = 0; ii < day_c; ii++) { + tomorrow(); + } + for (ii = 0; ii < hour_c; ii++) { + hour++; + if (hour > 24) { + hour = 0; + tomorrow(); + } + } + min = min + minutes; + if (min >= 60) { + min = min % 60; + hour++; + if (hour > 24) { + hour = 0; + tomorrow(); + } + } +} + +void Date::inc_seconds(int seconds) { + int min_c; + + min_c = seconds / 60; + seconds = seconds - min_c * 60; + inc_minutes(min_c); + sec = sec + seconds; + if (sec >= 60) { + sec = sec % 60; + inc_minutes(1); + } +} + string Date::to_string() { char buffer[30]; string ret_val; diff --git a/src/Date.hh b/src/Date.hh index b2b908d..2d6fd75 100644 --- a/src/Date.hh +++ b/src/Date.hh @@ -24,6 +24,9 @@ namespace plp { void printout(); bool is_leap_year(); void tomorrow(); + void next_hour(); + void inc_minutes(int minutes); + void inc_seconds(int seconds); Date *clone(); void copy(Date *date); bool before(Date date2); diff --git a/src/DeviceConfig.cc b/src/DeviceConfig.cc index f9e8f72..19cfbb9 100644 --- a/src/DeviceConfig.cc +++ b/src/DeviceConfig.cc @@ -128,7 +128,7 @@ enum_summary_calculation DeviceConfig::get_summary_calculation_type() { ret_val = MEAN; if (device_type.empty() == false) { - if (device_type.compare("counter") == 0) { + if (device_type.compare("Counter Device") == 0) { ret_val = DELTA; } } diff --git a/src/DeviceData.cc b/src/DeviceData.cc index 259d821..13c28aa 100644 --- a/src/DeviceData.cc +++ b/src/DeviceData.cc @@ -169,59 +169,137 @@ long int get_interval_type(Date *start_date, return ret_val; } -Data *DeviceData::get_daily_summary(Date *date) { +Data *DeviceData::get_day_summary(Date *date) { Data *ret_val; W1Store *store; + bool suc_flg; + + ret_val = NULL; + store = new W1Store(device_id, date); + if (store != NULL) { + suc_flg = store->load(); + if (suc_flg == true) { + switch(summary_calc_type) { + case SUM: + ret_val = store->get_sum(); + break; + case DELTA: + ret_val = store->get_delta(); + break; + case MEAN: + default: + ret_val = store->get_mean(); + break; + case MAX: + ret_val = store->get_max(); + break; + case MIN: + ret_val = store->get_min(); + break; + } + if (ret_val != NULL) { + ret_val->printout(); + } + else { + log_error("Could not read data log for device: %s\n", device_id.c_str()); + } + } + else { + log_error("Could not read data log for device: %s. Data file open load failed.\n", device_id.c_str()); + } + } + else { + log_error("Could not read data log for device: %s\n", device_id.c_str()); + } + delete(store); + return ret_val; +} + +DataRange *DeviceData::get_daily_summary(Date *start_date, + Date *end_date) { + DataRange *ret_val; + Data *data; + Date *date; + + ret_val = NULL; + date = start_date->clone(); + while(date->before(*end_date)) { + data = get_day_summary(date); + if (data != NULL) { + if (ret_val == NULL) { + ret_val = new DataRange(*data); + } + else { + ret_val->add_data(*data); + } + delete(data); + } + date->tomorrow(); + } + delete(date); + return ret_val; +} + +vector DeviceData::get_hourly_summary(Date *date) { + vector ret_val; + W1Store * store; store = new W1Store(device_id, date); store->load(); switch(summary_calc_type) { +/* case SUM: ret_val = store->get_sum(); break; +*/ case DELTA: - ret_val = store->get_delta(); + ret_val = store->get_delta(3600); break; case MEAN: default: - ret_val = store->get_mean(); + ret_val = store->get_mean(3600); break; +/* case MAX: ret_val = store->get_max(); break; case MIN: ret_val = store->get_min(); break; +*/ } - ret_val->printout(); delete(store); - return ret_val; } -DataRange *DeviceData::get_daily_summary(Date *start_date, +DataRange *DeviceData::get_hourly_summary(Date *start_date, Date *end_date) { DataRange *ret_val; + vector dta_list; Data *data; Date *date; ret_val = NULL; date = start_date->clone(); while(date->before(*end_date)) { - data = get_daily_summary(date); - if (ret_val == NULL) { - ret_val = new DataRange(*data); - } - else { - ret_val->add_data(*data); + dta_list = get_hourly_summary(date); + for(vector::iterator list_iter = dta_list.begin(); list_iter != dta_list.end(); list_iter++) { + data = (Data *)*list_iter; + if (data != NULL) { + if (ret_val == NULL) { + ret_val = new DataRange(*data); + } + else { + ret_val->add_data(*data); + } + delete(data); + } } - delete(data); date->tomorrow(); } delete(date); return ret_val; } - DataRange *DeviceData::get_data(Date *start_date, Date *end_date) { DataRange *ret_val; @@ -237,6 +315,7 @@ DataRange *DeviceData::get_data(Date *start_date, break; case 1: log_debug("get monthly summary\n"); + ret_val = get_daily_summary(start_date, end_date); break; case 2: log_debug("get daily summary\n"); @@ -244,6 +323,7 @@ DataRange *DeviceData::get_data(Date *start_date, break; case 3: log_debug("get hourly summary\n"); + ret_val = get_hourly_summary(start_date, end_date); break; case 4: log_debug("get minute summary data\n"); diff --git a/src/DeviceData.hh b/src/DeviceData.hh index 3362971..a4c06ac 100644 --- a/src/DeviceData.hh +++ b/src/DeviceData.hh @@ -27,8 +27,10 @@ namespace w1 { * Get summary data calculated from the daily data items that is meaning full. * Depending from the device type, it may be daily mean value, daily delta, highest value, etc... */ - Data *get_daily_summary(plp::Date *date); + Data *get_day_summary(plp::Date *date); DataRange *get_daily_summary(plp::Date *start_date, plp::Date *end_date); + std::vector get_hourly_summary(plp::Date *date); + DataRange *get_hourly_summary(plp::Date *start_date, plp::Date *end_date); DataRange *get_data(plp::Date *start_date, plp::Date *end_date); protected: std::string device_id; diff --git a/src/W1Store.cc b/src/W1Store.cc index 8debaa1..9913d0d 100644 --- a/src/W1Store.cc +++ b/src/W1Store.cc @@ -109,11 +109,13 @@ void W1Store::store(std::string device_id, delete(date); } -void W1Store::load() { +bool W1Store::load() { Data *data; ifstream in; string line; + bool ret_val; + ret_val = false; if (store_data != NULL) { delete(store_data); store_data = NULL; @@ -131,7 +133,12 @@ void W1Store::load() { } delete(data); } + ret_val = true; } + else { + log_error("Could not load data from file: %s\n", store_file_name.c_str()); + } + return ret_val; } Data *W1Store::get_sum() { @@ -330,6 +337,165 @@ Data *W1Store::get_min() { return ret_val; } +vector W1Store::get_mean(int freq_sec) { + int row_count; + int col_count; + int d_count; + int jj; + int ii; + Data *data; + Data *calc; + Date *limit_d; + Date date; + vector ret_val; + + calc = NULL; + limit_d = NULL; + d_count = 1; + if (store_data == NULL) { + load(); + } + if (store_data != NULL) { + row_count = store_data->get_data_row_count(); + if (row_count > 0) { + col_count = store_data->get_data_column_count(); + if (col_count > 0) { + for (ii = 0; ii < row_count; ii++) { + data = store_data->get_data(ii); + if (data != NULL) { + if (calc == NULL) { + d_count = 1; + calc = data->clone(); + limit_d = data->get_date().clone(); + limit_d->min = 0; + limit_d->sec = 0; + limit_d->inc_seconds(freq_sec); + } + else { + date = data->get_date(); + if (date.before(*limit_d)) { + for (jj = 0; jj < col_count; jj++) { + calc->value_arr[jj] = calc->value_arr[jj] + data->value_arr[jj]; + } + d_count++; + } + else { + for (jj = 0; jj < col_count; jj++) { + calc->value_arr[jj] = calc->value_arr[jj] / d_count; + } + ret_val.push_back(calc); + d_count = 1; + calc = data->clone(); + if (limit_d != NULL) { + delete(limit_d); + } + limit_d = data->get_date().clone(); + limit_d->min = 0; + limit_d->sec = 0; + limit_d->inc_seconds(freq_sec); + } + } + delete(data); + } + } + if (calc != NULL) { + delete(calc); + calc = NULL; + } + if (limit_d != NULL) { + delete(limit_d); + } + } + } + } + return ret_val; +} + +vector W1Store::get_delta(int freq_sec) { + int row_count; + int col_count; + int jj; + int ii; + Data *data; + Data *calc1; + Data *calc2; + Date *limit_d; + Date date; + vector ret_val; + + calc1 = NULL; + calc2 = NULL; + limit_d = NULL; + if (store_data == NULL) { + load(); + } + if (store_data != NULL) { + row_count = store_data->get_data_row_count(); + if (row_count > 0) { + col_count = store_data->get_data_column_count(); + if (col_count > 0) { + for (ii = 0; ii < row_count; ii++) { + data = store_data->get_data(ii); + if (data != NULL) { + if (calc1 == NULL) { + calc1 = data->clone(); + limit_d = data->get_date().clone(); + limit_d->min = 0; + limit_d->sec = 0; + limit_d->inc_seconds(freq_sec); + if (calc2 != NULL) { + delete(calc2); + } + calc2 = NULL; + } + else { + date = data->get_date(); + if (date.before(*limit_d)) { + if (calc2 != NULL) { + delete(calc2); + } + calc2 = data->clone(); + } + else { + if (calc2 == NULL) { + calc2 = calc1->clone(); + } + for (jj = 0; jj < col_count; jj++) { + calc2->value_arr[jj] = calc2->value_arr[jj] - calc1->value_arr[jj]; + } + ret_val.push_back(calc2); + delete(calc1); + calc1 = data->clone(); + calc2 = NULL; // do not delete calc2 as it's stored to array + if (limit_d != NULL) { + delete(limit_d); + } + limit_d = data->get_date().clone(); + limit_d->min = 0; + limit_d->sec = 0; + limit_d->inc_seconds(freq_sec); + } + } + delete(data); + } + } + if (calc1 != NULL) { + delete(calc1); + calc1 = NULL; + } + if (calc2 != NULL) { + delete(calc2); + calc2 = NULL; + } + if (limit_d != NULL) { + delete(limit_d); + } + } + } + } + return ret_val; +} + DataRange *W1Store::get_oldest_and_newest_data() { DataRange *ret_val; ifstream in; diff --git a/src/W1Store.hh b/src/W1Store.hh index 53b124a..fb6fadb 100644 --- a/src/W1Store.hh +++ b/src/W1Store.hh @@ -10,6 +10,9 @@ #include #include +#include + +#include #include "Data.hh" #include "Date.hh" @@ -24,12 +27,14 @@ namespace w1 { static std::string get_dir_name(std::string device_id, plp::Date *ltime); static std::string get_file_name(std::string device_id, plp::Date *ltime); static void store(std::string device_id, std::list *string_list); - void load(); + bool load(); Data *get_sum(); Data *get_delta(); Data *get_mean(); Data *get_max(); Data *get_min(); + std::vector get_mean(int freq_sec); + std::vector get_delta(int freq_sec); w1::Data *get_oldest_data(); w1::Data *get_newest_data(); w1::DataRange *get_oldest_and_newest_data(); diff --git a/src_test/test_w1_datalog_read.cc b/src_test/test_w1_datalog_read.cc index 046a475..d135c03 100644 --- a/src_test/test_w1_datalog_read.cc +++ b/src_test/test_w1_datalog_read.cc @@ -82,10 +82,11 @@ int main(int argc, char** argv) { d1 = fdata->get_date(); d2 = ldata->get_date(); dr2 = dta->get_data(&d1, &d2); - delete(ldata); if (dr2 != NULL) { + dr2->printout(); delete(dr2); } + delete(ldata); } delete(fdata); } -- 2.41.1