domotic/main/main.c
2025-05-21 20:56:47 +02:00

907 lines
30 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 "esp_http_server.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 "include/communication.h"
#include "stateManagement.h"
#include "driver/gpio.h"
#include "am2302_rmt.h"
#include "eventsManager.h"
#include "esp_timer.h"
#include <esp_task_wdt.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";
#define WIFI_RDY 0b0001
static void wifiStatus_obs_cb(lv_observer_t * observer, lv_subject_t * subject);
lv_subject_t mqttStatus;
extern lv_subject_t tempIntSubj;
extern lv_subject_t tempExtSubj;
extern lv_subject_t hauteurCuveSubj;
extern lv_subject_t hauteurCuveEvolSubj;
void mqtt_cb(mqtt_evt evt, esp_mqtt_event_handle_t event){
switch (evt)
{
case MQTT_CONNECTED:
if(lvgl_port_lock(50)){
ESP_LOGV(TAG,"Statut mqttStatus 1");
lv_subject_set_int(&mqttStatus,1);
lvgl_port_unlock();
}
break;
case MQTT_DISCONNECTED:
if(lvgl_port_lock(50)){
ESP_LOGE(TAG,"Statut mqttStatus 0");
lv_subject_set_int(&mqttStatus,0);
lvgl_port_unlock();
}
break;
case MQTT_DATA_RECEIVED:
lv_subject_set_int(&mqttStatus,2);
ESP_LOGD(TAG, "\nMQTT_EVENT_DATA");
ESP_LOGD(TAG, "TOPIC=%.*s\n", event->topic_len, event->topic);
ESP_LOGD(TAG, "DATA=%.*s\n", event->data_len, event->data);
char *topic = strndup(event->topic, event->topic_len);
if (strcmp(topic, topicTempExt) == 0)
{
if(lvgl_port_lock(50)){
float temp = strtof(event->data, NULL);
char buff[5];
sprintf(buff,"%.1f",temp);
lv_subject_copy_string(&tempExtSubj, buff);
lvgl_port_unlock();
}
}
else if (strcmp(topic, topicTempInt) == 0)
{
if(lvgl_port_lock(0)){
// on retransforme en float pour ne garder que la partie entiere de la température
float temp = strtof(event->data, NULL);
char buff[5];
sprintf(buff,"%.1f",temp);
lv_subject_copy_string(&tempIntSubj, buff);
lvgl_port_unlock();
}
}
/*else if (strncmp(event->topic, topicHauteurCuveEvol, event->topic_len) == 0)
{
float datas[4] = {};
splitIt(event->data, event->data_len, datas);
ser1->y_points[0] = 130 - (int)datas[0];
ser1->y_points[1] = 130 - (int)datas[1];
ser1->y_points[2] = 130 - (int)datas[2];
ser1->y_points[3] = 130 - (int)datas[3];
lvgl_port_lock(0);
lv_chart_refresh(chart);
lvgl_port_unlock();
// lv_subject_copy_string(&hauteurCuveEvolSubj, event->data);
}*/
else if (strcmp(topic, topicHauteurCuve) == 0)
{
char* datas = malloc(event->data_len+1);
strncpy(datas, event->data, event->data_len);
float f = strtof(datas, NULL);
free(datas);
ESP_LOGE(TAG,"%f recu mqtt", f);
send_event(EVT_HAUTEUR_CUVE,&f);
/*
if (lvgl_port_lock(50)){
float temp = strtof(event->data, NULL);
char buff[5];
sprintf(buff,"%.0f",temp);
lv_subject_copy_string(&hauteurCuveSubj, buff);
lvgl_port_unlock();
}
*/
}else if (strcmp(topic, topicTest) == 0){
ESP_LOGD(TAG,"Msg reecu sur test");
}else if (strcmp(topic, topicConsoElec) == 0){
char* datas = malloc(event->data_len+1);
strncpy(datas, event->data, event->data_len);
int puissanceRecue = atoi(datas);
free(datas);
ESP_LOGE(TAG, "MQTT: Puissance recue %i", puissanceRecue);
send_event(EVT_PUISSANCE_RECUE,&puissanceRecue);
}else if (strcmp(topic, topicEtatMachine) == 0){
char* datas = malloc(event->data_len+1);
strncpy(datas, event->data, event->data_len);
send_event(EVT_ETAT_MACHINE,datas);
}else if (strcmp(topic, topicdomoticCommand) == 0){
if(strncmp(event->data,"restart",7)==0){
ESP_LOGI(TAG," Commande 'restart' recue");
esp_restart();
}
}
else
{
ESP_LOGE(TAG, "None match :-( %s", topic);
}
free(topic);
if (lvgl_port_lock(50)){
lv_subject_set_int(&mqttStatus,3);
lvgl_port_unlock();
}
break;
default:
break;
}
}
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];
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");
static esp_err_t validate_image_header(esp_app_desc_t *new_app_info)
{
if (new_app_info == NULL) {
return ESP_ERR_INVALID_ARG;
}
const esp_partition_t *running = esp_ota_get_running_partition();
esp_app_desc_t running_app_info;
if (esp_ota_get_partition_description(running, &running_app_info) == ESP_OK) {
ESP_LOGI(TAG, "Running firmware version: %s", running_app_info.version);
}
#ifndef CONFIG_EXAMPLE_SKIP_VERSION_CHECK
if (memcmp(new_app_info->version, running_app_info.version, sizeof(new_app_info->version)) == 0) {
ESP_LOGW(TAG, "Current running version is the same as a new. We will not continue the update.");
return ESP_FAIL;
}
#endif
return ESP_OK;
}
void simple_ota_example_task(void *pvParameter)
{
ESP_LOGE(TAG,"En attente connexion wifi");
// Waiting until either the connection is established (WIFI_CONNECTED_BIT).
EventBits_t bits = xEventGroupWaitBits(domotic_event_group,
BIT0,
pdFALSE,
pdFALSE,
portMAX_DELAY);
if (bits & BIT0){
esp_err_t ota_finish_err = ESP_OK;
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",
.timeout_ms = 30000,
.buffer_size = 20000,
.buffer_size_tx = 20000, //TX Buffer, Main Buffer
.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,
.buffer_caps = MALLOC_CAP_INTERNAL
};
ESP_LOGI(TAG, "Attempting to download update from %s", config.url);
esp_https_ota_handle_t https_ota_handle = NULL;
esp_err_t err = esp_https_ota_begin(&ota_config, &https_ota_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "ESP HTTPS OTA Begin failed");
vTaskDelete(NULL);
}
esp_app_desc_t app_desc;
err = esp_https_ota_get_img_desc(https_ota_handle, &app_desc);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_https_ota_get_img_desc failed");
goto ota_end;
}
err = validate_image_header(&app_desc);
if (err != ESP_OK) {
ESP_LOGE(TAG, "image header verification failed");
goto ota_end;
}
xIHMEvent_t m = {
.eEventType = IHM_EVT_OTA_STARTED,
.pvData = NULL
};
//xQueueSendToBack(ihm_queue,&m,5);
esp_task_wdt_config_t cfgWdt = {
.idle_core_mask = 0,
.timeout_ms=15000,
.trigger_panic=false
};
esp_task_wdt_reconfigure(&cfgWdt);
while (1) {
err = esp_https_ota_perform(https_ota_handle);
if (err != ESP_ERR_HTTPS_OTA_IN_PROGRESS) {
break;
}
// esp_https_ota_perform returns after every read operation which gives user the ability to
// monitor the status of OTA upgrade by calling esp_https_ota_get_image_len_read, which gives length of image
// data read so far.
//ESP_LOGE(TAG,"Image size : %i", esp_https_ota_get_image_size(https_ota_handle));
int percent=esp_https_ota_get_image_len_read(https_ota_handle)*100/esp_https_ota_get_image_size(https_ota_handle);
//ESP_LOGE(TAG, "Image bytes read: %d %i%%", esp_https_ota_get_image_len_read(https_ota_handle),percent);
m.eEventType=IHM_EVT_OTA_PROGRESS;
m.pvData=(void*)percent;
//xQueueSendToBack(ihm_queue,&m,5);
vTaskDelay(10/portTICK_PERIOD_MS);
}
if (esp_https_ota_is_complete_data_received(https_ota_handle) != true) {
// the OTA image was not completely received and user can customise the response to this situation.
ESP_LOGE(TAG, "Complete data was not received.");
} else {
ota_finish_err = esp_https_ota_finish(https_ota_handle);
if ((err == ESP_OK) && (ota_finish_err == ESP_OK)) {
ESP_LOGI(TAG, "ESP_HTTPS_OTA upgrade successful. Rebooting ...");
vTaskDelay(1000 / portTICK_PERIOD_MS);
esp_restart();
} else {
if (ota_finish_err == ESP_ERR_OTA_VALIDATE_FAILED) {
ESP_LOGE(TAG, "Image validation failed, image is corrupted");
}
ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed 0x%x", ota_finish_err);
vTaskDelete(NULL);
}
}
ota_end:
esp_https_ota_abort(https_ota_handle);
ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed");
vTaskDelete(NULL);
}
}
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);
xIHMEvent_t m = {
.eEventType = IHM_EVT_HUMID_TEMP,
.pvData = buff
};
//xQueueSendToFront(ihm_queue,&m,5);
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);
}
static QueueHandle_t gpio_evt_queue = NULL;
// Durée pour l'arret automatique (micro-secondes ^^)
uint64_t arretAuto=5*60*1000*1000;
bool ecranEteint=true;
// Ce timer permet d'eteindre l'ecran "arretAuto" apres la derniere présence détectée
esp_timer_handle_t presence_timer;
static void IRAM_ATTR gpio_isr_handler(void* arg)
{
uint32_t gpio_num = (uint32_t) arg;
xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}
static void gpio_task_example(void* arg)
{
uint32_t io_num;
int delay=50;
for (;;) {
if (xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
ESP_LOGE(TAG,"Got it !");
if(ecranEteint){
for (int i = 0; i < 100; i+=2)
{
if(bsp_display_lock(0)){
bsp_display_brightness_set(i);
bsp_display_unlock();
}
vTaskDelay(delay/portTICK_PERIOD_MS);
}
ecranEteint=false;
}else{
ESP_LOGI(TAG, "Ecran déjà allumé");
}
//On arrete le timer de presence
esp_timer_stop(presence_timer);
//Pour le redemarrer
ESP_ERROR_CHECK(esp_timer_start_once(presence_timer, arretAuto));
}
}
}
#define GPIO_INPUT_IO_0 CONFIG_GPIO_INPUT_CAPTEUR_PIR
void initPirSensor(){
//create a queue to handle gpio event from isr
gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
//start gpio task
xTaskCreate(gpio_task_example, "gpio_task_example", 5000, NULL, 10, NULL);
gpio_config_t gpioconf={
.pin_bit_mask= 1ULL<<GPIO_INPUT_IO_0,
.intr_type=GPIO_INTR_POSEDGE,
.mode=GPIO_MODE_INPUT,
.pull_up_en=1
};
ESP_ERROR_CHECK(gpio_config(&gpioconf));
gpio_install_isr_service(0);
gpio_isr_handler_add(GPIO_INPUT_IO_0,gpio_isr_handler,(void*)(GPIO_INPUT_IO_0));
}
/* Ce timer permet d'eteindre l'ecran apres @arretAuto de présence*/
static void presence_timer_callback(void* arg)
{
int64_t time_since_boot = esp_timer_get_time();
for (int i = 100; i >= 0; i-=2)
{
if(bsp_display_lock(0)){
bsp_display_brightness_set(i);
bsp_display_unlock();
}
vTaskDelay(20/portTICK_PERIOD_MS);
}
ecranEteint=true;
}
static esp_err_t download_get_handler(httpd_req_t *req) {
httpd_resp_set_type(req, "application/octet-stream");
httpd_resp_set_hdr(req, "Content-Disposition",
"attachment;filename=core.bin");
esp_partition_iterator_t partition_iterator = esp_partition_find(
ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_COREDUMP, "coredump");
const esp_partition_t *partition = esp_partition_get(partition_iterator);
int file_size = 65536;
int chunk_size = 1024;
int i = 0;
for (i = 0; i < (file_size / chunk_size); i++) {
char store_data[chunk_size];
ESP_ERROR_CHECK(
esp_partition_read(partition, i * chunk_size, store_data, chunk_size));
httpd_resp_send_chunk(req, store_data, chunk_size);
}
uint16_t pending_size = file_size - (i * chunk_size);
char pending_data[pending_size];
if (pending_size > 0) {
ESP_ERROR_CHECK(esp_partition_read(partition, i * chunk_size, pending_data,
pending_size));
httpd_resp_send_chunk(req, pending_data, pending_size);
}
httpd_resp_send_chunk(req, NULL, 0);
return ESP_OK;
}
extern const unsigned char index_start[] asm("_binary_index_html_start");
extern const unsigned char index_end[] asm("_binary_index_html_end");
static esp_err_t crash_get_handler(httpd_req_t *req) {
const size_t index_size = (index_end - index_start);
httpd_resp_set_type(req, "text/html");
httpd_resp_send_chunk(req, (const char *)index_start, index_size);
httpd_resp_send_chunk(req, NULL, 0);
assert(0);
return ESP_OK;
}
static const httpd_uri_t download = {
.uri = "/download",
.method = HTTP_GET,
.handler = download_get_handler,
.user_ctx = NULL,
};
static const httpd_uri_t crash = {
.uri = "/crash",
.method = HTTP_GET,
.handler = crash_get_handler,
.user_ctx = NULL,
};
static esp_err_t root_get_handler(httpd_req_t *req) {
const size_t index_size = (index_end - index_start);
httpd_resp_set_type(req, "text/html");
httpd_resp_send_chunk(req, (const char *)index_start, index_size);
httpd_resp_send_chunk(req, NULL, 0);
return ESP_OK;
}
static const httpd_uri_t root = {
.uri = "/",
.method = HTTP_GET,
.handler = root_get_handler,
.user_ctx = NULL,
};
static httpd_handle_t start_webserver(void) {
httpd_handle_t server = NULL;
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.max_resp_headers = 1024;
config.lru_purge_enable = true;
// Start the httpd server
ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
if (httpd_start(&server, &config) == ESP_OK) {
// Set URI handlers
ESP_LOGI(TAG, "Registering URI handlers");
httpd_register_uri_handler(server, &root);
httpd_register_uri_handler(server, &download);
httpd_register_uri_handler(server, &crash);
return server;
}
ESP_LOGI(TAG, "Error starting server!");
return NULL;
}
void wifi_cb(wifi_evt evt){
ESP_LOGE(TAG,"On est dans wifi_cb %i", evt);
switch(evt){
case WIFI_CONNECTED:
mainState.wifi_init=true;
send_event(WIFI_CONNECTED,NULL);
break;
case WIFI_DISCONNECTED:
mainState.wifi_init=true;
send_event(WIFI_DISCONNECTED,NULL);
break;
case WIFI_GOT_IP:
mainState.wifi_init=true;
send_event(WIFI_CONNECTED,NULL);
break;
case WIFI_CONNECT_FAIL:
break;
default:
break;
}
}
extern lv_subject_t forecastD1Subj;
extern lv_subject_t forecastD2Subj;
extern lv_subject_t forecastD3Subj;
extern lv_subject_t forecastH1Subj;
extern lv_subject_t forecastH2Subj;
extern lv_subject_t forecastH3Subj;
extern lv_subject_t meteoStatus;
void weather_data_retreived(struct meteodailyforecast_data dailyDatas[3], struct meteoforecast_data datas[3])
{
/* ESP_LOGE(TAG, "debut debug");
printf("%lld\n", datas[0].datetime);
printf("%s\n", datas[0].previsions.desc);
printf("%f\n", datas[0].previsions.value);
printf("%lld\n", datas[1].datetime);
printf("%s\n", datas[1].previsions.desc);
printf("%f\n", datas[1].previsions.value);
printf("%lld\n", datas[2].datetime);
printf("%s\n", datas[2].previsions.desc);
printf("%f\n", datas[2].previsions.value);
ESP_LOGE(TAG, "fin debug");
*/
if (display_lock("weather_data_retreived"))
{
ESP_LOGV("MeteoFrance", "------------------------------------- Set des subjects J --------------------------------");
// Prévisions des 3 prochains jours
lv_subject_set_pointer(&forecastD1Subj, &dailyDatas[0]);
lv_subject_set_pointer(&forecastD2Subj, &dailyDatas[1]);
lv_subject_set_pointer(&forecastD3Subj, &dailyDatas[2]);
ESP_LOGV("MeteoFrance", "------------------------------------- Set des subjects H--------------------------------");
// Prévisions des 3 prochains jours
ESP_LOGV("MeteoFrance", "Pointeur %lli", datas[0].datetime);
lv_subject_set_pointer(&forecastH1Subj, &datas[0]);
lv_subject_set_pointer(&forecastH2Subj, &datas[1]);
lv_subject_set_pointer(&forecastH3Subj, &datas[2]);
lv_subject_set_int(&meteoStatus, 0);
display_unlock("weather_data_retreived");
ESP_LOGV(TAG, "------------------------------------- Fin Set des subjects --------------------------------");
}else{
ESP_LOGE(TAG, "Impossible d'obtenir le mutex dans weather_data_retreived");
}
}
void weather_data_retreived_start()
{
//if (display_lock("weather_data_retreived_start"))
//{
//ESP_LOGE(TAG,"Mutex obtenu dans weather_data_retreived_start");
lv_subject_set_int(&meteoStatus, 1);
ESP_LOGE(TAG,"Subject setted weather_data_retreived_start");
//display_unlock("weather_data_retreived_start");
//}else{
// ESP_LOGE(TAG,"Impossible d'obtenir le mutex dans weather_data_retreived_start");
//}
}
LV_IMAGE_DECLARE(mqtt_ok);
LV_IMAGE_DECLARE(mqtt_ko);
static void mqttStatus_obs_cb(lv_observer_t * observer, lv_subject_t * subject)
{
ESP_LOGV(TAG, "On passe dans le callback de chgt de statut; %li", lv_subject_get_int(subject));
if(lvgl_port_lock(0)){
lv_obj_t * wifiSt = lv_obj_get_child(lv_obj_get_child(lv_layer_top(), 0),3);
if(lv_obj_check_type(wifiSt, &lv_image_class)){
switch (lv_subject_get_int(subject))
{
case 0:
lv_image_set_src(wifiSt,&mqtt_ko);
break;
case 1:
lv_image_set_src(wifiSt,&mqtt_ok);
break;
case 2:
lv_color_t color = lv_color_make(255, 0, 0);
lv_obj_set_style_image_recolor_opa(wifiSt, 125, 0);
lv_obj_set_style_image_recolor(wifiSt, color, 0);
vTaskDelay(2000 / portTICK_PERIOD_MS);
break;
case 3:
lv_obj_set_style_image_recolor_opa(wifiSt, 0, 0);
break;
default:
break;
}
}else{
ESP_LOGE(TAG, "L'objet recuip en semble pas etre du bon type");
}
lvgl_port_unlock();
}
//int32_t prev_v = lv_subject_get_previous_int(subject);
//int32_t cur_v = lv_subject_get_int(subject);
//lv_obj_t * btn = lv_observer_get_target(observer);
}
void app_main(void)
{
startEvtManager();
//init_display();
const esp_timer_create_args_t periodic_timer_args = {
.callback = &presence_timer_callback,
/* name is optional, but may help identify the timer when debugging */
.name = "presence"
};
ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &presence_timer));
/* Start the timers */
ESP_ERROR_CHECK(esp_timer_start_once(presence_timer, 30*1000*1000));
initPirSensor();
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);
//mount_sd_card();
bsp_sdcard_mount();
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));
xTaskCreatePinnedToCore(&drawIhm,"ihm_task",10000,getIHMQueueHandle(),10,NULL,0);
// 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);
ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
wifi_init_sta(wifi_cb);
//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());
/* Ensure to disable any WiFi power save mode, this allows best throughput
* and hence timings for overall OTA operation.
*/
esp_wifi_set_ps(WIFI_PS_NONE);
xTaskCreatePinnedToCore(&simple_ota_example_task, "ota__task", 8192, NULL, 1, NULL,0);
on_weather_data_retrieval(weather_data_retreived);
on_weather_data_retrieval_start(weather_data_retreived_start);
ESP_LOGW(TAG, "Weather data retrieval initialized");
initialise_weather_data_retrieval(600000, domotic_event_group);
TaskHandle_t xHandle = NULL;
BaseType_t ret1;
ret1 = xTaskCreate(&imgdwn, "imageDownload_task", 3 * 1024, domotic_event_group, 5, &xHandle);
if (ret1 != pdPASS)
{
ESP_LOGE(TAG, "Impossiblke de creer la tache imageDownload_task %i", ret1);
}
/* Tache updateTime */
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);
}
/* Tache updateTime - FIN*/
mqtt_app_start(mqtt_cb, domotic_event_group);
//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 }
lv_subject_init_int(&mqttStatus,-1);
lv_subject_add_observer_obj(&mqttStatus, mqttStatus_obs_cb, NULL, NULL);
while(!mainState.wifi_init){
vTaskDelay(pdTICKS_TO_MS(10));
}
start_webserver();
// 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);
}