Skip to content

Commit

Permalink
#8 WiFi + Http request (GET) already retrieving the time
Browse files Browse the repository at this point in the history
  • Loading branch information
martinberlin committed Jun 30, 2020
1 parent a6e933e commit d537637
Show file tree
Hide file tree
Showing 2 changed files with 238 additions and 14 deletions.
1 change: 0 additions & 1 deletion main/cale.cpp
Expand Up @@ -10,7 +10,6 @@
#include "lwip/err.h"
#include "lwip/sys.h"
// - - - - HTTP Client
#include "nvs_flash.h"
#include "esp_netif.h"
#include "esp_err.h"
#include "esp_tls.h"
Expand Down
251 changes: 238 additions & 13 deletions main/demo-sleep-clock.cpp
@@ -1,3 +1,10 @@
/*
* - - - - - - - - Deepsleep clock example - - - - - - - - - - - - - - - - - - - -
* Please note that the intention of this clock is not to be precise.
* Just a simple: Sleep every N minutes, increment EPROM variable, refresh epaper.
* And once a day or every hour, a single HTTP request to sync the hour online.
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
Expand All @@ -11,21 +18,39 @@
#include <gdew027w3.h>
#include <Fonts/ubuntu/Ubuntu_M20pt8b.h>

/*
* - - - - - - - - Deepsleep clock example - - - - - - - - - - - - - - - - - - - -
* Please note that the intention of this clock is not to be precise.
* Just a simple: Sleep every N minutes, increment EPROM variable, refresh epaper.
* And once a day or every hour, a single HTTP request to sync the hour online.
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
EpdSpi io;
Gdew027w3 display(io);
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "lwip/err.h"
#include "lwip/sys.h"
// - - - - HTTP Client
#include "esp_netif.h"
#include "esp_err.h"
#include "esp_tls.h"
#include "esp_http_client.h"
#include "esp_sleep.h"

// HTTP Request constants
// Time query: HHmm -> 0800 (8 AM)
const char* timequery = "http://fs.fasani.de/api/?q=date&timezone=Europe/Berlin&f=Hi";
const char* timeQuery = "http://fs.fasani.de/api/?q=date&timezone=Europe/Berlin&f=Hi";
// Day N, month
const char* dayQuery = "http://fs.fasani.de/api/?q=date&timezone=Europe/Berlin&f=l+d,%20F";

// Clock will refresh each N minutes
int sleepMinutes = 3;
int sleepMinutes = 5;

// As default is 512 without setting buffer_size property in esp_http_client_config_t
#define HTTP_RECEIVE_BUFFER_SIZE 128
uint64_t startTime = 0;
uint16_t countDataEventCalls = 0;
static const char *TAG = "CALE CLOCK";
char espIpAddress[16];

EpdSpi io;
Gdew027w3 display(io);

// Values that will be stored in NVS - defaults should come initially from timequery (external HTTP request)
int8_t nvs_hour = 10;
Expand All @@ -40,7 +65,10 @@ void deepsleep(){
esp_deep_sleep(1000000LL * 60 * sleepMinutes);
}

// Not working as it should. deprecate or check later
/**
* Not working as it should. deprecate or check later
* deprecated
*/
void clockLeadingZeros(int8_t number, char outBuffer[3]){
char incomingInt[3];
itoa(number, incomingInt, 10);
Expand Down Expand Up @@ -95,11 +123,201 @@ void updateClock() {
display.update();
}

esp_err_t _http_event_handler(esp_http_client_event_t *evt)
{
char output_buffer[HTTP_RECEIVE_BUFFER_SIZE]; // Buffer to store HTTP response

switch (evt->event_id)
{
case HTTP_EVENT_ERROR:
ESP_LOGE(TAG, "HTTP_EVENT_ERROR");
break;
case HTTP_EVENT_ON_CONNECTED:
ESP_LOGI(TAG, "HTTP_EVENT_ON_CONNECTED");
break;
case HTTP_EVENT_HEADER_SENT:
ESP_LOGI(TAG, "HTTP_EVENT_HEADER_SENT");
break;
case HTTP_EVENT_ON_HEADER:
ESP_LOGI(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
break;

case HTTP_EVENT_ON_DATA:
++countDataEventCalls;
if (countDataEventCalls == 1)
{
startTime = esp_timer_get_time();
}
// Copy the response into the buffer
ESP_LOGI(TAG, "DATA CALLS: %d length:%d\n", countDataEventCalls, evt->data_len);
memcpy(output_buffer, evt->data, evt->data_len);
for (uint8_t c=0; c<evt->data_len; c++){
printf("%c", output_buffer[c]);
}
printf("\nEND OF DATA - - - -\n");

break;

case HTTP_EVENT_ON_FINISH:
ESP_LOGI(TAG, "HTTP_EVENT_ON_FINISH\nDownload took: %llu ms"
, (esp_timer_get_time()-startTime)/1000);
break;

case HTTP_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED\n");
break;
}
return ESP_OK;
}

/**
* GET simple example, could be done also with POST
*/
static void http_get(const char * requestUrl)
{
/**
* NOTE: All the configuration parameters for http_client must be spefied either in URL or as host and path parameters.
* If host and path parameters are not set, query parameter will be ignored. In such cases,
* query parameter should be specified in URL.
*/

esp_http_client_config_t config = {
.url = requestUrl,
.method = HTTP_METHOD_GET,
.event_handler = _http_event_handler,
.buffer_size = HTTP_RECEIVE_BUFFER_SIZE
};
esp_http_client_handle_t client = esp_http_client_init(&config);

esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK)
{
ESP_LOGI(TAG, "\nREQUEST URL: %s\n\nHTTP GET Status = %d, content_length = %d\n",
requestUrl,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
}
else
{
ESP_LOGE(TAG, "\nHTTP GET request failed: %s", esp_err_to_name(err));
}
//ESP_LOG_BUFFER_HEX(TAG, local_response_buffer, strlen(local_response_buffer));
}

/* FreeRTOS event group to signal when we are connected*/
static EventGroupHandle_t s_wifi_event_group;

/* The event group allows multiple bits for each event, but we only care about two events:
* - we are connected to the AP with an IP
* - we failed to connect after the maximum amount of retries */
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
static int s_retry_num = 0;

static void event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
{
esp_wifi_connect();
}
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
{
if (s_retry_num < CONFIG_ESP_MAXIMUM_RETRY)
{
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "Retry to connect to the AP");
}
else
{
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
ESP_LOGI(TAG, "Connect to the AP failed %d times. Going to deepsleep %d minutes", CONFIG_ESP_MAXIMUM_RETRY, CONFIG_DEEPSLEEP_MINUTES_AFTER_RENDER);
deepsleep();
}
}
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
{
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
sprintf(espIpAddress, IPSTR, IP2STR(&event->ip_info.ip));
ESP_LOGI(TAG, "got ip: %s\n", espIpAddress);
s_retry_num = 0;
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
}

void wifi_init_sta(void)
{
s_wifi_event_group = xEventGroupCreate();

ESP_ERROR_CHECK(esp_netif_init());

ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta();

wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));

esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&event_handler,
NULL,
&instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
IP_EVENT_STA_GOT_IP,
&event_handler,
NULL,
&instance_got_ip));

wifi_config_t wifi_config;
memset(&wifi_config, 0, sizeof(wifi_config));
sprintf(reinterpret_cast<char *>(wifi_config.sta.ssid), CONFIG_ESP_WIFI_SSID);
sprintf(reinterpret_cast<char *>(wifi_config.sta.password), CONFIG_ESP_WIFI_PASSWORD);
wifi_config.sta.pmf_cfg.capable = true;
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());

ESP_LOGI(TAG, "wifi_init_sta finished.");

/* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
* number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
pdFALSE,
pdFALSE,
portMAX_DELAY);

/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually happened. */
if (bits & WIFI_CONNECTED_BIT)
{
ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
CONFIG_ESP_WIFI_SSID, CONFIG_ESP_WIFI_PASSWORD);
}
else if (bits & WIFI_FAIL_BIT)
{
ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
CONFIG_ESP_WIFI_SSID, CONFIG_ESP_WIFI_PASSWORD);
}
else
{
ESP_LOGE(TAG, "UNEXPECTED EVENT");
}

/* The event will not be processed after unregister */
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip));
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id));
vEventGroupDelete(s_wifi_event_group);
}


void app_main(void)
{
printf("Demo sleeping clock\n");

// Initialize NVS
// Initialize NVS
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
// NVS partition was truncated and needs to be erased
Expand All @@ -109,6 +327,13 @@ void app_main(void)
}
ESP_ERROR_CHECK( err );

// Just a test, we need to start internet only to sync Time
ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
wifi_init_sta();

http_get(timeQuery);


// Open
printf("\n");
printf("Opening Non-Volatile Storage (NVS) handle... ");
Expand Down

0 comments on commit d537637

Please sign in to comment.