diff options
author | Erich Eckner <git@eckner.net> | 2019-09-24 10:16:10 +0200 |
---|---|---|
committer | Erich Eckner <git@eckner.net> | 2019-09-24 10:16:10 +0200 |
commit | 9ee88c6b2c0e1abcc2db39b531a9192662bb68b6 (patch) | |
tree | 1de873641e4dd53f6b1bf1c362ff971401a36df0 | |
parent | e103f73f5025f9fda6067040f22a211ea3af753d (diff) | |
parent | 375324e5f4c0cc0a4137c60df03334d1bef92fff (diff) | |
download | anzeige-9ee88c6b2c0e1abcc2db39b531a9192662bb68b6.tar.xz |
Merge branch 'humidity'
-rw-r--r-- | Makefile | 10 | ||||
-rw-r--r-- | anzeige.c | 15 | ||||
-rw-r--r-- | humidity.c | 25 | ||||
-rw-r--r-- | humidity.h | 39 | ||||
-rw-r--r-- | input_gadgets.c | 101 | ||||
-rw-r--r-- | input_gadgets.h | 3 |
6 files changed, 185 insertions, 8 deletions
@@ -1,11 +1,14 @@ CFLAGS=-Werror -O3 -pedantic -anzeige: anzeige.c fonts.o input_gadgets.o multiplexer.o +anzeige: anzeige.c fonts.o humidity.o input_gadgets.o multiplexer.o gcc -o "$@" $(CFLAGS) -lpthread -lzip -lxml2 -lcurl $^ fonts.o: fonts.c fonts.h gcc -o "$@" $(CFLAGS) -c "$<" +humidity.o: humidity.c humidity.h + gcc -o "$@" $(CFLAGS) -c "$<" + input_gadgets.o: input_gadgets.c input_gadgets.h gcc -o "$@" $(CFLAGS) -c -I/usr/include/libxml2 -lzip -lxml2 -lcurl "$<" @@ -14,4 +17,7 @@ multiplexer.o: multiplexer.c multiplexer.h all: anzeige -.PHONY: all +run: all + ./anzeige + +.PHONY: all run @@ -85,6 +85,8 @@ int main(int argc, char **argv) text_buffer_end = text_buffer; + double temperature, humidity; + text_buffer_end = gadgets_retrieve_weather_warnings(text_buffer_end,text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end); if (text_buffer_end == NULL) { fprintf(stderr, "gadgets_retrieve_weather_warnings failed\n"); @@ -94,7 +96,7 @@ int main(int argc, char **argv) } if (text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end > 0) text_buffer_end += snprintf(text_buffer_end, text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end, "; "); - text_buffer_end = gadgets_retrieve_current_temperature(text_buffer_end,text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end); + text_buffer_end = gadgets_retrieve_current_temperature(text_buffer_end, text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end, &temperature, &humidity); if (text_buffer_end == NULL) { fprintf(stderr, "gadgets_retrieve_current_temperature failed\n"); free(text_buffer); @@ -110,6 +112,17 @@ int main(int argc, char **argv) turn_off_display(); return EXIT_FAILURE; } + if (text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end > 0) + text_buffer_end += snprintf(text_buffer_end, text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end, "; "); + text_buffer_end = gadgets_retrieve_humidity(text_buffer_end, text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end, temperature, humidity); + if (text_buffer_end == NULL) { + fprintf(stderr, "gadgets_retrieve_humidity failed\n"); + free(text_buffer); + turn_off_display(); + return EXIT_FAILURE; + } + printf("%s\n", text_buffer); + return 0; struct tm time_struct; memset(&time_struct, 0, sizeof(time_struct)); localtime_r(&next_update, &time_struct); diff --git a/humidity.c b/humidity.c new file mode 100644 index 0000000..6aa1cfb --- /dev/null +++ b/humidity.c @@ -0,0 +1,25 @@ +#include "humidity.h" + +double maximale_luftfeuchte(double t) +{ + for (int i=1; i<DAMPF_ANZ; i++) + if (dampf_temperaturen[i]>=t) + return + (t - dampf_temperaturen[i-1]) + * (dampf_feuchten[i] - dampf_feuchten[i-1]) + / (dampf_temperaturen[i] - dampf_temperaturen[i-1]) + + dampf_feuchten[i-1]; + return -1; +} + +double taupunkt(double af) +{ + for (int i=1; i<DAMPF_ANZ; i++) + if (dampf_feuchten[i]>=af) + return + (af - dampf_feuchten[i-1]) + * (dampf_temperaturen[i] - dampf_temperaturen[i-1]) + / (dampf_feuchten[i] - dampf_feuchten[i-1]) + + dampf_temperaturen[i-1]; + return -1; +} diff --git a/humidity.h b/humidity.h new file mode 100644 index 0000000..23f43b3 --- /dev/null +++ b/humidity.h @@ -0,0 +1,39 @@ +#ifndef HUMIDITY_H +#define HUMIDITY_H + +#define DAMPF_ANZ 69 + +static double dampf_temperaturen[DAMPF_ANZ] = { + -100, -95, -90, -85, -80, -75, + -70, -65, -60, -55, -50, -45, + -40, -35, -30, -25, -20, -15, + -10, -5, -4, -3, -2, -1, + 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, + 30, 35, 40, 45, 50, 55, + 60, 65, 70, 75, 80, 85, + 90, 95, 100 +}; + +static double dampf_feuchten[DAMPF_ANZ] = { + 1.7465E-5, 4.5752E-5, 1.1373E-4, 2.6939E-4, 6.1013E-4, 1.3260E-3, + 2.7735E-3, 0.005598, 0.010930, 0.020692, 0.038056, 0.068124, + 0.11890, 0.20265, 0.33776, 0.55127, 0.88211, 1.3854, + 2.1380, 3.2449, 3.5205, 3.8172, 4.1363, 4.4794, + 4.84795, 5.19317, 5.55921, 5.94766, 6.35967, 6.79642, + 7.25917, 7.74919, 8.26783, 8.81648, 9.39658, 10.0096, + 10.6572, 11.3408, 12.0623, 12.8232, 13.6254, 14.4707, + 15.3611, 16.2984, 17.2848, 18.3224, 19.4132, 20.5596, + 21.7638, 23.0283, 24.3554, 25.7477, 27.2079, 28.7385, + 30.3424, 39.5623, 51.0726, 65.3114, 82.7730, 104.011, + 129.642, 160.344, 196.863, 240.011, 290.669, 349.782, + 418.369, 497.511, 588.359 +}; + +double maximale_luftfeuchte(double t); +double taupunkt(double af); + +#endif // HUMIDITY_H diff --git a/input_gadgets.c b/input_gadgets.c index 907e05e..863baab 100644 --- a/input_gadgets.c +++ b/input_gadgets.c @@ -11,10 +11,12 @@ #include <zip.h> #include "input_gadgets.h" +#include "humidity.h" -#define fh_temperature_regex "\n\\s*Wetterdaten vom ([0-9]{2}\\.[0-9]{2}\\.[0-9]{4} um [0-9]{2}:[0-9]{2} MEZ)</strong>(.|\n)*>Temperatur</td>\\s*\n\\s*<td [^>]*><strong>([^<]*)</strong>" +#define fh_temperature_regex "\n\\s*Wetterdaten vom ([0-9]{2}\\.[0-9]{2}\\.[0-9]{4} um [0-9]{2}:[0-9]{2} MEZ)</strong>(.|\n)*>Temperatur</td>\\s*\n\\s*<td [^>]*><strong>([^<]*)</strong>(.|\n)*>Luftfeuchtigkeit</td>\\s*\n\\s*<td [^>]*><strong>([^<]*)</strong>" #define wetter_warnung_filename_regex "^2\\.49\\.0\\.1\\.276\\.0\\.DWD\\.PVW\\.([0-9]+)\\." #define warnings_future_timespan (60*60*10) +#define kpi_regex "RH: (-?[0-9.]+) %\nT: (-?[0-9.]+) " static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) @@ -138,7 +140,7 @@ size_t adaptive_strftime(char *s, size_t max, const struct tm *tm_print) return strftime(s, max, "%H:%M", tm_print); } -char *gadgets_retrieve_current_temperature(char *output, int max_len) +char *gadgets_retrieve_current_temperature(char *output, int max_len, double *temperature, double *humidity) { CURL *curl_handle; CURLcode res; @@ -180,13 +182,13 @@ char *gadgets_retrieve_current_temperature(char *output, int max_len) } regex_t re; - regmatch_t rm[4]; + regmatch_t rm[6]; if (regcomp(&re, fh_temperature_regex, REG_EXTENDED|REG_NEWLINE) != 0) { fprintf(stderr, "Failed to compile regex '%s'\n", fh_temperature_regex); free(chunk.memory); return NULL; } - if (ret_val = regexec(&re, chunk.memory, 4, rm, 0)) { + if (ret_val = regexec(&re, chunk.memory, 6, rm, 0)) { char *reg_err; reg_err = malloc(1024); regerror(ret_val, &re, reg_err, 1024); @@ -210,6 +212,11 @@ char *gadgets_retrieve_current_temperature(char *output, int max_len) ende += snprintf(output, max_len, "%.*s", (int)(rm[3].rm_eo - rm[3].rm_so), (char*)(chunk.memory + rm[3].rm_so) // temperature ); + char tmp_str[7]; + snprintf(tmp_str, 6, "%.*s", (int)(rm[3].rm_eo - rm[3].rm_so - 3), (char*)(chunk.memory + rm[3].rm_so)); + *temperature = atof(tmp_str); + snprintf(tmp_str, 6, "%.*s", (int)(rm[5].rm_eo - rm[5].rm_so - 2), (char*)(chunk.memory + rm[5].rm_so)); + *humidity = atof(tmp_str) / 100.; for (char *i = output; i < ende; i++) if (*i == '.') *i = ','; @@ -964,3 +971,89 @@ char *gadgets_retrieve_weather_warnings(char *output, int max_len) return ende; } + +char *gadgets_retrieve_humidity(char *output, int max_len, double fh_temperature, double fh_humidity) +{ + CURL *curl_handle; + CURLcode res; + MemoryStruct chunk; + int ret_val; + double temperature, humidity; + char *ende = output; + + chunk.memory = malloc(1); + chunk.size = 0; + + curl_global_init(CURL_GLOBAL_ALL); + + curl_handle = curl_easy_init(); + if (!curl_handle) { + perror("Failed to init curl"); + free(chunk.memory); + return NULL; + } + curl_easy_setopt(curl_handle, CURLOPT_URL, "https://kpi.ddns.eckner.net/tmp/sensor"); + curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); + curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); + curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0"); + res = curl_easy_perform(curl_handle); + curl_easy_cleanup(curl_handle); + if (res != CURLE_OK) { + fprintf( + stderr, + "curl_easy_perform(%s) failed: %s\n", + "https://kpi.ddns.eckner.net/tmp/sensor", + curl_easy_strerror(res) + ); + free(chunk.memory); + if (res != CURLE_COULDNT_RESOLVE_HOST && res != CURLE_COULDNT_CONNECT) + return NULL; + if (max_len > 0) + ende += snprintf(ende, max_len, "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", 0xEE, 0x01, 0xEE, 0x02, 0xEE, 0x01, 0xEE, 0x02, 0xEE, 0x05, 0xEE, 0x06, 0xEE, 0x05, 0xEE, 0x06); + return ende; + } + + regex_t re; + regmatch_t rm[3]; + if (regcomp(&re, kpi_regex, REG_EXTENDED|REG_NEWLINE) != 0) { + fprintf(stderr, "Failed to compile regex '%s'\n", kpi_regex); + free(chunk.memory); + return NULL; + } + if (ret_val = regexec(&re, chunk.memory, 3, rm, 0)) { + char *reg_err; + reg_err = malloc(1024); + regerror(ret_val, &re, reg_err, 1024); + fprintf(stderr, "%d %s\n",ret_val,reg_err); + regfree(&re); + free(chunk.memory); + return NULL; + } + regfree(&re); + + char tmp_str[12]; + snprintf(tmp_str, 11, "%.*s", (int)(rm[1].rm_eo - rm[1].rm_so), (char*)(chunk.memory + rm[1].rm_so)); + humidity = atof(tmp_str) / 100.; + snprintf(tmp_str, 11, "%.*s", (int)(rm[2].rm_eo - rm[2].rm_so), (char*)(chunk.memory + rm[2].rm_so)); + temperature = atof(tmp_str); + + humidity *= maximale_luftfeuchte(temperature); + fh_humidity *= maximale_luftfeuchte(fh_temperature); + + if ((output + max_len - ende > 0) && (temperature <= taupunkt(fh_humidity))) + ende += snprintf(ende, max_len, "!TP %.1f K; ", taupunkt(fh_humidity) - temperature); + if ((output + max_len - ende > 0) && (temperature <= taupunkt(humidity))) + ende += snprintf(ende, max_len, "!TP %.1f K; ", taupunkt(humidity) - temperature); + if (output + max_len - ende > 0) + ende += snprintf(ende, max_len, "%.0f %%", humidity * 100 / fh_humidity); + free(chunk.memory); + + while (output < ende) { + if (*output == '.') + *output = ','; + output++; + } + + return ende; +} diff --git a/input_gadgets.h b/input_gadgets.h index 1c667e3..b3e3644 100644 --- a/input_gadgets.h +++ b/input_gadgets.h @@ -15,8 +15,9 @@ typedef struct { time_t onset, expires; } warning_t; -char *gadgets_retrieve_current_temperature(char *output, int max_len); +char *gadgets_retrieve_current_temperature(char *output, int max_len, double *temperature, double *humidity); char *gadgets_retrieve_weather_forecast(char *output, int max_len); char *gadgets_retrieve_weather_warnings(char *output, int max_len); +char *gadgets_retrieve_humidity(char *output, int max_len, double fh_temperature, double fh_humidity); #endif // INPUT_GADGETS_H |