diff --git a/libs/pilight/protocols/API/openweathermap.c b/libs/pilight/protocols/API/openweathermap.c index be5a6291a..f9ef314b7 100644 --- a/libs/pilight/protocols/API/openweathermap.c +++ b/libs/pilight/protocols/API/openweathermap.c @@ -36,12 +36,13 @@ #define INTERVAL 600 static int min_interval = INTERVAL; static int time_override = -1; -static char url[1024] = "http://api.openweathermap.org/data/2.5/weather?q=%s,%s&APPID=8db24c4ac56251371c7ea87fd3115493"; +static char url[1024] = "http://api.openweathermap.org/data/2.5/weather?q=%s,%s&APPID=%s"; typedef struct data_t { char *name; char *country; char *location; + char *api; uv_timer_t *enable_timer_req; uv_timer_t *update_timer_req; @@ -146,8 +147,8 @@ static void callback(int code, char *data, int size, char *type, void *userdata) OUT_OF_MEMORY /*LCOV_EXCL_LINE*/ }; snprintf(data->message, 1024, - "{\"location\":\"%s\",\"country\":\"%s\",\"temperature\":%.2f,\"humidity\":%.2f,\"update\":0,\"sunrise\":%.2f,\"sunset\":%.2f,\"sun\":\"%s\"}", - settings->location, settings->country, temp, humi, ((double)((tm_rise.tm_hour*100)+tm_rise.tm_min)/100), ((double)((tm_set.tm_hour*100)+tm_set.tm_min)/100), _sun + "{\"api\":\"%s\",\"location\":\"%s\",\"country\":\"%s\",\"temperature\":%.2f,\"humidity\":%.2f,\"update\":0,\"sunrise\":%.2f,\"sunset\":%.2f,\"sun\":\"%s\"}", + settings->api, settings->location, settings->country, temp, humi, ((double)((tm_rise.tm_hour*100)+tm_rise.tm_min)/100), ((double)((tm_set.tm_hour*100)+tm_set.tm_min)/100), _sun ); strncpy(data->origin, "receiver", 255); data->protocol = openweathermap->id; @@ -224,7 +225,7 @@ static void thread(uv_work_t *req) { char *enc = urlencode(settings->location); memset(parsed, '\0', 1024); - snprintf(parsed, 1024, url, enc, settings->country); + snprintf(parsed, 1024, url, enc, settings->country, settings->api); FREE(enc); http_get_content(parsed, callback, settings); @@ -258,8 +259,8 @@ static void *enable(void *param) { OUT_OF_MEMORY /*LCOV_EXCL_LINE*/ }; snprintf(data->message, 1024, - "{\"location\":\"%s\",\"country\":\"%s\",\"update\":1}", - settings->location, settings->country + "{\"api\":\"%s\",\"location\":\"%s\",\"country\":\"%s\",\"update\":1}", + settings->api, settings->location, settings->country ); strncpy(data->origin, "receiver", 255); data->protocol = openweathermap->id; @@ -359,14 +360,21 @@ static void *addDevice(int reason, void *param) { node->update = 0; node->temp_offset = 0; - int has_country = 0, has_location = 0; + int has_country = 0, has_location = 0, has_api = 0; if((jid = json_find_member(jdevice, "id"))) { jchild = json_first_child(jid); while(jchild) { - has_country = 0, has_location = 0; + has_country = 0, has_location = 0, has_api = 0; jchild1 = json_first_child(jchild); while(jchild1) { + if(strcmp(jchild1->key, "api") == 0) { + has_api = 1; + if((node->api = MALLOC(strlen(jchild1->string_)+1)) == NULL) { + OUT_OF_MEMORY /*LCOV_EXCL_LINE*/ + } + strcpy(node->api, jchild1->string_); + } if(strcmp(jchild1->key, "location") == 0) { has_location = 1; if((node->location = MALLOC(strlen(jchild1->string_)+1)) == NULL) { @@ -383,7 +391,7 @@ static void *addDevice(int reason, void *param) { } jchild1 = jchild1->next; } - if(has_country == 1 && has_location == 1) { + if(has_country == 1 && has_location == 1 && has_api == 1) { node->next = data; data = node; } else { @@ -452,6 +460,7 @@ static int createCode(struct JsonNode *code, char **message) { struct data_t *tmp = data; char *country = NULL; char *location = NULL; + char *api = NULL; double itmp = 0; if(json_find_number(code, "min-interval", &itmp) == 0) { @@ -461,6 +470,7 @@ static int createCode(struct JsonNode *code, char **message) { if(json_find_string(code, "country", &country) == 0 && json_find_string(code, "location", &location) == 0 && + json_find_string(code, "api", &api) == 0 && json_find_number(code, "update", &itmp) == 0) { time_t currenttime = time(NULL); @@ -470,7 +480,8 @@ static int createCode(struct JsonNode *code, char **message) { while(tmp) { if(strcmp(tmp->country, country) == 0 - && strcmp(tmp->location, location) == 0) { + && strcmp(tmp->location, location) == 0 + && strcmp(tmp->api, api) == 0) { if((currenttime-tmp->update) > min_interval) { uv_work_t *work_req = NULL; @@ -503,6 +514,7 @@ static void gc(void) { FREE(tmp->country); FREE(tmp->location); FREE(tmp->name); + FREE(tmp->api); data = data->next; FREE(tmp); } @@ -514,6 +526,7 @@ static void gc(void) { static void printHelp(void) { printf("\t -c --country=country\t\tupdate an entry with this country\n"); printf("\t -l --location=location\t\tupdate an entry with this location\n"); + printf("\t -a --api=api\t\t\tupdate an entry with this api code\n"); printf("\t -u --update\t\t\tupdate the defined weather entry\n"); } @@ -534,6 +547,7 @@ void openweathermapInit(void) { options_add(&openweathermap->options, 'h', "humidity", OPTION_HAS_VALUE, DEVICES_VALUE, JSON_NUMBER, NULL, "^[0-9]{1,5}$"); options_add(&openweathermap->options, 'l', "location", OPTION_HAS_VALUE, DEVICES_ID, JSON_STRING, NULL, "^([a-zA-Z-]|[[:space:]])+$"); options_add(&openweathermap->options, 'c', "country", OPTION_HAS_VALUE, DEVICES_ID, JSON_STRING, NULL, "^[a-zA-Z]+$"); + options_add(&openweathermap->options, 'a', "api", OPTION_HAS_VALUE, DEVICES_ID, JSON_STRING, NULL, "^[a-zA-Z]+$"); options_add(&openweathermap->options, 'x', "sunrise", OPTION_HAS_VALUE, DEVICES_VALUE, JSON_NUMBER, NULL, "^[0-9]{3,4}$"); options_add(&openweathermap->options, 'y', "sunset", OPTION_HAS_VALUE, DEVICES_VALUE, JSON_NUMBER, NULL, "^[0-9]{3,4}$"); options_add(&openweathermap->options, 's', "sun", OPTION_HAS_VALUE, DEVICES_VALUE, JSON_STRING, NULL, NULL); diff --git a/tests/protocols_api_openweathermap.c b/tests/protocols_api_openweathermap.c index 868c41911..0d1191631 100644 --- a/tests/protocols_api_openweathermap.c +++ b/tests/protocols_api_openweathermap.c @@ -72,11 +72,11 @@ static void *received(int reason, void *param) { CuAssertIntEquals(gtc, 1, duration); char message[1024]; CuAssertStrEquals(gtc, - "{\"location\":\"amsterdam\",\"country\":\"nl\",\"update\":1}", + "{\"api\":\"8db24c4ac56251371c7ea87fd3115493\",\"location\":\"amsterdam\",\"country\":\"nl\",\"update\":1}", data->message); steps = 1; CuAssertPtrNotNull(gtc, openweathermap->createCode); - struct JsonNode *code = json_decode("{\"location\":\"amsterdam\",\"country\":\"nl\",\"update\":1}"); + struct JsonNode *code = json_decode("{\"api\":\"8db24c4ac56251371c7ea87fd3115493\",\"location\":\"amsterdam\",\"country\":\"nl\",\"update\":1}"); char *p = message; openweathermap->createCode(code, &p); json_delete(code); @@ -86,7 +86,7 @@ static void *received(int reason, void *param) { case 1: { CuAssertIntEquals(gtc, 0, duration); CuAssertStrEquals(gtc, - "{\"location\":\"amsterdam\",\"country\":\"nl\",\"temperature\":-1.00,\"humidity\":74.00,\"update\":0,\"sunrise\":7.48,\"sunset\":15.44,\"sun\":\"set\"}", + "{\"api\":\"8db24c4ac56251371c7ea87fd3115493\",\"location\":\"amsterdam\",\"country\":\"nl\",\"temperature\":-1.00,\"humidity\":74.00,\"update\":0,\"sunrise\":7.48,\"sunset\":15.44,\"sun\":\"set\"}", data->message); uv_stop(uv_default_loop()); } break; @@ -107,7 +107,7 @@ static void *received(int reason, void *param) { * After two seconds the first message should be received */ CuAssertStrEquals(gtc, - "{\"location\":\"amsterdam\",\"country\":\"nl\",\"temperature\":-1.00,\"humidity\":74.00,\"update\":0,\"sunrise\":7.48,\"sunset\":15.44,\"sun\":\"set\"}", + "{\"api\":\"8db24c4ac56251371c7ea87fd3115493\",\"location\":\"amsterdam\",\"country\":\"nl\",\"temperature\":-1.00,\"humidity\":74.00,\"update\":0,\"sunrise\":7.48,\"sunset\":15.44,\"sun\":\"set\"}", data->message); /* * Shift time to after sunrise and check if we get a @@ -125,7 +125,7 @@ static void *received(int reason, void *param) { * After one second the sunrise notification should be sent */ CuAssertStrEquals(gtc, - "{\"location\":\"amsterdam\",\"country\":\"nl\",\"temperature\":-1.00,\"humidity\":74.00,\"update\":0,\"sunrise\":7.48,\"sunset\":15.44,\"sun\":\"rise\"}", + "{\"api\":\"8db24c4ac56251371c7ea87fd3115493\",\"location\":\"amsterdam\",\"country\":\"nl\",\"temperature\":-1.00,\"humidity\":74.00,\"update\":0,\"sunrise\":7.48,\"sunset\":15.44,\"sun\":\"rise\"}", data->message); uv_stop(uv_default_loop()); } break; @@ -146,7 +146,7 @@ static void *received(int reason, void *param) { * After two seconds the first message should be received */ CuAssertStrEquals(gtc, - "{\"location\":\"amsterdam\",\"country\":\"nl\",\"temperature\":-1.00,\"humidity\":74.00,\"update\":0,\"sunrise\":7.48,\"sunset\":15.44,\"sun\":\"rise\"}", + "{\"api\":\"8db24c4ac56251371c7ea87fd3115493\",\"location\":\"amsterdam\",\"country\":\"nl\",\"temperature\":-1.00,\"humidity\":74.00,\"update\":0,\"sunrise\":7.48,\"sunset\":15.44,\"sun\":\"rise\"}", data->message); /* * Shift time to after sunset and check if we get a @@ -164,7 +164,7 @@ static void *received(int reason, void *param) { * After one second the sunrise notification should be sent */ CuAssertStrEquals(gtc, - "{\"location\":\"amsterdam\",\"country\":\"nl\",\"temperature\":-1.00,\"humidity\":74.00,\"update\":0,\"sunrise\":7.48,\"sunset\":15.44,\"sun\":\"set\"}", + "{\"api\":\"8db24c4ac56251371c7ea87fd3115493\",\"location\":\"amsterdam\",\"country\":\"nl\",\"temperature\":-1.00,\"humidity\":74.00,\"update\":0,\"sunrise\":7.48,\"sunset\":15.44,\"sun\":\"set\"}", data->message); uv_stop(uv_default_loop()); } break; @@ -185,7 +185,7 @@ static void *received(int reason, void *param) { * Directly after, the first message should be received */ CuAssertStrEquals(gtc, - "{\"location\":\"amsterdam\",\"country\":\"nl\",\"temperature\":-1.00,\"humidity\":74.00,\"update\":0,\"sunrise\":7.48,\"sunset\":15.44,\"sun\":\"set\"}", + "{\"api\":\"8db24c4ac56251371c7ea87fd3115493\",\"location\":\"amsterdam\",\"country\":\"nl\",\"temperature\":-1.00,\"humidity\":74.00,\"update\":0,\"sunrise\":7.48,\"sunset\":15.44,\"sun\":\"set\"}", data->message); steps = 2; @@ -198,7 +198,7 @@ static void *received(int reason, void *param) { * After one second the sunrise notification should be sent */ CuAssertStrEquals(gtc, - "{\"location\":\"amsterdam\",\"country\":\"nl\",\"temperature\":-1.00,\"humidity\":74.00,\"update\":0,\"sunrise\":7.48,\"sunset\":15.44,\"sun\":\"set\"}", + "{\"api\":\"8db24c4ac56251371c7ea87fd3115493\",\"location\":\"amsterdam\",\"country\":\"nl\",\"temperature\":-1.00,\"humidity\":74.00,\"update\":0,\"sunrise\":7.48,\"sunset\":15.44,\"sun\":\"set\"}", data->message); uv_stop(uv_default_loop()); } break; @@ -328,8 +328,8 @@ static void test_protocols_api_openweathermap_update(CuTest *tc) { memset(&add, '\0', 1024); memset(&adapt, '\0', 1024); - strcpy(adapt, "{\"openweathermap\":{\"time-override\":1484393226,\"url\":\"http://127.0.0.1:10080/data/2.5/weather?q=%s,%s&APPID=8db24c4ac56251371c7ea87fd3115493\"}}"); - strcpy(add, "{\"test\":{\"protocol\":[\"openweathermap\"],\"id\":[{\"country\":\"nl\",\"location\":\"amsterdam\"}],\"humidity\":94.00,\"temperature\":0.21,\"sunrise\":8.29,\"sunset\":17.05,\"sun\":\"set\",\"update\":0,\"poll-interval\":1}}"); + strcpy(adapt, "{\"openweathermap\":{\"time-override\":1484393226,\"url\":\"http://127.0.0.1:10080/data/2.5/weather?q=%s,%s&APPID=%s\"}}"); + strcpy(add, "{\"test\":{\"protocol\":[\"openweathermap\"],\"id\":[{\"api\":\"8db24c4ac56251371c7ea87fd3115493\",\"country\":\"nl\",\"location\":\"amsterdam\"}],\"humidity\":94.00,\"temperature\":0.21,\"sunrise\":8.29,\"sunset\":17.05,\"sun\":\"set\",\"update\":0,\"poll-interval\":1}}"); run = UPDATE; @@ -354,8 +354,8 @@ static void test_protocols_api_openweathermap_sunrise(CuTest *tc) { memset(&add, '\0', 1024); memset(&adapt, '\0', 1024); - strcpy(adapt, "{\"openweathermap\":{\"time-override\":1483688921,\"url\":\"http://127.0.0.1:10080/data/2.5/weather?q=%s,%s&APPID=8db24c4ac56251371c7ea87fd3115493\"}}"); - strcpy(add, "{\"test\":{\"protocol\":[\"openweathermap\"],\"id\":[{\"country\":\"nl\",\"location\":\"amsterdam\"}],\"humidity\":94.00,\"temperature\":0.21,\"sunrise\":8.29,\"sunset\":17.05,\"sun\":\"set\",\"update\":0,\"poll-interval\":1}}"); + strcpy(adapt, "{\"openweathermap\":{\"time-override\":1483688921,\"url\":\"http://127.0.0.1:10080/data/2.5/weather?q=%s,%s&APPID=%s\"}}"); + strcpy(add, "{\"test\":{\"protocol\":[\"openweathermap\"],\"id\":[{\"api\":\"8db24c4ac56251371c7ea87fd3115493\",\"country\":\"nl\",\"location\":\"amsterdam\"}],\"humidity\":94.00,\"temperature\":0.21,\"sunrise\":8.29,\"sunset\":17.05,\"sun\":\"set\",\"update\":0,\"poll-interval\":1}}"); printf("[ %-48s ]\n", "- waiting for first openweathermap notification"); fflush(stdout); @@ -380,8 +380,8 @@ static void test_protocols_api_openweathermap_sunset(CuTest *tc) { memset(&add, '\0', 1024); memset(&adapt, '\0', 1024); - strcpy(adapt, "{\"openweathermap\":{\"time-override\":1483717489,\"url\":\"http://127.0.0.1:10080/data/2.5/weather?q=%s,%s&APPID=8db24c4ac56251371c7ea87fd3115493\"}}"); - strcpy(add, "{\"test\":{\"protocol\":[\"openweathermap\"],\"id\":[{\"country\":\"nl\",\"location\":\"amsterdam\"}],\"humidity\":94.00,\"temperature\":0.21,\"sunrise\":8.29,\"sunset\":17.05,\"sun\":\"set\",\"update\":0,\"poll-interval\":1}}"); + strcpy(adapt, "{\"openweathermap\":{\"time-override\":1483717489,\"url\":\"http://127.0.0.1:10080/data/2.5/weather?q=%s,%s&APPID=%s\"}}"); + strcpy(add, "{\"test\":{\"protocol\":[\"openweathermap\"],\"id\":[{\"api\":\"8db24c4ac56251371c7ea87fd3115493\",\"country\":\"nl\",\"location\":\"amsterdam\"}],\"humidity\":94.00,\"temperature\":0.21,\"sunrise\":8.29,\"sunset\":17.05,\"sun\":\"set\",\"update\":0,\"poll-interval\":1}}"); printf("[ %-48s ]\n", "- waiting for first openweathermap notification"); fflush(stdout); @@ -406,8 +406,8 @@ static void test_protocols_api_openweathermap_midnight(CuTest *tc) { memset(&add, '\0', 1024); memset(&adapt, '\0', 1024); - strcpy(adapt, "{\"openweathermap\":{\"time-override\":1483833599,\"url\":\"http://127.0.0.1:10080/data/2.5/weather?q=%s,%s&APPID=8db24c4ac56251371c7ea87fd3115493\"}}"); - strcpy(add, "{\"test\":{\"protocol\":[\"openweathermap\"],\"id\":[{\"country\":\"nl\",\"location\":\"amsterdam\"}],\"humidity\":94.00,\"temperature\":0.21,\"sunrise\":8.29,\"sunset\":17.05,\"sun\":\"set\",\"update\":0,\"poll-interval\":1}}"); + strcpy(adapt, "{\"openweathermap\":{\"time-override\":1483833599,\"url\":\"http://127.0.0.1:10080/data/2.5/weather?q=%s,%s&APPID=%s\"}}"); + strcpy(add, "{\"test\":{\"protocol\":[\"openweathermap\"],\"id\":[{\"api\":\"8db24c4ac56251371c7ea87fd3115493\",\"country\":\"nl\",\"location\":\"amsterdam\"}],\"humidity\":94.00,\"temperature\":0.21,\"sunrise\":8.29,\"sunset\":17.05,\"sun\":\"set\",\"update\":0,\"poll-interval\":1}}"); printf("[ %-48s ]\n", "- waiting for first openweathermap notification"); fflush(stdout);