]> pilppa.org Git - libplp.git/commitdiff
w1 independent file cleanups.
authorMika Laitio <lamikr@pilppa.org>
Sat, 5 Mar 2011 20:48:54 +0000 (22:48 +0200)
committerMika Laitio <lamikr@pilppa.org>
Sat, 5 Mar 2011 20:48:54 +0000 (22:48 +0200)
Moving w1 independent device and store files from lib1wire to
libplp.

Signed-off-by: Mika Laitio <lamikr@pilppa.org>
25 files changed:
configure.ac
src/Data.cc [new file with mode: 0644]
src/Data.hh [new file with mode: 0644]
src/DataReader.cc [new file with mode: 0644]
src/DataReader.hh [new file with mode: 0644]
src/Date.cc [new file with mode: 0644]
src/Date.hh [new file with mode: 0644]
src/Device.cc [new file with mode: 0644]
src/Device.hh [new file with mode: 0644]
src/DeviceConfig.cc [new file with mode: 0644]
src/DeviceConfig.hh [new file with mode: 0644]
src/DeviceData.cc [new file with mode: 0644]
src/DeviceData.hh [new file with mode: 0644]
src/DeviceTypes.hh [new file with mode: 0644]
src/FileUtil.cc [new file with mode: 0644]
src/FileUtil.hh [new file with mode: 0644]
src/Makefile.am
src/SensorDevice.hh [new file with mode: 0644]
src/Store.cc [new file with mode: 0644]
src/Store.hh [new file with mode: 0644]
src/StoreCache.cc [new file with mode: 0644]
src/StoreCache.hh [new file with mode: 0644]
src/StoreDay.cc [new file with mode: 0644]
src/StoreDay.hh [new file with mode: 0644]
src/retval.h

index bb2745032392d7fa235ece8ed9c0609572855681..ebfa5b16a2ed55fba0217087154c3960fcea77d9 100644 (file)
@@ -9,11 +9,15 @@ CFLAGS="$CFLAGS -g -Wall -Werror"
 LDFLAGS="$LDFLAGS -lpthread"
 AC_SUBST(CFLAGS)
 AC_SUBST(LDFLAGS)
+
+CXXFLAGS="$CXXFLAGS -ggdb -Wall -Werror"
+AC_SUBST(CXXFLAGS)
+
 AC_MSG_NOTICE([libplp Makefile])
 
 AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
 
-#AC_PROG_CXX
+AC_PROG_CXX
 AC_STDC_HEADERS
 AC_PROG_LIBTOOL
 AC_PROG_INSTALL
diff --git a/src/Data.cc b/src/Data.cc
new file mode 100644 (file)
index 0000000..544f3c8
--- /dev/null
@@ -0,0 +1,372 @@
+/*
+ * DataRange.cc
+ *
+ *  Created on: Dec 7, 2010
+ *      Author: lamikr
+ */
+
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+
+#include <stdio.h>
+#include <time.h>
+#include <malloc.h>
+
+#include "log.h"
+#include "Data.hh"
+#include "Date.hh"
+
+using namespace std;
+using namespace plp;
+
+template <class NumberDataType>
+bool string_to_number(NumberDataType& result,
+                 const string& string_param,
+                 std::ios_base& (*format)(std::ios_base&))
+{
+       std::istringstream iss(string_param);
+       return !(iss >> format >> result).fail();
+}
+
+Data::Data(int size) {
+       value_arr.resize(size);
+}
+
+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<double> *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<double> *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<double> *vector_param,
+               Date *date_param,
+               string unit_param) {
+       unsigned int    ii;
+       unsigned int    size;
+
+       size    = vector_param->size();
+       //log_debug("Data(), value count: %d\n", size);
+       value_arr.resize(size);
+       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<double> *val_arr_param, Date *date_param) {
+       unsigned int    ii;
+       unsigned int    sz;
+
+       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);
+}
+
+Data::~Data() {
+}
+
+Data *Data::clone() {
+       Data    *ret_val;
+
+       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(Date *date_param) {
+       date_time.copy(date_param);
+}
+
+string Data::get_unit() {
+       return unit;
+}
+
+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<double>  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
+                       date    = Date::parse_date_str(item);
+               }
+               else if (ii >= 1) {
+                       suc_flg = string_to_number<double>(val, item, dec);
+                       if (suc_flg) {
+                               //log_debug("adding number: %f\n", val);
+                               v.push_back(val);
+                       }
+               }
+               ii++;
+       }
+       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(int dec_precision) {
+       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(dec_precision) << value_arr[ii];
+               }
+               ret_val.append(out.str());
+               if (unit.empty() == false) {
+                       ret_val.append(" ");
+                       ret_val.append(unit.c_str());
+               }
+       }
+       return ret_val;
+}
+
+string Data::to_string() {
+       return to_string(3);
+}
+
+int Data::get_value_count() {
+       return value_arr.size();
+}
+
+double Data::get(int indx) {
+       return value_arr[indx];
+}
+
+DataRange::DataRange() {
+       val_matrix      = NULL;
+       column_count    = 0;
+       row_count       = 0;
+       unit            = "";
+}
+
+DataRange::DataRange(Data *data) {
+       val_matrix      = NULL;
+       row_count       = 0;
+       if (data != NULL) {
+               column_count    = data->value_arr.size();
+               unit            = data->get_unit();
+               add(data);
+       }
+       else {
+               column_count    = 0;
+               unit            = "";
+       }
+}
+
+DataRange::DataRange(DataRange *datarange) {
+       val_matrix      = NULL;
+       row_count       = 0;
+       column_count    = 0;
+       unit            = "";
+       if (datarange != NULL) {
+               add(datarange);
+       }
+}
+
+DataRange::DataRange(int value_count_per_data_item, string unit_param) {
+       val_matrix      = NULL;
+       column_count    = value_count_per_data_item;
+       row_count       = 0;
+       unit            = unit_param;
+}
+
+DataRange::~DataRange() {
+       unsigned int    ii;
+       Date            *date;
+
+       if (val_matrix != NULL) {
+               free(val_matrix);
+               val_matrix      = NULL;
+       }
+       for (ii = 0; ii < date_list.size(); ii++) {
+               date    = date_list.at(ii);
+               delete(date);
+       }
+}
+
+void DataRange::add(Data *data) {
+       int     ii;
+       int     indx;
+       Date    *date;
+       int     cnt;
+
+       if (data != NULL) {
+               if ((val_matrix == NULL) &&
+                   (column_count == 0) &&
+                   (unit.empty() == true)) {
+                       column_count    = data->value_arr.size();
+                       unit            = data->get_unit();
+               }
+               cnt             = (row_count + 1) * column_count;
+               val_matrix      = (double *)realloc(val_matrix, cnt * sizeof(double));
+               indx            = row_count * column_count;
+               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().clone();
+               date_list.push_back(date);
+               row_count++;
+       }
+}
+
+void DataRange::add(DataRange *datarange) {
+       int     ii;
+       int     cnt;
+       Data    *dta;
+
+       if (datarange != NULL) {
+               cnt     = datarange->get_count();
+               for (ii = 0; ii < cnt; ii++) {
+                       dta     = datarange->get(ii);
+                       add(dta);
+                       delete(dta);
+               }
+       }
+}
+
+Data *DataRange::get(int row_index) {
+       Data            *ret_val;
+       int             start_indx;
+       int             ii;
+       vector<double>  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++) {
+                       //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(&vect, date, unit);
+       }
+       return ret_val;
+}
+
+int DataRange::get_count() {
+       return row_count;
+}
+
+int DataRange::get_data_item_value_count() {
+       return column_count;
+}
+
+Data *DataRange::get_first() {
+       Data    *ret_val;
+
+       ret_val = NULL;
+       if (row_count > 0) {
+               ret_val = get(0);
+       }
+       return ret_val;
+}
+
+Data *DataRange::get_last() {
+       return get(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(ii);
+               if (data != NULL) {
+                       data->printout();
+                       delete(data);
+               }
+       }
+       log_debug("---- DataRange printout done ----\n");
+}
diff --git a/src/Data.hh b/src/Data.hh
new file mode 100644 (file)
index 0000000..07bea1a
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Data.hh
+ *
+ *  Created on: Dec 8, 2010
+ *      Author: lamikr
+ */
+
+#ifndef DATA_HH_
+#define DATA_HH_
+
+#include <string>
+#include <valarray>
+#include <vector>
+
+#include "Date.hh"
+
+namespace plp {
+       class Data {
+               public:
+                       Data(int size);
+                       Data(int size, double default_value, std::string unit_param);
+                       Data(std::vector<double> *val_vector_param);
+                       Data(std::vector<double> *val_vector_param, std::string unit_param);
+                       Data(std::vector<double> *val_vector_param, plp::Date *date_param, std::string unit_param);
+                       Data(std::valarray<double> *val_arr_param, plp::Date *date_param);
+                       virtual ~Data();
+                       Data *clone();
+                       void printout();
+                       std::string to_string(int dec_precision);
+                       std::string to_string();
+                       static Data *parse_string(const std::string& data_str);
+                       plp::Date get_date();
+                       void set_date(plp::Date *date_param);
+                       int get_value_count();
+                       double get(int indx);
+                       std::string get_unit();
+                       std::valarray<double>   value_arr;
+               private:
+                       plp::Date       date_time;
+                       std::string     unit;
+       };
+
+       class DataRange {
+               public:
+                       DataRange();
+                       DataRange(Data *data);
+                       DataRange(DataRange *datarange);
+                       DataRange(int item_count_per_value, std::string unit_param);
+                       virtual ~DataRange();
+                       void add(Data *data);
+                       void add(DataRange *datarange);
+                       Data *get(int row_index);
+                       Data *get_first();
+                       Data *get_last();
+                       int get_count();
+                       int get_data_item_value_count();
+                       std::string get_unit();
+                       void printout();
+               protected:
+                       double                          *val_matrix;
+                       std::vector<plp::Date *>        date_list;
+                       int                             row_count;
+                       int                             column_count;
+                       std::string                     unit;
+       };
+}
+
+#endif /* DATA_HH_ */
diff --git a/src/DataReader.cc b/src/DataReader.cc
new file mode 100644 (file)
index 0000000..1c7e9a3
--- /dev/null
@@ -0,0 +1,426 @@
+/*
+ * DataReader.cc
+ *
+ *  Created on: Nov 7, 2010
+ *      Author: lamikr
+ */
+#include <sstream>
+
+#include <dirent.h>
+#include <malloc.h>
+#include <errno.h>
+#include <string.h>
+
+#include "log.h"
+
+#include "DataReader.hh"
+#include "DeviceConfig.hh"
+#include "FileUtil.hh"
+#include "StoreDay.hh"
+#include "StoreCache.hh"
+
+using namespace std;
+using namespace plp;
+
+template <class NumberDataType>
+bool string_to_number(NumberDataType& result,
+                 const std::string& string_param,
+                 std::ios_base& (*format)(std::ios_base&))
+{
+       istringstream iss(string_param);
+       return !(iss >> format >> result).fail();
+}
+
+DataReader::DataReader(string device_id_param) {
+       string  base_dir;
+
+       device_config   = NULL;
+       device_id       = device_id_param;
+       base_dir        = DeviceConfig::get_base_dir_name();
+       device_dir      = FileUtil::concat_paths(base_dir, device_id);
+       device_ch_dir   = FileUtil::concat_paths(base_dir, "cache");
+       device_ch_dir   = FileUtil::concat_paths(device_ch_dir, device_id);
+}
+
+DataReader::~DataReader() {
+       if (device_config != NULL) {
+               delete(device_config);
+               device_config   = NULL;
+       }
+}
+
+Data *DataReader::find_latest_data(vector<string> year_name_vector_param) {
+       string  year_name;
+       int     size;
+       Data    *ret_val;
+       Date    date;
+       int     val_int;
+
+       ret_val = NULL;
+       size    = year_name_vector_param.size();
+       if (size > 0) {
+               // dirs are alphabetically sorted
+               year_name       = year_name_vector_param.at(size - 1);
+               string_to_number<int>(val_int, year_name, dec);
+               date.year       = val_int;
+               ret_val         = StoreCache::get_latest_data(&date, device_id, PERIOD_YEARLY);
+       }
+       return ret_val;
+}
+
+Data *DataReader::get_latest_data() {
+       vector<string>  y_list;
+       Data            *ret_val;
+
+       ret_val = NULL;
+       y_list  = FileUtil::get_subdirectories(device_dir);
+       ret_val = find_latest_data(y_list);
+       return ret_val;
+}
+
+Data *DataReader::find_oldest_data(vector<string> year_name_vector_param) {
+       int     size;
+       string  year_name;
+       Data    *ret_val;
+       Date    date;
+       int     val_int;
+
+       ret_val = NULL;
+       size    = year_name_vector_param.size();
+       if (size > 0) {
+               // dirs are alphabetically sorted
+               year_name       = year_name_vector_param.at(0);
+               string_to_number<int>(val_int, year_name, dec);
+               date.year       = val_int;
+               ret_val         = StoreCache::get_oldest_data(&date, device_id, PERIOD_YEARLY);
+       }
+       return ret_val;
+}
+
+DataRange *DataReader::get_data_range() {
+       DataRange       *ret_val;
+       vector<string>  y_list;
+       Data            *o_data;
+       Data            *n_data;
+
+       ret_val = NULL;
+       y_list  = FileUtil::get_subdirectories(device_dir);
+       o_data  = find_oldest_data(y_list);
+       if (o_data != NULL) {
+               n_data  = find_latest_data(y_list);
+               if (n_data != NULL) {
+                       ret_val = new DataRange(o_data);
+                       ret_val->add(n_data);
+                       delete(n_data);
+               }
+               delete(o_data);
+       }
+       return ret_val;
+}
+
+EnumSummaryPeriod get_period_type(Date *start_date,
+                       Date *end_date) {
+       int                     diff;
+       EnumSummaryPeriod       ret_val;
+
+       ret_val = PERIOD_YEARLY;
+       diff    = end_date->year - start_date->year;
+       if (diff != 0) {
+               ret_val = PERIOD_YEARLY;
+       }
+       else {
+               diff    = end_date->month - start_date->month;
+               if (diff != 0) {
+                       ret_val = PERIOD_MONTHLY;
+               }
+               else {
+                       diff    = end_date->day - start_date->day;
+                       if (diff != 0) {
+                               ret_val = PERIOD_DAILY;
+                       }
+                       else {
+                               diff    = end_date->hour - start_date->hour;
+                               if (diff != 0) {
+                                       ret_val = PERIOD_HOURLY;
+                               }
+                               else {
+                                       diff    = end_date->min - start_date->min;
+                                       if (diff != 0) {
+                                               ret_val = PERIOD_MINUTELY;
+                                       }
+                                       else {
+                                               ret_val = PERIOD_SECONDLY;
+                                       }
+                               }
+                       }
+               }
+       }
+       return ret_val;
+}
+
+DataRange *DataReader::get_summary(Date *date_param,
+                               EnumSummaryCalculationType calc_type_param,
+                               EnumSummaryPeriod period_type_param) {
+       DataRange       *ret_val;
+       StoreCache      *store;
+
+       ret_val = NULL;
+       //store = new StoreDay(device_id, date_param);
+       store   = new StoreCache(device_id, date_param);
+       if (store != NULL) {
+               switch(calc_type_param) {
+                       case SUM:
+                               ret_val = store->get_sum(period_type_param);
+                               break;
+                       case DELTA:
+                               ret_val = store->get_delta(period_type_param);
+                               break;
+                       case MAX:
+                               ret_val = store->get_max(period_type_param);
+                               break;
+                       case MIN:
+                               ret_val = store->get_min(period_type_param);
+                               break;
+                       case MEAN:
+                       default:
+                               ret_val = store->get_mean(period_type_param);
+                               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\n", device_id.c_str());
+       }
+       delete(store);
+       return ret_val;
+}
+
+DataRange *DataReader::get_yearly_summary(Date *date,
+                               EnumSummaryCalculationType calc_type_param) {
+       return get_summary(date, calc_type_param, PERIOD_YEARLY);
+}
+
+DataRange *DataReader::get_yearly_summary(Date *date) {
+       DataRange       *ret_val;
+
+       if (device_config == NULL) {
+               device_config           = DeviceConfig::get_device_config(device_id);
+               summary_calc_type       = device_config->get_summary_calculation_type();
+       }
+       ret_val = get_yearly_summary(date, summary_calc_type);
+       return ret_val;
+}
+
+DataRange *DataReader::get_yearly_summary(Date *start_date,
+                                       Date *end_date) {
+       DataRange       *ret_val;
+       DataRange       *data;
+       Date            *date;
+
+       ret_val = NULL;
+       date    = start_date->clone();
+       while(date->before_or_equal_year(end_date)) {
+               data    = get_yearly_summary(date);
+               if (data != NULL) {
+                       if (ret_val == NULL) {
+                               ret_val = new DataRange(data);
+                       }
+                       else {
+                               ret_val->add(data);
+                       }
+                       delete(data);
+               }
+               date->next_year();
+       }
+       delete(date);
+       return ret_val;
+}
+
+DataRange *DataReader::get_monthly_summary(Date *date,
+                               EnumSummaryCalculationType calc_type_param) {
+       return get_summary(date, calc_type_param, PERIOD_MONTHLY);
+}
+
+DataRange *DataReader::get_monthly_summary(Date *date) {
+       DataRange       *ret_val;
+
+       if (device_config == NULL) {
+               device_config           = DeviceConfig::get_device_config(device_id);
+               summary_calc_type       = device_config->get_summary_calculation_type();
+       }
+       ret_val = get_monthly_summary(date, summary_calc_type);
+       return ret_val;
+}
+
+DataRange *DataReader::get_monthly_summary(Date *start_date,
+                                       Date *end_date) {
+       DataRange       *ret_val;
+       DataRange       *data;
+       Date            *date;
+
+       ret_val = NULL;
+       date    = start_date->clone();
+       while(date->before_or_equal_month(end_date)) {
+               data    = get_monthly_summary(date);
+               if (data != NULL) {
+                       if (ret_val == NULL) {
+                               ret_val = new DataRange(data);
+                       }
+                       else {
+                               ret_val->add(data);
+                       }
+                       delete(data);
+               }
+               date->next_month();
+       }
+       delete(date);
+       return ret_val;
+}
+
+DataRange *DataReader::get_daily_summary(Date *date,
+                               EnumSummaryCalculationType calc_type_param) {
+       return get_summary(date, calc_type_param, PERIOD_DAILY);
+}
+
+DataRange *DataReader::get_daily_summary(Date *date) {
+       DataRange       *ret_val;
+
+       if (device_config == NULL) {
+               device_config           = DeviceConfig::get_device_config(device_id);
+               summary_calc_type       = device_config->get_summary_calculation_type();
+       }
+       ret_val = get_daily_summary(date, summary_calc_type);
+       return ret_val;
+}
+
+DataRange *DataReader::get_daily_summary(Date *start_date,
+                                       Date *end_date) {
+       DataRange       *ret_val;
+       DataRange       *data;
+       Date            *date;
+
+       ret_val = NULL;
+       date    = start_date->clone();
+       while(date->before_or_equal_day(end_date)) {
+               data    = get_daily_summary(date);
+               if (data != NULL) {
+                       if (ret_val == NULL) {
+                               ret_val = new DataRange(data);
+                       }
+                       else {
+                               ret_val->add(data);
+                       }
+                       delete(data);
+               }
+               date->next_day();
+       }
+       delete(date);
+       return ret_val;
+}
+
+DataRange *DataReader::get_hourly_summary(Date *date,
+               EnumSummaryCalculationType calc_type_param) {
+       return get_summary(date, calc_type_param, PERIOD_HOURLY);
+}
+
+DataRange *DataReader::get_hourly_summary(Date *date) {
+       DataRange       *ret_val;
+
+       if (device_config == NULL) {
+               device_config           = DeviceConfig::get_device_config(device_id);
+               summary_calc_type       = device_config->get_summary_calculation_type();
+       }
+       ret_val = get_hourly_summary(date, summary_calc_type);
+       return ret_val;
+}
+
+DataRange *DataReader::get_hourly_summary(Date *start_date,
+                                       Date *end_date) {
+       DataRange       *ret_val;
+       DataRange       *dta_lst;
+       Data            *data;
+       Date            *date;
+       int             cnt;
+       int             ii;
+
+       ret_val = NULL;
+       date    = start_date->clone();
+       while(date->before_or_equal_hour(end_date)) {
+               dta_lst = get_hourly_summary(date);
+               cnt     = dta_lst->get_count();
+               for(ii = 0; ii < cnt; ii++) {
+                       data    = dta_lst->get(ii);
+                       if (data != NULL) {
+                               if (ret_val == NULL) {
+                                       ret_val = new DataRange(data);
+                               }
+                               else {
+                                       ret_val->add(data);
+                               }
+                               delete(data);
+                       }
+               }
+               date->next_day();
+       }
+       delete(date);
+       return ret_val;
+}
+
+DataRange *DataReader::get_data(Date *start_date,
+                               Date *end_date) {
+       DataRange               *ret_val;
+       EnumSummaryPeriod       period;
+
+       ret_val = NULL;
+       start_date->printout();
+       end_date->printout();
+       period  = get_period_type(start_date, end_date);
+       switch(period) {
+               case PERIOD_YEARLY:
+                       log_debug("get yearly summary: %s - %s\n", start_date->to_string().c_str(), end_date->to_string().c_str());
+                       ret_val = get_yearly_summary(start_date, end_date);
+                       break;
+               case PERIOD_MONTHLY:
+                       log_debug("get monthly summary\n");
+                       ret_val = get_monthly_summary(start_date, end_date);
+                       break;
+               case PERIOD_DAILY:
+                       log_debug("get daily summary\n");
+                       ret_val = get_daily_summary(start_date, end_date);
+                       break;
+               case PERIOD_HOURLY:
+                       log_debug("get hourly summary\n");
+                       ret_val = get_hourly_summary(start_date, end_date);
+                       break;
+               case PERIOD_MINUTELY:
+                       log_debug("get minute summary data\n");
+                       break;
+               case PERIOD_SECONDLY:
+               default:
+                       log_debug("get second summary data\n");
+                       break;
+       }
+       return ret_val;
+}
+
+string DataReader::get_device_id() {
+       return device_id;
+}
+
+/**
+ * Read device type from the device specific config file
+ */
+string DataReader::get_device_type() {
+       string  ret_val;
+
+       if (device_config == NULL) {
+               device_config   = DeviceConfig::get_device_config(device_id);
+               ret_val         = device_config->get_cfg_value(DEVICE_CONFIG_VALUE_KEY__TYPE);
+       }
+       return ret_val;
+}
diff --git a/src/DataReader.hh b/src/DataReader.hh
new file mode 100644 (file)
index 0000000..3266ec2
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * DataReader.hh
+ *
+ *  Created on: Nov 7, 2010
+ *      Author: lamikr
+ */
+
+#ifndef DATAREADER_H_
+#define DATAREADER_H_
+
+#include <string>
+#include <vector>
+
+#include "Data.hh"
+#include "Date.hh"
+#include "DeviceConfig.hh"
+
+#include <time.h>
+
+namespace plp {
+       class DataReader {
+               public:
+                       DataReader(std::string device_id);
+                       virtual ~DataReader();
+                       DataRange *get_data_range();
+                       /**
+                        * Get monthly summary data.
+                        * Depending from the device type, it may be daily mean value, daily delta, highest value, etc...
+                        */
+                       DataRange *get_yearly_summary(Date *date, EnumSummaryCalculationType calc_type);
+                       DataRange *get_yearly_summary(Date *date);
+                       DataRange *get_yearly_summary(Date *start_date, Date *end_date);
+                       /**
+                        * Get monthly summary data.
+                        * Depending from the device type, it may be daily mean value, daily delta, highest value, etc...
+                        */
+                       DataRange *get_monthly_summary(Date *date, EnumSummaryCalculationType calc_type);
+                       DataRange *get_monthly_summary(Date *date);
+                       DataRange *get_monthly_summary(Date *start_date, Date *end_date);
+                       /**
+                        * Get daily summary data calculated from the daily data items.
+                        * Depending from the device type, it may be daily mean value, daily delta, highest value, etc...
+                        */
+                       DataRange *get_daily_summary(Date *date, EnumSummaryCalculationType calc_type);
+                       DataRange *get_daily_summary(Date *date);
+                       DataRange *get_daily_summary(Date *start_date, Date *end_date);
+                       DataRange *get_hourly_summary(Date *date, EnumSummaryCalculationType calc_type);
+                       DataRange *get_hourly_summary(Date *date);
+                       DataRange *get_hourly_summary(Date *start_date, Date *end_date);
+                       DataRange *get_data(Date *start_date, Date *end_date);
+                       std::string get_device_id();
+                       std::string get_device_type();
+                       Data *get_latest_data();
+               protected:
+                       std::string                     device_id;
+                       std::string                     device_dir;
+                       std::string                     device_ch_dir;
+                       DeviceConfig                    *device_config;
+                       EnumSummaryCalculationType      summary_calc_type;
+                       Data *find_oldest_data(std::vector<std::string> year_vector);
+                       Data *find_latest_data(std::vector<std::string> year_vector);
+                       DataRange *get_summary(Date *date_param,
+                                       EnumSummaryCalculationType calc_type_param,
+                                       EnumSummaryPeriod period_type_param);
+       };
+}
+
+#endif /* DATAREADER_H_ */
diff --git a/src/Date.cc b/src/Date.cc
new file mode 100644 (file)
index 0000000..461c9d0
--- /dev/null
@@ -0,0 +1,383 @@
+/*
+ * Date.cc
+ *
+ *  Created on: Dec 7, 2010
+ *      Author: lamikr
+ */
+
+#include <iostream>
+#include <sstream>
+
+#include <stdio.h>
+#include <time.h>
+#include <malloc.h>
+
+#include "log.h"
+#include "Date.hh"
+
+using namespace std;
+using namespace plp;
+
+static const int CONST__DAYS_PER_MONTH[]       = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+Date::Date() {
+       time_t          wtime;
+       struct tm       *ltime;
+
+       time(&wtime);
+       ltime   = localtime(&wtime);
+       year    = 1900 + ltime->tm_year;
+       month   = ltime->tm_mon + 1;    // ltime-month: values 0 - 11...
+       day     = ltime->tm_mday;
+       hour    = ltime->tm_hour;
+       min     = ltime->tm_min;
+       sec     = ltime->tm_sec;
+}
+
+Date::Date(int year_param,
+       int month_param,
+       int day_param,
+       int hour_param,
+       int min_param,
+       int sec_param) {
+       year    = year_param;
+       month   = month_param;
+       day     = day_param;
+       hour    = hour_param;
+       min     = min_param;
+       sec     = sec_param;
+}
+
+Date::~Date() {
+       // TODO Auto-generated destructor stub
+}
+
+bool Date::is_leap_year() {
+       bool    ret_val;
+
+       ret_val = false;
+       if ((year % 4 == 0) &&
+           ((year % 400 == 0) || (year % 100 != 0))) {
+               ret_val = true;
+       }
+       return ret_val;
+}
+
+void Date::printout() {
+       log_debug("%d-%02d-%02d %02d:%02d:%02d\n", year, month, day, hour, min, sec);
+}
+
+Date *Date::clone() {
+       Date    *ret_val;
+
+       ret_val = new Date(year,
+                       month,
+                       day,
+                       hour,
+                       min,
+                       sec);
+       return ret_val;
+}
+
+void Date::copy(Date *date) {
+       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;
+       string  s2;
+
+       ret_val = false;
+       if (date2 != NULL) {
+               s1      = this->to_sortable_string();
+               s2      = date2->to_sortable_string();
+               if (s1.compare(s2) < 0) {
+                       ret_val = true;
+               }
+       }
+       return ret_val;
+}
+
+bool Date::equals(Date *date2) {
+       bool ret_val;
+
+       ret_val = false;
+       if (date2 != NULL) {
+               if ((this->sec == date2->sec) &&
+                   (this->min == date2->min) &&
+                   (this->hour == date2->hour) &&
+                   (this->day == date2->day) &&
+                   (this->month == date2->month) &&
+                   (this->year == date2->year)) {
+                       ret_val = true;
+               }
+       }
+       return ret_val;
+}
+
+bool Date::before_or_equal_year(Date *date2) {
+       bool    ret_val;
+       string  s1;
+       string  s2;
+
+       ret_val = (this->year <= date2->year);
+       return ret_val;
+}
+
+bool Date::before_or_equal_month(Date *date2) {
+       bool    ret_val;
+       string  s1;
+       string  s2;
+
+       ret_val = false;
+       if (this->year < date2->year) {
+               ret_val = true;
+       }
+       else {
+               if ((this->year == date2->year) &&
+                   (this->month <= date2->month)) {
+                       ret_val = true;
+               }
+       }
+       return ret_val;
+}
+
+bool Date::before_or_equal_day(Date *date2) {
+       bool    ret_val;
+       string  s1;
+       string  s2;
+
+       ret_val = false;
+       if (date2 != NULL) {
+               s1      = this->to_sortable_day_string();
+               s2      = date2->to_sortable_day_string();
+               if (s1.compare(s2) <= 0) {
+                       ret_val = true;
+               }
+       }
+       return ret_val;
+}
+
+bool Date::before_or_equal_hour(Date *date2) {
+       bool    ret_val;
+       string  s1;
+       string  s2;
+
+       ret_val = false;
+       if (date2 != NULL) {
+               s1      = this->to_sortable_hour_string();
+               s2      = date2->to_sortable_hour_string();
+               if (s1.compare(s2) <= 0) {
+                       ret_val = true;
+               }
+       }
+       return ret_val;
+}
+
+bool Date::before_or_equal_min(Date *date2) {
+       bool    ret_val;
+       string  s1;
+       string  s2;
+
+       ret_val = false;
+       if (date2 != NULL) {
+               s1      = this->to_sortable_min_string();
+               s2      = date2->to_sortable_min_string();
+               if (s1.compare(s2) <= 0) {
+                       ret_val = true;
+               }
+       }
+       return ret_val;
+}
+
+bool Date::before_or_equal(Date *date2) {
+       bool    ret_val;
+       string  s1;
+       string  s2;
+
+       ret_val = false;
+       if (date2 != NULL) {
+               s1      = this->to_sortable_string();
+               s2      = date2->to_sortable_string();
+               if (s1.compare(s2) <= 0) {
+                       ret_val = true;
+               }
+       }
+       return ret_val;
+}
+
+void Date::next_second() {
+       if (sec < 59) {
+               sec++;
+       }
+       else {
+               next_min();
+       }
+}
+
+void Date::next_min() {
+       if (min < 59) {
+               sec     = 0;
+               min++;
+       }
+       else {
+               next_hour();
+       }
+}
+
+void Date::next_hour() {
+       hour++;
+       if (hour < 23) {
+               sec     = 0;
+               min     = 0;
+               hour++;
+       }
+       else {
+               next_day();
+       }
+}
+
+void Date::next_day() {
+       if ((month > 0) &&
+           (month <= 12)) {
+               if ((day < CONST__DAYS_PER_MONTH[month - 1]) ||
+                   ((month == 2) &&
+                    (is_leap_year() == true) &&
+                    (day == 28))) {
+                       sec     = 0;
+                       min     = 0;
+                       hour    = 0;
+                       day++;
+               }
+               else {
+                       next_month();
+               }
+       }
+}
+
+void Date::next_month() {
+       if (month < 12) {
+               sec     = 0;
+               min     = 0;
+               hour    = 0;
+               day     = 1;
+               month++;
+       }
+       else {
+               next_year();
+       }
+}
+
+void Date::next_year() {
+       sec     = 0;
+       min     = 0;
+       hour    = 0;
+       day     = 1;
+       month   = 1;
+       year++;
+}
+
+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++) {
+               next_day();
+       }
+       for (ii = 0; ii < hour_c; ii++) {
+               hour++;
+               if (hour > 24) {
+                       hour    = 0;
+                       next_day();
+               }
+       }
+       min     = min + minutes;
+       if (min >= 60) {
+               min     = min % 60;
+               hour++;
+               if (hour > 24) {
+                       hour    = 0;
+                       next_day();
+               }
+       }
+}
+
+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_sortable_day_string() {
+       char    buffer[30];
+
+
+       string  ret_val;
+
+       sprintf(buffer, "%016d%02d%02d", year, month, day);
+       ret_val = buffer;
+       return ret_val;
+}
+
+string Date::to_sortable_hour_string() {
+       char    buffer[30];
+       string  ret_val;
+
+       sprintf(buffer, "%016d%02d%02d%02d", year, month, day, hour);
+       ret_val = buffer;
+       return ret_val;
+}
+
+string Date::to_sortable_min_string() {
+       char    buffer[30];
+       string  ret_val;
+
+       sprintf(buffer, "%016d%02d%02d%02d%02d", year, month, day, hour, min);
+       ret_val = buffer;
+       return ret_val;
+}
+
+string Date::to_sortable_string() {
+       char    buffer[30];
+       string  ret_val;
+
+       sprintf(buffer, "%016d%02d%02d%02d%02d%02d", year, month, day, hour, min, sec);
+       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;
+}
+
+Date Date::parse_date_str(string date_str) {
+       char            c;
+       stringstream    ss(date_str);
+       Date            ret_val;
+
+       ss >>ret_val.year >>c >>ret_val.month >>c >>ret_val.day >>ret_val.hour >>c >>ret_val.min >>c >>ret_val.sec;
+       return ret_val;
+}
diff --git a/src/Date.hh b/src/Date.hh
new file mode 100644 (file)
index 0000000..21b6bbe
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Date.hh
+ *
+ *  Created on: Dec 7, 2010
+ *      Author: lamikr
+ */
+
+#ifndef DATE_HH_
+#define DATE_HH_
+
+#include <string>
+
+namespace plp {
+       class Date {
+               public:
+                       Date();
+                       Date(int year_param,
+                            int month_param,
+                            int day_param,
+                            int hour_param,
+                            int min_param,
+                            int sec_param);
+                       virtual ~Date();
+                       void printout();
+                       bool is_leap_year();
+                       void next_second();
+                       void next_min();
+                       void next_hour();
+                       void next_day();
+                       void next_month();
+                       void next_year();
+                       void inc_minutes(int minutes);
+                       void inc_seconds(int seconds);
+                       Date *clone();
+                       void copy(Date *date);
+                       bool before(Date *date2);
+                       bool equals(Date *date2);
+                       bool before_or_equal(Date *date2);
+                       bool before_or_equal_year(Date *date2);
+                       bool before_or_equal_month(Date *date2);
+                       bool before_or_equal_day(Date *date2);
+                       bool before_or_equal_hour(Date *date2);
+                       bool before_or_equal_min(Date *date2);
+                       static plp::Date parse_date_str(std::string date_str);
+                       int     year;
+                       int     month;
+                       int     day;
+                       int     hour;
+                       int     min;
+                       int     sec;
+                       std::string to_string();
+               protected:
+                       std::string to_sortable_string();
+                       std::string to_sortable_day_string();
+                       std::string to_sortable_hour_string();
+                       std::string to_sortable_min_string();
+                       //static const int arr_days_per_month[];
+       };
+}
+
+#endif /* DATE_HH_ */
diff --git a/src/Device.cc b/src/Device.cc
new file mode 100644 (file)
index 0000000..8923ff8
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Device.cc
+ *
+ *  Created on: Mar 5, 2011
+ *      Author: lamikr
+ */
+#include <string>
+
+#include "Device.hh"
+#include "DeviceConfig.hh"
+
+using namespace std;
+using namespace plp;
+
+Device::Device(string id_param, string type_param) : plp::DeviceData(id_param, type_param) {
+}
+
+Device::Device(string id_param, string type_param, string name_param, EnumDeviceLifeCycleStatus status_param) : plp::DeviceData(id_param, type_param, name_param, status_param) {
+}
diff --git a/src/Device.hh b/src/Device.hh
new file mode 100644 (file)
index 0000000..a0984ff
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * GenericDevice.hh
+ *
+ *  Created on: Feb 28, 2011
+ *      Author: lamikr
+ */
+
+#ifndef DEVICE_HH_
+#define DEVICE_HH_
+
+#include <string>
+
+#include "DeviceData.hh"
+#include "DataReader.hh"
+
+namespace plp {
+       class Device : public DeviceData {
+               public:
+                       Device(std::string id_param, std::string type_param);
+                       Device(std::string id_param, std::string type_param, std::string name_param, plp::EnumDeviceLifeCycleStatus status_param);
+                       virtual plp::DataReader *get_device_data() = 0;
+       };
+}
+
+#endif /* DEVICE_HH_ */
diff --git a/src/DeviceConfig.cc b/src/DeviceConfig.cc
new file mode 100644 (file)
index 0000000..a78a62f
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * DeviceConfig.cc
+ *
+ *  Created on: Dec 9, 2010
+ *      Author: lamikr
+ */
+
+#include "DeviceConfig.hh"
+
+#include <string.h>
+#include <malloc.h>
+
+#include "log.h"
+
+#include "DataReader.hh"
+#include "FileUtil.hh"
+
+using namespace std;
+using namespace plp;
+
+string DeviceConfig::store_base_dir    = DEFAULT_STORAGE_BASE_DIR;
+
+ConfigHandle::ConfigHandle(uci_context *ctx_param, uci_package *pkg_param) {
+       _ctx    = ctx_param;
+       _pkg    = pkg_param;
+}
+
+ConfigHandle::~ConfigHandle() {
+       uci_unload(_ctx, _pkg);
+       uci_free_context(_ctx);
+}
+
+DeviceConfig::DeviceConfig(string device_id_param) {
+       device_id       = device_id_param;
+       uci_handle      = load_device_config(device_id_param);
+       if (uci_handle != NULL) {
+               device_type     = get_cfg_value(DEVICE_CONFIG_VALUE_KEY__TYPE);
+       }
+       else {
+               log_error("Could not read device configuration.\n");
+       }
+}
+
+DeviceConfig::~DeviceConfig() {
+       if (uci_handle != NULL) {
+               delete(uci_handle);
+               uci_handle      = NULL;
+       }
+}
+
+void DeviceConfig::set_base_dir_name(string store_param) {
+       int     pos;
+       int     b_count;
+
+       pos     = store_param.find_last_of("/");
+       b_count = store_param.length();
+       if (pos == (b_count - 1)) {
+               store_base_dir  = store_param;
+       }
+       else {
+               store_base_dir  = store_param + "/";
+       }
+}
+
+string DeviceConfig::get_base_dir_name() {
+       return store_base_dir;
+}
+
+string DeviceConfig::get_dir_name(string device_id_param) {
+       string  ret_val;
+       string  d_name;
+
+       d_name  = DeviceConfig::get_base_dir_name();
+       ret_val = FileUtil::concat_paths(d_name, device_id_param);
+       return ret_val;
+}
+
+string DeviceConfig::get_file_name(string device_id_param) {
+       string  ret_val;
+       string  fname;
+
+       fname   = DEVICE_CONFIG__FILE_NAME;
+       ret_val = get_dir_name(device_id);
+       ret_val = FileUtil::concat_paths(ret_val, fname);
+       return ret_val;
+}
+
+string DeviceConfig::get_cfg_value(string key) {
+       struct uci_section      *section;
+       struct uci_option       *option;
+       string                  ret_val;
+
+       if (uci_handle != NULL) {
+               section = uci_lookup_section(uci_handle->_ctx, uci_handle->_pkg, DEVICE_CONFIG__SECTION_NAME);
+               if (section != NULL) {
+                       option  = uci_lookup_option(uci_handle->_ctx, section, key.c_str());
+                       if (option != NULL) {
+                               switch (option->type) {
+                                       case UCI_TYPE_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("key: %s Failed to read parameter value\n", key.c_str());
+                                               break;
+                               }
+                       }
+                       else {
+                               log_error("key: %s Failed to read parameter value\n", key.c_str());
+                       }
+               }
+       }
+       return ret_val;
+}
+
+void DeviceConfig::set_cfg_value(string key, string value) {
+       string  cfg_dir;
+       string  cfg_fl;
+
+       cfg_dir = get_dir_name(device_id);
+       cfg_fl  = DEVICE_CONFIG__FILE_NAME;
+       set_config_value(cfg_dir.c_str(),
+                       cfg_fl.c_str(),
+                       DEVICE_CONFIG__SECTION_TYPE,
+                       DEVICE_CONFIG__SECTION_NAME,
+                       key.c_str(),
+                       value.c_str());
+}
+
+EnumSummaryCalculationType DeviceConfig::get_summary_calculation_type() {
+       EnumSummaryCalculationType      ret_val;
+
+       ret_val = MEAN;
+       if (device_type.empty() == false) {
+               if (device_type.compare("Counter Device") == 0) {
+                       ret_val = DELTA;
+               }
+       }
+       return ret_val;;
+}
+
+ConfigHandle *DeviceConfig::load_device_config(string device_id_param) {
+       int                     err_flg;
+       struct uci_context      *ctx;
+       struct uci_package      *pkg;
+       string                  cfg_fl;
+       string                  cfg_dir;
+       ConfigHandle            *ret_val;
+
+       ret_val = NULL;
+       cfg_dir = get_dir_name(device_id_param);
+       if (cfg_dir.empty() == false) {
+               if (access(cfg_dir.c_str(), W_OK) != 0) {
+                       FileUtil::mkdirs(cfg_dir.c_str());
+               }
+               cfg_fl  = get_file_name(device_id_param);
+               if (access(cfg_fl.c_str(), R_OK) == 0) {
+                       ctx     = uci_alloc_context();
+                       if (ctx != NULL) {
+                               //log_debug("uci_set_confdir: %s\n", cfg_dir.c_str());
+                               uci_set_confdir(ctx, cfg_dir.c_str());
+                               err_flg = uci_load(ctx, cfg_fl.c_str(), &pkg);
+                               if (err_flg == UCI_OK) {
+                                       //log_debug("Loaded device configuration: %s.\n", cfg_fl.c_str());
+                                       ret_val = new ConfigHandle(ctx, pkg);
+                               }
+                               else {
+                                       log_debug("Failed to load device configuration: %s, err code: %d.\n", cfg_fl.c_str(), UCI_OK);
+                                       set_cfg_value(DEVICE_CONFIG_VALUE_KEY__TYPE, "");
+                                       uci_free_context(ctx);
+                               }
+                       }
+                       else {
+                               log_error("Failed to load device device configuration, memory allocation error.\n");
+                               set_cfg_value(DEVICE_CONFIG_VALUE_KEY__TYPE, "");
+                       }
+               }
+               else {
+                       log_error("Failed to load device device configuration, file does not exist: %s.\n", cfg_fl.c_str());
+               }
+       }
+       return ret_val;
+}
+
+DeviceConfig *DeviceConfig::get_device_config(string device_id) {
+       DeviceConfig    *ret_val;
+
+       ret_val = new DeviceConfig(device_id);
+       return ret_val;
+}
diff --git a/src/DeviceConfig.hh b/src/DeviceConfig.hh
new file mode 100644 (file)
index 0000000..90ff28d
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * DeviceConfig.hh
+ *
+ *  Created on: Dec 9, 2010
+ *      Author: lamikr
+ */
+
+#ifndef DEVICECONFIG_HH_
+#define DEVICECONFIG_HH_
+
+#include <string>
+
+extern "C" {
+       #include <uci.h>
+       #include "config.h"
+}
+
+enum EnumSummaryPeriod{PERIOD_YEARLY, PERIOD_MONTHLY, PERIOD_DAILY, PERIOD_HOURLY, PERIOD_MINUTELY, PERIOD_SECONDLY};
+enum EnumSummaryCalculationType {SUM, DELTA, MIN, MAX, MEAN};
+
+const std::string SUMMARY_PERIOD_NAMES_ARRAY[]         = {"yearly", "monthly", "daily", "minutely", "secondly"};
+const std::string CALCULATION_TYPE_NAMES_ARRAY[]       = {"sum", "delta", "min", "max", "mean"};
+
+#define DEVICE_CONFIG__FILE_NAME               "dev_cfg.txt"
+#define DEVICE_CONFIG__SECTION_TYPE            "device"
+#define DEVICE_CONFIG__SECTION_NAME            "base_data"
+#define DEVICE_CONFIG_VALUE_KEY__TYPE          "type"
+#define DEVICE_CONFIG_VALUE_KEY__ID            "id"
+#define DEVICE_CONFIG_VALUE_KEY__NAME          "name"
+
+#define DEFAULT_STORAGE_BASE_DIR               "/tmp/w1data"
+#define DATAFILE_SUFFIX                                ".txt"
+#define CACHE_DIR_NAME                         "cache"
+
+namespace plp {
+       struct ConfigHandle {
+               public:
+                       ConfigHandle(uci_context *ctx_param, uci_package *pkg_param);
+                       ~ConfigHandle();
+                       struct uci_context      *_ctx;
+                       struct uci_package      *_pkg;
+       };
+
+       class DeviceConfig {
+               public:
+                       DeviceConfig(std::string device_id_param);
+                       virtual ~DeviceConfig();
+                       static std::string get_base_dir_name();
+                       static void set_base_dir_name(std::string store_param);
+                       static DeviceConfig *get_device_config(std::string device_id);
+                       std::string get_cfg_value(std::string key);
+                       void set_cfg_value(std::string key, std::string value);
+                       EnumSummaryCalculationType get_summary_calculation_type();
+               private:
+                       static std::string      store_base_dir;
+                       std::string             device_id;
+                       std::string             device_type;
+                       ConfigHandle            *uci_handle;
+                       ConfigHandle *load_device_config(std::string device_id_param);
+                       std::string get_dir_name(std::string device_id);
+                       std::string get_file_name(std::string device_id_param);
+       };
+}
+
+#endif /* DEVICECONFIG_HH_ */
diff --git a/src/DeviceData.cc b/src/DeviceData.cc
new file mode 100644 (file)
index 0000000..60edf5e
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * DeviceData.cc
+ *
+ *  Created on: Mar 4, 2011
+ *      Author: lamikr
+ */
+#include <plp/Device.hh>
+#include "DeviceData.hh"
+
+using namespace std;
+using namespace plp;
+
+DeviceData::DeviceData(string id_param, string type_param) {
+       id                      = id_param;
+       type                    = type_param;
+       lifecycle_status        = LIFECYCLE_STATUS__UNAVAILABLE;
+}
+
+DeviceData::DeviceData(std::string id_param, std::string type_param, std::string name_param, plp::EnumDeviceLifeCycleStatus status_param) {
+       id                      = id_param;
+       type                    = type_param;
+       name                    = name_param;
+       lifecycle_status        = status_param;
+}
+
+DeviceData::~DeviceData() {
+
+}
+
+string DeviceData::get_id() {
+       return id;
+}
+
+string DeviceData::get_name() {
+       return name;
+}
+
+void DeviceData::set_name(string name_param) {
+       name    = name_param;
+}
+
+EnumDeviceLifeCycleStatus DeviceData::get_lifecycle_state() {
+       return lifecycle_status;
+}
+
+string DeviceData::get_type() {
+       return type;
+}
+
+void DeviceData::printout() {
+
+}
diff --git a/src/DeviceData.hh b/src/DeviceData.hh
new file mode 100644 (file)
index 0000000..ce0f89a
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * DeviceData.hh
+ *
+ *  Created on: Mar 4, 2011
+ *      Author: lamikr
+ */
+
+#ifndef DEVICEINFO_HH_
+#define DEVICEINFO_HH_
+
+#include <string>
+
+using namespace std;
+
+namespace plp {
+       enum EnumDeviceLifeCycleStatus {LIFECYCLE_STATUS__UNAVAILABLE, LIFECYCLE_STATUS__AVAILABLE};
+
+       class DeviceData {
+               public:
+                       DeviceData(string id_param, string type_param);
+                       DeviceData(string id_param, string type_param, string name_param, EnumDeviceLifeCycleStatus status_param);
+                       ~DeviceData();
+                       std::string get_id();
+                       std::string get_name();
+                       std::string get_type();
+                       plp::EnumDeviceLifeCycleStatus get_lifecycle_state();
+                       void set_name(std::string name_param);
+                       void printout();
+               protected:
+                       std::string id;
+                       std::string name;
+                       std::string type;
+                       plp::EnumDeviceLifeCycleStatus lifecycle_status;
+       };
+}
+
+#endif /* DEVICEINFO_HH_ */
diff --git a/src/DeviceTypes.hh b/src/DeviceTypes.hh
new file mode 100644 (file)
index 0000000..e37a68b
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * DeviceTypes.hh
+ *
+ *  Created on: Mar 3, 2011
+ *      Author: lamikr
+ */
+
+#ifndef DEVICETYPES_HH_
+#define DEVICETYPES_HH_
+
+#define DEVICE_TYPE_UNKNOWN            "Unknown"
+#define DEVICE_TYPE_TEMPERATURESENSOR  "Temperature Sensor"
+#define DEVICE_TYPE_COUNTER_DEVICE     "Counter Device"
+
+#endif /* DEVICETYPES_HH_ */
diff --git a/src/FileUtil.cc b/src/FileUtil.cc
new file mode 100644 (file)
index 0000000..7d95bef
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+ * FileUtil.cc
+ *
+ *  Created on: Mar 5, 2011
+ *      Author: lamikr
+ */
+
+#include <algorithm>
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <stdbool.h>
+
+#include "log.h"
+#include "FileUtil.hh"
+#include "DeviceConfig.hh"
+
+using namespace std;
+using namespace plp;
+
+template <class NumberDataType>
+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();
+}
+
+FileUtil::FileUtil() {
+}
+
+FileUtil::~FileUtil() {
+}
+
+char *FileUtil::parse_directory_path(const char *file_path) {
+       char    *p;
+       size_t  b_count;
+       size_t  f_size;
+       char    *ret_val;
+
+       ret_val = NULL;
+       if (file_path != NULL) {
+               f_size  = 0;
+               b_count = strlen(file_path);
+               for (p = &((char *)file_path)[b_count]; p != (char *)file_path; p--) {
+                       f_size++;
+                       if ((*p == '/') ||
+                           (*p == '\\')) {
+                               b_count = (b_count - f_size) + 1;
+                               ret_val = strndup(file_path, b_count);
+                               log_debug("dir: %s\n", ret_val);
+                               break;
+                       }
+               }
+       }
+       return ret_val;
+}
+
+bool FileUtil::mkdirs(const char *path) {
+       bool    ret_val;
+       char    *p;
+       int     err_flg;
+
+       ret_val = true;
+       if (path != NULL) {
+               // go through each directory one by and and create if not exist
+               for (p = (char *)path; *p; p++) {
+                   if ((p != path) &&
+                       ((*p == '/') ||
+                        (*p == '\\'))) {
+                               *p = '\0';
+                               // if dir does not exist, create it
+                               if (access(path, F_OK) != 0) {
+                                       //log_debug("trying to create directory: %s\n", path);
+                                       err_flg = mkdir(path, S_IRWXU);
+                                       if (err_flg != 0) {
+                                               log_error("Could not create directory: %s\n", path);
+                                               ret_val = false;
+                                               break;
+                                       }
+                               }
+                               *p = '/';
+                       }
+               }
+               if (ret_val == true) {
+                       // if dir does not exist, create it
+                       if (access(path, F_OK) != 0) {
+                               //log_debug("trying to create directory: %s\n", path);
+                               err_flg = mkdir(path, S_IRWXU);
+                               if (err_flg != 0) {
+                                       log_error("Could not create directory: %s\n", path);
+                                       ret_val = false;
+                               }
+                       }
+               }
+       }
+       else {
+               ret_val = false;
+               log_error("Could not create NULL directory\n");
+       }
+       return ret_val;
+}
+
+std::ofstream *FileUtil::open_for_writing(const char *f_path) {
+       char            *d_path;
+       size_t          b_count;
+       ofstream        *ret_val;
+       bool            b_flg;
+
+       ret_val = NULL;
+       if (f_path != NULL) {
+               b_count = strlen(f_path);
+               if ((f_path[b_count - 1] != '/') &&
+                   (f_path[b_count - 1] != '\\')) {
+                       ret_val = new ofstream();
+                       ret_val->open(f_path, ios::app);
+                       if (ret_val->is_open() == false) {
+                               d_path  = parse_directory_path(f_path);
+                               if (d_path != NULL) {
+                                       b_flg   = mkdirs(d_path);
+                                       free(d_path);
+                               }
+                               if (b_flg == true) {
+                                       ret_val->open(f_path, ios::app);
+                               }
+                       }
+               }
+               else {
+                       log_error("Could not open file, invalid file name. (%s)\n", f_path);
+               }
+       }
+       else {
+               log_error("Could not open file, invalid file name. (= NULL)\n");
+       }
+       return ret_val;
+}
+
+string FileUtil::concat_paths(string path_start, string path_end) {
+       return concat_paths(path_start.c_str(), path_end.c_str());
+}
+
+string FileUtil::concat_paths(const char *path_start, const char *path_end) {
+       string  ret_val;
+       string  end_str;
+       int     pos;
+       int     b_count;
+
+       if (path_start != NULL) {
+               ret_val = path_start;
+               if (path_end != NULL) {
+                       end_str = path_end;
+                       b_count = ret_val.length();
+                       pos     = ret_val.find_last_of("/");
+                       if (pos == (b_count -1)) {
+                               ret_val.append(end_str);
+                       }
+                       else {
+                               pos     = end_str.find_first_of("/");
+                               if (pos == 0) {
+                                       ret_val.append(end_str);
+                               }
+                               else {
+                                       ret_val.append("/");
+                                       ret_val.append(end_str);
+                               }
+                       }
+               }
+       }
+       else {
+               if (path_end != NULL) {
+                       ret_val = path_end;
+               }
+       }
+       return ret_val;
+}
+
+bool FileUtil::is_subdirectory(const char *path, dirent *direntry) {
+       bool            ret_val;
+       struct stat     stat_info;
+       string          fname;
+
+       ret_val = false;
+       if (direntry != NULL) {
+               if ((strcmp(direntry->d_name, ".") == 0) ||
+                   (strcmp(direntry->d_name, "..") == 0)) {
+                       ret_val = false;
+               }
+               else {
+                       fname   = concat_paths(path, direntry->d_name);
+                       stat(fname.c_str(), &stat_info);
+                       ret_val = S_ISDIR(stat_info.st_mode);
+                       //log_debug("stat for: %s: %d\n", fname.c_str(), ret_val);
+               }
+       }
+       return ret_val;
+}
+
+bool FileUtil::is_datafile(const char *path, dirent *direntry) {
+       bool            ret_val;
+       struct stat     stat_info;
+       string          name;
+       int             pos;
+       string          fname;
+
+       ret_val = false;
+       if (direntry != NULL) {
+               name    = direntry->d_name;
+               pos     = name.find(DATAFILE_SUFFIX);
+               if (pos > 0) {
+                       fname   = concat_paths(path, direntry->d_name);
+                       stat(fname.c_str(), &stat_info);
+                       ret_val = S_ISREG(stat_info.st_mode);
+               }
+       }
+       return ret_val;
+}
+
+/**
+ * get sub-directories sorted in alphabetical order.
+ */
+vector<string> FileUtil::get_subdirectories(const string& path) {
+       dirent          *direntry;
+       DIR             *dir;
+       bool            bool_flg;
+       vector<string>  ret_val;
+
+       //log_debug("scanning path: %s\n", path.c_str());
+       errno   = 0;
+       if (path.empty() == false) {
+               dir     = opendir(path.c_str());
+               if (dir) {
+                       while (true) {
+                               errno           = 0;
+                               direntry        = readdir(dir);
+                               if (direntry != NULL) {
+                                       bool_flg        = is_subdirectory(path.c_str(), direntry);
+                                       if (bool_flg == true) {
+                                               ret_val.push_back(string(direntry->d_name));
+                                               //log_debug("added dir: %s\n", direntry->d_name);
+                                       }
+                               }
+                               else {
+                                       break;
+                               }
+                       }
+                       closedir(dir);
+                       sort(ret_val.begin(), ret_val.end());
+               }
+       }
+       return ret_val;
+}
+
+/**
+ * get sub-directories sorted in alphabetical order.
+ */
+vector<string> FileUtil::get_data_files(const string& path) {
+       dirent          *direntry;
+       DIR             *dir;
+       vector<string>  ret_val;
+
+       errno   = 0;
+       if (path.empty() == false) {
+               dir     = opendir(path.c_str());
+               if (dir) {
+                       while (true) {
+                               errno           = 0;
+                               direntry        = readdir(dir);
+                               if (direntry != NULL) {
+                                       if (is_datafile(path.c_str(), direntry) == true) {
+                                               ret_val.push_back(string(direntry->d_name));
+                                       }
+                               }
+                               else {
+                                       break;
+                               }
+                       }
+                       closedir(dir);
+                       sort(ret_val.begin(), ret_val.end());
+               }
+       }
+       return ret_val;
+}
diff --git a/src/FileUtil.hh b/src/FileUtil.hh
new file mode 100644 (file)
index 0000000..e69ada8
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * FileUtil.hh
+ *
+ *  Created on: Mar 5, 2011
+ *      Author: lamikr
+ */
+
+#ifndef FILEUTIL_HH_
+#define FILEUTIL_HH_
+
+#include <string>
+#include <vector>
+
+#include <dirent.h>
+
+namespace plp {
+       class FileUtil {
+               public:
+                       FileUtil();
+                       virtual ~FileUtil();
+                       static std::string concat_paths(std::string path_start, std::string path_end);
+                       static std::string concat_paths(const char *path_start, const char *path_end);
+                       static bool is_subdirectory(const char *path, dirent *direntry);
+                       static bool is_datafile(const char *path, dirent *direntry);
+                       static std::vector<std::string> get_subdirectories(const std::string& path);
+                       static std::vector<std::string> get_data_files(const std::string& path);
+                       static char *parse_directory_path(const char *file_path);
+                       static bool mkdirs(const char *path);
+                       static std::ofstream *open_for_writing(const char *path);
+       };
+}
+
+#endif /* FILEUTIL_HH_ */
index 7ad0d5a88c40c1e80566753a9af0fbc9de408f3e..183b03bd68abdeacce5d6f60badf3aa055fb6f7e 100644 (file)
@@ -1,6 +1,18 @@
 lib_LTLIBRARIES = libplp.la
 libplp_la_SOURCES = \
        config.c config.h \
+       Data.hh Data.cc \
+       DataReader.hh DataReader.cc \
+       Date.hh Date.cc \
+       Device.hh Device.cc \
+       DeviceConfig.hh DeviceConfig.cc \
+       DeviceData.hh DeviceData.cc \
+       DeviceTypes.hh \
+       FileUtil.cc FileUtil.hh \
+       SensorDevice.hh \
+       Store.cc Store.hh \
+       StoreDay.cc StoreDay.hh \
+       StoreCache.cc StoreCache.hh \
        log.h \
        log_config.c \
        str_util.c str_util.h \
@@ -13,4 +25,17 @@ libplpinclude_HEADERS =   \
         config.h \
         log.h \
         retval.h \
-        str_util.h
+        str_util.h \
+        Data.hh \
+        DataReader.hh \
+        Date.hh \
+        Device.hh \
+        DeviceConfig.hh \
+        DeviceData.hh \
+        DeviceTypes.hh \
+        FileUtil.hh \
+        SensorDevice.hh \
+        Store.hh \
+       StoreDay.hh \
+       StoreCache.hh
+        
diff --git a/src/SensorDevice.hh b/src/SensorDevice.hh
new file mode 100644 (file)
index 0000000..80c02df
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * DeviceTypeSensor.hh
+ *
+ *  Created on: Feb 28, 2011
+ *      Author: lamikr
+ */
+
+#ifndef DEVICETYPESENSOR_HH_
+#define DEVICETYPESENSOR_HH_
+
+#include <string>
+
+#include "Device.hh"
+
+namespace plp {
+       class SensorDevice : public Device {
+               public:
+                       SensorDevice(std::string id_param, std::string type_param) : Device(id_param, type_param) {}
+                       virtual std::string get_unit() = 0;
+                       virtual plp::Data *get_data() = 0;
+       };
+}
+
+#endif /* DEVICETYPESENSOR_HH_ */
diff --git a/src/Store.cc b/src/Store.cc
new file mode 100644 (file)
index 0000000..ba29ed1
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Store.cc
+ *
+ *  Created on: Jan 20, 2011
+ *      Author: lamikr
+ */
+#include <fstream>
+
+#include "log.h"
+#include "Store.hh"
+
+using namespace std;
+using namespace plp;
+
+Store::Store(string device_id_param,
+               Date *date_param) {
+       device_id       = device_id_param;
+       if (date_param != NULL) {
+               date            = date_param->clone();
+       }
+       else {
+               date    = NULL;
+       }
+       store_data      = NULL;
+       range_data      = NULL;
+}
+
+Store::~Store() {
+       if (store_data != NULL) {
+               delete(store_data);
+               store_data      = NULL;
+       }
+       if (date != NULL) {
+               delete(date);
+       }
+}
+
+bool Store::load(string fname_param) {
+       Data            *data;
+       ifstream        in;
+       string          data_str;
+       bool            ret_val;
+
+       ret_val = false;
+       if (store_data != NULL) {
+               delete(store_data);
+               store_data      = NULL;
+       }
+       if (access(fname_param.c_str(), R_OK) == 0) {
+               //log_debug("opening file: %s\n", fname_param.c_str());
+               in.open(fname_param.c_str());
+               if (in.is_open() == true) {
+                       while (in.eof() == false) {
+                               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);
+                                               }
+                                               delete(data);
+                                       }
+                               }
+                       }
+                       ret_val = true;
+               }
+               else {
+                       log_error("Could not open data file: %s\n", fname_param.c_str());
+               }
+       }
+       else {
+               log_error("Could not find file: %s\n", fname_param.c_str());
+       }
+       return ret_val;
+}
diff --git a/src/Store.hh b/src/Store.hh
new file mode 100644 (file)
index 0000000..cb0b6c2
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Store.hh
+ *
+ *  Created on: Jan 20, 2011
+ *      Author: lamikr
+ */
+
+#ifndef STORE_HH_
+#define STORE_HH_
+
+#include <string>
+
+#include "Data.hh"
+#include "Date.hh"
+#include "DeviceConfig.hh"
+
+namespace plp {
+       class Store {
+               public:
+                       Store(std::string device_id, plp::Date *date_time);
+                       virtual ~Store();
+                       virtual plp::DataRange *get_sum(EnumSummaryPeriod period_type_param) = 0;
+                       virtual plp::DataRange *get_mean(EnumSummaryPeriod period_type_param) = 0;
+                       virtual plp::DataRange *get_delta(EnumSummaryPeriod period_type_param) = 0;
+                       virtual plp::DataRange *get_max(EnumSummaryPeriod period_type_param) = 0;
+                       virtual plp::DataRange *get_min(EnumSummaryPeriod period_type_param) = 0;
+               protected:
+                       std::string     device_id;
+                       plp::Date       *date;
+                       plp::DataRange  *store_data;
+                       plp::DataRange  *range_data;
+                       bool load(std::string fname_param);
+       };
+}
+
+#endif /* STORE_HH_ */
diff --git a/src/StoreCache.cc b/src/StoreCache.cc
new file mode 100644 (file)
index 0000000..6e19690
--- /dev/null
@@ -0,0 +1,852 @@
+/*
+ * StoreCache.cc
+ *
+ *  Created on: Jan 6, 2011
+ *      Author: lamikr
+ */
+#include <sstream>
+#include <fstream>
+
+#include "log.h"
+#include "Store.hh"
+#include "StoreCache.hh"
+#include "StoreDay.hh"
+#include "DeviceConfig.hh"
+#include "FileUtil.hh"
+
+using namespace std;
+using namespace plp;
+
+StoreCache::StoreCache(string device_id_param,
+       Date *date_time_param): Store(device_id_param, date_time_param) {
+}
+
+StoreCache::~StoreCache() {
+}
+
+string StoreCache::get_dir_name(string device_id_param,
+                               Date *date_time_param,
+                               EnumSummaryPeriod period_type_param,
+                               EnumSummaryCalculationType calc_type_param) {
+       string  ret_val;
+       char    buffer[30];
+       string  bd_name;
+
+       bd_name = DeviceConfig::get_base_dir_name();
+       bd_name = FileUtil::concat_paths(bd_name, CACHE_DIR_NAME);
+       bd_name = FileUtil::concat_paths(bd_name, device_id_param);
+       bd_name = FileUtil::concat_paths(bd_name, SUMMARY_PERIOD_NAMES_ARRAY[period_type_param]);
+       bd_name = FileUtil::concat_paths(bd_name, CALCULATION_TYPE_NAMES_ARRAY[calc_type_param]);
+       if (period_type_param == PERIOD_YEARLY) {
+               ret_val = bd_name;
+       }
+       else if (period_type_param == PERIOD_MONTHLY) {
+               snprintf(buffer, 30, "%d", date_time_param->year);
+               ret_val = bd_name + "/" + buffer;
+       }
+       else {
+               snprintf(buffer, 30, "%d/%02d", date_time_param->year, date_time_param->month);
+               ret_val = bd_name + "/" + buffer;
+       }
+       return ret_val;
+}
+
+string StoreCache::get_file_name(string device_id_param,
+                               Date *date_time_param,
+                               EnumSummaryPeriod period_type_param,
+                               EnumSummaryCalculationType calc_type_param) {
+       string  ret_val;
+       string  fname;
+       char    buffer[30];
+
+       if (period_type_param == PERIOD_YEARLY) {
+               snprintf(buffer, 30, "%d", date_time_param->year);
+       }
+       else if (period_type_param == PERIOD_MONTHLY) {
+               snprintf(buffer, 30, "%d-%02d",
+                       date_time_param->year,
+                       date_time_param->month);
+       }
+       else {
+               snprintf(buffer, 30, "%d-%02d-%02d",
+                       date_time_param->year,
+                       date_time_param->month,
+                       date_time_param->day);
+       }
+       fname   = buffer;
+       fname   = fname + DATAFILE_SUFFIX;
+       ret_val = get_dir_name(device_id_param, date_time_param, period_type_param, calc_type_param);
+       ret_val = FileUtil::concat_paths(ret_val, fname);
+       return ret_val;
+}
+
+plp::Date *StoreCache::get_scanning_limit_date(EnumSummaryPeriod period_type_param) {
+       Data    *cur_data;;
+       Date    *ret_val;
+
+       cur_data        = get_latest_data(date, device_id, period_type_param);
+       if (cur_data != NULL) {
+               ret_val = cur_data->get_date().clone();
+               ret_val->next_second();
+               delete(cur_data);
+               cur_data        = NULL;
+       }
+       else {
+               ret_val = date->clone();
+               if (period_type_param == PERIOD_YEARLY) {
+                       ret_val->next_year();
+               }
+               else {
+                       ret_val->next_month();
+               }
+       }
+       return ret_val;
+}
+
+DataRange *StoreCache::get_mean(EnumSummaryPeriod period_type_param) {
+       int             row_count;
+       DataRange       *ret_val;
+       Data            *dta;
+       string          fname;
+
+       ret_val = NULL;
+       fname   = get_file_name(device_id,
+                               date,
+                               period_type_param,
+                               MEAN);
+       if (store_data == NULL) {
+               if (access(fname.c_str(), R_OK) == 0) {
+                       load(fname);
+               }
+       }
+       if (store_data != NULL) {
+               row_count       = store_data->get_count();
+               if (row_count > 0) {
+                       ret_val = new DataRange();
+                       dta     = store_data->get(0);
+                       ret_val->add(dta);
+                       delete(dta);
+               }
+       }
+       if (ret_val == NULL) {
+               switch(period_type_param) {
+                       case PERIOD_YEARLY:
+                       case PERIOD_MONTHLY:
+                       {
+                                       Data            *cur_data;
+                                       Data            *res_data;
+                                       Date            *cur_date;
+                                       Date            *max_date;
+                                       int             ii;
+                                       int             cnt;
+                                       int             val_cnt;
+                                       DataRange       *dr;
+                                       Store           *store;
+
+                                       cur_date        = date->clone();
+                                       max_date        = get_scanning_limit_date(period_type_param);
+                                       cur_data        = NULL;
+                                       res_data        = NULL;
+                                       cnt             = 0;
+                                       while(cur_date->before(max_date)) {
+                                               if (period_type_param == PERIOD_YEARLY) {
+                                                       store   = new StoreCache(device_id, cur_date);
+                                                       dr      = store->get_mean(PERIOD_MONTHLY);
+                                               }
+                                               else {
+                                                       store   = new StoreDay(device_id, cur_date);
+                                                       dr      = store->get_mean(PERIOD_DAILY);
+                                               }
+                                               if (dr != NULL) {
+                                                       cur_data        = dr->get_first();
+                                                       if (cur_data != NULL) {
+                                                               cnt++;
+                                                               if (res_data == NULL) {
+                                                                       res_data        = cur_data;
+                                                                       val_cnt         = res_data->get_value_count();
+                                                               }
+                                                               else {
+                                                                       for (ii = 0; ii < val_cnt; ii++) {
+                                                                               res_data->value_arr[ii] = res_data->value_arr[ii] + cur_data->value_arr[ii];
+                                                                       }
+                                                                       delete(cur_data);
+                                                               }
+                                                       }
+                                                       delete(dr);
+                                               }
+                                               delete(store);
+                                               if (period_type_param == PERIOD_YEARLY) {
+                                                       cur_date->next_month();
+                                               }
+                                               else {
+                                                       cur_date->next_day();
+                                               }
+                                       }
+                                       if ((res_data != NULL) &&
+                                           (cnt > 0)) {
+                                               for (ii = 0; ii < val_cnt; ii++) {
+                                                       res_data->value_arr[ii] = res_data->value_arr[ii] / cnt;
+                                               }
+                                               ret_val = new DataRange(res_data);
+                                               save(fname, ret_val, 4);
+                                               delete(res_data);
+                                       }
+                                       delete(cur_date);
+                                       delete(max_date);
+                               }
+                               break;
+                       case PERIOD_DAILY:
+                       case PERIOD_HOURLY:
+                       case PERIOD_MINUTELY:
+                       case PERIOD_SECONDLY: {
+                                       StoreDay        *store;
+
+                                       store   = new StoreDay(device_id, date);
+                                       ret_val = store->get_mean(period_type_param);
+                                       if ((period_type_param != PERIOD_MINUTELY) ||
+                                           (period_type_param != PERIOD_SECONDLY)) {
+                                               // no need cache second or minute data
+                                               save(fname, ret_val, 4);
+                                       }
+                                       delete(store);
+                               }
+                               break;
+               }
+       }
+       return ret_val;
+}
+
+DataRange *StoreCache::get_sum(EnumSummaryPeriod period_type_param) {
+       int             row_count;
+       DataRange       *ret_val;
+       Data            *dta;
+       string          fname;
+       Store           *store;
+
+       ret_val = NULL;
+       fname   = get_file_name(device_id,
+                               date,
+                               period_type_param,
+                               SUM);
+       if (store_data == NULL) {
+               if (access(fname.c_str(), R_OK) == 0) {
+                       load(fname);
+               }
+       }
+       if (store_data != NULL) {
+               row_count       = store_data->get_count();
+               if (row_count > 0) {
+                       ret_val = new DataRange();
+                       dta     = store_data->get(0);
+                       ret_val->add(dta);
+                       delete(dta);
+               }
+       }
+       if (ret_val == NULL) {
+               switch(period_type_param) {
+                       case PERIOD_YEARLY:
+                       case PERIOD_MONTHLY: {
+                                       Data            *cur_data;
+                                       Data            *res_data;
+                                       Date            *cur_date;
+                                       Date            *max_date;
+                                       int             ii;
+                                       int             cnt;
+                                       int             val_cnt;
+                                       DataRange       *dr;
+
+                                       cur_date        = date->clone();
+                                       max_date        = get_scanning_limit_date(period_type_param);
+                                       cur_data        = NULL;
+                                       res_data        = NULL;
+                                       cnt             = 0;
+                                       while(cur_date->before(max_date)) {
+                                               if (period_type_param == PERIOD_YEARLY) {
+                                                       store   = new StoreCache(device_id, cur_date);
+                                                       dr      = store->get_sum(PERIOD_MONTHLY);
+                                               }
+                                               else {
+                                                       store   = new StoreDay(device_id, cur_date);
+                                                       dr      = store->get_sum(PERIOD_DAILY);
+                                               }
+                                               if (dr != NULL) {
+                                                       cur_data        = dr->get_first();
+                                                       if (cur_data != NULL) {
+                                                               cnt++;
+                                                               if (res_data == NULL) {
+                                                                       res_data        = cur_data;
+                                                               }
+                                                               else {
+                                                                       val_cnt = res_data->get_value_count();
+                                                                       for (ii = 0; ii < val_cnt; ii++) {
+                                                                               res_data->value_arr[ii] = res_data->value_arr[ii] + cur_data->value_arr[ii];
+                                                                       }
+                                                                       delete(cur_data);
+                                                               }
+                                                       }
+                                                       delete(dr);
+                                               }
+                                               delete(store);
+                                               if (period_type_param == PERIOD_YEARLY) {
+                                                       cur_date->next_month();
+                                               }
+                                               else {
+                                                       cur_date->next_day();
+                                               }
+                                       }
+                                       if ((res_data != NULL) &&
+                                           (cnt > 0)) {
+                                               ret_val = new DataRange(res_data);
+                                               save(fname, ret_val, 4);
+                                               delete(res_data);
+                                       }
+                                       delete(cur_date);
+                                       delete(max_date);
+                               }
+                               break;
+                       case PERIOD_DAILY:
+                       case PERIOD_HOURLY:
+                       case PERIOD_MINUTELY:
+                       case PERIOD_SECONDLY:
+                               store   = new StoreDay(device_id, date);
+                               ret_val = store->get_sum(period_type_param);
+                               if ((period_type_param != PERIOD_MINUTELY) ||
+                                   (period_type_param != PERIOD_SECONDLY)) {
+                                       // no need cache second or minute data
+                                       save(fname, ret_val, 4);
+                               }
+                               delete(store);
+                               break;
+               }
+       }
+       return ret_val;
+}
+
+DataRange *StoreCache::get_delta(EnumSummaryPeriod period_type_param) {
+       int             row_count;
+       DataRange       *ret_val;
+       Data            *dta;
+       string          fname;
+       StoreDay        *store;
+
+       ret_val = NULL;
+       fname   = get_file_name(device_id,
+                               date,
+                               period_type_param,
+                               DELTA);
+       if (store_data == NULL) {
+               if (access(fname.c_str(), R_OK) == 0) {
+                       // read from cache file
+                       load(fname);
+               }
+       }
+       if (store_data != NULL) {
+               row_count       = store_data->get_count();
+               if (row_count > 0) {
+                       ret_val = new DataRange();
+                       dta     = store_data->get(0);
+                       ret_val->add(dta);
+                       delete(dta);
+               }
+       }
+       if (ret_val == NULL) {
+               switch(period_type_param) {
+                       case PERIOD_YEARLY: {
+                                       Data    *first_data;
+                                       Data    *last_data;
+                                       int     ii;
+                                       int     cnt;
+
+                                       first_data      = get_oldest_data(date, device_id, PERIOD_YEARLY);
+                                       if (first_data != NULL) {
+                                               last_data       = get_latest_data(date, device_id, PERIOD_YEARLY);
+                                               if (last_data != NULL) {
+                                                       ret_val         = new DataRange();
+                                                       cnt             = last_data->get_value_count();
+                                                       for (ii = 0; ii < cnt; ii++) {
+                                                               last_data->value_arr[ii]        = last_data->value_arr[ii] - first_data->value_arr[ii];
+                                                       }
+                                                       ret_val->add(last_data);
+                                                       delete(last_data);
+                                               }
+                                               delete(first_data);
+                                               save(fname, ret_val, 4);
+                                       }
+                                       else {
+                                               log_error("Could not read first or last data item from device %s for year: %d", device_id.c_str(), date->year);
+                                       }
+                               }
+                               break;
+                       case PERIOD_MONTHLY: {
+                                       Data    *first_data;
+                                       Data    *last_data;
+                                       Data    *cur_data;
+                                       Date    *cur_date;
+                                       Date    *limit_date;
+                                       int     ii;
+                                       int     cnt;
+
+                                       cur_date        = date->clone();
+                                       limit_date      = date->clone();
+                                       limit_date->next_month();
+                                       first_data      = NULL;
+                                       last_data       = NULL;
+                                       while(cur_date->before(limit_date)) {
+                                               store   = new StoreDay(device_id, cur_date);
+                                               if (first_data == NULL) {
+                                                       cur_data        = store->get_oldest_data();
+                                                       if (cur_data != NULL) {
+                                                               first_data      = cur_data->clone();
+                                                               last_data       = cur_data->clone();
+                                                               delete(cur_data);
+                                                       }
+                                               }
+                                               cur_data        = store->get_latest_data();
+                                               if (cur_data != NULL) {
+                                                       if (last_data != NULL) {
+                                                               delete(last_data);
+                                                       }
+                                                       last_data       = cur_data;
+                                               }
+                                               delete(store);
+                                               cur_date->next_day();
+                                       }
+                                       delete(cur_date);
+                                       delete(limit_date);
+                                       if (first_data != NULL) {
+                                               if (last_data == NULL) {
+                                                       last_data       = first_data->clone();
+                                               }
+                                               cnt     = last_data->get_value_count();
+                                               for (ii = 0; ii < cnt; ii++) {
+                                                       last_data->value_arr[ii]        = last_data->value_arr[ii] - first_data->value_arr[ii];
+                                               }
+                                               cur_date        = first_data->get_date().clone();
+                                               last_data->set_date(cur_date);
+                                               delete(cur_date);
+                                               ret_val = new DataRange(last_data);
+                                               delete(first_data);
+                                               delete(last_data);
+                                               save(fname, ret_val, 4);
+                                       }
+                               }
+                               break;
+                       case PERIOD_DAILY:
+                       case PERIOD_HOURLY:
+                       case PERIOD_MINUTELY:
+                       case PERIOD_SECONDLY:
+                               store   = new StoreDay(device_id, date);
+                               ret_val = store->get_delta(period_type_param);
+                               if ((period_type_param != PERIOD_MINUTELY) ||
+                                   (period_type_param != PERIOD_SECONDLY)) {
+                                       // no need cache second or minute data
+                                       save(fname, ret_val, 4);
+                               }
+                               delete(store);
+                               break;
+               }
+       }
+       return ret_val;
+}
+
+DataRange *StoreCache::get_max(EnumSummaryPeriod period_type_param) {
+       int             row_count;
+       DataRange       *ret_val;
+       Data            *dta;
+       string          fname;
+       Store           *store;
+
+       ret_val = NULL;
+       fname   = get_file_name(device_id,
+                               date,
+                               period_type_param,
+                               MAX);
+       if (store_data == NULL) {
+               if (access(fname.c_str(), R_OK) == 0) {
+                       load(fname);
+               }
+       }
+       if (store_data != NULL) {
+               row_count       = store_data->get_count();
+               if (row_count > 0) {
+                       ret_val = new DataRange();
+                       dta     = store_data->get(0);
+                       ret_val->add(dta);
+                       delete(dta);
+               }
+       }
+       if (ret_val == NULL) {
+               switch(period_type_param) {
+                       case PERIOD_YEARLY:
+                       case PERIOD_MONTHLY: {
+                                       Data            *cur_data;
+                                       Data            *res_data;
+                                       Date            *cur_date;
+                                       Date            *max_date;
+                                       int             ii;
+                                       int             cnt;
+                                       int             val_cnt;
+                                       DataRange       *dr;
+
+                                       cur_date        = date->clone();
+                                       max_date        = get_scanning_limit_date(period_type_param);
+                                       cur_data        = NULL;
+                                       res_data        = NULL;
+                                       cnt             = 0;
+                                       while(cur_date->before(max_date)) {
+                                               if (period_type_param == PERIOD_YEARLY) {
+                                                       store   = new StoreCache(device_id, cur_date);
+                                                       dr      = store->get_max(PERIOD_MONTHLY);
+                                               }
+                                               else {
+                                                       store   = new StoreDay(device_id, cur_date);
+                                                       dr      = store->get_max(PERIOD_DAILY);
+                                               }
+                                               if (dr != NULL) {
+                                                       cur_data        = dr->get_first();
+                                                       if (cur_data != NULL) {
+                                                               cnt++;
+                                                               if (res_data == NULL) {
+                                                                       res_data        = cur_data;
+                                                               }
+                                                               else {
+                                                                       val_cnt = res_data->get_value_count();
+                                                                       int changed = 0;
+                                                                       for (ii = 0; ii < val_cnt; ii++) {
+                                                                               if (cur_data->value_arr[ii] > res_data->value_arr[ii]) {
+                                                                                       res_data->value_arr[ii] = cur_data->value_arr[ii];
+                                                                                       changed = 1;
+                                                                               }
+                                                                       }
+                                                                       if (changed == 1) {
+                                                                               Date new_date;
+
+                                                                               new_date        = cur_data->get_date();
+                                                                               res_data->set_date(&new_date);
+                                                                       }
+                                                                       delete(cur_data);
+                                                               }
+                                                       }
+                                                       delete(dr);
+                                               }
+                                               delete(store);
+                                               if (period_type_param == PERIOD_YEARLY) {
+                                                       cur_date->next_month();
+                                               }
+                                               else {
+                                                       cur_date->next_day();
+                                               }
+                                       }
+                                       if ((res_data != NULL) &&
+                                           (cnt > 0)) {
+                                               ret_val = new DataRange(res_data);
+                                               save(fname, ret_val, 4);
+                                               delete(res_data);
+                                       }
+                                       delete(cur_date);
+                                       delete(max_date);
+                               }
+                               break;
+                       case PERIOD_DAILY:
+                       case PERIOD_HOURLY:
+                       case PERIOD_MINUTELY:
+                       case PERIOD_SECONDLY:
+                               store   = new StoreDay(device_id, date);
+                               ret_val = store->get_max(period_type_param);
+                               if ((period_type_param != PERIOD_MINUTELY) ||
+                                   (period_type_param != PERIOD_SECONDLY)) {
+                                       // no need cache second or minute data
+                                       save(fname, ret_val, 4);
+                               }
+                               delete(store);
+                               break;
+               }
+       }
+       return ret_val;
+}
+
+DataRange *StoreCache::get_min(EnumSummaryPeriod period_type_param) {
+       int             row_count;
+       DataRange       *ret_val;
+       Data            *dta;
+       string          fname;
+       Store           *store;
+
+       ret_val = NULL;
+       fname   = get_file_name(device_id,
+                               date,
+                               period_type_param,
+                               MIN);
+       if (store_data == NULL) {
+               if (access(fname.c_str(), R_OK) == 0) {
+                       load(fname);
+               }
+       }
+       if (store_data != NULL) {
+               row_count       = store_data->get_count();
+               if (row_count > 0) {
+                       ret_val = new DataRange();
+                       dta     = store_data->get(0);
+                       ret_val->add(dta);
+                       delete(dta);
+               }
+       }
+       if (ret_val == NULL) {
+               switch(period_type_param) {
+                       case PERIOD_YEARLY:
+                       case PERIOD_MONTHLY: {
+                                       Data            *cur_data;
+                                       Data            *res_data;
+                                       Date            *cur_date;
+                                       Date            *max_date;
+                                       int             ii;
+                                       int             cnt;
+                                       int             val_cnt;
+                                       DataRange       *dr;
+
+                                       cur_date        = date->clone();
+                                       max_date        = get_scanning_limit_date(period_type_param);
+                                       cur_data        = NULL;
+                                       res_data        = NULL;
+                                       cnt             = 0;
+                                       while(cur_date->before(max_date)) {
+                                               if (period_type_param == PERIOD_YEARLY) {
+                                                       store   = new StoreCache(device_id, cur_date);
+                                                       dr      = store->get_min(PERIOD_MONTHLY);
+                                               }
+                                               else {
+                                                       store   = new StoreDay(device_id, cur_date);
+                                                       dr      = store->get_min(PERIOD_DAILY);
+                                               }
+                                               if (dr != NULL) {
+                                                       cur_data        = dr->get_first();
+                                                       if (cur_data != NULL) {
+                                                               cnt++;
+                                                               if (res_data == NULL) {
+                                                                       res_data        = cur_data;
+                                                               }
+                                                               else {
+                                                                       val_cnt = res_data->get_value_count();
+                                                                       int changed = 0;
+                                                                       for (ii = 0; ii < val_cnt; ii++) {
+                                                                               if (cur_data->value_arr[ii] < res_data->value_arr[ii]) {
+                                                                                       res_data->value_arr[ii] = cur_data->value_arr[ii];
+                                                                                       changed = 1;
+                                                                               }
+                                                                       }
+                                                                       if (changed == 1) {
+                                                                               Date new_date;
+
+                                                                               new_date        = cur_data->get_date();
+                                                                               res_data->set_date(&new_date);
+                                                                       }
+                                                                       delete(cur_data);
+                                                               }
+                                                       }
+                                                       delete(dr);
+                                               }
+                                               delete(store);
+                                               if (period_type_param == PERIOD_YEARLY) {
+                                                       cur_date->next_month();
+                                               }
+                                               else {
+                                                       cur_date->next_day();
+                                               }
+                                       }
+                                       if ((res_data != NULL) &&
+                                           (cnt > 0)) {
+                                               ret_val = new DataRange(res_data);
+                                               save(fname, ret_val, 4);
+                                               delete(res_data);
+                                       }
+                                       delete(cur_date);
+                                       delete(max_date);
+                               }
+                               break;
+                       case PERIOD_DAILY:
+                       case PERIOD_HOURLY:
+                       case PERIOD_MINUTELY:
+                       case PERIOD_SECONDLY:
+                               store   = new StoreDay(device_id, date);
+                               ret_val = store->get_min(period_type_param);
+                               if ((period_type_param != PERIOD_MINUTELY) ||
+                                   (period_type_param != PERIOD_SECONDLY)) {
+                                       // no need cache second or minute data
+                                       save(fname, ret_val, 4);
+                               }
+                               delete(store);
+                               break;
+               }
+       }
+       return ret_val;
+}
+
+void StoreCache::save(std::string fname_param, plp::DataRange *datarange_param, int decimal_count_param) {
+       string          line;
+       Data            *data;
+       ofstream        *ostream;
+       int             ii;
+       int             cnt;
+
+       cnt     = datarange_param->get_count();
+       ostream =  NULL;
+       //log_info("[%s] cacheing %d data values.\n", device_id.c_str(), cnt);
+       ostream = FileUtil::open_for_writing(fname_param.c_str());
+       if ((ostream != NULL) &&
+           (ostream->is_open() == true)) {
+               // TODO: add mutex to protect string_list while it's read and emptied
+               for(ii = 0; ii < cnt; ii++) {
+                       data    = datarange_param->get(ii);
+                       if (data != NULL) {
+                               line    = data->to_string(decimal_count_param);
+                               if (line.length() > 0) {
+                                       *ostream << line << endl;
+                               }
+                               delete(data);
+                       }
+               }
+       }
+       else {
+               log_error("[%s] File open for data save failed: %s\n", device_id.c_str(), fname_param.c_str());
+       }
+       if (ostream != NULL) {
+               ostream->close();
+               delete(ostream);
+       }
+}
+
+Data *StoreCache::get_oldest_data(Date *date_param, string device_id_param, EnumSummaryPeriod period_type_param) {
+       int             size;
+       unsigned int    ii;
+       string          year_dr;
+       string          mon_dr;
+       vector<string>  mon_vcr;
+       vector<string>  dta_vcr;
+       string          f_name;
+       StoreDay        *store;
+       Data            *ret_val;
+       string          device_dir;
+       char            buffer[30];
+       string          year_name;
+
+       ret_val = NULL;
+       if (period_type_param == PERIOD_YEARLY) {
+               snprintf(buffer, 30, "%d", date_param->year);
+               year_name.append(buffer);
+               device_dir      = DeviceConfig::get_base_dir_name();
+               device_dir      = FileUtil::concat_paths(device_dir, device_id_param);
+               year_dr = FileUtil::concat_paths(device_dir, year_name);
+               mon_vcr = FileUtil::get_subdirectories(year_dr);
+               for (ii = 0; ii < mon_vcr.size(); ii++) {
+                       mon_dr  = mon_vcr.at(ii);
+                       mon_dr  = FileUtil::concat_paths(year_dr, mon_dr);
+                       // scan data files from month dir
+                       dta_vcr = FileUtil::get_data_files(mon_dr);
+                       size    = dta_vcr.size();
+                       if (size > 0) {
+                               f_name  = dta_vcr.at(0);
+                               f_name  = FileUtil::concat_paths(mon_dr, f_name);
+                               store   = new StoreDay(f_name);
+                               ret_val = store->get_oldest_data();
+                               delete(store);
+                               break;
+                       }
+               }
+       }
+       else if (period_type_param == PERIOD_MONTHLY) {
+               ret_val         = NULL;
+               snprintf(buffer, 30, "%d", date_param->year);
+               year_name.append(buffer);
+               device_dir      = DeviceConfig::get_base_dir_name();
+               device_dir      = FileUtil::concat_paths(device_dir, device_id_param);
+               year_dr         = FileUtil::concat_paths(device_dir, year_name);
+               snprintf(buffer, 30, "%02d", date_param->month);
+               mon_dr.append(buffer);
+               mon_dr          = FileUtil::concat_paths(year_dr, mon_dr);
+               // scan data files from month dir
+               dta_vcr         = FileUtil::get_data_files(mon_dr);
+               size            = dta_vcr.size();
+               if (size > 0) {
+                       f_name  = dta_vcr.at(0);
+                       f_name  = FileUtil::concat_paths(mon_dr, f_name);
+                       store   = new StoreDay(f_name);
+                       ret_val = store->get_oldest_data();
+                       delete(store);
+               }
+
+       }
+       else {
+               store   = new StoreDay(device_id_param, date_param);
+               ret_val = store->get_oldest_data();
+               delete(store);
+       }
+       return ret_val;
+}
+
+Data *StoreCache::get_latest_data(Date *date_param, string device_id_param, EnumSummaryPeriod period_type_param) {
+       int             ii;
+       string          mon_dr;
+       vector<string>  mon_vcr;
+       vector<string>  dta_vcr;
+       string          f_name;
+       StoreDay        *store;
+       Data            *ret_val;
+       string          year_dr;
+       int             size;
+       string          device_dir;
+       char            buffer[30];
+       string          year_name;
+
+       ret_val = NULL;
+       if (period_type_param == PERIOD_YEARLY) {
+               snprintf(buffer, 30, "%d", date_param->year);
+               year_name.append(buffer);
+               device_dir      = DeviceConfig::get_base_dir_name();
+               device_dir      = FileUtil::concat_paths(device_dir, device_id_param);
+               year_dr = FileUtil::concat_paths(device_dir, year_name);
+               mon_vcr = FileUtil::get_subdirectories(year_dr);
+               for (ii = mon_vcr.size() - 1; ii >= 0; ii--) {
+                       mon_dr  = mon_vcr.at(ii);
+                       mon_dr  = FileUtil::concat_paths(year_dr, mon_dr);
+                       // scan data files from month dir
+                       dta_vcr = FileUtil::get_data_files(mon_dr);
+                       size    = dta_vcr.size();
+                       if (size > 0) {
+                               f_name  = dta_vcr.at(size - 1);
+                               f_name  = FileUtil::concat_paths(mon_dr, f_name);
+                               store   = new StoreDay(f_name);
+                               ret_val = store->get_latest_data();
+                               delete(store);
+                               break;
+                       }
+               }
+       }
+       else if (period_type_param == PERIOD_MONTHLY) {
+               ret_val         = NULL;
+               snprintf(buffer, 30, "%d", date_param->year);
+               year_name.append(buffer);
+               device_dir      = DeviceConfig::get_base_dir_name();
+               device_dir      = FileUtil::concat_paths(device_dir, device_id_param);
+               year_dr         = FileUtil::concat_paths(device_dir, year_name);
+               snprintf(buffer, 30, "%02d", date_param->month);
+               mon_dr.append(buffer);
+               mon_dr          = FileUtil::concat_paths(year_dr, mon_dr);
+               // scan data files from month dir
+               dta_vcr         = FileUtil::get_data_files(mon_dr);
+               size            = dta_vcr.size();
+               if (size > 0) {
+                       f_name  = dta_vcr.at(size - 1);
+                       f_name  = FileUtil::concat_paths(mon_dr, f_name);
+                       store   = new StoreDay(f_name);
+                       ret_val = store->get_latest_data();
+                       delete(store);
+               }
+
+       }
+       else {
+               store   = new StoreDay(device_id_param, date_param);
+               ret_val = store->get_latest_data();
+               delete(store);
+       }
+       return ret_val;
+}
diff --git a/src/StoreCache.hh b/src/StoreCache.hh
new file mode 100644 (file)
index 0000000..4be7b1f
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * StoreCache.hh
+ *
+ *  Created on: Jan 6, 2011
+ *      Author: lamikr
+ */
+
+#ifndef STORECACHE_HH_
+#define STORECACHE_HH_
+
+#include <vector>
+#include <list>
+
+#include "Data.hh"
+#include "Date.hh"
+#include "Store.hh"
+
+namespace plp {
+       class StoreCache: public plp::Store {
+               public:
+                       StoreCache(std::string device_id_param,
+                               plp::Date *date_time_param);
+                       virtual ~StoreCache();
+                       plp::DataRange *get_sum(EnumSummaryPeriod period_type_param);
+                       plp::DataRange *get_mean(EnumSummaryPeriod period_type_param);
+                       plp::DataRange *get_delta(EnumSummaryPeriod period_type_param);
+                       plp::DataRange *get_max(EnumSummaryPeriod period_type_param);
+                       plp::DataRange *get_min(EnumSummaryPeriod period_type_param);
+                       static plp::Data *get_oldest_data(plp::Date *date_param, std::string device_id_param, EnumSummaryPeriod period_type_param);
+                       static plp::Data *get_latest_data(plp::Date *date_param, std::string device_id_param, EnumSummaryPeriod period_type_param);
+               protected:
+                       static std::string get_dir_name(std::string device_id_param,
+                                               Date *date_time_param,
+                                               EnumSummaryPeriod period_type_param,
+                                               EnumSummaryCalculationType calc_type_param);
+                       static std::string get_file_name(std::string device_id_param,
+                                               Date *date_time_param,
+                                               EnumSummaryPeriod period_type_param,
+                                               EnumSummaryCalculationType calc_type_param);
+                       void save(std::string fname_param, plp::DataRange *datarange_param, int decimal_count_param);
+               private:
+                       plp::Date *get_scanning_limit_date(EnumSummaryPeriod period_type_param);
+       };
+}
+
+#endif /* STORECACHE_HH_ */
diff --git a/src/StoreDay.cc b/src/StoreDay.cc
new file mode 100644 (file)
index 0000000..08e56c9
--- /dev/null
@@ -0,0 +1,604 @@
+/*
+ * Store.cc
+ *
+ *  Created on: Oct 31, 2010
+ *      Author: lamikr
+ */
+
+#include <list>
+#include <string>
+#include <fstream>
+#include <limits>
+
+#include <time.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "log.h"
+#include "DeviceConfig.hh"
+#include "StoreDay.hh"
+#include "FileUtil.hh"
+
+using namespace std;
+using namespace plp;
+
+StoreDay::StoreDay(string device_id_param,
+               Date *date_time_param): Store(device_id_param, date_time_param) {
+       store_fname     = get_file_name(device_id_param, date_time_param);
+}
+
+StoreDay::StoreDay(string fname_param): Store("", NULL) {
+       store_data      = NULL;
+       range_data      = NULL;
+       store_fname     = fname_param;
+}
+
+StoreDay::~StoreDay() {
+       if (store_data != NULL) {
+               delete(store_data);
+               store_data      = NULL;
+       }
+}
+
+string StoreDay::get_dir_name(string device_id, Date *date_time_param) {
+       string  ret_val;
+       char    buffer[30];
+       string  bd_name;
+
+       snprintf(buffer, 30, "%d/%02d", date_time_param->year, date_time_param->month);
+       bd_name = DeviceConfig::get_base_dir_name();
+       bd_name = FileUtil::concat_paths(bd_name, device_id);
+       ret_val = bd_name + "/" + buffer;
+       return ret_val;
+}
+
+string StoreDay::get_file_name(string device_id, Date *date_time_param) {
+       string  ret_val;
+       string  fname;
+       char    buffer[30];
+
+       snprintf(buffer, 30, "%d-%02d-%02d", date_time_param->year, date_time_param->month, date_time_param->day);
+       fname   = buffer;
+       fname   = fname + DATAFILE_SUFFIX;
+       ret_val = get_dir_name(device_id, date_time_param);
+       ret_val = FileUtil::concat_paths(ret_val, fname);
+       return ret_val;
+}
+
+void StoreDay::save(string device_id,
+               std::list<Data *> *data_list,
+               int dec_precision) {
+       string                  n_path;
+       string                  f_path;
+       string                  line;
+       Data                    *data;
+       ofstream                *ostream;
+       Date                    date;
+       list<Data *>::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
+       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 = FileUtil::open_for_writing(f_path.c_str());
+               }
+               if ((ostream != NULL) &&
+                   (ostream->is_open() == true)) {
+                       line    = data->to_string(dec_precision);
+                       if (line.length() > 0) {
+                               log_debug("storing line: %s\n", line.c_str());
+                               *ostream << line << endl;
+                       }
+               }
+               else {
+                       log_error("[%s] File open for data save failed: %s\n", device_id.c_str(), f_path.c_str());
+               }
+       }
+       if (ostream != NULL) {
+               ostream->close();
+               delete(ostream);
+       }
+}
+
+bool StoreDay::load() {
+       return Store::load(store_fname);
+}
+
+bool StoreDay::exist(string fname_param) {
+       bool    ret_val;
+       ret_val = (access(fname_param.c_str(), F_OK) == 0);
+       return ret_val;
+}
+
+bool StoreDay::exist() {
+       return exist(store_fname);
+}
+
+static int get_summary_period_as_freq_seconds(EnumSummaryPeriod period_type_param) {
+       int     ret_val;
+
+       ret_val = 3600;
+       switch(period_type_param) {
+               case PERIOD_SECONDLY:
+                       ret_val = 1;
+                       break;
+               case PERIOD_MINUTELY:
+                       ret_val = 60;
+                       break;
+               case PERIOD_HOURLY:
+                       ret_val = 3600;
+                       break;
+               case PERIOD_DAILY:
+               case PERIOD_MONTHLY:
+               case PERIOD_YEARLY:
+               default:
+                       // -1 as freq means that show all data from the current store
+                       ret_val = -1;
+                       break;
+       }
+       return ret_val;
+}
+
+plp::DataRange *StoreDay::get_sum(EnumSummaryPeriod period_type_param) {
+       int             row_count;
+       int             col_count;
+       int             jj;
+       int             ii;
+       Data            *data;
+       Data            *calc;
+       Date            *limit_d;
+       Date            date;
+       DataRange       *ret_val;
+       int             frq_sec;
+
+       ret_val = new DataRange();
+       calc    = NULL;
+       limit_d = NULL;
+       frq_sec = get_summary_period_as_freq_seconds(period_type_param);
+       if (store_data == NULL) {
+               load();
+       }
+       if (store_data != NULL) {
+               row_count       = store_data->get_count();
+               if (row_count > 0) {
+                       col_count       = store_data->get_data_item_value_count();
+                       if (col_count > 0) {
+                               for (ii = 0; ii < row_count; ii++) {
+                                       data    = store_data->get(ii);
+                                       if (data != NULL) {
+                                               if (calc == NULL) {
+                                                       calc            = data->clone();
+                                                       limit_d         = data->get_date().clone();
+                                                       limit_d->min    = 0;
+                                                       limit_d->sec    = 0;
+                                                       limit_d->inc_seconds(frq_sec);
+                                               }
+                                               else {
+                                                       date    = data->get_date();
+                                                       if ((ii <= (row_count -1)) &&
+                                                           ((frq_sec == -1) || (date.before(limit_d)))) {
+                                                               for (jj = 0; jj < col_count; jj++) {
+                                                                       calc->value_arr[jj]     = calc->value_arr[jj] + data->value_arr[jj];
+                                                               }
+                                                       }
+                                                       if ((ii >= (row_count -1)) ||
+                                                           ((frq_sec != -1) && (date.before(limit_d) == false))) {
+                                                               ret_val->add(calc);
+                                                               delete(calc);
+                                                               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(frq_sec);
+                                                       }
+                                               }
+                                               delete(data);
+                                       }
+                               }
+                               if (calc != NULL) {
+                                       delete(calc);
+                                       calc    = NULL;
+                               }
+                               if (limit_d != NULL) {
+                                       delete(limit_d);
+                               }
+                       }
+               }
+       }
+       return ret_val;
+}
+
+plp::DataRange *StoreDay::get_mean(EnumSummaryPeriod period_type_param) {
+       int             row_count;
+       int             col_count;
+       int             d_count;
+       int             jj;
+       int             ii;
+       Data            *data;
+       Data            *calc;
+       Date            *limit_d;
+       Date            date;
+       DataRange       *ret_val;
+       int             frq_sec;
+
+       ret_val = new DataRange();
+       calc    = NULL;
+       limit_d = NULL;
+       d_count = 1;
+       frq_sec = get_summary_period_as_freq_seconds(period_type_param);
+       if (store_data == NULL) {
+               load();
+       }
+       if (store_data != NULL) {
+               row_count       = store_data->get_count();
+               if (row_count > 0) {
+                       col_count       = store_data->get_data_item_value_count();
+                       if (col_count > 0) {
+                               for (ii = 0; ii < row_count; ii++) {
+                                       data    = store_data->get(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(frq_sec);
+                                               }
+                                               else {
+                                                       date    = data->get_date();
+                                                       if ((ii <= (row_count -1)) &&
+                                                           ((frq_sec == -1) || (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++;
+                                                       }
+                                                       if ((ii >= (row_count -1)) ||
+                                                           ((frq_sec != -1) && (date.before(limit_d) == false))) {
+                                                               for (jj = 0; jj < col_count; jj++) {
+                                                                       calc->value_arr[jj]     = calc->value_arr[jj] / d_count;
+                                                               }
+                                                               ret_val->add(calc);
+                                                               delete(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(frq_sec);
+                                                       }
+                                               }
+                                               delete(data);
+                                       }
+                               }
+                               if (calc != NULL) {
+                                       delete(calc);
+                                       calc    = NULL;
+                               }
+                               if (limit_d != NULL) {
+                                       delete(limit_d);
+                               }
+                       }
+               }
+       }
+       return ret_val;
+}
+
+plp::DataRange *StoreDay::get_delta(EnumSummaryPeriod period_type_param) {
+       int             row_count;
+       int             col_count;
+       int             jj;
+       int             ii;
+       Data            *data;
+       Data            *calc1;
+       Data            *calc2;
+       Date            *limit_d;
+       Date            date;
+       DataRange       *ret_val;
+       int             frq_sec;
+
+       ret_val = new DataRange();
+       calc1   = NULL;
+       calc2   = NULL;
+       limit_d = NULL;
+       frq_sec = get_summary_period_as_freq_seconds(period_type_param);
+       if (store_data == NULL) {
+               load();
+       }
+       if (store_data != NULL) {
+               row_count       = store_data->get_count();
+               if (row_count > 0) {
+                       col_count       = store_data->get_data_item_value_count();
+                       if (col_count > 0) {
+                               for (ii = 0; ii < row_count; ii++) {
+                                       data    = store_data->get(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(frq_sec);
+                                                       if (calc2 != NULL) {
+                                                               delete(calc2);
+                                                       }
+                                                       calc2           = NULL;
+                                               }
+                                               else {
+                                                       date    = data->get_date();
+                                                       if ((ii <= (row_count -1)) &&
+                                                           ((frq_sec == -1) || (date.before(limit_d)))) {
+                                                               if (calc2 != NULL) {
+                                                                       delete(calc2);
+                                                               }
+                                                               calc2   = data->clone();
+                                                       }
+                                                       if ((ii >= (row_count -1)) ||
+                                                           ((frq_sec != -1) && (date.before(limit_d) == false))) {
+                                                               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->add(calc2);
+                                                               delete(calc1);
+                                                               calc1   = data->clone();
+                                                               delete(calc2);
+                                                               calc2   = NULL;
+                                                               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(frq_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;
+}
+
+plp::DataRange *StoreDay::get_max_or_min(EnumSummaryPeriod period_type_param, bool max) {
+       int             row_count;
+       int             col_count;
+       int             jj;
+       int             ii;
+       Data            *data;
+       Data            *calc;
+       Date            *limit_d;
+       Date            date;
+       DataRange       *ret_val;
+       int             frq_sec;
+
+       ret_val = new DataRange();
+       calc    = NULL;
+       limit_d = NULL;
+       frq_sec = get_summary_period_as_freq_seconds(period_type_param);
+       if (store_data == NULL) {
+               load();
+       }
+       if (store_data != NULL) {
+               row_count       = store_data->get_count();
+               if (row_count > 0) {
+                       col_count       = store_data->get_data_item_value_count();
+                       if (col_count > 0) {
+                               for (ii = 0; ii < row_count; ii++) {
+                                       data    = store_data->get(ii);
+                                       if (data != NULL) {
+                                               if (calc == NULL) {
+                                                       calc            = data->clone();
+                                                       limit_d         = data->get_date().clone();
+                                                       limit_d->min    = 0;
+                                                       limit_d->sec    = 0;
+                                                       limit_d->inc_seconds(frq_sec);
+                                               }
+                                               else {
+                                                       date    = data->get_date();
+                                                       if ((ii <= (row_count -1)) &&
+                                                           ((frq_sec == -1) || (date.before(limit_d)))) {
+                                                               int changed = 0;
+                                                               if (max == true) {
+                                                                       for (jj = 0; jj < col_count; jj++) {
+                                                                               if (calc->value_arr[jj] < data->value_arr[jj]) {
+                                                                                       calc->value_arr[jj]     = data->value_arr[jj];
+                                                                                       changed = 1;
+                                                                               }
+                                                                       }
+                                                               }
+                                                               else {
+                                                                       for (jj = 0; jj < col_count; jj++) {
+                                                                               if (data->value_arr[jj] < calc->value_arr[jj]) {
+                                                                                       calc->value_arr[jj]     = data->value_arr[jj];
+                                                                                       changed = 1;
+                                                                               }
+                                                                       }
+                                                               }
+                                                               if (changed == 1) {
+                                                                       Date new_date;
+
+                                                                       new_date        = data->get_date();
+                                                                       calc->set_date(&new_date);
+                                                               }
+                                                       }
+                                                       if ((ii >= (row_count -1)) ||
+                                                           ((frq_sec != -1) && (date.before(limit_d) == false))) {
+                                                               ret_val->add(calc);
+                                                               delete(calc);
+                                                               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(frq_sec);
+                                                       }
+                                               }
+                                               delete(data);
+                                       }
+                               }
+                               if (calc != NULL) {
+                                       delete(calc);
+                                       calc    = NULL;
+                               }
+                               if (limit_d != NULL) {
+                                       delete(limit_d);
+                               }
+                       }
+               }
+       }
+       return ret_val;
+}
+
+plp::DataRange *StoreDay::get_max(EnumSummaryPeriod period_type_param) {
+       DataRange       *ret_val;
+
+       ret_val = get_max_or_min(period_type_param, true);
+       return ret_val;
+}
+
+plp::DataRange *StoreDay::get_min(EnumSummaryPeriod period_type_param) {
+       DataRange       *ret_val;
+
+       ret_val = get_max_or_min(period_type_param, false);
+       return ret_val;
+}
+
+DataRange *StoreDay::get_oldest_and_latest_data(string fname_param) {
+       DataRange       *ret_val;
+       ifstream        in;
+       Data            *o_data;
+       Data            *n_data;
+       string          latest;
+       int             row_count;
+       string          line;
+       string          prev_line;
+
+       ret_val = NULL;
+       o_data  = NULL;
+       n_data  = NULL;
+       if (store_data != NULL) {
+               row_count       = store_data->get_count();
+               if (row_count > 0) {
+                       o_data  = store_data->get(0);
+                       n_data  = store_data->get(row_count - 1);
+               }
+       }
+       else {
+               if (range_data != NULL) {
+                       row_count       = range_data->get_count();
+                       if (row_count > 0) {
+                               o_data  = range_data->get(0);
+                               n_data  = range_data->get(row_count - 1);
+                       }
+               }
+               else {
+                       in.open(fname_param.c_str());
+                       if (in.is_open() == true) {
+                               while (in.eof() == false) {
+                                       getline(in, line);
+                                       if (line.empty() == false) {
+                                               if (o_data == NULL) {
+                                                       o_data  = Data::parse_string(line);
+                                               }
+                                               prev_line       = line;
+                                       }
+                               }
+                               if (prev_line.empty() == false) {
+                                       n_data  = Data::parse_string(prev_line);
+                               }
+                       }
+               }
+       }
+       if ((o_data != NULL) &&
+           (n_data != NULL)) {
+               ret_val = new DataRange(o_data);
+               ret_val->add(n_data);
+               if (range_data != NULL) {
+                       range_data      = new DataRange(o_data);
+                       range_data->add(n_data);
+               }
+       }
+       if (o_data != NULL) {
+               delete(o_data);
+       }
+       if (n_data != NULL) {
+               delete(n_data);
+       }
+       return ret_val;
+}
+
+DataRange *StoreDay::get_oldest_and_latest_data() {
+       return get_oldest_and_latest_data(store_fname);
+}
+
+Data *StoreDay::get_oldest_data() {
+       int             row_count;
+       Data            *ret_val;
+       DataRange       *dr;
+
+       ret_val = NULL;
+       dr      = get_oldest_and_latest_data();
+       if (dr != NULL) {
+               row_count       = dr->get_count();
+               if (row_count >= 1) {
+                       ret_val = dr->get(0);
+               }
+               delete(dr);
+       }
+       return ret_val;
+}
+
+Data *StoreDay::get_latest_data() {
+       int             row_count;
+       Data            *ret_val;
+       DataRange       *dr;
+
+       ret_val = NULL;
+       dr      = get_oldest_and_latest_data();
+       if (dr != NULL) {
+               row_count       = dr->get_count();
+               if (row_count == 2) {
+                       ret_val = dr->get(1);
+               }
+               delete(dr);
+       }
+       return ret_val;
+}
diff --git a/src/StoreDay.hh b/src/StoreDay.hh
new file mode 100644 (file)
index 0000000..1b416e5
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Store.hh
+ *
+ *  Created on: Oct 31, 2010
+ *      Author: lamikr
+ */
+
+#ifndef W1STORE_HH_
+#define W1STORE_HH_
+
+#include <string>
+#include <list>
+#include <vector>
+
+#include <stdbool.h>
+
+#include "Data.hh"
+#include "Date.hh"
+#include "Store.hh"
+
+namespace plp {
+       class StoreDay: public plp::Store {
+               public:
+                       StoreDay(std::string device_id_param,
+                               plp::Date *date_time_param);
+                       StoreDay(std::string file_name_param);
+                       virtual ~StoreDay();
+                       static void save(std::string device_id, std::list<plp::Data *> *data_list, int dec_precision);
+                       plp::DataRange *get_sum(EnumSummaryPeriod period_type_param);
+                       plp::DataRange *get_mean(EnumSummaryPeriod period_type_param);
+                       plp::DataRange *get_delta(EnumSummaryPeriod period_type_param);
+                       plp::DataRange *get_max(EnumSummaryPeriod period_type_param);
+                       plp::DataRange *get_min(EnumSummaryPeriod period_type_param);
+                       plp::Data *get_oldest_data();
+                       plp::Data *get_latest_data();
+                       plp::DataRange *get_oldest_and_latest_data();
+                       /*
+                        * Checks whether store file exist.
+                        */
+                       bool exist();
+               protected:
+                       std::string     store_fname;
+                       bool load();
+                       plp::DataRange *get_max_or_min(EnumSummaryPeriod period_type_param, bool max);
+                       static std::string get_dir_name(std::string device_id,
+                                                       plp::Date *date_time_param);
+                       static std::string get_file_name(std::string device_id,
+                                                       plp::Date *date_time_param);
+                       plp::DataRange *get_oldest_and_latest_data(std::string fname_param);
+                       bool exist(std::string fname_param);
+       };
+}
+
+#endif /* W1STORE_HH_ */
index 1baf3c5eb576546554f023f50b17b38729d800dc..bee4062801bddeafa59fa53746ba8c43a7cb7f5f 100644 (file)
@@ -11,7 +11,8 @@
 enum
 {
        PLP_OK = 0,
-       PLP_ERR_UNKNOWN,
+       PLP_ERR,
+       PLP_ERR_DATA_NOT_FOUND,
        C_ERR_MEMORY,
        PLP_ERR_IO
 };