libsensors_chip.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2014, Open Source Robotics Foundation, Inc
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the Open Source Robotics Foundation nor the
18  * names of its contributors may be used to endorse or promote
19  * products derived from this software without specific prior
20  * written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 /*
37  * Author: Mitchell Wills
38  */
39 
40 #include <stdlib.h>
41 #include <algorithm>
42 #include <ros/ros.h>
43 #include <boost/foreach.hpp>
45 #include <sstream>
46 
47 #define NAME_BUFFER_SIZE 250
48 
49 SensorChip::SensorChip(sensors_chip_name const *chip_name,
50  const std::vector<std::string> &ignore) :
51  internal_name_(chip_name)
52 {
53  char name_buffer[NAME_BUFFER_SIZE];
54  sensors_snprintf_chip_name(name_buffer, NAME_BUFFER_SIZE, internal_name_);
55  name_ = name_buffer;
56 
57  ROS_DEBUG("Found Sensor: %s", getName().c_str());
58 
59  // enumerate the features of this sensor
60  sensors_feature const *feature;
61  int number = 0;
62 
63  while ((feature = sensors_get_features(internal_name_, &number)) != NULL) {
64  sensors_feature_type type = feature->type;
65  SensorChipFeaturePtr feature_ptr;
66  switch(type){
67  case SENSORS_FEATURE_FAN:
68  feature_ptr.reset(new FanSensor(*this, feature));
69  break;
70  case SENSORS_FEATURE_TEMP:
71  feature_ptr.reset(new TempSensor(*this, feature));
72  break;
73  case SENSORS_FEATURE_IN:
74  feature_ptr.reset(new VoltageSensor(*this, feature));
75  break;
76  default:
77  feature_ptr.reset(new OtherSensor(*this, feature));
78  break;
79  }
80 
81  if( std::count(ignore.begin(), ignore.end(),
82  feature_ptr->getFullName()) > 0 ) {
83  ROS_INFO_STREAM("Ignoring sensor " << feature_ptr->getFullName());
84  } else {
85  features_.push_back(feature_ptr);
86  }
87  }
88 
89  std::stringstream info_msg;
90  info_msg << "Found sensor " << getName();
91  if( features_.size() > 0 ) {
92  info_msg << " with features: ";
93  size_t remain = features_.size();
94  BOOST_FOREACH(const SensorChipFeaturePtr & feature, features_) {
95  remain--;
96  info_msg << feature->getFeatureName();
97  if( remain > 0 ) info_msg << ", ";
98  }
99  } else {
100  info_msg << " with no features?";
101  }
102  ROS_INFO_STREAM(info_msg.str());
103 }
104 
105 
106 
108  sensors_feature const *feature) :
109  chip_(chip),
110  feature_(feature)
111 {
112  name_ = feature_->name;
113  char* label_c_str = sensors_get_label(chip_.internal_name_, feature_);
114  if( label_c_str == NULL ) {
115  ROS_WARN("Could not get label for %s", name_.c_str());
116  label_ = "(None)";
117  } else {
118  label_ = label_c_str;
119  free(label_c_str);
120  }
123 
124 
125  ROS_DEBUG("\tFound Feature: %s(%s)[%d]", getFullLabel().c_str(),
126  getFullName().c_str(), feature_->type);
127 
129 }
130 
131 
133  sensors_subfeature const *subfeature;
134  int number = 0;
135 
136  while ((subfeature = sensors_get_all_subfeatures(chip_.internal_name_, feature_, &number)) != NULL) {
137  SensorChipSubFeaturePtr subfeature_ptr(new SensorChipSubFeature(*this,
138  subfeature));
139  sub_features_.push_back(subfeature_ptr);
140  }
141 }
142 
143 
145  BOOST_FOREACH(SensorChipSubFeaturePtr subfeature, sub_features_){
146  if(subfeature->getType()==type)
147  return subfeature;
148  }
149  return SensorChipSubFeaturePtr();
150 }
151 
152 
154  sensors_subfeature const *subfeature) :
155  feature_(feature),
156  subfeature_(subfeature),
157  name_(subfeature->name)
158 {
159  ROS_DEBUG("\t\tFound Sub-Feature: %s[%d] = %f", getName().c_str(),
160  subfeature_->type, getValue());
161 }
162 
163 
165  double value;
166  if( sensors_get_value(feature_.chip_.internal_name_, subfeature_->number,
167  &value) != 0 ) {
168  ROS_WARN_STREAM("Failed to get value for " << feature_.getFullName() <<
169  " " << getName());
170  }
171  return value;
172 }
173 
175  SensorChipSubFeaturePtr speed = getSubFeatureByType(SENSORS_SUBFEATURE_FAN_INPUT);
176  if(speed){
177  double speed_val = speed->getValue();
178  if(speed_val==0)
179  stat.summary(diagnostic_msgs::DiagnosticStatus::WARN,
180  "Fan stalled or not connected");
181  else
182  stat.summaryf(diagnostic_msgs::DiagnosticStatus::OK, "Fan OK (%.2f RPM)",
183  speed_val);
184  stat.add("Fan Speed (RPM)", speed_val);
185  }
186  else
187  stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR, "No Fan Input!!!");
188 }
189 
190 
192  SensorChipSubFeaturePtr temp = getSubFeatureByType(SENSORS_SUBFEATURE_TEMP_INPUT);
193  SensorChipSubFeaturePtr max_temp = getSubFeatureByType(SENSORS_SUBFEATURE_TEMP_MAX);
194  SensorChipSubFeaturePtr temp_crit = getSubFeatureByType(SENSORS_SUBFEATURE_TEMP_CRIT);
195  SensorChipSubFeaturePtr temp_crit_alarm = getSubFeatureByType(SENSORS_SUBFEATURE_TEMP_CRIT_ALARM);
196  if(temp){
197  double temp_val = temp->getValue();
198  stat.add("Temperature (C)", temp_val);
199 
200  if(max_temp && max_temp->getValue()!=0)
201  stat.add("Max Temperature (C)", max_temp->getValue());
202  if(temp_crit && temp_crit->getValue()!=0)
203  stat.add("Temperature Critical (C)", temp_crit->getValue());
204 
205  if(temp_crit_alarm && temp_crit_alarm->getValue()!=0)
206  stat.summaryf(diagnostic_msgs::DiagnosticStatus::WARN,
207  "Critical Temp Alarm (%.2f C)", temp_val);
208  else if(temp_crit && temp_crit->getValue()!=0 &&
209  temp_val > temp_crit->getValue())
210  stat.summaryf(diagnostic_msgs::DiagnosticStatus::WARN,
211  "Critical Temp Alarm (%.2f C)", temp_val);
212  else if(max_temp && max_temp->getValue()!=0 &&
213  temp_val > max_temp->getValue())
214  stat.summaryf(diagnostic_msgs::DiagnosticStatus::WARN,
215  "Max Temp Alarm (%.2f C)", temp_val);
216  else
217  stat.summaryf(diagnostic_msgs::DiagnosticStatus::OK,
218  "Temp OK (%.2f C)", temp_val);
219  }
220  else
221  stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR, "NO TEMP Input!!!");
222 }
223 
225  SensorChipSubFeaturePtr voltage = getSubFeatureByType(
226  SENSORS_SUBFEATURE_IN_INPUT);
227  SensorChipSubFeaturePtr min = getSubFeatureByType(
228  SENSORS_SUBFEATURE_IN_MIN);
229  SensorChipSubFeaturePtr max = getSubFeatureByType(
230  SENSORS_SUBFEATURE_IN_MAX);
231  SensorChipSubFeaturePtr lcrit = getSubFeatureByType(
232  SENSORS_SUBFEATURE_IN_LCRIT);
233  SensorChipSubFeaturePtr crit = getSubFeatureByType(
234  SENSORS_SUBFEATURE_IN_CRIT);
235 
236  // alarm inputs are nonzero on alarm
237  SensorChipSubFeaturePtr alarm = getSubFeatureByType(
238  SENSORS_SUBFEATURE_IN_ALARM);
239  SensorChipSubFeaturePtr min_alarm = getSubFeatureByType(
240  SENSORS_SUBFEATURE_IN_MIN_ALARM);
241  SensorChipSubFeaturePtr max_alarm = getSubFeatureByType(
242  SENSORS_SUBFEATURE_IN_MAX_ALARM);
243  SensorChipSubFeaturePtr lcrit_alarm = getSubFeatureByType(
244  SENSORS_SUBFEATURE_IN_LCRIT_ALARM);
245  SensorChipSubFeaturePtr crit_alarm = getSubFeatureByType(
246  SENSORS_SUBFEATURE_IN_CRIT_ALARM);
247 
248  if(voltage){
249  double voltage_val = voltage->getValue();
250  stat.add("Voltage (V)", voltage_val);
251 
252  bool low_warn = false;
253  bool low_err = false;
254  bool high_warn = false;
255  bool high_err = false;
256 
257  // max voltage (warning)
258  if(max) {
259  stat.add("Max Voltage (V)", max->getValue());
260  if(max_alarm && max_alarm->getValue()!=0) {
261  high_warn = true;
262  } else if(voltage_val >= max->getValue()) {
263  high_warn = true;
264  }
265  }
266 
267  // min voltage (warning)
268  if(min) {
269  stat.add("Min Voltage (V)", min->getValue());
270  if(min_alarm && min_alarm->getValue()!=0) {
271  low_warn = true;
272  } else if(voltage_val <= min->getValue()) {
273  low_warn = true;
274  }
275  }
276 
277  if(crit) {
278  stat.add("Critical Max Voltage (V)", crit->getValue());
279  if(crit_alarm && crit_alarm->getValue()!=0) {
280  high_err = true;
281  } else if(voltage_val >= crit->getValue()) {
282  high_err = true;
283  }
284  }
285 
286  if(lcrit) {
287  stat.add("Critical Min Voltage (V)", lcrit->getValue());
288  if(lcrit_alarm && lcrit_alarm->getValue()!=0) {
289  low_err = true;
290  } else if(voltage_val <= lcrit->getValue()) {
291  low_err = true;
292  }
293  }
294 
295  // check for alarms and set summary
296  if(high_err) {
297  stat.summaryf(diagnostic_msgs::DiagnosticStatus::ERROR,
298  "High Voltage CRITICAL (%.2f V)", voltage_val);
299  } else if(low_err) {
300  stat.summaryf(diagnostic_msgs::DiagnosticStatus::ERROR,
301  "Low Voltage CRITICAL (%.2f V)", voltage_val);
302  } else if(high_warn) {
303  stat.summaryf(diagnostic_msgs::DiagnosticStatus::WARN,
304  "High Voltage ALARM (%.2f V)", voltage_val);
305  } else if(low_warn) {
306  stat.summaryf(diagnostic_msgs::DiagnosticStatus::WARN,
307  "Low Voltage ALARM (%.2f V)", voltage_val);
308  } else {
309  stat.summaryf(diagnostic_msgs::DiagnosticStatus::OK,
310  "Voltage OK (%.2f V)", voltage_val);
311  }
312  } else {
313  stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR,
314  "NO Voltage Input!!!");
315  }
316 }
317 
319  stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "Unkown sensor type");
320  BOOST_FOREACH(SensorChipSubFeaturePtr subfeature, sub_features_){
321  stat.add(subfeature->getName(), subfeature->getValue());
322  }
323 }
SensorChipFeature(const SensorChip &chip, sensors_feature const *feature)
#define NAME_BUFFER_SIZE
friend class SensorChipSubFeature
SensorChip(sensors_chip_name const *chip_name, const std::vector< std::string > &ignore)
virtual void buildStatus(diagnostic_updater::DiagnosticStatusWrapper &stat)
const SensorChipFeature & feature_
SensorChipSubFeature(const SensorChipFeature &feature, sensors_subfeature const *subfeature)
void summary(unsigned char lvl, const std::string s)
std::string full_name_
const std::string & getName()
const std::string & getFeatureName() const
boost::shared_ptr< SensorChipSubFeature > SensorChipSubFeaturePtr
sensors_feature const * feature_
const std::string & getFeatureLabel() const
#define ROS_WARN(...)
void summaryf(unsigned char lvl, const char *format,...)
sensors_subfeature const * subfeature_
const std::string & getName() const
std::string name_
const SensorChip & chip_
sensors_chip_name const * internal_name_
std::vector< SensorChipSubFeaturePtr > sub_features_
virtual void buildStatus(diagnostic_updater::DiagnosticStatusWrapper &stat)
std::string label_
#define ROS_WARN_STREAM(args)
std::string full_label_
std::vector< SensorChipFeaturePtr > features_
#define ROS_INFO_STREAM(args)
const std::string & getFullName() const
SensorChipSubFeaturePtr getSubFeatureByType(sensors_subfeature_type type)
virtual void buildStatus(diagnostic_updater::DiagnosticStatusWrapper &stat)
void add(const std::string &key, const T &val)
const std::string & getFullLabel() const
virtual void buildStatus(diagnostic_updater::DiagnosticStatusWrapper &stat)
std::string getChipName()
#define ROS_DEBUG(...)


libsensors_monitor
Author(s): Mitchell Wills
autogenerated on Sun Nov 17 2019 03:20:10