#include "wifi.h" #include "mqtt.h" #include "misc/lv_types.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_lcd_panel_io.h" #include "esp_lcd_panel_ops.h" #include "esp_lcd_panel_rgb.h" #include "esp_lvgl_port.h" #include "esp_event.h" #include "nvs_flash.h" #include "meteofrance.h" #include "image_downloader.h" #include #include "fatfs.h" #define DIR FF_DIR /* ESP IDF typedefs `DIR` as `FF_DIR` in its version of ff.h. Use `FF_DIR` in LVGL too */ #include "esp_vfs_fat.h" #include "sdmmc_cmd.h" #include #include "obtain_time.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 #include "esp_lcd_touch_gt911.h" #include "main.h" LV_FONT_DECLARE(montserrat_medium_12) LV_FONT_DECLARE(montserrat_medium_18) LV_FONT_DECLARE(montserrat_medium_24) char *days[7]={"Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"}; char *months[12]={"Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Août","Septembre","Octobre","Novembre","Décembre"}; /* LCD size */ #define EXAMPLE_LCD_H_RES (800) #define EXAMPLE_LCD_V_RES (480) /* LCD settings */ #define EXAMPLE_LCD_LVGL_FULL_REFRESH (0) #define EXAMPLE_LCD_LVGL_DIRECT_MODE (1) #define EXAMPLE_LCD_LVGL_AVOID_TEAR (1) #define EXAMPLE_LCD_RGB_BOUNCE_BUFFER_MODE (1) #define EXAMPLE_LCD_DRAW_BUFF_DOUBLE (1) #define EXAMPLE_LCD_DRAW_BUFF_HEIGHT (100) #define EXAMPLE_LCD_RGB_BUFFER_NUMS (2) #define EXAMPLE_LCD_RGB_BOUNCE_BUFFER_HEIGHT (10) /* LCD pins */ #define EXAMPLE_LCD_GPIO_VSYNC (GPIO_NUM_41) #define EXAMPLE_LCD_GPIO_HSYNC (GPIO_NUM_39) #define EXAMPLE_LCD_GPIO_DE (GPIO_NUM_40) #define EXAMPLE_LCD_GPIO_PCLK (GPIO_NUM_42) #define EXAMPLE_LCD_GPIO_DISP (GPIO_NUM_NC) #define EXAMPLE_LCD_GPIO_DATA0 (GPIO_NUM_8) #define EXAMPLE_LCD_GPIO_DATA1 (GPIO_NUM_3) #define EXAMPLE_LCD_GPIO_DATA2 (GPIO_NUM_46) #define EXAMPLE_LCD_GPIO_DATA3 (GPIO_NUM_9) #define EXAMPLE_LCD_GPIO_DATA4 (GPIO_NUM_1) #define EXAMPLE_LCD_GPIO_DATA5 (GPIO_NUM_5) #define EXAMPLE_LCD_GPIO_DATA6 (GPIO_NUM_6) #define EXAMPLE_LCD_GPIO_DATA7 (GPIO_NUM_7) #define EXAMPLE_LCD_GPIO_DATA8 (GPIO_NUM_15) #define EXAMPLE_LCD_GPIO_DATA9 (GPIO_NUM_16) #define EXAMPLE_LCD_GPIO_DATA10 (GPIO_NUM_4) #define EXAMPLE_LCD_GPIO_DATA11 (GPIO_NUM_45) #define EXAMPLE_LCD_GPIO_DATA12 (GPIO_NUM_48) #define EXAMPLE_LCD_GPIO_DATA13 (GPIO_NUM_47) #define EXAMPLE_LCD_GPIO_DATA14 (GPIO_NUM_21) #define EXAMPLE_LCD_GPIO_DATA15 (GPIO_NUM_14) /* Touch settings */ #define EXAMPLE_TOUCH_I2C_NUM (0) #define EXAMPLE_TOUCH_I2C_CLK_HZ (400000) /* LCD touch pins */ #define EXAMPLE_TOUCH_I2C_SCL (GPIO_NUM_18) #define EXAMPLE_TOUCH_I2C_SDA (GPIO_NUM_17) #define EXAMPLE_LCD_PANEL_35HZ_RGB_TIMING() \ { \ .pclk_hz = 16 * 1000 * 1000, \ .h_res = EXAMPLE_LCD_H_RES, \ .v_res = EXAMPLE_LCD_V_RES, \ .hsync_pulse_width = 4, \ .hsync_back_porch = 8, \ .hsync_front_porch = 8, \ .vsync_pulse_width = 4, \ .vsync_back_porch = 8, \ .vsync_front_porch = 8, \ .flags.pclk_active_neg = true, \ .flags.hsync_idle_low =true, \ } static const char *TAG = "domoTic"; extern char *upEvent; extern char *downEvent; // LVGL image declare LV_IMG_DECLARE(esp_logo) /* LCD IO and panel */ static esp_lcd_panel_handle_t lcd_panel = NULL; static esp_lcd_touch_handle_t touch_handle = NULL; /* LVGL display and touch */ static lv_display_t *lvgl_disp = NULL; static lv_indev_t *lvgl_touch_indev = NULL; lv_obj_t *chart; lv_chart_series_t *ser1; static esp_err_t app_lcd_init(void) { esp_err_t ret = ESP_OK; /* LCD initialization */ ESP_LOGI(TAG, "Initialize RGB panel"); esp_lcd_rgb_panel_config_t panel_conf = { .clk_src = LCD_CLK_SRC_PLL160M, .psram_trans_align = 64, .data_width = 16, .bits_per_pixel = 16, .de_gpio_num = EXAMPLE_LCD_GPIO_DE, .pclk_gpio_num = EXAMPLE_LCD_GPIO_PCLK, .vsync_gpio_num = EXAMPLE_LCD_GPIO_VSYNC, .hsync_gpio_num = EXAMPLE_LCD_GPIO_HSYNC, .disp_gpio_num = EXAMPLE_LCD_GPIO_DISP, .data_gpio_nums = { EXAMPLE_LCD_GPIO_DATA0, EXAMPLE_LCD_GPIO_DATA1, EXAMPLE_LCD_GPIO_DATA2, EXAMPLE_LCD_GPIO_DATA3, EXAMPLE_LCD_GPIO_DATA4, EXAMPLE_LCD_GPIO_DATA5, EXAMPLE_LCD_GPIO_DATA6, EXAMPLE_LCD_GPIO_DATA7, EXAMPLE_LCD_GPIO_DATA8, EXAMPLE_LCD_GPIO_DATA9, EXAMPLE_LCD_GPIO_DATA10, EXAMPLE_LCD_GPIO_DATA11, EXAMPLE_LCD_GPIO_DATA12, EXAMPLE_LCD_GPIO_DATA13, EXAMPLE_LCD_GPIO_DATA14, EXAMPLE_LCD_GPIO_DATA15, }, .timings = EXAMPLE_LCD_PANEL_35HZ_RGB_TIMING(), .flags.fb_in_psram = 1, .num_fbs = EXAMPLE_LCD_RGB_BUFFER_NUMS, #if EXAMPLE_LCD_RGB_BOUNCE_BUFFER_MODE .bounce_buffer_size_px = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_RGB_BOUNCE_BUFFER_HEIGHT, #endif }; ESP_GOTO_ON_ERROR(esp_lcd_new_rgb_panel(&panel_conf, &lcd_panel), err, TAG, "RGB init failed"); ESP_GOTO_ON_ERROR(esp_lcd_panel_init(lcd_panel), err, TAG, "LCD init failed"); return ret; err: if (lcd_panel) { esp_lcd_panel_del(lcd_panel); } return ret; } static esp_err_t app_touch_init(void) { /* Initilize I2C */ const i2c_config_t i2c_conf = { .mode = I2C_MODE_MASTER, .sda_io_num = EXAMPLE_TOUCH_I2C_SDA, .sda_pullup_en = GPIO_PULLUP_DISABLE, .scl_io_num = EXAMPLE_TOUCH_I2C_SCL, .scl_pullup_en = GPIO_PULLUP_DISABLE, .master.clk_speed = EXAMPLE_TOUCH_I2C_CLK_HZ}; ESP_RETURN_ON_ERROR(i2c_param_config(EXAMPLE_TOUCH_I2C_NUM, &i2c_conf), TAG, "I2C configuration failed"); ESP_RETURN_ON_ERROR(i2c_driver_install(EXAMPLE_TOUCH_I2C_NUM, i2c_conf.mode, 0, 0, 0), TAG, "I2C initialization failed"); /* Initialize touch HW */ const esp_lcd_touch_config_t tp_cfg = { .x_max = EXAMPLE_LCD_H_RES, .y_max = EXAMPLE_LCD_V_RES, .rst_gpio_num = GPIO_NUM_NC, .int_gpio_num = GPIO_NUM_NC, .levels = { .reset = 0, .interrupt = 0, }, .flags = { .swap_xy = 0, .mirror_x = 0, .mirror_y = 0, }, }; esp_lcd_panel_io_handle_t tp_io_handle = NULL; const esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG(); ESP_RETURN_ON_ERROR(esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)EXAMPLE_TOUCH_I2C_NUM, &tp_io_config, &tp_io_handle), TAG, ""); return esp_lcd_touch_new_i2c_gt911(tp_io_handle, &tp_cfg, &touch_handle); } static esp_err_t app_lvgl_init(void) { /* Initialize LVGL */ const lvgl_port_cfg_t lvgl_cfg = { .task_priority = 4, /* LVGL task priority */ .task_stack = 12288,//6144, /* LVGL task stack size */ .task_affinity = -1, /* LVGL task pinned to core (-1 is no affinity) */ .task_max_sleep_ms = 500, /* Maximum sleep in LVGL task */ .timer_period_ms = 5 /* LVGL timer tick period in ms */ }; ESP_RETURN_ON_ERROR(lvgl_port_init(&lvgl_cfg), TAG, "LVGL port initialization failed"); uint32_t buff_size = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_DRAW_BUFF_HEIGHT; #if EXAMPLE_LCD_LVGL_FULL_REFRESH || EXAMPLE_LCD_LVGL_DIRECT_MODE buff_size = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES; #endif /* Add LCD screen */ ESP_LOGD(TAG, "Add LCD screen"); const lvgl_port_display_cfg_t disp_cfg = { .panel_handle = lcd_panel, .buffer_size = buff_size, .double_buffer = EXAMPLE_LCD_DRAW_BUFF_DOUBLE, .hres = EXAMPLE_LCD_H_RES, .vres = EXAMPLE_LCD_V_RES, .monochrome = false, #if LVGL_VERSION_MAJOR >= 9 .color_format = LV_COLOR_FORMAT_RGB565, #endif .rotation = { .swap_xy = false, .mirror_x = false, .mirror_y = false, }, .flags = { .buff_dma = false, .buff_spiram = false, #if EXAMPLE_LCD_LVGL_FULL_REFRESH .full_refresh = true, #elif EXAMPLE_LCD_LVGL_DIRECT_MODE .direct_mode = true, #endif #if LVGL_VERSION_MAJOR >= 9 .swap_bytes = false, #endif }}; const lvgl_port_display_rgb_cfg_t rgb_cfg = { .flags = { #if EXAMPLE_LCD_RGB_BOUNCE_BUFFER_MODE .bb_mode = true, #else .bb_mode = false, #endif #if EXAMPLE_LCD_LVGL_AVOID_TEAR .avoid_tearing = true, #else .avoid_tearing = false, #endif }}; lvgl_disp = lvgl_port_add_disp_rgb(&disp_cfg, &rgb_cfg); /* Add touch input (for selected screen) */ const lvgl_port_touch_cfg_t touch_cfg = { .disp = lvgl_disp, .handle = touch_handle, }; lvgl_touch_indev = lvgl_port_add_touch(&touch_cfg); return ESP_OK; } static void _app_button_cb(lv_event_t *e) { if(lvgl_port_lock(0)){ lv_disp_rotation_t rotation = lv_disp_get_rotation(lvgl_disp); rotation++; if (rotation > LV_DISPLAY_ROTATION_270) { rotation = LV_DISPLAY_ROTATION_0; } /* LCD HW rotation */ lv_disp_set_rotation(lvgl_disp, rotation); lvgl_port_unlock(); } } lv_subject_t wifiStatus; lv_subject_t mqttStatus; lv_subject_t meteoStatus; static lv_style_t no_padding; static lv_style_t style_font_18; static void app_main_display(void) { lv_style_init(&no_padding); lv_style_set_pad_all(&no_padding, 0); lv_obj_t *cont_status = lv_obj_create(lv_layer_top()); lv_obj_add_style(cont_status,&no_padding,0); 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 *jour = lv_label_create(cont_status); lv_obj_add_style(jour,&style_font_18,0); setlocale(LC_ALL, "fr_FR"); char strftime_buf[64]; time_t now = 0; time(&now); struct tm timeinfo = { 0 }; localtime_r(&now, &timeinfo); sprintf(strftime_buf,"%s %d %s", days[timeinfo.tm_wday], timeinfo.tm_mday, months[timeinfo.tm_mon]); lv_label_set_text(jour,strftime_buf); lv_obj_align(jour, LV_ALIGN_CENTER,0,0); lv_obj_t *meteoR = lv_label_create(cont_status); lv_label_set_text(meteoR,"--"); lv_label_bind_text(meteoR, &meteoStatus, "Meteo %d"); lv_obj_t *wifi = lv_label_create(cont_status); lv_obj_set_style_bg_color(wifi, lv_palette_darken(LV_PALETTE_GREY, 3), 0); lv_obj_set_style_border_width(wifi,1,0); lv_obj_set_style_border_color(wifi,lv_palette_darken(LV_PALETTE_GREY, 3),0); 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 .... */ /* Create image */ lv_obj_t *img_logo = lv_img_create(scr); lv_img_set_src(img_logo, &esp_logo); lv_obj_align(img_logo, LV_ALIGN_TOP_MID, 0, 20); /* Label */ lv_obj_t *label = lv_label_create(scr); lv_obj_set_width(label, EXAMPLE_LCD_H_RES); lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0); #if LVGL_VERSION_MAJOR == 8 lv_label_set_recolor(label, true); lv_label_set_text(label, "#FF0000 " LV_SYMBOL_BELL " Hello world Espressif and LVGL " LV_SYMBOL_BELL "#\n#FF9400 " LV_SYMBOL_WARNING " For simplier initialization, use BSP " LV_SYMBOL_WARNING " #"); #else lv_label_set_text(label, LV_SYMBOL_BELL " Hello world Espressif and LVGL " LV_SYMBOL_BELL "\n " LV_SYMBOL_WARNING " For simplier initialization, use BSP " LV_SYMBOL_WARNING); #endif lv_obj_align(label, LV_ALIGN_CENTER, 0, 20); /* Button */ lv_obj_t *btn = lv_btn_create(scr); label = lv_label_create(btn); lv_label_set_text_static(label, "Rotate screen"); lv_obj_align(btn, LV_ALIGN_BOTTOM_MID, 0, -30); lv_obj_add_event_cb(btn, _app_button_cb, LV_EVENT_CLICKED, NULL); } char tempExtStr[6]; char tempIntStr[6]; char hauteurCuveStr[9]; char hauteurCuveEvolStr[9]; lv_subject_t tempIntSubj; lv_subject_t tempExtSubj; lv_subject_t hauteurCuveSubj; lv_subject_t hauteurCuveEvolSubj; lv_subject_t forecastD1Subj; lv_subject_t forecastD2Subj; lv_subject_t forecastD3Subj; lv_subject_t *tmpSubj[3] = {&forecastD1Subj, &forecastD2Subj, &forecastD3Subj}; lv_subject_t forecastH1Subj; lv_subject_t forecastH2Subj; lv_subject_t forecastH3Subj; lv_subject_t *tmpHSubj[3] = {&forecastH1Subj, &forecastH2Subj, &forecastH3Subj}; extern esp_mqtt_client_handle_t client; static void event_handler(lv_event_t *e) { lv_event_code_t code = lv_event_get_code(e); //lv_obj_t *obj = (lv_obj_t *)lv_event_get_target(e); char *evtData = (char *)lv_event_get_user_data(e); switch (code) { case LV_EVENT_PRESSED: // LV_LOG_USER("%s was pressed\n", evtData); break; case LV_EVENT_CLICKED: ESP_LOGI(TAG, "%s was clicked\n", evtData); esp_mqtt_client_publish(client, "volets", evtData, 0, 0, 0); break; case LV_EVENT_LONG_PRESSED: LV_LOG_USER("%s was long pressed\n", evtData); break; case LV_EVENT_LONG_PRESSED_REPEAT: LV_LOG_USER("%s was long press repeat\n", evtData); break; default: break; } } LV_IMAGE_DECLARE(plan_rdc); LV_IMAGE_DECLARE(plan_etage); LV_IMAGE_DECLARE(p1j); LV_IMAGE_DECLARE(p2j); LV_IMAGE_DECLARE(p3j); LV_IMAGE_DECLARE(p4j); LV_IMAGE_DECLARE(p5bisj); LV_IMAGE_DECLARE(p12j); LV_IMAGE_DECLARE(p12bisj); LV_IMAGE_DECLARE(p13j); LV_IMAGE_DECLARE(p13bisj); LV_IMAGE_DECLARE(p14j); LV_IMAGE_DECLARE(p24j); LV_IMAGE_DECLARE(p25j); LV_IMAGE_DECLARE(p26j); LV_IMAGE_DECLARE(p27j); LV_IMAGE_DECLARE(p28j); LV_IMAGE_DECLARE(p29j); struct lv_observer_t { lv_subject_t * subject; /**< The observed value */ lv_observer_cb_t cb; /**< Callback that should be called when the value changes*/ void * target; /**< A target for the observer, e.g. a widget or style*/ void * user_data; /**< Additional parameter supplied when subscribing*/ uint32_t auto_free_user_data : 1; /**< Automatically free user data when the observer is removed */ uint32_t notified : 1; /**< Mark if this observer was already notified*/ uint32_t for_obj : 1; /**< `target` is an `lv_obj_t *`*/ }; static lv_style_t style_container; static lv_style_t style_font_24; static lv_style_t style_font_12; // Callback pour mettre à jour une météo journaliere // On pointe sur un tableau de meteodailyforecast_data static void weatherdata_obs_cb(lv_observer_t *observer, lv_subject_t *subject) { ESP_LOGE(TAG, "CB meteo jour declenché"); // Retrieve weatherdata const struct meteodailyforecast_data *data = subject->value.pointer; //printffd(data); //char buff[40] = {}; // sprintf(buff,"%s %.1f %.1f", data->previsions.desc, data->previsions.min, data->previsions.max); lv_obj_t *parent = (lv_obj_t *)(observer->target); lv_obj_t *datefld = lv_obj_get_child(parent, 0); lv_obj_t *desc_icon = lv_obj_get_child(parent, 1); lv_obj_t *temps = lv_obj_get_child(parent, 2); showMeteoIcon(data->previsions.icon, desc_icon,0); char buffer[80]; dtToString(data->datetime,buffer); lv_label_set_text(datefld, buffer); lv_label_set_text(lv_obj_get_child(desc_icon, 1), data->previsions.desc); lv_label_set_text_fmt(lv_obj_get_child(temps, 0), "%.1f°C", data->previsions.max); lv_label_set_text_fmt(lv_obj_get_child(temps, 1), "%.1f°C", data->previsions.min); } // Callback pour mettre à jour une météo horaire // On pointe sur un tableau de meteoforecast_data static void weatherdataH_obs_cb(lv_observer_t *observer, lv_subject_t *subject) { ESP_LOGE(TAG, "CB meteo horaire declenché"); // Retrieve weatherdata const struct meteoforecast_data *data = subject->value.pointer; //printffd(data); //char buff[40] = {}; // sprintf(buff,"%s %.1f %.1f", data->previsions.desc, data->previsions.min, data->previsions.max); lv_obj_t *parent = (lv_obj_t *)(observer->target); lv_obj_t *datefld = lv_obj_get_child(parent, 0); lv_obj_t *temp_desc_icon = lv_obj_get_child(parent, 1); showMeteoIcon(data->previsions.icon, temp_desc_icon, 1); char buffer[80]; dtHToString(data->datetime,buffer); lv_label_set_text(datefld, buffer); lv_label_set_text(lv_obj_get_child(temp_desc_icon, 2), data->previsions.desc); lv_label_set_text_fmt(lv_obj_get_child(temp_desc_icon, 0), "%.1f°C", data->previsions.value); } void showMeteoIcon(const char *icon, lv_obj_t *desc_icon, int childNr) { lv_obj_t* img = lv_obj_get_child(desc_icon, childNr); if (strcmp(icon, "p1j") == 0) { lv_image_set_src(img, &p1j); } else if (strcmp(icon, "p2j") == 0) { lv_image_set_src(img, &p2j); } else if (strcmp(icon, "p3j") == 0) { lv_image_set_src(img, &p3j); } else if (strcmp(icon, "p4j") == 0) { lv_image_set_src(img, &p4j); } else if (strcmp(icon, "p5bisj") == 0) { lv_image_set_src(img, &p5bisj); } else if (strcmp(icon, "p12j") == 0) { lv_image_set_src(img, &p12j); } else if (strcmp(icon, "p12bisj") == 0) { lv_image_set_src(img, &p12bisj); } else if (strcmp(icon, "p13j") == 0) { lv_image_set_src(img, &p13j); } else if (strcmp(icon, "p13bisj") == 0) { lv_image_set_src(img, &p13bisj); } else if (strcmp(icon, "p14j") == 0) { lv_image_set_src(img, &p14j); } else if (strcmp(icon, "p24j") == 0) { lv_image_set_src(img, &p24j); } else if (strcmp(icon, "p25j") == 0) { lv_image_set_src(img, &p25j); } else if (strcmp(icon, "p26j") == 0) { lv_image_set_src(img, &p26j); } else if (strcmp(icon, "p27j") == 0) { lv_image_set_src(img, &p27j); } else if (strcmp(icon, "p28j") == 0) { lv_image_set_src(img, &p28j); } else if (strcmp(icon, "p29j") == 0) { lv_image_set_src(img, &p29j); } else { ESP_LOGE(TAG, "Image %s non connue", icon); } } /* ------------------------------------------------------------ */ /* Fragment meteo journaliere (date,icone, min et max) */ /* ------------------------------------------------------------ */ // Structure meteo journaliere struct weatherDay_fragment_t { /* IMPORTANT: don't miss this part */ lv_fragment_t base; /* States, object references and data fields for this fragment */ int dayNr; bool showTitle; const char *title; float minTemp; float maxTemp; }; //Constructeur meteo journaliere static void weatherDay_fragment_ctor(lv_fragment_t *self, void * args) { int dayNo = ((int *)args)[0]; bool showDate = ((int*)args)[1]; ((struct weatherDay_fragment_t *)self)->dayNr = dayNo; ((struct weatherDay_fragment_t *)self)->showTitle = showDate; ESP_LOGI(TAG, "Fragment initialisé avec le jour n°%d - Afficher la date %d",dayNo, showDate); } // Ce fragment affiche une prévision journaliere (date,icone, min et max) static lv_obj_t *weatherDay_fragment_create_obj(lv_fragment_t *self, lv_obj_t *parent) { lv_obj_t *sup = lv_obj_create(parent); lv_obj_t *title = lv_label_create(sup); lv_label_set_text(title, "--"); lv_obj_set_flex_flow(sup, LV_FLEX_FLOW_ROW); lv_obj_add_style(sup, &style_container, 0); lv_obj_set_size(sup, LV_SIZE_CONTENT, LV_SIZE_CONTENT); lv_obj_t *container = lv_obj_create(sup); lv_obj_set_flex_flow(container, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(container,LV_FLEX_ALIGN_CENTER,LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_add_style(container, &no_padding, 0); lv_obj_set_width(container, 100); lv_obj_set_height(container, 80); lv_obj_t *img1 = lv_image_create(container); lv_obj_add_style(img1, &no_padding, 0); lv_obj_set_style_bg_color(img1,lv_palette_lighten(LV_PALETTE_BLUE_GREY, 4),0); lv_image_set_inner_align(img1, LV_IMAGE_ALIGN_TOP_LEFT); lv_image_set_offset_y(img1, -8); lv_image_set_offset_x(img1, -5); lv_obj_set_size(img1,40,32); 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); lv_obj_t *desc = lv_label_create(container); lv_label_set_text(desc,"--"); lv_obj_add_style(desc, &style_font_12, 0); lv_obj_t *container2 = lv_obj_create(sup); lv_obj_set_width(container2, LV_SIZE_CONTENT); lv_obj_set_height(container2, 80); lv_obj_add_style(container2, &no_padding, 0); lv_obj_set_style_pad_top(container2,5,0); lv_obj_set_style_pad_bottom(container2,5,0); lv_obj_set_flex_flow(container2, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(container2, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); static lv_style_t tempStyle; lv_style_init(&tempStyle); //lv_style_set_text_font(&tempStyle,¬omedium16); lv_obj_t *max = lv_label_create(container2); lv_label_set_text(max,"--"); lv_obj_add_style(max, &tempStyle,0); lv_obj_add_style(max, &style_font_18, 0); lv_obj_set_style_text_color(max,lv_color_hex(0xFF0000),0); lv_obj_add_style(max, &style_font_18, 0); lv_obj_t *min = lv_label_create(container2); lv_label_set_text(min,"--"); lv_obj_add_style(min, &tempStyle,0); lv_obj_add_style(min, &style_font_18, 0); lv_obj_set_style_text_color(min,lv_color_hex(0x3000FF),0); lv_obj_add_style(min, &style_font_18, 0); // On positionne un observer sur le subjet correspondant au jour du widget lv_subject_add_observer_obj(tmpSubj[((struct weatherDay_fragment_t *)self)->dayNr], weatherdata_obs_cb, sup, NULL); return container; } // Fragment meteo journaliere const lv_fragment_class_t meteoFragment = { /* Initialize something needed */ .constructor_cb = weatherDay_fragment_ctor, /* Create view objects */ .create_obj_cb = weatherDay_fragment_create_obj, /* IMPORTANT: size of your fragment struct */ .instance_size = sizeof(struct weatherDay_fragment_t), }; /* ------------------------------------------------------------ */ /* Fragment meteo horaire ("heure",icone, temp) */ /* ------------------------------------------------------------ */ // Structure meteo horaire struct weatherH_fragment_t { /* IMPORTANT: don't miss this part */ lv_fragment_t base; /* States, object references and data fields for this fragment */ int horaireNr; bool showTitle; const char *horaire; float temp; }; //Constructeur meteo horaire static void weatherH_fragment_ctor(lv_fragment_t *self, void * args) { // Represente le n° (index dans le tableau) a afficher int horaireNr = ((int *)args)[0]; bool showDate = ((int*)args)[1]; ((struct weatherH_fragment_t *)self)->horaireNr = horaireNr; ((struct weatherH_fragment_t *)self)->showTitle = showDate; ESP_LOGI(TAG, "Fragment initialisé avec l'horaire %d",horaireNr); } // Ce fragment affiche une prévision horaire (date,icone, temp moyenne) static lv_obj_t *weatherH_fragment_create_obj(lv_fragment_t *self, lv_obj_t *parent) { lv_obj_t *sup = lv_obj_create(parent); lv_obj_t *title = lv_label_create(sup); lv_label_set_text(title, "--"); lv_obj_set_flex_flow(sup, LV_FLEX_FLOW_ROW); lv_obj_add_style(sup, &style_container, 0); lv_obj_set_size(sup, LV_SIZE_CONTENT, LV_SIZE_CONTENT); lv_obj_t *container = lv_obj_create(sup); lv_obj_set_flex_flow(container, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(container,LV_FLEX_ALIGN_CENTER,LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_add_style(container, &no_padding, 0); lv_obj_set_width(container, 100); lv_obj_set_height(container, LV_SIZE_CONTENT); static lv_style_t tempStyle; lv_style_init(&tempStyle); //lv_style_set_text_font(&tempStyle,¬omedium16); lv_obj_t *temp = lv_label_create(container); lv_label_set_text(temp,"--"); lv_obj_add_style(temp, &tempStyle,0); lv_obj_add_style(temp, &style_font_18, 0); //lv_obj_set_style_text_color(temp,lv_color_hex(0xFF0000),0); lv_obj_add_style(temp, &style_font_18, 0); lv_obj_t *img1 = lv_image_create(container); lv_obj_add_style(img1, &no_padding, 0); lv_obj_set_style_bg_color(img1,lv_palette_lighten(LV_PALETTE_BLUE_GREY, 4),0); lv_image_set_inner_align(img1, LV_IMAGE_ALIGN_TOP_LEFT); lv_image_set_offset_y(img1, -8); lv_image_set_offset_x(img1, -5); lv_obj_set_size(img1,40,32); 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); lv_obj_t *desc = lv_label_create(container); lv_label_set_text(desc,"--"); lv_obj_add_style(desc, &style_font_12, 0); // On positionne un observer sur le subjet correspondant a l'horaire du widget ESP_LOGE(TAG, "on positionne obs sur horaire %d", ((struct weatherH_fragment_t *)self)->horaireNr); lv_subject_add_observer_obj(tmpHSubj[((struct weatherH_fragment_t *)self)->horaireNr], weatherdataH_obs_cb, sup, NULL); return container; } // Fragment meteo horaire const lv_fragment_class_t meteoHFragment = { /* Initialize something needed */ .constructor_cb = weatherH_fragment_ctor, /* Create view objects */ .create_obj_cb = weatherH_fragment_create_obj, /* IMPORTANT: size of your fragment struct */ .instance_size = sizeof(struct weatherH_fragment_t), }; /* -------------------------------------------------------------- */ /* Fragment 3 meteo "jour" (aujourd'hui, demain, apres demain) */ /* -------------------------------------------------------------- */ struct meteodailyforecast_fragment_t { /* IMPORTANT: don't miss this part */ lv_fragment_t base; /* States, object references and data fields for this fragment */ const char *title; bool showDate; }; static void meteodailyforecast_fragment_ctor(lv_fragment_t * self, void * args){ struct meteodailyforecast_fragment_t *myself=((struct meteodailyforecast_fragment_t *) self); myself->showDate = args; } static lv_obj_t * meteodailyforecast_fragment_create_obj(lv_fragment_t * self, lv_obj_t * parent) { lv_fragment_manager_t *manager = lv_fragment_manager_create(NULL); int args[2]={0,((struct meteodailyforecast_fragment_t*)self)->showDate}; lv_fragment_t *fragment = lv_fragment_create(&meteoFragment, args); lv_fragment_manager_add(manager, fragment, &parent); args[0]=1; fragment = lv_fragment_create(&meteoFragment, args); lv_fragment_manager_add(manager, fragment, &parent); args[0]=2; fragment = lv_fragment_create(&meteoFragment, args); lv_fragment_manager_add(manager, fragment, &parent); return parent; } const lv_fragment_class_t meteodailyforecast_cls = { /* Initialize something needed */ .constructor_cb = meteodailyforecast_fragment_ctor, /* Create view objects */ .create_obj_cb = meteodailyforecast_fragment_create_obj, /* IMPORTANT: size of your fragment struct */ .instance_size = sizeof(struct meteodailyforecast_fragment_t), }; /* -------------------------------------------------------------------------------- */ /* Fragment 3 meteo "horaire" - matin/midi/soir (icone, temp moyenne) */ /* -------------------------------------------------------------------------------- */ struct meteoforecast_fragment_t { /* IMPORTANT: don't miss this part */ lv_fragment_t base; /* States, object references and data fields for this fragment */ const char *title; bool showDate; }; static void meteoforecast_fragment_ctor(lv_fragment_t * self, void * args){ struct meteoforecast_fragment_t *myself=((struct meteoforecast_fragment_t *) self); myself->showDate = args; } static lv_obj_t * meteoforecast_fragment_create_obj(lv_fragment_t * self, lv_obj_t * parent) { lv_fragment_manager_t *manager = lv_fragment_manager_create(NULL); // On affiche 3 fragment meteo. 1 pour chaque "horaire" int args[2]={0,((struct meteoforecast_fragment_t*)self)->showDate}; lv_fragment_t *fragment = lv_fragment_create(&meteoHFragment, args); lv_fragment_manager_add(manager, fragment, &parent); args[0]=1; fragment = lv_fragment_create(&meteoHFragment, args); lv_fragment_manager_add(manager, fragment, &parent); args[0]=2; fragment = lv_fragment_create(&meteoHFragment, args); lv_fragment_manager_add(manager, fragment, &parent); return parent; } const lv_fragment_class_t meteoforecast_cls = { /* Initialize something needed */ .constructor_cb = meteoforecast_fragment_ctor, /* Create view objects */ .create_obj_cb = meteoforecast_fragment_create_obj, /* IMPORTANT: size of your fragment struct */ .instance_size = sizeof(struct meteoforecast_fragment_t), }; struct lv_event_t { void * current_target; void * original_target; lv_event_code_t code; void * user_data; void * param; lv_event_t * prev; uint8_t deleted : 1; uint8_t stop_processing : 1; uint8_t stop_bubbling : 1; }; lv_obj_t * tab1; lv_obj_t * tab2b; lv_obj_t * tab3; lv_obj_t * tab4; static void tabChgEvt(lv_event_t * event) { uint32_t tabNr = lv_tabview_get_tab_active(event->user_data); printf("Tab change %lu\n", tabNr); switch (tabNr) { case 1: lv_obj_t * tab2=lv_obj_create(tab2b); lv_obj_set_flex_flow(tab2, LV_FLEX_FLOW_COLUMN); lv_obj_add_style(tab2,&no_padding,0); lv_obj_set_size(tab2, lv_pct(85),lv_pct(100)); lv_obj_t * cont_rdc=lv_obj_create(tab2); lv_obj_set_size(cont_rdc,lv_pct(100), lv_pct(100)); lv_obj_add_style(cont_rdc,&no_padding,0); lv_obj_add_style(tab2,&no_padding,0); lv_point_t positions_rdc[]={ {5,105}, {55,45}, {110,20}, {155,25}, {225,45}, {275,115}, {295,185}}; lv_obj_t * img=lv_image_create(cont_rdc); lv_img_set_src(img, &plan_rdc); float coef=1.5; for (size_t i = 1; i < 8; i++) { lv_obj_t * btnVolet = lv_checkbox_create(cont_rdc); lv_obj_set_pos(btnVolet,positions_rdc[i-1].x*coef,positions_rdc[i-1].y*coef); lv_obj_add_style(btnVolet,&style_font_24,0); //lv_obj_set_size(btnVolet,100,24); //char *nom[10]; //sprintf(nom,"%d", i); lv_checkbox_set_text(btnVolet,""); } lv_obj_t * cont_btn_volets=lv_obj_create(tab2b); lv_obj_add_style(cont_btn_volets,&no_padding,0); lv_obj_set_size(cont_btn_volets,lv_pct(15), lv_pct(100)); lv_obj_set_layout(cont_btn_volets, LV_LAYOUT_GRID); static int32_t column_dsc[] = {LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST}; /*2 columns */ static int32_t row_dsc[] = {LV_GRID_FR(1),LV_GRID_FR(1),LV_GRID_FR(1),LV_GRID_FR(1),LV_GRID_FR(1),LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST}; lv_obj_set_grid_dsc_array(cont_btn_volets, column_dsc, row_dsc); lv_obj_t * btnUp_bis = lv_button_create(cont_btn_volets); lv_obj_t * lblButtonUp = lv_label_create(btnUp_bis); lv_label_set_text(lblButtonUp,LV_SYMBOL_UP); lv_obj_t * btnDwn_bis = lv_button_create(cont_btn_volets); lv_obj_t * lblButtonDwn = lv_label_create(btnDwn_bis); lv_label_set_text(lblButtonDwn,LV_SYMBOL_DOWN); lv_obj_set_grid_cell(btnUp_bis, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_STRETCH, 0, 1); lv_obj_set_grid_cell(btnDwn_bis, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_STRETCH, 1, 1); lv_obj_t * cont_etage=lv_obj_create(tab2); lv_obj_set_size(cont_etage,lv_pct(100), lv_pct(100)); lv_obj_add_style(cont_etage,&no_padding,0); img=lv_image_create(cont_etage); lv_img_set_src(img, &plan_etage); lv_point_t positions_etage[]={ {100,15}, {250,15}, {400,15}, {480,300}, {460,360}, {320,415}}; for (size_t i = 1; i < 7; i++) { lv_obj_t * btnVolet = lv_checkbox_create(cont_etage); lv_obj_set_pos(btnVolet,positions_etage[i-1].x,positions_etage[i-1].y); lv_obj_add_style(btnVolet,&style_font_24,0); //lv_obj_set_size(btnVolet,100,24); //char *nom[10]; //sprintf(nom,"%d", i); lv_checkbox_set_text(btnVolet,""); } case 2: // Onglet Météo lv_fragment_manager_t *manager2 = lv_fragment_manager_create(NULL); lv_fragment_t *fragment2 = lv_fragment_create(&meteodailyforecast_cls, (void *)1); lv_fragment_manager_add(manager2, fragment2, &tab3); break; case 3: // Onglet températures lv_obj_t * imgGraf = lv_image_create(tab4); lv_image_set_src(imgGraf, "A:/sdcard/hello2.png"); break; default: break; } } /* ------------------------------------------------------------ */ /* Dessin IHM */ /* ------------------------------------------------------------ */ void draw_ihm() { lv_subject_init_string(&tempExtSubj, tempExtStr, NULL, 6, "--"); lv_subject_init_string(&tempIntSubj, tempIntStr, NULL, 6, "--"); lv_subject_init_string(&hauteurCuveSubj, hauteurCuveStr, NULL, 9, "--"); lv_subject_init_string(&hauteurCuveEvolSubj, hauteurCuveEvolStr, NULL, 9, "--"); struct meteodailyforecast_data d; struct dailyforecast_prev p; lv_strcpy(p.desc,""); d.previsions = p; lv_subject_init_pointer(&forecastD1Subj, &d); lv_subject_init_pointer(&forecastD2Subj, &d); lv_subject_init_pointer(&forecastD3Subj, &d); struct meteoforecast_data d1; struct forecast_prev p1; lv_strcpy(p1.desc,""); d1.previsions = p1; lv_subject_init_pointer(&forecastH1Subj, &d1); lv_subject_init_pointer(&forecastH2Subj, &d1); lv_subject_init_pointer(&forecastH3Subj, &d1); // keys.clear(); lv_obj_clean(lv_scr_act()); /*Create a Tab view object*/ lv_obj_t * tabview; tabview = lv_tabview_create(lv_screen_active()); lv_tabview_set_tab_bar_position(tabview, LV_DIR_LEFT); lv_tabview_set_tab_bar_size(tabview, 80); lv_obj_add_event_cb(tabview, tabChgEvt, LV_EVENT_VALUE_CHANGED, tabview); /* Assign an event callback */ lv_obj_set_style_bg_color(tabview, lv_palette_lighten(LV_PALETTE_RED, 2), 0); lv_obj_t * tab_buttons = lv_tabview_get_tab_bar(tabview); lv_obj_set_width(tab_buttons,100); lv_obj_set_style_text_font(tab_buttons, &montserrat_medium_18, 0); lv_obj_set_style_bg_color(tab_buttons, lv_palette_darken(LV_PALETTE_GREY, 3), 0); lv_obj_set_style_text_color(tab_buttons, lv_palette_lighten(LV_PALETTE_GREY, 5), 0); lv_obj_set_style_border_side(tab_buttons, LV_BORDER_SIDE_RIGHT, LV_PART_ITEMS | LV_STATE_CHECKED); /*Add 3 tabs (the tabs are page (lv_page) and can be scrolled*/ tab1 = lv_tabview_add_tab(tabview, LV_SYMBOL_HOME); tab2b = lv_tabview_add_tab(tabview, "Volets"); tab3 = lv_tabview_add_tab(tabview, "Météo"); tab4 = lv_tabview_add_tab(tabview, "Températures"); /*lv_obj_t * tab5 = */lv_tabview_add_tab(tabview, "Cuve"); lv_obj_set_style_bg_color(tab2b, lv_palette_lighten(LV_PALETTE_AMBER, 3), 0); lv_obj_set_style_bg_opa(tab2b, LV_OPA_COVER, 0); static lv_style_t style_btn; lv_style_init(&style_btn); lv_style_init(&style_font_18); lv_style_set_text_font(&style_font_18, &montserrat_medium_18); lv_style_init(&style_font_24); lv_style_set_text_font(&style_font_24, &montserrat_medium_24); lv_style_init(&style_font_12); lv_style_set_text_font(&style_font_12, &montserrat_medium_12); // lv_style_set_bg_color(&style_btn, lv_color_hex(0x115588)); // lv_style_set_bg_opa(&style_btn, LV_OPA_50); // lv_style_set_border_width(&style_btn, 2); // lv_style_set_border_color(&style_btn, lv_color_black()); lv_style_set_width(&style_btn, 80); lv_style_set_height(&style_btn, 100); // Un style pour les conteneurs (température, cuve ...) lv_style_init(&style_container); lv_style_set_pad_all(&style_container, 5); // lv_style_set_height(&style_container,LV_SIZE_CONTENT); lv_style_set_height(&style_container, 80); lv_style_set_width(&style_container, 200); lv_style_set_bg_color(&style_container, lv_palette_lighten(LV_PALETTE_BLUE_GREY, 4)); 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_style_set_text_font(&style_lbvValue, &lv_font_montserrat_40); lv_obj_t *supmain = tab1; lv_obj_set_flex_flow(supmain, LV_FLEX_FLOW_COLUMN); lv_obj_t *main = lv_obj_create(supmain); lv_obj_add_style(main,&no_padding,0); lv_obj_set_size(main,LV_SIZE_CONTENT,LV_SIZE_CONTENT); 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(main); lv_obj_set_style_pad_all(cont_col, 5, 0); lv_obj_set_size(cont_col, 250, 400); lv_obj_align(cont_col, LV_ALIGN_TOP_LEFT, 0, 0); lv_obj_set_flex_flow(cont_col, LV_FLEX_FLOW_COLUMN); 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(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); /*Create a container with COLUMN flex direction*/ lv_obj_t *cont_col3 = lv_obj_create(main); lv_obj_set_style_pad_all(cont_col3, 5, 0); lv_obj_set_size(cont_col3, 300, 400); lv_obj_set_flex_flow(cont_col3, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(cont_col3, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_height(cont_col2, 400); lv_obj_set_width(cont_col2, LV_SIZE_CONTENT); lv_obj_align_to(cont_col2, cont_col, LV_ALIGN_OUT_TOP_RIGHT, 0, 0); lv_obj_set_flex_flow(cont_col2, LV_FLEX_FLOW_COLUMN); lv_obj_t *label1 = lv_label_create(cont_col); lv_obj_set_style_text_font(label1, &montserrat_medium_18,0); lv_label_set_text(label1, "Températures"); lv_obj_set_pos(label1, 0, 0); /*Create a container with COLUMN flex direction*/ lv_obj_t *cont_tempExt = lv_obj_create(cont_col); lv_obj_add_style(cont_tempExt, &style_container, 0); // lv_obj_set_height(cont_tempExt,50); lv_obj_set_flex_flow(cont_tempExt, LV_FLEX_FLOW_ROW); lv_obj_t *lblExt = lv_label_create(cont_tempExt); lv_label_set_text(lblExt, "ext."); lv_obj_t *lblTempExt = lv_label_create(cont_tempExt); lv_obj_add_style(lblTempExt, &style_lbvValue, 0); lv_label_set_text(lblTempExt, ""); lv_label_bind_text(lblTempExt, &tempExtSubj, "%s °C"); /*Create a container with COLUMN flex direction*/ lv_obj_t *cont_tempInt = lv_obj_create(cont_col); lv_obj_add_style(cont_tempInt, &style_container, 0); // lv_obj_set_height(cont_tempInt,50); lv_obj_set_flex_flow(cont_tempInt, LV_FLEX_FLOW_ROW); lv_obj_t *lblInt = lv_label_create(cont_tempInt); lv_label_set_text(lblInt, "int."); lv_obj_t *lblTempInt = lv_label_create(cont_tempInt); lv_obj_add_style(lblTempInt, &style_lbvValue, 0); lv_label_set_text(lblTempInt, ""); lv_label_bind_text(lblTempInt, &tempIntSubj, "%s °C"); /*Create a container with COLUMN flex direction*/ lv_obj_t *cont_Cuve = lv_obj_create(cont_col); lv_obj_add_style(cont_Cuve, &style_container, 0); lv_obj_set_flex_flow(cont_Cuve, LV_FLEX_FLOW_ROW_WRAP); // lv_obj_set_height(cont_Cuve,80); lv_obj_t *lblHauteurEau = lv_label_create(cont_Cuve); lv_label_set_text(lblHauteurEau, "Cuve: "); lv_obj_t *lblHauteurCuve = lv_label_create(cont_Cuve); lv_obj_add_style(lblHauteurCuve, &style_lbvValue, 0); lv_label_bind_text(lblHauteurCuve, &hauteurCuveSubj, "%s cm"); lv_obj_t *btnUp = lv_button_create(cont_col2); lv_obj_add_style(btnUp, &style_btn, 0); lv_obj_add_event_cb(btnUp, event_handler, LV_EVENT_ALL, upEvent); lv_obj_align(btnUp, LV_ALIGN_CENTER, 0, -40); lv_obj_remove_flag(btnUp, LV_OBJ_FLAG_PRESS_LOCK); lv_obj_t *label = lv_label_create(btnUp); lv_obj_add_style(label, &style_lbvValue, 0); lv_label_set_text(label, LV_SYMBOL_UP); lv_obj_center(label); lv_obj_t *btnDwn = lv_button_create(cont_col2); lv_obj_add_style(btnDwn, &style_btn, 0); lv_obj_add_event_cb(btnDwn, event_handler, LV_EVENT_ALL, downEvent); lv_obj_align(btnDwn, LV_ALIGN_CENTER, 0, -40); lv_obj_remove_flag(btnDwn, LV_OBJ_FLAG_PRESS_LOCK); label = lv_label_create(btnDwn); lv_obj_add_style(label, &style_lbvValue, 0); lv_label_set_text(label, LV_SYMBOL_DOWN); lv_obj_center(label); lv_fragment_manager_t *manager = lv_fragment_manager_create(NULL); lv_fragment_t *fragment = lv_fragment_create(&meteoforecast_cls, 0); lv_fragment_manager_add(manager, fragment, &cont_col3); lv_obj_set_flex_flow(tab2b, LV_FLEX_FLOW_ROW); lv_obj_set_flex_flow(tab3, LV_FLEX_FLOW_COLUMN); } void weather_data_retreived_start() { if(lvgl_port_lock(0)){ lv_subject_set_int(&meteoStatus,1); lvgl_port_unlock(); } } 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.min); printf("%lld\n", datas[1].datetime); printf("%s\n", datas[1].previsions.desc); printf("%f\n", datas[1].previsions.min); printf("%lld\n", datas[2].datetime); printf("%s\n", datas[2].previsions.desc); printf("%f\n", datas[2].previsions.min); ESP_LOGE(TAG, "fin debug"); */ if (lvgl_port_lock(0)) { ESP_LOGE(TAG, "------------------------------------- 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_LOGE(TAG, "------------------------------------- Set des subjects H--------------------------------"); //Prévisions des 3 prochains jours ESP_LOGE(TAG,"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); lvgl_port_unlock(); //ESP_LOGE(TAG, "------------------------------------- Fin Set des subjects --------------------------------"); } } 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); } void app_main(void){ esp_log_level_set("wifi", ESP_LOG_ERROR); mount_sd_card(); /* LCD HW initialization */ ESP_ERROR_CHECK(app_lcd_init()); /* Touch initialization */ ESP_ERROR_CHECK(app_touch_init()); /* LVGL initialization */ ESP_ERROR_CHECK(app_lvgl_init()); /* On affiche au plus tot l'ecran de démarrage */ if(lvgl_port_lock(0)){ //ESP_ERROR_CHECK(esp_lcd_panel_mirror(lcd_panel,true,true)); app_main_display(); lvgl_port_unlock(); } // 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); lv_subject_init_int(&wifiStatus,-1); lv_subject_init_int(&mqttStatus,-1); lv_subject_init_int(&meteoStatus,-1); ESP_LOGI(TAG, "ESP_WIFI_MODE_STA"); wifi_init_sta(); //mqtt_app_start(); 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("Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize()); heap_caps_print_heap_info(MALLOC_CAP_DEFAULT); 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"); ESP_LOGW(TAG, "On telecharge l'image cuve"); TaskHandle_t xHandle = NULL; BaseType_t ret1 = xTaskCreate(&imgdwn, "imageDownload_task", 5 * 1024, NULL, 5, &xHandle); if(ret1!=pdPASS ){ ESP_LOGE(TAG, "Impossiblke de creer la tache %i", ret1); } /* Show LVGL objects */ if(lvgl_port_lock(0)){ draw_ihm(); //lv_disp_set_rotation(lvgl_disp, LV_DISPLAY_ROTATION_180); lvgl_port_unlock(); } }