@cryptotaxi247 / netdata-1 / commits / 87b992b37

Sensors (windows.plugin) (#21266)

thiagoftsm committed Nov 13, 2025 at 22:46 UTC 87b992b3788eaf24b01a33fd195176e8e442427a
3 files changed +424 -184
src/collectors/all.h
+16
@@ -454,6 +454,22 @@
454
455 // Sensors
456 #define NETDATA_CHART_PRIO_SENSORS 70000 // many charts
457 +#define NETDATA_CHART_PRIO_SENSOR_CURRENT 70003
458 +#define NETDATA_CHART_PRIO_SENSOR_HUMIDITY 70004
459 +#define NETDATA_CHART_PRIO_SENSOR_POWER 70006
460 +#define NETDATA_CHART_PRIO_SENSOR_LUX 70010
461 +#define NETDATA_CHART_PRIO_SENSOR_TEMPERATURE 70011
462 +#define NETDATA_CHART_PRIO_SENSOR_VOLTAGE 70012
463 +#define NETDATA_CHART_PRIO_SENSOR_RESISTENCE 70013
464 +#define NETDATA_CHART_PRIO_SENSOR_AMBIENT_PRESSURE 70014
465 +#define NETDATA_CHART_PRIO_SENSOR_LATITUDE 70015
466 +#define NETDATA_CHART_PRIO_SENSOR_LONGITUDE 70016
467 +#define NETDATA_CHART_PRIO_SENSOR_FORCE 70017
468 +#define NETDATA_CHART_PRIO_SENSOR_GAUGE_PRESSURE 70018
469 +#define NETDATA_CHART_PRIO_SENSOR_DISTANCE 70019
470 +#define NETDATA_CHART_PRIO_SENSOR_ACCELERATION 70022
471 +#define NETDATA_CHART_PRIO_SENSOR_MIN_CUSTOM 70100 // Windows only
472 +#define NETDATA_CHART_PRIO_SENSOR_MAX_CUSTOM 70128 // Windows only
473
474 // STATSD
475
src/collectors/windows.plugin/GetSensors.c
+391 -182
@@ -36,43 +36,108 @@ enum netdata_win_sensor_monitored {
36 NETDATA_WIN_SENSOR_TYPE_DISTANCE_X,
37 NETDATA_WIN_SENSOR_ACCELERATION_X_G,
38
39 - NETDATA_WIN_SENSOR_NEVER_USE_ME,
39 + NETDATA_WIN_SENSOR_LAST_WELL_DEFINED,
40
41 // Remaining axis should be added here
42 NETDATA_WIN_SENSOR_TYPE_DISTANCE_Y,
43 NETDATA_WIN_SENSOR_TYPE_DISTANCE_Z,
44 NETDATA_WIN_SENSOR_ACCELERATION_Y_G,
45 - NETDATA_WIN_SENSOR_ACCELERATION_Z_G
45 + NETDATA_WIN_SENSOR_ACCELERATION_Z_G,
46 +
47 + NETDATA_WIN_SENSOR_NEVER_USE_ME,
48 +
49 + // Custom sensors
50 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_USAGE,
51 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_BOOLEAN_ARRAY,
52 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE1,
53 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE2,
54 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE3,
55 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE4,
56 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE5,
57 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE6,
58 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE7,
59 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE8,
60 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE9,
61 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE10,
62 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE11,
63 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE12,
64 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE13,
65 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE14,
66 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE15,
67 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE16,
68 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE17,
69 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE18,
70 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE19,
71 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE20,
72 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE21,
73 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE22,
74 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE23,
75 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE24,
76 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE25,
77 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE26,
78 + NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE27
79 };
80
81 REFPROPERTYKEY sensor_keys[] = {
49 - &SENSOR_DATA_TYPE_TEMPERATURE_CELSIUS,
50 - &SENSOR_DATA_TYPE_ELECTRICAL_POWER_WATTS,
51 - &SENSOR_DATA_TYPE_CURRENT_AMPS,
52 - &SENSOR_DATA_TYPE_RELATIVE_HUMIDITY_PERCENT,
53 - &SENSOR_DATA_TYPE_LIGHT_LEVEL_LUX,
54 - &SENSOR_DATA_TYPE_LIGHT_TEMPERATURE_KELVIN,
55 - &SENSOR_DATA_TYPE_VOLTAGE_VOLTS,
56 - &SENSOR_DATA_TYPE_RESISTANCE_OHMS,
57 - &SENSOR_DATA_TYPE_ATMOSPHERIC_PRESSURE_BAR,
58 - &SENSOR_DATA_TYPE_LATITUDE_DEGREES,
59 - &SENSOR_DATA_TYPE_LONGITUDE_DEGREES,
60 - &SENSOR_DATA_TYPE_FORCE_NEWTONS,
61 - &SENSOR_DATA_TYPE_GAUGE_PRESSURE_PASCAL,
62 -
63 - // Add only one vector axis here
64 - &SENSOR_DATA_TYPE_DISTANCE_X_METERS,
65 - &SENSOR_DATA_TYPE_ACCELERATION_X_G,
66 -
67 - // Main loop stop
68 - NULL,
82 + &SENSOR_DATA_TYPE_TEMPERATURE_CELSIUS,
83 + &SENSOR_DATA_TYPE_ELECTRICAL_POWER_WATTS,
84 + &SENSOR_DATA_TYPE_CURRENT_AMPS,
85 + &SENSOR_DATA_TYPE_RELATIVE_HUMIDITY_PERCENT,
86 + &SENSOR_DATA_TYPE_LIGHT_LEVEL_LUX,
87 + &SENSOR_DATA_TYPE_LIGHT_TEMPERATURE_KELVIN,
88 + &SENSOR_DATA_TYPE_VOLTAGE_VOLTS,
89 + &SENSOR_DATA_TYPE_RESISTANCE_OHMS,
90 + &SENSOR_DATA_TYPE_ATMOSPHERIC_PRESSURE_BAR,
91 + &SENSOR_DATA_TYPE_LATITUDE_DEGREES,
92 + &SENSOR_DATA_TYPE_LONGITUDE_DEGREES,
93 + &SENSOR_DATA_TYPE_FORCE_NEWTONS,
94 + &SENSOR_DATA_TYPE_GAUGE_PRESSURE_PASCAL,
95
70 - // Remaining axis should be added here
71 - &SENSOR_DATA_TYPE_DISTANCE_Y_METERS,
72 - &SENSOR_DATA_TYPE_DISTANCE_Z_METERS,
73 - &SENSOR_DATA_TYPE_ACCELERATION_Y_G,
74 - &SENSOR_DATA_TYPE_ACCELERATION_Z_G};
96 + // Add only one vector axis here
97 + &SENSOR_DATA_TYPE_DISTANCE_X_METERS,
98 + &SENSOR_DATA_TYPE_ACCELERATION_X_G,
99
100 + // Main loop stop
101 + NULL,
102 +
103 + // Remaining axis should be added here
104 + &SENSOR_DATA_TYPE_DISTANCE_Y_METERS,
105 + &SENSOR_DATA_TYPE_DISTANCE_Z_METERS,
106 + &SENSOR_DATA_TYPE_ACCELERATION_Y_G,
107 + &SENSOR_DATA_TYPE_ACCELERATION_Z_G,
108 +
109 + // Stop additional
110 + NULL,
111 +
112 + &SENSOR_DATA_TYPE_CUSTOM_USAGE,
113 + &SENSOR_DATA_TYPE_CUSTOM_BOOLEAN_ARRAY,
114 + &SENSOR_DATA_TYPE_CUSTOM_VALUE1,
115 + &SENSOR_DATA_TYPE_CUSTOM_VALUE2,
116 + &SENSOR_DATA_TYPE_CUSTOM_VALUE3,
117 + &SENSOR_DATA_TYPE_CUSTOM_VALUE4,
118 + &SENSOR_DATA_TYPE_CUSTOM_VALUE5,
119 + &SENSOR_DATA_TYPE_CUSTOM_VALUE6,
120 + &SENSOR_DATA_TYPE_CUSTOM_VALUE7,
121 + &SENSOR_DATA_TYPE_CUSTOM_VALUE8,
122 + &SENSOR_DATA_TYPE_CUSTOM_VALUE9,
123 + &SENSOR_DATA_TYPE_CUSTOM_VALUE10,
124 + &SENSOR_DATA_TYPE_CUSTOM_VALUE11,
125 + &SENSOR_DATA_TYPE_CUSTOM_VALUE12,
126 + &SENSOR_DATA_TYPE_CUSTOM_VALUE13,
127 + &SENSOR_DATA_TYPE_CUSTOM_VALUE14,
128 + &SENSOR_DATA_TYPE_CUSTOM_VALUE15,
129 + &SENSOR_DATA_TYPE_CUSTOM_VALUE16,
130 + &SENSOR_DATA_TYPE_CUSTOM_VALUE17,
131 + &SENSOR_DATA_TYPE_CUSTOM_VALUE18,
132 + &SENSOR_DATA_TYPE_CUSTOM_VALUE19,
133 + &SENSOR_DATA_TYPE_CUSTOM_VALUE20,
134 + &SENSOR_DATA_TYPE_CUSTOM_VALUE21,
135 + &SENSOR_DATA_TYPE_CUSTOM_VALUE22,
136 + &SENSOR_DATA_TYPE_CUSTOM_VALUE23,
137 + &SENSOR_DATA_TYPE_CUSTOM_VALUE24,
138 + &SENSOR_DATA_TYPE_CUSTOM_VALUE25,
139 + &SENSOR_DATA_TYPE_CUSTOM_VALUE26,
140 + &SENSOR_DATA_TYPE_CUSTOM_VALUE27};
141
142 static struct win_sensor_config {
143 const char *title;
@@ -82,111 +147,132 @@ static struct win_sensor_config {
147
148 int priority;
149 } configs[] = {
85 - {
86 - .title = "Sensor Temperature",
87 - .units = "Cel",
88 - .context = "system.hw.sensor.temperature.input",
89 - .family = "Temperature",
90 - .priority = 70000,
91 - },
92 - {
93 - .title = "Sensor Power",
94 - .units = "W",
95 - .context = "system.hw.sensor.power.input",
96 - .family = "Power",
97 - .priority = 70006,
98 - },
99 - {
100 - .title = "Sensor Current",
101 - .units = "A",
102 - .context = "system.hw.sensor.current.input",
103 - .family = "Current",
104 - .priority = 70003,
105 - },
106 - {
107 - .title = "Sensor Humidity",
108 - .units = "%",
109 - .context = "system.hw.sensor.humidity.input",
110 - .family = "Humidity",
111 - .priority = 70004,
112 - },
113 - {
114 - .title = "Ambient light level",
115 - .units = "lx",
116 - .context = "system.hw.sensor.lux.input",
117 - .family = "illuminance",
118 - .priority = 70010,
119 - },
120 - {
121 - .title = "Color temperature of light",
122 - .units = "Cel",
123 - .context = "system.hw.sensor.color.input",
124 - .family = "Temperature",
125 - .priority = 70011,
126 - },
127 - {
128 - .title = "Electrical potential.",
129 - .units = "V",
130 - .context = "system.hw.sensor.voltage.input",
131 - .family = "Potential",
132 - .priority = 70012,
133 - },
134 - {
135 - .title = "Electrical resistence.",
136 - .units = "Ohms",
137 - .context = "system.hw.sensor.resistence.input",
138 - .family = "Resistence",
139 - .priority = 70013,
140 - },
141 - {
142 - .title = "Ambient atmospheric pressure",
143 - .units = "Pa",
144 - .context = "system.hw.sensor.pressure.input",
145 - .family = "Pressure",
146 - .priority = 70014,
147 - },
148 - {
149 - .title = "Geographic latitude",
150 - .units = "Degrees",
151 - .context = "system.hw.sensor.latitude.input",
152 - .family = "Location",
153 - .priority = 70015,
154 - },
155 - {
156 - .title = "Geographic longitude",
157 - .units = "Degrees",
158 - .context = "system.hw.sensor.longitude.input",
159 - .family = "Location",
160 - .priority = 70016,
161 - },
162 - {
163 - .title = "Force",
164 - .units = "N",
165 - .context = "system.hw.sensor.force.input",
166 - .family = "Force",
167 - .priority = 70017,
168 - },
169 - {
170 - .title = "Gauge Pressure",
171 - .units = "Pa",
172 - .context = "system.hw.sensor.gauge_pressure.input",
173 - .family = "Pressure",
174 - .priority = 70018,
175 - },
176 - {
177 - .title = "Distance",
178 - .units = "m",
179 - .context = "system.hw.sensor.distance.input",
180 - .family = "Distance",
181 - .priority = 70019,
182 - },
183 - {
184 - .title = "Acceleration.",
185 - .units = "g",
186 - .context = "system.hw.sensor.acceleration.input",
187 - .family = "Acceleration",
188 - .priority = 70022,
189 - }
150 + {
151 + .title = "Sensor Temperature",
152 + .units = "Cel",
153 + .context = "system.hw.sensor.temperature.input",
154 + .family = "Temperature",
155 + .priority = NETDATA_CHART_PRIO_SENSORS,
156 + },
157 + {
158 + .title = "Sensor Power",
159 + .units = "W",
160 + .context = "system.hw.sensor.power.input",
161 + .family = "Power",
162 + .priority = NETDATA_CHART_PRIO_SENSOR_POWER,
163 + },
164 + {
165 + .title = "Sensor Current",
166 + .units = "A",
167 + .context = "system.hw.sensor.current.input",
168 + .family = "Current",
169 + .priority = NETDATA_CHART_PRIO_SENSOR_CURRENT,
170 + },
171 + {
172 + .title = "Sensor Humidity",
173 + .units = "%",
174 + .context = "system.hw.sensor.humidity.input",
175 + .family = "Humidity",
176 + .priority = NETDATA_CHART_PRIO_SENSOR_HUMIDITY,
177 + },
178 + {
179 + .title = "Ambient light level",
180 + .units = "lx",
181 + .context = "system.hw.sensor.lux.input",
182 + .family = "illuminance",
183 + .priority = NETDATA_CHART_PRIO_SENSOR_LUX,
184 + },
185 + {
186 + .title = "Color temperature of light",
187 + .units = "Cel",
188 + .context = "system.hw.sensor.color.input",
189 + .family = "Temperature",
190 + .priority = NETDATA_CHART_PRIO_SENSOR_TEMPERATURE,
191 + },
192 + {
193 + .title = "Electrical potential.",
194 + .units = "V",
195 + .context = "system.hw.sensor.voltage.input",
196 + .family = "Potential",
197 + .priority = NETDATA_CHART_PRIO_SENSOR_VOLTAGE,
198 + },
199 + {
200 + .title = "Electrical resistence.",
201 + .units = "Ohms",
202 + .context = "system.hw.sensor.resistence.input",
203 + .family = "Resistence",
204 + .priority = NETDATA_CHART_PRIO_SENSOR_RESISTENCE,
205 + },
206 + {
207 + .title = "Ambient atmospheric pressure",
208 + .units = "Pa",
209 + .context = "system.hw.sensor.pressure.input",
210 + .family = "Pressure",
211 + .priority = NETDATA_CHART_PRIO_SENSOR_AMBIENT_PRESSURE,
212 + },
213 + {
214 + .title = "Geographic latitude",
215 + .units = "Degrees",
216 + .context = "system.hw.sensor.latitude.input",
217 + .family = "Location",
218 + .priority = NETDATA_CHART_PRIO_SENSOR_LATITUDE,
219 + },
220 + {
221 + .title = "Geographic longitude",
222 + .units = "Degrees",
223 + .context = "system.hw.sensor.longitude.input",
224 + .family = "Location",
225 + .priority = NETDATA_CHART_PRIO_SENSOR_LONGITUDE,
226 + },
227 + {
228 + .title = "Force",
229 + .units = "N",
230 + .context = "system.hw.sensor.force.input",
231 + .family = "Force",
232 + .priority = NETDATA_CHART_PRIO_SENSOR_FORCE,
233 + },
234 + {
235 + .title = "Gauge Pressure",
236 + .units = "Pa",
237 + .context = "system.hw.sensor.gauge_pressure.input",
238 + .family = "Pressure",
239 + .priority = NETDATA_CHART_PRIO_SENSOR_GAUGE_PRESSURE,
240 + },
241 + {
242 + .title = "Distance",
243 + .units = "m",
244 + .context = "system.hw.sensor.distance.input",
245 + .family = "Distance",
246 + .priority = NETDATA_CHART_PRIO_SENSOR_DISTANCE,
247 + },
248 + {
249 + .title = "Acceleration.",
250 + .units = "g",
251 + .context = "system.hw.sensor.acceleration.input",
252 + .family = "Acceleration",
253 + .priority = NETDATA_CHART_PRIO_SENSOR_ACCELERATION,
254 + },
255 + {
256 + .title = "Custom Chart",
257 + .units = "nd",
258 + .context = "system.hw.sensor.custom",
259 + .family = "sensors",
260 + .priority = NETDATA_CHART_PRIO_SENSOR_MIN_CUSTOM,
261 + }};
262 +
263 +struct netdata_sensors_extra_values {
264 + collected_number value;
265 + enum netdata_win_sensor_monitored sensor_data_type;
266 + RRDDIM *rd_value;
267 +
268 + struct netdata_sensors_extra_values *next;
269 +};
270 +
271 +struct netdata_sensors_extra_config {
272 + const char *units;
273 + const char *title;
274 +
275 + int multiplier;
276 };
277
278 struct sensor_data {
@@ -195,12 +281,14 @@ struct sensor_data {
281 bool enabled;
282 enum netdata_win_sensor_monitored sensor_data_type;
283 struct win_sensor_config *config;
284 + struct netdata_sensors_extra_values *values;
285
286 const char *type;
287 const char *category;
288 const char *name;
289 const char *manufacturer;
290 const char *model;
291 + struct netdata_sensors_extra_config *external_config;
292
293 SensorState current_state;
294
@@ -234,7 +322,8 @@ static void netdata_clsid_to_char(char *output, const GUID *pguid)
322 }
323 }
324
237 -static inline char *netdata_convert_guid_to_string(HRESULT hr, GUID *value) {
325 +static inline char *netdata_convert_guid_to_string(HRESULT hr, GUID *value)
326 +{
327 if (SUCCEEDED(hr)) {
328 char cguid[ADDTIONAL_UUID_STR_LEN];
329 netdata_clsid_to_char(cguid, value);
@@ -247,14 +336,14 @@ static inline void netdata_fill_sensor_type(struct sensor_data *sd, ISensor *pSe
336 {
337 GUID type = {0};
338 HRESULT hr = pSensor->lpVtbl->GetType(pSensor, &type);
250 - sd->type = netdata_convert_guid_to_string(hr, &type);
339 + sd->type = netdata_convert_guid_to_string(hr, &type);
340 }
341
342 static inline void netdata_fill_sensor_category(struct sensor_data *sd, ISensor *pSensor)
343 {
344 GUID category = {0};
345 HRESULT hr = pSensor->lpVtbl->GetCategory(pSensor, &category);
257 - sd->category = netdata_convert_guid_to_string(hr, &category);
346 + sd->category = netdata_convert_guid_to_string(hr, &category);
347 }
348
349 static inline char *netdata_pvar_to_char(const PROPERTYKEY *key, ISensor *pSensor)
@@ -265,7 +354,8 @@ static inline char *netdata_pvar_to_char(const PROPERTYKEY *key, ISensor *pSenso
354 if (SUCCEEDED(hr) && pv.vt == VT_LPWSTR) {
355 char value[8192];
356 size_t len = wcslen(pv.pwszVal);
268 - wcstombs(value, pv.pwszVal, len);
357 + len = wcstombs(value, pv.pwszVal, len);
358 + value[len] = '\0';
359 PropVariantClear(&pv);
360 return strdupz(value);
361 }
@@ -282,8 +372,7 @@ static void netdata_initialize_sensor_dict(struct sensor_data *sd, ISensor *pSen
372 sd->manufacturer = netdata_pvar_to_char(&SENSOR_PROPERTY_MANUFACTURER, pSensor);
373 }
374
285 -static int
286 -netdata_collect_sensor_data(struct sensor_data *sd, ISensor *pSensor, REFPROPERTYKEY key, int vector_idx)
375 +static int netdata_collect_sensor_data(collected_number *value, ISensor *pSensor, REFPROPERTYKEY key, NETDATA_DOUBLE div_factor)
376 {
377 ISensorDataReport *pReport = NULL;
378 PROPVARIANT pv = {};
@@ -297,13 +386,13 @@ netdata_collect_sensor_data(struct sensor_data *sd, ISensor *pSensor, REFPROPERT
386 if (SUCCEEDED(hr) && (pv.vt == VT_R4 || pv.vt == VT_R8 || pv.vt == VT_UI4)) {
387 switch (pv.vt) {
388 case VT_UI4:
300 - sd->current_data_value[vector_idx] = (collected_number)(pv.ulVal * 100);
389 + *value = (collected_number)(pv.ulVal * 100);
390 break;
391 case VT_R4:
303 - sd->current_data_value[vector_idx] = (collected_number)(pv.fltVal * sd->div_factor);
392 + *value = (collected_number)(pv.fltVal * div_factor);
393 break;
394 case VT_R8:
306 - sd->current_data_value[vector_idx] = (collected_number)(pv.dblVal * sd->div_factor);
395 + *value = (collected_number)(pv.dblVal * div_factor);
396 break;
397 }
398 defined = 1;
@@ -311,7 +400,7 @@ netdata_collect_sensor_data(struct sensor_data *sd, ISensor *pSensor, REFPROPERT
400 PropVariantClear(&pv);
401 pReport->lpVtbl->Release(pReport);
402 } else {
314 - sd->current_data_value[vector_idx] = 0;
403 + *value = 0;
404 }
405
406 return defined;
@@ -320,17 +409,29 @@ netdata_collect_sensor_data(struct sensor_data *sd, ISensor *pSensor, REFPROPERT
409 static void netdata_sensors_get_data(struct sensor_data *sd, ISensor *pSensor)
410 {
411 for (int i = 0; sensor_keys[i]; i++) {
323 - if (netdata_collect_sensor_data(sd, pSensor, sensor_keys[i], 0)) {
412 + if (netdata_collect_sensor_data(&sd->current_data_value[0], pSensor, sensor_keys[i], sd->div_factor)) {
413 sd->sensor_data_type = i;
414 sd->config = &configs[i];
415 sd->enabled = true;
416
417 if (i == NETDATA_WIN_SENSOR_TYPE_DISTANCE_X) {
329 - netdata_collect_sensor_data(sd, pSensor, sensor_keys[NETDATA_WIN_SENSOR_TYPE_DISTANCE_Y], 1);
330 - netdata_collect_sensor_data(sd, pSensor, sensor_keys[NETDATA_WIN_SENSOR_TYPE_DISTANCE_Z], 2);
418 + netdata_collect_sensor_data(&sd->current_data_value[1],
419 + pSensor,
420 + sensor_keys[NETDATA_WIN_SENSOR_TYPE_DISTANCE_Y],
421 + sd->div_factor);
422 + netdata_collect_sensor_data(&sd->current_data_value[2],
423 + pSensor,
424 + sensor_keys[NETDATA_WIN_SENSOR_TYPE_DISTANCE_Z],
425 + sd->div_factor);
426 } else if (i == NETDATA_WIN_SENSOR_ACCELERATION_X_G) {
332 - netdata_collect_sensor_data(sd, pSensor, sensor_keys[NETDATA_WIN_SENSOR_ACCELERATION_Y_G], 1);
333 - netdata_collect_sensor_data(sd, pSensor, sensor_keys[NETDATA_WIN_SENSOR_ACCELERATION_Z_G], 2);
427 + netdata_collect_sensor_data(&sd->current_data_value[1],
428 + pSensor,
429 + sensor_keys[NETDATA_WIN_SENSOR_ACCELERATION_Y_G],
430 + sd->div_factor);
431 + netdata_collect_sensor_data(&sd->current_data_value[2],
432 + pSensor,
433 + sensor_keys[NETDATA_WIN_SENSOR_ACCELERATION_Z_G],
434 + sd->div_factor);
435 } else if (i == NETDATA_WIN_SENSOR_DATA_TYPE_LIGHT_TEMPERATURE) {
436 sd->div_factor = 100.0;
437 sd->add_factor = -27315.0; // 273.15 * 100.0
@@ -342,6 +443,53 @@ static void netdata_sensors_get_data(struct sensor_data *sd, ISensor *pSensor)
443 sd->first_time = false;
444 }
445
446 +static void netdata_sensors_get_custom_data(struct sensor_data *sd, ISensor *pSensor)
447 +{
448 + collected_number current;
449 + // Last two values have been constant through all collections. One of the values are always negative.
450 + for (int i = NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE1; i < NETDATA_WIN_SENSOR_TYPE_CUSTOM_VALUE25; i++) {
451 + if (netdata_collect_sensor_data(&current, pSensor, sensor_keys[i], sd->div_factor)) {
452 + if (unlikely(!sd->enabled)) {
453 + sd->sensor_data_type = i;
454 + sd->config = &configs[NETDATA_WIN_SENSOR_LAST_WELL_DEFINED];
455 + sd->enabled = true;
456 + sd->current_data_value[0] = current;
457 + } else {
458 + if (unlikely(!sd->values)) {
459 + sd->values = callocz(sizeof(struct netdata_sensors_extra_values), 1);
460 + sd->values->sensor_data_type = i;
461 + sd->values->value = current;
462 + } else {
463 + struct netdata_sensors_extra_values *move;
464 + for (move = sd->values; move->next; move = move->next);
465 + move->next = callocz(sizeof(struct netdata_sensors_extra_values), 1);
466 + move->next->sensor_data_type = i;
467 + move->next->value = current;
468 + }
469 + }
470 + }
471 + }
472 +}
473 +
474 +static struct netdata_sensors_extra_config *netdata_sensors_fill_configuration(const char *name)
475 +{
476 +#define NETDATA_DEFAULT_SENSOR_SECTION "plugin:windows:GetSensors"
477 + char section_name[CONFIG_MAX_NAME];
478 + snprintfz(section_name, CONFIG_MAX_NAME, "%s:%s", NETDATA_DEFAULT_SENSOR_SECTION, name);
479 +
480 + const char *units = inicfg_get(&netdata_config, section_name, "units", NULL);
481 + if (unlikely(!units)) {
482 + return NULL;
483 + }
484 +
485 + struct netdata_sensors_extra_config *sec = callocz(sizeof(struct netdata_sensors_extra_config), 1);
486 + sec->units = units;
487 + sec->title = inicfg_get(&netdata_config, section_name, "title", NULL);;
488 + sec->multiplier = (int)inicfg_get_number(&netdata_config, section_name, "multiplier", 1);
489 +
490 + return sec;
491 +}
492 +
493 static void netdata_get_sensors()
494 {
495 ISensorCollection *pSensorCollection = NULL;
@@ -382,16 +530,43 @@ static void netdata_get_sensors()
530 sd->current_state = SENSOR_STATE_MIN;
531 (void)pSensor->lpVtbl->GetState(pSensor, &sd->current_state);
532
385 - if (sd->first_time)
533 + if (sd->first_time) {
534 netdata_sensors_get_data(sd, pSensor);
387 - else if (likely(sd->enabled)) {
388 - netdata_collect_sensor_data(sd, pSensor, sensor_keys[sd->sensor_data_type], 0);
535 + sd->external_config = netdata_sensors_fill_configuration(sd->name);
536 + if (unlikely(!sd->enabled))
537 + netdata_sensors_get_custom_data(sd, pSensor);
538 + } else if (likely(sd->enabled)) {
539 + netdata_collect_sensor_data(&sd->current_data_value[0],
540 + pSensor,
541 + sensor_keys[sd->sensor_data_type],
542 + sd->div_factor);
543 if (sd->sensor_data_type == NETDATA_WIN_SENSOR_TYPE_DISTANCE_X) {
390 - netdata_collect_sensor_data(sd, pSensor, sensor_keys[NETDATA_WIN_SENSOR_TYPE_DISTANCE_Y], 1);
391 - netdata_collect_sensor_data(sd, pSensor, sensor_keys[NETDATA_WIN_SENSOR_TYPE_DISTANCE_Z], 2);
544 + netdata_collect_sensor_data(&sd->current_data_value[1],
545 + pSensor,
546 + sensor_keys[NETDATA_WIN_SENSOR_TYPE_DISTANCE_Y],
547 + sd->div_factor);
548 + netdata_collect_sensor_data(&sd->current_data_value[2],
549 + pSensor,
550 + sensor_keys[NETDATA_WIN_SENSOR_TYPE_DISTANCE_Z],
551 + sd->div_factor);
552 } else if (sd->sensor_data_type == NETDATA_WIN_SENSOR_ACCELERATION_X_G) {
393 - netdata_collect_sensor_data(sd, pSensor, sensor_keys[NETDATA_WIN_SENSOR_ACCELERATION_Y_G], 1);
394 - netdata_collect_sensor_data(sd, pSensor, sensor_keys[NETDATA_WIN_SENSOR_ACCELERATION_Z_G], 2);
553 + netdata_collect_sensor_data(&sd->current_data_value[1],
554 + pSensor,
555 + sensor_keys[NETDATA_WIN_SENSOR_ACCELERATION_Y_G],
556 + sd->div_factor);
557 + netdata_collect_sensor_data(&sd->current_data_value[2],
558 + pSensor,
559 + sensor_keys[NETDATA_WIN_SENSOR_ACCELERATION_Z_G],
560 + sd->div_factor);
561 + }
562 + if (likely(sd->values)) {
563 + struct netdata_sensors_extra_values *move;
564 + for (move = sd->values; move; move = move->next) {
565 + netdata_collect_sensor_data(&move->value,
566 + pSensor,
567 + sensor_keys[move->sensor_data_type],
568 + sd->div_factor);
569 + }
570 }
571 }
572
@@ -502,19 +677,20 @@ static inline void sensors_state_chart_loop(struct sensor_data *sd, int update_e
677 rrdset_done(sd->st_sensor_state);
678 }
679
505 -static inline RRDDIM *netdata_add_sensor_dimension(struct sensor_data *sd, char *label)
680 +static inline RRDDIM *netdata_add_sensor_dimension(struct sensor_data *sd, char *label, int mult_factor)
681 {
507 - return rrddim_add(sd->st_sensor_data,
508 - label,
509 - NULL,
510 - (collected_number )sd->mult_factor,
511 - (collected_number )sd->div_factor,
512 - RRD_ALGORITHM_ABSOLUTE);
682 + return rrddim_add(
683 + sd->st_sensor_data,
684 + label,
685 + NULL,
686 + (collected_number)mult_factor,
687 + (collected_number)sd->div_factor,
688 + RRD_ALGORITHM_ABSOLUTE);
689 }
690
691 static inline void netdata_state_chart_set_value(RRDDIM *dim, struct sensor_data *sd, int value_idx)
692 {
517 - collected_number value = sd->current_data_value[value_idx] + (collected_number )sd->add_factor;
693 + collected_number value = sd->current_data_value[value_idx] + (collected_number)sd->add_factor;
694 rrddim_set_by_pointer(sd->st_sensor_data, dim, value);
695 }
696
@@ -522,39 +698,72 @@ static void sensors_data_chart(struct sensor_data *sd, int update_every)
698 {
699 if (!sd->st_sensor_data) {
700 char id[RRD_ID_LENGTH_MAX + 1];
701 + char ctx[RRD_ID_LENGTH_MAX + 1];
702 + int priority = sd->config->priority;
703 +
704 snprintfz(id, RRD_ID_LENGTH_MAX, "sensors.%s_input", sd->name);
705 netdata_fix_chart_name(id);
706 + struct netdata_sensors_extra_config *cfg = sd->external_config;
707 + if (sd->sensor_data_type > NETDATA_WIN_SENSOR_TYPE_CUSTOM_USAGE) {
708 + static int min_custom = NETDATA_CHART_PRIO_SENSOR_MIN_CUSTOM;
709 + static int custom_input = 1;
710 +
711 + snprintfz(ctx, RRD_ID_LENGTH_MAX, "%s%d.input", sd->config->context, custom_input++);
712 + priority = min_custom++;
713 + } else {
714 + ctx[0] = '\0';
715 + }
716 sd->st_sensor_data = rrdset_create_localhost(
528 - "sensors",
529 - id,
530 - NULL,
531 - sd->config->family,
532 - sd->config->context,
533 - sd->config->title,
534 - sd->config->units,
535 - PLUGIN_WINDOWS_NAME,
536 - "GetSensors",
537 - sd->config->priority,
538 - update_every,
539 - RRDSET_TYPE_LINE);
717 + "sensors",
718 + id,
719 + NULL,
720 + sd->config->family,
721 + (unlikely(!ctx[0])) ? sd->config->context: ctx,
722 + (cfg && cfg->title) ? cfg->title : sd->config->title,
723 + (cfg && cfg->units) ? cfg->units : sd->config->units,
724 + PLUGIN_WINDOWS_NAME,
725 + "GetSensors",
726 + priority,
727 + update_every,
728 + RRDSET_TYPE_LINE);
729
730 rrdlabels_add(sd->st_sensor_data->rrdlabels, "name", sd->name, RRDLABEL_SRC_AUTO);
731 rrdlabels_add(sd->st_sensor_data->rrdlabels, "manufacturer", sd->manufacturer, RRDLABEL_SRC_AUTO);
732 rrdlabels_add(sd->st_sensor_data->rrdlabels, "model", sd->model, RRDLABEL_SRC_AUTO);
733
545 - if (sd->sensor_data_type != NETDATA_WIN_SENSOR_TYPE_DISTANCE_X && sd->sensor_data_type != NETDATA_WIN_SENSOR_ACCELERATION_X_G)
546 - sd->rd_sensor_data_0 = netdata_add_sensor_dimension(sd, "input");
547 - else {
548 - sd->rd_sensor_data_0 = netdata_add_sensor_dimension(sd, "inputX");
549 - sd->rd_sensor_data_1 = netdata_add_sensor_dimension(sd, "inputY");
550 - sd->rd_sensor_data_2 = netdata_add_sensor_dimension(sd, "inputZ");
734 + if (sd->sensor_data_type != NETDATA_WIN_SENSOR_TYPE_DISTANCE_X &&
735 + sd->sensor_data_type != NETDATA_WIN_SENSOR_ACCELERATION_X_G) {
736 + sd->rd_sensor_data_0 = netdata_add_sensor_dimension(sd,
737 + (unlikely(!ctx[0])) ? "input" : "input0",
738 + (cfg) ? cfg->multiplier : sd->mult_factor);
739 + if (likely(sd->values)) {
740 + int i;
741 + struct netdata_sensors_extra_values *move;
742 + for (move = sd->values, i = 1; move; move = move->next, i++) {
743 + snprintfz(id, RRD_ID_LENGTH_MAX, "input%d", i);
744 + move->rd_value = netdata_add_sensor_dimension(sd, id, (cfg) ? cfg->multiplier : sd->mult_factor);
745 + }
746 + }
747 + } else {
748 + sd->rd_sensor_data_0 =
749 + netdata_add_sensor_dimension(sd, "inputX", (cfg) ? cfg->multiplier : sd->mult_factor);
750 + sd->rd_sensor_data_1 =
751 + netdata_add_sensor_dimension(sd, "inputY", (cfg) ? cfg->multiplier : sd->mult_factor);
752 + sd->rd_sensor_data_2 =
753 + netdata_add_sensor_dimension(sd, "inputZ", (cfg) ? cfg->multiplier : sd->mult_factor);
754 }
755 }
756
757 netdata_state_chart_set_value(sd->rd_sensor_data_0, sd, 0);
555 - if (sd->sensor_data_type == NETDATA_WIN_SENSOR_TYPE_DISTANCE_X || sd->sensor_data_type == NETDATA_WIN_SENSOR_ACCELERATION_X_G) {
758 + if (sd->sensor_data_type == NETDATA_WIN_SENSOR_TYPE_DISTANCE_X ||
759 + sd->sensor_data_type == NETDATA_WIN_SENSOR_ACCELERATION_X_G) {
760 netdata_state_chart_set_value(sd->rd_sensor_data_1, sd, 1);
761 netdata_state_chart_set_value(sd->rd_sensor_data_2, sd, 2);
762 + } else if (likely(sd->values)) {
763 + struct netdata_sensors_extra_values *move;
764 + for (move = sd->values; move; move = move->next) {
765 + rrddim_set_by_pointer(sd->st_sensor_data, move->rd_value, move->value);
766 + }
767 }
768 rrdset_done(sd->st_sensor_data);
769 }
@@ -602,4 +811,4 @@ void do_Sensors_cleanup()
811
812 CoUninitialize();
813 }
605 -}
\ No newline at end of file
814 +}
src/collectors/windows.plugin/metadata.yaml
+17 -2
@@ -1218,9 +1218,18 @@ modules:
1218 required: false
1219 examples:
1220 folding:
1221 - enabled: false
1221 + enabled: true
1222 title: ""
1223 - list: []
1223 + list:
1224 + - name: Specific Sensors
1225 + description: You can add custom sensor information by creating a dedicated sensor section.
1226 + folding:
1227 + enabled: false
1228 + config: |
1229 + [plugin:windows:GetSensors:Your Sensor Name]
1230 + units = Speed
1231 + multiplier = 100
1232 + title = Current speed.
1233 troubleshooting:
1234 problems:
1235 list: []
@@ -1347,6 +1356,12 @@ modules:
1356 - name: initializing
1357 - name: access_denied
1358 - name: error
1359 + - name: system.hw.sensor.custom
1360 + description: Custom Chart
1361 + unit: "nd"
1362 + chart_type: line
1363 + dimensions:
1364 + - name: inputN
1365 - meta:
1366 plugin_name: windows.plugin
1367 module_name: PerflibWebService