From 6dea0b59503a71874c4476c05044fff3c5ae26a5 Mon Sep 17 00:00:00 2001 From: Mika Laitio Date: Sun, 2 Jan 2011 23:15:05 +0200 Subject: [PATCH] Refactoring and fixes. - File where to save data item is checked for each file separately. (Old versions had a bug that if there were data in save cache from multiple days (before and after day change), all data were saved to previous days file. - Data datatype refactoring, values are stored now in double array, instead of storing them internally to serialized string. - Memory leak fixes - Refactoring - TODO: Caching objects in Factory class, caching serialized data string until values are changed. Signed-off-by: Mika Laitio --- src/Data.cc | 170 +++++++++++++++++++++++------- src/Data.hh | 25 +++-- src/Date.cc | 39 ++++--- src/Date.hh | 6 +- src/DeviceConfig.cc | 11 +- src/DeviceData.cc | 34 +++--- src/Factory.cc | 22 ++-- src/W1CounterDevice.cc | 58 +++++----- src/W1CounterDevice.hh | 8 +- src/W1Device.cc | 66 +++++++++--- src/W1Device.hh | 19 ++-- src/W1Store.cc | 125 +++++++++++++--------- src/W1Store.hh | 2 +- src/W1TemperatureSensor.cc | 60 ++++++----- src/W1TemperatureSensor.hh | 6 +- src_test/test_w1_datalog_write.cc | 6 +- 16 files changed, 422 insertions(+), 235 deletions(-) diff --git a/src/Data.cc b/src/Data.cc index c964bc4..e81039b 100644 --- a/src/Data.cc +++ b/src/Data.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -24,7 +25,7 @@ using namespace w1; template bool string_to_number(NumberDataType& result, - const std::string& string_param, + const string& string_param, std::ios_base& (*format)(std::ios_base&)) { std::istringstream iss(string_param); @@ -35,35 +36,68 @@ Data::Data(int size) { value_arr.resize(size); } -Data::Data(int size, double default_value) { +Data::Data(int size, double default_value, string unit_param) { int ii; value_arr.resize(size); for (ii = 0; ii < size; ii++) { value_arr[ii] = default_value; } + unit = unit_param; } -Data::Data(vector vector_param, Date *date_param) { +Data::Data(vector *vect_param) { + unsigned int ii; + unsigned int sz; + + sz = vect_param->size(); + //log_debug("Data(), value count: %d\n", size); + value_arr.resize(sz); + for (ii = 0; ii < sz; ii++) { + value_arr[ii] = vect_param->at(ii); + //log_debug("Data(), value[%d]: %f\n", ii, value_arr[ii]); + } +} + +Data::Data(std::vector *vector_param, string unit_param) { + unsigned int ii; + unsigned int sz; + + sz = vector_param->size(); + //log_debug("Data(), value count: %d\n", size); + value_arr.resize(sz); + for (ii = 0; ii < sz; ii++) { + value_arr[ii] = vector_param->at(ii); + //log_debug("Data(), value[%d]: %f\n", ii, value_arr[ii]); + } + unit = unit_param; +} + +Data::Data(vector *vector_param, + Date *date_param, + string unit_param) { unsigned int ii; unsigned int size; - size = vector_param.size(); + size = vector_param->size(); //log_debug("Data(), value count: %d\n", size); value_arr.resize(size); - for (ii = 0; ii < vector_param.size(); ii++) { - value_arr[ii] = vector_param.at(ii); + for (ii = 0; ii < size; ii++) { + value_arr[ii] = vector_param->at(ii); //log_debug("Data(), value[%d]: %f\n", ii, value_arr[ii]); } date_time.copy(date_param); + unit = unit_param; } -Data::Data(std::valarray value_arr_param, Date *date_param) { - unsigned int ii; +Data::Data(std::valarray *val_arr_param, Date *date_param) { + unsigned int ii; + unsigned int sz; - value_arr.resize(value_arr_param.size()); - for (ii = 0; ii < value_arr_param.size(); ii++) { - value_arr[ii] = value_arr_param[ii]; + sz = val_arr_param->size(); + value_arr.resize(sz); + for (ii = 0; ii < sz; ii++) { + value_arr[ii] = (*val_arr_param)[ii]; } date_time.copy(date_param); } @@ -74,38 +108,41 @@ Data::~Data() { Data *Data::clone() { Data *ret_val; - ret_val = new Data(value_arr, &date_time); + ret_val = new Data(&value_arr, &date_time); return ret_val; } +void Data::printout() { + log_debug(" data: %s\n", to_string().c_str()); +} + plp::Date Data::get_date() { return date_time; } -void Data::set_date(plp::Date date) { - date_time.copy(&date); +void Data::set_date(Date *date_param) { + date_time.copy(date_param); } -void Data::printout() { - unsigned int ii; - - date_time.printout(); - for (ii = 0; ii < value_arr.size(); ii++) { - log_debug(" data[%d] = %f\n", ii, value_arr[ii]); - } +string Data::get_unit() { + return unit; } -Data *Data::parse_data_string(const string& dataline) { +Data *Data::parse_string(const string& dataline) { stringstream ss(dataline); string item; double val; Data *ret_val; int ii; + int sz; bool suc_flg; vector v; + string unit; Date date; ii = 0; + ret_val = NULL; + log_debug("parse_string: %s\n", dataline.c_str()); while(getline(ss, item, '|')) { if (ii == 0) { // parse date @@ -114,27 +151,60 @@ Data *Data::parse_data_string(const string& dataline) { else if (ii >= 1) { suc_flg = string_to_number(val, item, dec); if (suc_flg) { - //log_debug("adding number: %f\n", val); + log_debug("adding number: %f\n", val); v.push_back(val); } } ii++; } - ret_val = new Data(v, &date); + ii = item.find_last_of(" "); + sz = item.size(); + if ((ii >= 0) && + ((ii + 1) <= (sz - 1))) { + unit = item.substr(ii + 1); + } + else { + unit = ""; + } + if (v.size() > 0) { + ret_val = new Data(&v, &date, unit); + } + return ret_val; +} + +string Data::to_string() { + unsigned int ii; + ostringstream out; + string ret_val; + + ret_val = date_time.to_string(); + if (value_arr.size() > 0) { + for (ii = 0; ii < value_arr.size(); ii++) { + out << fixed << setprecision(3) << value_arr[ii]; + ret_val.append("|"); + ret_val.append(out.str()); + } + if (unit.empty() == false) { + ret_val.append(" "); + ret_val.append(unit.c_str()); + } + } return ret_val; } -DataRange::DataRange(int value_count_per_data_item) { +DataRange::DataRange(Data *data) { val_matrix = NULL; - column_count = value_count_per_data_item; + column_count = data->value_arr.size(); row_count = 0; + unit = data->get_unit(); + add_data(data); } -DataRange::DataRange(Data data) { +DataRange::DataRange(int value_count_per_data_item, string unit_param) { val_matrix = NULL; - column_count = data.value_arr.size(); + column_count = value_count_per_data_item; row_count = 0; - add_data(data); + unit = unit_param; } DataRange::~DataRange() { @@ -151,24 +221,38 @@ DataRange::~DataRange() { } } -void DataRange::add_data(Data data) { - unsigned int ii; - int indx; - Date date; +void DataRange::add_data(Data *data) { + int ii; + int indx; + Date *date; + int cnt; //log_debug("old row_count: %d, column_count: %d, value_arr_size: %d\n", row_count, column_count, data.value_arr.size()); - val_matrix = (double *)realloc(val_matrix, ((row_count + 1) * column_count) * sizeof(double)); + cnt = (row_count + 1) * column_count; + val_matrix = (double *)realloc(val_matrix, cnt * sizeof(double)); indx = row_count * column_count; - for (ii = 0; ii < data.value_arr.size(); ii++) { - val_matrix[indx + ii] = data.value_arr[ii]; + cnt = data->value_arr.size(); + if (cnt != column_count) { + log_error("Error when adding data... Invalid data item count!\n"); + if (cnt > column_count) { + cnt = column_count; + } + else { + for (ii = cnt; ii < column_count; ii++) { + val_matrix[indx + ii] = 0; + } + } + } + for (ii = 0; ii < cnt; ii++) { + val_matrix[indx + ii] = data->value_arr[ii]; } /* for (int ii = 0; ii < ((row_count + 1) * column_count); ii++) { log_debug("data_matrix[%d] = %f\n", ii, val_matrix[ii]); } */ - date = data.get_date(); - date_list.push_back(date.clone()); + date = data->get_date().clone(); + date_list.push_back(date); row_count++; } @@ -176,18 +260,22 @@ Data *DataRange::get_data(int row_index) { Data *ret_val; int start_indx; int ii; - vector vector; + vector vect; Date *date; + double val; ret_val = NULL; if ((row_index >= 0) && (row_index < row_count)) { start_indx = row_index * column_count; for (ii = 0; ii < column_count; ii++) { - vector.push_back(val_matrix[start_indx + ii]); + //val = val_matrix[0]; + val = val_matrix[start_indx + ii]; + log_debug("val[%d] = %f\n", (start_indx + ii), val); + vect.push_back(val); } date = date_list.at(row_index); - ret_val = new Data(vector, date); + ret_val = new Data(&vect, date, unit); } return ret_val; } diff --git a/src/Data.hh b/src/Data.hh index 8a8a28a..196cf3b 100644 --- a/src/Data.hh +++ b/src/Data.hh @@ -18,37 +18,44 @@ namespace w1 { class Data { public: Data(int size); - Data(int size, double default_value); - Data(std::vector vector_param, plp::Date *date_param); - Data(std::valarray value_arr_param, plp::Date *date_param); + Data(int size, double default_value, std::string unit_param); + Data(std::vector *val_vector_param); + Data(std::vector *val_vector_param, std::string unit_param); + Data(std::vector *val_vector_param, plp::Date *date_param, std::string unit_param); + Data(std::valarray *val_arr_param, plp::Date *date_param); virtual ~Data(); Data *clone(); - plp::Date get_date(); - void set_date(plp::Date date); void printout(); - static Data *parse_data_string(const std::string& dataline); + std::string to_string(); + static Data *parse_string(const std::string& data_str); + plp::Date get_date(); + void set_date(plp::Date *date_param); + std::string get_unit(); std::valarray value_arr; private: plp::Date date_time; + std::string unit; }; class DataRange { public: - DataRange(Data data); - DataRange(int value_count_per_data_item); + DataRange(Data *data); + DataRange(int item_count_per_value, std::string unit_param); virtual ~DataRange(); - void add_data(Data data); + void add_data(Data *data); Data *get_data(int row_index); Data *get_first_data(); Data *get_last_data(); int get_data_row_count(); int get_data_column_count(); + std::string get_unit(); void printout(); protected: double *val_matrix; std::vector date_list; int row_count; int column_count; + std::string unit; }; } diff --git a/src/Date.cc b/src/Date.cc index e82ee99..6e8fdb6 100644 --- a/src/Date.cc +++ b/src/Date.cc @@ -70,29 +70,29 @@ void Date::printout() { Date *Date::clone() { Date *ret_val; - ret_val = new Date(this->year, - this->month, - this->day, - this->hour, - this->min, - this->sec); + ret_val = new Date(year, + month, + day, + hour, + min, + sec); return ret_val; } void Date::copy(Date *date) { - this->year = date->year; - this->month = date->month; - this->day = date->day; - this->hour = date->hour; - this->min = date->min; - this->sec = date->sec; + year = date->year; + month = date->month; + day = date->day; + hour = date->hour; + min = date->min; + sec = date->sec; } bool Date::before(Date date2) { bool ret_val; - string s1 = this->to_string(); - string s2 = date2.to_string(); + string s1 = this->to_sortable_string(); + string s2 = date2.to_sortable_string(); ret_val = false; if (s1.compare(s2) < 0) { ret_val = true; @@ -191,7 +191,7 @@ void Date::inc_seconds(int seconds) { } } -string Date::to_string() { +string Date::to_sortable_string() { char buffer[30]; string ret_val; @@ -199,3 +199,12 @@ string Date::to_string() { ret_val = buffer; return ret_val; } + +string Date::to_string() { + char buffer[30]; + string ret_val; + + sprintf(buffer, "%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, min, sec); + ret_val = buffer; + return ret_val; +} diff --git a/src/Date.hh b/src/Date.hh index 2d6fd75..f51f28f 100644 --- a/src/Date.hh +++ b/src/Date.hh @@ -31,15 +31,15 @@ namespace plp { void copy(Date *date); bool before(Date date2); bool equals(Date date2); - std::string to_string(); - int year; int month; int day; int hour; int min; int sec; - private: + std::string to_string(); + protected: + std::string to_sortable_string(); //static const int arr_days_per_month[]; }; } diff --git a/src/DeviceConfig.cc b/src/DeviceConfig.cc index 19cfbb9..f94637c 100644 --- a/src/DeviceConfig.cc +++ b/src/DeviceConfig.cc @@ -97,11 +97,11 @@ string DeviceConfig::get_cfg_value(string key) { option = uci_lookup_option(uci_handle->ctx, section, key.c_str()); switch (option->type) { case UCI_TYPE_STRING: - log_info("config file: key: %s option name: %s, value: %s\n", key.c_str(), option->e.name, option->v.string); + log_info("key: %s option name: %s, value: %s\n", key.c_str(), option->e.name, option->v.string); ret_val = option->v.string; break; default: - log_error("config file: key: %s can not parse parameter value\n", key.c_str()); + log_error("key: %s Failed to read parameter value\n", key.c_str()); break; } } @@ -155,15 +155,14 @@ ConfigHandle *DeviceConfig::load_device_config(string device_id_param) { log_debug("uci_set_confdir: %s\n", cfg_dir.c_str()); uci_set_confdir(ctx, cfg_dir.c_str()); if (access(cfg_fl.c_str(), R_OK) == 0) { - log_debug("loading file: %s\n", cfg_fl.c_str()); err_flg = uci_load(ctx, cfg_fl.c_str(), &pkg); if (err_flg == UCI_OK) { - log_debug("Loaded device configuration: %s, UCI_OK: %d, err flg: %d\n.", cfg_fl.c_str(), UCI_OK, err_flg); + log_debug("Loaded device configuration file: %s\n.", cfg_fl.c_str()); ret_val = new ConfigHandle(ctx, pkg); } else { - log_debug("Failed to load file: %s, UCI_OK: %d, err flg: %d\n.", cfg_fl.c_str(), UCI_OK, err_flg); - set_cfg_value(DEVICE_CONFIG_VALUE_KEY__TYPE, "unknowntype"); + log_debug("Failed to load file: %s, err code: %d\n.", cfg_fl.c_str(), UCI_OK); + set_cfg_value(DEVICE_CONFIG_VALUE_KEY__TYPE, ""); } } else { diff --git a/src/DeviceData.cc b/src/DeviceData.cc index 59327ba..5f95966 100644 --- a/src/DeviceData.cc +++ b/src/DeviceData.cc @@ -110,21 +110,21 @@ Data *DeviceData::find_newest_data(vector year_vector) { DataRange *DeviceData::get_data_range() { DataRange *ret_val; - vector year_list; - Data *first_data; - Data *newest_data; + vector y_list; + Data *o_data; + Data *n_data; - ret_val = NULL; - year_list = W1Util::get_subdirectories(device_dir); - first_data = find_oldest_data(year_list); - if (first_data != NULL) { - newest_data = find_newest_data(year_list); - if (newest_data != NULL) { - ret_val = new DataRange(*first_data); - ret_val->add_data(*newest_data); - delete(newest_data); + ret_val = NULL; + y_list = W1Util::get_subdirectories(device_dir); + o_data = find_oldest_data(y_list); + if (o_data != NULL) { + n_data = find_newest_data(y_list); + if (n_data != NULL) { + ret_val = new DataRange(o_data); + ret_val->add_data(n_data); + delete(n_data); } - delete(first_data); + delete(o_data); } return ret_val; } @@ -227,10 +227,10 @@ DataRange *DeviceData::get_daily_summary(Date *start_date, data = get_day_summary(date); if (data != NULL) { if (ret_val == NULL) { - ret_val = new DataRange(*data); + ret_val = new DataRange(data); } else { - ret_val->add_data(*data); + ret_val->add_data(data); } delete(data); } @@ -288,10 +288,10 @@ DataRange *DeviceData::get_hourly_summary(Date *start_date, data = (Data *)*iter; if (data != NULL) { if (ret_val == NULL) { - ret_val = new DataRange(*data); + ret_val = new DataRange(data); } else { - ret_val->add_data(*data); + ret_val->add_data(data); } delete(data); } diff --git a/src/Factory.cc b/src/Factory.cc index 8a09eaa..1ce585b 100644 --- a/src/Factory.cc +++ b/src/Factory.cc @@ -44,26 +44,24 @@ W1Device *Factory::get_device(int family_code, DeviceConfig *config; ret_val = NULL; - log_debug("family_code: %d\n", family_code); switch(family_code) { case 0x10: case 0x28: ret_val = new W1TemperatureSensor(family_code, device_id, direntry_param); - log_debug("temperature sensor: %d\n", ret_val->get_family_code()); break; case 0x1d: ret_val = new W1CounterDevice(family_code, device_id, direntry_param); - log_debug("counter device: %d\n", family_code); break; default: - log_debug("device not created, unsupported device type: %d\n", family_code); + log_debug("Unsupported 1-wire-family code: %#x, device not created: %s\n", family_code, device_id.c_str()); break; } if (ret_val != NULL) { + log_debug("%s: %#x\n", ret_val->get_device_type().c_str(), ret_val->get_w1_family_code()); // check that device config exist - // if not, create default... config = get_device_config(device_id); if (config != NULL) { + // if not, create default device config string type; type = config->get_cfg_value(DEVICE_CONFIG_VALUE_KEY__TYPE); if (type.empty() == true) { @@ -71,6 +69,7 @@ W1Device *Factory::get_device(int family_code, config->set_cfg_value(DEVICE_CONFIG_VALUE_KEY__TYPE, type); config->set_cfg_value(DEVICE_CONFIG_VALUE_KEY__ID, ret_val->get_id()); } + delete(config); } } return ret_val; @@ -93,7 +92,7 @@ W1Device *Factory::create_device(dirent *direntry_param) { // number in string is in hex format, convert to int suc_flg = string_to_number(family_code, tmp_str, hex); if (suc_flg == true) { - log_debug("family_code: %d\n", family_code); + log_debug("1-wire device family code: %#x\n", family_code); device_name = folder_name.substr(pos + 1, folder_name.length() - pos); ret_val = Factory::get_device(family_code, device_name, @@ -111,28 +110,25 @@ list Factory::get_device_list() { bool is_subdir; list ret_val; - printf("get_device_list() started\n"); dir = opendir(W1_SCAN_ROOTDIR); if (dir != NULL) { direntry = readdir(dir); while(direntry != NULL) { is_subdir = W1Util::is_subdirectory(W1_SCAN_ROOTDIR, direntry); if (is_subdir == true) { - log_info("dir_name: %s\n", direntry->d_name); device = create_device(direntry); if (device != NULL) { - log_info("device: %d\n", device->get_family_code()); ret_val.push_back(device); } else { - log_info("unsupported device-directory: %s\n", direntry->d_name); + log_info("Unsupported 1-wire device detected: %s\n", direntry->d_name); } } direntry = readdir(dir); } err_flg = closedir(dir); if (err_flg < 0) { - log_error("failed to close 1-wire device directory: %s\n", W1_SCAN_ROOTDIR); + log_error("Failed to close 1-wire device directory: %s\n", W1_SCAN_ROOTDIR); } } return ret_val; @@ -147,7 +143,6 @@ list Factory::get_device_data_list() { bool is_subdir; list ret_val; - printf("get_device_list() started\n"); dr_name = DeviceConfig::get_base_dir_name(); dir = opendir(dr_name.c_str()); if (dir != NULL) { @@ -157,7 +152,6 @@ list Factory::get_device_data_list() { is_subdir = W1Util::is_subdirectory(dr_name.c_str(), direntry); if (is_subdir == true) { dev_dta = new DeviceData(direntry->d_name); - log_info("dir_name: %s\n", direntry->d_name); ret_val.push_back(dev_dta); } } @@ -165,7 +159,7 @@ list Factory::get_device_data_list() { } err_flg = closedir(dir); if (err_flg < 0) { - log_error("failed to close 1-wire device data directory: %s\n", dr_name.c_str()); + log_error("Failed to close 1-wire device data directory: %s\n", dr_name.c_str()); } } return ret_val; diff --git a/src/W1CounterDevice.cc b/src/W1CounterDevice.cc index d4a20f6..3ebdbd4 100644 --- a/src/W1CounterDevice.cc +++ b/src/W1CounterDevice.cc @@ -7,12 +7,25 @@ #include #include +#include +#include + +#include #include "W1CounterDevice.hh" using namespace std; using namespace w1; +template +bool string_to_number(NumberDataType& result, + const std::string& string_param, + std::ios_base& (*format)(std::ios_base&)) +{ + std::istringstream iss(string_param); + return !(iss >> format >> result).fail(); +} + W1CounterDevice::W1CounterDevice(int family_code_param, string device_id_param, dirent *direntry_param): W1Device(family_code_param, device_id_param, direntry_param) { @@ -31,7 +44,7 @@ W1CounterDevice::~W1CounterDevice() { // TODO Auto-generated destructor stub } -bool W1CounterDevice::is_supported_family_code(int family_code) { +bool W1CounterDevice::is_supported_w1_family_code(int family_code) { bool ret_val; ret_val = false; @@ -43,37 +56,30 @@ bool W1CounterDevice::is_supported_family_code(int family_code) { return ret_val; } -string W1CounterDevice::get_raw_data() { - string ret_val; - string value_line; - int pos; - int length; +vector *W1CounterDevice::get_raw_data() { + int pos; + int b_cnt; + string val_str; + int val_dbl; + vector *ret_val; - ret_val = ""; + ret_val = NULL; ifstream ifs(slave_file.c_str()); if (ifs.is_open() == true) { - ret_val = ""; - while(getline(ifs, value_line)) { - length = value_line.length(); - if (length > 0) { - pos = value_line.find("crc=YES c="); + while(getline(ifs, val_str)) { + b_cnt = val_str.length(); + if (b_cnt > 0) { + pos = val_str.find("crc=YES c="); if ((pos >= 0) && - (pos + 10 < length)) { - value_line = value_line.substr(pos + 10); - } - else { - value_line = ""; + ((pos + 10) < b_cnt)) { + if (ret_val == NULL) { + ret_val = new vector(); + } + val_str = val_str.substr(pos + 10); + string_to_number(val_dbl, val_str, dec); + ret_val->push_back(val_dbl); } } - else { - value_line = ""; - } - if (ret_val.length() == 0) { - ret_val = value_line; - } - else { - ret_val = ret_val + "|" + value_line; - } } ifs.close(); } diff --git a/src/W1CounterDevice.hh b/src/W1CounterDevice.hh index c5198bd..c642eca 100644 --- a/src/W1CounterDevice.hh +++ b/src/W1CounterDevice.hh @@ -8,20 +8,22 @@ #ifndef W1COUNTERDEVICE_HH_ #define W1COUNTERDEVICE_HH_ +#include + #include "W1Device.hh" namespace w1 { - class W1CounterDevice: public w1::W1Device { + class W1CounterDevice: public W1Device { public: W1CounterDevice(int family_code_param, std::string device_id_param, dirent *direntry_param); virtual ~W1CounterDevice(); - std::string get_raw_data(); std::string get_unit(); std::string get_device_type(); protected: - bool is_supported_family_code(int family_code); + std::vector *get_raw_data(); + bool is_supported_w1_family_code(int family_code); }; } diff --git a/src/W1Device.cc b/src/W1Device.cc index 6719be7..7bb4418 100644 --- a/src/W1Device.cc +++ b/src/W1Device.cc @@ -6,6 +6,8 @@ */ #include #include +#include +#include #include #include @@ -36,7 +38,7 @@ W1Device::W1Device(int family_code_param, W1Device::~W1Device() { } -int W1Device::get_family_code() { +int W1Device::get_w1_family_code() { return family_code; } @@ -66,34 +68,66 @@ string W1Device::get_time() { } void W1Device::printout() { - string text; + Data *data; + string text; + + data = get_and_collect_data(); + if (data != NULL) { + text = data->to_string(); + cout << text << endl; + } + else { + log_error("Could not data for %s device: %s\n", get_device_type().c_str(), get_name().c_str()); + } +} + +string W1Device::to_string(double dbl_val, int digit_count) { + string ret_val; + ostringstream out; - text = get_formatted_data(); - cout << text << endl; + out << fixed << setprecision(digit_count) << dbl_val; + ret_val = out.str(); + return ret_val; } -string W1Device::get_formatted_data() { - string ret_val; - string val; - val = get_raw_data(); - ret_val = get_formatted_data(val); +Data *W1Device::get_and_collect_data() { + Data *ret_val; + vector *vect; + + ret_val = NULL; + vect = get_raw_data(); + if (vect != NULL) { + ret_val = new Data(vect, get_unit()); + collect_data(ret_val); + delete(vect); + } return ret_val; } -string W1Device::get_formatted_data(string raw_data) { - string ret_val; +/* +Data *W1Device::get_formatted_data(Data *data) { + Data *ret_val; ret_val = get_time() + "|" + raw_data + " " + get_unit(); - add_to_memory_cache(ret_val); + add_to_save_fifo(ret_val); return ret_val; } +*/ -void W1Device::add_to_memory_cache(std::string formatted_data) { +void W1Device::collect_data(Data *data) { // TODO: add mutex for memory_cache - memory_cache.push_back(formatted_data); + memory_cache.push_back(data); } -void W1Device::store() { - W1Store::store(id, &memory_cache); +void W1Device::save_data() { + list::iterator iter; + Data *data; + + W1Store::save(id, &memory_cache); + for(iter = memory_cache.begin(); iter != memory_cache.end(); iter++) { + data = (Data *)*iter; + delete(data); + } + memory_cache.clear(); } diff --git a/src/W1Device.hh b/src/W1Device.hh index 73cd8f5..a702e0f 100644 --- a/src/W1Device.hh +++ b/src/W1Device.hh @@ -14,6 +14,8 @@ #include #include +#include "Data.hh" + #ifndef W1_SCAN_ROOTDIR #define W1_SCAN_ROOTDIR "/sys/bus/w1/devices" #endif @@ -29,27 +31,28 @@ namespace w1 { std::string device_id_param, dirent *direntry_param); virtual ~W1Device(); - int get_family_code(); + int get_w1_family_code(); std::string get_id(); std::string get_name(); void set_name(std::string name_param); - virtual std::string get_raw_data() = 0; - std::string get_formatted_data(); virtual std::string get_unit() = 0; virtual std::string get_device_type() = 0; std::string get_time(); + Data *get_and_collect_data(); + virtual void save_data(); virtual void printout(); - virtual void store(); protected: - void add_to_memory_cache(std::string formatted_data); - std::string get_formatted_data(std::string raw_data); - virtual bool is_supported_family_code(int family_code) = 0; + virtual std::vector *get_raw_data() = 0; + void collect_data(Data *data); + std::string to_string(double val, int digit_count); + //Data *get_formatted_data(Data *data); + virtual bool is_supported_w1_family_code(int family_code) = 0; int family_code; std::string id; std::string name; std::string dir_path; std::string slave_file; - std::list memory_cache; + std::list memory_cache; private: }; } diff --git a/src/W1Store.cc b/src/W1Store.cc index 09ff706..4f35376 100644 --- a/src/W1Store.cc +++ b/src/W1Store.cc @@ -8,7 +8,6 @@ #include #include #include -#include #include #include @@ -74,45 +73,55 @@ string W1Store::get_file_name(string device_id, Date *date_time) { return ret_val; } -void W1Store::store(string device_id, - list *string_list) { - string f_path; - string line; - ofstream *ostream; - Date *date; - - date = new Date(); - f_path = get_file_name(device_id, date); - ostream = W1Util::open_for_writing(f_path.c_str()); +void W1Store::save(string device_id, + std::list *data_list) { + string n_path; + string f_path; + string line; + Data *data; + ofstream *ostream; + Date date; + list::iterator iter; + + ostream = NULL; + f_path = ""; + log_info("[%s] writing %d data values to save.\n", device_id.c_str(), data_list->size()); // TODO: add mutex to protect string_list while it's read and emptied - if (ostream != NULL) { - if (ostream->is_open()) { - log_info("[%s] writing %d data values to file: %s\n", device_id.c_str(), string_list->size(), f_path.c_str()); - while(string_list->size() > 0) { - line = string_list->front(); - string_list->pop_front(); - if (line.length() > 0) { - log_debug("storing line: %s\n", line.c_str()); - *ostream << line << endl; - } + for(iter = data_list->begin(); iter != data_list->end(); iter++) { + data = (Data *)*iter; + date = data->get_date(); + n_path = get_file_name(device_id, &date); + if (n_path.compare(f_path) != 0) { + if (ostream != NULL) { + ostream->close(); + delete(ostream); + } + f_path = n_path; + log_info("[%s] Opening file for save: %s\n", device_id.c_str(), f_path.c_str()); + ostream = W1Util::open_for_writing(f_path.c_str()); + } + if ((ostream != NULL) && + (ostream->is_open() == true)) { + line = data->to_string(); + if (line.length() > 0) { + log_debug("storing line: %s\n", line.c_str()); + *ostream << line << endl; } - ostream->close(); } else { - log_error("[%s] Could not store data to file: %s\n", device_id.c_str(), f_path.c_str()); + log_error("[%s] File open for data save failed: %s\n", device_id.c_str(), f_path.c_str()); } - delete(ostream); } - else { - log_error("[%s] Could not store data to file: %s\n", device_id.c_str(), f_path.c_str()); + if (ostream != NULL) { + ostream->close(); + delete(ostream); } - delete(date); } bool W1Store::load() { Data *data; ifstream in; - string line; + string data_str; bool ret_val; ret_val = false; @@ -120,18 +129,23 @@ bool W1Store::load() { delete(store_data); store_data = NULL; } + log_debug("opening file: %s\n", store_file_name.c_str()); in.open(store_file_name.c_str()); if (in.is_open() == true) { while (in.eof() == false) { - getline(in, line); - data = Data::parse_data_string(line); - if (store_data == NULL) { - store_data = new DataRange(*data); - } - else { - store_data->add_data(*data); + getline(in, data_str); + if (data_str.empty() == false) { + data = Data::parse_string(data_str); + if (data != NULL) { + if (store_data == NULL) { + store_data = new DataRange(data); + } + else { + store_data->add_data(data); + } + delete(data); + } } - delete(data); } ret_val = true; } @@ -149,6 +163,7 @@ Data *W1Store::get_sum() { int jj; Data *data; Data *ret_val; + Date date; ret_val = NULL; data = NULL; @@ -176,7 +191,8 @@ Data *W1Store::get_sum() { //log_debug("new val: %f, sum: %f\n", new_val, sum); } } - ret_val->set_date(data->get_date()); + date = data->get_date(); + ret_val->set_date(&date); if (data != NULL) { delete(data); } @@ -193,6 +209,7 @@ Data *W1Store::get_delta() { Data *ret_val; int ii; DataRange *dr; + Date date; ret_val = NULL; dr = get_oldest_and_newest_data(); @@ -205,10 +222,12 @@ Data *W1Store::get_delta() { ret_val = new Data(col_count); if (col_count > 0) { for (ii = 0; ii < col_count; ii++) { + log_debug("old_data[%d]: %f new data: %f\n", ii, o_data->value_arr[ii], n_data->value_arr[ii]); ret_val->value_arr[ii] = n_data->value_arr[ii] - o_data->value_arr[ii]; } } - ret_val->set_date(n_data->get_date()); + date = n_data->get_date(); + ret_val->set_date(&date); delete(o_data); delete(n_data); } @@ -252,6 +271,7 @@ Data *W1Store::get_max() { Data *data; Data *ret_val; double min_val; + Date date; ret_val = NULL; data = NULL; @@ -265,7 +285,10 @@ Data *W1Store::get_max() { col_count = store_data->get_data_column_count(); log_debug("data item count per row: %d\n", col_count); min_val = numeric_limits::min(); - ret_val = new Data(col_count, min_val); + data = store_data->get_data(0); + ret_val = new Data(col_count, + min_val, + data->get_unit()); if (col_count > 0) { for (ii = 0; ii < row_count - 1; ii++) { data = store_data->get_data(ii); @@ -281,7 +304,8 @@ Data *W1Store::get_max() { } } } - ret_val->set_date(data->get_date()); + date = data->get_date(); + ret_val->set_date(&date); if (data != NULL) { delete(data); } @@ -299,6 +323,7 @@ Data *W1Store::get_min() { Data *data; Data *ret_val; double max_val; + Date date; ret_val = NULL; data = NULL; @@ -312,7 +337,10 @@ Data *W1Store::get_min() { col_count = store_data->get_data_column_count(); log_debug("data item count per row: %d\n", col_count); max_val = numeric_limits::max(); - ret_val = new Data(col_count, max_val); + data = store_data->get_data(0); + ret_val = new Data(col_count, + max_val, + data->get_unit()); if (col_count > 0) { for (ii = 0; ii < row_count - 1; ii++) { data = store_data->get_data(ii); @@ -328,7 +356,8 @@ Data *W1Store::get_min() { } } } - ret_val->set_date(data->get_date()); + date = data->get_date(); + ret_val->set_date(&date); if (data != NULL) { delete(data); } @@ -530,23 +559,23 @@ DataRange *W1Store::get_oldest_and_newest_data() { getline(in, line); if (line.empty() == false) { if (o_data == NULL) { - o_data = Data::parse_data_string(line); + o_data = Data::parse_string(line); } prev_line = line; } } if (prev_line.empty() == false) { - n_data = Data::parse_data_string(prev_line); + n_data = Data::parse_string(prev_line); } } } if ((o_data != NULL) && (n_data != NULL)) { - ret_val = new DataRange(*o_data); - ret_val->add_data(*n_data); + ret_val = new DataRange(o_data); + ret_val->add_data(n_data); if (range_data != NULL) { - range_data = new DataRange(*o_data); - range_data->add_data(*n_data); + range_data = new DataRange(o_data); + range_data->add_data(n_data); } } if (o_data != NULL) { diff --git a/src/W1Store.hh b/src/W1Store.hh index fb6fadb..b0726a4 100644 --- a/src/W1Store.hh +++ b/src/W1Store.hh @@ -26,7 +26,7 @@ namespace w1 { virtual ~W1Store(); 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); + static void save(std::string device_id, std::list *data_list); bool load(); Data *get_sum(); Data *get_delta(); diff --git a/src/W1TemperatureSensor.cc b/src/W1TemperatureSensor.cc index 9c282b3..e7930ff 100644 --- a/src/W1TemperatureSensor.cc +++ b/src/W1TemperatureSensor.cc @@ -17,6 +17,8 @@ using namespace std; using namespace w1; +#define CONST_UNIT_CELCIUS "C" + template bool string_to_number(NumberDataType& result, const std::string& string_param, @@ -26,28 +28,32 @@ bool string_to_number(NumberDataType& result, return !(iss >> format >> result).fail(); } -string convert_celcius_value_to_three_digits(string raw_value) { - string ret_val; +double convert_w1_temperature_to_celcius(string raw_value, int *err_flg) { bool suc_flg; double dbl_val; + dbl_val = 0; suc_flg = string_to_number(dbl_val, raw_value, dec); if (suc_flg == true) { - dbl_val = dbl_val / 1000; + dbl_val = dbl_val / 1000; + *err_flg = 0; +/* std::ostringstream out; out << fixed << setprecision(3) << dbl_val; ret_val = out.str(); +*/ } else { - ret_val = raw_value; + log_error("Failed to convert temperature %s to celsius value", raw_value.c_str()); + *err_flg = 1; } - return ret_val; + return dbl_val; } W1TemperatureSensor::W1TemperatureSensor(int family_code_param, string device_id_param, dirent *direntry_param): W1Device(family_code_param, device_id_param, direntry_param) { - string text; + string text; log_debug("trying to open file: %s\n", slave_file.c_str()); ifstream ifs(slave_file.c_str()); @@ -62,7 +68,7 @@ W1TemperatureSensor::W1TemperatureSensor(int family_code_param, W1TemperatureSensor::~W1TemperatureSensor() { } -bool W1TemperatureSensor::is_supported_family_code(int family_code) { +bool W1TemperatureSensor::is_supported_w1_family_code(int family_code) { bool ret_val; ret_val = false; @@ -75,38 +81,44 @@ bool W1TemperatureSensor::is_supported_family_code(int family_code) { return ret_val; } -string W1TemperatureSensor::get_raw_data() { - string temp; - string ret_val; - string last_line; +vector *W1TemperatureSensor::get_raw_data() { + vector *ret_val; + string tmp_str; + string val_str; + double val_dbl; int pos; - int length; - string format; + int b_cnt; + int err_flg; - ret_val = ""; + ret_val = NULL; + err_flg = 0; ifstream ifs(slave_file.c_str()); if (ifs.is_open() == true) { - while(getline(ifs, temp)) { - if (temp.length() > 0) { - last_line = temp; + while(getline(ifs, tmp_str)) { + if (tmp_str.empty() == false) { + val_str = tmp_str; } } ifs.close(); - length = last_line.length(); - if (length > 0) { - pos = last_line.find("t="); + b_cnt = val_str.length(); + if (b_cnt > 0) { + pos = val_str.find("t="); if ((pos >= 0) && - (pos + 2 < length)) { - ret_val = last_line.substr(pos + 2); + ((pos + 2) < b_cnt)) { + val_str = val_str.substr(pos + 2); + val_dbl = convert_w1_temperature_to_celcius(val_str, &err_flg); + if (err_flg == 0) { + ret_val = new vector(); + ret_val->push_back(val_dbl); + } } } } - ret_val = convert_celcius_value_to_three_digits(ret_val); return ret_val; } string W1TemperatureSensor::get_unit() { - return "C"; + return CONST_UNIT_CELCIUS; } string W1TemperatureSensor::get_device_type() { diff --git a/src/W1TemperatureSensor.hh b/src/W1TemperatureSensor.hh index a637222..15989d5 100644 --- a/src/W1TemperatureSensor.hh +++ b/src/W1TemperatureSensor.hh @@ -8,6 +8,8 @@ #ifndef W1TEMPERATURESENSOR_HH_ #define W1TEMPERATURESENSOR_HH_ +#include + #include "W1Device.hh" namespace w1 { @@ -17,11 +19,11 @@ namespace w1 { std::string device_id_param, dirent *direntry_param); virtual ~W1TemperatureSensor(); - std::string get_raw_data(); std::string get_unit(); std::string get_device_type(); protected: - bool is_supported_family_code(int family_code); + std::vector *get_raw_data(); + bool is_supported_w1_family_code(int family_code); }; } diff --git a/src_test/test_w1_datalog_write.cc b/src_test/test_w1_datalog_write.cc index 88d4c5f..126a02f 100644 --- a/src_test/test_w1_datalog_write.cc +++ b/src_test/test_w1_datalog_write.cc @@ -73,14 +73,16 @@ int main(int argc, char** argv) { device_list = Factory::get_device_list(); round = 0; if (device_list.size() > 0) { - while(1) { + int ii = 0; + while(ii < 6) { + ii++; round++; for(iter = device_list.begin(); iter != device_list.end(); iter++) { device = (W1Device *)*iter; device->printout(); sleep(1); if (round >= store_interval) { - device->store(); + device->save_data(); } } sleep(scan_interval); -- 2.41.0