root/lm-sensors/branches/lm-sensors-3.0.0/prog/sensors/chips.c @ 5184

Revision 5184, 13.8 KB (checked in by djwong, 7 years ago)

Subject: [PATCH 3/4 v2] sensors: Print energy and power meters

Display power and energy meters in sensors.

Signed-off-by: Darrick J. Wong <djwong@…>

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    chips.c - Part of sensors, a user-space program for hardware monitoring
3    Copyright (C) 1998-2003  Frodo Looijaard <frodol@dds.nl> and
4                             Mark D. Studebaker <mdsxyz123@yahoo.com>
5    Copyright (C) 2007       Jean Delvare <khali@linux-fr.org>
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20    MA 02110-1301 USA.
21*/
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
27#include "main.h"
28#include "chips.h"
29#include "lib/sensors.h"
30#include "lib/error.h"
31
32void print_chip_raw(const sensors_chip_name *name)
33{
34        int a, b, err;
35        const sensors_feature *feature;
36        const sensors_subfeature *sub;
37        char *label;
38        double val;
39
40        a = 0;
41        while ((feature = sensors_get_features(name, &a))) {
42                if (!(label = sensors_get_label(name, feature))) {
43                        fprintf(stderr, "ERROR: Can't get label of feature "
44                                "%s!\n", feature->name);
45                        continue;
46                }
47                printf("%s:\n", label);
48                free(label);
49
50                b = 0;
51                while ((sub = sensors_get_all_subfeatures(name, feature, &b))) {
52                        if (sub->flags & SENSORS_MODE_R) {
53                                if ((err = sensors_get_value(name, sub->number,
54                                                             &val)))
55                                        fprintf(stderr, "ERROR: Can't get "
56                                                "value of subfeature %s: %s\n",
57                                                sub->name,
58                                                sensors_strerror(err));
59                                else
60                                        printf("  %s: %.2f\n", sub->name, val);
61                        } else
62                                printf("(%s)\n", label);
63                }
64        }
65}
66
67static inline double deg_ctof(double cel)
68{
69        return cel * (9.0F / 5.0F) + 32.0F;
70}
71
72static void print_label(const char *label, int space)
73{
74        int len = strlen(label)+1;
75        printf("%s:%*s", label, space - len, "");
76}
77
78static double get_value(const sensors_chip_name *name,
79                        const sensors_subfeature *sub)
80{
81        double val;
82        int err;
83
84        err = sensors_get_value(name, sub->number, &val);
85        if (err) {
86                fprintf(stderr, "ERROR: Can't get value of subfeature %s: %s\n",
87                        sub->name, sensors_strerror(err));
88                val = 0;
89        }
90        return val;
91}
92
93static int get_label_size(const sensors_chip_name *name)
94{
95        int i;
96        const sensors_feature *iter;
97        char *label;
98        unsigned int max_size = 11;     /* 11 as minumum label width */
99
100        i = 0;
101        while ((iter = sensors_get_features(name, &i))) {
102                if ((label = sensors_get_label(name, iter)) &&
103                    strlen(label) > max_size)
104                        max_size = strlen(label);
105                free(label);
106        }
107        return max_size + 1;
108}
109
110static void print_temp_limits(double limit1, double limit2,
111                              const char *name1, const char *name2, int alarm)
112{
113        if (fahrenheit) {
114                limit1 = deg_ctof(limit1);
115                limit2 = deg_ctof(limit2);
116        }
117
118        if (name2) {
119                printf("(%-4s = %+5.1f%s, %-4s = %+5.1f%s)  ",
120                       name1, limit1, degstr,
121                       name2, limit2, degstr);
122        } else if (name1) {
123                printf("(%-4s = %+5.1f%s)                  ",
124                       name1, limit1, degstr);
125        } else {
126                printf("                                  ");
127        }
128
129        if (alarm)
130                printf("ALARM  ");
131}
132
133static void print_chip_temp(const sensors_chip_name *name,
134                            const sensors_feature *feature,
135                            int label_size)
136{
137        const sensors_subfeature *sf, *sfmin, *sfmax, *sfcrit, *sfhyst;
138        double val, limit1, limit2;
139        const char *s1, *s2;
140        int alarm, crit_displayed = 0;
141        char *label;
142
143        if (!(label = sensors_get_label(name, feature))) {
144                fprintf(stderr, "ERROR: Can't get label of feature %s!\n",
145                        feature->name);
146                return;
147        }
148        print_label(label, label_size);
149        free(label);
150
151        sf = sensors_get_subfeature(name, feature,
152                                    SENSORS_SUBFEATURE_TEMP_ALARM);
153        alarm = sf && get_value(name, sf);
154
155        sfmin = sensors_get_subfeature(name, feature,
156                                       SENSORS_SUBFEATURE_TEMP_MIN);
157        sfmax = sensors_get_subfeature(name, feature,
158                                       SENSORS_SUBFEATURE_TEMP_MAX);
159        sfcrit = sensors_get_subfeature(name, feature,
160                                        SENSORS_SUBFEATURE_TEMP_CRIT);
161        if (sfmax) {
162                sf = sensors_get_subfeature(name, feature,
163                                        SENSORS_SUBFEATURE_TEMP_MAX_ALARM);
164                if (sf && get_value(name, sf))
165                        alarm |= 1;
166
167                if (sfmin) {
168                        limit1 = get_value(name, sfmin);
169                        s1 = "low";
170                        limit2 = get_value(name, sfmax);
171                        s2 = "high";
172
173                        sf = sensors_get_subfeature(name, feature,
174                                        SENSORS_SUBFEATURE_TEMP_MIN_ALARM);
175                        if (sf && get_value(name, sf))
176                                alarm |= 1;
177                } else {
178                        limit1 = get_value(name, sfmax);
179                        s1 = "high";
180
181                        sfhyst = sensors_get_subfeature(name, feature,
182                                        SENSORS_SUBFEATURE_TEMP_MAX_HYST);
183                        if (sfhyst) {
184                                limit2 = get_value(name, sfhyst);
185                                s2 = "hyst";
186                        } else if (sfcrit) {
187                                limit2 = get_value(name, sfcrit);
188                                s2 = "crit";
189
190                                sf = sensors_get_subfeature(name, feature,
191                                        SENSORS_SUBFEATURE_TEMP_CRIT_ALARM);
192                                if (sf && get_value(name, sf))
193                                        alarm |= 1;
194                                crit_displayed = 1;
195                        } else {
196                                limit2 = 0;
197                                s2 = NULL;
198                        }
199                }
200        } else if (sfcrit) {
201                limit1 = get_value(name, sfcrit);
202                s1 = "crit";
203
204                sfhyst = sensors_get_subfeature(name, feature,
205                                        SENSORS_SUBFEATURE_TEMP_CRIT_HYST);
206                if (sfhyst) {
207                        limit2 = get_value(name, sfhyst);
208                        s2 = "hyst";
209                } else {
210                        limit2 = 0;
211                        s2 = NULL;
212                }
213
214                sf = sensors_get_subfeature(name, feature,
215                                        SENSORS_SUBFEATURE_TEMP_CRIT_ALARM);
216                if (sf && get_value(name, sf))
217                        alarm |= 1;
218                crit_displayed = 1;
219        } else {
220                limit1 = limit2 = 0;
221                s1 = s2 = NULL;
222        }
223
224
225        sf = sensors_get_subfeature(name, feature,
226                                    SENSORS_SUBFEATURE_TEMP_FAULT);
227        if (sf && get_value(name, sf)) {
228                printf("   FAULT  ");
229        } else {
230                sf = sensors_get_subfeature(name, feature,
231                                            SENSORS_SUBFEATURE_TEMP_INPUT);
232                if (sf) {
233                        val = get_value(name, sf);
234                        if (fahrenheit)
235                                val = deg_ctof(val);
236                        printf("%+6.1f%s  ", val, degstr);
237                } else
238                        printf("     N/A  ");
239        }
240        print_temp_limits(limit1, limit2, s1, s2, alarm);
241
242        if (!crit_displayed && sfcrit) {
243                limit1 = get_value(name, sfcrit);
244                s1 = "crit";
245
246                sfhyst = sensors_get_subfeature(name, feature,
247                                        SENSORS_SUBFEATURE_TEMP_CRIT_HYST);
248                if (sfhyst) {
249                        limit2 = get_value(name, sfhyst);
250                        s2 = "hyst";
251                } else {
252                        limit2 = 0;
253                        s2 = NULL;
254                }
255
256                sf = sensors_get_subfeature(name, feature,
257                                        SENSORS_SUBFEATURE_TEMP_CRIT_ALARM);
258                alarm = sf && get_value(name, sf);
259
260                printf("\n%*s", label_size + 10, "");
261                print_temp_limits(limit1, limit2, s1, s2, alarm);
262        }
263
264        /* print out temperature sensor info */
265        sf = sensors_get_subfeature(name, feature,
266                                    SENSORS_SUBFEATURE_TEMP_TYPE);
267        if (sf) {
268                int sens = (int)get_value(name, sf);
269
270                /* older kernels / drivers sometimes report a beta value for
271                   thermistors */
272                if (sens > 1000)
273                        sens = 4;
274
275                printf("sensor = %s", sens == 0 ? "disabled" :
276                       sens == 1 ? "diode" :
277                       sens == 2 ? "transistor" :
278                       sens == 3 ? "thermal diode" :
279                       sens == 4 ? "thermistor" :
280                       sens == 5 ? "AMD AMDSI" :
281                       sens == 6 ? "Intel PECI" : "unknown");
282        }
283        printf("\n");
284}
285
286static void print_chip_in(const sensors_chip_name *name,
287                          const sensors_feature *feature,
288                          int label_size)
289{
290        const sensors_subfeature *sf, *sfmin, *sfmax;
291        double alarm_max, alarm_min;
292        char *label;
293
294        if (!(label = sensors_get_label(name, feature))) {
295                fprintf(stderr, "ERROR: Can't get label of feature %s!\n",
296                        feature->name);
297                return;
298        }
299        print_label(label, label_size);
300        free(label);
301
302        sf = sensors_get_subfeature(name, feature,
303                                    SENSORS_SUBFEATURE_IN_INPUT);
304        if (sf)
305                printf("%+6.2f V", get_value(name, sf));
306        else
307                printf("     N/A");
308
309        sfmin = sensors_get_subfeature(name, feature,
310                                       SENSORS_SUBFEATURE_IN_MIN);
311        sfmax = sensors_get_subfeature(name, feature,
312                                       SENSORS_SUBFEATURE_IN_MAX);
313        if (sfmin && sfmax)
314                printf("  (min = %+6.2f V, max = %+6.2f V)",
315                       get_value(name, sfmin),
316                       get_value(name, sfmax));
317        else if (sfmin)
318                printf("  (min = %+6.2f V)",
319                       get_value(name, sfmin));
320        else if (sfmax)
321                printf("  (max = %+6.2f V)",
322                       get_value(name, sfmax));
323
324        sf = sensors_get_subfeature(name, feature,
325                                    SENSORS_SUBFEATURE_IN_ALARM);
326        sfmin = sensors_get_subfeature(name, feature,
327                                       SENSORS_SUBFEATURE_IN_MIN_ALARM);
328        sfmax = sensors_get_subfeature(name, feature,
329                                       SENSORS_SUBFEATURE_IN_MAX_ALARM);
330        if (sfmin || sfmax) {
331                alarm_max = sfmax ? get_value(name, sfmax) : 0;
332                alarm_min = sfmin ? get_value(name, sfmin) : 0;
333
334                if (alarm_min || alarm_max) {
335                        printf(" ALARM (");
336
337                        if (alarm_min)
338                                printf("MIN");
339                        if (alarm_max)
340                                printf("%sMAX", (alarm_min) ? ", " : "");
341
342                        printf(")");
343                }
344        } else if (sf) {
345                printf("   %s",
346                       get_value(name, sf) ? "ALARM" : "");
347        }
348
349        printf("\n");
350}
351
352static void print_chip_fan(const sensors_chip_name *name,
353                           const sensors_feature *feature,
354                           int label_size)
355{
356        const sensors_subfeature *sf, *sfmin, *sfdiv;
357        char *label;
358
359        if (!(label = sensors_get_label(name, feature))) {
360                fprintf(stderr, "ERROR: Can't get label of feature %s!\n",
361                        feature->name);
362                return;
363        }
364        print_label(label, label_size);
365        free(label);
366
367        sf = sensors_get_subfeature(name, feature,
368                                    SENSORS_SUBFEATURE_FAN_FAULT);
369        if (sf && get_value(name, sf))
370                printf("   FAULT");
371        else {
372                sf = sensors_get_subfeature(name, feature,
373                                            SENSORS_SUBFEATURE_FAN_INPUT);
374                if (sf)
375                        printf("%4.0f RPM", get_value(name, sf));
376                else
377                        printf("     N/A");
378        }
379
380        sfmin = sensors_get_subfeature(name, feature,
381                                       SENSORS_SUBFEATURE_FAN_MIN);
382        sfdiv = sensors_get_subfeature(name, feature,
383                                       SENSORS_SUBFEATURE_FAN_DIV);
384        if (sfmin && sfdiv)
385                printf("  (min = %4.0f RPM, div = %1.0f)",
386                       get_value(name, sfmin),
387                       get_value(name, sfdiv));
388        else if (sfmin)
389                printf("  (min = %4.0f RPM)",
390                       get_value(name, sfmin));
391        else if (sfdiv)
392                printf("  (div = %1.0f)",
393                       get_value(name, sfdiv));
394
395        sf = sensors_get_subfeature(name, feature,
396                                    SENSORS_SUBFEATURE_FAN_ALARM);
397        if (sf && get_value(name, sf)) {
398                printf("  ALARM");
399        }
400
401        printf("\n");
402}
403
404static void print_chip_power(const sensors_chip_name *name,
405                             const sensors_feature *feature,
406                             int label_size)
407{
408        int need_space = 0;
409        const sensors_subfeature *sf, *sfmin, *sfmax, *sfint;
410        char *label;
411
412        if (!(label = sensors_get_label(name, feature))) {
413                fprintf(stderr, "ERROR: Can't get label of feature %s!\n",
414                        feature->name);
415                return;
416        }
417        print_label(label, label_size);
418        free(label);
419
420        sf = sensors_get_subfeature(name, feature,
421                                    SENSORS_SUBFEATURE_POWER_AVERAGE);
422        if (sf)
423                printf("%6.2f W", get_value(name, sf));
424        else
425                printf("     N/A");
426
427        sfmin = sensors_get_subfeature(name, feature,
428                                      SENSORS_SUBFEATURE_POWER_AVERAGE_HIGHEST);
429        sfmax = sensors_get_subfeature(name, feature,
430                                       SENSORS_SUBFEATURE_POWER_AVERAGE_LOWEST);
431        sfint = sensors_get_subfeature(name, feature,
432                                     SENSORS_SUBFEATURE_POWER_AVERAGE_INTERVAL);
433        if (sfmin || sfmax || sfint) {
434                printf("  (");
435
436                if (sfmin) {
437                        printf("min = %6.2f W", get_value(name, sfmin));
438                        need_space = 1;
439                }
440
441                if (sfmax) {
442                        printf("%smax = %6.2f W", (need_space ? ", " : ""),
443                               get_value(name, sfmax));
444                        need_space = 1;
445                }
446
447                if (sfint) {
448                        printf("%sinterval = %6.2f s", (need_space ? ", " : ""),
449                               get_value(name, sfint));
450                        need_space = 1;
451                }
452                printf(")");
453        }
454
455        printf("\n");
456}
457
458static void print_chip_energy(const sensors_chip_name *name,
459                              const sensors_feature *feature,
460                              int label_size)
461{
462        const sensors_subfeature *sf;
463        char *label;
464
465        if (!(label = sensors_get_label(name, feature))) {
466                fprintf(stderr, "ERROR: Can't get label of feature %s!\n",
467                        feature->name);
468                return;
469        }
470        print_label(label, label_size);
471        free(label);
472
473        sf = sensors_get_subfeature(name, feature,
474                                    SENSORS_SUBFEATURE_ENERGY_INPUT);
475        if (sf)
476                printf("%6.2f J", get_value(name, sf));
477        else
478                printf("     N/A");
479
480        printf("\n");
481}
482
483static void print_chip_vid(const sensors_chip_name *name,
484                           const sensors_feature *feature,
485                           int label_size)
486{
487        char *label;
488        const sensors_subfeature *subfeature;
489        double vid;
490
491        subfeature = sensors_get_subfeature(name, feature,
492                                            SENSORS_SUBFEATURE_VID);
493        if (!subfeature)
494                return;
495
496        if ((label = sensors_get_label(name, feature))
497         && !sensors_get_value(name, subfeature->number, &vid)) {
498                print_label(label, label_size);
499                printf("%+6.3f V\n", vid);
500        }
501        free(label);
502}
503
504static void print_chip_beep_enable(const sensors_chip_name *name,
505                                   const sensors_feature *feature,
506                                   int label_size)
507{
508        char *label;
509        const sensors_subfeature *subfeature;
510        double beep_enable;
511
512        subfeature = sensors_get_subfeature(name, feature,
513                                            SENSORS_SUBFEATURE_BEEP_ENABLE);
514        if (!subfeature)
515                return;
516
517        if ((label = sensors_get_label(name, feature))
518         && !sensors_get_value(name, subfeature->number, &beep_enable)) {
519                print_label(label, label_size);
520                printf("%s\n", beep_enable ? "enabled" : "disabled");
521        }
522        free(label);
523}
524
525void print_chip(const sensors_chip_name *name)
526{
527        const sensors_feature *feature;
528        int i, label_size;
529
530        label_size = get_label_size(name);
531
532        i = 0;
533        while ((feature = sensors_get_features(name, &i))) {
534                switch (feature->type) {
535                case SENSORS_FEATURE_TEMP:
536                        print_chip_temp(name, feature, label_size);
537                        break;
538                case SENSORS_FEATURE_IN:
539                        print_chip_in(name, feature, label_size);
540                        break;
541                case SENSORS_FEATURE_FAN:
542                        print_chip_fan(name, feature, label_size);
543                        break;
544                case SENSORS_FEATURE_VID:
545                        print_chip_vid(name, feature, label_size);
546                        break;
547                case SENSORS_FEATURE_BEEP_ENABLE:
548                        print_chip_beep_enable(name, feature, label_size);
549                        break;
550                case SENSORS_FEATURE_POWER:
551                        print_chip_power(name, feature, label_size);
552                        break;
553                case SENSORS_FEATURE_ENERGY:
554                        print_chip_energy(name, feature, label_size);
555                        break;
556                default:
557                        continue;
558                }
559        }
560}
Note: See TracBrowser for help on using the browser.