#include "bsp/display.h" #include "bsp_board_extra.h" #include "lv_theme_domotic.h" #include "esp_lvgl_port.h" #include "ihm.h" #include "misc/lv_types.h" #include "esp_log.h" #include "string.h" #include "meteofrance.h" #include "main.h" #include "bsp/esp-bsp.h" #define upEvent "monter" #define downEvent "descendre" lv_subject_t dateHeureSubj; lv_obj_t *lblTempInt2; 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}; lv_subject_t meteoStatus; char dateHeureStr[30]; static lv_style_t no_padding; static const char *TAG = "IHM"; static lv_subject_t wifiStatus; LV_IMAGE_DECLARE(wifi_ok); LV_IMAGE_DECLARE(wifi_ko); static void wifiStatus_obs_cb(lv_observer_t * observer, lv_subject_t * subject) { ESP_LOGE(TAG, "On passe dans le callback de chgt de statut; %li", lv_subject_get_int(subject)); bsp_display_lock(0); if(lv_layer_top()!=NULL && lv_obj_get_child_cnt(lv_layer_top())){ lv_obj_t * wifiSt = lv_obj_get_child(lv_obj_get_child(lv_layer_top(), 0),2); if(lv_obj_check_type(wifiSt, &lv_image_class)){ switch (lv_subject_get_int(subject)) { case 0: lv_image_set_src(wifiSt,&wifi_ko); break; case 1: lv_image_set_src(wifiSt,&wifi_ok); break; default: break; } }else{ ESP_LOGE(TAG, "L'objet recuip en semble pas etre du bon type"); } }else{ ESP_LOGI(TAG,"Pour le moment l'icone de statut n'existe pas"); } bsp_display_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 drawIhm(void *xIHMEventQueue){ init_display(); lv_subject_init_int(&wifiStatus,0); lv_subject_add_observer_obj(&wifiStatus, wifiStatus_obs_cb, NULL, NULL); display_lock("app_main"); app_main_display(); display_unlock("app_main"); // 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"); } while (1) { xIPStackEvent_t xReceivedEvent; // On cree une queue qui va permettre de recevoir les informations a afficher xQueueReceive(xIHMEventQueue,&xReceivedEvent, portMAX_DELAY ); switch (xReceivedEvent.eEventType) { case IHM_EVT_WIFI_STATUS: ESP_LOGE(TAG, "On a recu un evt wifi"); lv_subject_set_int(&wifiStatus, (int)xReceivedEvent.pvData); break; case IHM_EVT_TIME_SETTED: ESP_LOGE(TAG, "On a recu un evt timesetted"); draw_time(xReceivedEvent.pvData); break; default: ESP_LOGE(TAG, "Evt inconnu"); break; }; vTaskDelay(5/portTICK_PERIOD_MS); } } void draw_time(char* dateHeure){ if(display_lock("updateTime")){ lv_subject_copy_string(&dateHeureSubj, dateHeure); display_unlock("updateTime"); } } void draw_temp(char * tempHumid){ if(lvgl_port_lock(5)){ lv_label_set_text(lblTempInt2,tempHumid); lvgl_port_unlock(); } } 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; } } void init_display(){ lvgl_port_cfg_t cfgLVGL = { .task_priority = 4, .task_stack = 7168, .task_affinity = 1, // On se met sur le core 1 .task_max_sleep_ms = 500, .timer_period_ms = 5, }; bsp_display_cfg_t cfg = { //.lvgl_port_cfg = ESP_LVGL_PORT_INIT_CONFIG(), .lvgl_port_cfg = cfgLVGL, .buffer_size = BSP_LCD_DRAW_BUFF_SIZE, .double_buffer = BSP_LCD_DRAW_BUFF_DOUBLE, .flags = { .buff_dma = true, .buff_spiram = false, .sw_rotate = false, } }; ESP_LOGE(TAG,"On demarre le display"); lv_display_t *dsp = bsp_display_start_with_config(&cfg); //bsp_display_rotate(dsp,LV_DISP_ROTATION_180); bsp_display_brightness_set(50); bsp_display_backlight_on(); mainState.display_init=true; } void app_main_display() { lv_subject_init_int(&meteoStatus, -1); struct meteodailyforecast_data d; struct dailyforecast_prev p; lv_strcpy(p.desc, ""); d.previsions = p; d.isValid=false; 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; d1.isValid=false; lv_subject_init_pointer(&forecastH1Subj, &d1); lv_subject_init_pointer(&forecastH2Subj, &d1); lv_subject_init_pointer(&forecastH3Subj, &d1); lv_theme_t * th = lv_theme_domotic_init(lv_display_get_default()); lv_display_set_theme(lv_disp_get_default(), th); /* Assign theme to display */ lv_subject_init_string(&dateHeureSubj, dateHeureStr, NULL, 64, "--"); lv_style_init(&no_padding); lv_style_set_pad_all(&no_padding, 0); static const lv_color_t grad_colors[2] = { LV_COLOR_MAKE(0x9B, 0x18, 0x42), LV_COLOR_MAKE(0x00, 0x00, 0x00), }; static lv_style_t style_gradient; lv_style_init(&style_gradient); /*First define a color gradient. In this example we use a purple to black color map.*/ static lv_grad_dsc_t grad; ESP_LOGE(TAG,"On aimerait %d stops", sizeof(grad_colors) / sizeof(lv_color_t)); lv_gradient_init_stops(&grad, grad_colors, NULL, NULL, sizeof(grad_colors) / sizeof(lv_color_t)); /*Make a radial gradient with the center in the middle of the object, extending to the farthest corner*/ lv_grad_radial_init(&grad, LV_GRAD_CENTER, LV_GRAD_CENTER, LV_GRAD_RIGHT, LV_GRAD_BOTTOM, LV_GRAD_EXTEND_PAD); /*Set gradient as background*/ lv_style_set_bg_grad(&style_gradient, &grad); 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_set_style_text_font(jour,lv_theme_get_font_normal(jour),0); lv_obj_set_width(jour, LV_SIZE_CONTENT); lv_label_bind_text(jour, &dateHeureSubj, NULL); lv_obj_refr_size(cont_status); // lv_obj_align(jour, LV_ALIGN_CENTER,0,0); lv_obj_t *meteoR = lv_label_create(cont_status); lv_obj_set_style_text_font(meteoR,lv_theme_get_font_normal(jour),0); lv_label_set_text(meteoR, "\xEF\x83\x82"); lv_obj_set_style_text_color(meteoR, lv_color_make(0x00, 0xff, 0xff), 0); lv_subject_add_observer_obj(&meteoStatus, meteo_obs_cb, meteoR, NULL); // lv_label_bind_text(meteoR, &meteoStatus, "Meteo %d"); /*lv_obj_t *wifi =*/ lv_image_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_image_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(); lv_obj_add_style(scr, &style_gradient, 0); /* Your LVGL objects code here .... */ /* Label */ lv_obj_t *label = lv_label_create(scr); lv_obj_set_width(label, lv_pct(100)); lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0); lv_obj_set_style_text_font(label,lv_theme_get_font_large(label),0); lv_label_set_text(label, LV_SYMBOL_BELL "Bienvenue sur DomoTIC !" LV_SYMBOL_BELL); lv_obj_align(label, LV_ALIGN_CENTER, 0, 20); } bool display_lock(const char* TAG){ ESP_LOGI(TAG,"Obtention mutexx"); if(bsp_display_lock(5000)){ ESP_LOGI(TAG, "Mutex obtenu"); return true; }else{ ESP_LOGE(TAG, "Impossible d'obtenir le mutex"); return false; } } void display_unlock(const char* TAG){ ESP_LOGI(TAG,"Libération mutexx"); bsp_display_unlock(); } // Ce callback est applé lorsque meteoStatus change void meteo_obs_cb(lv_observer_t *observer, lv_subject_t *subject) { ESP_LOGI(TAG, "On passe dans le callback de chgt de statut meteo; %li", lv_subject_get_int(subject)); if (display_lock("meteo_obs_cb")) { lv_obj_t *meteoSt = observer->target; switch (lv_subject_get_int(subject)) { case 0: lv_obj_set_style_text_color(meteoSt, lv_color_make(0x00, 0xff, 0xff), 0); break; case 1: lv_obj_set_style_text_color(meteoSt, lv_color_make(0xff, 0x00, 0x00), 0); break; } display_unlock("meteo_obs_cb"); }else{ ESP_LOGE(TAG,"Impossible d'obtenir le mutex dans meteo_obs_cb"); } } LV_IMAGE_DECLARE(plan_rdc); LV_IMAGE_DECLARE(plan_etage); static lv_style_t style_container; // 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) { // Retrieve weatherdata const struct meteodailyforecast_data *data = subject->value.pointer; ESP_LOGE(TAG, "CB meteo jour declenché. Meteo valide : %i", data->isValid); // printffd(data); // char buff[40] = {}; // sprintf(buff,"%s %.1f %.1f", data->previsions.desc, data->previsions.min, data->previsions.max); if(data->isValid){ 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_LOGV("MeteoFrance", "CB meteo horaire declenché"); // Retrieve weatherdata const struct meteoforecast_data *data = subject->value.pointer; if(data->isValid){ //printffd(data); char buff[40] = {}; sprintf(buff,"%.1f", data->previsions.value); ESP_LOGV(TAG, "On a recu [%s]", buff); 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); }else{ ESP_LOGE(TAG, "Pas de odnnées valides"); } } void showMeteoIcon(const char *icon, lv_obj_t *desc_icon, int childNr) { lv_obj_t *img = lv_obj_get_child(desc_icon, childNr); char *str1 = "A:/littlefs/"; char *result = malloc(strlen(str1) + strlen(icon) + 6); sprintf(result, "%s%s.png", str1, icon); ESP_LOGE(TAG,"On affiche l'image %s", result); lv_image_set_src(img, result); free(result); } // Ce fragment affiche une prévision journaliere (date,icone, min et max) static lv_obj_t* weatherDay_fragment_create_obj(int dayNr, 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, 150); 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_set_style_text_font(desc, lv_theme_get_font_normal(desc),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_set_style_text_font(max,lv_theme_get_font_normal(max),0); lv_obj_set_style_text_color(max, lv_color_hex(0xFF0000), 0); lv_obj_t *min = lv_label_create(container2); lv_label_set_text(min, "--"); lv_obj_add_style(min, &tempStyle, 0); lv_obj_set_style_text_font(min,lv_theme_get_font_normal(max),0); lv_obj_set_style_text_color(min, lv_color_hex(0x3000FF), 0); // On positionne un observer sur le subjet correspondant au jour du widget lv_subject_add_observer_obj(tmpSubj[dayNr], weatherdata_obs_cb, sup, NULL); return container; } // Ce fragment affiche une prévision horaire (date,icone, temp moyenne) static lv_obj_t* weatherH_fragment_create_obj(int horaireNr, 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, 150); 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_set_style_text_font(temp,lv_theme_get_font_normal(temp),0); // lv_obj_set_style_text_color(temp,lv_color_hex(0xFF0000),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_set_style_text_font(desc, lv_theme_get_font_normal(desc), 0); // On positionne un observer sur le subjet correspondant a l'horaire du widget ESP_LOGE(TAG, "on positionne obs sur horaire %d", horaireNr); lv_subject_add_observer_obj(tmpHSubj[horaireNr], weatherdataH_obs_cb, sup, NULL); return container; } uint32_t oldTab; /*void tabChgEvt(lv_event_t *event) { uint32_t tabNr = lv_tabview_get_tab_active(event->user_data); switch (oldTab) { case 1: lv_obj_clean(tabVolets); break; case 2: //lv_fragment_delete_obj(fragment2);; //lv_fragment_manager_remove(manager2,fragment2); ESP_LOGE(TAG, "On appelle lv_fragment_delete_obj sur l'onglet"); lv_fragment_delete_obj(fragment2); ESP_LOGE(TAG, "On appelle lv_fragment_manager_pop sur l'onglet"); lv_fragment_manager_pop(manager2); ESP_LOGE(TAG, "On appelle obj_clean sur l'onglet"); lv_obj_clean(tabMeteo); break; case 3: lv_obj_clean(tabCuve); break; default: break; } oldTab = tabNr; printf("Tab change %lu\n", tabNr); switch (tabNr) { case 1: draw_tabVolets(); break; case 2: // Onglet Météo draw_tabMeteo(); break; case 3: // Onglet Cuve draw_tabCuve(); break; case 4: // Onglet Settings draw_tabSettings(); break; default: break; } }*/ void btnRestart_cb(lv_event_t * e){ lv_event_code_t code = lv_event_get_code(e); if(code == LV_EVENT_CLICKED) { esp_restart(); } } static void log_event_handler(lv_event_t * e) { lv_event_code_t code = lv_event_get_code(e); lv_obj_t * obj = lv_event_get_target(e); if(code == LV_EVENT_VALUE_CHANGED) { LV_UNUSED(obj); char *tag=lv_event_get_user_data(e); if(lv_obj_has_state(obj, LV_STATE_CHECKED)){ esp_log_level_set(tag,ESP_LOG_DEBUG); }else{ esp_log_level_set(tag,ESP_LOG_INFO); } LV_LOG_USER("State for %s: %s\n", tag, lv_obj_has_state(obj, LV_STATE_CHECKED) ? "On" : "Off"); } } static lv_style_t style_lbvValue; static lv_style_t style_btn; void draw_tabSettings(lv_obj_t * parent) { lv_obj_t *btnGrp = lv_obj_create(parent); lv_obj_set_height(btnGrp, 400); lv_obj_set_flex_flow(btnGrp, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(btnGrp, LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_align(btnGrp,LV_ALIGN_BOTTOM_MID,0,0); lv_obj_t *btnRestart = lv_button_create(btnGrp); lv_obj_t *lblRestart = lv_label_create(btnRestart); lv_label_set_text(lblRestart,"Restart"); lv_obj_add_event_cb(btnRestart, btnRestart_cb, LV_EVENT_CLICKED, NULL); lv_label_set_text(lv_label_create(btnGrp),"Meteo Debug"); lv_obj_t *sw = lv_switch_create(btnGrp); lv_obj_add_state(sw, LV_STATE_DEFAULT); lv_obj_add_event_cb(sw, log_event_handler, LV_EVENT_ALL, "MeteoFrance"); lv_label_set_text(lv_label_create(btnGrp),"Cuve"); sw = lv_switch_create(btnGrp); lv_obj_add_state(sw, LV_STATE_DEFAULT); lv_obj_add_event_cb(sw, log_event_handler, LV_EVENT_ALL, "ImgDwn"); lv_label_set_text(lv_label_create(btnGrp),"MQTT"); sw = lv_switch_create(btnGrp); lv_obj_add_state(sw, LV_STATE_DEFAULT); lv_obj_add_event_cb(sw, log_event_handler, LV_EVENT_ALL, "domo_mqtt"); } lv_obj_t *tabview; static void cuve_click_cb(lv_event_t * e){ lv_tabview_set_active(tabview, 3, false); } void draw_tabHome(lv_obj_t* parent){ lv_obj_t *supmain = parent; 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_pct(100), lv_pct(100)); lv_obj_set_flex_flow(main, LV_FLEX_FLOW_ROW); lv_obj_set_style_pad_column(main, 1, 0); /*Conteneur Colonne: Températures*/ lv_obj_t *cont_colTemp = lv_obj_create(main); lv_obj_set_style_pad_all(cont_colTemp, 5, 0); lv_obj_set_size(cont_colTemp, lv_pct(40), lv_pct(100)); lv_obj_align(cont_colTemp, LV_ALIGN_TOP_LEFT, 0, 0); lv_obj_set_flex_flow(cont_colTemp, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(cont_colTemp, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); /*Create a container with COLUMN flex direction*/ lv_obj_t *cont_colVolets = lv_obj_create(main); lv_obj_set_style_pad_all(cont_colVolets, 5, 0); lv_obj_set_flex_align(cont_colVolets, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_size(cont_colVolets, lv_pct(20), lv_pct(100)); lv_obj_align_to(cont_colVolets, cont_colTemp, LV_ALIGN_OUT_TOP_RIGHT, 0, 0); lv_obj_set_flex_flow(cont_colVolets, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(cont_colVolets, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER); /*Conteneur Colonne: Meteo*/ 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, lv_pct(40), lv_pct(100)); 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_t *label1 = lv_label_create(cont_colTemp); lv_obj_set_style_text_font(label1, lv_theme_get_font_small(label1), 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_colTemp); 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_colTemp); 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_tempInt2 = lv_obj_create(cont_colTemp); lv_obj_add_style(cont_tempInt2, &style_container, 0); // lv_obj_set_height(cont_tempInt,50); lv_obj_set_flex_flow(cont_tempInt2, LV_FLEX_FLOW_ROW); lblInt = lv_label_create(cont_tempInt2); lv_label_set_text(lblInt, "int."); lblTempInt2 = lv_label_create(cont_tempInt2); lv_obj_add_style(lblTempInt2, &style_lbvValue, 0); lv_obj_set_style_text_font(lblTempInt2,lv_theme_get_font_large(lblTempInt2),0); lv_label_set_text(lblTempInt2, ""); //Create a container with COLUMN flex direction lv_obj_t *cont_Cuve = lv_obj_create(cont_colTemp); lv_obj_add_event_cb(cont_Cuve, cuve_click_cb, LV_EVENT_CLICKED, NULL); 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_colVolets); 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_colVolets); 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); weatherH_fragment_create_obj(0,cont_col3); weatherH_fragment_create_obj(1,cont_col3); weatherH_fragment_create_obj(2,cont_col3); } void draw_tabCuve(lv_obj_t* parent) { lv_obj_t *imgGraf = lv_image_create(parent); lv_image_set_src(imgGraf, "A:/sdcard/hello2.png"); } void draw_tabMeteo(lv_obj_t * parent) { weatherDay_fragment_create_obj(0,parent); weatherDay_fragment_create_obj(1,parent); weatherDay_fragment_create_obj(2,parent); //manager2 = lv_fragment_manager_create(NULL); //fragment2 = lv_fragment_create(&meteodailyforecast_cls, (void *)1); //lv_fragment_manager_add(manager2, fragment2, &parent); } void draw_tabVolets(lv_obj_t* parent) { lv_obj_t *tabVolet = lv_obj_create(parent); lv_obj_set_flex_flow(tabVolet, LV_FLEX_FLOW_COLUMN); lv_obj_add_style(tabVolet, &no_padding, 0); lv_obj_set_size(tabVolet, lv_pct(85), lv_pct(100)); lv_obj_t *cont_rdc = lv_obj_create(tabVolet); 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(tabVolet, &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_set_style_text_font(btnVolet,lv_theme_get_font_normal(btnVolet),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(parent); 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(tabVolet); 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_set_style_text_font(btnVolet,lv_theme_get_font_large(btnVolet),0); // lv_obj_set_size(btnVolet,100,24); // char *nom[10]; // sprintf(nom,"%d", i); lv_checkbox_set_text(btnVolet, ""); } } /* ------------------------------------------------------------ */ /* 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, "--"); // keys.clear(); lv_obj_clean(lv_scr_act()); //Create a Tab view object 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, lv_theme_get_font_large(tab_buttons), 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 lv_obj_t* tab0 = lv_tabview_add_tab(tabview, LV_SYMBOL_HOME); lv_obj_t* tabVolets = lv_tabview_add_tab(tabview, "Volets"); lv_obj_t* tabMeteo = lv_tabview_add_tab(tabview, "Météo"); lv_obj_t* tabCuve = lv_tabview_add_tab(tabview, "\xEF\x95\xB5" "Cuve"); lv_obj_t* tabSettings = lv_tabview_add_tab(tabview, "Settings"); // lv_obj_set_style_bg_color(tab2b, lv_palette_lighten(LV_PALETTE_AMBER, 3), 0); lv_obj_set_style_bg_opa(tabVolets, LV_OPA_COVER, 0); lv_style_init(&style_btn); // 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, lv_pct(80)); 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); lv_style_init(&style_lbvValue); lv_style_set_text_font(&style_lbvValue, &lv_font_montserrat_40); draw_tabHome(tab0); draw_tabVolets(tabVolets); draw_tabMeteo(tabMeteo); draw_tabCuve(tabCuve); draw_tabSettings(tabSettings); lv_obj_set_flex_flow(tabVolets, LV_FLEX_FLOW_ROW); lv_obj_set_flex_flow(tabMeteo, LV_FLEX_FLOW_COLUMN); } void log_cb(lv_log_level_t level, const char * buf){ ESP_LOGE(TAG, "%s",buf); } void show_temp(char * tempHumid){ display_lock("tempHumid"); lv_label_set_text(lblTempInt2, tempHumid); display_unlock("tempHumid"); }