diff options
Diffstat (limited to 'src/collectors/windows.plugin/perflib-thermalzone.c')
-rw-r--r-- | src/collectors/windows.plugin/perflib-thermalzone.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/collectors/windows.plugin/perflib-thermalzone.c b/src/collectors/windows.plugin/perflib-thermalzone.c new file mode 100644 index 000000000..f85ba019f --- /dev/null +++ b/src/collectors/windows.plugin/perflib-thermalzone.c @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "windows_plugin.h" +#include "windows-internals.h" + +struct thermal_zone { + RRDSET *st; + RRDDIM *rd; + + COUNTER_DATA thermalZoneTemperature; +}; + +static inline void initialize_thermal_zone_keys(struct thermal_zone *p) { + p->thermalZoneTemperature.key = "Temperature"; +} + +void dict_thermal_zone_insert_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused) { + struct thermal_zone *p = value; + initialize_thermal_zone_keys(p); +} + +static DICTIONARY *thermal_zones = NULL; + +static void initialize(void) { + thermal_zones = dictionary_create_advanced( + DICT_OPTION_DONT_OVERWRITE_VALUE | DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct thermal_zone)); + + dictionary_register_insert_callback(thermal_zones, dict_thermal_zone_insert_cb, NULL); +} + +static bool do_thermal_zones(PERF_DATA_BLOCK *pDataBlock, int update_every) { + PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, "Thermal Zone Information"); + if (!pObjectType) + return false; + + PERF_INSTANCE_DEFINITION *pi = NULL; + for (LONG i = 0; i < pObjectType->NumInstances; i++) { + pi = perflibForEachInstance(pDataBlock, pObjectType, pi); + if (!pi) + break; + + if (!getInstanceName(pDataBlock, pObjectType, pi, windows_shared_buffer, sizeof(windows_shared_buffer))) + strncpyz(windows_shared_buffer, "[unknown]", sizeof(windows_shared_buffer) - 1); + + struct thermal_zone *p = dictionary_set(thermal_zones, windows_shared_buffer, NULL, sizeof(*p)); + + perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &p->thermalZoneTemperature); + + // https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/design-guide + if (!p->st) { + char id[RRD_ID_LENGTH_MAX + 1]; + snprintfz(id, RRD_ID_LENGTH_MAX, "thermalzone_%s_temperature", windows_shared_buffer); + netdata_fix_chart_name(id); + p->st = rrdset_create_localhost( + "system", + id, + NULL, + "thermalzone", + "system.thermalzone_temperature", + "Thermal zone temperature", + "Celsius", + PLUGIN_WINDOWS_NAME, + "ThermalZone", + NETDATA_CHART_PRIO_WINDOWS_THERMAL_ZONES, + update_every, + RRDSET_TYPE_LINE); + + p->rd = rrddim_add(p->st, id, "temperature", 1, 1, RRD_ALGORITHM_ABSOLUTE); + + rrdlabels_add(p->st->rrdlabels, "thermalzone", windows_shared_buffer, RRDLABEL_SRC_AUTO); + } + + // Convert to Celsius before to plot + NETDATA_DOUBLE kTemperature = (NETDATA_DOUBLE)p->thermalZoneTemperature.current.Data; + kTemperature -= 273.15; + + rrddim_set_by_pointer(p->st, p->rd, (collected_number)kTemperature); + rrdset_done(p->st); + } + + return true; +} + +int do_PerflibThermalZone(int update_every, usec_t dt __maybe_unused) { + static bool initialized = false; + + if (unlikely(!initialized)) { + initialize(); + initialized = true; + } + + DWORD id = RegistryFindIDByName("Thermal Zone Information"); + if (id == PERFLIB_REGISTRY_NAME_NOT_FOUND) + return -1; + + PERF_DATA_BLOCK *pDataBlock = perflibGetPerformanceData(id); + if (!pDataBlock) + return -1; + + do_thermal_zones(pDataBlock, update_every); + + return 0; +} |