diff --git a/components/http/CMakeLists.txt b/components/http/CMakeLists.txt deleted file mode 100644 index 78f19f0..0000000 --- a/components/http/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -idf_component_register(SRCS "http.c" - INCLUDE_DIRS "include") diff --git a/components/http/http.c b/components/http/http.c deleted file mode 100644 index 87539ee..0000000 --- a/components/http/http.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - http.c - HTTP request routines - - File based on https://github.com/espressif/esp-idf/tree/master/examples/03_http_request - - This file is part of the ESP32 Everest Run project - https://github.com/krzychb/esp32-everest-run - - Copyright (c) 2016 Krzysztof Budzynski - This work is licensed under the Apache License, Version 2.0, January 2004 - See the file LICENSE for details. -*/ - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "esp_system.h" -#include "esp_log.h" - -#include -#include "lwip/err.h" -#include "lwip/sockets.h" -#include "lwip/sys.h" -#include "lwip/netdb.h" -#include "lwip/dns.h" - -#include "http.h" - -#define RECV_BUFFER_SIZE 64 -static const char* TAG = "HTTP"; - - -void http_client_on_connected(http_client_data *client, http_callback http_on_connected_cb) -{ - client->http_connected_cb = http_on_connected_cb; -} - -void http_client_on_process_chunk(http_client_data *client, http_callback http_process_chunk_cb) -{ - client->http_process_chunk_cb = http_process_chunk_cb; -} - -void http_client_on_disconnected(http_client_data *client, http_callback http_disconnected_cb) -{ - client->http_disconnected_cb = http_disconnected_cb; -} - -esp_err_t http_client_request(http_client_data *client, const char *web_server, const char *request_string) -{ - const struct addrinfo hints = { - .ai_family = AF_INET, - .ai_socktype = SOCK_STREAM, - }; - struct addrinfo *res; - struct in_addr *addr; - int s, r; - char recv_buf[RECV_BUFFER_SIZE]; - - client->recv_buf = recv_buf; - client->recv_buf_size = sizeof(recv_buf); - - int err = getaddrinfo(web_server, "80", &hints, &res); - - if (err != 0 || res == NULL) { - ESP_LOGE(TAG, "DNS lookup failed err=%d res=%p", err, res); - vTaskDelay(1000 / portTICK_PERIOD_MS); - return ESP_ERR_HTTP_DNS_LOOKUP_FAILED; - } - - /* Code to print the resolved IP. - Note: inet_ntoa is non-reentrant, look at ipaddr_ntoa_r for "real" code - */ - addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr; - ESP_LOGI(TAG, "DNS lookup succeeded. IP=%s", inet_ntoa(*addr)); - - s = socket(res->ai_family, res->ai_socktype, 0); - if (s < 0) { - ESP_LOGE(TAG, "... Failed to allocate socket."); - freeaddrinfo(res); - vTaskDelay(1000 / portTICK_PERIOD_MS); - return ESP_ERR_HTTP_FAILED_TO_ALLOCATE_SOCKET; - } - ESP_LOGI(TAG, "... allocated socket"); - - if (connect(s, res->ai_addr, res->ai_addrlen) != 0) { - ESP_LOGE(TAG, "... socket connect failed errno=%d", errno); - close(s); - freeaddrinfo(res); - vTaskDelay(4000 / portTICK_PERIOD_MS); - return ESP_ERR_HTTP_SOCKET_CONNECT_FAILED; - } - - ESP_LOGI(TAG, "... connected"); - freeaddrinfo(res); - if (client->http_connected_cb) { - client->http_connected_cb((uint32_t*) client); - } - - if (write(s, request_string, strlen(request_string)) < 0) { - ESP_LOGE(TAG, "... socket send failed"); - close(s); - vTaskDelay(4000 / portTICK_PERIOD_MS); - return ESP_ERR_HTTP_SOCKET_SEND_FAILED; - } - ESP_LOGI(TAG, "... socket send success"); - - /* Read HTTP response */ - do { - bzero(recv_buf, sizeof(recv_buf)); - r = read(s, recv_buf, sizeof(recv_buf)-1); - if (client->http_process_chunk_cb) { - client->http_process_chunk_cb((uint32_t*) client); - } - } while (r > 0); - - ESP_LOGI(TAG, "... done reading from socket. Last read return=%d errno=%d", r, errno); - close(s); - if (client->http_disconnected_cb) { - client->http_disconnected_cb((uint32_t*) client); - } - return ESP_OK; -} - -/* Out of HTTP response return pointer to response body - Function return NULL if end of header cannot be identified - */ -const char* find_response_body(char * response) -{ - // Identify end of the response headers - // http://stackoverflow.com/questions/11254037/how-to-know-when-the-http-headers-part-is-ended - char * eol; // end of line - char * bol; // beginning of line - bool nheaderfound = false; // end of response headers has been found - - bol = response; - while ((eol = index(bol, '\n')) != NULL) { - // update bol based upon the value of eol - bol = eol + 1; - // test if end of headers has been reached - if ( (!(strncmp(bol, "\r\n", 2))) || (!(strncmp(bol, "\n", 1))) ) - { - // note that end of headers has been found - nheaderfound = true; - // update the value of bol to reflect the beginning of the line - // immediately after the headers - if (bol[0] != '\n') { - bol += 1; - } - bol += 1; - break; - } - } - if (nheaderfound) { - return bol; - } else { - return NULL; - } -} - - diff --git a/components/http/include/http.h b/components/http/include/http.h deleted file mode 100644 index 7a72b79..0000000 --- a/components/http/include/http.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - http.h - HTTP request routines - - This file is part of the ESP32 Everest Run project - https://github.com/krzychb/esp32-everest-run - - Copyright (c) 2016 Krzysztof Budzynski - This work is licensed under the Apache License, Version 2.0, January 2004 - See the file LICENSE for details. -*/ -#ifndef HTTP_H -#define HTTP_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "esp_err.h" - -typedef void (*http_callback)(uint32_t *args); - -typedef struct { - char *recv_buf; /*!< Pointer to a receive buffer, data from the socket are collected here */ - int recv_buf_size; /*!< Size of the receive buffer */ - char *proc_buf; /*!< Pointer to processing buffer, chunks of data from receive buffer and collected here. */ - int proc_buf_size; /*!< Size of processing buffer*/ - http_callback http_connected_cb; /*!< Pointer to function called once socket connection is established */ - http_callback http_process_chunk_cb; /*!< Pointer to function called to process contents of receive buffer, once it is filled up */ - http_callback http_disconnected_cb; /*!< Pointer to function called after disconnecting from the socket */ -} http_client_data; - -#define ESP_ERR_HTTP_BASE 0x40000 -#define ESP_ERR_HTTP_DNS_LOOKUP_FAILED (ESP_ERR_HTTP_BASE + 1) -#define ESP_ERR_HTTP_FAILED_TO_ALLOCATE_SOCKET (ESP_ERR_HTTP_BASE + 2) -#define ESP_ERR_HTTP_SOCKET_CONNECT_FAILED (ESP_ERR_HTTP_BASE + 3) -#define ESP_ERR_HTTP_SOCKET_SEND_FAILED (ESP_ERR_HTTP_BASE + 4) - -const char* find_response_body(char * response); -void http_client_on_connected(http_client_data *client, http_callback http_connected_cb); -void http_client_on_process_chunk(http_client_data *client, http_callback http_process_chunk_cb); -void http_client_on_disconnected(http_client_data *client, http_callback http_disconnected_cb); -esp_err_t http_client_request(http_client_data *client, const char *web_server, const char *request_string); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/components/jsmn/CMakeLists.txt b/components/jsmn/CMakeLists.txt deleted file mode 100644 index 776aa30..0000000 --- a/components/jsmn/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -idf_component_register(SRCS "jsmn.c" - INCLUDE_DIRS "include") diff --git a/components/jsmn/include/jsmn.h b/components/jsmn/include/jsmn.h deleted file mode 100644 index a1f17b7..0000000 --- a/components/jsmn/include/jsmn.h +++ /dev/null @@ -1,471 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2010 Serge Zaitsev - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef JSMN_H -#define JSMN_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef JSMN_STATIC -#define JSMN_API static -#else -#define JSMN_API extern -#endif - -/** - * JSON type identifier. Basic types are: - * o Object - * o Array - * o String - * o Other primitive: number, boolean (true/false) or null - */ -typedef enum { - JSMN_UNDEFINED = 0, - JSMN_OBJECT = 1 << 0, - JSMN_ARRAY = 1 << 1, - JSMN_STRING = 1 << 2, - JSMN_PRIMITIVE = 1 << 3 -} jsmntype_t; - -enum jsmnerr { - /* Not enough tokens were provided */ - JSMN_ERROR_NOMEM = -1, - /* Invalid character inside JSON string */ - JSMN_ERROR_INVAL = -2, - /* The string is not a full JSON packet, more bytes expected */ - JSMN_ERROR_PART = -3 -}; - -/** - * JSON token description. - * type type (object, array, string etc.) - * start start position in JSON data string - * end end position in JSON data string - */ -typedef struct jsmntok { - jsmntype_t type; - int start; - int end; - int size; -#ifdef JSMN_PARENT_LINKS - int parent; -#endif -} jsmntok_t; - -/** - * JSON parser. Contains an array of token blocks available. Also stores - * the string being parsed now and current position in that string. - */ -typedef struct jsmn_parser { - unsigned int pos; /* offset in the JSON string */ - unsigned int toknext; /* next token to allocate */ - int toksuper; /* superior token node, e.g. parent object or array */ -} jsmn_parser; - -/** - * Create JSON parser over an array of tokens - */ -JSMN_API void jsmn_init(jsmn_parser *parser); - -/** - * Run JSON parser. It parses a JSON data string into and array of tokens, each - * describing - * a single JSON object. - */ -JSMN_API int jsmn_parse(jsmn_parser *parser, const char *js, const size_t len, - jsmntok_t *tokens, const unsigned int num_tokens); - -#ifndef JSMN_HEADER -/** - * Allocates a fresh unused token from the token pool. - */ -static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser, jsmntok_t *tokens, - const size_t num_tokens) { - jsmntok_t *tok; - if (parser->toknext >= num_tokens) { - return NULL; - } - tok = &tokens[parser->toknext++]; - tok->start = tok->end = -1; - tok->size = 0; -#ifdef JSMN_PARENT_LINKS - tok->parent = -1; -#endif - return tok; -} - -/** - * Fills token type and boundaries. - */ -static void jsmn_fill_token(jsmntok_t *token, const jsmntype_t type, - const int start, const int end) { - token->type = type; - token->start = start; - token->end = end; - token->size = 0; -} - -/** - * Fills next available token with JSON primitive. - */ -static int jsmn_parse_primitive(jsmn_parser *parser, const char *js, - const size_t len, jsmntok_t *tokens, - const size_t num_tokens) { - jsmntok_t *token; - int start; - - start = parser->pos; - - for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { - switch (js[parser->pos]) { -#ifndef JSMN_STRICT - /* In strict mode primitive must be followed by "," or "}" or "]" */ - case ':': -#endif - case '\t': - case '\r': - case '\n': - case ' ': - case ',': - case ']': - case '}': - goto found; - default: - /* to quiet a warning from gcc*/ - break; - } - if (js[parser->pos] < 32 || js[parser->pos] >= 127) { - parser->pos = start; - return JSMN_ERROR_INVAL; - } - } -#ifdef JSMN_STRICT - /* In strict mode primitive must be followed by a comma/object/array */ - parser->pos = start; - return JSMN_ERROR_PART; -#endif - -found: - if (tokens == NULL) { - parser->pos--; - return 0; - } - token = jsmn_alloc_token(parser, tokens, num_tokens); - if (token == NULL) { - parser->pos = start; - return JSMN_ERROR_NOMEM; - } - jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos); -#ifdef JSMN_PARENT_LINKS - token->parent = parser->toksuper; -#endif - parser->pos--; - return 0; -} - -/** - * Fills next token with JSON string. - */ -static int jsmn_parse_string(jsmn_parser *parser, const char *js, - const size_t len, jsmntok_t *tokens, - const size_t num_tokens) { - jsmntok_t *token; - - int start = parser->pos; - - /* Skip starting quote */ - parser->pos++; - - for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { - char c = js[parser->pos]; - - /* Quote: end of string */ - if (c == '\"') { - if (tokens == NULL) { - return 0; - } - token = jsmn_alloc_token(parser, tokens, num_tokens); - if (token == NULL) { - parser->pos = start; - return JSMN_ERROR_NOMEM; - } - jsmn_fill_token(token, JSMN_STRING, start + 1, parser->pos); -#ifdef JSMN_PARENT_LINKS - token->parent = parser->toksuper; -#endif - return 0; - } - - /* Backslash: Quoted symbol expected */ - if (c == '\\' && parser->pos + 1 < len) { - int i; - parser->pos++; - switch (js[parser->pos]) { - /* Allowed escaped symbols */ - case '\"': - case '/': - case '\\': - case 'b': - case 'f': - case 'r': - case 'n': - case 't': - break; - /* Allows escaped symbol \uXXXX */ - case 'u': - parser->pos++; - for (i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; - i++) { - /* If it isn't a hex character we have an error */ - if (!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */ - (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */ - (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */ - parser->pos = start; - return JSMN_ERROR_INVAL; - } - parser->pos++; - } - parser->pos--; - break; - /* Unexpected symbol */ - default: - parser->pos = start; - return JSMN_ERROR_INVAL; - } - } - } - parser->pos = start; - return JSMN_ERROR_PART; -} - -/** - * Parse JSON string and fill tokens. - */ -JSMN_API int jsmn_parse(jsmn_parser *parser, const char *js, const size_t len, - jsmntok_t *tokens, const unsigned int num_tokens) { - int r; - int i; - jsmntok_t *token; - int count = parser->toknext; - - for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { - char c; - jsmntype_t type; - - c = js[parser->pos]; - switch (c) { - case '{': - case '[': - count++; - if (tokens == NULL) { - break; - } - token = jsmn_alloc_token(parser, tokens, num_tokens); - if (token == NULL) { - return JSMN_ERROR_NOMEM; - } - if (parser->toksuper != -1) { - jsmntok_t *t = &tokens[parser->toksuper]; -#ifdef JSMN_STRICT - /* In strict mode an object or array can't become a key */ - if (t->type == JSMN_OBJECT) { - return JSMN_ERROR_INVAL; - } -#endif - t->size++; -#ifdef JSMN_PARENT_LINKS - token->parent = parser->toksuper; -#endif - } - token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY); - token->start = parser->pos; - parser->toksuper = parser->toknext - 1; - break; - case '}': - case ']': - if (tokens == NULL) { - break; - } - type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY); -#ifdef JSMN_PARENT_LINKS - if (parser->toknext < 1) { - return JSMN_ERROR_INVAL; - } - token = &tokens[parser->toknext - 1]; - for (;;) { - if (token->start != -1 && token->end == -1) { - if (token->type != type) { - return JSMN_ERROR_INVAL; - } - token->end = parser->pos + 1; - parser->toksuper = token->parent; - break; - } - if (token->parent == -1) { - if (token->type != type || parser->toksuper == -1) { - return JSMN_ERROR_INVAL; - } - break; - } - token = &tokens[token->parent]; - } -#else - for (i = parser->toknext - 1; i >= 0; i--) { - token = &tokens[i]; - if (token->start != -1 && token->end == -1) { - if (token->type != type) { - return JSMN_ERROR_INVAL; - } - parser->toksuper = -1; - token->end = parser->pos + 1; - break; - } - } - /* Error if unmatched closing bracket */ - if (i == -1) { - return JSMN_ERROR_INVAL; - } - for (; i >= 0; i--) { - token = &tokens[i]; - if (token->start != -1 && token->end == -1) { - parser->toksuper = i; - break; - } - } -#endif - break; - case '\"': - r = jsmn_parse_string(parser, js, len, tokens, num_tokens); - if (r < 0) { - return r; - } - count++; - if (parser->toksuper != -1 && tokens != NULL) { - tokens[parser->toksuper].size++; - } - break; - case '\t': - case '\r': - case '\n': - case ' ': - break; - case ':': - parser->toksuper = parser->toknext - 1; - break; - case ',': - if (tokens != NULL && parser->toksuper != -1 && - tokens[parser->toksuper].type != JSMN_ARRAY && - tokens[parser->toksuper].type != JSMN_OBJECT) { -#ifdef JSMN_PARENT_LINKS - parser->toksuper = tokens[parser->toksuper].parent; -#else - for (i = parser->toknext - 1; i >= 0; i--) { - if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) { - if (tokens[i].start != -1 && tokens[i].end == -1) { - parser->toksuper = i; - break; - } - } - } -#endif - } - break; -#ifdef JSMN_STRICT - /* In strict mode primitives are: numbers and booleans */ - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case 't': - case 'f': - case 'n': - /* And they must not be keys of the object */ - if (tokens != NULL && parser->toksuper != -1) { - const jsmntok_t *t = &tokens[parser->toksuper]; - if (t->type == JSMN_OBJECT || - (t->type == JSMN_STRING && t->size != 0)) { - return JSMN_ERROR_INVAL; - } - } -#else - /* In non-strict mode every unquoted value is a primitive */ - default: -#endif - r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens); - if (r < 0) { - return r; - } - count++; - if (parser->toksuper != -1 && tokens != NULL) { - tokens[parser->toksuper].size++; - } - break; - -#ifdef JSMN_STRICT - /* Unexpected char in strict mode */ - default: - return JSMN_ERROR_INVAL; -#endif - } - } - - if (tokens != NULL) { - for (i = parser->toknext - 1; i >= 0; i--) { - /* Unmatched opened object or array */ - if (tokens[i].start != -1 && tokens[i].end == -1) { - return JSMN_ERROR_PART; - } - } - } - - return count; -} - -/** - * Creates a new parser based over a given buffer with an array of tokens - * available. - */ -JSMN_API void jsmn_init(jsmn_parser *parser) { - parser->pos = 0; - parser->toknext = 0; - parser->toksuper = -1; -} - -#endif /* JSMN_HEADER */ - -#ifdef __cplusplus -} -#endif - -#endif /* JSMN_H */ \ No newline at end of file diff --git a/components/jsmn/jsmn.c b/components/jsmn/jsmn.c deleted file mode 100644 index ca159c3..0000000 --- a/components/jsmn/jsmn.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include "jsmn.h" - -void func(void) -{ - -} diff --git a/components/meteofrance/CMakeLists.txt b/components/meteofrance/CMakeLists.txt index b32baf4..36f4789 100644 --- a/components/meteofrance/CMakeLists.txt +++ b/components/meteofrance/CMakeLists.txt @@ -1,3 +1,3 @@ idf_component_register(SRCS "meteofrance.c" INCLUDE_DIRS "include" - REQUIRES http jsmn json esp_http_client esp-tls) + REQUIRES json esp_http_client esp-tls) diff --git a/components/meteofrance/include/meteofrance.h b/components/meteofrance/include/meteofrance.h index f11011b..a926b8c 100644 --- a/components/meteofrance/include/meteofrance.h +++ b/components/meteofrance/include/meteofrance.h @@ -24,6 +24,7 @@ struct meteoforecast_data{ }; typedef void (*weather_data_callback)(struct meteoforecast_data *datas); +typedef void (*weather_data_start_callback)(); typedef struct { unsigned int humidity; @@ -31,11 +32,13 @@ typedef struct { float pressure; unsigned long retreival_period; weather_data_callback data_retreived_cb; + weather_data_start_callback data_retreived_cb_start; } weather_data; void printftemp(struct forecast_temp *tmp); void printffd(struct meteoforecast_data *tmp); void on_weather_data_retrieval(weather_data_callback data_retreived_cb); +void on_weather_data_retrieval_start(weather_data_callback data_retreived_cb); void initialise_weather_data_retrieval(unsigned long retreival_period); diff --git a/components/meteofrance/meteofrance.c b/components/meteofrance/meteofrance.c index dfab41a..a99f331 100644 --- a/components/meteofrance/meteofrance.c +++ b/components/meteofrance/meteofrance.c @@ -18,7 +18,6 @@ #include #include "meteofrance.h" -#include "jsmn.h" #include "cJSON.h" #include "esp_http_client.h" #include "esp_tls.h" @@ -205,7 +204,9 @@ static bool process_response_body(const char * body) static void http_request_task(void *pvParameter) { - while(1) { + while(1) { + ESP_LOGE(TAG,"Début recup méteo --------------------------"); + weather.data_retreived_cb_start(NULL); char *local_response_buffer = heap_caps_malloc((MAX_HTTP_OUTPUT_BUFFER + 1)*(sizeof(char)),MALLOC_CAP_SPIRAM); //char local_response_buffer[MAX_HTTP_OUTPUT_BUFFER + 1] = {0}; /** @@ -238,7 +239,7 @@ static void http_request_task(void *pvParameter) } else { ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err)); } - ESP_LOGE(TAG, "%s",local_response_buffer); + //ESP_LOGE(TAG, "%s",local_response_buffer); bool weather_data_phrased = false; weather_data_phrased = process_response_body(local_response_buffer); @@ -255,13 +256,17 @@ void on_weather_data_retrieval(weather_data_callback data_retreived_cb) weather.data_retreived_cb = data_retreived_cb; } +void on_weather_data_retrieval_start(weather_data_callback data_retreived_cb_start) +{ + weather.data_retreived_cb_start = data_retreived_cb_start; +} + void initialise_weather_data_retrieval(unsigned long retreival_period) { weather.retreival_period = retreival_period; //http_client_on_process_chunk(&http_client, process_chunk); //http_client_on_disconnected(&http_client, disconnected); - xTaskCreate(&http_request_task, "http_request_task", 10 * 2048, NULL, 5, NULL); ESP_LOGI(TAG, "HTTP request task started"); } diff --git a/components/weather/CMakeLists.txt b/components/weather/CMakeLists.txt deleted file mode 100644 index b119fce..0000000 --- a/components/weather/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -idf_component_register(SRCS "weather.c" - INCLUDE_DIRS "include" - REQUIRES http jsmn) diff --git a/components/weather/Kconfig.projbuild b/components/weather/Kconfig.projbuild deleted file mode 100644 index 9dcd636..0000000 --- a/components/weather/Kconfig.projbuild +++ /dev/null @@ -1,11 +0,0 @@ -menu "Wather data retreival from OpenWeatherMap" - -config OPENWEATHERMAP_API_KEY - string "OpenWeatherMap API key" - default "12345678901234567890123456789012" - help - API key obtained from 'https://home.openweathermap.org/' site. - - You need to set up a free account on this site first. - -endmenu diff --git a/components/weather/component.mk b/components/weather/component.mk deleted file mode 100644 index 2581b04..0000000 --- a/components/weather/component.mk +++ /dev/null @@ -1,2 +0,0 @@ -COMPONENT_ADD_INCLUDEDIRS := . - diff --git a/components/weather/include/weather.h b/components/weather/include/weather.h deleted file mode 100644 index a39d17d..0000000 --- a/components/weather/include/weather.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - weather.h - Weather data retrieval from api.openweathermap.org - - This file is part of the ESP32 Everest Run project - https://github.com/krzychb/esp32-everest-run - - Copyright (c) 2016 Krzysztof Budzynski - This work is licensed under the Apache License, Version 2.0, January 2004 - See the file LICENSE for details. -*/ -#ifndef WEATHER_H -#define WEATHER_H - -#include "esp_err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*weather_data_callback)(uint32_t *args); - -typedef struct { - unsigned int humidity; - float temperature; - float pressure; - unsigned long retreival_period; - weather_data_callback data_retreived_cb; -} weather_data; - -#define ESP_ERR_WEATHER_BASE 0x50000 -#define ESP_ERR_WEATHER_RETREIVAL_FAILED (ESP_ERR_WEATHER_BASE + 1) - -void on_weather_data_retrieval(weather_data_callback data_retreived_cb); -void initialise_weather_data_retrieval(unsigned long retreival_period); - -#ifdef __cplusplus -} -#endif - -#endif // WEATHER_H diff --git a/components/weather/weather.c b/components/weather/weather.c deleted file mode 100644 index a7f85c6..0000000 --- a/components/weather/weather.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - weather.c - Weather data retrieval from api.openweathermap.org - - This file is part of the ESP32 Everest Run project - https://github.com/krzychb/esp32-everest-run - - Copyright (c) 2016 Krzysztof Budzynski - This work is licensed under the Apache License, Version 2.0, January 2004 - See the file LICENSE for details. -*/ - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "esp_system.h" -#include "esp_log.h" - -#include -#include - -#include "weather.h" -#include "http.h" -#include "jsmn.h" - -static const char* TAG = "Weather"; - -/* Constants that aren't configurable in menuconfig - Typically only LOCATION_ID may need to be changed - */ -#define WEB_SERVER "api.openweathermap.org" -#define WEB_URL "http://api.openweathermap.org/data/2.5/weather" -// Location ID to get the weather data for -//#define LOCATION_ID "756135" -#define LATITUDE "49.22017054145735" -#define LONGITUDE "3.92188756221628" - -// The API key below is configurable in menuconfig -#define OPENWEATHERMAP_API_KEY "24d95e3a2c27a1843590b91bf2cbf37b__" - -static const char *get_request = "GET " WEB_URL"?lat="LATITUDE"&lon="LONGITUDE"&appid="OPENWEATHERMAP_API_KEY" HTTP/1.1\n" - "Host: "WEB_SERVER"\n" - "Connection: close\n" - "User-Agent: esp-idf/1.0 esp32\n" - "\n"; - -static weather_data weather; -static http_client_data http_client = {0}; - -/* Collect chunks of data received from server - into complete message and save it in proc_buf - */ -static void process_chunk(uint32_t *args) -{ - http_client_data* client = (http_client_data*)args; - - int proc_buf_new_size = client->proc_buf_size + client->recv_buf_size; - char *copy_from; - - if (client->proc_buf == NULL){ - client->proc_buf = malloc(proc_buf_new_size); - copy_from = client->proc_buf; - } else { - proc_buf_new_size -= 1; // chunks of data are '\0' terminated - client->proc_buf = realloc(client->proc_buf, proc_buf_new_size); - copy_from = client->proc_buf + proc_buf_new_size - client->recv_buf_size; - } - if (client->proc_buf == NULL) { - ESP_LOGE(TAG, "Failed to allocate memory"); - } - client->proc_buf_size = proc_buf_new_size; - memcpy(copy_from, client->recv_buf, client->recv_buf_size); -} - -static int jsoneq(const char *json, jsmntok_t *tok, const char *s) { - if (tok->type == JSMN_STRING && (int) strlen(s) == tok->end - tok->start && - strncmp(json + tok->start, s, tok->end - tok->start) == 0) { - return 0; - } - return -1; -} - -static bool process_response_body(const char * body) -{ - /* Using great little JSON parser http://zserge.com/jsmn.html - find specific weather information: - - Humidity, - - Temperature, - - Pressure - in HTTP response body that happens to be a JSON string - - Return true if phrasing was successful or false if otherwise - */ - - #define JSON_MAX_TOKENS 100 - jsmn_parser parser; - jsmntok_t t[JSON_MAX_TOKENS]; - jsmn_init(&parser); - ESP_LOGE(TAG,"%s",body); - int r = jsmn_parse(&parser, body, strlen(body), t, JSON_MAX_TOKENS); - if (r < 0) { - ESP_LOGE(TAG, "JSON parse error %d", r); - return false; - } - if (r < 1 || t[0].type != JSMN_OBJECT) { - ESP_LOGE(TAG, "JSMN_OBJECT expected"); - return false; - } else { - ESP_LOGI(TAG, "Token(s) found %d", r); - char subbuff[8]; - int str_length; - for (int i = 1; i < r; i++) { - if (jsoneq(body, &t[i], "humidity") == 0) { - str_length = t[i+1].end - t[i+1].start; - memcpy(subbuff, body + t[i+1].start, str_length); - subbuff[str_length] = '\0'; - weather.humidity = atoi(subbuff); - i++; - } else if (jsoneq(body, &t[i], "temp") == 0) { - str_length = t[i+1].end - t[i+1].start; - memcpy(subbuff, body + t[i+1].start, str_length); - subbuff[str_length] = '\0'; - weather.temperature = atof(subbuff); - i++; - } else if (jsoneq(body, &t[i], "pressure") == 0) { - str_length = t[i+1].end - t[i+1].start; - memcpy(subbuff, body + t[i+1].start, str_length); - subbuff[str_length] = '\0'; - weather.pressure = atof(subbuff); - i++; - } - } - return true; - } -} - - -static void disconnected(uint32_t *args) -{ - http_client_data* client = (http_client_data*)args; - bool weather_data_phrased = false; - - const char * response_body = find_response_body(client->proc_buf); - if (response_body) { - weather_data_phrased = process_response_body(response_body); - } else { - ESP_LOGE(TAG, "No HTTP header found"); - } - - free(client->proc_buf); - client->proc_buf = NULL; - client->proc_buf_size = 0; - - // execute callback if data was retrieved - if (weather_data_phrased) { - if (weather.data_retreived_cb) { - weather.data_retreived_cb((uint32_t*) &weather); - } - } - ESP_LOGD(TAG, "Free heap %u", xPortGetFreeHeapSize()); -} - -static void http_request_task(void *pvParameter) -{ - while(1) { - http_client_request(&http_client, WEB_SERVER, get_request); - vTaskDelay(weather.retreival_period / portTICK_PERIOD_MS); - } -} - -void on_weather_data_retrieval(weather_data_callback data_retreived_cb) -{ - weather.data_retreived_cb = data_retreived_cb; -} - -void initialise_weather_data_retrieval(unsigned long retreival_period) -{ - weather.retreival_period = retreival_period; - - http_client_on_process_chunk(&http_client, process_chunk); - http_client_on_disconnected(&http_client, disconnected); - - xTaskCreate(&http_request_task, "http_request_task", 2 * 2048, NULL, 5, NULL); - ESP_LOGI(TAG, "HTTP request task started"); -} diff --git a/main/main.c b/main/main.c index 1f96066..a9705ec 100644 --- a/main/main.c +++ b/main/main.c @@ -270,8 +270,37 @@ static void _app_button_cb(lv_event_t *e) } } +lv_subject_t wifiStatus; +lv_subject_t mqttStatus; +lv_subject_t meteoStatus; + + static void app_main_display(void) { + + lv_subject_init_int(&wifiStatus,-1); + lv_subject_init_int(&mqttStatus,-1); + lv_subject_init_int(&meteoStatus,-1); + + lv_obj_t *cont_status = lv_obj_create(lv_layer_top()); + lv_obj_align(cont_status,LV_ALIGN_TOP_RIGHT,0,0); + lv_obj_set_flex_flow(cont_status, LV_FLEX_FLOW_ROW); + lv_obj_set_height(cont_status,LV_SIZE_CONTENT); + lv_obj_set_width(cont_status,LV_SIZE_CONTENT); + + lv_obj_t *meteoR = lv_label_create(cont_status); + lv_label_set_text(meteoR,"Refresh"); + lv_label_bind_text(meteoR, &meteoStatus, "Meteo %d"); + + lv_obj_t *wifi = lv_label_create(cont_status); + lv_label_set_text(wifi,"Wifi Ok"); + lv_label_bind_text(wifi, &wifiStatus, "Wifi %d"); + + + lv_obj_t *mqtt = lv_label_create(cont_status); + lv_label_set_text(mqtt,"Mqtt Ok"); + lv_label_bind_text(mqtt, &mqttStatus, "Mqtt %d"); + lv_obj_t *scr = lv_scr_act(); /* Your LVGL objects code here .... */ @@ -453,7 +482,7 @@ static lv_obj_t *weatherDay_fragment_create_obj(lv_fragment_t *self, lv_obj_t *p lv_image_set_offset_y(img1, -8); lv_image_set_offset_x(img1, -8); lv_obj_set_size(img1,40,40); - lv_image_set_src(img1, &p1j); + lv_image_set_src(img1,LV_SYMBOL_DUMMY); //lv_obj_set_style_border_width(img1,2,0); //lv_obj_set_style_border_color(img1, lv_palette_main(LV_PALETTE_BLUE_GREY), 0); lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0); @@ -511,6 +540,9 @@ void draw_ihm() // keys.clear(); lv_obj_clean(lv_scr_act()); + + + /*Create a Tab view object*/ lv_obj_t * tabview; tabview = lv_tabview_create(lv_screen_active()); @@ -563,17 +595,21 @@ void draw_ihm() lv_style_set_align(&style_container, LV_ALIGN_BOTTOM_LEFT); lv_style_set_flex_cross_place(&style_container, LV_FLEX_ALIGN_END); + static lv_style_t no_padding; + lv_style_init(&no_padding); + lv_style_set_pad_all(&no_padding, 0); + static lv_style_t style_lbvValue; lv_style_init(&style_lbvValue); lv_obj_t *main = tab1; - + lv_obj_add_style(main,&no_padding,0); lv_style_set_text_font(&style_lbvValue, &lv_font_montserrat_40); - lv_obj_set_flex_flow(tab1, LV_FLEX_FLOW_ROW); - lv_obj_set_style_pad_column(tab1, 1, 0); + lv_obj_set_flex_flow(main, LV_FLEX_FLOW_ROW); + lv_obj_set_style_pad_column(main, 1, 0); /*Create a container with COLUMN flex direction*/ - lv_obj_t *cont_col = lv_obj_create(tab1); + lv_obj_t *cont_col = lv_obj_create(main); lv_obj_set_style_pad_all(cont_col, 5, 0); lv_obj_set_size(cont_col, 250, 480); lv_obj_align(cont_col, LV_ALIGN_TOP_LEFT, 0, 0); @@ -581,7 +617,7 @@ void draw_ihm() lv_obj_set_flex_align(cont_col,LV_FLEX_ALIGN_CENTER,LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); /*Create a container with COLUMN flex direction*/ - lv_obj_t *cont_col2 = lv_obj_create(tab1); + lv_obj_t *cont_col2 = lv_obj_create(main); lv_obj_set_style_pad_all(cont_col2, 5, 0); lv_obj_set_flex_align(cont_col2, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); @@ -760,6 +796,10 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base, } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { + if(lvgl_port_lock(0)){ + lv_subject_set_int(&wifiStatus,0); + lvgl_port_unlock(); + } if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) { esp_wifi_connect(); @@ -774,6 +814,10 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base, } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { + if(lvgl_port_lock(0)){ + lv_subject_set_int(&wifiStatus,1); + lvgl_port_unlock(); + } ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); s_retry_num = 0; @@ -839,15 +883,28 @@ void wifi_init_sta(void) { ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); + if(lvgl_port_lock(0)){ + lv_subject_set_int(&wifiStatus,1); + lvgl_port_unlock(); + } } else if (bits & WIFI_FAIL_BIT) { ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); + if(lvgl_port_lock(0)){ + lv_subject_set_int(&wifiStatus,0); + lvgl_port_unlock(); + } } else { ESP_LOGE(TAG, "UNEXPECTED EVENT"); + if(lvgl_port_lock(0)){ + lv_subject_set_int(&wifiStatus,0); + lvgl_port_unlock(); + } + } } @@ -901,6 +958,10 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_ switch ((esp_mqtt_event_id_t)event_id) { case MQTT_EVENT_CONNECTED: + if(lvgl_port_lock(0)){ + lv_subject_set_int(&mqttStatus,1); + lvgl_port_unlock(); + } ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED"); msg_id = esp_mqtt_client_publish(client, "/topic/qos1", "data_3", 0, 1, 0); ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id); @@ -924,6 +985,10 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_ ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id); break; case MQTT_EVENT_DISCONNECTED: + if(lvgl_port_lock(0)){ + lv_subject_set_int(&mqttStatus,0); + lvgl_port_unlock(); + } ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED"); break; @@ -1043,6 +1108,15 @@ static void mqtt_app_start(void) esp_mqtt_client_start(client); } +void weather_data_retreived_start() +{ + ESP_LOGE(TAG,"Début recup méteo"); + if(lvgl_port_lock(0)){ + lv_subject_set_int(&meteoStatus,1); + lvgl_port_unlock(); + } +} + void weather_data_retreived(struct meteoforecast_data datas[3]) { // struct meteoforecast_data* weather = (meteoforecast_data*) args; @@ -1065,6 +1139,7 @@ void weather_data_retreived(struct meteoforecast_data datas[3]) lv_subject_set_pointer(&tempD1Subj, &datas[0]); lv_subject_set_pointer(&tempD2Subj, &datas[1]); lv_subject_set_pointer(&tempD3Subj, &datas[2]); + lv_subject_set_int(&meteoStatus,0); lvgl_port_unlock(); ESP_LOGE(TAG, "------------------------------------- Fin Set des subjects --------------------------------"); } @@ -1099,8 +1174,9 @@ void app_main(void) wifi_init_sta(); mqtt_app_start(); - initialise_weather_data_retrieval(60000); on_weather_data_retrieval(weather_data_retreived); + on_weather_data_retrieval_start(weather_data_retreived_start); + initialise_weather_data_retrieval(60000); ESP_LOGW(TAG, "Weather data retrieval initialized"); /* Show LVGL objects */