domotic/main/main.c

422 lines
13 KiB
C

#include "meteofrance.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_check.h"
#include "driver/i2c.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include <locale.h>
#include "esp_vfs_fat.h"
#include "sdmmc_cmd.h"
#include <stdio.h>
#include "bsp/esp-bsp.h"
#include "main.h"
#include "ihm.h"
// OTA
#include "esp_ota_ops.h"
#include "esp_http_client.h"
#include "esp_https_ota.h"
// Includes personnels
#include "wifi_logger.h"
#include "obtain_time.h"
#include "image_downloader.h"
#include "communication.h"
#include "stateManagement.h"
#include "am2302_rmt.h"
// GPIO assignment
#define AM2302_GPIO 4
#include "esp_littlefs.h"
#define MOUNT_POINT "/sdcard"
// Pin assignments can be set in menuconfig, see "SD SPI Example Configuration" menu.
// You can also change the pin assignments here by changing the following 4 lines.
#define PIN_NUM_MISO 13
#define PIN_NUM_MOSI 11
#define PIN_NUM_CLK 12
#define PIN_NUM_CS 10
static const char *TAG = "domoTic";
extern esp_mqtt_client_handle_t client;
struct state mainState={
.wifi_init=false,
.display_init=false
};
void mount_sd_card()
{
// Options for mounting the filesystem.
// If format_if_mount_failed is set to true, SD card will be partitioned and
// formatted in case when mounting fails.
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
.format_if_mount_failed = false,
.max_files = 5,
.allocation_unit_size = 16 * 1024};
sdmmc_card_t *card;
const char mount_point[] = MOUNT_POINT;
ESP_LOGI(TAG, "Initializing SD card");
ESP_LOGI(TAG, "Using SPI peripheral");
sdmmc_host_t host = SDSPI_HOST_DEFAULT();
spi_bus_config_t bus_cfg = {
.mosi_io_num = PIN_NUM_MOSI,
.miso_io_num = PIN_NUM_MISO,
.sclk_io_num = PIN_NUM_CLK,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 4000,
};
esp_err_t ret = spi_bus_initialize(host.slot, &bus_cfg, SDSPI_DEFAULT_DMA);
if (ret != ESP_OK)
{
ESP_LOGE(TAG, "Failed to initialize bus.");
return;
}
sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
slot_config.gpio_cs = PIN_NUM_CS;
slot_config.host_id = host.slot;
ESP_LOGI(TAG, "Mounting filesystem");
ret = esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config, &card);
if (ret != ESP_OK)
{
if (ret == ESP_FAIL)
{
ESP_LOGE(TAG, "Failed to mount filesystem. "
"If you want the card to be formatted, set the CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.");
}
else
{
ESP_LOGE(TAG, "Failed to initialize the card (%s). "
"Make sure SD card lines have pull-up resistors in place.",
esp_err_to_name(ret));
}
return;
}
ESP_LOGI(TAG, "Filesystem mounted");
// Card has been initialized, print its properties
sdmmc_card_print_info(stdout, card);
}
extern char *days[7];
extern char *months[12];
static void updateTime(void *pvParameter)
{
char strftime_buf[64];
time_t now = 0;
while (1)
{
time(&now);
struct tm timeinfo = {0};
localtime_r(&now, &timeinfo);
sprintf(strftime_buf, "%s %d %s %02d:%02d", days[timeinfo.tm_wday], timeinfo.tm_mday, months[timeinfo.tm_mon], timeinfo.tm_hour, timeinfo.tm_min);
draw_time(strftime_buf);
/*
lv_obj_refr_size(lv_obj_get_child(lv_obj_get_child(lv_layer_top(),0),0));
lv_obj_refr_size(lv_obj_get_child(lv_layer_top(),0));
lvgl_port_unlock();
}*/
vTaskDelay(60000 / portTICK_PERIOD_MS);
}
}
esp_err_t _ota_http_event_handler(esp_http_client_event_t *evt)
{
switch (evt->event_id) {
case HTTP_EVENT_ERROR:
ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
break;
case HTTP_EVENT_ON_CONNECTED:
ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
break;
case HTTP_EVENT_HEADER_SENT:
ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
break;
case HTTP_EVENT_ON_HEADER:
ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
break;
case HTTP_EVENT_ON_DATA:
ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
break;
case HTTP_EVENT_ON_FINISH:
ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
break;
case HTTP_EVENT_DISCONNECTED:
ESP_LOGD(TAG, "HTTP_EVENT_DISCONNECTED");
break;
case HTTP_EVENT_REDIRECT:
ESP_LOGD(TAG, "HTTP_EVENT_REDIRECT");
break;
}
return ESP_OK;
}
extern const uint8_t server_cert_pem_start[] asm("_binary_ca_cert_pem_start");
extern const uint8_t server_cert_pem_end[] asm("_binary_ca_cert_pem_end");
void simple_ota_example_task(void *pvParameter)
{
ESP_LOGI(TAG, "Starting OTA example task");
#ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF
esp_netif_t *netif = get_example_netif_from_desc(bind_interface_name);
if (netif == NULL) {
ESP_LOGE(TAG, "Can't find netif from interface description");
abort();
}
struct ifreq ifr;
esp_netif_get_netif_impl_name(netif, ifr.ifr_name);
ESP_LOGI(TAG, "Bind interface name is %s", ifr.ifr_name);
#endif
esp_http_client_config_t config = {
.url = "https://192.168.0.28:8070/rgb_lcd.bin",
.event_handler = _ota_http_event_handler,
.keep_alive_enable = true,
.cert_pem = (char *)server_cert_pem_start,
#ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF
.if_name = &ifr,
#endif
};
#ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL_FROM_STDIN
char url_buf[OTA_URL_SIZE];
if (strcmp(config.url, "FROM_STDIN") == 0) {
example_configure_stdin_stdout();
fgets(url_buf, OTA_URL_SIZE, stdin);
int len = strlen(url_buf);
url_buf[len - 1] = '\0';
config.url = url_buf;
} else {
ESP_LOGE(TAG, "Configuration mismatch: wrong firmware upgrade image url");
abort();
}
#endif
#ifdef CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK
config.skip_cert_common_name_check = true;
#endif
esp_https_ota_config_t ota_config = {
.http_config = &config,
};
ESP_LOGI(TAG, "Attempting to download update from %s", config.url);
esp_err_t ret = esp_https_ota(&ota_config);
if (ret == ESP_OK) {
ESP_LOGI(TAG, "OTA Succeed, Rebooting...");
esp_restart();
} else {
ESP_LOGE(TAG, "Firmware upgrade failed");
}
while (1) {
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
am2302_handle_t sensor = NULL;
void readTempHumid(void *pvParameter)
{
float temperature = 0;
float humidity = 0;
while (1)
{
am2302_read_temp_humi(sensor, &temperature, &humidity);
char buff[40];
ESP_LOGI(TAG, "Temperature: %.1f °C, Humidity: %.1f %%", temperature, humidity);
sprintf(buff,"%.1f °C, %.1f %%", temperature, humidity);
show_temp(buff);
vTaskDelay(60000 / portTICK_PERIOD_MS);
}
}
void alloc_fail(size_t size, uint32_t caps, const char * function_name){
ESP_LOGE(TAG,"fail alloc %u in %" PRIu32 " in %s", size,caps,function_name);
}
void app_main(void)
{
printf("Minimum free heap size: %" PRIu32 " bytes\n", esp_get_minimum_free_heap_size());
printf("Free heap size: %" PRIu32 " bytes\n", esp_get_free_heap_size());
heap_caps_print_heap_info(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
heap_caps_register_failed_alloc_callback(alloc_fail);
printf("1- Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
esp_log_level_set("wifi", ESP_LOG_ERROR);
esp_log_level_set(TAG, ESP_LOG_VERBOSE);
printf("2- Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
//mount_sd_card();
bsp_sdcard_mount();
//lv_log_register_print_cb(log_cb);
// LCD HW initialization
//ESP_ERROR_CHECK(app_lcd_init());
printf("4 - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
// Touch initialization
//ESP_ERROR_CHECK(app_touch_init());
printf("5 - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
// LVGL initialization
//ESP_ERROR_CHECK(app_lvgl_init());
printf("6 - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
ESP_LOGI(TAG, "Initializing LittleFS");
esp_vfs_littlefs_conf_t conflfs = {
.base_path = "/littlefs",
.partition_label = "littlefs",
.format_if_mount_failed = true,
.dont_mount = false,
};
// Use settings defined above to initialize and mount LittleFS filesystem.
// Note: esp_vfs_littlefs_register is an all-in-one convenience function.
esp_err_t retlfs = esp_vfs_littlefs_register(&conflfs);
if (retlfs != ESP_OK){
if (retlfs == ESP_FAIL){
ESP_LOGE(TAG, "Failed to mount or format filesystem");
}else if (retlfs == ESP_ERR_NOT_FOUND){
ESP_LOGE(TAG, "Failed to find LittleFS partition");
}else{
ESP_LOGE(TAG, "Failed to initialize LittleFS (%s)", esp_err_to_name(retlfs));
}
return;
}
size_t total = 0, used = 0;
retlfs = esp_littlefs_info(conflfs.partition_label, &total, &used);
if (retlfs != ESP_OK)
{
ESP_LOGE(TAG, "Failed to get LittleFS partition information (%s)", esp_err_to_name(retlfs));
}
else
{
ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used);
}
// On affiche au plus tot l'ecran de démarrage
// ESP_ERROR_CHECK(esp_lcd_panel_mirror(lcd_panel,true,true));
init_display();
display_lock("app_main");
app_main_display();
display_unlock("app_main");
printf("7 - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
// Initialize NVS
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);
printf("8 - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
wifi_init_sta();
//start_wifi_logger();
//wifi_log_e("test", "%s %d %f", "hello world wifi logger", 43, 45.341223242); // write log over wifi with log level -> ERROR
esp_log_level_set("tcp_handler", ESP_LOG_NONE);
printf("8b - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
printf("9 - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
time_t now;
struct tm timeinfo;
time(&now);
localtime_r(&now, &timeinfo);
// Is time set? If not, tm_year will be (1970 - 1900).
if (timeinfo.tm_year < (2016 - 1900))
{
ESP_LOGI(TAG, "Time is not set yet. Connecting to WiFi and getting time over NTP.");
obtain_time();
// update 'now' variable with current time
time(&now);
}
char strftime_buf[64];
// Set timezone to Eastern Standard Time and print local time
setenv("TZ", "CET-1CEST,M3.5.0,M10.5.0/3", 1);
tzset();
localtime_r(&now, &timeinfo);
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
printf("10. Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
heap_caps_print_heap_info(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
printf("11. Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
ESP_LOGW(TAG, "On telecharge l'image cuve");
TaskHandle_t xHandle = NULL;
BaseType_t ret1;
ret1 = xTaskCreate(&imgdwn, "imageDownload_task", 3 * 1024, NULL, 5, &xHandle);
if (ret1 != pdPASS)
{
ESP_LOGE(TAG, "Impossiblke de creer la tache imageDownload_task %i", ret1);
}
BaseType_t ret2 = xTaskCreate(&updateTime, "updateTimeTask", 3 * 1024, NULL, 5, NULL);
if (ret2 != pdPASS)
{
ESP_LOGE(TAG, "Impossiblke de creer la tache updateTimeTask %i", ret2);
}
printf("12. Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
// Show LVGL objects
if(display_lock("draw_ihm")){
draw_ihm();
display_unlock("draw_ihm");
}else{
ESP_LOGE(TAG,"Impossible d'obtenir le mutex pour draw_ihm");
}
mqtt_app_start();
// Configuration de la sonde Temp/Humid.
am2302_config_t am2302_config = {
.gpio_num = AM2302_GPIO,
};
am2302_rmt_config_t rmt_config = {
.clk_src = RMT_CLK_SRC_DEFAULT,
};
ESP_ERROR_CHECK(am2302_new_sensor_rmt(&am2302_config, &rmt_config, &sensor));
xTaskCreate(&readTempHumid, "read_temp_task", 8192, NULL, 5, NULL);
}