1795 lines
62 KiB
C
1795 lines
62 KiB
C
#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_lcd_touch_gt911.h"
|
|
#include "esp_lvgl_port.h"
|
|
#include "esp_event.h"
|
|
#include "nvs_flash.h"
|
|
#include <locale.h>
|
|
#include "esp_vfs_fat.h"
|
|
#include "sdmmc_cmd.h"
|
|
#include <stdio.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 "fatfs.h"
|
|
#include "meteofrance.h"
|
|
#include "image_downloader.h"
|
|
#include "wifi.h"
|
|
#include "mqtt.h"
|
|
|
|
#include "am2302_rmt.h"
|
|
|
|
// GPIO assignment
|
|
#define AM2302_GPIO 19
|
|
|
|
|
|
#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
|
|
|
|
#include "main.h"
|
|
LV_FONT_DECLARE(montserrat_medium_12)
|
|
LV_FONT_DECLARE(montserrat_medium_18)
|
|
LV_FONT_DECLARE(montserrat_medium_24)
|
|
|
|
/* 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 meteoStatus;
|
|
lv_subject_t dateHeureSubj;
|
|
char dateHeureStr[30];
|
|
|
|
static lv_style_t no_padding;
|
|
static lv_style_t style_font_18;
|
|
static lv_style_t style_font_24;
|
|
|
|
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 void meteo_obs_cb(lv_observer_t *observer, lv_subject_t *subject)
|
|
{
|
|
ESP_LOGV("MeteoFrance", "On passe dans le callback de chgt de statut meteo; %li", lv_subject_get_int(subject));
|
|
if (lvgl_port_lock(0))
|
|
{
|
|
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;
|
|
}
|
|
lvgl_port_unlock();
|
|
}
|
|
}
|
|
|
|
static void app_main_display(void)
|
|
{
|
|
|
|
lv_subject_init_string(&dateHeureSubj, dateHeureStr, NULL, 64, "--");
|
|
|
|
lv_style_init(&no_padding);
|
|
lv_style_set_pad_all(&no_padding, 0);
|
|
|
|
lv_style_init(&style_font_18);
|
|
lv_style_set_text_font(&style_font_18, &montserrat_medium_18);
|
|
|
|
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);
|
|
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_add_style(meteoR, &style_font_18, 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();
|
|
|
|
/* 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 "Bienvenue sur DomoTIC !" LV_SYMBOL_BELL);
|
|
#endif
|
|
lv_obj_align(label, LV_ALIGN_CENTER, 0, 20);
|
|
}
|
|
|
|
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);
|
|
*/
|
|
|
|
static lv_style_t style_container;
|
|
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_LOGV("MeteoFrance", "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);
|
|
char *str1 = "A:/littlefs/";
|
|
char *result = malloc(strlen(str1) + strlen(icon) + 6);
|
|
sprintf(result, "%s%s.png", str1, icon);
|
|
lv_image_set_src(img, result);
|
|
/*
|
|
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, 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_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, 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_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 *tab0;
|
|
lv_obj_t *tabVolets;
|
|
lv_obj_t *tabMeteo;
|
|
lv_obj_t *tabCuve;
|
|
lv_obj_t *tabSettings;
|
|
uint32_t oldTab;
|
|
lv_fragment_manager_t *manager2;
|
|
lv_fragment_t *fragment2;
|
|
|
|
static 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_delete(manager2);
|
|
// lv_obj_clean(tab3);
|
|
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 *btnGrp = lv_obj_create(tabSettings);
|
|
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 *lblTempInt2;
|
|
|
|
void draw_tabHome(){
|
|
lv_obj_t *supmain = tab0;
|
|
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_set_flex_align(cont_col2, LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_SPACE_BETWEEN);
|
|
|
|
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_tempInt2 = lv_obj_create(cont_col);
|
|
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,&montserrat_medium_24,0);
|
|
|
|
lv_label_set_text(lblTempInt2, "");
|
|
|
|
/*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);
|
|
}
|
|
|
|
void draw_tabCuve()
|
|
{
|
|
lv_obj_t *imgGraf = lv_image_create(tabCuve);
|
|
lv_image_set_src(imgGraf, "A:/sdcard/hello2.png");
|
|
}
|
|
|
|
void draw_tabMeteo()
|
|
{
|
|
manager2 = lv_fragment_manager_create(NULL);
|
|
fragment2 = lv_fragment_create(&meteodailyforecast_cls, (void *)1);
|
|
lv_fragment_manager_add(manager2, fragment2, &tabCuve);
|
|
}
|
|
|
|
void draw_tabVolets()
|
|
{
|
|
lv_obj_t *tabMeteo = lv_obj_create(tabVolets);
|
|
lv_obj_set_flex_flow(tabMeteo, LV_FLEX_FLOW_COLUMN);
|
|
lv_obj_add_style(tabMeteo, &no_padding, 0);
|
|
|
|
lv_obj_set_size(tabMeteo, lv_pct(85), lv_pct(100));
|
|
lv_obj_t *cont_rdc = lv_obj_create(tabMeteo);
|
|
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(tabMeteo, &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(tabVolets);
|
|
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(tabMeteo);
|
|
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, "");
|
|
}
|
|
}
|
|
|
|
/* ------------------------------------------------------------ */
|
|
/* 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_24, 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*/
|
|
tab0 = lv_tabview_add_tab(tabview, LV_SYMBOL_HOME);
|
|
tabVolets = lv_tabview_add_tab(tabview, "Volets");
|
|
tabMeteo = lv_tabview_add_tab(tabview, "Météo");
|
|
tabCuve = lv_tabview_add_tab(tabview, "\xEF\x95\xB5"
|
|
"Cuve");
|
|
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_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);
|
|
|
|
lv_style_init(&style_lbvValue);
|
|
lv_style_set_text_font(&style_lbvValue, &lv_font_montserrat_40);
|
|
|
|
draw_tabHome();
|
|
|
|
lv_obj_set_flex_flow(tabVolets, LV_FLEX_FLOW_ROW);
|
|
|
|
lv_obj_set_flex_flow(tabMeteo, 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_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);
|
|
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);
|
|
}
|
|
|
|
extern char *days[7];
|
|
extern char *months[12];
|
|
|
|
static void updateTime(void *pvParameter)
|
|
{
|
|
|
|
char strftime_buf[64];
|
|
time_t now = 0;
|
|
while (1)
|
|
{
|
|
time(&now);
|
|
struct tm timeinfo = {0};
|
|
localtime_r(&now, &timeinfo);
|
|
sprintf(strftime_buf, "%s %d %s %02d:%02d", days[timeinfo.tm_wday], timeinfo.tm_mday, months[timeinfo.tm_mon], timeinfo.tm_hour, timeinfo.tm_min);
|
|
if(lvgl_port_lock(0)){
|
|
lv_subject_copy_string(&dateHeureSubj, strftime_buf);
|
|
lvgl_port_unlock();
|
|
}
|
|
/*
|
|
lv_obj_refr_size(lv_obj_get_child(lv_obj_get_child(lv_layer_top(),0),0));
|
|
lv_obj_refr_size(lv_obj_get_child(lv_layer_top(),0));
|
|
lvgl_port_unlock();
|
|
}*/
|
|
vTaskDelay(60000 / portTICK_PERIOD_MS);
|
|
}
|
|
}
|
|
|
|
esp_err_t _ota_http_event_handler(esp_http_client_event_t *evt)
|
|
{
|
|
switch (evt->event_id) {
|
|
case HTTP_EVENT_ERROR:
|
|
ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
|
|
break;
|
|
case HTTP_EVENT_ON_CONNECTED:
|
|
ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
|
|
break;
|
|
case HTTP_EVENT_HEADER_SENT:
|
|
ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
|
|
break;
|
|
case HTTP_EVENT_ON_HEADER:
|
|
ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
|
|
break;
|
|
case HTTP_EVENT_ON_DATA:
|
|
ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
|
|
break;
|
|
case HTTP_EVENT_ON_FINISH:
|
|
ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
|
|
break;
|
|
case HTTP_EVENT_DISCONNECTED:
|
|
ESP_LOGD(TAG, "HTTP_EVENT_DISCONNECTED");
|
|
break;
|
|
case HTTP_EVENT_REDIRECT:
|
|
ESP_LOGD(TAG, "HTTP_EVENT_REDIRECT");
|
|
break;
|
|
}
|
|
return ESP_OK;
|
|
}
|
|
|
|
extern const uint8_t server_cert_pem_start[] asm("_binary_ca_cert_pem_start");
|
|
extern const uint8_t server_cert_pem_end[] asm("_binary_ca_cert_pem_end");
|
|
|
|
void simple_ota_example_task(void *pvParameter)
|
|
{
|
|
ESP_LOGI(TAG, "Starting OTA example task");
|
|
#ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF
|
|
esp_netif_t *netif = get_example_netif_from_desc(bind_interface_name);
|
|
if (netif == NULL) {
|
|
ESP_LOGE(TAG, "Can't find netif from interface description");
|
|
abort();
|
|
}
|
|
struct ifreq ifr;
|
|
esp_netif_get_netif_impl_name(netif, ifr.ifr_name);
|
|
ESP_LOGI(TAG, "Bind interface name is %s", ifr.ifr_name);
|
|
#endif
|
|
esp_http_client_config_t config = {
|
|
.url = "https://192.168.0.28:8070/rgb_lcd.bin",
|
|
.event_handler = _ota_http_event_handler,
|
|
.keep_alive_enable = true,
|
|
.cert_pem = (char *)server_cert_pem_start,
|
|
#ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF
|
|
.if_name = &ifr,
|
|
#endif
|
|
};
|
|
|
|
#ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL_FROM_STDIN
|
|
char url_buf[OTA_URL_SIZE];
|
|
if (strcmp(config.url, "FROM_STDIN") == 0) {
|
|
example_configure_stdin_stdout();
|
|
fgets(url_buf, OTA_URL_SIZE, stdin);
|
|
int len = strlen(url_buf);
|
|
url_buf[len - 1] = '\0';
|
|
config.url = url_buf;
|
|
} else {
|
|
ESP_LOGE(TAG, "Configuration mismatch: wrong firmware upgrade image url");
|
|
abort();
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK
|
|
config.skip_cert_common_name_check = true;
|
|
#endif
|
|
|
|
esp_https_ota_config_t ota_config = {
|
|
.http_config = &config,
|
|
};
|
|
ESP_LOGI(TAG, "Attempting to download update from %s", config.url);
|
|
esp_err_t ret = esp_https_ota(&ota_config);
|
|
if (ret == ESP_OK) {
|
|
ESP_LOGI(TAG, "OTA Succeed, Rebooting...");
|
|
esp_restart();
|
|
} else {
|
|
ESP_LOGE(TAG, "Firmware upgrade failed");
|
|
}
|
|
while (1) {
|
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
|
}
|
|
}
|
|
|
|
|
|
am2302_handle_t sensor = NULL;
|
|
|
|
void readTempHumid(void *pvParameter)
|
|
{
|
|
float temperature = 0;
|
|
float humidity = 0;
|
|
while (1)
|
|
{
|
|
am2302_read_temp_humi(sensor, &temperature, &humidity);
|
|
char buff[40];
|
|
ESP_LOGI(TAG, "Temperature: %.1f °C, Humidity: %.1f %%", temperature, humidity);
|
|
sprintf(buff,"%.1f °C, %.1f %%", temperature, humidity);
|
|
if(lvgl_port_lock(0)){
|
|
lv_label_set_text(lblTempInt2,buff);
|
|
lvgl_port_unlock();
|
|
}
|
|
vTaskDelay(60000 / portTICK_PERIOD_MS);
|
|
}
|
|
|
|
}
|
|
|
|
void app_main(void)
|
|
{
|
|
printf("Minimum free heap size: %" PRIu32 " bytes\n", esp_get_minimum_free_heap_size());
|
|
printf("Free heap size: %" PRIu32 " bytes\n", esp_get_free_heap_size());
|
|
|
|
printf("1- Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
|
|
|
|
esp_log_level_set("wifi", ESP_LOG_ERROR);
|
|
|
|
printf("2- Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
|
|
|
|
mount_sd_card();
|
|
|
|
esp_vfs_littlefs_conf_t conf = {
|
|
.base_path = "/littlefs",
|
|
.partition_label = "littlefs",
|
|
.format_if_mount_failed = true,
|
|
.dont_mount = false,
|
|
};
|
|
|
|
printf("3 - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
|
|
/* LCD HW initialization */
|
|
ESP_ERROR_CHECK(app_lcd_init());
|
|
|
|
printf("4 - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
|
|
/* Touch initialization */
|
|
ESP_ERROR_CHECK(app_touch_init());
|
|
|
|
printf("5 - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
|
|
/* LVGL initialization */
|
|
ESP_ERROR_CHECK(app_lvgl_init());
|
|
|
|
printf("6 - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
|
|
|
|
lv_subject_init_int(&meteoStatus, -1);
|
|
|
|
/* 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();
|
|
}
|
|
|
|
printf("7 - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
|
|
// Initialize NVS
|
|
esp_err_t ret = nvs_flash_init();
|
|
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
|
|
{
|
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
|
ret = nvs_flash_init();
|
|
}
|
|
ESP_ERROR_CHECK(ret);
|
|
|
|
printf("8 - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
|
|
ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
|
|
wifi_init_sta();
|
|
start_wifi_logger();
|
|
wifi_log_e("test", "%s %d %f", "hello world wifi logger", 43, 45.341223242); // write log over wifi with log level -> ERROR
|
|
esp_log_level_set("tcp_handler", ESP_LOG_NONE);
|
|
printf("8b - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
|
|
mqtt_app_start();
|
|
|
|
printf("9 - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
|
|
|
|
time_t now;
|
|
struct tm timeinfo;
|
|
time(&now);
|
|
localtime_r(&now, &timeinfo);
|
|
// Is time set? If not, tm_year will be (1970 - 1900).
|
|
if (timeinfo.tm_year < (2016 - 1900))
|
|
{
|
|
ESP_LOGI(TAG, "Time is not set yet. Connecting to WiFi and getting time over NTP.");
|
|
obtain_time();
|
|
// update 'now' variable with current time
|
|
time(&now);
|
|
}
|
|
|
|
char strftime_buf[64];
|
|
|
|
// Set timezone to Eastern Standard Time and print local time
|
|
setenv("TZ", "CET-1CEST,M3.5.0,M10.5.0/3", 1);
|
|
tzset();
|
|
localtime_r(&now, &timeinfo);
|
|
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
|
|
|
|
printf("10. Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
|
|
heap_caps_print_heap_info(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
|
|
|
on_weather_data_retrieval(weather_data_retreived);
|
|
on_weather_data_retrieval_start(weather_data_retreived_start);
|
|
initialise_weather_data_retrieval(600000);
|
|
ESP_LOGW(TAG, "Weather data retrieval initialized");
|
|
|
|
printf("11. Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
|
|
ESP_LOGW(TAG, "On telecharge l'image cuve");
|
|
TaskHandle_t xHandle = NULL;
|
|
BaseType_t ret1;
|
|
|
|
ret1 = xTaskCreate(&imgdwn, "imageDownload_task", 3 * 1024, NULL, 5, &xHandle);
|
|
if (ret1 != pdPASS)
|
|
{
|
|
ESP_LOGE(TAG, "Impossiblke de creer la tache imageDownload_task %i", ret1);
|
|
}
|
|
|
|
BaseType_t ret2 = xTaskCreate(&updateTime, "updateTimeTask", 3 * 1024, NULL, 5, NULL);
|
|
if (ret2 != pdPASS)
|
|
{
|
|
ESP_LOGE(TAG, "Impossiblke de creer la tache updateTimeTask %i", ret1);
|
|
}
|
|
|
|
printf("12. Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
|
|
/* Show LVGL objects */
|
|
if (lvgl_port_lock(0))
|
|
{
|
|
draw_ihm();
|
|
// lv_disp_set_rotation(lvgl_disp, LV_DISPLAY_ROTATION_180);
|
|
|
|
lvgl_port_unlock();
|
|
}
|
|
printf("13. Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
|
|
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());
|
|
LV_ASSERT_MEM_INTEGRITY();
|
|
|
|
lv_mem_monitor_t mon;
|
|
lv_mem_monitor(&mon);
|
|
printf("used: %6d (%3d %%), frag: %3d %%, biggest free: %6d\n",
|
|
(int)mon.total_size - mon.free_size, mon.used_pct, mon.frag_pct,
|
|
(int)mon.free_biggest_size);
|
|
|
|
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.
|
|
ret = esp_vfs_littlefs_register(&conflfs);
|
|
|
|
if (ret != ESP_OK)
|
|
{
|
|
if (ret == ESP_FAIL)
|
|
{
|
|
ESP_LOGE(TAG, "Failed to mount or format filesystem");
|
|
}
|
|
else if (ret == 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(ret));
|
|
}
|
|
return;
|
|
}
|
|
|
|
size_t total = 0, used = 0;
|
|
ret = esp_littlefs_info(conflfs.partition_label, &total, &used);
|
|
if (ret != ESP_OK)
|
|
{
|
|
ESP_LOGE(TAG, "Failed to get LittleFS partition information (%s)", esp_err_to_name(ret));
|
|
}
|
|
else
|
|
{
|
|
ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used);
|
|
}
|
|
|
|
ESP_LOGI(TAG, "Reading file");
|
|
FILE *f = fopen("/littlefs/p1j.png", "r");
|
|
if (f == NULL)
|
|
{
|
|
ESP_LOGE(TAG, "Failed to open file for reading");
|
|
return;
|
|
}
|
|
|
|
char line[128];
|
|
char *pos;
|
|
|
|
fgets(line, sizeof(line), f);
|
|
fclose(f);
|
|
// strip newline
|
|
pos = strchr(line, '\n');
|
|
if (pos)
|
|
{
|
|
*pos = '\0';
|
|
}
|
|
ESP_LOGI(TAG, "Read from file: '%s'", line);
|
|
|
|
//OTA désactivé
|
|
//xTaskCreate(&simple_ota_example_task, "ota_example_task", 8192, NULL, 5, NULL);
|
|
|
|
/* 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);
|
|
|
|
|
|
}
|