#include "wifi.h"
#include "http.h"
#include <cJSON.h>
#include "liquid_crystal.h"
#include "mqtt_client.h"
#include "esp_log.h"
#define CONFIG_LOG_DEFAULT_LEVEL_VERBOSE 1
#define CONFIG_LOG_DEFAULT_LEVEL 5
#define CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE 1
#define CONFIG_LOG_MAXIMUM_LEVEL 5
#define CONFIG_LOG_COLORS 1
#define CONFIG_LOG_TIMESTAMP_SOURCE_RTOS 1
static char http_buffer [512];
const char* title_1 = "ESP-IDF WiFi";
const char* title_2 = "Weather API";
const uint8_t rs = 5, en = 18, d4 = 19, d5 = 21, d6 = 22, d7 = 23;
static const char *TAG3 = "mqtt_example";
static void http_error()
{
lcd_clear();
lcd_set_cursor(0, 0);
const char* error = " HTTP ERROR";
for (int i = 0; i < 14; ++i)
{
lcd_write(error[i]);
}
}
static int get_temp(char* weather)
{
int tempC = 999;
const cJSON *temperature = NULL;
const cJSON *current_weather = NULL;
cJSON *weather_json = cJSON_Parse(weather);
if (weather_json == NULL)
{
const char *error_ptr = cJSON_GetErrorPtr();
if (error_ptr != NULL)
{
ESP_LOGE("main", "Error before: %s\n", error_ptr);
cJSON_Delete(weather_json);
http_error();
return 0;
}
}
current_weather = cJSON_GetObjectItemCaseSensitive(weather_json, "current_weather");
temperature = cJSON_GetObjectItemCaseSensitive(current_weather, "temperature");
if (!cJSON_IsNumber(temperature))
{
ESP_LOGE("main", "Temperature NaN");
cJSON_Delete(weather_json);
http_error();
return 0;
}
else
{
ESP_LOGI("main", "Successfully parsed JSON response.");
tempC = temperature->valuedouble;
}
cJSON_Delete(weather_json);
return tempC;
}
static void mqtt_event_handler(esp_mqtt_event_handle_t event){ //here esp_mqtt_event_handle_t is a struct which receieves struct event from mqtt app start funtion
esp_mqtt_client_handle_t client = event->client; //making obj client of struct esp_mqtt_client_handle_t and assigning it the receieved event client
if(event->event_id == MQTT_EVENT_CONNECTED){
ESP_LOGI(TAG3, "MQTT_EVENT_CONNECTED");
esp_mqtt_client_subscribe(client,"/topic/qos0",0); //in mqtt we require a topic to subscribe and client is from event client and 0 is quality of service it can be 1 or 2
ESP_LOGI(TAG3, "sent subscribe successful" );
}
else if(event->event_id == MQTT_EVENT_DISCONNECTED)
{
ESP_LOGI(TAG3, "MQTT_EVENT_DISCONNECTED"); //if disconnected
}
else if(event->event_id == MQTT_EVENT_SUBSCRIBED)
{
ESP_LOGI(TAG3, "MQTT_EVENT_SUBSCRIBED");
}
else if(event->event_id == MQTT_EVENT_UNSUBSCRIBED) //when subscribed
{
ESP_LOGI(TAG3, "MQTT_EVENT_UNSUBSCRIBED");
}
else if(event->event_id == MQTT_EVENT_DATA)//when unsubscribed
{
// https://github.com/espressif/esp-idf/blob/v5.2.1/examples/protocols/mqtt/tcp/main/app_main.c
// mosquitto_pub -h mqtt.eclipseprojects.io -m "daje" -t "/topic/qos0"
ESP_LOGI(TAG3, "MQTT_EVENT_DATA");
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
printf("DATA=%.*s\r\n", event->data_len, event->data);
}
else if(event->event_id == MQTT_EVENT_ERROR)//when any error
{
ESP_LOGI(TAG3, "MQTT_EVENT_ERROR");
}
}
static void mqtt_app_start(void)
{
const esp_mqtt_client_config_t mqtt_cfg={
.uri="mqtt://mqtt.eclipseprojects.io", //Uniform Resource Identifier includes path,protocol
.event_handle=mqtt_event_handler, //described above event handler
// https://medium.com/@fatehsali517/how-to-code-mqtt-on-esp-idf-from-scratch-fe6bc238330
// .username=/*your username*/, //your username
// .password=/*your adafruit password*/, //your adafruit io password
};
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
/* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
// esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
esp_mqtt_client_start(client);
}
static void main_loop(void *pvParameters)
{
while(1)
{
http_params params = {
METEO_SERVER,
METEO_PORT,
METEO_REQUEST,
http_buffer,
512
};
if (http_request(params) == 0)
{
http_error();
}
else
{
int outdoorTempC = get_temp(http_buffer);
int outdoorTempF = (outdoorTempC * 1.8) + 32.0;
ESP_LOGI("main", "outdoor temp celsius: %i", outdoorTempC);
ESP_LOGI("main", "outdoor temp fahrenheit: %i", outdoorTempF);
char tempbuf [16];
snprintf (tempbuf, 16, "Temp: %i F", outdoorTempF);
lcd_clear();
lcd_set_cursor(0, 0);
for (int i = 0; i < 16; ++i)
{
lcd_write(tempbuf[i]);
}
char locbuf [16];
snprintf (locbuf, 16, "Berlin, Germany");
lcd_set_cursor(0, 1);
for (int i = 0; i < 16; ++i)
{
lcd_write(locbuf[i]);
}
}
for(int countdown = 300; countdown >= 0; countdown--)
{
ESP_LOGI("main", "%d... ", countdown);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
}
void app_main()
{
esp_log_level_set(TAG3, ESP_LOG_VERBOSE);
/*
ESP_LOGW(TAG3, "AppMain -> Início.");
ESP_LOGI(TAG3, "AppMain -> Início.");
ESP_LOGE(TAG3, "AppMain -> Início.");
ESP_LOGD(TAG3, "AppMain -> Início.");
ESP_LOGV(TAG3, "AppMain -> Início.");
*/
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
wifi_init_sta();
liquid_crystal(rs, en, d4, d5, d6, d7);
lcd_begin(16, 2);
lcd_set_cursor(2, 0);
for (int i = 0; i < 12; i++)
{
lcd_write(title_1[i]);
}
lcd_set_cursor(2, 1);
for (int i = 0; i < 12; i++)
{
lcd_write(title_2[i]);
}
mqtt_app_start();
vTaskDelay(2000 / portTICK_PERIOD_MS);
xTaskCreate(&main_loop, "main_loop", 4096, NULL, 5, NULL);
}