MFC rev 1.2:
[dragonfly.git] / usr.bin / systat / sensors.c
blob551a5d6b4329497a97fc657938aa70899f5077bd
1 /* $OpenBSD: sensors.c,v 1.11 2007/03/23 14:48:22 ckuethe Exp $ */
2 /* $DragonFly: src/usr.bin/systat/sensors.c,v 1.1 2007/10/02 12:57:01 hasso Exp $ */
4 /*
5 * Copyright (c) 2007 Deanna Phillips <deanna@openbsd.org>
6 * Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
7 * Copyright (c) 2006 Constantine A. Murenin <cnst+openbsd@bugmail.mojo.ru>
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 #include <sys/cdefs.h>
23 #include <sys/param.h>
24 #include <sys/sysctl.h>
25 #include <sys/sensors.h>
27 #include <err.h>
28 #include <errno.h>
29 #include <stdio.h>
30 #include <stdlib.h>
32 #include "systat.h"
33 #include "extern.h"
35 struct sensor sensor;
36 struct sensordev sensordev;
37 int row, sensor_cnt;
38 void printline(void);
39 static char * fmttime(double);
41 WINDOW *
42 opensensors(void)
44 return (subwin(stdscr, LINES-5-1, 0, 5, 0));
47 void
48 closesensors(WINDOW *w)
50 if (w == NULL)
51 return;
52 wclear(w);
53 wrefresh(w);
54 delwin(w);
57 void
58 labelsensors(void)
60 wmove(wnd, 0, 0);
61 wclrtobot(wnd);
62 mvwaddstr(wnd, 0, 0, "Sensor");
63 mvwaddstr(wnd, 0, 34, "Value");
64 mvwaddstr(wnd, 0, 45, "Status");
65 mvwaddstr(wnd, 0, 58, "Description");
68 void
69 fetchsensors(void)
71 enum sensor_type type;
72 size_t slen, sdlen;
73 int mib[5], dev, numt;
75 mib[0] = CTL_HW;
76 mib[1] = HW_SENSORS;
77 slen = sizeof(struct sensor);
78 sdlen = sizeof(struct sensordev);
80 row = 1;
81 sensor_cnt = 0;
83 wmove(wnd, row, 0);
84 wclrtobot(wnd);
86 for (dev = 0; dev < MAXSENSORDEVICES; dev++) {
87 mib[2] = dev;
88 if (sysctl(mib, 3, &sensordev, &sdlen, NULL, 0) == -1) {
89 if (errno != ENOENT)
90 warn("sysctl");
91 continue;
93 for (type = 0; type < SENSOR_MAX_TYPES; type++) {
94 mib[3] = type;
95 for (numt = 0; numt < sensordev.maxnumt[type]; numt++) {
96 mib[4] = numt;
97 if (sysctl(mib, 5, &sensor, &slen, NULL, 0)
98 == -1) {
99 if (errno != ENOENT)
100 warn("sysctl");
101 continue;
103 if (sensor.flags & SENSOR_FINVALID)
104 continue;
105 sensor_cnt++;
106 printline();
112 const char *drvstat[] = {
113 NULL,
114 "empty", "ready", "powerup", "online", "idle", "active",
115 "rebuild", "powerdown", "fail", "pfail"
118 void
119 showsensors(void)
121 if (sensor_cnt == 0)
122 mvwaddstr(wnd, row, 0, "No sensors found.");
126 initsensors(void)
128 return (1);
131 void
132 printline(void)
134 mvwprintw(wnd, row, 0, "%s.%s%d", sensordev.xname,
135 sensor_type_s[sensor.type], sensor.numt);
136 switch (sensor.type) {
137 case SENSOR_TEMP:
138 mvwprintw(wnd, row, 24, "%10.2f degC",
139 (sensor.value - 273150000) / 1000000.0);
140 break;
141 case SENSOR_FANRPM:
142 mvwprintw(wnd, row, 24, "%11lld RPM", sensor.value);
143 break;
144 case SENSOR_VOLTS_DC:
145 mvwprintw(wnd, row, 24, "%10.2f V DC",
146 sensor.value / 1000000.0);
147 break;
148 case SENSOR_AMPS:
149 mvwprintw(wnd, row, 24, "%10.2f A", sensor.value / 1000000.0);
150 break;
151 case SENSOR_INDICATOR:
152 mvwprintw(wnd, row, 24, "%15s", sensor.value? "On" : "Off");
153 break;
154 case SENSOR_INTEGER:
155 mvwprintw(wnd, row, 24, "%11lld raw", sensor.value);
156 break;
157 case SENSOR_PERCENT:
158 mvwprintw(wnd, row, 24, "%14.2f%%", sensor.value / 1000.0);
159 break;
160 case SENSOR_LUX:
161 mvwprintw(wnd, row, 24, "%15.2f lx", sensor.value / 1000000.0);
162 break;
163 case SENSOR_DRIVE:
164 if (0 < sensor.value &&
165 sensor.value < sizeof(drvstat)/sizeof(drvstat[0])) {
166 mvwprintw(wnd, row, 24, "%15s", drvstat[sensor.value]);
167 break;
169 break;
170 case SENSOR_TIMEDELTA:
171 mvwprintw(wnd, row, 24, "%15s", fmttime(sensor.value / 1000000000.0));
172 break;
173 case SENSOR_WATTHOUR:
174 mvwprintw(wnd, row, 24, "%12.2f Wh", sensor.value / 1000000.0);
175 break;
176 case SENSOR_AMPHOUR:
177 mvwprintw(wnd, row, 24, "%10.2f Ah", sensor.value / 1000000.0);
178 break;
179 default:
180 mvwprintw(wnd, row, 24, "%10lld", sensor.value);
181 break;
183 if (sensor.desc[0] != '\0')
184 mvwprintw(wnd, row, 58, "(%s)", sensor.desc);
186 switch (sensor.status) {
187 case SENSOR_S_UNSPEC:
188 break;
189 case SENSOR_S_UNKNOWN:
190 mvwaddstr(wnd, row, 45, "unknown");
191 break;
192 case SENSOR_S_WARN:
193 mvwaddstr(wnd, row, 45, "WARNING");
194 break;
195 case SENSOR_S_CRIT:
196 mvwaddstr(wnd, row, 45, "CRITICAL");
197 break;
198 case SENSOR_S_OK:
199 mvwaddstr(wnd, row, 45, "OK");
200 break;
202 row++;
205 #define SECS_PER_DAY 86400
206 #define SECS_PER_HOUR 3600
207 #define SECS_PER_MIN 60
209 static char *
210 fmttime(double in)
212 int signbit = 1;
213 int tiny = 0;
214 char *unit;
215 #define LEN 32
216 static char outbuf[LEN];
218 if (in < 0){
219 signbit = -1;
220 in *= -1;
223 if (in >= SECS_PER_DAY ){
224 unit = "days";
225 in /= SECS_PER_DAY;
226 } else if (in >= SECS_PER_HOUR ){
227 unit = "hr";
228 in /= SECS_PER_HOUR;
229 } else if (in >= SECS_PER_MIN ){
230 unit = "min";
231 in /= SECS_PER_MIN;
232 } else if (in >= 1 ){
233 unit = "s";
234 /* in *= 1; */ /* no op */
235 } else if (in == 0 ){ /* direct comparisons to floats are scary */
236 unit = "s";
237 } else if (in >= 1e-3 ){
238 unit = "ms";
239 in *= 1e3;
240 } else if (in >= 1e-6 ){
241 unit = "us";
242 in *= 1e6;
243 } else if (in >= 1e-9 ){
244 unit = "ns";
245 in *= 1e9;
246 } else {
247 unit = "ps";
248 if (in < 1e-13)
249 tiny = 1;
250 in *= 1e12;
253 snprintf(outbuf, LEN,
254 tiny ? "%s%lf %s" : "%s%.3lf %s",
255 signbit == -1 ? "-" : "", in, unit);
257 return outbuf;