2
0
mirror of https://github.com/lm-sensors/lm-sensors synced 2025-08-31 06:15:15 +00:00

sensors: Added support for additional sensor attributes

git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@5943 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Guenter Roeck
2011-03-16 17:23:33 +00:00
parent aea4b6cbe8
commit 57815ea1c7
3 changed files with 281 additions and 243 deletions

View File

@@ -30,6 +30,8 @@
#include "lib/sensors.h"
#include "lib/error.h"
#define ARRAY_SIZE(arr) (int)(sizeof(arr) / sizeof((arr)[0]))
void print_chip_raw(const sensors_chip_name *name)
{
int a, b, err;
@@ -126,38 +128,159 @@ static int get_label_size(const sensors_chip_name *name)
return max_size + 2;
}
static void print_temp_limits(double limit1, double limit2,
const char *name1, const char *name2, int alarm)
static void print_alarms(struct sensor_subfeature_data *alarms, int alarm_count,
int leading_spaces)
{
if (fahrenheit) {
limit1 = deg_ctof(limit1);
limit2 = deg_ctof(limit2);
}
int i, printed;
if (name2) {
printf("(%-4s = %+5.1f%s, %-4s = %+5.1f%s) ",
name1, limit1, degstr,
name2, limit2, degstr);
} else if (name1) {
printf("(%-4s = %+5.1f%s) ",
name1, limit1, degstr);
} else {
printf(" ");
printf("%*s", leading_spaces + 7, "ALARM");
if (alarm_count > 1 || alarms[0].name) {
printf(" (");
for (i = printed = 0; i < alarm_count; i++) {
if (alarms[i].name) {
if (printed)
printf(", ");
printf("%s", alarms[i].name);
printed = 1;
}
}
printf(")");
}
if (alarm)
printf("ALARM ");
}
static void print_limits(struct sensor_subfeature_data *limits,
int limit_count,
struct sensor_subfeature_data *alarms,
int alarm_count, int label_size,
const char *fmt)
{
int i;
int alarms_printed = 0;
for (i = 0; i < limit_count; i++) {
if (!(i & 1)) {
if (i)
printf("\n%*s", label_size + 10, "");
printf("(");
} else {
printf(", ");
}
printf(fmt, limits[i].name, limits[i].value,
limits[i].unit);
if ((i & 1) || i == limit_count - 1) {
printf(")");
if (alarm_count && !alarms_printed) {
print_alarms(alarms, alarm_count,
(i & 1) ? 0 : 16);
alarms_printed = 1;
}
}
}
if (alarm_count && !alarms_printed)
print_alarms(alarms, alarm_count, 32);
}
/*
* Get sensor limit information.
* *num_limits and *num_alarms must be initialized by the caller.
*/
static void get_sensor_limit_data(const sensors_chip_name *name,
const sensors_feature *feature,
const struct sensor_subfeature_list *sfl,
struct sensor_subfeature_data *limits,
int max_limits,
int *num_limits,
struct sensor_subfeature_data *alarms,
int max_alarms,
int *num_alarms)
{
const sensors_subfeature *sf;
for (; sfl->subfeature >= 0; sfl++) {
sf = sensors_get_subfeature(name, feature, sfl->subfeature);
if (sf) {
if (sfl->alarm) {
/*
* Only queue alarm subfeatures if the alarm
* is active, and don't store the alarm value
* (it is implied to be active if queued).
*/
if (get_value(name, sf)) {
if (*num_alarms >= max_alarms) {
fprintf(stderr,
"Not enough %s buffers (%d)\n",
"alarm", max_alarms);
} else {
alarms[*num_alarms].name = sfl->name;
(*num_alarms)++;
}
}
} else {
/*
* Always queue limit subfeatures with their value.
*/
if (*num_limits >= max_limits) {
fprintf(stderr,
"Not enough %s buffers (%d)\n",
"limit", max_limits);
} else {
limits[*num_limits].value = get_value(name, sf);
limits[*num_limits].name = sfl->name;
(*num_limits)++;
}
}
if (sfl->exists) {
get_sensor_limit_data(name, feature, sfl->exists,
limits, max_limits, num_limits,
alarms, max_alarms, num_alarms);
}
}
}
}
static const struct sensor_subfeature_list temp_max_sensors[] = {
{ SENSORS_SUBFEATURE_TEMP_MAX_HYST, NULL, 0, "hyst" },
{ -1, NULL, 0, NULL }
};
static const struct sensor_subfeature_list temp_crit_sensors[] = {
{ SENSORS_SUBFEATURE_TEMP_CRIT_HYST, NULL, 0, "crit hyst" },
{ -1, NULL, 0, NULL }
};
static const struct sensor_subfeature_list temp_emergency_sensors[] = {
{ SENSORS_SUBFEATURE_TEMP_EMERGENCY_HYST, NULL, 0,
"emerg hyst" },
{ -1, NULL, 0, NULL }
};
static const struct sensor_subfeature_list temp_sensors[] = {
{ SENSORS_SUBFEATURE_TEMP_ALARM, NULL, 1, NULL },
{ SENSORS_SUBFEATURE_TEMP_LCRIT_ALARM, NULL, 1, "LCRIT" },
{ SENSORS_SUBFEATURE_TEMP_MIN_ALARM, NULL, 1, "LOW" },
{ SENSORS_SUBFEATURE_TEMP_MAX_ALARM, NULL, 1, "HIGH" },
{ SENSORS_SUBFEATURE_TEMP_CRIT_ALARM, NULL, 1, "CRIT" },
{ SENSORS_SUBFEATURE_TEMP_EMERGENCY_ALARM, NULL, 1, "EMERGENCY" },
{ SENSORS_SUBFEATURE_TEMP_MIN, NULL, 0, "low" },
{ SENSORS_SUBFEATURE_TEMP_MAX, temp_max_sensors, 0, "high" },
{ SENSORS_SUBFEATURE_TEMP_LCRIT, NULL, 0, "crit low" },
{ SENSORS_SUBFEATURE_TEMP_CRIT, temp_crit_sensors, 0, "crit" },
{ SENSORS_SUBFEATURE_TEMP_EMERGENCY, temp_emergency_sensors, 0,
"emerg" },
{ -1, NULL, 0, NULL }
};
static void print_chip_temp(const sensors_chip_name *name,
const sensors_feature *feature,
int label_size)
{
const sensors_subfeature *sf, *sfmin, *sfmax, *sfcrit, *sfhyst;
double val, limit1, limit2;
const char *s1, *s2;
int alarm, crit_displayed = 0;
struct sensor_subfeature_data sensors[8];
struct sensor_subfeature_data alarms[5];
int sensor_count, alarm_count;
const sensors_subfeature *sf;
double val;
char *label;
int i;
if (!(label = sensors_get_label(name, feature))) {
fprintf(stderr, "ERROR: Can't get label of feature %s!\n",
@@ -167,80 +290,6 @@ static void print_chip_temp(const sensors_chip_name *name,
print_label(label, label_size);
free(label);
sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_ALARM);
alarm = sf && get_value(name, sf);
sfmin = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_MIN);
sfmax = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_MAX);
sfcrit = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_CRIT);
if (sfmax) {
sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_MAX_ALARM);
if (sf && get_value(name, sf))
alarm |= 1;
if (sfmin) {
limit1 = get_value(name, sfmin);
s1 = "low";
limit2 = get_value(name, sfmax);
s2 = "high";
sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_MIN_ALARM);
if (sf && get_value(name, sf))
alarm |= 1;
} else {
limit1 = get_value(name, sfmax);
s1 = "high";
sfhyst = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_MAX_HYST);
if (sfhyst) {
limit2 = get_value(name, sfhyst);
s2 = "hyst";
} else if (sfcrit) {
limit2 = get_value(name, sfcrit);
s2 = "crit";
sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_CRIT_ALARM);
if (sf && get_value(name, sf))
alarm |= 1;
crit_displayed = 1;
} else {
limit2 = 0;
s2 = NULL;
}
}
} else if (sfcrit) {
limit1 = get_value(name, sfcrit);
s1 = "crit";
sfhyst = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_CRIT_HYST);
if (sfhyst) {
limit2 = get_value(name, sfhyst);
s2 = "hyst";
} else {
limit2 = 0;
s2 = NULL;
}
sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_CRIT_ALARM);
if (sf && get_value(name, sf))
alarm |= 1;
crit_displayed = 1;
} else {
limit1 = limit2 = 0;
s1 = s2 = NULL;
}
sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_FAULT);
if (sf && get_value(name, sf)) {
@@ -256,30 +305,21 @@ static void print_chip_temp(const sensors_chip_name *name,
} else
printf(" N/A ");
}
print_temp_limits(limit1, limit2, s1, s2, alarm);
if (!crit_displayed && sfcrit) {
limit1 = get_value(name, sfcrit);
s1 = "crit";
sensor_count = alarm_count = 0;
get_sensor_limit_data(name, feature, temp_sensors,
sensors, ARRAY_SIZE(sensors), &sensor_count,
alarms, ARRAY_SIZE(alarms), &alarm_count);
sfhyst = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_CRIT_HYST);
if (sfhyst) {
limit2 = get_value(name, sfhyst);
s2 = "hyst";
} else {
limit2 = 0;
s2 = NULL;
}
sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_CRIT_ALARM);
alarm = sf && get_value(name, sf);
printf("\n%*s", label_size + 10, "");
print_temp_limits(limit1, limit2, s1, s2, alarm);
for (i = 0; i < sensor_count; i++) {
if (fahrenheit)
sensors[i].value = deg_ctof(sensors[i].value);
sensors[i].unit = degstr;
}
print_limits(sensors, sensor_count, alarms, alarm_count, label_size,
"%-4s = %+5.1f%s");
/* print out temperature sensor info */
sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_TYPE);
@@ -291,7 +331,7 @@ static void print_chip_temp(const sensors_chip_name *name,
if (sens > 1000)
sens = 4;
printf("sensor = %s", sens == 0 ? "disabled" :
printf(" sensor = %s", sens == 0 ? "disabled" :
sens == 1 ? "diode" :
sens == 2 ? "transistor" :
sens == 3 ? "thermal diode" :
@@ -302,13 +342,29 @@ static void print_chip_temp(const sensors_chip_name *name,
printf("\n");
}
static const struct sensor_subfeature_list voltage_sensors[] = {
{ SENSORS_SUBFEATURE_IN_ALARM, NULL, 1, NULL },
{ SENSORS_SUBFEATURE_IN_LCRIT_ALARM, NULL, 1, "LCRIT" },
{ SENSORS_SUBFEATURE_IN_MIN_ALARM, NULL, 1, "MIN" },
{ SENSORS_SUBFEATURE_IN_MAX_ALARM, NULL, 1, "MAX" },
{ SENSORS_SUBFEATURE_IN_CRIT_ALARM, NULL, 1, "CRIT" },
{ SENSORS_SUBFEATURE_IN_LCRIT, NULL, 0, "crit min" },
{ SENSORS_SUBFEATURE_IN_MIN, NULL, 0, "min" },
{ SENSORS_SUBFEATURE_IN_MAX, NULL, 0, "max" },
{ SENSORS_SUBFEATURE_IN_CRIT, NULL, 0, "crit max" },
{ -1, NULL, 0, NULL }
};
static void print_chip_in(const sensors_chip_name *name,
const sensors_feature *feature,
int label_size)
{
const sensors_subfeature *sf, *sfmin, *sfmax;
double val, alarm_max, alarm_min;
const sensors_subfeature *sf;
char *label;
struct sensor_subfeature_data sensors[4];
struct sensor_subfeature_data alarms[4];
int sensor_count, alarm_count;
double val;
if (!(label = sensors_get_label(name, feature))) {
fprintf(stderr, "ERROR: Can't get label of feature %s!\n",
@@ -321,49 +377,17 @@ static void print_chip_in(const sensors_chip_name *name,
sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_IN_INPUT);
if (sf && get_input_value(name, sf, &val) == 0)
printf("%+6.2f V", val);
printf("%+6.2f V ", val);
else
printf(" N/A");
printf(" N/A ");
sfmin = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_IN_MIN);
sfmax = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_IN_MAX);
if (sfmin && sfmax)
printf(" (min = %+6.2f V, max = %+6.2f V)",
get_value(name, sfmin),
get_value(name, sfmax));
else if (sfmin)
printf(" (min = %+6.2f V)",
get_value(name, sfmin));
else if (sfmax)
printf(" (max = %+6.2f V)",
get_value(name, sfmax));
sensor_count = alarm_count = 0;
get_sensor_limit_data(name, feature, voltage_sensors,
sensors, ARRAY_SIZE(sensors), &sensor_count,
alarms, ARRAY_SIZE(alarms), &alarm_count);
sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_IN_ALARM);
sfmin = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_IN_MIN_ALARM);
sfmax = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_IN_MAX_ALARM);
if (sfmin || sfmax) {
alarm_max = sfmax ? get_value(name, sfmax) : 0;
alarm_min = sfmin ? get_value(name, sfmin) : 0;
if (alarm_min || alarm_max) {
printf(" ALARM (");
if (alarm_min)
printf("MIN");
if (alarm_max)
printf("%sMAX", (alarm_min) ? ", " : "");
printf(")");
}
} else if (sf) {
printf(" %s",
get_value(name, sf) ? "ALARM" : "");
}
print_limits(sensors, sensor_count, alarms, alarm_count, label_size,
"%s = %+6.2f V");
printf("\n");
}
@@ -455,15 +479,43 @@ static void scale_value(double *value, const char **prefixstr)
*prefixstr = scale->unit;
}
static const struct sensor_subfeature_list power_common_sensors[] = {
{ SENSORS_SUBFEATURE_POWER_ALARM, NULL, 1, NULL },
{ SENSORS_SUBFEATURE_POWER_MAX_ALARM, NULL, 1, "MAX" },
{ SENSORS_SUBFEATURE_POWER_CRIT_ALARM, NULL, 1, "CRIT" },
{ SENSORS_SUBFEATURE_POWER_CAP_ALARM, NULL, 1, "CAP" },
{ SENSORS_SUBFEATURE_POWER_MAX, NULL, 0, "max" },
{ SENSORS_SUBFEATURE_POWER_CRIT, NULL, 0, "crit" },
{ SENSORS_SUBFEATURE_POWER_CAP, NULL, 0, "cap" },
{ -1, NULL, 0, NULL }
};
static const struct sensor_subfeature_list power_inst_sensors[] = {
{ SENSORS_SUBFEATURE_POWER_INPUT_LOWEST, NULL, 0, "lowest" },
{ SENSORS_SUBFEATURE_POWER_INPUT_HIGHEST, NULL, 0, "highest" },
{ -1, NULL, 0, NULL }
};
static const struct sensor_subfeature_list power_avg_sensors[] = {
{ SENSORS_SUBFEATURE_POWER_AVERAGE_LOWEST, NULL, 0, "lowest" },
{ SENSORS_SUBFEATURE_POWER_AVERAGE_HIGHEST, NULL, 0, "highest" },
{ SENSORS_SUBFEATURE_POWER_AVERAGE_INTERVAL, NULL, 0,
"interval" },
{ -1, NULL, 0, NULL }
};
static void print_chip_power(const sensors_chip_name *name,
const sensors_feature *feature,
int label_size)
{
double val;
int need_space = 0;
const sensors_subfeature *sf, *sfmin, *sfmax, *sfint;
const sensors_subfeature *sf;
struct sensor_subfeature_data sensors[6];
struct sensor_subfeature_data alarms[3];
int sensor_count, alarm_count;
char *label;
const char *unit;
int i;
if (!(label = sensors_get_label(name, feature))) {
fprintf(stderr, "ERROR: Can't get label of feature %s!\n",
@@ -473,59 +525,37 @@ static void print_chip_power(const sensors_chip_name *name,
print_label(label, label_size);
free(label);
sensor_count = alarm_count = 0;
/* Power sensors come in 2 flavors: instantaneous and averaged.
To keep things simple, we assume that each sensor only implements
one flavor. */
sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_POWER_INPUT);
if (sf) {
sfmin = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_POWER_INPUT_HIGHEST);
sfmax = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_POWER_INPUT_LOWEST);
sfint = NULL;
} else {
get_sensor_limit_data(name, feature,
sf ? power_inst_sensors : power_avg_sensors,
sensors, ARRAY_SIZE(sensors), &sensor_count,
alarms, ARRAY_SIZE(alarms), &alarm_count);
/* Add sensors common to both flavors. */
get_sensor_limit_data(name, feature,
power_common_sensors,
sensors, ARRAY_SIZE(sensors), &sensor_count,
alarms, ARRAY_SIZE(alarms), &alarm_count);
if (!sf)
sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_POWER_AVERAGE);
sfmin = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_POWER_AVERAGE_HIGHEST);
sfmax = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_POWER_AVERAGE_LOWEST);
sfint = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_POWER_AVERAGE_INTERVAL);
}
if (sf && get_input_value(name, sf, &val) == 0) {
scale_value(&val, &unit);
printf("%6.2f %sW", val, unit);
printf("%6.2f %sW ", val, unit);
} else
printf(" N/A");
printf(" N/A ");
if (sfmin || sfmax || sfint) {
printf(" (");
for (i = 0; i < sensor_count; i++)
scale_value(&sensors[i].value, &sensors[i].unit);
if (sfmin) {
val = get_value(name, sfmin);
scale_value(&val, &unit);
printf("min = %6.2f %sW", val, unit);
need_space = 1;
}
if (sfmax) {
val = get_value(name, sfmax);
scale_value(&val, &unit);
printf("%smax = %6.2f %sW", (need_space ? ", " : ""),
val, unit);
need_space = 1;
}
if (sfint) {
printf("%sinterval = %6.2f s", (need_space ? ", " : ""),
get_value(name, sfint));
need_space = 1;
}
printf(")");
}
print_limits(sensors, sensor_count, alarms, alarm_count,
label_size, "%s = %6.2f %sW");
printf("\n");
}
@@ -600,13 +630,29 @@ static void print_chip_beep_enable(const sensors_chip_name *name,
free(label);
}
static const struct sensor_subfeature_list current_sensors[] = {
{ SENSORS_SUBFEATURE_CURR_ALARM, NULL, 1, NULL },
{ SENSORS_SUBFEATURE_CURR_LCRIT_ALARM, NULL, 1, "LCRIT" },
{ SENSORS_SUBFEATURE_CURR_MIN_ALARM, NULL, 1, "MIN" },
{ SENSORS_SUBFEATURE_CURR_MAX_ALARM, NULL, 1, "MAX" },
{ SENSORS_SUBFEATURE_CURR_CRIT_ALARM, NULL, 1, "CRIT" },
{ SENSORS_SUBFEATURE_CURR_LCRIT, NULL, 0, "crit min" },
{ SENSORS_SUBFEATURE_CURR_MIN, NULL, 0, "min" },
{ SENSORS_SUBFEATURE_CURR_MAX, NULL, 0, "max" },
{ SENSORS_SUBFEATURE_CURR_CRIT, NULL, 0, "crit max" },
{ -1, NULL, 0, NULL }
};
static void print_chip_curr(const sensors_chip_name *name,
const sensors_feature *feature,
int label_size)
{
const sensors_subfeature *sf, *sfmin, *sfmax;
double alarm_max, alarm_min, val;
const sensors_subfeature *sf;
double val;
char *label;
struct sensor_subfeature_data sensors[4];
struct sensor_subfeature_data alarms[4];
int sensor_count, alarm_count;
if (!(label = sensors_get_label(name, feature))) {
fprintf(stderr, "ERROR: Can't get label of feature %s!\n",
@@ -619,49 +665,17 @@ static void print_chip_curr(const sensors_chip_name *name,
sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_CURR_INPUT);
if (sf && get_input_value(name, sf, &val) == 0)
printf("%+6.2f A", val);
printf("%+6.2f A ", val);
else
printf(" N/A");
printf(" N/A ");
sfmin = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_CURR_MIN);
sfmax = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_CURR_MAX);
if (sfmin && sfmax)
printf(" (min = %+6.2f A, max = %+6.2f A)",
get_value(name, sfmin),
get_value(name, sfmax));
else if (sfmin)
printf(" (min = %+6.2f A)",
get_value(name, sfmin));
else if (sfmax)
printf(" (max = %+6.2f A)",
get_value(name, sfmax));
sensor_count = alarm_count = 0;
get_sensor_limit_data(name, feature, current_sensors,
sensors, ARRAY_SIZE(sensors), &sensor_count,
alarms, ARRAY_SIZE(alarms), &alarm_count);
sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_CURR_ALARM);
sfmin = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_CURR_MIN_ALARM);
sfmax = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_CURR_MAX_ALARM);
if (sfmin || sfmax) {
alarm_max = sfmax ? get_value(name, sfmax) : 0;
alarm_min = sfmin ? get_value(name, sfmin) : 0;
if (alarm_min || alarm_max) {
printf(" ALARM (");
if (alarm_min)
printf("MIN");
if (alarm_max)
printf("%sMAX", (alarm_min) ? ", " : "");
printf(")");
}
} else if (sf) {
printf(" %s",
get_value(name, sf) ? "ALARM" : "");
}
print_limits(sensors, sensor_count, alarms, alarm_count, label_size,
"%s = %+6.2f A");
printf("\n");
}