]> git.ipfire.org Git - collecty.git/commitdiff
graphs: Automatically convert temperatures to K/C/F
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 30 Oct 2025 23:20:07 +0000 (23:20 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 30 Oct 2025 23:20:07 +0000 (23:20 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/daemon/graph.c
src/daemon/graph.h
src/daemon/graphs/disk.c
src/daemon/graphs/graph.h

index 267de7044e99a888c9a371e5c271a71c46486a32..81dcdcd580209668b55647a9fbb277bfeea789b8 100644 (file)
@@ -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"));
index e244c3e41a71517dadfff5ecafbefffcd95b56f6..a3c4bcbc00efb44398f8b6afe9926a67753b5043 100644 (file)
@@ -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
 */
index 1c129d1e00af0a86693dc004e9776409e5ac024e..ffec74611477774858ef7523660a91aa606faede 100644 (file)
@@ -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;
 }
index 13332a4e931df4fbe7d488550b06f56d7ed9b545..0875b5bf44f83b992e64eea7ca6b835923f75da9 100644 (file)
@@ -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 */