]> pilppa.org Git - lib1wire.git/blob - src/W1Device.cc
load deviceconfig only once
[lib1wire.git] / src / W1Device.cc
1 /*
2  * W1Device.cc
3  *
4  *  Created on: Oct 20, 2010
5  *      Author: lamikr
6  */
7 #include <iostream>
8 #include <fstream>
9 #include <sstream>
10 #include <iomanip>
11
12 #include <time.h>
13 #include <plp/log.h>
14
15 #include <plp/DeviceConfig.hh>
16 #include <plp/StoreDay.hh>
17
18 #include "Factory.hh"
19 #include "W1Device.hh"
20
21 using namespace std;
22 using namespace w1;
23 using namespace plp;
24
25 W1Device::W1Device(string device_id_param,
26                 string device_type_param,
27                 dirent *direntry_param) : SensorDevice(device_id_param, device_type_param) {
28         string rootdir;
29         string device_dir;
30         string temp_str;
31
32         pthread_mutex_init(&plock, NULL);
33         type    = device_type_param;
34         id      = device_id_param;
35         if (direntry_param != NULL) {
36                 rootdir                 = W1_SCAN_ROOTDIR;
37                 temp_str                = W1_SLAVE_FILE;
38                 dir_path                = rootdir + "/" + direntry_param->d_name;
39                 slave_file              = dir_path + "/" + temp_str;
40                 lifecycle_status        = LIFECYCLE_STATUS__AVAILABLE;
41                 log_debug("1-wire device's data file: %s\n", slave_file.c_str());
42         }
43         else {
44                 lifecycle_status        = LIFECYCLE_STATUS__UNAVAILABLE;
45         }
46         reader  = new DataReader(id);
47         name    = "";
48         _cfg    = NULL;
49 }
50
51 W1Device::~W1Device() {
52         log_debug("started\n");
53         save_and_clean_cache();
54         if (reader != NULL) {
55                 delete(reader);
56                 reader  = NULL;
57         }
58 }
59
60 string Device::get_name() {
61         if (name.empty() == true) {
62                 if (_cfg == NULL) {
63                         _cfg    = DeviceConfig::get_device_config(id);
64                 }
65                 if (_cfg != NULL) {
66                         _cfg->get_config_value(DEVICE_CONFIG_VALUE_KEY__NAME, name);
67                 }
68         }
69         return name;
70 }
71
72 void Device::set_name(string name_param) {
73         if (name.compare(name_param) != 0) {
74                 name    = name_param;
75                 if (_cfg == NULL) {
76                         _cfg    = DeviceConfig::get_device_config(id);
77                 }
78                 if (_cfg != NULL) {
79                         _cfg->set_config_value(DEVICE_CONFIG_VALUE_KEY__NAME, name_param, true);
80                 }
81         }
82 }
83
84 void W1Device::printout() {
85         Data    *data;
86         string  text;
87         string  type;
88         string  name;
89
90         data    = get_data();
91         if (data != NULL) {
92                 text    = data->to_string();
93                 cout << text << endl;
94                 delete(data);
95         }
96         else {
97                 type    = get_type();
98                 name    = get_name();
99                 log_error("Could not read data for %s device: %s\n", type.c_str(), name.c_str());
100         }
101 }
102
103 string W1Device::to_string(double dbl_val, int digit_count) {
104         string          ret_val;
105         ostringstream   out;
106
107         out << fixed << setprecision(digit_count) << dbl_val;
108         ret_val = out.str();
109         return ret_val;
110 }
111
112 Data *W1Device::get_data() {
113         Data            *ret_val;
114         vector<double>  *vect;
115
116         ret_val = NULL;
117         vect    = get_raw_data();
118         if (vect != NULL) {
119                 ret_val = new Data(vect, get_unit());
120                 cache(ret_val);
121                 delete(vect);
122                 log_debug("%s returning new data\n", id.c_str());
123         }
124         else {
125                 // read old already saved data
126                 log_debug("%s returning old saved data\n", id.c_str());
127                 ret_val = reader->get_latest_data();
128         }
129         return ret_val;
130 }
131
132 void W1Device::cache(Data *new_data) {
133         Data    *data;
134         int     dec_precision;
135
136         data    = new_data->clone();
137         pthread_mutex_lock(&plock);
138         memory_cache.push_back(data);
139         if (memory_cache.size() > 5) {
140                 dec_precision   = get_data_decimal_precision();
141                 StoreDay::save(id, &memory_cache, dec_precision);
142                 while(memory_cache.empty() == false) {
143                         data    = memory_cache.back();
144                         memory_cache.pop_back();
145                         delete(data);
146                 }
147         }
148         pthread_mutex_unlock(&plock);
149 }
150
151 void W1Device::save_and_clean_cache() {
152         Data    *data;
153         int     dec_precision;
154
155         dec_precision   = get_data_decimal_precision();
156         pthread_mutex_lock(&plock);
157         /* needs to be casted to long unsigned int value is "unsigned int" in some
158            toolchains and that would otherwise cause an warning/error 
159         */
160         log_debug("memory cache size: %lu\n", (long unsigned int)memory_cache.size());
161         StoreDay::save(id, &memory_cache, dec_precision);
162         while(memory_cache.empty() == false) {
163                 data    = memory_cache.back();
164                 memory_cache.pop_back();
165                 delete(data);
166         }
167         pthread_mutex_unlock(&plock);
168 }
169
170 const DataReader *W1Device::get_datareader() {
171         return reader;
172 }