]> pilppa.org Git - lib1wire.git/blob - src/W1Device.cc
a15f3d8c18a1ec7355fa59553b99c560323aaec0
[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 }
49
50 W1Device::~W1Device() {
51         log_debug("started\n");
52         save_and_clean_cache();
53         if (reader != NULL) {
54                 delete(reader);
55                 reader  = NULL;
56         }
57 }
58
59 string Device::get_name() {
60         DeviceConfig    *cfg;
61
62         if (name.empty() == true) {
63                 cfg     = DeviceConfig::get_device_config(id);
64                 if (cfg != NULL) {
65                         cfg->get_config_value(DEVICE_CONFIG_VALUE_KEY__NAME, name);
66                         delete(cfg);
67                 }
68         }
69         return name;
70 }
71
72 void Device::set_name(string name_param) {
73         DeviceConfig    *cfg;
74
75         log_debug("set_name started\n");
76         if (name.compare(name_param) != 0) {
77                 name    = name_param;
78                 cfg     = DeviceConfig::get_device_config(id);
79                 if (cfg != NULL) {
80                         cfg->set_config_value(DEVICE_CONFIG_VALUE_KEY__NAME, name_param, true);
81                         delete(cfg);
82                 }
83         }
84 }
85
86 void W1Device::printout() {
87         Data    *data;
88         string  text;
89         string  type;
90         string  name;
91
92         data    = get_data();
93         if (data != NULL) {
94                 text    = data->to_string();
95                 cout << text << endl;
96                 delete(data);
97         }
98         else {
99                 type    = get_type();
100                 name    = get_name();
101                 log_error("Could not read data for %s device: %s\n", type.c_str(), name.c_str());
102         }
103 }
104
105 string W1Device::to_string(double dbl_val, int digit_count) {
106         string          ret_val;
107         ostringstream   out;
108
109         out << fixed << setprecision(digit_count) << dbl_val;
110         ret_val = out.str();
111         return ret_val;
112 }
113
114 Data *W1Device::get_data() {
115         Data            *ret_val;
116         vector<double>  *vect;
117
118         ret_val = NULL;
119         vect    = get_raw_data();
120         if (vect != NULL) {
121                 ret_val = new Data(vect, get_unit());
122                 cache(ret_val);
123                 delete(vect);
124                 log_debug("%s returning new data\n", id.c_str());
125         }
126         else {
127                 // read old already saved data
128                 log_debug("%s returning old saved data\n", id.c_str());
129                 ret_val = reader->get_latest_data();
130         }
131         return ret_val;
132 }
133
134 void W1Device::cache(Data *new_data) {
135         Data    *data;
136         int     dec_precision;
137
138         data    = new_data->clone();
139         pthread_mutex_lock(&plock);
140         memory_cache.push_back(data);
141         if (memory_cache.size() > 5) {
142                 dec_precision   = get_data_decimal_precision();
143                 StoreDay::save(id, &memory_cache, dec_precision);
144                 while(memory_cache.empty() == false) {
145                         data    = memory_cache.back();
146                         memory_cache.pop_back();
147                         delete(data);
148                 }
149         }
150         pthread_mutex_unlock(&plock);
151 }
152
153 void W1Device::save_and_clean_cache() {
154         Data    *data;
155         int     dec_precision;
156
157         dec_precision   = get_data_decimal_precision();
158         pthread_mutex_lock(&plock);
159         /* needs to be casted to long unsigned int value is "unsigned int" in some
160            toolchains and that would otherwise cause an warning/error 
161         */
162         log_debug("memory cache size: %lu\n", (long unsigned int)memory_cache.size());
163         StoreDay::save(id, &memory_cache, dec_precision);
164         while(memory_cache.empty() == false) {
165                 data    = memory_cache.back();
166                 memory_cache.pop_back();
167                 delete(data);
168         }
169         pthread_mutex_unlock(&plock);
170 }
171
172 const DataReader *W1Device::get_datareader() {
173         return reader;
174 }