2 * Copyright (C) 2010-2014 jeanfi@gmail.com
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #define _(str) gettext(str)
27 #include <sensors/sensors.h>
28 #include <sensors/error.h>
34 static const char *PROVIDER_NAME = "lmsensor";
36 struct lmsensor_data {
37 const sensors_chip_name *chip;
39 const sensors_feature *feature;
42 static const sensors_chip_name *get_chip_name(struct psensor *s)
44 return ((struct lmsensor_data *)s->provider_data)->chip;
47 static const sensors_feature *get_feature(struct psensor *s)
49 return ((struct lmsensor_data *)s->provider_data)->feature;
52 static void lmsensor_data_set(struct psensor *s,
53 const struct sensors_chip_name *chip,
54 const struct sensors_feature *feature)
56 struct lmsensor_data *data;
58 data = malloc(sizeof(struct lmsensor_data));
60 data->feature = feature;
62 s->provider_data = data;
65 static double get_value(const sensors_chip_name *name,
66 const sensors_subfeature *sub)
71 err = sensors_get_value(name, sub->number, &val);
73 log_err(_("%s: Cannot get value of subfeature %s: %s."),
76 sensors_strerror(err));
77 val = UNKNOWN_DBL_VALUE;
82 static double get_temp_input(struct psensor *sensor)
84 const sensors_subfeature *sf;
86 const sensors_chip_name *chip;
88 const sensors_feature *feature;
90 chip = get_chip_name(sensor);
91 feature = get_feature(sensor);
93 sf = sensors_get_subfeature(chip,
95 SENSORS_SUBFEATURE_TEMP_INPUT);
97 return get_value(chip, sf);
99 return UNKNOWN_DBL_VALUE;
102 static double get_fan_input(struct psensor *sensor)
104 const sensors_chip_name *chip;
105 const sensors_feature *feature;
107 const sensors_subfeature *sf;
109 chip = get_chip_name(sensor);
110 feature = get_feature(sensor);
112 sf = sensors_get_subfeature(chip,
114 SENSORS_SUBFEATURE_FAN_INPUT);
117 return get_value(chip, sf);
119 return UNKNOWN_DBL_VALUE;
122 void lmsensor_psensor_list_update(struct psensor **sensors)
133 if (!(s->type & SENSOR_TYPE_REMOTE)
134 && s->type & SENSOR_TYPE_LMSENSOR) {
136 if (s->type & SENSOR_TYPE_TEMP)
137 v = get_temp_input(s);
138 else /* s->type & SENSOR_TYPE_RPM */
139 v = get_fan_input(s);
141 if (v != UNKNOWN_DBL_VALUE)
142 psensor_set_current_value(s, v);
149 static struct psensor *
150 lmsensor_psensor_create(const sensors_chip_name *chip,
151 const sensors_feature *feature,
152 int values_max_length)
155 const sensors_subfeature *sf;
157 char *id, *label, *cname;
158 struct psensor *psensor;
159 sensors_subfeature_type fault_subfeature;
161 if (sensors_snprintf_chip_name(name, 200, chip) < 0)
164 if (feature->type == SENSORS_FEATURE_TEMP) {
165 fault_subfeature = SENSORS_SUBFEATURE_TEMP_FAULT;
166 } else if (feature->type == SENSORS_FEATURE_FAN) {
167 fault_subfeature = SENSORS_SUBFEATURE_FAN_FAULT;
169 log_err(_("%s: Wrong feature type."), PROVIDER_NAME);
173 sf = sensors_get_subfeature(chip, feature, fault_subfeature);
174 if (sf && get_value(chip, sf))
177 label = sensors_get_label(chip, feature);
181 type = SENSOR_TYPE_LMSENSOR;
182 if (feature->type == SENSORS_FEATURE_TEMP)
183 type |= SENSOR_TYPE_TEMP;
184 else if (feature->type == SENSORS_FEATURE_FAN)
185 type |= (SENSOR_TYPE_RPM|SENSOR_TYPE_FAN);
189 id = malloc(strlen(PROVIDER_NAME)
195 sprintf(id, "%s %s %s", PROVIDER_NAME, name, label);
197 if (!strcmp(chip->prefix, "coretemp"))
198 cname = strdup(_("Intel CPU"));
199 else if (!strcmp(chip->prefix, "k10temp")
200 || !strcmp(chip->prefix, "k8temp")
201 || !strcmp(chip->prefix, "fam15h_power"))
202 cname = strdup(_("AMD CPU"));
203 else if (!strcmp(chip->prefix, "nouveau"))
204 cname = strdup(_("NVIDIA GPU"));
205 else if (!strcmp(chip->prefix, "via-cputemp"))
206 cname = strdup(_("VIA CPU"));
207 else if (!strcmp(chip->prefix, "acpitz"))
208 cname = strdup(_("ACPI"));
210 cname = strdup(chip->prefix);
212 psensor = psensor_create(id, label, cname, type, values_max_length);
215 sf = sensors_get_subfeature(chip, feature, SENSORS_SUBFEATURE_TEMP_MAX);
217 psensor->max = get_value(chip, sf);
219 sf = sensors_get_subfeature(chip, feature, SENSORS_SUBFEATURE_TEMP_MIN);
221 psensor->min = get_value(chip, sf);
223 lmsensor_data_set(psensor, chip, feature);
225 if (feature->type == SENSORS_FEATURE_TEMP
226 && (get_temp_input(psensor) == UNKNOWN_DBL_VALUE)) {
234 static void lmsensor_init(void)
238 err = sensors_init(NULL);
241 log_err(_("%s: initialization failure: %s."),
243 sensors_strerror(err));
250 void lmsensor_psensor_list_append(struct psensor ***sensors, int vn)
252 const sensors_chip_name *chip;
254 const sensors_feature *feature;
264 while ((chip = sensors_get_detected_chips(NULL, &chip_nr))) {
267 while ((feature = sensors_get_features(chip, &i))) {
268 if (feature->type == SENSORS_FEATURE_TEMP
269 || feature->type == SENSORS_FEATURE_FAN) {
271 s = lmsensor_psensor_create(chip, feature, vn);
274 psensor_list_append(sensors, s);
280 void lmsensor_cleanup(void)