summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErich Eckner <git@eckner.net>2018-10-24 15:30:09 +0200
committerErich Eckner <git@eckner.net>2018-10-24 15:30:09 +0200
commit49116c127443e5880423eca02889f8d576635652 (patch)
tree98d22f02766e84aa2290150557f54e4676591e87
parentd7e5888dd7467daf56b9b7adc52c28794cdc6282 (diff)
downloadanzeige-49116c127443e5880423eca02889f8d576635652.tar.xz
input_gadgets: gadgets_retrieve_weather_forecast() neu
-rw-r--r--Makefile4
-rw-r--r--anzeige.c2
-rw-r--r--input_gadgets.c126
-rw-r--r--input_gadgets.h1
4 files changed, 130 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index 15d0f41..0d0a706 100644
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,13 @@
CFLAGS="-Werror=implicit-function-declaration"
anzeige: anzeige.c fonts.o input_gadgets.o multiplexer.o
- gcc -O3 -o "$@" $(CFLAGS) -lpthread -lcurl $^
+ gcc -O3 -o "$@" $(CFLAGS) -lpthread -lxml2 -lcurl $^
fonts.o: fonts.c fonts.h
gcc -O3 -o "$@" $(CFLAGS) -c "$<"
input_gadgets.o: input_gadgets.c input_gadgets.h
- gcc -O3 -o "$@" $(CFLAGS) -c -lcurl "$<"
+ gcc -O3 -o "$@" $(CFLAGS) -c -I/usr/include/libxml2 -lxml2 -lcurl "$<"
multiplexer.o: multiplexer.c multiplexer.h
gcc -O3 -o "$@" $(CFLAGS) -c -lpthread "$<"
diff --git a/anzeige.c b/anzeige.c
index 0c3143a..cd6dbf0 100644
--- a/anzeige.c
+++ b/anzeige.c
@@ -51,7 +51,7 @@ int main(int argc, char **argv)
}
memset(text_buffer, 0, TEXT_BUFFER_LENGTH);
- ret_val = gadgets_retrieve_current_temperature(text_buffer,TEXT_BUFFER_LENGTH);
+ ret_val = gadgets_retrieve_weather_forecast(text_buffer,TEXT_BUFFER_LENGTH);
if (ret_val) {
free(text_buffer);
exit(ret_val);
diff --git a/input_gadgets.c b/input_gadgets.c
index f452ca0..0426c56 100644
--- a/input_gadgets.c
+++ b/input_gadgets.c
@@ -2,6 +2,11 @@
#include <stdlib.h>
#include <curl/curl.h>
#include <regex.h>
+#include <stdio.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <time.h>
+#include <math.h>
#include "input_gadgets.h"
@@ -92,3 +97,124 @@ int gadgets_retrieve_current_temperature(unsigned char *output, int max_len)
free(chunk.memory);
return 0;
}
+
+xmlNode *xml_find_node_by_name(xmlNode *cur_node, char *name)
+{
+ while (cur_node) {
+ if ((cur_node -> type == XML_ELEMENT_NODE) &&
+ (strcmp(cur_node -> name, name) == 0))
+ return cur_node;
+ cur_node = cur_node -> next;
+ }
+ return NULL;
+}
+
+int gadgets_retrieve_weather_forecast(unsigned char *output, int max_len)
+{
+ CURL *curl_handle;
+ CURLcode res;
+ struct MemoryStruct chunk;
+ int ret_val;
+
+ 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 EXIT_FAILURE;
+ }
+ curl_easy_setopt(curl_handle, CURLOPT_URL, "https://api.met.no/weatherapi/locationforecast/1.9/?lat=50.8830&lon=11.6223&msl=170");
+ 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() failed: %s\n", curl_easy_strerror(res));
+ free(chunk.memory);
+ return EXIT_FAILURE;
+ }
+
+ LIBXML_TEST_VERSION
+
+ xmlDocPtr doc;
+ doc = xmlReadMemory(chunk.memory, chunk.size, "noname.xml", NULL, 0);
+ free(chunk.memory);
+ if (doc == NULL) {
+ fprintf(stderr, "Failed to parse document\n");
+ return EXIT_FAILURE;
+ }
+
+ xmlNode *cur_node = NULL;
+ xmlNode *sub_node = NULL;
+ cur_node = xmlDocGetRootElement(doc);
+ if (!cur_node) {
+ fprintf(stderr, "Failed to reach root node of xml\n");
+ return EXIT_FAILURE;
+ }
+ cur_node = xml_find_node_by_name(cur_node, "weatherdata");
+ if (!cur_node) {
+ fprintf(stderr, "Failed to enter <weatherdata>\n");
+ return EXIT_FAILURE;
+ }
+ cur_node = xml_find_node_by_name(cur_node -> children, "product");
+ if (!cur_node) {
+ fprintf(stderr, "Failed to enter <product>\n");
+ return EXIT_FAILURE;
+ }
+
+ float rain_total = 0, temp_min = NAN, temp_max = NAN, wind_max = NAN, cur_val;
+
+ char time_str[2][21];
+ time_t now;
+ time(&now);
+ now = ((int)(now/60/60))*60*60;
+
+ for (cur_node = cur_node -> children; cur_node; cur_node = cur_node->next) {
+ if ((cur_node->type == XML_ELEMENT_NODE) && (strcmp(cur_node->name,"time")==0) && (strcmp(xmlGetProp(cur_node,"datatype"),"forecast")==0)) {
+ for (int i=0; i<=14; i++) {
+ now += i*60*60;
+ strftime(time_str[0],21,"%Y-%m-%dT%H:%M:%SZ",gmtime(&now));
+ now += 60*60;
+ strftime(time_str[1],21,"%Y-%m-%dT%H:%M:%SZ",gmtime(&now));
+ now -= (i+1)*60*60;
+ if ((strcmp(time_str[1],xmlGetProp(cur_node,"from"))==0) && (strcmp(time_str[1],xmlGetProp(cur_node,"to"))==0)) {
+ sub_node = xml_find_node_by_name(cur_node -> children,"location");
+ cur_val = atof(xmlGetProp(xml_find_node_by_name(sub_node -> children, "temperature"), "value"));
+ if (isnan(temp_max) || (cur_val > temp_max))
+ temp_max = cur_val;
+ if (isnan(temp_min) || (cur_val < temp_min))
+ temp_min = cur_val;
+ cur_val = atof(xmlGetProp(xml_find_node_by_name(sub_node -> children, "windSpeed"),"mps"));
+ if (isnan(wind_max) || (cur_val > wind_max))
+ wind_max = cur_val;
+ }
+ if ((strcmp(time_str[0],xmlGetProp(cur_node,"from"))==0) && (strcmp(time_str[1],xmlGetProp(cur_node,"to"))==0)) {
+ sub_node = xml_find_node_by_name(cur_node -> children,"location");
+ if (!sub_node)
+ continue;
+ sub_node = xml_find_node_by_name(sub_node -> children, "precipitation");
+ if (!sub_node)
+ continue;
+ rain_total += atof(xmlGetProp(sub_node,"value"));
+ }
+ }
+ }
+ }
+ xmlFreeDoc(doc);
+ xmlCleanupParser();
+
+ int i = snprintf(output, max_len, "%0.1f ,, %0.1f °C; %0.1f mm; %0.1f m/s;", temp_min, temp_max, rain_total, wind_max);
+ for (; i>=0; i--)
+ if (output[i] == '.')
+ output[i] = ',';
+ else if (output[i] == ',')
+ output[i] = '.';
+
+ return EXIT_SUCCESS;
+}
diff --git a/input_gadgets.h b/input_gadgets.h
index cdf1bcb..002d9ef 100644
--- a/input_gadgets.h
+++ b/input_gadgets.h
@@ -4,3 +4,4 @@ struct MemoryStruct {
};
int gadgets_retrieve_current_temperature(unsigned char *output, int max_len);
+int gadgets_retrieve_weather_forecast(unsigned char *output, int max_len);