Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f60e9c38c | |||
| 67e6d1cfaa | |||
| 77e8116d54 | |||
| 0de95c5386 | |||
| f871b76ca2 | |||
| 9d31148d21 | |||
| 9293b5fdc6 | |||
| bce9f03eb4 | |||
| 9217397d7d | |||
| b7552e15ce | |||
| 434ede2480 | |||
| 8e868da692 | |||
| e1640f4ad9 | |||
| a41945bcef | |||
| 7316561482 | |||
| ae99b85932 | |||
| 5ac20b78fa | |||
| fc5f46d3fd | |||
| f5419e85aa | |||
| 4658da4adb | |||
| f32cad2987 | |||
| 1d91bac9e9 | |||
| c87cc69b9e | |||
| 6f338020ab | |||
| d9ac74a595 | |||
| 5bd2ef288a | |||
| 28c5870ca6 | |||
| 2da4a8f94b | |||
| f29fee752f | |||
| 3a791daa47 |
2
.vscode/c_cpp_properties.json
vendored
@ -2,7 +2,7 @@
|
||||
"configurations": [
|
||||
{
|
||||
"name": "ESP-IDF",
|
||||
"compilerPath": "${config:idf.toolsPath}/tools/xtensa-esp-elf/esp-14.2.0_20241119/xtensa-esp-elf/bin/xtensa-esp32-elf-gcc",
|
||||
"compilerPath": "/home/marc/.espressif/tools/riscv32-esp-elf/esp-14.2.0_20251107/riscv32-esp-elf/bin/riscv32-esp-elf-gcc",
|
||||
"compileCommands": "${config:idf.buildPath}/compile_commands.json",
|
||||
"includePath": [
|
||||
"${config:idf.espIdfPath}/components/**",
|
||||
|
||||
2
.vscode/launch.json
vendored
@ -37,7 +37,7 @@
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "Build - Build IHM",
|
||||
"program": "${workspaceFolder}/components/domotic_display/test_host/build/nvs_host_test.elf",
|
||||
"program": "${workspaceFolder}/components/domotic_display/test_host/build/host_test.elf",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
|
||||
5
.vscode/settings.json
vendored
@ -7,13 +7,12 @@
|
||||
"idf.customExtraVars": {
|
||||
"OPENOCD_SCRIPTS": "/home/marc/.espressif/tools/openocd-esp32/v0.12.0-esp32-20251215/openocd-esp32/share/openocd/scripts",
|
||||
"ESP_ROM_ELF_DIR": "/home/marc/.espressif/tools/esp-rom-elfs/20240305/",
|
||||
"IDF_TARGET": "linux"
|
||||
"IDF_TARGET": "esp32p4"
|
||||
},
|
||||
"idf.gitPath": "git",
|
||||
"idf.adapterTargetName": "esp32s3",
|
||||
"idf.openOcdConfigs": [
|
||||
"interface/ftdi/esp_ftdi.cfg",
|
||||
"target/esp32.cfg"
|
||||
"board/esp32p4-builtin.cfg"
|
||||
],
|
||||
"idf.flashType": "UART",
|
||||
"idf.port": "/dev/ttyUSB0",
|
||||
|
||||
@ -1,3 +1,54 @@
|
||||
# --------------------------------------------------
|
||||
# 1. Version de base (version.txt)
|
||||
# --------------------------------------------------
|
||||
file(READ "${CMAKE_SOURCE_DIR}/version.txt" FW_VERSION)
|
||||
string(STRIP "${FW_VERSION}" FW_VERSION)
|
||||
|
||||
# --------------------------------------------------
|
||||
# 2. Détection git + branche
|
||||
# --------------------------------------------------
|
||||
find_package(Git)
|
||||
|
||||
set(GIT_BRANCH "")
|
||||
set(IS_GIT_REPO OFF)
|
||||
|
||||
if(GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
||||
set(IS_GIT_REPO ON)
|
||||
|
||||
execute_process(
|
||||
COMMAND git rev-parse --abbrev-ref HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_BRANCH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
ERROR_QUIET
|
||||
)
|
||||
endif()
|
||||
|
||||
# --------------------------------------------------
|
||||
# 3. Mode dev ou release
|
||||
# --------------------------------------------------
|
||||
# Convention simple :
|
||||
# - branche main / master => release
|
||||
# - le reste => dev
|
||||
set(IS_DEV_BUILD OFF)
|
||||
|
||||
if(IS_GIT_REPO AND NOT GIT_BRANCH STREQUAL "main" AND NOT GIT_BRANCH STREQUAL "master")
|
||||
set(IS_DEV_BUILD ON)
|
||||
endif()
|
||||
|
||||
# --------------------------------------------------
|
||||
# 4. Nettoyage nom de branche
|
||||
# --------------------------------------------------
|
||||
if(IS_DEV_BUILD)
|
||||
# remplace / par -
|
||||
string(REPLACE "/" "-" GIT_BRANCH_CLEAN "${GIT_BRANCH}")
|
||||
set(FW_VERSION "${FW_VERSION}-${GIT_BRANCH_CLEAN}")
|
||||
endif()
|
||||
|
||||
message(STATUS "Firmware version: ${FW_VERSION}")
|
||||
|
||||
# --------------------------------------------------
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
option(SIMULATION_QEMU "Build for QEMU simulation" OFF)
|
||||
message(STATUS "ROOT:: SIMULATION_QEMU = ${SIMULATION_QEMU}")
|
||||
@ -33,7 +84,7 @@ endif()
|
||||
#list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/esp_timer")
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(rgb_lcd)
|
||||
project(domotic)
|
||||
|
||||
|
||||
# -------------------------------------------------
|
||||
@ -61,3 +112,44 @@ else()
|
||||
|
||||
add_link_options(-fsanitize=address)
|
||||
endif()
|
||||
|
||||
# --- Paramètres OTA ---
|
||||
set(OTA_DIR "${CMAKE_SOURCE_DIR}/../ota/fw")
|
||||
set(DEVICE "esp32p4")
|
||||
|
||||
|
||||
# --- Nom final du binaire ---
|
||||
set(OTA_BIN_NAME "${PROJECT_NAME}-v${FW_VERSION}.bin")
|
||||
set(BUILD_BIN "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.bin")
|
||||
set(BUILD_ELF "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.elf")
|
||||
|
||||
message(STATUS "Firmware version: ${FW_VERSION}")
|
||||
|
||||
# --- Target OTA ---
|
||||
add_custom_target(ota_push ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${OTA_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${BUILD_BIN}
|
||||
${OTA_DIR}/${OTA_BIN_NAME}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${BUILD_ELF}
|
||||
${OTA_DIR}/latest.elf
|
||||
COMMENT "📦 Copy firmware to OTA server directory"
|
||||
DEPENDS app
|
||||
)
|
||||
|
||||
add_custom_target(ota_latest
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
"{ \"version\":\"${FW_VERSION}\", \
|
||||
\"bin\":\"${OTA_BIN_NAME}\" }"
|
||||
> ${OTA_DIR}/latest.json
|
||||
DEPENDS ota_push
|
||||
)
|
||||
|
||||
add_custom_target(ota_to_mqtt
|
||||
COMMAND podman run --rm eclipse-mosquitto:alpine
|
||||
mosquitto_pub
|
||||
-h 192.168.0.10
|
||||
-t devices/esp32p4_01/ota/update
|
||||
-m '{"version":"${FW_VERSION}","url":"https://192.168.0.9:8443/${OTA_BIN_NAME}","sha256":"","force":true}'
|
||||
)
|
||||
|
||||
3
components/audio/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "audio.c"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES esp32_p4_function_ev_board)
|
||||
224
components/audio/audio.c
Normal file
@ -0,0 +1,224 @@
|
||||
#include <stdio.h>
|
||||
#include "audio.h"
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <sdkconfig.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "esp_log.h"
|
||||
#include "bsp/esp-bsp.h"
|
||||
|
||||
/* Buffer for reading/writing to I2S driver. Same length as SPIFFS buffer and I2S buffer, for optimal read/write performance.
|
||||
External SPI Flash -> SPIFFS buffer -> App buffer (RAM) -> I2S buffer (DMA) -> I2S peripheral.
|
||||
*/
|
||||
#define BUFFER_SIZE (1024)
|
||||
#define DEFAULT_VOLUME (50)
|
||||
|
||||
/* Globals */
|
||||
static const char *TAG = "audio";
|
||||
TaskHandle_t audio_task_handle;
|
||||
|
||||
|
||||
// Very simple WAV header, ignores most fields
|
||||
typedef struct __attribute__((packed))
|
||||
{
|
||||
uint8_t ignore_0[22];
|
||||
uint16_t num_channels;
|
||||
uint32_t sample_rate;
|
||||
uint8_t ignore_1[6];
|
||||
uint16_t bits_per_sample;
|
||||
uint8_t ignore_2[4];
|
||||
uint32_t data_size;
|
||||
uint8_t data[];
|
||||
} dumb_wav_header_t;
|
||||
|
||||
typedef struct {
|
||||
FILE *f;
|
||||
uint32_t data_offset;
|
||||
uint32_t data_size;
|
||||
} wav_ctx_t;
|
||||
#define AUDIO_CHUNK_SIZE 4096
|
||||
|
||||
bool wav_open(wav_ctx_t *ctx, const char *path)
|
||||
{
|
||||
ctx->f = fopen(path, "rb");
|
||||
if (!ctx->f) return false;
|
||||
|
||||
/* Skip RIFF header */
|
||||
fseek(ctx->f, 12, SEEK_SET);
|
||||
|
||||
uint32_t chunk_id, chunk_size;
|
||||
|
||||
while (fread(&chunk_id, 4, 1, ctx->f))
|
||||
{
|
||||
fread(&chunk_size, 4, 1, ctx->f);
|
||||
|
||||
if (chunk_id == 0x61746164) { // "data"
|
||||
ctx->data_offset = ftell(ctx->f);
|
||||
ctx->data_size = chunk_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
fseek(ctx->f, chunk_size, SEEK_CUR);
|
||||
}
|
||||
|
||||
fclose(ctx->f);
|
||||
return false;
|
||||
}
|
||||
void rewind_wav(wav_ctx_t *ctx)
|
||||
{
|
||||
fseek(ctx->f, ctx->data_offset, SEEK_SET);
|
||||
}
|
||||
#define AUDIO_CHUNK_SIZE 4096
|
||||
static void audio_task(void *arg)
|
||||
{
|
||||
ESP_LOGI(TAG,"Audio task");
|
||||
|
||||
esp_codec_dev_handle_t spk_codec_dev = bsp_audio_codec_speaker_init();
|
||||
assert(spk_codec_dev);
|
||||
|
||||
esp_codec_dev_set_out_vol(spk_codec_dev, DEFAULT_VOLUME);
|
||||
esp_codec_dev_set_out_mute(spk_codec_dev, false); // 🔑 CRITIQUE
|
||||
|
||||
const char *play_filename = "/littlefs/sounds/mixkit-clear-announce-tones-2861.wav";
|
||||
|
||||
uint8_t *wav_bytes = malloc(BUFFER_SIZE);
|
||||
assert(wav_bytes != NULL);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* ⏸️ Attend PLAY */
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
bool stop_requested = false;
|
||||
|
||||
while (!stop_requested) {
|
||||
ESP_LOGI(TAG,"On joue !");
|
||||
|
||||
FILE *play_file = fopen(play_filename, "rb");
|
||||
if (!play_file) {
|
||||
ESP_LOGE(TAG,"File not found");
|
||||
break;
|
||||
}
|
||||
|
||||
dumb_wav_header_t wav_header;
|
||||
if (fread(&wav_header, 1, sizeof(wav_header), play_file) != sizeof(wav_header)) {
|
||||
ESP_LOGE(TAG,"Header read failed");
|
||||
fclose(play_file);
|
||||
break;
|
||||
}
|
||||
|
||||
esp_codec_dev_sample_info_t fs = {
|
||||
.sample_rate = wav_header.sample_rate,
|
||||
.channel = wav_header.num_channels,
|
||||
.bits_per_sample = wav_header.bits_per_sample,
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(esp_codec_dev_open(spk_codec_dev, &fs));
|
||||
|
||||
uint32_t bytes_sent = 0;
|
||||
while (bytes_sent < wav_header.data_size) {
|
||||
size_t bytes_read = fread(wav_bytes, 1, BUFFER_SIZE, play_file);
|
||||
if (bytes_read == 0) break;
|
||||
|
||||
esp_codec_dev_write(spk_codec_dev, wav_bytes, bytes_read);
|
||||
bytes_sent += bytes_read;
|
||||
|
||||
vTaskDelay(1); // watchdog + scheduler
|
||||
}
|
||||
|
||||
esp_codec_dev_close(spk_codec_dev);
|
||||
fclose(play_file);
|
||||
|
||||
ESP_LOGI(TAG,"Fin du fichier");
|
||||
|
||||
if (ulTaskNotifyTake(pdTRUE, 0) > 0) {
|
||||
stop_requested = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(wav_bytes);
|
||||
}
|
||||
static void audio_task__(void *arg)
|
||||
{
|
||||
ESP_LOGE(TAG,"Audio task");
|
||||
esp_codec_dev_handle_t spk_codec_dev = bsp_audio_codec_speaker_init();
|
||||
assert(spk_codec_dev);
|
||||
esp_codec_dev_set_out_vol(spk_codec_dev, DEFAULT_VOLUME);
|
||||
|
||||
/* Pointer to a file that is going to be played */
|
||||
const char music_filename[] = "/littlefs/sounds/mixkit-clear-announce-tones-2861.wav";
|
||||
const char *play_filename = music_filename;
|
||||
|
||||
int16_t *wav_bytes = malloc(BUFFER_SIZE);
|
||||
assert(wav_bytes != NULL);
|
||||
|
||||
bool stop_requested = false;
|
||||
|
||||
while (!stop_requested){
|
||||
ESP_LOGE(TAG,"On joue !");
|
||||
/* Open WAV file */
|
||||
ESP_LOGI(TAG, "Playing file %s", play_filename);
|
||||
FILE *play_file = fopen(play_filename, "rb");
|
||||
if (play_file == NULL) {
|
||||
ESP_LOGW(TAG, "%s file does not exist!", play_filename);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Read WAV header file */
|
||||
dumb_wav_header_t wav_header;
|
||||
if (fread((void *)&wav_header, 1, sizeof(wav_header), play_file) != sizeof(wav_header)) {
|
||||
ESP_LOGW(TAG, "Error in reading file");
|
||||
break;
|
||||
}
|
||||
//ESP_LOGI(TAG, "Number of channels: %" PRIu16 "", wav_header.num_channels);
|
||||
//ESP_LOGI(TAG, "Bits per sample: %" PRIu16 "", wav_header.bits_per_sample);
|
||||
//ESP_LOGI(TAG, "Sample rate: %" PRIu32 "", wav_header.sample_rate);
|
||||
//ESP_LOGI(TAG, "Data size: %" PRIu32 "", wav_header.data_size);
|
||||
|
||||
esp_codec_dev_sample_info_t fs = {
|
||||
.sample_rate = wav_header.sample_rate,
|
||||
.channel = wav_header.num_channels,
|
||||
.bits_per_sample = wav_header.bits_per_sample,
|
||||
};
|
||||
esp_codec_dev_open(spk_codec_dev, &fs);
|
||||
|
||||
uint32_t bytes_send_to_i2s = 0;
|
||||
while (bytes_send_to_i2s < wav_header.data_size) {
|
||||
/* Get data from SPIFFS and send it to codec */
|
||||
size_t bytes_read_from_spiffs = fread(wav_bytes, 1, BUFFER_SIZE, play_file);
|
||||
esp_codec_dev_write(spk_codec_dev, wav_bytes, bytes_read_from_spiffs);
|
||||
bytes_send_to_i2s += bytes_read_from_spiffs;
|
||||
|
||||
/* ⭐ LIGNE CRITIQUE ⭐ */
|
||||
vTaskDelay(1); // laisse respirer IDLE + watchdog
|
||||
}
|
||||
ESP_LOGE(TAG,"On a fini le fichier");
|
||||
|
||||
fclose(play_file);
|
||||
esp_codec_dev_close(spk_codec_dev);
|
||||
if(ulTaskNotifyTake(pdTRUE, 0)>0){
|
||||
stop_requested=true;
|
||||
break;
|
||||
};
|
||||
|
||||
}
|
||||
free(wav_bytes);
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
|
||||
void playSound(void)
|
||||
{
|
||||
if(audio_task_handle==NULL){
|
||||
BaseType_t ret = xTaskCreate(audio_task, "audio_task", 4096, NULL, 6, &audio_task_handle);
|
||||
assert(ret == pdPASS);
|
||||
}
|
||||
xTaskNotifyGive(audio_task_handle);
|
||||
}
|
||||
void stopSound(void){
|
||||
if (audio_task_handle) {
|
||||
xTaskNotifyGive(audio_task_handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
4
components/audio/include/audio.h
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
void playSound(void);
|
||||
|
||||
void stopSound(void);
|
||||
@ -19,7 +19,7 @@ make_font(Super_Malibu super_malibu 80)
|
||||
#execute_process(COMMAND podman run -v /home/marc/rgb_lcd/components/domotic_display/fonts:/app -w /app lvfontconv lv_font_conv --bpp 4 --size 72 --no-compress --font Roboto-Medium.ttf --symbols "0123456789.°àéèûCABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz %,'():ê/-" --format lvgl -o roboto_medium_72.c --font fa-solid-900.ttf --range 61461,0xf0c2,0xf575)
|
||||
|
||||
|
||||
SET(comps meteofrance eventsManager lvgl RemindMe)
|
||||
SET(comps meteofrance eventsManager lvgl RemindMe washingMachineState)
|
||||
if(${IDF_TARGET} STREQUAL "esp32p4" OR ${IDF_TARGET} STREQUAL "esp32s3")
|
||||
#esp32_p4_function_ev_board
|
||||
idf_component_register(SRC_DIRS . fonts
|
||||
@ -32,7 +32,6 @@ if(${IDF_TARGET} STREQUAL "esp32p4" OR ${IDF_TARGET} STREQUAL "esp32s3")
|
||||
lvgl_port_create_c_image("images/mqtt_ok.png" "images/" "AUTO" "NONE")
|
||||
lvgl_port_create_c_image("images/mqtt_ko.png" "images/" "ARGB8888" "NONE")
|
||||
lvgl_port_add_images(${COMPONENT_LIB} "images/")
|
||||
#littlefs_create_partition_image(littlefs images_meteo FLASH_IN_PROJECT)
|
||||
elseif(${IDF_TARGET} STREQUAL "linux")
|
||||
idf_component_register(SRC_DIRS . fonts images
|
||||
INCLUDE_DIRS "include"
|
||||
|
||||
@ -36,9 +36,10 @@ LV_IMAGE_DECLARE(mqtt_ok);
|
||||
LV_IMAGE_DECLARE(mqtt_ko);
|
||||
|
||||
lv_subject_t dateHeureSubj;
|
||||
lv_obj_t *lblTempInt2;
|
||||
lv_obj_t *lblTempInt;
|
||||
lv_obj_t *lblTempExt;
|
||||
char tempExtStr[6];
|
||||
char tempIntStr[6];
|
||||
char tempIntStr[50];
|
||||
char hauteurCuveStr[9];
|
||||
char hauteurCuveEvolStr[9];
|
||||
lv_subject_t tempIntSubj;
|
||||
@ -48,7 +49,7 @@ 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 *tmpDSubj[3] = {&forecastD1Subj, &forecastD2Subj, &forecastD3Subj};
|
||||
lv_subject_t forecastH1Subj;
|
||||
lv_subject_t forecastH2Subj;
|
||||
lv_subject_t forecastH3Subj;
|
||||
@ -109,11 +110,36 @@ void draw_time(struct tm *dateHeure){
|
||||
//}
|
||||
}
|
||||
|
||||
void draw_temp(char * tempHumid){
|
||||
if(display_lock("draw_temp")){
|
||||
lv_label_set_text(lblTempInt2,tempHumid);
|
||||
display_unlock("draw_temp");
|
||||
void draw_tempExt(char * tempHumid){
|
||||
//if(display_lock("draw_temp")){
|
||||
//lv_label_set_text_fmt(lblTempExt,LV_SYMBOL_HOME "\xEF\x8B\x8A : %.1f°C", atof(tempHumid));
|
||||
lv_subject_copy_string(&tempExtSubj,tempHumid);
|
||||
// display_unlock("draw_temp");
|
||||
//}
|
||||
}
|
||||
|
||||
void draw_temp(char * tempHumid){
|
||||
//if(display_lock("draw_temp")){
|
||||
ESP_LOGE(TAG, "draw_temp : %s", tempHumid);
|
||||
lv_subject_copy_string(&tempIntSubj,tempHumid);
|
||||
//lv_label_set_text_fmt(lblTempInt, "\xEE\x86\xB0\xEF\x8B\x8A : %s", tempHumid);
|
||||
|
||||
// display_unlock("draw_temp");
|
||||
//}
|
||||
}
|
||||
|
||||
void draw_meteo(meteo_event_payload_t *meteo){
|
||||
//if(display_lock("updateTime")){
|
||||
//lv_label_set_text(jour, dateHeure);
|
||||
lv_subject_set_pointer(&forecastH1Subj, &meteo->forecast[0]);
|
||||
lv_subject_set_pointer(&forecastH2Subj, &meteo->forecast[1]);
|
||||
lv_subject_set_pointer(&forecastH3Subj, &meteo->forecast[2]);
|
||||
lv_subject_set_pointer(&forecastD1Subj, &meteo->daily[0]);
|
||||
lv_subject_set_pointer(&forecastD2Subj, &meteo->daily[1]);
|
||||
lv_subject_set_pointer(&forecastD3Subj, &meteo->daily[2]);
|
||||
|
||||
//display_unlock("updateTime");
|
||||
//}
|
||||
}
|
||||
|
||||
lv_obj_t* myChart;
|
||||
@ -123,6 +149,7 @@ lv_obj_t* lblEtatMachine;
|
||||
static lv_style_t style_lbvValue;
|
||||
static lv_style_t style_btn;
|
||||
|
||||
/*
|
||||
lv_theme_t *lv_theme_create(void)
|
||||
{
|
||||
lv_theme_t *theme = lv_zalloc(sizeof(*theme));
|
||||
@ -139,6 +166,7 @@ void lv_theme_copy(lv_theme_t *dst, const lv_theme_t *src)
|
||||
}
|
||||
lv_memcpy(dst, src, sizeof(*src));
|
||||
}
|
||||
*/
|
||||
static void create_ui(void*)
|
||||
{
|
||||
// Initialisation du thème
|
||||
@ -151,6 +179,7 @@ static void create_ui(void*)
|
||||
|
||||
// Création des écrans / widgets
|
||||
app_main_display(); // ton écran principal
|
||||
initHome(); // écran Home
|
||||
drawHome(); // écran Home
|
||||
// chart, labels, boutons, etc.
|
||||
// par exemple : lblEtatMachine, lblHauteurCuve, myChart, ser...
|
||||
@ -162,6 +191,13 @@ static void create_ui(void*)
|
||||
#include <unistd.h> // usleep
|
||||
#include "platform_detect.h"
|
||||
|
||||
bool suspended;
|
||||
void suspendIHM(){
|
||||
suspended=true;
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
lvgl_port_stop();
|
||||
#endif
|
||||
}
|
||||
void drawIhm(void *param) {
|
||||
// Init display + LVGL
|
||||
init_display_ihm();
|
||||
@ -176,8 +212,14 @@ void drawIhm(void *param) {
|
||||
|
||||
// Loop unifiée
|
||||
while (1) {
|
||||
if(!suspended){
|
||||
ihm_gateway_process_queue();
|
||||
//uint32_t idle_time = lv_timer_handler();
|
||||
#if CONFIG_IDF_TARGET_LINUX
|
||||
uint32_t idle_time = lv_timer_handler();
|
||||
#endif
|
||||
}else{
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
// ESP32 : task FreeRTOS
|
||||
//vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
@ -217,6 +259,8 @@ static void event_handler(lv_event_t *e)
|
||||
static lv_indev_t *keyboard;
|
||||
#endif
|
||||
|
||||
struct tm timeinfo;
|
||||
|
||||
void init_display_ihm(){
|
||||
|
||||
#if CONFIG_IDF_TARGET_LINUX
|
||||
@ -228,13 +272,14 @@ void init_display_ihm(){
|
||||
keyboard = lv_sdl_keyboard_create();
|
||||
#else
|
||||
lvgl_port_cfg_t lvgl_cfg = ESP_LVGL_PORT_INIT_CONFIG();
|
||||
lvgl_cfg.task_priority=4;
|
||||
lvgl_cfg.task_priority=18;
|
||||
lvgl_cfg.task_stack=12000;
|
||||
bsp_display_cfg_t cfg = {
|
||||
.lvgl_port_cfg = lvgl_cfg,
|
||||
.buffer_size = 1024*600,//BSP_LCD_DRAW_BUFF_SIZE,
|
||||
.double_buffer = 1,
|
||||
.hw_cfg = {
|
||||
.dsi_bus.lane_bit_rate_mbps= 1000
|
||||
.dsi_bus.lane_bit_rate_mbps= BSP_LCD_MIPI_DSI_LANE_BITRATE_MBPS
|
||||
},
|
||||
.flags = {
|
||||
.buff_dma = false,
|
||||
@ -243,8 +288,8 @@ void init_display_ihm(){
|
||||
}
|
||||
};
|
||||
ESP_LOGE(TAG,"On demarre le display");
|
||||
lv_display_t *dsp = bsp_display_start();
|
||||
//lv_display_t *dsp = bsp_display_start_with_config(&cfg);
|
||||
//lv_display_t *dsp = bsp_display_start();
|
||||
lv_display_t *dsp = bsp_display_start_with_config(&cfg);
|
||||
|
||||
/*bsp_display_lock(0);
|
||||
bsp_display_rotate(dsp,LV_DISP_ROTATION_90);
|
||||
@ -259,7 +304,6 @@ void init_display_ihm(){
|
||||
mainState.display_init=true;
|
||||
|
||||
time_t now;
|
||||
struct tm timeinfo;
|
||||
time(&now);
|
||||
localtime_r(&now, &timeinfo);
|
||||
|
||||
@ -325,10 +369,9 @@ void app_main_display()
|
||||
|
||||
|
||||
struct meteodailyforecast_data d;
|
||||
struct dailyforecast_prev p;
|
||||
lv_strcpy(p.desc, "");
|
||||
struct dailyforecast_prev p={.desc="", .max=31, .min=12};
|
||||
d.previsions = p;
|
||||
d.isValid=false;
|
||||
d.isValid=true;
|
||||
ESP_LOGI(TAG, "Init forecastD1Subj");
|
||||
|
||||
lv_subject_init_pointer(&forecastD1Subj, &d);
|
||||
@ -402,7 +445,8 @@ void app_main_display()
|
||||
// lv_label_bind_text(mqtt, &mqttStatus, "Mqtt %d");
|
||||
|
||||
lv_obj_t *scr = lv_scr_act();
|
||||
lv_obj_add_style(scr, &style_gradient, 0);
|
||||
//lv_obj_add_style(scr, &style_gradient, 0);
|
||||
lv_obj_set_style_bg_color(scr,lv_color_darken(lv_color_make(0x9B, 0x18, 0x42), LV_OPA_40),0);
|
||||
|
||||
/* Your LVGL objects code here .... */
|
||||
|
||||
@ -479,13 +523,14 @@ 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)
|
||||
static void weatherdataJour_obs_cb(lv_observer_t *observer, lv_subject_t *subject)
|
||||
{
|
||||
|
||||
// Retrieve weatherdata
|
||||
const struct meteodailyforecast_data *data = subject->value.pointer;
|
||||
|
||||
bool isMinimal = observer->user_data;
|
||||
ESP_LOGI(TAG, "CB meteo jour declenché. Meteo valide : %b - Mode minimal : %d", data->isValid, isMinimal);
|
||||
ESP_LOGI(TAG, "CB meteo jour declenché. Meteo valide : %d - Mode minimal : %d", data->isValid, isMinimal);
|
||||
if(!data->isValid){
|
||||
ESP_LOGI(TAG,"Données meteo non valides");
|
||||
return;
|
||||
@ -495,9 +540,9 @@ static void weatherdata_obs_cb(lv_observer_t *observer, lv_subject_t *subject)
|
||||
{
|
||||
char buff[40] = {};
|
||||
snprintf(buff,sizeof(buff),"%s %.1f %.1f", data->previsions.desc, data->previsions.min, data->previsions.max);
|
||||
ESP_LOGI(TAG, "CB meteo jour declenché. Meteo valide : %s", buff);
|
||||
ESP_LOGI(TAG, "meteo jour declenché. Meteo valide : %s", buff);
|
||||
lv_obj_t *parent = (lv_obj_t *)(lv_observer_get_target(observer));
|
||||
lv_obj_dump_tree(parent->parent);
|
||||
//lv_obj_dump_tree(parent->parent);
|
||||
ESP_LOGI(TAG, "On accede au parent %p %s", (void*)parent, lv_obj_get_name(parent));
|
||||
if(parent!=NULL){
|
||||
if(isMinimal){
|
||||
@ -522,34 +567,57 @@ static void weatherdata_obs_cb(lv_observer_t *observer, lv_subject_t *subject)
|
||||
}
|
||||
}
|
||||
}
|
||||
//free(data);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
static void weatherdataHeure_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;
|
||||
bool isMinimal = observer->user_data;
|
||||
//ESP_LOGE(TAG, "CB meteo horaire declenché. Meteo valide : %d - Mode minimal : %d", data->isValid, isMinimal);
|
||||
|
||||
if(data->isValid){
|
||||
|
||||
//printffd(data);
|
||||
char buff[40] = {};
|
||||
snprintf(buff,sizeof(buff),"%.1f", data->previsions.value);
|
||||
ESP_LOGV(TAG, "On a recu [%s]", buff);
|
||||
//ESP_LOGE(TAG, "On a recu %s - [%s] - %s", data->type, buff, data->previsions.icon);
|
||||
|
||||
if(isMinimal){
|
||||
lv_obj_t *parent = (lv_obj_t *)(lv_observer_get_target(observer));
|
||||
//lv_obj_dump_tree(parent);
|
||||
|
||||
lv_obj_t *timefld = lv_obj_get_child(parent, 0);
|
||||
char buffer[8];
|
||||
dtHToString(data->datetime, buffer,8);
|
||||
lv_label_set_text(timefld, buffer);
|
||||
showMeteoIcon(data->previsions.icon, parent, 1);
|
||||
lv_obj_t *descfld = lv_obj_get_child(parent, 2);
|
||||
lv_label_set_text(descfld, data->previsions.desc);
|
||||
lv_obj_t *valuefld = lv_obj_get_child(parent, 3);
|
||||
lv_label_set_text_fmt(valuefld, "%.1f°C", data->previsions.value);
|
||||
|
||||
}else{
|
||||
lv_obj_t *parent = (lv_obj_t *)(lv_observer_get_target(observer));
|
||||
lv_obj_dump_tree(parent);
|
||||
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);
|
||||
char buffer[8];
|
||||
dtHToString(data->datetime, buffer,8);
|
||||
|
||||
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);
|
||||
}
|
||||
//free(data);
|
||||
|
||||
}else{
|
||||
ESP_LOGE(TAG, "Pas de odnnées valides");
|
||||
@ -560,14 +628,17 @@ static void weatherdataH_obs_cb(lv_observer_t *observer, lv_subject_t *subject)
|
||||
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 *str1 = "A:/home/marc/domotic/components/domotic_display/images_meteo";
|
||||
#if CONFIG_IDF_TARGET_LINUX
|
||||
char *str1 = "A:/home/marc/esp/domotic/domotic/components/domotic_display/images_meteo/";
|
||||
#else
|
||||
char *str1 = "A:/littlefs/images_meteo/";
|
||||
#endif
|
||||
int sizeOfStr;
|
||||
sizeOfStr = strlen(str1) + strlen(icon) + 6;
|
||||
char *result = malloc(sizeOfStr);
|
||||
snprintf(result,sizeOfStr, "%s%s.png", str1, icon);
|
||||
ESP_LOGV(TAG,"On affiche l'image %s", result);
|
||||
lv_image_set_src(img, "A:/home/marc/esp/domotic/domotic/components/domotic_display/images_meteo/p4j.png");
|
||||
lv_image_set_src(img, result);
|
||||
free(result);
|
||||
}
|
||||
|
||||
@ -577,7 +648,6 @@ static lv_style_t tempStyle;
|
||||
static void weatherDay_fragment_create_obj(int dayNr, lv_obj_t *parent, bool minimal)
|
||||
{
|
||||
|
||||
|
||||
if (minimal)
|
||||
{
|
||||
//lv_obj_set_flex_flow(sup, LV_FLEX_FLOW_COLUMN);
|
||||
@ -586,6 +656,7 @@ static void weatherDay_fragment_create_obj(int dayNr, lv_obj_t *parent, bool min
|
||||
//lv_obj_set_style_border_width(sup, 1, 0);
|
||||
//lv_obj_set_style_border_color(sup, lv_color_white(), 0);
|
||||
|
||||
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_t *container = lv_obj_create(parent);
|
||||
lv_obj_set_align(container, LV_ALIGN_CENTER);
|
||||
lv_obj_set_name(container, "container_meteo");
|
||||
@ -628,7 +699,7 @@ static void weatherDay_fragment_create_obj(int dayNr, lv_obj_t *parent, bool min
|
||||
|
||||
// On positionne un observer sur le subjet correspondant au jour du widget
|
||||
bool isMinimal = true;
|
||||
lv_subject_add_observer_obj(tmpSubj[dayNr], weatherdata_obs_cb, parent, &isMinimal);
|
||||
lv_subject_add_observer_obj(tmpDSubj[dayNr], weatherdataJour_obs_cb, parent, &isMinimal);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -686,15 +757,15 @@ static void weatherDay_fragment_create_obj(int dayNr, lv_obj_t *parent, bool min
|
||||
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_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);
|
||||
//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);
|
||||
lv_subject_add_observer_obj(tmpDSubj[dayNr], weatherdataJour_obs_cb, sup, NULL);
|
||||
}
|
||||
|
||||
//return container;
|
||||
@ -703,9 +774,76 @@ static void weatherDay_fragment_create_obj(int dayNr, lv_obj_t *parent, bool min
|
||||
static lv_style_t tempStyle;
|
||||
|
||||
// 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)
|
||||
static lv_obj_t* weatherH_fragment_create_obj(int horaireNr, lv_obj_t *parent, bool minimal)
|
||||
{
|
||||
|
||||
lv_obj_t *container = lv_obj_create(parent);
|
||||
if (minimal)
|
||||
{
|
||||
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_ROW);
|
||||
//lv_obj_set_flex_flow(sup, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_size(parent, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
//lv_obj_set_flex_align(sup, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||
//lv_obj_set_style_border_width(sup, 1, 0);
|
||||
//lv_obj_set_style_border_color(sup, lv_color_white(), 0);
|
||||
|
||||
lv_obj_set_align(container, LV_ALIGN_CENTER);
|
||||
char name[17];
|
||||
snprintf(name, 17,"%s%d","container_meteo", horaireNr);
|
||||
lv_obj_set_name(container, name);
|
||||
// lv_obj_remove_style_all(container);
|
||||
// lv_obj_set_style_border_width(container, 1, 0);
|
||||
// lv_obj_set_style_border_color(container, lv_color_make(0, 255, 0), 0);
|
||||
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_size(container, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
lv_obj_add_flag(container, LV_OBJ_FLAG_EVENT_BUBBLE);
|
||||
|
||||
lv_obj_t *heure = lv_label_create(container);
|
||||
lv_label_set_text(heure, "--");
|
||||
lv_obj_add_style(heure, &tempStyle, 0);
|
||||
lv_obj_set_style_text_font(heure,lv_theme_get_font_normal(heure),0);
|
||||
|
||||
lv_obj_t *img1 = lv_image_create(container);
|
||||
lv_obj_set_name(img1, "meteo_img");
|
||||
lv_obj_add_flag(img1, LV_OBJ_FLAG_EVENT_BUBBLE);
|
||||
|
||||
lv_obj_remove_style_all(img1);
|
||||
//lv_obj_set_style_bg_color(img1, lv_color_white(),0);
|
||||
//lv_obj_set_style_border_width(img1,1,0);
|
||||
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, 35);
|
||||
lv_image_set_src(img1, LV_SYMBOL_DUMMY);
|
||||
//lv_obj_set_style_image_recolor_opa(img1, 100, 0);
|
||||
//lv_obj_set_style_image_recolor(img1, lv_color_black(), 0);
|
||||
// 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_obj_set_name(desc, "meteo_desc");
|
||||
lv_label_set_long_mode(desc, LV_LABEL_LONG_MODE_WRAP);
|
||||
lv_obj_set_size(desc, 130, LV_SIZE_CONTENT);
|
||||
//lv_obj_set_style_text_color(desc, lv_color_white(), 0);
|
||||
lv_label_set_text(desc, name);
|
||||
lv_obj_set_style_text_align(desc, LV_TEXT_ALIGN_CENTER, 0);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
// On positionne un observer sur le subjet correspondant a l'horaire du widget
|
||||
bool isMinimal = true;
|
||||
//ESP_LOGE(TAG, "on positionne obs sur horaire %d", horaireNr);
|
||||
lv_subject_add_observer_obj(tmpHSubj[horaireNr], weatherdataHeure_obs_cb, container, &isMinimal);
|
||||
}else{
|
||||
lv_obj_t *sup = lv_obj_create(parent);
|
||||
|
||||
lv_obj_t *title = lv_label_create(sup);
|
||||
@ -748,8 +886,9 @@ static lv_obj_t* weatherH_fragment_create_obj(int horaireNr, lv_obj_t *parent)
|
||||
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_LOGV(TAG, "on positionne obs sur horaire %d", horaireNr);
|
||||
lv_subject_add_observer_obj(tmpHSubj[horaireNr], weatherdataH_obs_cb, sup, NULL);
|
||||
//ESP_LOGV(TAG, "on positionne obs sur horaire %d", horaireNr);
|
||||
lv_subject_add_observer_obj(tmpHSubj[horaireNr], weatherdataHeure_obs_cb, sup, NULL);
|
||||
}
|
||||
return container;
|
||||
}
|
||||
|
||||
@ -921,6 +1060,7 @@ 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);
|
||||
@ -932,7 +1072,7 @@ void draw_tabHome(lv_obj_t* parent){
|
||||
lv_obj_set_flex_flow(main, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_set_style_pad_column(main, 1, 0);
|
||||
|
||||
/*Conteneur Colonne: Températures*/
|
||||
//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));
|
||||
@ -940,7 +1080,7 @@ void draw_tabHome(lv_obj_t* parent){
|
||||
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*/
|
||||
//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);
|
||||
@ -949,7 +1089,7 @@ void draw_tabHome(lv_obj_t* parent){
|
||||
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*/
|
||||
// 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));
|
||||
@ -976,7 +1116,7 @@ void draw_tabHome(lv_obj_t* parent){
|
||||
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);
|
||||
@ -987,7 +1127,7 @@ void draw_tabHome(lv_obj_t* parent){
|
||||
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);
|
||||
@ -996,11 +1136,11 @@ void draw_tabHome(lv_obj_t* parent){
|
||||
lv_obj_set_flex_flow(cont_tempInt2, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_t * 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);
|
||||
//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, "");
|
||||
//lv_label_set_text(lblTempInt2, "");
|
||||
|
||||
//Create a container with COLUMN flex direction
|
||||
lv_obj_t *cont_Cuve = lv_obj_create(cont_colTemp);
|
||||
@ -1035,9 +1175,9 @@ void draw_tabHome(lv_obj_t* parent){
|
||||
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);
|
||||
weatherH_fragment_create_obj(0, cont_col3,false);
|
||||
weatherH_fragment_create_obj(1, cont_col3,false);
|
||||
weatherH_fragment_create_obj(2, cont_col3,false);
|
||||
}
|
||||
|
||||
void draw_tabCuve(lv_obj_t* parent)
|
||||
@ -1046,15 +1186,8 @@ void draw_tabCuve(lv_obj_t* parent)
|
||||
lv_image_set_src(imgGraf, "A:/sdcard/hello2.png");
|
||||
}
|
||||
|
||||
void draw_tabMeteo(lv_obj_t * parent)
|
||||
{
|
||||
weatherDay_fragment_create_obj(0,parent, false);
|
||||
weatherDay_fragment_create_obj(1,parent, false);
|
||||
weatherDay_fragment_create_obj(2,parent, false);
|
||||
//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)
|
||||
{
|
||||
@ -1096,7 +1229,7 @@ void draw_tabVolets(lv_obj_t* parent)
|
||||
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 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);
|
||||
|
||||
@ -1140,6 +1273,16 @@ void draw_tabVolets(lv_obj_t* parent)
|
||||
}
|
||||
}
|
||||
|
||||
void draw_tabMeteo(lv_obj_t * parent)
|
||||
{
|
||||
weatherDay_fragment_create_obj(0,parent, false);
|
||||
weatherDay_fragment_create_obj(1,parent, false);
|
||||
weatherDay_fragment_create_obj(2,parent, false);
|
||||
//manager2 = lv_fragment_manager_create(NULL);
|
||||
//fragment2 = lv_fragment_create(&meteodailyforecast_cls, (void *)1);
|
||||
//lv_fragment_manager_add(manager2, fragment2, &parent);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
lv_obj_t *date_group;
|
||||
lv_span_t *date_day;
|
||||
@ -1163,69 +1306,47 @@ static inline void u8_to_2digits(char *buf, uint8_t v)
|
||||
}
|
||||
|
||||
|
||||
// Ce callback est appelé lorsque le pointeur "tempExt"/"tempInt" est modifié
|
||||
static void temp_observer_cb(lv_observer_t *observer, lv_subject_t *subject){
|
||||
lv_obj_t *tempObj = lv_observer_get_target_obj(observer);
|
||||
char *templateValue = lv_observer_get_user_data(observer);
|
||||
char *temp = lv_subject_get_string(subject);
|
||||
//ESP_LOGE(TAG,"On passe dans temp_observer_cb pour %s avec %s - %s ",lv_obj_get_name(tempObj), templateValue, temp);
|
||||
lv_label_set_text_fmt(tempObj,templateValue,temp);
|
||||
}
|
||||
|
||||
static void time_observer_cb(lv_observer_t *observer, lv_subject_t *subject)
|
||||
{
|
||||
LV_UNUSED(observer);
|
||||
|
||||
lv_obj_t *dateTimeObj = lv_observer_get_target_obj(observer);
|
||||
datetime_ctx_t *ctx = lv_obj_get_user_data(dateTimeObj);
|
||||
if (!ctx) return;
|
||||
lv_obj_t *parent = observer->target;
|
||||
struct tm *timeStruct=lv_subject_get_pointer(subject);
|
||||
|
||||
struct tm *t = (struct tm *)lv_subject_get_pointer(subject);
|
||||
if (!t) return;
|
||||
ESP_LOGE(TAG,"%d %d %d %02d:%02d", t->tm_wday, t->tm_mday, t->tm_mon, t->tm_hour, t->tm_min);
|
||||
lv_obj_t *day = lv_obj_find_by_name(parent, "day");
|
||||
lv_obj_t *month = lv_obj_find_by_name(parent, "month");
|
||||
|
||||
char buf[4];
|
||||
bool refresh_date = false;
|
||||
bool refresh_time = false;
|
||||
lv_obj_t *hour = lv_obj_find_by_name(parent, "hour");
|
||||
lv_obj_t *minute = lv_obj_find_by_name(parent, "minute");
|
||||
|
||||
// ---- DATE ----
|
||||
if (t->tm_mday != ctx->last_day) {
|
||||
ctx->last_day = t->tm_mday;
|
||||
u8_to_2digits(buf, t->tm_mday);
|
||||
buf[2] = '/';
|
||||
buf[3] = '\0';
|
||||
ESP_LOGE(TAG,"Jour %s",buf);
|
||||
lv_span_set_text(ctx->date_day, buf);
|
||||
refresh_date = true;
|
||||
}
|
||||
|
||||
if ((t->tm_mon + 1) != ctx->last_month) {
|
||||
ctx->last_month = t->tm_mon + 1;
|
||||
u8_to_2digits(buf, ctx->last_month);
|
||||
ESP_LOGE(TAG,"Mois %s",buf);
|
||||
lv_span_set_text(ctx->date_month, buf);
|
||||
refresh_date = true;
|
||||
}
|
||||
int d = timeStruct->tm_mday;
|
||||
int monthVal = timeStruct->tm_mon;
|
||||
int h = timeStruct->tm_hour;
|
||||
int m = timeStruct->tm_min;
|
||||
|
||||
if (refresh_date) {
|
||||
lv_spangroup_refresh(ctx->date_group);
|
||||
}
|
||||
char buf[12];
|
||||
|
||||
// ---- TIME ----
|
||||
if (t->tm_hour != ctx->last_hour) {
|
||||
ctx->last_hour = t->tm_hour;
|
||||
u8_to_2digits(buf, t->tm_hour);
|
||||
ESP_LOGE(TAG,"Heure %s",buf);
|
||||
lv_span_set_text(ctx->time_hour, buf);
|
||||
refresh_time = true;
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "%02d", d);
|
||||
lv_label_set_text(day, buf);
|
||||
|
||||
if (t->tm_min != ctx->last_min) {
|
||||
ctx->last_min = t->tm_min;
|
||||
buf[0] = ':';
|
||||
buf[1] = '0' + (t->tm_min / 10);
|
||||
buf[2] = '0' + (t->tm_min % 10);
|
||||
buf[3] = '\0';
|
||||
ESP_LOGE(TAG,"Minutes %s",buf);
|
||||
lv_span_set_text(ctx->time_min, buf);
|
||||
refresh_time = true;
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "%02d", monthVal+1);
|
||||
lv_label_set_text(month, buf);
|
||||
|
||||
if (refresh_time) {
|
||||
lv_spangroup_refresh(ctx->time_group);
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "%02d", h);
|
||||
lv_label_set_text(hour, buf);
|
||||
|
||||
snprintf(buf, sizeof(buf), "%02d", m);
|
||||
lv_label_set_text(minute, buf);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@ -1397,6 +1518,7 @@ void messageCardContent(lv_obj_t *cont_messages)
|
||||
|
||||
lv_obj_t *btnUp = lv_button_create(cont_colVolets);
|
||||
lv_obj_set_id(btnUp, (void *)"CV_BT_UP");
|
||||
lv_obj_set_size(btnUp,60,60);
|
||||
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);
|
||||
@ -1411,6 +1533,7 @@ void messageCardContent(lv_obj_t *cont_messages)
|
||||
lv_obj_set_name(btnDwn, "btnDown_#");
|
||||
|
||||
lv_obj_add_style(btnDwn, &style_btn, 0);
|
||||
lv_obj_set_size(btnDwn,60,60);
|
||||
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);
|
||||
@ -1423,15 +1546,57 @@ void messageCardContent(lv_obj_t *cont_messages)
|
||||
{
|
||||
// lv_obj_t *txt = lv_label_create(container);
|
||||
// lv_label_set_text(txt, "Meteo");
|
||||
weatherDay_fragment_create_obj(0, container, true);
|
||||
weatherH_fragment_create_obj(0, container,true);
|
||||
weatherH_fragment_create_obj(1, container,true);
|
||||
weatherH_fragment_create_obj(2, container,true);
|
||||
// lv_subject_add_observer_obj(&forecastD1Subj, weatherdata_obs_cb, container, NULL);
|
||||
}
|
||||
|
||||
lv_obj_t *txtMinuteur;
|
||||
void minuteurCardContent(lv_obj_t * container)
|
||||
{
|
||||
lv_obj_t *txt = lv_label_create(container);
|
||||
lv_label_set_text(txt, "Rien à signaler !");
|
||||
txtMinuteur = lv_label_create(container);
|
||||
lv_label_set_long_mode(txtMinuteur, LV_LABEL_LONG_MODE_WRAP);
|
||||
lv_label_set_text(txtMinuteur, "Rien à signaler !");
|
||||
lv_obj_set_width(txtMinuteur, LV_PCT(100));
|
||||
}
|
||||
|
||||
|
||||
lv_obj_t *btnStopNotif;
|
||||
static void minuteur_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_CLICKED:
|
||||
send_event(EVT_FIN_MACHINE_STOP_NOTIF,NULL);
|
||||
lv_obj_delete(btnStopNotif);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void draw_minuteur(char *txt){
|
||||
lv_label_set_text(txtMinuteur, txt);
|
||||
}
|
||||
|
||||
void draw_minuteurStop(char *txt){
|
||||
lv_obj_t *ctr = lv_obj_get_parent(txtMinuteur);
|
||||
btnStopNotif = lv_btn_create(ctr);
|
||||
lv_obj_add_event_cb(btnStopNotif, minuteur_event_handler, LV_EVENT_ALL, NULL);
|
||||
lv_obj_t * label=lv_label_create(btnStopNotif);
|
||||
lv_label_set_text(label, "Stop !");
|
||||
lv_obj_center(label);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void backCb(lv_event_t * e)
|
||||
{
|
||||
ESP_LOGE(TAG, "We're here !!!!!!!!!!!!!!!!!!!!!!");
|
||||
@ -1457,15 +1622,7 @@ void messageCardContent(lv_obj_t *cont_messages)
|
||||
lv_obj_set_size(meteoContainer, LV_PCT(100), LV_PCT(100));
|
||||
lv_obj_set_flex_flow(meteoContainer, LV_FLEX_FLOW_COLUMN);
|
||||
|
||||
lv_obj_t *back = lv_label_create(meteoContainer);
|
||||
lv_obj_add_flag(back, LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_set_id(back, "backBtn");
|
||||
lv_label_set_text(back, LV_SYMBOL_HOME);
|
||||
//lv_obj_set_style_border_color(back, lv_color_make(255, 0, 0), 0);
|
||||
//lv_obj_set_style_border_width(back, 1, 0);
|
||||
lv_obj_set_style_text_font(back, lv_theme_get_font_large(back), 0);
|
||||
//lv_obj_set_style_text_color(back, lv_color_white(), 0);
|
||||
lv_obj_add_event_cb(back, backCb, LV_EVENT_CLICKED, NULL);
|
||||
createBackBtn(meteoContainer);
|
||||
|
||||
lv_obj_t *title = lv_label_create(meteoContainer);
|
||||
lv_obj_set_id(title, "titleMeteoLbl");
|
||||
@ -1485,15 +1642,7 @@ void messageCardContent(lv_obj_t *cont_messages)
|
||||
lv_obj_set_size(meteoContainer, LV_PCT(100), LV_PCT(100));
|
||||
lv_obj_set_flex_flow(meteoContainer, LV_FLEX_FLOW_COLUMN);
|
||||
|
||||
lv_obj_t *back = lv_label_create(meteoContainer);
|
||||
lv_obj_add_flag(back, LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_set_id(back, "backBtn");
|
||||
lv_label_set_text(back, LV_SYMBOL_HOME);
|
||||
//lv_obj_set_style_border_color(back, lv_color_make(255, 0, 0), 0);
|
||||
//lv_obj_set_style_border_width(back, 1, 0);
|
||||
lv_obj_set_style_text_font(back, lv_theme_get_font_large(back), 0);
|
||||
lv_obj_set_style_text_color(back, lv_color_white(), 0);
|
||||
lv_obj_add_event_cb(back, backCb, LV_EVENT_CLICKED, NULL);
|
||||
createBackBtn(meteoContainer);
|
||||
|
||||
lv_obj_t *title = lv_label_create(meteoContainer);
|
||||
lv_obj_set_id(title, "titleMeteoLbl");
|
||||
@ -1515,15 +1664,7 @@ void messageCardContent(lv_obj_t *cont_messages)
|
||||
lv_obj_set_size(meteoContainer, LV_PCT(100), LV_PCT(100));
|
||||
lv_obj_set_flex_flow(meteoContainer, LV_FLEX_FLOW_COLUMN);
|
||||
|
||||
lv_obj_t *back = lv_label_create(meteoContainer);
|
||||
lv_obj_add_flag(back, LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_set_id(back, "backBtn");
|
||||
lv_label_set_text(back, LV_SYMBOL_HOME);
|
||||
//lv_obj_set_style_border_color(back, lv_color_make(255, 0, 0), 0);
|
||||
//lv_obj_set_style_border_width(back, 1, 0);
|
||||
lv_obj_set_style_text_font(back, lv_theme_get_font_large(back), 0);
|
||||
lv_obj_set_style_text_color(back, lv_color_white(), 0);
|
||||
lv_obj_add_event_cb(back, backCb, LV_EVENT_CLICKED, NULL);
|
||||
createBackBtn(meteoContainer);
|
||||
|
||||
lv_obj_t *title = lv_label_create(meteoContainer);
|
||||
lv_obj_set_id(title, "titleMeteoLbl");
|
||||
@ -1546,15 +1687,7 @@ void messageCardContent(lv_obj_t *cont_messages)
|
||||
lv_obj_set_size(meteoContainer, LV_PCT(100), LV_PCT(100));
|
||||
lv_obj_set_flex_flow(meteoContainer, LV_FLEX_FLOW_COLUMN);
|
||||
|
||||
lv_obj_t *back = lv_label_create(meteoContainer);
|
||||
lv_obj_add_flag(back, LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_set_id(back, "backBtn");
|
||||
lv_label_set_text(back, LV_SYMBOL_HOME);
|
||||
//lv_obj_set_style_border_color(back, lv_color_make(255, 0, 0), 0);
|
||||
//lv_obj_set_style_border_width(back, 1, 0);
|
||||
lv_obj_set_style_text_font(back, lv_theme_get_font_large(back), 0);
|
||||
lv_obj_set_style_text_color(back, lv_color_white(), 0);
|
||||
lv_obj_add_event_cb(back, backCb, LV_EVENT_CLICKED, NULL);
|
||||
createBackBtn(meteoContainer);
|
||||
|
||||
lv_obj_t *title = lv_label_create(meteoContainer);
|
||||
lv_obj_set_id(title, "titleMeteoLbl");
|
||||
@ -1564,7 +1697,24 @@ void messageCardContent(lv_obj_t *cont_messages)
|
||||
lv_obj_add_event_cb(title, backCb, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
draw_tabMeteo(meteoContainer);
|
||||
}
|
||||
|
||||
void createBackBtn(lv_obj_t *meteoContainer)
|
||||
{
|
||||
lv_obj_t *backBtn = lv_button_create(meteoContainer);
|
||||
lv_obj_add_flag(backBtn, LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_set_id(backBtn, "backBtn");
|
||||
lv_obj_set_style_border_color(backBtn, lv_color_make(0, 0, 0), 0);
|
||||
lv_obj_set_style_border_width(backBtn, 1, 0);
|
||||
lv_obj_set_style_bg_opa(backBtn, 50, 0);
|
||||
lv_obj_set_size(backBtn, 80, 80);
|
||||
lv_obj_add_event_cb(backBtn, backCb, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_t *backBtnLbl = lv_label_create(backBtn);
|
||||
lv_label_set_text(backBtnLbl, LV_SYMBOL_HOME);
|
||||
lv_obj_set_align(backBtnLbl, LV_TEXT_ALIGN_CENTER);
|
||||
lv_obj_set_style_text_font(backBtnLbl, lv_theme_get_font_large(backBtnLbl), 0);
|
||||
lv_obj_set_style_text_color(backBtnLbl, lv_color_white(), 0);
|
||||
lv_obj_center(backBtnLbl);
|
||||
}
|
||||
|
||||
void messagerieCb(lv_obj_t *base_obj)
|
||||
@ -1573,6 +1723,7 @@ void messageCardContent(lv_obj_t *cont_messages)
|
||||
}
|
||||
void minuteurCb(lv_obj_t *base_obj)
|
||||
{
|
||||
send_event(EVT_FIN_MACHINE_STOP_NOTIF,NULL);
|
||||
drawMinuteur(base_obj);
|
||||
}
|
||||
void voletsCb(lv_obj_t *base_obj)
|
||||
@ -1602,21 +1753,29 @@ void messageCardContent(lv_obj_t *cont_messages)
|
||||
lv_obj_set_user_data(dateTimeObj, ctx);
|
||||
}
|
||||
|
||||
|
||||
void drawHome()
|
||||
{
|
||||
|
||||
void initHome(){
|
||||
/*Initialize the styles*/
|
||||
lv_style_init(&style_btn);
|
||||
// lv_style_set_bg_color(&style_btn, lv_palette_main(LV_PALETTE_GREEN));
|
||||
// lv_style_set_border_color(&style_btn, lv_palette_darken(LV_PALETTE_GREEN, 3));
|
||||
// lv_style_set_border_width(&style_btn, 3);
|
||||
|
||||
lv_style_init(&objstyle);
|
||||
lv_style_set_bg_color(&objstyle, accent);
|
||||
lv_style_set_outline_color(&objstyle, accent);
|
||||
|
||||
|
||||
lv_subject_init_string(&tempExtSubj, tempExtStr, NULL, 6, "--");
|
||||
lv_subject_init_string(&tempIntSubj, tempIntStr, NULL, 6, "--");
|
||||
lv_subject_init_string(&tempIntSubj, tempIntStr, NULL, 50, "--");
|
||||
lv_subject_init_string(&hauteurCuveSubj, hauteurCuveStr, NULL, 9, "--");
|
||||
lv_subject_init_string(&hauteurCuveEvolSubj, hauteurCuveEvolStr, NULL, 9, "--");
|
||||
|
||||
}
|
||||
|
||||
void drawHome()
|
||||
{
|
||||
|
||||
|
||||
// keys.clear();
|
||||
lv_obj_clean(lv_scr_act());
|
||||
|
||||
@ -1631,9 +1790,6 @@ void messageCardContent(lv_obj_t *cont_messages)
|
||||
lv_obj_set_style_pad_top(bg_cont, 5, 0);
|
||||
lv_obj_set_style_bg_color(bg_cont, bgColor, 0);
|
||||
|
||||
lv_style_init(&objstyle);
|
||||
lv_style_set_bg_color(&objstyle, accent);
|
||||
lv_style_set_outline_color(&objstyle, accent);
|
||||
|
||||
/* info area */
|
||||
|
||||
@ -1655,46 +1811,96 @@ void messageCardContent(lv_obj_t *cont_messages)
|
||||
//lv_obj_remove_style_all(date_and_time);
|
||||
lv_obj_set_size(date_and_time, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
|
||||
lv_obj_t *date = lv_spangroup_create(date_and_time);
|
||||
lv_obj_t *date = lv_obj_create(date_and_time);
|
||||
lv_obj_set_name(date, "date");
|
||||
lv_obj_set_id(date, "date");
|
||||
lv_obj_set_size(date, 250, LV_SIZE_CONTENT);
|
||||
lv_obj_clear_flag(date, LV_OBJ_FLAG_SCROLLABLE);
|
||||
lv_obj_set_style_bg_opa(date, LV_OPA_TRANSP, 0);
|
||||
lv_obj_set_style_border_width(date, 0, 0);
|
||||
// Layout flex horizontal
|
||||
lv_obj_set_flex_flow(date, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_set_flex_align(
|
||||
date,
|
||||
LV_FLEX_ALIGN_SPACE_BETWEEN, // répartit les enfants
|
||||
LV_FLEX_ALIGN_CENTER, // align vertical
|
||||
LV_FLEX_ALIGN_CENTER
|
||||
);
|
||||
// lv_obj_add_style(date, &c->fonts[FONT_HEADING_MD], 0);
|
||||
// lv_obj_add_style(date, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
|
||||
lv_span_t *day = lv_spangroup_add_span(date);
|
||||
lv_span_set_text(day, "--");
|
||||
lv_style_set_text_font(lv_span_get_style(day), &super_malibu_80);
|
||||
lv_style_set_text_color(lv_span_get_style(day), base);
|
||||
lv_style_set_line_color(lv_span_get_style(day), lv_color_black());
|
||||
lv_style_set_line_width(lv_span_get_style(day), 2);
|
||||
lv_span_t *month = lv_spangroup_add_span(date);
|
||||
lv_span_set_text(month, "--");
|
||||
lv_style_set_text_font(lv_span_get_style(month), &super_malibu_80);
|
||||
lv_obj_t *day = lv_label_create(date);
|
||||
lv_obj_set_name(day, "day");
|
||||
lv_label_set_text(day, "--");
|
||||
lv_obj_set_style_text_font(day, &super_malibu_80, 0);
|
||||
lv_obj_set_style_text_color(day, lv_color_white(), 0);
|
||||
lv_obj_set_style_line_color(day, lv_color_black(), 0);
|
||||
lv_obj_set_style_line_width(day, 2, 0);
|
||||
// --- / ---
|
||||
lv_obj_t *slash_lbl = lv_label_create(date);
|
||||
lv_obj_set_name(slash_lbl, "slash");
|
||||
lv_obj_set_style_text_font(slash_lbl, &super_malibu_80, 0);
|
||||
lv_obj_set_style_text_color(slash_lbl, base, 0);
|
||||
lv_label_set_text(slash_lbl, "/");
|
||||
|
||||
lv_obj_t *time = lv_spangroup_create(date_and_time);
|
||||
lv_obj_set_name(time, "time");
|
||||
lv_obj_set_id(time, "time");
|
||||
// lv_obj_add_style(time, &txtstyle, 0);
|
||||
lv_span_t *hourSpan = lv_spangroup_add_span(time);
|
||||
lv_span_set_text(hourSpan, "--");
|
||||
lv_style_set_text_font(lv_span_get_style(hourSpan), &super_malibu_80);
|
||||
lv_span_t *minute = lv_spangroup_add_span(time);
|
||||
lv_span_set_text(minute, ":--");
|
||||
lv_style_set_text_color(lv_span_get_style(minute), base);
|
||||
lv_style_set_line_color(lv_span_get_style(minute), accent);
|
||||
lv_style_set_text_font(lv_span_get_style(minute), &super_malibu_80);
|
||||
//lv_subject_add_observer_obj(&c->th, theme_observer_accent_span_cb, time, minute);
|
||||
lv_obj_t *month = lv_label_create(date);
|
||||
lv_obj_set_name(month, "month");
|
||||
lv_label_set_text(month, "--");
|
||||
lv_obj_set_style_text_font(month, &super_malibu_80,0);
|
||||
|
||||
lv_obj_t *objTime = lv_obj_create(date_and_time);
|
||||
lv_obj_set_size(objTime, 250, LV_SIZE_CONTENT);
|
||||
lv_obj_clear_flag(objTime, LV_OBJ_FLAG_SCROLLABLE);
|
||||
lv_obj_set_style_bg_opa(objTime, LV_OPA_TRANSP, 0);
|
||||
lv_obj_set_style_border_width(objTime, 0, 0);
|
||||
|
||||
// Layout flex horizontal
|
||||
lv_obj_set_flex_flow(objTime, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_set_flex_align(
|
||||
objTime,
|
||||
LV_FLEX_ALIGN_SPACE_BETWEEN, // répartit les enfants
|
||||
LV_FLEX_ALIGN_CENTER, // align vertical
|
||||
LV_FLEX_ALIGN_CENTER
|
||||
);
|
||||
|
||||
// --- HEURES ---
|
||||
lv_obj_t *hour_lbl = lv_label_create(objTime);
|
||||
lv_obj_set_name(hour_lbl, "hour");
|
||||
lv_obj_set_style_text_font(hour_lbl, &super_malibu_80, 0);
|
||||
lv_obj_set_style_text_color(hour_lbl, lv_color_white(), 0);
|
||||
lv_label_set_text(hour_lbl, "--");
|
||||
|
||||
// --- DEUX-POINTS ---
|
||||
lv_obj_t *colon_lbl = lv_label_create(objTime);
|
||||
lv_obj_set_name(colon_lbl, "colon");
|
||||
lv_obj_set_style_text_font(colon_lbl, &super_malibu_80, 0);
|
||||
lv_obj_set_style_text_color(colon_lbl, base, 0);
|
||||
lv_label_set_text(colon_lbl, ":");
|
||||
|
||||
// --- MINUTES ---
|
||||
lv_obj_t *minute_lbl = lv_label_create(objTime);
|
||||
lv_obj_set_name(minute_lbl, "minute");
|
||||
lv_obj_set_style_text_font(minute_lbl, &super_malibu_80, 0);
|
||||
lv_obj_set_style_text_color(minute_lbl, lv_color_white(), 0);
|
||||
lv_label_set_text(minute_lbl, "--");
|
||||
|
||||
// Init datetime
|
||||
//datetime_ctx_init(date_and_time);
|
||||
lv_subject_add_observer_obj(&timeSubj, time_observer_cb, date_and_time, NULL);
|
||||
datetime_ctx_init(date_and_time);
|
||||
|
||||
lv_obj_t * subContent = lv_obj_create(info_area);
|
||||
lv_obj_set_flex_flow(subContent, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_size(subContent, LV_PCT(70), LV_PCT(100));
|
||||
lv_obj_t *lblTempInt = lv_label_create(subContent);
|
||||
lv_label_set_text(lblTempInt, "\xEE\x86\xB0\xEF\x8B\x8A : 21°C");
|
||||
lblTempInt = lv_label_create(subContent);
|
||||
lv_obj_set_name(lblTempInt,"lblTempInt");
|
||||
char *templateValue="\xEE\x86\xB0\xEF\x8B\x8A : %s";
|
||||
lv_obj_set_style_text_font(lblTempInt, lv_theme_get_font_large(lblTempInt),0);
|
||||
lv_obj_t *lblTempExt = lv_label_create(subContent);
|
||||
lv_label_set_text(lblTempExt, LV_SYMBOL_HOME "\xEF\x8B\x8A : 12°C");
|
||||
lv_subject_add_observer_obj(&tempIntSubj, temp_observer_cb, lblTempInt, templateValue);
|
||||
|
||||
lblTempExt = lv_label_create(subContent);
|
||||
lv_obj_set_name(lblTempExt,"lblTempExt");
|
||||
char *templateValue2=LV_SYMBOL_HOME "\xEF\x8B\x8A : %s°C";
|
||||
lv_obj_set_style_text_font(lblTempExt, lv_theme_get_font_large(lblTempExt),0);
|
||||
lv_subject_add_observer_obj(&tempExtSubj, temp_observer_cb, lblTempExt, templateValue2);
|
||||
|
||||
/*for (size_t i = 0; i < 2; i++)
|
||||
{
|
||||
@ -1717,11 +1923,11 @@ void messageCardContent(lv_obj_t *cont_messages)
|
||||
lv_obj_set_flex_flow(apps, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_set_style_pad_column(apps, 6, 0);
|
||||
|
||||
create_card(apps, "Météo", meteoCardContent, meteoCb);
|
||||
create_card(apps, "Météo", meteoCardContent, meteoCb,400);
|
||||
|
||||
create_card(apps, "Volets", coverCardContent, voletsCb);
|
||||
create_card(apps, "Minuteur", minuteurCardContent, minuteurCb);
|
||||
create_card(apps, "Messagerie", messageCardContent, messagerieCb);
|
||||
create_card(apps, "Volets", coverCardContent, voletsCb,150);
|
||||
create_card(apps, "Minuteur", minuteurCardContent, minuteurCb,300);
|
||||
create_card(apps, "Messagerie", messageCardContent, messagerieCb,300);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1803,7 +2009,7 @@ static void app_card_click_cb(lv_event_t *e)
|
||||
app_cb(base_obj);
|
||||
}
|
||||
|
||||
void create_card(lv_obj_t *parent, char *lbl, void (*contentFct)(lv_obj_t *), app_cb_t app_cb)
|
||||
void create_card(lv_obj_t *parent, char *lbl, void (*contentFct)(lv_obj_t *), app_cb_t app_cb, int width)
|
||||
{
|
||||
//lv_style_init(&objstyle);
|
||||
//lv_style_init(&txtstyle);
|
||||
@ -1818,6 +2024,9 @@ void create_card(lv_obj_t *parent, char *lbl, void (*contentFct)(lv_obj_t *), ap
|
||||
lv_obj_set_id(app_card, "app_card");
|
||||
lv_obj_set_name(app_card, "app_card");
|
||||
//lv_obj_remove_style_all(app_card);
|
||||
if(width>0)
|
||||
lv_obj_set_size(app_card, width, 200);
|
||||
else
|
||||
lv_obj_set_size(app_card, 300, 200);
|
||||
//lv_obj_set_size(app_card, 100, 60);
|
||||
lv_obj_set_style_radius(app_card, 20, 0);
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include "platform_detect.h"
|
||||
#include "cJSON.h"
|
||||
#include "esp_log.h"
|
||||
#include "washingMachineState.h"
|
||||
|
||||
static const char *TAG = "IHM_GW";
|
||||
|
||||
@ -34,10 +35,11 @@ void ihm_gateway_post_event(xIHMEvent_t *evt) {
|
||||
|
||||
extern lv_subject_t wifiStatus;
|
||||
|
||||
static xIHMEvent_t *evt = NULL;
|
||||
|
||||
void ihm_gateway_process_queue(void) {
|
||||
if (!xIHMEventQueue) return;
|
||||
|
||||
xIHMEvent_t *evt = NULL;
|
||||
|
||||
#if CONFIG_IDF_TARGET_LINUX
|
||||
while (xQueueReceive(xIHMEventQueue, &evt, pdMS_TO_TICKS(0)) == pdTRUE)
|
||||
@ -48,7 +50,7 @@ void ihm_gateway_process_queue(void) {
|
||||
if (!evt) return;
|
||||
|
||||
UBaseType_t pending = uxQueueMessagesWaiting(xIHMEventQueue);
|
||||
ESP_LOGE(TAG,"Evt recu %d. La queue comporte %d éléments à traiter", evt->eEventType, pending);
|
||||
ESP_LOGV(TAG,"Evt recu %d. La queue comporte %d éléments à traiter", evt->eEventType, pending);
|
||||
|
||||
lv_async_call(traiteEvt, evt);
|
||||
}
|
||||
@ -65,6 +67,7 @@ void traiteEvt(void *arg)
|
||||
|
||||
case IHM_EVT_TIME_SETTED:
|
||||
draw_time(evt->pvData);
|
||||
evt->bNeedToFreeData=false;
|
||||
break;
|
||||
|
||||
case IHM_EVT_OTA_STARTED:
|
||||
@ -73,6 +76,12 @@ void traiteEvt(void *arg)
|
||||
|
||||
case IHM_EVT_HUMID_TEMP:
|
||||
draw_temp((char *)evt->pvData);
|
||||
evt->bNeedToFreeData=false;
|
||||
break;
|
||||
|
||||
case IHM_EVT_TEMP_RECUE:
|
||||
draw_tempExt((char *)evt->pvData);
|
||||
evt->bNeedToFreeData=false;
|
||||
break;
|
||||
|
||||
case IHM_EVT_PUISSANCE_EMISE:
|
||||
@ -86,25 +95,20 @@ void traiteEvt(void *arg)
|
||||
case IHM_EVT_ETAT_MACHINE:
|
||||
{
|
||||
char *etatMachine = evt->pvData;
|
||||
cJSON *root = cJSON_Parse(etatMachine);
|
||||
bool enRoute = cJSON_GetObjectItem(root, "state")->valueint;
|
||||
int timestamp = cJSON_GetObjectItem(root, "timestamp")->valueint;
|
||||
|
||||
time_t rawtime = (time_t)timestamp;
|
||||
struct tm *heure_locale = localtime(&rawtime);
|
||||
char heureFormattee[50];
|
||||
strftime(heureFormattee, sizeof(heureFormattee), "%d/%m/%Y %H:%M:%S", heure_locale);
|
||||
|
||||
char etatFormate[90];
|
||||
snprintf(etatFormate, sizeof(etatFormate),
|
||||
enRoute ? "Machine en route depuis %s" : "Machine : Arrêt détecté depuis %s",
|
||||
heureFormattee);
|
||||
|
||||
WashingMachineState wms = traiteMessage(etatMachine);
|
||||
char etat[80];
|
||||
getEtatMachineStr(wms, etat,80);
|
||||
ESP_LOGI(TAG,"Etat machine : %s", etat);
|
||||
draw_minuteur(etat);
|
||||
// lv_label_set_text(lblEtatMachine, etatFormate);
|
||||
cJSON_Delete(root);
|
||||
break;
|
||||
}
|
||||
|
||||
case IHM_EVT_MACHINE_TERMINEE:
|
||||
{
|
||||
draw_minuteurStop();
|
||||
}
|
||||
|
||||
case IHM_EVT_HAUTEUR_CUVE:
|
||||
{
|
||||
float hauteur = *(float *)evt->pvData;
|
||||
@ -112,13 +116,39 @@ void traiteEvt(void *arg)
|
||||
break;
|
||||
}
|
||||
|
||||
case IHM_EVT_METEO_RECUE:{
|
||||
//(void *)evt->pvData; // Pointeur sur tableau
|
||||
//(void *)evt->pvData
|
||||
ESP_LOGI(TAG, "Reception evt MF");
|
||||
|
||||
// On ne veut liberer la memoire que lorsque l'evenement aura été traité!
|
||||
evt->bNeedToFreeData=false;
|
||||
meteo_event_payload_t *datas = (meteo_event_payload_t *) evt->pvData;
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
{
|
||||
ESP_LOGI(TAG,"Type: %s - Valide : %d - %s", datas->daily[i].type, datas->daily[i].isValid, datas->daily[i].previsions.desc);
|
||||
}
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
{
|
||||
ESP_LOGI(TAG,"Type: %s - Valide : %d - %s - %s - %f", datas->forecast[i].type, datas->forecast[i].isValid, datas->forecast[i].previsions.desc, datas->forecast[i].previsions.icon, datas->forecast[i].previsions.value);
|
||||
}
|
||||
|
||||
draw_meteo(datas);
|
||||
//lv_subject_set_int(&meteoStatus, 0);
|
||||
//display_unlock("weather_data_retreived");
|
||||
ESP_LOGI(TAG, "Fin Reception evt MF");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ESP_LOGE(TAG, "Evt inconnu");
|
||||
break;
|
||||
}
|
||||
// Nettoyage mémoire sécurisé
|
||||
if (evt->bNeedToFreeData && evt->pvData)
|
||||
if (evt->bNeedToFreeData && evt->pvData){
|
||||
//ESP_LOGE(TAG, "Libération mémoire");
|
||||
free(evt->pvData);
|
||||
}
|
||||
free(evt);
|
||||
ESP_LOGV(TAG, "Evt traité");
|
||||
}
|
||||
|
||||
@ -19,16 +19,23 @@ void showMeteoIcon(const char *icon, lv_obj_t *desc_icon, int childNr);
|
||||
|
||||
void draw_tabVolets();
|
||||
void meteoCb(lv_obj_t *base_obj);
|
||||
void createBackBtn(lv_obj_t *ontainer);
|
||||
void initHome();
|
||||
void drawHome();
|
||||
|
||||
void draw_time(struct tm *dateHeure);
|
||||
void draw_tempExt(char *tempHumid);
|
||||
void draw_minuteur(char *txt);
|
||||
void draw_minuteurStop();
|
||||
void draw_temp(char *tempHumid);
|
||||
|
||||
void draw_meteo(meteo_event_payload_t *meteo);
|
||||
|
||||
void create_card();
|
||||
|
||||
void weather_data_retreived_start();
|
||||
|
||||
void weather_data_retreived(meteodailyforecast_data dailyDatas[3], meteoforecast_data datas[3]);
|
||||
void weather_data_retreived(meteo_event_payload_t *datas);
|
||||
|
||||
void draw_tabMeteo(lv_obj_t * parent);
|
||||
|
||||
@ -38,4 +45,6 @@ void draw_tabCuve(lv_obj_t * parent);
|
||||
void draw_tabHome(lv_obj_t * parent);
|
||||
void draw_tabSettings(lv_obj_t * parent);
|
||||
|
||||
void suspendIHM();
|
||||
|
||||
void drawIhm(void *pvParameter);
|
||||
|
||||
@ -10,6 +10,7 @@ list(APPEND EXTRA_COMPONENT_DIRS
|
||||
../../stateManagement
|
||||
../../eventsManager
|
||||
../../RemindMe
|
||||
../../washingMachineState
|
||||
)
|
||||
|
||||
idf_build_set_property(COMPILE_DEFINITIONS "NO_DEBUG_STORAGE" APPEND)
|
||||
|
||||
@ -2,7 +2,7 @@ dependencies:
|
||||
idf:
|
||||
source:
|
||||
type: idf
|
||||
version: 5.5.2
|
||||
version: 5.5.0
|
||||
lvgl/lvgl:
|
||||
component_hash: 17e68bfd21f0edf4c3ee838e2273da840bf3930e5dbc3bfa6c1190c3aed41f9f
|
||||
dependencies: []
|
||||
|
||||
@ -20,7 +20,7 @@ idf_component_register(SRCS
|
||||
"../../include"
|
||||
"../mock"
|
||||
WHOLE_ARCHIVE
|
||||
REQUIRES lvgl meteofrance RemindMe)
|
||||
REQUIRES lvgl meteofrance RemindMe washingMachineState)
|
||||
|
||||
message("Including SDL2 support")
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
@ -1,3 +1,9 @@
|
||||
if(${IDF_TARGET} STREQUAL "esp32p4")
|
||||
idf_component_register(SRCS "obtain_time.c" "eventsManager.c" obtain_time.c
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES mqtt esp_netif)
|
||||
REQUIRES mqtt esp_netif meteofrance audio)
|
||||
else()
|
||||
idf_component_register(SRCS "obtain_time.c" "eventsManager.c" obtain_time.c
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES mqtt esp_netif meteofrance)
|
||||
endif()
|
||||
|
||||
@ -5,10 +5,14 @@
|
||||
#include "mqtt_client.h"
|
||||
#include "obtain_time.h"
|
||||
#include <time.h>
|
||||
#include "meteofrance.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
#include "audio.h"
|
||||
#endif
|
||||
|
||||
EventGroupHandle_t domotic_event_group;
|
||||
QueueHandle_t ihm_queue;
|
||||
//extern esp_mqtt_client_handle_t client;
|
||||
extern esp_mqtt_client_handle_t client;
|
||||
|
||||
static const char *TAG = "evtMgr";
|
||||
|
||||
@ -25,8 +29,43 @@ void startEvtManager(){
|
||||
/* Tache updateTime - FIN*/
|
||||
}
|
||||
|
||||
const char * domo_event_to_str(domo_events evt)
|
||||
{
|
||||
switch (evt) {
|
||||
case EVT_WIFI_CONNECTED: return "WIFI_CONNECTED";
|
||||
case EVT_TIME_SETTED: return "TIME_SETTED";
|
||||
case EVT_BTN_VOLET: return "BTN_VOLET";
|
||||
case EVT_PUISSANCE_RECUE: return "PUISSANCE_RECUE";
|
||||
case EVT_ETAT_MACHINE: return "ETAT_MACHINE";
|
||||
case EVT_HAUTEUR_CUVE: return "HAUTEUR_CUVE";
|
||||
case EVT_METEO_RECUE: return "METEO_RECUE";
|
||||
case EVT_TEMP_EXT: return "TEMP_EXT";
|
||||
case EVT_TEMP_INT: return "TEMP_INT";
|
||||
case EVT_FIN_MACHINE: return "FIN_MACHINE";
|
||||
case EVT_FIN_MACHINE_STOP_NOTIF: return "FIN_MACHINE_STOP_NOTIF";
|
||||
default: return "EVT_UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
const char * ihm_event_to_str(eIHMEvent_t evt)
|
||||
{
|
||||
switch (evt) {
|
||||
case IHM_EVT_WIFI_STATUS: return "IHM_WIFI_STATUS";
|
||||
case IHM_EVT_TIME_SETTED: return "IHM_TIME_SETTED";
|
||||
case IHM_EVT_OTA_STARTED: return "IHM_OTA_STARTED";
|
||||
case IHM_EVT_OTA_PROGRESS: return "IHM_OTA_PROGRESS";
|
||||
case IHM_EVT_HUMID_TEMP: return "IHM_HUMID_TEMP";
|
||||
case IHM_EVT_PUISSANCE_EMISE: return "IHM_PUISSANCE_EMISE";
|
||||
case IHM_EVT_ETAT_MACHINE: return "IHM_ETAT_MACHINE";
|
||||
case IHM_EVT_HAUTEUR_CUVE: return "IHM_HAUTEUR_CUVE";
|
||||
case IHM_EVT_METEO_RECUE: return "IHM_METEO_RECUE";
|
||||
case IHM_EVT_TEMP_RECUE: return "IHM_TEMP_RECUE";
|
||||
default: return "IHM_EVT_UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
void send_event(domo_events evt, void* pDatas) {
|
||||
ESP_LOGV(TAG,"On est dans l'event handler %i", evt);
|
||||
ESP_LOGI(TAG, "EventManager: On est dans l'event handler %s", domo_event_to_str(evt));
|
||||
|
||||
xIHMEvent_t *ihmEvt = malloc(sizeof(xIHMEvent_t));
|
||||
if (!ihmEvt) {
|
||||
@ -78,12 +117,13 @@ void send_event(domo_events evt, void* pDatas) {
|
||||
break;
|
||||
|
||||
case EVT_BTN_VOLET:
|
||||
//esp_mqtt_client_publish(client, "volets", pDatas, 0, 0, 0);
|
||||
esp_mqtt_client_publish(client, "volets", pDatas, 0, 0, 0);
|
||||
free(ihmEvt); // rien à envoyer à l'IHM
|
||||
ihmEvt = NULL;
|
||||
return;
|
||||
|
||||
case EVT_PUISSANCE_RECUE:
|
||||
ESP_LOGE(TAG, "Puissance recue %i", *(int*)pDatas);
|
||||
ESP_LOGI(TAG, "Puissance recue %i", *(int*)pDatas);
|
||||
int *data = malloc(sizeof(int));
|
||||
if (!data) {
|
||||
ESP_LOGE(TAG, "malloc failed for puissance_5mn");
|
||||
@ -110,6 +150,38 @@ void send_event(domo_events evt, void* pDatas) {
|
||||
ihmEvt->bNeedToFreeData = true;
|
||||
break;
|
||||
|
||||
case EVT_TEMP_EXT:
|
||||
const char *msg3 = (const char *)pDatas;
|
||||
char *msg_copy3 = malloc(strlen(msg3) + 1);
|
||||
if (!msg_copy3) {
|
||||
ESP_LOGE(TAG, "malloc failed for message string");
|
||||
free(ihmEvt);
|
||||
return;
|
||||
}
|
||||
strcpy(msg_copy3, msg3);
|
||||
ihmEvt->eEventType = IHM_EVT_TEMP_RECUE;
|
||||
ihmEvt->pvData = msg_copy3;
|
||||
ihmEvt->bNeedToFreeData = true;
|
||||
break;
|
||||
|
||||
case EVT_TEMP_INT:
|
||||
const char *msg4 = (const char *)pDatas;
|
||||
char *msg_copy4 = malloc(strlen(msg4) + 1);
|
||||
if (!msg_copy4) {
|
||||
ESP_LOGE(TAG, "malloc failed for message string");
|
||||
free(ihmEvt);
|
||||
return;
|
||||
}
|
||||
strcpy(msg_copy4, msg4);
|
||||
ihmEvt->eEventType = IHM_EVT_HUMID_TEMP;
|
||||
ihmEvt->pvData = msg_copy4;
|
||||
ihmEvt->bNeedToFreeData = true;
|
||||
|
||||
//On envoie les données via mqtt
|
||||
esp_mqtt_client_publish(client, topicTempInt, pDatas, 0, 0, 0);
|
||||
|
||||
break;
|
||||
|
||||
case EVT_HAUTEUR_CUVE: {
|
||||
float *data = malloc(sizeof(float));
|
||||
if (!data) {
|
||||
@ -125,13 +197,49 @@ void send_event(domo_events evt, void* pDatas) {
|
||||
break;
|
||||
}
|
||||
|
||||
case EVT_METEO_RECUE:{
|
||||
meteo_event_payload_t *incoming = (meteo_event_payload_t *) pDatas;
|
||||
meteo_event_payload_t *payload = malloc(sizeof(meteo_event_payload_t));
|
||||
if (payload == NULL) {
|
||||
// gérer l’erreur
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(payload->daily, incoming->daily, sizeof(incoming->daily));
|
||||
memcpy(payload->forecast, incoming->forecast, sizeof(incoming->forecast));
|
||||
ihmEvt->eEventType = IHM_EVT_METEO_RECUE;
|
||||
ihmEvt->pvData = payload;
|
||||
ihmEvt->bNeedToFreeData = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case EVT_FIN_MACHINE:{
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
playSound();
|
||||
#endif
|
||||
ihmEvt->eEventType = IHM_EVT_MACHINE_TERMINEE;
|
||||
ihmEvt->pvData = NULL;
|
||||
ihmEvt->bNeedToFreeData = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case EVT_FIN_MACHINE_STOP_NOTIF:{
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
stopSound();
|
||||
#endif
|
||||
free(ihmEvt); // rien à envoyer à l'IHM
|
||||
ihmEvt = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ESP_LOGE(TAG, "Unhandled event type");
|
||||
free(ihmEvt);
|
||||
ihmEvt = NULL;
|
||||
return;
|
||||
}
|
||||
ESP_LOGE(TAG, "Envoi d'un evt %i a l'IHM", ihmEvt->eEventType);
|
||||
if( ihm_queue != NULL && ihmEvt){
|
||||
ESP_LOGI(TAG, "Suite %s : Envoi d'un evt %s (%i) a l'IHM", domo_event_to_str(evt), ihm_event_to_str(ihmEvt->eEventType),ihmEvt->eEventType);
|
||||
if (xQueueSendToFront(ihm_queue, &ihmEvt, pdMS_TO_TICKS(10)) != pdPASS)
|
||||
{
|
||||
ESP_LOGE(TAG, "La queue est pleine");
|
||||
@ -141,5 +249,8 @@ void send_event(domo_events evt, void* pDatas) {
|
||||
}
|
||||
free(ihmEvt);
|
||||
}
|
||||
}else{
|
||||
ESP_LOGI(TAG, "Suite %s : on n'envoie rien a l'IHM", domo_event_to_str(evt));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,6 +14,9 @@ typedef enum eIHMEvent_t{
|
||||
IHM_EVT_PUISSANCE_EMISE,
|
||||
IHM_EVT_ETAT_MACHINE,
|
||||
IHM_EVT_HAUTEUR_CUVE,
|
||||
IHM_EVT_METEO_RECUE,
|
||||
IHM_EVT_TEMP_RECUE,
|
||||
IHM_EVT_MACHINE_TERMINEE
|
||||
} eIHMEvent_t;
|
||||
|
||||
typedef struct IHM_EVENT
|
||||
@ -29,8 +32,22 @@ typedef enum domo_events{
|
||||
EVT_BTN_VOLET,
|
||||
EVT_PUISSANCE_RECUE,
|
||||
EVT_ETAT_MACHINE,
|
||||
EVT_HAUTEUR_CUVE
|
||||
EVT_HAUTEUR_CUVE,
|
||||
EVT_METEO_RECUE,
|
||||
EVT_TEMP_EXT,
|
||||
EVT_TEMP_INT,
|
||||
EVT_FIN_MACHINE,
|
||||
EVT_FIN_MACHINE_STOP_NOTIF
|
||||
} domo_events;
|
||||
void startEvtManager();
|
||||
QueueHandle_t getIHMQueueHandle();
|
||||
void send_event(domo_events evt, void *pDatas);
|
||||
|
||||
#define topicTempExt "house/temp/282A802600008059"
|
||||
#define topicHauteurCuve "house/cuve/hauteur"
|
||||
#define topicTempInt "house/temp/287DCF1E00008020"
|
||||
#define topicHauteurCuveEvol "house/cuve/hauteurEvol"
|
||||
#define topicConsoElec "energy/puissance_5mn"
|
||||
#define topicEtatMachine "energy/machine_en_route"
|
||||
#define topicdomoticCommand "domotic/cmd"
|
||||
#define topicTest "test"
|
||||
|
||||
@ -73,8 +73,6 @@ void updateTime(void *pvParameter)
|
||||
while (1)
|
||||
{
|
||||
time(&now);
|
||||
setenv("TZ", "CET-1CEST,M3.5.0,M10.5.0/3", 1);
|
||||
tzset();
|
||||
struct tm timeinfo = {0};
|
||||
localtime_r(&now, &timeinfo);
|
||||
sprintf(strftime_buf, "%s %d %s %02d:%02d (%lli mn depuis reboot)", days[timeinfo.tm_wday], timeinfo.tm_mday, months[timeinfo.tm_mon], timeinfo.tm_hour, timeinfo.tm_min, (esp_timer_get_time() / 1000 / 1000 / 60));
|
||||
|
||||
@ -29,21 +29,28 @@
|
||||
char icon[9];
|
||||
};
|
||||
|
||||
typedef struct meteodailyforecast_data
|
||||
typedef struct meteodailyforecast_data // Meteo "par jour"
|
||||
{
|
||||
char *type;
|
||||
time_t datetime;
|
||||
bool isValid;
|
||||
struct dailyforecast_prev previsions;
|
||||
} meteodailyforecast_data;
|
||||
|
||||
typedef struct meteoforecast_data
|
||||
typedef struct meteoforecast_data // Meteo "par heure"
|
||||
{
|
||||
char *type;
|
||||
time_t datetime;
|
||||
bool isValid;
|
||||
struct forecast_prev previsions;
|
||||
} meteoforecast_data;
|
||||
|
||||
typedef void (*weather_data_callback)(struct meteodailyforecast_data *datas, struct meteoforecast_data *datasf);
|
||||
typedef struct {
|
||||
meteodailyforecast_data daily[3];
|
||||
meteoforecast_data forecast[3];
|
||||
} meteo_event_payload_t;
|
||||
|
||||
typedef void (*weather_data_callback)(meteo_event_payload_t *datas);
|
||||
typedef void (*weather_data_start_callback)();
|
||||
|
||||
typedef struct
|
||||
@ -60,7 +67,7 @@
|
||||
void printftemp(struct forecast_prev * tmp);
|
||||
void printfdf(struct meteodailyforecast_data * tmp);
|
||||
void dtToString(time_t, char *buffer);
|
||||
void dtHToString(time_t, char *buffer);
|
||||
void dtHToString(time_t, char *buffer, size_t bufSize);
|
||||
void printff(struct meteoforecast_data * tmp);
|
||||
|
||||
void on_weather_data_retrieval(weather_data_callback data_retreived_cb);
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "esp_http_client.h"
|
||||
#include "esp_tls.h"
|
||||
#include "stateManagement.h"
|
||||
#include "eventsManager.h"
|
||||
static const char *TAG = "MeteoFrance";
|
||||
|
||||
/* Constants that aren't configurable in menuconfig
|
||||
@ -39,8 +40,8 @@ static const char *TAG = "MeteoFrance";
|
||||
#define MAX_HTTP_OUTPUT_BUFFER 32000
|
||||
|
||||
static weather_data weather;
|
||||
static struct meteodailyforecast_data dailydatas[5];
|
||||
static struct meteoforecast_data forecastdatas[5];
|
||||
static struct meteodailyforecast_data dailydatas[3];
|
||||
static struct meteoforecast_data forecastdatas[3];
|
||||
|
||||
void printdftemp(struct dailyforecast_prev *tmp)
|
||||
{
|
||||
@ -69,10 +70,10 @@ void dtToString(time_t ttt, char* buffer){
|
||||
//sprintf(strftime_buf, "%d %d %d", timeinfo.tm_wday, timeinfo.tm_mday, timeinfo.tm_mon + 1);
|
||||
}
|
||||
|
||||
void dtHToString(time_t ttt, char* buffer){
|
||||
void dtHToString(time_t ttt, char* buffer, size_t bufSize){
|
||||
struct tm timeinfo = {0};
|
||||
localtime_r(&ttt, &timeinfo);
|
||||
strftime(buffer, MAX_SIZE, "%H:%M", &timeinfo);
|
||||
strftime(buffer, bufSize, "%H:%M", &timeinfo);
|
||||
//char strftime_buf[64];
|
||||
//sprintf(strftime_buf, "%d %d %d", timeinfo.tm_wday, timeinfo.tm_mday, timeinfo.tm_mon + 1);
|
||||
}
|
||||
@ -247,6 +248,7 @@ void JSON_Parse(const cJSON *const root)
|
||||
cJSON *dt = cJSON_GetObjectItem(current_element, "dt");
|
||||
if (cJSON_IsNumber(dt))
|
||||
{
|
||||
datasT.type="Daily";
|
||||
datasT.datetime = dt->valueint;
|
||||
cJSON *temps = cJSON_GetObjectItem(current_element, "T");
|
||||
datasT.previsions.min = cJSON_GetObjectItem(temps, "min")->valuedouble;
|
||||
@ -278,6 +280,7 @@ void JSON_Parse(const cJSON *const root)
|
||||
cJSON *dt = cJSON_GetObjectItem(current_element, "dt");
|
||||
if (cJSON_IsNumber(dt))
|
||||
{
|
||||
datasT.type="Hourly";
|
||||
datasT.datetime = dt->valueint;
|
||||
struct tm timeinfo = {0};
|
||||
localtime_r(&(datasT.datetime), &timeinfo);
|
||||
@ -379,8 +382,13 @@ static void meteo_task(void* domotic_event_group)
|
||||
heap_caps_free(local_response_buffer);
|
||||
esp_http_client_cleanup(client);
|
||||
if(dailydatas->isValid){
|
||||
ESP_LOGV(TAG, "Données valides on appelle le cb");
|
||||
weather.data_retreived_cb(dailydatas, forecastdatas);
|
||||
ESP_LOGE(TAG, "Données valides on appelle le cb");
|
||||
meteo_event_payload_t *payload = malloc(sizeof(*payload));
|
||||
memcpy(payload->daily, dailydatas, sizeof(payload->daily));
|
||||
memcpy(payload->forecast, forecastdatas, sizeof(payload->forecast));
|
||||
send_event(EVT_METEO_RECUE, payload);
|
||||
//weather.data_retreived_cb(payload);
|
||||
free(payload);
|
||||
vTaskDelay(weather.retreival_period / portTICK_PERIOD_MS);
|
||||
}else{
|
||||
//Ca a échoué on recommence dans 30 secondes
|
||||
|
||||
2
components/washingMachineState/CMakeLists.txt
Normal file
@ -0,0 +1,2 @@
|
||||
idf_component_register(SRCS "washingMachineState.c" PRIV_REQUIRES json eventsManager
|
||||
INCLUDE_DIRS "include")
|
||||
5
components/washingMachineState/Readme.md
Normal file
@ -0,0 +1,5 @@
|
||||
But:
|
||||
Exposer l'état de la machine à laver
|
||||
Dans sa plus simple expression c'est un listener MQTT
|
||||
L'état de la machine est ensuite émise via une interface
|
||||
Le topic est en retain pour pouvoir garder le dernier état de la machine {etat, timestamp}
|
||||
24
components/washingMachineState/include/washingMachineState.h
Normal file
@ -0,0 +1,24 @@
|
||||
|
||||
typedef enum {
|
||||
LAVEUSE_ARRET,
|
||||
LAVEUSE_REMPLISSAGE,
|
||||
LAVEUSE_LAVAGE,
|
||||
LAVEUSE_RINCAGE,
|
||||
LAVEUSE_ESSORAGE,
|
||||
LAVEUSE_TERMINEE,
|
||||
LAVEUSE_ERREUR
|
||||
} WMState;
|
||||
|
||||
typedef struct {
|
||||
WMState etat; // Indique l'état de la machine
|
||||
double depuis; // timestamp de l'evenement
|
||||
bool ack; // Evenement acquitté ?
|
||||
} WashingMachineState;
|
||||
|
||||
WashingMachineState traiteMessage(char *message);
|
||||
|
||||
void timestampToDate(double timestamp, char* dateStr, size_t dateStrSize);
|
||||
|
||||
WashingMachineState getEtatMachine();
|
||||
void getEtatMachineStr(WashingMachineState wms, char* etat, size_t etatSize);
|
||||
void acknoledge();
|
||||
121
components/washingMachineState/washingMachineState.c
Normal file
@ -0,0 +1,121 @@
|
||||
#include <stdio.h>
|
||||
#include <cJSON.h>
|
||||
#include <esp_log.h>
|
||||
#include "washingMachineState.h"
|
||||
#include "eventsManager.h"
|
||||
#include <time.h>
|
||||
|
||||
#define TAG "WMS"
|
||||
|
||||
WashingMachineState wms;
|
||||
bool stateOn; // Indique si la machine est en route
|
||||
|
||||
WashingMachineState traiteMessage(char* message){
|
||||
|
||||
cJSON *root = cJSON_Parse(message);
|
||||
char* json = cJSON_PrintUnformatted(root);
|
||||
ESP_LOGE(TAG, "%s", json);
|
||||
|
||||
bool state = cJSON_IsTrue(cJSON_GetObjectItem(root, "state"));
|
||||
double timestamp = cJSON_GetNumberValue(cJSON_GetObjectItem(root, "timestamp"));
|
||||
bool ack = cJSON_HasObjectItem(root,"ack") && cJSON_GetNumberValue(cJSON_GetObjectItem(root,"ack"));
|
||||
|
||||
//char dateStr[80] ;
|
||||
//timestampToDate(timestamp,dateStr,80);
|
||||
|
||||
wms.etat = state?LAVEUSE_LAVAGE:LAVEUSE_ARRET;
|
||||
wms.depuis = timestamp;
|
||||
wms.ack = ack;
|
||||
|
||||
if(wms.etat==LAVEUSE_LAVAGE){
|
||||
stateOn=true;
|
||||
}
|
||||
if(wms.etat==LAVEUSE_ARRET && stateOn){
|
||||
//Fin détectée !
|
||||
stateOn=false;
|
||||
send_event(EVT_FIN_MACHINE, NULL);
|
||||
}
|
||||
|
||||
cJSON_Delete(root);
|
||||
|
||||
return wms;
|
||||
}
|
||||
|
||||
void timestampToDate(double timestamp, char* dateStr, size_t dateStrSize)
|
||||
{
|
||||
time_t ts = timestamp;
|
||||
struct tm *pTime = localtime(&ts);
|
||||
|
||||
strftime(dateStr, dateStrSize, "%d/%m/%Y %H:%M:%S", pTime);
|
||||
//printf("Date and french time : %s\n", dateStr);
|
||||
}
|
||||
|
||||
WashingMachineState getEtatMachine(){
|
||||
return wms;
|
||||
}
|
||||
|
||||
char *duree_depuis_timestamp_formatee(time_t timestamp)
|
||||
{
|
||||
time_t maintenant = time(NULL);
|
||||
long diff_minutes = (maintenant - timestamp) / 60;
|
||||
|
||||
if (diff_minutes < 0)
|
||||
diff_minutes = 0; // sécurité si timestamp futur
|
||||
|
||||
char *resultat = malloc(32);
|
||||
if (!resultat)
|
||||
return NULL;
|
||||
|
||||
if (diff_minutes < 60) {
|
||||
snprintf(resultat, 32, "%ldmn", diff_minutes);
|
||||
} else {
|
||||
long heures = diff_minutes / 60;
|
||||
long minutes = diff_minutes % 60;
|
||||
snprintf(resultat, 32, "%ldh%02ld", heures, minutes);
|
||||
}
|
||||
|
||||
return resultat;
|
||||
}
|
||||
|
||||
void getEtatMachineStr(WashingMachineState wms, char* etat, size_t etatSize)
|
||||
{
|
||||
char* etatStr;
|
||||
switch (wms.etat)
|
||||
{
|
||||
case LAVEUSE_ARRET:
|
||||
/* code */
|
||||
etatStr="Machine arretée";
|
||||
break;
|
||||
|
||||
case LAVEUSE_LAVAGE:
|
||||
/* code */
|
||||
etatStr="Machine en route";
|
||||
break;
|
||||
|
||||
default:
|
||||
etatStr="Etat inconnu";
|
||||
break;
|
||||
}
|
||||
|
||||
char dateStr[30];
|
||||
timestampToDate(wms.depuis,dateStr,30);
|
||||
|
||||
//Si la machine est en route on ajoute la durée en heures/minutes depuis le départ
|
||||
if(wms.etat==LAVEUSE_LAVAGE){
|
||||
char *duree = duree_depuis_timestamp_formatee(wms.depuis);
|
||||
if (duree) {
|
||||
printf("Durée : %s\n", duree);
|
||||
snprintf(etat,etatSize,"%s depuis %s\n (%s)", etatStr, duree, dateStr);
|
||||
free(duree);
|
||||
}
|
||||
}else{
|
||||
snprintf(etat,etatSize,"%s depuis %s", etatStr, dateStr);
|
||||
}
|
||||
|
||||
ESP_LOGE(TAG,"%s",etat);
|
||||
|
||||
}
|
||||
|
||||
void acknoledge(){
|
||||
wms.ack=true;
|
||||
}
|
||||
@ -1,16 +1,223 @@
|
||||
dependencies:
|
||||
espressif/esp_lcd_qemu_rgb:
|
||||
component_hash: e8981dd7399504a5ab647ce28a4876f8467c03b759895f50c24f0cb6095faaa0
|
||||
espressif/bh1750:
|
||||
component_hash: c8cae6dca70fd5fdf5943ae37efbbea6cc41bcb784506e61ea301b3e94dce74b
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=4.0'
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
version: 1.0.3
|
||||
espressif/cmake_utilities:
|
||||
component_hash: 351350613ceafba240b761b4ea991e0f231ac7a9f59a9ee901f751bddc0bb18f
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=4.1'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
version: 0.5.3
|
||||
espressif/eppp_link:
|
||||
component_hash: 9472e6825f4bb71eca2b39cf1bc92659c1ac60bfd7416560ad033a7dd8641b17
|
||||
dependencies:
|
||||
- name: espressif/esp_serial_slave_link
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: ^1.1.0
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.2'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
version: 1.1.4
|
||||
espressif/esp32_p4_function_ev_board:
|
||||
component_hash: 2d90a5160cd2aa81f1bc90edf90d802bdc15626b9ec6d699aa36a35bad119ed9
|
||||
dependencies:
|
||||
- name: espressif/esp_codec_dev
|
||||
registry_url: https://components.espressif.com
|
||||
require: public
|
||||
version: ~1.5
|
||||
- name: espressif/esp_lcd_ek79007
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: '>=2.0.1,<3.0.0'
|
||||
- name: espressif/esp_lcd_ili9881c
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: '>=1.0.3,<2.0.0'
|
||||
- name: espressif/esp_lcd_touch_gt911
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: ^1
|
||||
- name: espressif/esp_video
|
||||
registry_url: https://components.espressif.com
|
||||
require: public
|
||||
version: ~1.4
|
||||
- name: espressif/esp_lcd_lt8912b
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: '>=0.1.3,<1.0.0'
|
||||
- name: espressif/esp_lvgl_port
|
||||
registry_url: https://components.espressif.com
|
||||
require: public
|
||||
version: ^2
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.4'
|
||||
- name: lvgl/lvgl
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: '>=8,<10'
|
||||
- name: espressif/usb
|
||||
registry_url: https://components.espressif.com
|
||||
require: public
|
||||
rules:
|
||||
- if: idf_version >=6.0
|
||||
version: ^1.0.0
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
targets:
|
||||
- esp32p4
|
||||
version: 5.2.1
|
||||
espressif/esp_cam_sensor:
|
||||
component_hash: db5b1c725799dced61e7b100dc027e1e59558c9973d7e1ed8ce42a5ec89da31c
|
||||
dependencies:
|
||||
- name: espressif/cmake_utilities
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: 0.*
|
||||
- name: espressif/esp_sccb_intf
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: '>=0.0.5'
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.3'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
targets:
|
||||
- esp32p4
|
||||
- esp32s3
|
||||
- esp32c3
|
||||
- esp32c5
|
||||
- esp32c6
|
||||
- esp32c61
|
||||
version: 1.7.0
|
||||
espressif/esp_codec_dev:
|
||||
component_hash: 0d9e9bc288156eb55f79338d312e1ebf8c9dfbd5e7d13ef0f20ccb031b4e15cf
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=4.0'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
version: 1.5.4
|
||||
espressif/esp_h264:
|
||||
component_hash: fa5daaebc8a304f0b79bc57e51aab43e0a03eabc2ba3865bff4063c56b5d4564
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=4.4'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
version: 1.0.4
|
||||
espressif/esp_hosted:
|
||||
component_hash: 9eea9ce83444a412b4a02311f787f3639a5d29fe67e6df83863010dd68ab250b
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.3'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
version: 2.12.0
|
||||
espressif/esp_ipa:
|
||||
component_hash: 31003e536f0d26158e10d7fcf2448b6377ce1148518287d0f34ed3b6c942c6d8
|
||||
dependencies:
|
||||
- name: espressif/cmake_utilities
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: 0.*
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.4'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
targets:
|
||||
- esp32p4
|
||||
version: 1.3.1
|
||||
espressif/esp_lcd_ek79007:
|
||||
component_hash: 7a0896e167d88b9fc368ac74b2e84774ec5b48cd9baa390896c4be255d900e2e
|
||||
dependencies:
|
||||
- name: espressif/cmake_utilities
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: 0.*
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.3'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
targets:
|
||||
- esp32p4
|
||||
version: 2.0.2
|
||||
espressif/esp_lcd_ili9881c:
|
||||
component_hash: 0288df12755c95d406ccea245a427595f314df0b14a61846286d926ea6f3698e
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.3'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
targets:
|
||||
- esp32p4
|
||||
version: 1.1.0
|
||||
espressif/esp_lcd_lt8912b:
|
||||
component_hash: f954a3393c8e16159f0c7448c9f4312b58933a53563fe5173db5f63a2b0f7aa7
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.3'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
version: 0.2.0
|
||||
espressif/esp_lcd_touch:
|
||||
component_hash: 3f85a7d95af876f1a6ecca8eb90a81614890d0f03a038390804e5a77e2caf862
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=4.4.2'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
version: 1.2.1
|
||||
espressif/esp_lcd_touch_gt911:
|
||||
component_hash: be02e243d18b9a661bc13b0d22c0a5cfa3f708cf04d6eb059772276c8c8a4d76
|
||||
dependencies:
|
||||
- name: espressif/esp_lcd_touch
|
||||
registry_url: https://components.espressif.com
|
||||
require: public
|
||||
version: ^1.2.0
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=4.4.2'
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
version: 1.0.2
|
||||
version: 1.2.0~1
|
||||
espressif/esp_lvgl_port:
|
||||
component_hash: f872401524cb645ee6ff1c9242d44fb4ddcfd4d37d7be8b9ed3f4e85a404efcd
|
||||
component_hash: b6360960f47b6776462e7092861b3ea66477ffb762a01baa0aecbb3d74cd50f4
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
@ -22,22 +229,153 @@ dependencies:
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
version: 2.7.0
|
||||
version: 2.7.2
|
||||
espressif/esp_sccb_intf:
|
||||
component_hash: c071b189e49f40940722aea01a5489f873385cc39cd5b14012341135b85d1a9d
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.3'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
version: 0.0.8
|
||||
espressif/esp_serial_slave_link:
|
||||
component_hash: ac1776806de0a6e371c84e87898bb983e19ce62aa7f1e2e5c4a3b0234a575d2c
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.0'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
version: 1.1.2
|
||||
espressif/esp_video:
|
||||
component_hash: 2239aed49fa4eb1efdf3b0c2b95b05c03fc8b363c101bc2cd70f5e3bcd3c7cc4
|
||||
dependencies:
|
||||
- name: espressif/cmake_utilities
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: 0.*
|
||||
- name: espressif/esp_cam_sensor
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: 1.7.*
|
||||
- name: espressif/esp_h264
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
rules:
|
||||
- if: target in [esp32p4]
|
||||
version: 1.0.4
|
||||
- name: espressif/esp_ipa
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
rules:
|
||||
- if: target in [esp32p4]
|
||||
version: 1.3.*
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.4'
|
||||
- name: espressif/usb_host_uvc
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
rules:
|
||||
- if: target in [esp32p4, esp32s3]
|
||||
version: 2.4.*
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
targets:
|
||||
- esp32p4
|
||||
- esp32s3
|
||||
- esp32c3
|
||||
- esp32c5
|
||||
- esp32c6
|
||||
- esp32c61
|
||||
version: 1.4.1
|
||||
espressif/esp_wifi_remote:
|
||||
component_hash: 20393ed850b2cb40cadcf369b4c852ef5af49e2d89e58774d968c57b0c436fd3
|
||||
dependencies:
|
||||
- name: espressif/eppp_link
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: '>=0.1'
|
||||
- name: espressif/esp_hosted
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
rules:
|
||||
- if: target in [esp32h2, esp32p4]
|
||||
version: '>=0.0.6'
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.3'
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
version: 0.14.4
|
||||
espressif/usb_host_uvc:
|
||||
component_hash: 197eae0d1dd5ddec773704653e0ff70e81126b8ccdb62e034ed239f755adb48c
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.0'
|
||||
- name: espressif/usb
|
||||
registry_url: https://components.espressif.com
|
||||
require: public
|
||||
rules:
|
||||
- if: idf_version >=6.0
|
||||
- if: target not in ["linux"]
|
||||
version: ^1.0.0
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
targets:
|
||||
- esp32s2
|
||||
- esp32s3
|
||||
- esp32p4
|
||||
- esp32h4
|
||||
- linux
|
||||
version: 2.4.1
|
||||
idf:
|
||||
source:
|
||||
type: idf
|
||||
version: 5.5.1
|
||||
version: 5.5.2
|
||||
joltwallet/littlefs:
|
||||
component_hash: dcea25bcef2de023f089f5f01e8d8c46ad1b8ffef75861ad5ffb4098555839df
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.0'
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
version: 1.20.4
|
||||
lvgl/lvgl:
|
||||
component_hash: 184e532558c1c45fefed631f3e235423d22582aafb4630f3e8885c35281a49ae
|
||||
dependencies: []
|
||||
source:
|
||||
path: /home/marc/domotic/components/lvgl__lvgl
|
||||
type: local
|
||||
version: 9.4.0
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
version: 9.5.0
|
||||
suda-morris/am2302_rmt:
|
||||
component_hash: 890df8ebfec652eb9f8e1d612959f00a951dbe9241335e5e335fc7fb1468ea32
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.1'
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
version: 1.1.0
|
||||
direct_dependencies:
|
||||
- espressif/esp_lcd_qemu_rgb
|
||||
- espressif/bh1750
|
||||
- espressif/esp32_p4_function_ev_board
|
||||
- espressif/esp_lcd_touch_gt911
|
||||
- espressif/esp_lvgl_port
|
||||
- espressif/esp_wifi_remote
|
||||
- idf
|
||||
- lvgl/lvgl
|
||||
manifest_hash: 6dfd2d16dd4d21f701b251046402dbd6cb442f0c69beab0ba9af1b2ef32c7367
|
||||
target: esp32s3
|
||||
- joltwallet/littlefs
|
||||
- suda-morris/am2302_rmt
|
||||
manifest_hash: ff7936466302f0a070f567433bba5708f3bdab0fb5fa4b9941b77ae4ac95532c
|
||||
target: esp32p4
|
||||
version: 2.0.0
|
||||
|
||||
@ -9,12 +9,13 @@ if(${IDF_TARGET} STREQUAL "esp32p4")
|
||||
idf_component_register(SRCS main.c communication.c
|
||||
INCLUDE_DIRS "./include"
|
||||
REQUIRES ${comps}
|
||||
EMBED_TXTFILES ${PROJECT_DIR}/main/ca_cert.pem
|
||||
EMBED_TXTFILES ${PROJECT_DIR}/main/ca_cert.pem ${PROJECT_DIR}/../ota/certs/server.crt
|
||||
EMBED_FILES "index.html")
|
||||
littlefs_create_partition_image(littlefs medias FLASH_IN_PROJECT)
|
||||
elseif(${IDF_TARGET} STREQUAL "linux")
|
||||
message(STATUS "Linux Mode --> main standard")
|
||||
list(APPEND comps vfs esp_http_server)
|
||||
idf_component_register(SRCS main.c
|
||||
idf_component_register(SRCS main.c communication.c
|
||||
INCLUDE_DIRS "./include"
|
||||
REQUIRES ${comps}
|
||||
EMBED_TXTFILES ${PROJECT_DIR}/main/ca_cert.pem
|
||||
|
||||
@ -2,206 +2,22 @@
|
||||
#include "esp_log.h"
|
||||
#include "mqtt_client.h"
|
||||
#include "stateManagement.h"
|
||||
#include "eventsManager.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
#include "esp_wifi.h"
|
||||
#endif
|
||||
#include "esp_log.h"
|
||||
|
||||
|
||||
esp_mqtt_client_handle_t client;
|
||||
|
||||
static const char *TAG = "domo_mqtt";
|
||||
|
||||
|
||||
static void log_error_if_nonzero(const char *message, int error_code)
|
||||
{
|
||||
if (error_code != 0)
|
||||
{
|
||||
ESP_LOGE(TAG, "Last error %s: 0x%x", message, error_code);
|
||||
}
|
||||
}
|
||||
|
||||
void splitIt(char *payload, unsigned int length, float *datas)
|
||||
{
|
||||
char *sep = ",";
|
||||
char *token;
|
||||
char *saveptr1;
|
||||
|
||||
token = strtok_r(payload, sep, &saveptr1);
|
||||
datas[0] = atof(token);
|
||||
ESP_LOGE(TAG,"%f",datas[0]);
|
||||
|
||||
token = strtok_r(NULL, sep, &saveptr1);
|
||||
datas[1] = atof(token);
|
||||
ESP_LOGE(TAG,"%f",datas[1]);
|
||||
|
||||
token = strtok_r(NULL, sep, &saveptr1);
|
||||
datas[2] = atof(token);
|
||||
ESP_LOGE(TAG,"%f",datas[2]);
|
||||
|
||||
token = strtok_r(NULL, sep, &saveptr1);
|
||||
datas[3] = atof(token);
|
||||
ESP_LOGE(TAG,"%f",datas[3]);
|
||||
}
|
||||
|
||||
mqtt_callback mqttcb;
|
||||
|
||||
void mqtt_publish(const char *topic, const char *datas){
|
||||
esp_mqtt_client_publish(client, topic, datas, 0, 1, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Event handler registered to receive MQTT events
|
||||
*
|
||||
* This function is called by the MQTT client event loop.
|
||||
*
|
||||
* @param handler_args user data registered to the event.
|
||||
* @param base Event base for the handler(always MQTT Base in this example).
|
||||
* @param event_id The id for the received event.
|
||||
* @param event_data The data for the event, esp_mqtt_event_handle_t.
|
||||
*/
|
||||
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
|
||||
{
|
||||
ESP_LOGV(TAG, "Event dispatched from event loop base=%s, event_id=%" PRIi32 "", base, event_id);
|
||||
esp_mqtt_event_handle_t event = event_data;
|
||||
esp_mqtt_client_handle_t client = event->client;
|
||||
int msg_id;
|
||||
switch ((esp_mqtt_event_id_t)event_id)
|
||||
{
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
mqttcb(MQTT_CONNECTED,NULL);
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
|
||||
//msg_id = esp_mqtt_client_publish(client, "/topic/qos1", "data_3", 0, 1, 0);
|
||||
//ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, topicTempExt, 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, topicTempInt, 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, topicHauteurCuve, 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, topicHauteurCuveEvol, 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, topicTest, 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, topicdomoticCommand, 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, topicdomoticCommand, 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, topicEtatMachine, 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, topicConsoElec, 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
//msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
|
||||
//ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
//msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
|
||||
//ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
mqttcb(MQTT_DISCONNECTED,NULL);
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
//msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
|
||||
//ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_UNSUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_PUBLISHED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_DATA:
|
||||
mqttcb(MQTT_DATA_RECEIVED, event);
|
||||
break;
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
|
||||
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT)
|
||||
{
|
||||
log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
|
||||
log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
|
||||
log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno);
|
||||
ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
void mqtt_app_start(mqtt_callback callback, EventGroupHandle_t domotic_event_group)
|
||||
{
|
||||
|
||||
|
||||
mqttcb=callback;
|
||||
esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker.address.uri = "mqtt://192.168.0.10",
|
||||
.network.timeout_ms = 1000};
|
||||
#if CONFIG_BROKER_URL_FROM_STDIN
|
||||
char line[128];
|
||||
|
||||
if (strcmp(mqtt_cfg.broker.address.uri, "FROM_STDIN") == 0)
|
||||
{
|
||||
int count = 0;
|
||||
printf("Please enter url of mqtt broker\n");
|
||||
while (count < 128)
|
||||
{
|
||||
int c = fgetc(stdin);
|
||||
if (c == '\n')
|
||||
{
|
||||
line[count] = '\0';
|
||||
break;
|
||||
}
|
||||
else if (c > 0 && c < 127)
|
||||
{
|
||||
line[count] = c;
|
||||
++count;
|
||||
}
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
}
|
||||
mqtt_cfg.broker.address.uri = line;
|
||||
printf("Broker url: %s\n", line);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "Configuration mismatch: wrong broker url");
|
||||
abort();
|
||||
}
|
||||
#endif /* CONFIG_BROKER_URL_FROM_STDIN */
|
||||
|
||||
client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
/* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
|
||||
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
|
||||
// Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
|
||||
// number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above)
|
||||
EventBits_t bits = xEventGroupWaitBits(domotic_event_group,
|
||||
BIT0,
|
||||
pdFALSE,
|
||||
pdFALSE,
|
||||
portMAX_DELAY);
|
||||
if (bits & BIT0)
|
||||
{
|
||||
esp_mqtt_client_start(client);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* FreeRTOS event group to signal when we are connected*/
|
||||
static EventGroupHandle_t s_wifi_event_group;
|
||||
|
||||
/* The event group allows multiple bits for each event, but we only care about two events:
|
||||
* - we are connected to the AP with an IP
|
||||
* - we failed to connect after the maximum amount of retries */
|
||||
#define BIT0 0x00000001
|
||||
|
||||
#define WIFI_CONNECTED_BIT BIT0
|
||||
#define WIFI_FAIL_BIT BIT1
|
||||
|
||||
@ -215,7 +31,8 @@ static EventGroupHandle_t s_wifi_event_group;
|
||||
static int s_retry_num = 0;
|
||||
wifi_callback cb;
|
||||
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
#define BIT0 0x00000001
|
||||
static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
|
||||
{
|
||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
|
||||
@ -319,4 +136,213 @@ void wifi_init_sta(wifi_callback callback)
|
||||
}
|
||||
*/
|
||||
}
|
||||
#else
|
||||
#include <time.h>
|
||||
int64_t esp_timer_get_time(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return (int64_t)ts.tv_sec * 1000000LL + ts.tv_nsec / 1000;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
esp_mqtt_client_handle_t client;
|
||||
|
||||
|
||||
|
||||
static void log_error_if_nonzero(const char *message, int error_code)
|
||||
{
|
||||
if (error_code != 0)
|
||||
{
|
||||
ESP_LOGE(TAG, "Last error %s: 0x%x", message, error_code);
|
||||
}
|
||||
}
|
||||
|
||||
void splitIt(char *payload, unsigned int length, float *datas)
|
||||
{
|
||||
char *sep = ",";
|
||||
char *token;
|
||||
char *saveptr1;
|
||||
|
||||
token = strtok_r(payload, sep, &saveptr1);
|
||||
datas[0] = atof(token);
|
||||
ESP_LOGE(TAG,"%f",datas[0]);
|
||||
|
||||
token = strtok_r(NULL, sep, &saveptr1);
|
||||
datas[1] = atof(token);
|
||||
ESP_LOGE(TAG,"%f",datas[1]);
|
||||
|
||||
token = strtok_r(NULL, sep, &saveptr1);
|
||||
datas[2] = atof(token);
|
||||
ESP_LOGE(TAG,"%f",datas[2]);
|
||||
|
||||
token = strtok_r(NULL, sep, &saveptr1);
|
||||
datas[3] = atof(token);
|
||||
ESP_LOGE(TAG,"%f",datas[3]);
|
||||
}
|
||||
|
||||
mqtt_callback mqttcb;
|
||||
|
||||
void mqtt_publish(const char *topic, const char *datas, bool retain){
|
||||
esp_mqtt_client_publish(client, topic, datas, 0, 1, retain);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Event handler registered to receive MQTT events
|
||||
*
|
||||
* This function is called by the MQTT client event loop.
|
||||
*
|
||||
* @param handler_args user data registered to the event.
|
||||
* @param base Event base for the handler(always MQTT Base in this example).
|
||||
* @param event_id The id for the received event.
|
||||
* @param event_data The data for the event, esp_mqtt_event_handle_t.
|
||||
*/
|
||||
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
|
||||
{
|
||||
ESP_LOGV(TAG, "Event dispatched from event loop base=%s, event_id=%" PRIi32 "", base, event_id);
|
||||
esp_mqtt_event_handle_t event = event_data;
|
||||
esp_mqtt_client_handle_t client = event->client;
|
||||
int msg_id;
|
||||
switch ((esp_mqtt_event_id_t)event_id)
|
||||
{
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
mqttcb(MQTT_CONNECTED,NULL);
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
|
||||
//msg_id = esp_mqtt_client_publish(client, "/topic/qos1", "data_3", 0, 1, 0);
|
||||
//ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, topicTempExt, 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, topicTempInt, 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, topicHauteurCuve, 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, topicHauteurCuveEvol, 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, topicTest, 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, topicdomoticCommand, 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, topicdomoticCommand, 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, topicEtatMachine, 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, topicConsoElec, 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, "devices/esp32p4_01/ota/update", 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
|
||||
//msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
|
||||
//ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
//msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
|
||||
//ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
mqttcb(MQTT_DISCONNECTED,NULL);
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
//msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
|
||||
//ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_UNSUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_PUBLISHED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_DATA:
|
||||
mqttcb(MQTT_DATA_RECEIVED, event);
|
||||
break;
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
|
||||
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT)
|
||||
{
|
||||
log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
|
||||
log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
|
||||
log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno);
|
||||
ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
void mqtt_app_start(mqtt_callback callback, EventGroupHandle_t domotic_event_group)
|
||||
{
|
||||
|
||||
|
||||
mqttcb=callback;
|
||||
esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker.address.uri = "mqtt://192.168.0.10",
|
||||
.network.timeout_ms = 1000,
|
||||
.session.keepalive=30,
|
||||
.session.last_will.topic="esp32p4_domotic/binary_sensor/online/state",
|
||||
.session.last_will.msg = "offline",
|
||||
.session.last_will.qos = 1,
|
||||
.session.last_will.retain = 1
|
||||
};
|
||||
#if CONFIG_BROKER_URL_FROM_STDIN
|
||||
char line[128];
|
||||
|
||||
if (strcmp(mqtt_cfg.broker.address.uri, "FROM_STDIN") == 0)
|
||||
{
|
||||
int count = 0;
|
||||
printf("Please enter url of mqtt broker\n");
|
||||
while (count < 128)
|
||||
{
|
||||
int c = fgetc(stdin);
|
||||
if (c == '\n')
|
||||
{
|
||||
line[count] = '\0';
|
||||
break;
|
||||
}
|
||||
else if (c > 0 && c < 127)
|
||||
{
|
||||
line[count] = c;
|
||||
++count;
|
||||
}
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
}
|
||||
mqtt_cfg.broker.address.uri = line;
|
||||
printf("Broker url: %s\n", line);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "Configuration mismatch: wrong broker url");
|
||||
abort();
|
||||
}
|
||||
#endif /* CONFIG_BROKER_URL_FROM_STDIN */
|
||||
|
||||
client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
/* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
|
||||
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
|
||||
// Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
|
||||
// number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above)
|
||||
EventBits_t bits = xEventGroupWaitBits(domotic_event_group,
|
||||
BIT0,
|
||||
pdFALSE,
|
||||
pdFALSE,
|
||||
portMAX_DELAY);
|
||||
if (bits & BIT0)
|
||||
{
|
||||
esp_mqtt_client_start(client);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -16,14 +16,6 @@ typedef void (*wifi_callback)(wifi_evt evt);
|
||||
typedef void (*mqtt_callback)(mqtt_evt evt, esp_mqtt_event_handle_t evt_data);
|
||||
void wifi_init_sta(wifi_callback cb);
|
||||
void mqtt_app_start(mqtt_callback cb, EventGroupHandle_t evtGroup);
|
||||
void mqtt_publish(const char *topic, const char *datas);
|
||||
void mqtt_publish(const char *topic, const char *datas, bool retain);
|
||||
|
||||
#define topicTempExt "house/temp/282A802600008059"
|
||||
#define topicHauteurCuve "house/cuve/hauteur"
|
||||
#define topicTempInt "house/temp/287DCF1E00008020"
|
||||
#define topicHauteurCuveEvol "house/cuve/hauteurEvol"
|
||||
#define topicConsoElec "energy/puissance_5mn"
|
||||
#define topicEtatMachine "energy/machine_en_route"
|
||||
#define topicdomoticCommand "domotic/cmd"
|
||||
#define topicTest "test"
|
||||
|
||||
|
||||
@ -73,8 +73,8 @@
|
||||
<h1>Developed by Mark</h1>
|
||||
<h2>How to save and Download crash dump</h2>
|
||||
</br></br>
|
||||
<button class="btn success"><a href="http://192.168.4.1/download">Download</a></button></br></br>
|
||||
<button class="btn success"><a href="http://192.168.4.1/crash">Crash</a></button>
|
||||
<button class="btn success"><a href="./download">Download</a></button></br></br>
|
||||
<button class="btn success"><a href="./crash">Crash</a></button>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
298
main/main.c
@ -20,10 +20,10 @@
|
||||
#include "ihm_gateway.h"
|
||||
|
||||
// OTA
|
||||
/*#include "esp_ota_ops.h"
|
||||
#include "esp_http_client.h"
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_https_ota.h"
|
||||
*/
|
||||
#include "esp_http_client.h"
|
||||
|
||||
// Includes personnels
|
||||
//#include "wifi_logger.h"
|
||||
#include "obtain_time.h"
|
||||
@ -31,13 +31,16 @@
|
||||
#include "include/communication.h"
|
||||
#include "stateManagement.h"
|
||||
//#include "driver/gpio.h"
|
||||
//#include "am2302_rmt.h"
|
||||
#include "eventsManager.h"
|
||||
|
||||
#include "esp_timer.h"
|
||||
|
||||
#include <esp_task_wdt.h>
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
#include "am2302_rmt.h"
|
||||
#include "esp_wifi.h"
|
||||
#endif
|
||||
// GPIO assignment
|
||||
#define AM2302_GPIO 4
|
||||
|
||||
@ -104,8 +107,128 @@ void bh1750_init(void)
|
||||
bh1750 = bh1750_create(I2C_MASTER_NUM, BH1750_I2C_ADDRESS_DEFAULT, bus_handle);
|
||||
*/
|
||||
}
|
||||
TaskHandle_t ihm_task;
|
||||
|
||||
typedef struct {
|
||||
char version[32];
|
||||
char url[256];
|
||||
char sha256[65];
|
||||
bool force;
|
||||
} ota_msg_t;
|
||||
static QueueHandle_t ota_queue;
|
||||
static const char *OTA_TOPIC = "devices/esp32p4_01/ota/update";
|
||||
#include <cJSON.h>
|
||||
bool parse_ota_json(const char *json, ota_msg_t *msg)
|
||||
{
|
||||
ESP_LOGE("OTA","On demande à parser : %s", json);
|
||||
cJSON *root = cJSON_Parse(json);
|
||||
if (!root) return false;
|
||||
|
||||
snprintf(msg->version, sizeof(msg->version),
|
||||
"%s", cJSON_GetStringValue(cJSON_GetObjectItem(root, "version")));
|
||||
|
||||
snprintf(msg->url, sizeof(msg->url),
|
||||
"%s", cJSON_GetStringValue(cJSON_GetObjectItem(root, "url")));
|
||||
|
||||
snprintf(msg->sha256, sizeof(msg->sha256),
|
||||
"%s", cJSON_GetStringValue(cJSON_GetObjectItem(root, "sha256")));
|
||||
|
||||
msg->force = cJSON_IsTrue(cJSON_GetObjectItem(root, "force"));
|
||||
|
||||
cJSON_Delete(root);
|
||||
return true;
|
||||
}
|
||||
extern const uint8_t server_cert_pem_start[] asm("_binary_server_crt_start");
|
||||
extern const uint8_t server_cert_pem_end[] asm("_binary_server_crt_end");
|
||||
void ota_task(void *arg)
|
||||
{
|
||||
ota_msg_t msg;
|
||||
|
||||
while (1) {
|
||||
if (xQueueReceive(ota_queue, &msg, portMAX_DELAY)) {
|
||||
|
||||
ESP_LOGI("OTA", "Starting OTA to %s", msg.version);
|
||||
|
||||
esp_http_client_config_t http_cfg = {
|
||||
.url = msg.url,
|
||||
.cert_pem = (const char *)server_cert_pem_start,
|
||||
.timeout_ms = 15000,
|
||||
.skip_cert_common_name_check = true,
|
||||
};
|
||||
|
||||
esp_https_ota_config_t ota_cfg = {
|
||||
.http_config = &http_cfg,
|
||||
};
|
||||
lv_obj_t *ota = lv_msgbox_create(lv_scr_act());
|
||||
lv_msgbox_add_text(ota,"Mise à jour OTA en cours");
|
||||
suspendIHM();
|
||||
|
||||
esp_err_t ret = esp_https_ota(&ota_cfg);
|
||||
|
||||
if (ret == ESP_OK) {
|
||||
ESP_LOGI("OTA", "OTA successful, rebooting");
|
||||
esp_restart();
|
||||
} else {
|
||||
ESP_LOGE("OTA", "OTA failed (%s)", esp_err_to_name(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static bool parse_semver(const char *ver, int *maj, int *min, int *pat)
|
||||
{
|
||||
return sscanf(ver, "%d.%d.%d", maj, min, pat) == 3;
|
||||
}
|
||||
static bool is_dev_build(void)
|
||||
{
|
||||
const esp_app_desc_t *desc = esp_app_get_description();
|
||||
return strchr(desc->version, '-') != NULL;
|
||||
}
|
||||
static const char *get_suffix(const char *ver)
|
||||
{
|
||||
const char *dash = strchr(ver, '-');
|
||||
return dash ? dash + 1 : NULL;
|
||||
}
|
||||
bool is_new_version(const char *incoming)
|
||||
{
|
||||
int cur_maj, cur_min, cur_pat;
|
||||
int new_maj, new_min, new_pat;
|
||||
|
||||
const esp_app_desc_t *desc = esp_app_get_description();
|
||||
const char *current = desc->version;
|
||||
|
||||
if (!parse_semver(current, &cur_maj, &cur_min, &cur_pat) ||
|
||||
!parse_semver(incoming, &new_maj, &new_min, &new_pat)) {
|
||||
ESP_LOGW("OTA", "Invalid version format");
|
||||
return true; // fail-open
|
||||
}
|
||||
|
||||
// 1️⃣ Upgrade semver classique
|
||||
if (new_maj != cur_maj) return new_maj > cur_maj;
|
||||
if (new_min != cur_min) return new_min > cur_min;
|
||||
if (new_pat != cur_pat) return new_pat > cur_pat;
|
||||
|
||||
// 2️⃣ Même X.Y.Z → comportement dépend du mode
|
||||
if (is_dev_build()) {
|
||||
const char *cur_suffix = get_suffix(current);
|
||||
const char *new_suffix = get_suffix(incoming);
|
||||
|
||||
// si une des deux n'a pas de suffixe → contexte différent
|
||||
if (!cur_suffix || !new_suffix) {
|
||||
ESP_LOGI("OTA", "Dev mode: context change (suffix missing)");
|
||||
return true;
|
||||
}
|
||||
|
||||
// suffix différent → OTA
|
||||
if (strcmp(cur_suffix, new_suffix) != 0) {
|
||||
ESP_LOGI("OTA", "Dev mode: branch change (%s → %s)",
|
||||
cur_suffix, new_suffix);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
ESP_LOGI("OTA", "No OTA needed");
|
||||
return false;
|
||||
}
|
||||
void mqtt_cb(mqtt_evt evt, esp_mqtt_event_handle_t event){
|
||||
switch (evt)
|
||||
{
|
||||
@ -126,16 +249,37 @@ void mqtt_cb(mqtt_evt evt, esp_mqtt_event_handle_t event){
|
||||
break;
|
||||
case MQTT_DATA_RECEIVED:
|
||||
//lv_subject_set_int(&mqttStatus,2);
|
||||
ESP_LOGD(TAG, "\nMQTT_EVENT_DATA");
|
||||
ESP_LOGD(TAG, "TOPIC=%.*s\n", event->topic_len, event->topic);
|
||||
ESP_LOGD(TAG, "DATA=%.*s\n", event->data_len, event->data);
|
||||
ESP_LOGE(TAG, "MQTT_EVENT_DATA");
|
||||
ESP_LOGE(TAG, "TOPIC=%.*s\n", event->topic_len, event->topic);
|
||||
ESP_LOGE(TAG, "DATA=%.*s\n", event->data_len, event->data);
|
||||
char *topic = strndup(event->topic, event->topic_len);
|
||||
if (strcmp(topic, topicTempExt) == 0)
|
||||
if (strncmp(topic, OTA_TOPIC, event->topic_len ) == 0) {
|
||||
ota_msg_t msg = {0};
|
||||
|
||||
// ⚠️ copie safe (topic/data pas null-terminated)
|
||||
char payload[512] = {0};
|
||||
memcpy(payload, event->data, event->data_len);
|
||||
|
||||
if (!parse_ota_json(payload, &msg)) {
|
||||
ESP_LOGE("OTA", "Invalid OTA JSON");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_new_version(msg.version) && !msg.force) {
|
||||
ESP_LOGI("OTA", "Version already installed");
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGI("OTA", "OTA requested: %s", msg.version);
|
||||
|
||||
xQueueSend(ota_queue, &msg, 0); }
|
||||
else if (strcmp(topic, topicTempExt) == 0)
|
||||
{
|
||||
//if(lvgl_port_lock(50)){
|
||||
float temp = strtof(event->data, NULL);
|
||||
char buff[5];
|
||||
sprintf(buff,"%.1f",temp);
|
||||
send_event(EVT_TEMP_EXT, buff);
|
||||
//lv_subject_copy_string(&tempExtSubj, buff);
|
||||
|
||||
//lvgl_port_unlock();
|
||||
@ -294,7 +438,7 @@ extern char *days[7];
|
||||
extern char *months[12];
|
||||
|
||||
|
||||
/* esp_err_t _ota_http_event_handler(esp_http_client_event_t *evt)
|
||||
esp_err_t _ota_http_event_handler(esp_http_client_event_t *evt)
|
||||
{
|
||||
switch (evt->event_id) {
|
||||
case HTTP_EVENT_ERROR:
|
||||
@ -324,11 +468,10 @@ extern char *months[12];
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
extern const uint8_t server_cert_pem_start[] asm("_binary_ca_cert_pem_start");
|
||||
extern const uint8_t server_cert_pem_end[] asm("_binary_ca_cert_pem_end");
|
||||
/* static esp_err_t validate_image_header(esp_app_desc_t *new_app_info)
|
||||
static esp_err_t validate_image_header(esp_app_desc_t *new_app_info)
|
||||
{
|
||||
if (new_app_info == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@ -349,12 +492,11 @@ extern const uint8_t server_cert_pem_end[] asm("_binary_ca_cert_pem_end");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
void simple_ota_example_task(void *pvParameter)
|
||||
{
|
||||
/* ESP_LOGE(TAG,"En attente connexion wifi");
|
||||
ESP_LOGE(TAG,"En attente connexion wifi");
|
||||
// Waiting until either the connection is established (WIFI_CONNECTED_BIT).
|
||||
EventBits_t bits = xEventGroupWaitBits(domotic_event_group,
|
||||
BIT0,
|
||||
@ -378,8 +520,8 @@ void simple_ota_example_task(void *pvParameter)
|
||||
esp_http_client_config_t config = {
|
||||
.url = "https://192.168.0.28:8070/rgb_lcd.bin",
|
||||
.timeout_ms = 30000,
|
||||
.buffer_size = 20000,
|
||||
.buffer_size_tx = 20000, //TX Buffer, Main Buffer
|
||||
.buffer_size = 6144,
|
||||
.buffer_size_tx = 6144, //TX Buffer, Main Buffer
|
||||
.event_handler = _ota_http_event_handler,
|
||||
.keep_alive_enable = true,
|
||||
.cert_pem = (char *)server_cert_pem_start,
|
||||
@ -480,13 +622,14 @@ ota_end:
|
||||
ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed");
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
*/}
|
||||
}
|
||||
|
||||
//am2302_handle_t sensor = NULL;
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
am2302_handle_t sensor = NULL;
|
||||
|
||||
void readTempHumid(void *pvParameter)
|
||||
{
|
||||
/* float temperature = 0;
|
||||
float temperature = 0;
|
||||
float humidity = 0;
|
||||
while (1)
|
||||
{
|
||||
@ -494,16 +637,30 @@ void readTempHumid(void *pvParameter)
|
||||
char buff[40];
|
||||
ESP_LOGI(TAG, "Temperature: %.1f °C, Humidity: %.1f %%", temperature, humidity);
|
||||
sprintf(buff,"%.1f °C, %.1f %%", temperature, humidity);
|
||||
xIHMEvent_t m = {
|
||||
.eEventType = IHM_EVT_HUMID_TEMP,
|
||||
.pvData = buff
|
||||
};
|
||||
//xQueueSendToFront(ihm_queue,&m,5);
|
||||
send_event(EVT_TEMP_INT, buff);
|
||||
vTaskDelay(60000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
*/
|
||||
}
|
||||
#include "esp_littlefs.h"
|
||||
|
||||
void littlefs_mount(void)
|
||||
{
|
||||
esp_vfs_littlefs_conf_t conf = {
|
||||
.base_path = "/littlefs",
|
||||
.partition_label = "littlefs", // ← DOIT matcher partitions.csv
|
||||
.format_if_mount_failed = false
|
||||
};
|
||||
|
||||
esp_err_t ret = esp_vfs_littlefs_register(&conf);
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
printf("LittleFS mount failed: %s\n", esp_err_to_name(ret));
|
||||
} else {
|
||||
printf("LittleFS mounted at /littlefs\n");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
void alloc_fail(size_t size, uint32_t caps, const char * function_name){
|
||||
ESP_LOGE(TAG,"fail alloc %u in %" PRIu32 " in %s", size,caps,function_name);
|
||||
|
||||
@ -711,9 +868,9 @@ extern lv_subject_t forecastH2Subj;
|
||||
extern lv_subject_t forecastH3Subj;
|
||||
extern lv_subject_t meteoStatus;
|
||||
|
||||
void weather_data_retreived(struct meteodailyforecast_data dailyDatas[3], struct meteoforecast_data datas[3])
|
||||
void weather_data_retreived(meteo_event_payload_t *datas)
|
||||
{
|
||||
|
||||
send_event(EVT_METEO_RECUE, datas);
|
||||
/* ESP_LOGE(TAG, "debut debug");
|
||||
printf("%lld\n", datas[0].datetime);
|
||||
printf("%s\n", datas[0].previsions.desc);
|
||||
@ -728,22 +885,6 @@ void weather_data_retreived(struct meteodailyforecast_data dailyDatas[3], struct
|
||||
*/
|
||||
//if (display_lock("weather_data_retreived"))
|
||||
//{
|
||||
ESP_LOGV("MeteoFrance", "------------------------------------- Set des subjects J --------------------------------");
|
||||
// Prévisions des 3 prochains jours
|
||||
//lv_subject_set_pointer(&forecastD1Subj, &dailyDatas[0]);
|
||||
//lv_subject_set_pointer(&forecastD2Subj, &dailyDatas[1]);
|
||||
//lv_subject_set_pointer(&forecastD3Subj, &dailyDatas[2]);
|
||||
|
||||
ESP_LOGV("MeteoFrance", "------------------------------------- Set des subjects H--------------------------------");
|
||||
// Prévisions des 3 prochains jours
|
||||
ESP_LOGV("MeteoFrance", "Pointeur %lli", datas[0].datetime);
|
||||
//lv_subject_set_pointer(&forecastH1Subj, &datas[0]);
|
||||
//lv_subject_set_pointer(&forecastH2Subj, &datas[1]);
|
||||
// lv_subject_set_pointer(&forecastH3Subj, &datas[2]);
|
||||
|
||||
//lv_subject_set_int(&meteoStatus, 0);
|
||||
//display_unlock("weather_data_retreived");
|
||||
ESP_LOGV(TAG, "------------------------------------- Fin Set des subjects --------------------------------");
|
||||
//}else{
|
||||
//ESP_LOGE(TAG, "Impossible d'obtenir le mutex dans weather_data_retreived");
|
||||
//}
|
||||
@ -870,16 +1011,34 @@ void lightSensorTask(void *pvParameter){
|
||||
*/
|
||||
}
|
||||
|
||||
static void heartbeat_task(void *arg)
|
||||
{
|
||||
const char *topic = "esp32p4_domotic/binary_sensor/online/state";
|
||||
|
||||
while (1) {
|
||||
mqtt_publish(
|
||||
topic,
|
||||
"online",
|
||||
true);
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(30000)); // 30 s
|
||||
}
|
||||
}
|
||||
|
||||
#define BUILD_TIME __DATE__ " " __TIME__
|
||||
//#include "audio.h"
|
||||
void app_main(void)
|
||||
{
|
||||
|
||||
setenv("TZ", "CET-1CEST,M3.5.0,M10.5.0/3", 1);
|
||||
tzset();
|
||||
|
||||
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
ihm_gateway_init();
|
||||
startEvtManager();
|
||||
|
||||
boucleMeteo();
|
||||
|
||||
#if CONFIG_IDF_TARGET_LINUX
|
||||
// en mode linux on simule l'obtention de la connexion wifi
|
||||
xEventGroupSetBits(domotic_event_group, WIFI_CONNECTED_BIT);
|
||||
@ -887,13 +1046,27 @@ void app_main(void)
|
||||
//drawIhm(getIHMQueueHandle());
|
||||
|
||||
#else
|
||||
xTaskCreate(&drawIhm,"ihm_task",10000,getIHMQueueHandle(),10,NULL);
|
||||
littlefs_mount();
|
||||
xTaskCreate(&drawIhm,"ihm_task",10000,getIHMQueueHandle(),3,&ihm_task);
|
||||
//et sinon on se connecte
|
||||
ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
|
||||
wifi_init_sta(wifi_cb);
|
||||
//start_wifi_logger();
|
||||
/* Ensure to disable any WiFi power save mode, this allows best throughput
|
||||
* and hence timings for overall OTA operation.
|
||||
*/
|
||||
esp_wifi_set_ps(WIFI_PS_NONE);
|
||||
//xTaskCreate(&simple_ota_example_task, "ota_example_task", 8192, NULL, 5, NULL);
|
||||
#endif
|
||||
|
||||
|
||||
boucleMeteo();
|
||||
|
||||
ota_queue = xQueueCreate(1, sizeof(ota_msg_t));
|
||||
xTaskCreate(ota_task,"ota_task",8192,NULL,5,NULL);
|
||||
|
||||
mqtt_app_start(mqtt_cb, domotic_event_group);
|
||||
|
||||
TaskHandle_t xHandle = NULL;
|
||||
BaseType_t ret1;
|
||||
/*ret1 = xTaskCreate(&imgdwn, "imageDownload_task", 3 * 1024, domotic_event_group, 5, &xHandle);
|
||||
@ -902,6 +1075,30 @@ void app_main(void)
|
||||
ESP_LOGE(TAG, "Impossiblke de creer la tache imageDownload_task %i", ret1);
|
||||
}*/
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
|
||||
//playSound();
|
||||
//send_event(EVT_FIN_MACHINE,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);
|
||||
#endif
|
||||
|
||||
esp_ota_mark_app_valid_cancel_rollback();
|
||||
esp_app_desc_t *appDesc = esp_app_get_description();
|
||||
char buff[300];
|
||||
snprintf(buff,300,"%s %s %s", BUILD_TIME, appDesc->version, appDesc->idf_ver);
|
||||
mqtt_publish("esp32p4_domotic/sensor/firmware/state",buff, true);
|
||||
|
||||
xTaskCreate(heartbeat_task, "heartbeat_task", 4096, NULL, 5, NULL);
|
||||
|
||||
start_webserver();
|
||||
}
|
||||
|
||||
void boucleMeteo()
|
||||
@ -1028,14 +1225,5 @@ void app_main1(void)
|
||||
start_webserver();
|
||||
|
||||
|
||||
/* // Configuration de la sonde Temp/Humid.
|
||||
am2302_config_t am2302_config = {
|
||||
.gpio_num = AM2302_GPIO,
|
||||
};
|
||||
am2302_rmt_config_t rmt_config = {
|
||||
.clk_src = RMT_CLK_SRC_DEFAULT,
|
||||
};
|
||||
ESP_ERROR_CHECK(am2302_new_sensor_rmt(&am2302_config, &rmt_config, &sensor));
|
||||
xTaskCreate(&readTempHumid, "read_temp_task", 8192, NULL, 5, NULL);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
BIN
main/medias/images_meteo/p10j.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
main/medias/images_meteo/p10n.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
main/medias/images_meteo/p11j.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
main/medias/images_meteo/p11n.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
main/medias/images_meteo/p12bisj.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
main/medias/images_meteo/p12j.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
main/medias/images_meteo/p12n.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
main/medias/images_meteo/p13bisj.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
main/medias/images_meteo/p13j.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
main/medias/images_meteo/p13n.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
main/medias/images_meteo/p14bisj.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
main/medias/images_meteo/p14j.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
main/medias/images_meteo/p14n.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
main/medias/images_meteo/p15j.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
main/medias/images_meteo/p15n.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
main/medias/images_meteo/p16bisj.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
main/medias/images_meteo/p16j.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
main/medias/images_meteo/p16n.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
main/medias/images_meteo/p17j.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
main/medias/images_meteo/p17n.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
main/medias/images_meteo/p18j.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
main/medias/images_meteo/p18n.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
main/medias/images_meteo/p19j.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
main/medias/images_meteo/p19n.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
main/medias/images_meteo/p1j.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
main/medias/images_meteo/p1n.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
main/medias/images_meteo/p20j.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
main/medias/images_meteo/p20n.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
main/medias/images_meteo/p21j.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
main/medias/images_meteo/p21n.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
main/medias/images_meteo/p22j.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
main/medias/images_meteo/p22n.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
main/medias/images_meteo/p23j.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
main/medias/images_meteo/p23n.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
main/medias/images_meteo/p24j.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
main/medias/images_meteo/p24n.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
main/medias/images_meteo/p25j.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
main/medias/images_meteo/p25n.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
main/medias/images_meteo/p26j.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
main/medias/images_meteo/p26n.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
main/medias/images_meteo/p27j.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
main/medias/images_meteo/p27n.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
main/medias/images_meteo/p28j.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
main/medias/images_meteo/p28n.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
main/medias/images_meteo/p29j.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
main/medias/images_meteo/p29n.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
main/medias/images_meteo/p2j.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
main/medias/images_meteo/p2n.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
main/medias/images_meteo/p30j.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
main/medias/images_meteo/p30n.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
main/medias/images_meteo/p31j.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
main/medias/images_meteo/p31n.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
main/medias/images_meteo/p32j.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
main/medias/images_meteo/p32n.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
main/medias/images_meteo/p3bisj.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
main/medias/images_meteo/p3j.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
main/medias/images_meteo/p3n.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
main/medias/images_meteo/p4j.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
main/medias/images_meteo/p4n.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
main/medias/images_meteo/p5bisj.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
main/medias/images_meteo/p5j.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
main/medias/images_meteo/p5n.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
main/medias/images_meteo/p6bisj.png
Normal file
|
After Width: | Height: | Size: 551 B |
BIN
main/medias/images_meteo/p6j.png
Normal file
|
After Width: | Height: | Size: 551 B |
BIN
main/medias/images_meteo/p6n.png
Normal file
|
After Width: | Height: | Size: 551 B |
BIN
main/medias/images_meteo/p7j.png
Normal file
|
After Width: | Height: | Size: 930 B |
BIN
main/medias/images_meteo/p7n.png
Normal file
|
After Width: | Height: | Size: 930 B |
BIN
main/medias/images_meteo/p8j.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
main/medias/images_meteo/p8n.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
main/medias/images_meteo/p9j.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |