2 * Copyright (C) 2010-2016 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)
127 if (!init_done || !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, min_subfeature,
162 if (sensors_snprintf_chip_name(name, 200, chip) < 0)
165 if (feature->type == SENSORS_FEATURE_TEMP) {
166 fault_subfeature = SENSORS_SUBFEATURE_TEMP_FAULT;
167 max_subfeature = SENSORS_SUBFEATURE_TEMP_MAX;
168 min_subfeature = SENSORS_SUBFEATURE_TEMP_MIN;
169 } else if (feature->type == SENSORS_FEATURE_FAN) {
170 fault_subfeature = SENSORS_SUBFEATURE_FAN_FAULT;
171 max_subfeature = SENSORS_SUBFEATURE_FAN_MAX;
172 min_subfeature = SENSORS_SUBFEATURE_FAN_MIN;
174 log_err(_("%s: Wrong feature type."), PROVIDER_NAME);
178 sf = sensors_get_subfeature(chip, feature, fault_subfeature);
179 if (sf && get_value(chip, sf))
182 label = sensors_get_label(chip, feature);
186 type = SENSOR_TYPE_LMSENSOR;
187 if (feature->type == SENSORS_FEATURE_TEMP)
188 type |= SENSOR_TYPE_TEMP;
189 else if (feature->type == SENSORS_FEATURE_FAN)
190 type |= (SENSOR_TYPE_RPM|SENSOR_TYPE_FAN);
194 id = malloc(strlen(PROVIDER_NAME)
200 sprintf(id, "%s %s %s", PROVIDER_NAME, name, label);
202 if (!strcmp(chip->prefix, "coretemp"))
203 cname = strdup(_("Intel CPU"));
204 else if (!strcmp(chip->prefix, "k10temp")
205 || !strcmp(chip->prefix, "k8temp")
206 || !strcmp(chip->prefix, "fam15h_power"))
207 cname = strdup(_("AMD CPU"));
208 else if (!strcmp(chip->prefix, "nouveau"))
209 cname = strdup(_("NVIDIA GPU"));
210 else if (!strcmp(chip->prefix, "via-cputemp"))
211 cname = strdup(_("VIA CPU"));
212 else if (!strcmp(chip->prefix, "acpitz"))
213 cname = strdup(_("ACPI"));
215 cname = strdup(chip->prefix);
217 psensor = psensor_create(id, label, cname, type, values_max_length);
219 sf = sensors_get_subfeature(chip, feature, max_subfeature);
221 psensor->max = get_value(chip, sf);
223 sf = sensors_get_subfeature(chip, feature, min_subfeature);
225 psensor->min = get_value(chip, sf);
227 lmsensor_data_set(psensor, chip, feature);
229 if (feature->type == SENSORS_FEATURE_TEMP
230 && (get_temp_input(psensor) == UNKNOWN_DBL_VALUE)) {
238 static void lmsensor_init(void)
242 err = sensors_init(NULL);
245 log_err(_("%s: initialization failure: %s."),
247 sensors_strerror(err));
254 void lmsensor_psensor_list_append(struct psensor ***sensors, int vn)
256 const sensors_chip_name *chip;
258 const sensors_feature *feature;
268 while ((chip = sensors_get_detected_chips(NULL, &chip_nr))) {
271 while ((feature = sensors_get_features(chip, &i))) {
272 if (feature->type == SENSORS_FEATURE_TEMP
273 || feature->type == SENSORS_FEATURE_FAN) {
275 s = lmsensor_psensor_create(chip, feature, vn);
278 psensor_list_append(sensors, s);
284 void lmsensor_cleanup(void)