xosview  1.23
About: xosview is an X Windows based system monitor (cpu, memory, swap and network usage; interrupt and serial activities; load average).
  Fossies Dox: xosview-1.23.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

sensorfieldmeter.cc
Go to the documentation of this file.
1 //
2 // Copyright (c) 2014 by Tomi Tapper <tomi.o.tapper@jyu.fi>
3 //
4 // This file may be distributed under terms of the GPL
5 //
6 // Put code common to *BSD and Linux sensor meters here.
7 //
8 
9 #include "sensorfieldmeter.h"
10 #include <stdio.h>
11 #include <string.h>
12 #include <math.h>
13 
14 
15 SensorFieldMeter::SensorFieldMeter( XOSView *parent, const char *title,
16  const char *legend, int docaptions,
17  int dolegends, int dousedlegends )
18  : FieldMeter( parent, 3, title, legend, docaptions, dolegends, dousedlegends ){
19  metric_ = true;
20  negative_ = false;
21  unit_[0] = '\0';
22  high_ = low_ = 0.0;
23  has_low_ = has_high_ = false;
24 }
25 
27 }
28 
30  char l[32], lscale[2], tscale[2];
31  double limit = ( negative_ ? low_ : high_ ), total;
32  total = scaleValue(total_, tscale, true);
33  if ( (!negative_ && has_high_) || (negative_ && has_low_) ) {
34  if ( ( 0.1 <= fabs(total_) && fabs(total_) < 9.95 ) ||
35  ( 0.1 <= fabs(limit) && fabs(limit) < 9.95 ) ) {
36  if ( strlen(unit_) )
37  snprintf(l, 32, "ACT(%s)/%.1f/%.1f", unit_, limit, total_);
38  else
39  snprintf(l, 32, "ACT/%.1f/%.1f", limit, total_);
40  }
41  else if ( ( 9.95 <= fabs(total_) && fabs(total_) < 10000 ) ||
42  ( 9.95 <= fabs(limit) && fabs(limit) < 10000 ) ) {
43  if ( strlen(unit_) )
44  snprintf(l, 32, "ACT(%s)/%.0f/%.0f", unit_, limit, total_);
45  else
46  snprintf(l, 32, "ACT/%.0f/%0.f", limit, total_);
47  }
48  else {
49  limit = scaleValue(limit, lscale, true);
50  if ( strlen(unit_) )
51  snprintf(l, 32, "ACT(%s)/%.0f%s/%.0f%s", unit_, limit, lscale, total, tscale);
52  else
53  snprintf(l, 32, "ACT/%.0f%s/%.0f%s", limit, lscale, total, tscale);
54  }
55  }
56  else {
57  if ( ( 0.1 <= fabs(total_) && fabs(total_) < 9.95 ) ||
58  ( 0.1 <= fabs(limit) && fabs(limit) < 9.95 ) ) {
59  if ( strlen(unit_) )
60  snprintf(l, 32, "ACT(%s)/%s/%.1f", unit_, ( negative_ ? "LOW" : "HIGH" ), total_);
61  else
62  snprintf(l, 32, "ACT/%s/%.1f", ( negative_ ? "LOW" : "HIGH" ), total_);
63  }
64  else if ( ( 9.95 <= fabs(total_) && fabs(total_) < 10000 ) ||
65  ( 9.95 <= fabs(limit) && fabs(limit) < 10000 ) ) {
66  if ( strlen(unit_) )
67  snprintf(l, 32, "ACT(%s)/%s/%.0f", unit_, ( negative_ ? "LOW" : "HIGH" ), total_);
68  else
69  snprintf(l, 32, "ACT/%s/%.0f", ( negative_ ? "LOW" : "HIGH" ), total_);
70  }
71  else {
72  if ( strlen(unit_) )
73  snprintf(l, 32, "ACT(%s)/%s/%.0f%s", unit_, ( negative_ ? "LOW" : "HIGH" ), total, tscale);
74  else
75  snprintf(l, 32, "ACT/%s/%.0f%s", ( negative_ ? "LOW" : "HIGH" ), total, tscale);
76  }
77  }
78  legend(l);
79 }
80 
81 /* Check if meter needs to be flipped, or total/limits changed. */
82 /* Check also if alarm limit is reached. */
83 /* This is to be called after the values have been read. */
84 void SensorFieldMeter::checkFields( double low, double high ){
85  // Most sensors stay at either positive or negative values. Consider the
86  // actual value and alarm limits when deciding should the meter be showing
87  // positive or negative scale.
88  bool do_legend = false;
89 
90  if (negative_) { // negative at previous run
91  if (fields_[0] >= 0 || low > 0) { // flip to positive
92  negative_ = false;
93  total_ = fabs(total_);
94  high_ = ( has_high_ ? high : total_ );
95  low_ = ( has_low_ ? low : 0 );
97  do_legend = true;
98  }
99  else {
100  if (has_low_ && low != low_) {
101  low_ = low;
102  do_legend = true;
103  }
104  if (has_high_ && high != high_)
105  high_ = high;
106  }
107  }
108  else { // positive at previous run
109  if ( fields_[0] < 0 && // flip to negative if value and either limit is below 0
110  ( (!has_low_ && !has_high_) || low < 0 || high < 0 ) ) {
111  negative_ = true;
112  total_ = -fabs(total_);
113  high_ = ( has_high_ ? high : 0 );
114  low_ = ( has_low_ ? low : total_ );
115  setfieldcolor( 2, lowcolor_ );
116  do_legend = true;
117  }
118  else {
119  if (has_high_ && high != high_) {
120  high_ = high;
121  do_legend = true;
122  }
123  if (has_low_ && low != low_)
124  low_ = low;
125  }
126  }
127 
128  // change total if value or alarms won't fit
129  double highest = fabs(high_);
130  if ( fabs(fields_[0]) > highest )
131  highest = fabs(fields_[0]);
132  if ( fabs(low_) > highest )
133  highest = fabs(low_);
134  if ( highest > fabs(total_) ) {
135  do_legend = true;
136  int scale = floor(log10(highest));
137  total_ = ceil((highest / pow(10, scale)) * 1.25) * pow(10, scale);
138  if (negative_) {
139  total_ = -fabs(total_);
140  if (!has_low_)
141  low_ = total_;
142  if (!has_high_)
143  high_ = 0;
144  }
145  else {
146  if (!has_low_)
147  low_ = 0;
148  if (!has_high_)
149  high_ = total_;
150  }
151  }
152  if (do_legend)
153  updateLegend();
154 
155  // check for alarms
156  if (fields_[0] > high_) { // alarm: T > max
157  if (colors_[0] != highcolor_) {
159  do_legend = true;
160  }
161  }
162  else if (fields_[0] < low_) { // alarm: T < min
163  if (colors_[0] != lowcolor_) {
164  setfieldcolor( 0, lowcolor_ );
165  do_legend = true;
166  }
167  }
168  else {
169  if (colors_[0] != actcolor_) {
170  setfieldcolor( 0, actcolor_ );
171  do_legend = true;
172  }
173  }
174 
175  setUsed(fields_[0], total_);
176  if (negative_)
177  fields_[1] = ( fields_[0] < low_ ? 0 : low_ - fields_[0] );
178  else {
179  if (fields_[0] < 0)
180  fields_[0] = 0;
181  fields_[1] = ( fields_[0] > high_ ? 0 : high_ - fields_[0] );
182  }
183  fields_[2] = total_ - fields_[1] - fields_[0];
184 
185  if (do_legend) {
186  drawlegend();
187  drawfields(1); // force drawing in case only limit has changed
188  }
189 }
double total_
Definition: fieldmeter.h:41
void setfieldcolor(int field, const char *color)
Definition: fieldmeter.cc:108
bool metric_
Definition: fieldmeter.h:48
void drawlegend(void)
Definition: fieldmeter.cc:136
void setUsed(double val, double total)
Definition: fieldmeter.cc:76
virtual void drawfields(int mandatory=0)
Definition: fieldmeter.cc:221
double * fields_
Definition: fieldmeter.h:40
unsigned long * colors_
Definition: fieldmeter.h:43
static double scaleValue(double value, char *scale, bool metric)
Definition: meter.cc:67
const char * legend(void)
Definition: meter.h:27
void checkFields(double low, double high)
SensorFieldMeter(XOSView *parent, const char *title="", const char *legend="", int docaptions=0, int dolegends=0, int dousedlegends=0)
void updateLegend(void)
unsigned long actcolor_
unsigned long lowcolor_
unsigned long highcolor_