summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErich Eckner <git@eckner.net>2019-09-24 10:16:10 +0200
committerErich Eckner <git@eckner.net>2019-09-24 10:16:10 +0200
commit9ee88c6b2c0e1abcc2db39b531a9192662bb68b6 (patch)
tree1de873641e4dd53f6b1bf1c362ff971401a36df0
parente103f73f5025f9fda6067040f22a211ea3af753d (diff)
parent375324e5f4c0cc0a4137c60df03334d1bef92fff (diff)
downloadanzeige-9ee88c6b2c0e1abcc2db39b531a9192662bb68b6.tar.xz
Merge branch 'humidity'
-rw-r--r--Makefile10
-rw-r--r--anzeige.c15
-rw-r--r--humidity.c25
-rw-r--r--humidity.h39
-rw-r--r--input_gadgets.c101
-rw-r--r--input_gadgets.h3
6 files changed, 185 insertions, 8 deletions
diff --git a/Makefile b/Makefile
index f04d9ec..b494daa 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/anzeige.c b/anzeige.c
index 2a28867..311b4ac 100644
--- a/anzeige.c
+++ b/anzeige.c
@@ -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