--- /dev/null
+/*
+ * 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;
+}