From: Michael Tremer Date: Thu, 30 Oct 2025 23:20:07 +0000 (+0000) Subject: graphs: Automatically convert temperatures to K/C/F X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f1b9daa765fca6972e123e5e649ab6dda9bafa45;p=people%2Fms%2Ftelemetry.git graphs: Automatically convert temperatures to K/C/F Signed-off-by: Michael Tremer --- diff --git a/src/daemon/graph.c b/src/daemon/graph.c index 267de70..81dcdcd 100644 --- a/src/daemon/graph.c +++ b/src/daemon/graph.c @@ -509,6 +509,42 @@ ERROR: return r; } +td_graph_temps td_graph_temperature(const td_graph_render_options* options) { + // These countries predominantly use Fahrenheit + const char* fahrenheit[] = { + // United States + "en_US", + // Bahamas + "en_BS", + // Belize + "en_BZ", + // Cayman Islands + "en_KY", + // Liberia + "en_LR", + // Palau + "en_PW", + // Marshall Islands + "en_MH", + // Micronesia + "en_FM", + NULL, + }; + + // If there is no locale, we will use Kelvin + if (!options->locale || !*options->locale || td_string_equals(options->locale, "C")) + return TD_GRAPH_TEMP_KELVIN; + + // Find anyone using Fahrenheit + for (const char** code = fahrenheit; *code; code++) { + if (td_string_startswith(options->locale, *code)) + return TD_GRAPH_TEMP_FAHRENHEIT; + } + + // Otherwise use Celsius + return TD_GRAPH_TEMP_CELSIUS; +} + int td_graph_vlabel_bps(td_ctx* ctx, td_graph* graph, const char* object, char* vlabel, size_t length) { return __td_string_set(vlabel, length, _("Bits Per Second")); diff --git a/src/daemon/graph.h b/src/daemon/graph.h index e244c3e..a3c4bcb 100644 --- a/src/daemon/graph.h +++ b/src/daemon/graph.h @@ -111,6 +111,8 @@ typedef enum td_graph_temps { TD_GRAPH_TEMP_FAHRENHEIT, } td_graph_temps; +td_graph_temps td_graph_temperature(const td_graph_render_options* options); + /* Commonly used vlabels */ diff --git a/src/daemon/graphs/disk.c b/src/daemon/graphs/disk.c index 1c129d1..ffec746 100644 --- a/src/daemon/graphs/disk.c +++ b/src/daemon/graphs/disk.c @@ -41,7 +41,7 @@ static int disk_temp_render(td_ctx* ctx, td_graph* graph, PRINT_HEADER4(args, _("Current"), _("Average"), _("Minimum"), _("Maximum")); // Draw the temperature - DRAW_TEMPERATURE_KELVIN(args, "temperature", object, "%s", _("Temperature")); + DRAW_TEMPERATURE(args, options, "temperature", object, "%s", _("Temperature")); return 0; } diff --git a/src/daemon/graphs/graph.h b/src/daemon/graphs/graph.h index 13332a4..0875b5b 100644 --- a/src/daemon/graphs/graph.h +++ b/src/daemon/graphs/graph.h @@ -76,6 +76,8 @@ typedef enum flags { // Temperatures #define KELVIN "%%12.2lf K" +#define CELSIUS "%%11.2lf °C" +#define FAHRENHEIT "%%11.2lf °F" // Macro to terminate a line #define EOL "\\j" @@ -233,6 +235,8 @@ static inline int __DRAW(td_args* args, const char* what, const char* field, #define FIELD_INF(field) field "_inf" #define FIELD_NEGINF(field) field "_neginf" #define FIELD_BITS(field) field "_bits" +#define FIELD_CELSIUS(field) field "_c" +#define FIELD_FAHRENHEIT(field) field "_f" #define VALUE_CURRENT(args, field, object) SCRIPT(args, "VDEF:" FIELD_CURRENT(FIELD) "=" FIELD ",LAST", FIELD_AND_OBJECT(field, object), FIELD_AND_OBJECT(field, object)) #define VALUE_AVERAGE(args, field, object) SCRIPT(args, "VDEF:" FIELD_AVERAGE(FIELD) "=" FIELD ",AVERAGE", FIELD_AND_OBJECT(field, object), FIELD_AND_OBJECT(field, object)) @@ -286,6 +290,25 @@ static inline int __DRAW(td_args* args, const char* what, const char* field, #define COMPUTE_BITS(args, bits, object, bytes) \ COMPUTE_MULTIPLY(args, bits, object, bytes, object, 8) +// Convert Kelvin to Celsius +#define COMPUTE_CELSIUS(args, field, object) \ + do { \ + COMPUTE_CDEF(args, FIELD "=" FIELD ",273.15,-", \ + FIELD_AND_OBJECT(FIELD_CELSIUS(field), object), \ + FIELD_AND_OBJECT(field, object) \ + ); \ + VALUE_ALL(args, FIELD_CELSIUS(field), object); \ + } while (0) + +#define COMPUTE_FAHRENHEIT(args, field, object) \ + do { \ + COMPUTE_CDEF(args, FIELD "=" FIELD ",273.15,-,9,*,5,/,32,+", \ + FIELD_AND_OBJECT(FIELD_FAHRENHEIT(field), object), \ + FIELD_AND_OBJECT(field, object) \ + ); \ + VALUE_ALL(args, FIELD_FAHRENHEIT(field), object); \ + } while (0) + #define COMPUTE_DIVIDE(args, fraction, object1, dividend, object2, divisor) \ do { \ COMPUTE_CDEF(args, FIELD "=" FIELD "," TOSTRING(divisor) ",/", \ @@ -340,10 +363,41 @@ static inline int __DRAW(td_args* args, const char* what, const char* field, /* This draws a temperature graph */ -#define DRAW_TEMPERATURE_KELVIN(args, field, object, ...) \ +#define DRAW_TEMPERATURE(args, options, field, object, ...) \ + do { \ + switch (td_graph_temperature(options)) { \ + case TD_GRAPH_TEMP_KELVIN: \ + DRAW_TEMPERATURE_K(args, field, object, __VA_ARGS__); \ + break; \ + \ + case TD_GRAPH_TEMP_CELSIUS: \ + DRAW_TEMPERATURE_C(args, field, object, __VA_ARGS__); \ + break; \ + \ + case TD_GRAPH_TEMP_FAHRENHEIT: \ + DRAW_TEMPERATURE_F(args, field, object, __VA_ARGS__); \ + break; \ + } \ + } while (0) + +#define DRAW_TEMPERATURE_K(args, field, object, ...) \ do { \ DRAW_LINE_WITH_LABEL(args, 1, field, object, COLOR_TEMPERATURE, 0, ##__VA_ARGS__); \ PRINT_CAMM(args, field, object, KELVIN); \ } while (0) +#define DRAW_TEMPERATURE_C(args, field, object, ...) \ + do { \ + COMPUTE_CELSIUS(args, field, object); \ + DRAW_LINE_WITH_LABEL(args, 1, FIELD_CELSIUS(field), object, COLOR_TEMPERATURE, 0, ##__VA_ARGS__); \ + PRINT_CAMM(args, FIELD_CELSIUS(field), object, CELSIUS); \ + } while (0) + +#define DRAW_TEMPERATURE_F(args, field, object, ...) \ + do { \ + COMPUTE_FAHRENHEIT(args, field, object); \ + DRAW_LINE_WITH_LABEL(args, 1, FIELD_FAHRENHEIT(field), object, COLOR_TEMPERATURE, 0, ##__VA_ARGS__); \ + PRINT_CAMM(args, FIELD_FAHRENHEIT(field), object, FAHRENHEIT); \ + } while (0) + #endif /* TELEMETRY_GRAPHS_GRAPH_H */