1 /* $OpenBSD: sensors.c,v 1.11 2007/03/23 14:48:22 ckuethe Exp $ */
4 * Copyright (c) 2007 Deanna Phillips <deanna@openbsd.org>
5 * Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
6 * Copyright (c) 2006 Constantine A. Murenin <cnst+openbsd@bugmail.mojo.ru>
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 #include <sys/param.h>
22 #include <sys/sysctl.h>
23 #include <sys/sensors.h>
36 struct sensordev sensordev
;
39 static char * fmttime(double);
41 struct sensordev_xname
{
44 u_int flags
; /* XNAME_FLAG_ */
47 #define XNAME_FLAG_WILDCARD 0x1
49 static int sensors_enabled
[SENSOR_MAX_TYPES
];
53 static int sensordev_xname_cnt
;
54 static struct sensordev_xname sensordev_xname
[XNAME_MAX
];
59 return (subwin(stdscr
, LINES
-5-1, 0, 5, 0));
63 closesensors(WINDOW
*w
)
77 mvwaddstr(wnd
, 0, 0, "Sensor");
78 mvwaddstr(wnd
, 0, 34, "Value");
79 mvwaddstr(wnd
, 0, 45, "Status");
80 mvwaddstr(wnd
, 0, 58, "Description");
86 enum sensor_type type
;
87 size_t slen
, sdlen
, idmax_len
;
88 int mib
[5], dev
, numt
, idmax
;
91 maxsensordevices
= MAXSENSORDEVICES
;
92 idmax_len
= sizeof(idmax
);
93 if (sysctlbyname("hw.sensors.dev_idmax", &idmax
, &idmax_len
,
95 maxsensordevices
= idmax
;
99 slen
= sizeof(struct sensor
);
100 sdlen
= sizeof(struct sensordev
);
108 for (dev
= 0; dev
< maxsensordevices
; dev
++) {
110 if (sysctl(mib
, 3, &sensordev
, &sdlen
, NULL
, 0) == -1) {
116 if (sensordev_xname_cnt
> 0) {
117 int i
, match
= 0, xname_len
;
119 xname_len
= strlen(sensordev
.xname
);
120 for (i
= 0; i
< sensordev_xname_cnt
; ++i
) {
121 const struct sensordev_xname
*x
;
123 x
= &sensordev_xname
[i
];
124 if (x
->flags
& XNAME_FLAG_WILDCARD
) {
125 if (xname_len
<= x
->xname_len
)
128 sensordev
.xname
[x
->xname_len
]))
130 if (strncmp(x
->xname
, sensordev
.xname
,
131 x
->xname_len
) == 0) {
135 } else if (xname_len
== x
->xname_len
&&
136 strcmp(x
->xname
, sensordev
.xname
) == 0) {
145 for (type
= 0; type
< SENSOR_MAX_TYPES
; type
++) {
146 if (!sensors_enabled
[type
])
150 for (numt
= 0; numt
< sensordev
.maxnumt
[type
]; numt
++) {
152 if (sysctl(mib
, 5, &sensor
, &slen
, NULL
, 0)
158 if (sensor
.flags
& SENSOR_FINVALID
)
167 const char *drvstat
[] = {
169 "empty", "ready", "powerup", "online", "idle", "active",
170 "rebuild", "powerdown", "fail", "pfail"
177 mvwaddstr(wnd
, row
, 0, "No sensors found.");
185 for (i
= 0; i
< SENSOR_MAX_TYPES
; ++i
)
186 sensors_enabled
[i
] = 1;
193 mvwprintw(wnd
, row
, 0, "%s.%s%d", sensordev
.xname
,
194 sensor_type_s
[sensor
.type
], sensor
.numt
);
195 switch (sensor
.type
) {
197 mvwprintw(wnd
, row
, 24, "%10.2f degC",
198 (sensor
.value
- 273150000) / 1000000.0);
201 mvwprintw(wnd
, row
, 24, "%11lld RPM", sensor
.value
);
203 case SENSOR_VOLTS_DC
:
204 mvwprintw(wnd
, row
, 24, "%10.2f V DC",
205 sensor
.value
/ 1000000.0);
208 mvwprintw(wnd
, row
, 24, "%10.2f A", sensor
.value
/ 1000000.0);
210 case SENSOR_INDICATOR
:
211 mvwprintw(wnd
, row
, 24, "%15s", sensor
.value
? "On" : "Off");
214 mvwprintw(wnd
, row
, 24, "%11lld raw", sensor
.value
);
217 mvwprintw(wnd
, row
, 24, "%14.2f%%", sensor
.value
/ 1000.0);
220 mvwprintw(wnd
, row
, 24, "%15.2f lx", sensor
.value
/ 1000000.0);
223 if (0 < sensor
.value
&&
224 (size_t)sensor
.value
< sizeof(drvstat
)/sizeof(drvstat
[0])) {
225 mvwprintw(wnd
, row
, 24, "%15s", drvstat
[sensor
.value
]);
229 case SENSOR_TIMEDELTA
:
230 mvwprintw(wnd
, row
, 24, "%15s", fmttime(sensor
.value
/ 1000000000.0));
232 case SENSOR_WATTHOUR
:
233 mvwprintw(wnd
, row
, 24, "%12.2f Wh", sensor
.value
/ 1000000.0);
236 mvwprintw(wnd
, row
, 24, "%10.2f Ah", sensor
.value
/ 1000000.0);
239 mvwprintw(wnd
, row
, 24, "%10lld", sensor
.value
);
242 if (sensor
.desc
[0] != '\0')
243 mvwprintw(wnd
, row
, 58, "(%s)", sensor
.desc
);
245 switch (sensor
.status
) {
246 case SENSOR_S_UNSPEC
:
248 case SENSOR_S_UNKNOWN
:
249 mvwaddstr(wnd
, row
, 45, "unknown");
252 mvwaddstr(wnd
, row
, 45, "WARNING");
255 mvwaddstr(wnd
, row
, 45, "CRITICAL");
258 mvwaddstr(wnd
, row
, 45, "OK");
264 #define SECS_PER_DAY 86400
265 #define SECS_PER_HOUR 3600
266 #define SECS_PER_MIN 60
275 static char outbuf
[LEN
];
282 if (in
>= SECS_PER_DAY
){
285 } else if (in
>= SECS_PER_HOUR
){
288 } else if (in
>= SECS_PER_MIN
){
291 } else if (in
>= 1 ){
293 /* in *= 1; */ /* no op */
294 } else if (in
== 0 ){ /* direct comparisons to floats are scary */
296 } else if (in
>= 1e-3 ){
299 } else if (in
>= 1e-6 ){
302 } else if (in
>= 1e-9 ){
312 snprintf(outbuf
, LEN
,
313 tiny
? "%s%lf %s" : "%s%.3lf %s",
314 signbit
== -1 ? "-" : "", in
, unit
);
320 cmdsensors(const char *cmd
, char *args
)
322 if (prefix(cmd
, "type")) {
326 for (i
= 0; i
< SENSOR_MAX_TYPES
; ++i
)
327 sensors_enabled
[i
] = 0;
329 while ((t
= strsep(&args
, " ")) != NULL
) {
334 for (i
= 0; i
< SENSOR_MAX_TYPES
; ++i
) {
335 if (strcmp(t
, sensor_type_s
[i
]) == 0) {
336 sensors_enabled
[i
] = 1;
343 for (i
= 0; i
< SENSOR_MAX_TYPES
; ++i
)
344 sensors_enabled
[i
] = 1;
346 } else if (prefix(cmd
, "match")) {
349 sensordev_xname_cnt
= 0;
350 while ((xname
= strsep(&args
, " ")) != NULL
) {
351 struct sensordev_xname
*x
;
352 int xname_len
, cp_len
;
354 xname_len
= strlen(xname
);
358 x
= &sensordev_xname
[sensordev_xname_cnt
];
361 if (xname
[xname_len
- 1] == '*') {
365 x
->flags
|= XNAME_FLAG_WILDCARD
;
368 if (cp_len
>= (int)sizeof(x
->xname
))
369 cp_len
= sizeof(x
->xname
) - 1;
371 memcpy(x
->xname
, xname
, cp_len
);
372 x
->xname
[cp_len
] = '\0';
373 x
->xname_len
= strlen(x
->xname
);
375 sensordev_xname_cnt
++;
376 if (sensordev_xname_cnt
== XNAME_MAX
)