Compare commits
13 Commits
a41945bcef
...
8f60e9c38c
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f60e9c38c | |||
| 67e6d1cfaa | |||
| 77e8116d54 | |||
| 0de95c5386 | |||
| f871b76ca2 | |||
| 9d31148d21 | |||
| 9293b5fdc6 | |||
| bce9f03eb4 | |||
| 9217397d7d | |||
| b7552e15ce | |||
| 434ede2480 | |||
| 8e868da692 | |||
| e1640f4ad9 |
2
.vscode/c_cpp_properties.json
vendored
2
.vscode/c_cpp_properties.json
vendored
@ -2,7 +2,7 @@
|
||||
"configurations": [
|
||||
{
|
||||
"name": "ESP-IDF",
|
||||
"compilerPath": "${config:idf.toolsPath}/tools/riscv32-esp-elf/esp-14.2.0_20251107/riscv32-esp-elf/bin/riscv32-esp-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
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,
|
||||
|
||||
@ -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}'
|
||||
)
|
||||
|
||||
@ -10,12 +10,10 @@
|
||||
#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.
|
||||
Recording audio data path:
|
||||
I2S peripheral -> I2S buffer (DMA) -> App buffer (RAM) -> SPIFFS buffer -> External SPI Flash.
|
||||
Vice versa for playback. */
|
||||
External SPI Flash -> SPIFFS buffer -> App buffer (RAM) -> I2S buffer (DMA) -> I2S peripheral.
|
||||
*/
|
||||
#define BUFFER_SIZE (1024)
|
||||
#define SAMPLE_RATE (16000) // For recording
|
||||
#define DEFAULT_VOLUME (25)
|
||||
#define DEFAULT_VOLUME (50)
|
||||
|
||||
/* Globals */
|
||||
static const char *TAG = "audio";
|
||||
@ -35,22 +33,130 @@ typedef struct __attribute__((packed))
|
||||
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/imperial_march.wav";
|
||||
const char music_filename[] = "/littlefs/sounds/mixkit-clear-announce-tones-2861.wav";
|
||||
const char *play_filename = music_filename;
|
||||
|
||||
while (1) {
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
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");
|
||||
@ -65,10 +171,10 @@ static void audio_task(void *arg)
|
||||
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_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,
|
||||
@ -83,11 +189,22 @@ static void audio_task(void *arg)
|
||||
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);
|
||||
free(wav_bytes);
|
||||
esp_codec_dev_close(spk_codec_dev);
|
||||
if(ulTaskNotifyTake(pdTRUE, 0)>0){
|
||||
stop_requested=true;
|
||||
break;
|
||||
};
|
||||
|
||||
}
|
||||
free(wav_bytes);
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
|
||||
void playSound(void)
|
||||
@ -98,5 +215,10 @@ void playSound(void)
|
||||
}
|
||||
xTaskNotifyGive(audio_task_handle);
|
||||
}
|
||||
void stopSound(void){
|
||||
if (audio_task_handle) {
|
||||
xTaskNotifyGive(audio_task_handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,2 +1,4 @@
|
||||
|
||||
void playSound(void);
|
||||
|
||||
void stopSound(void);
|
||||
|
||||
Binary file not shown.
@ -191,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();
|
||||
@ -205,10 +212,14 @@ void drawIhm(void *param) {
|
||||
|
||||
// Loop unifiée
|
||||
while (1) {
|
||||
if(!suspended){
|
||||
ihm_gateway_process_queue();
|
||||
#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);
|
||||
@ -248,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
|
||||
@ -291,7 +304,6 @@ void init_display_ihm(){
|
||||
mainState.display_init=true;
|
||||
|
||||
time_t now;
|
||||
struct tm timeinfo;
|
||||
time(&now);
|
||||
localtime_r(&now, &timeinfo);
|
||||
|
||||
@ -433,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 .... */
|
||||
|
||||
@ -1306,73 +1319,34 @@ static void time_observer_cb(lv_observer_t *observer, lv_subject_t *subject)
|
||||
{
|
||||
LV_UNUSED(observer);
|
||||
|
||||
//ESP_LOGE(TAG,"################### On passe dans le cb time");
|
||||
lv_obj_t *parent = observer->target;
|
||||
struct tm *timeStruct=lv_subject_get_pointer(subject);
|
||||
|
||||
lv_obj_t *dateTimeObj = lv_observer_get_target_obj(observer);
|
||||
datetime_ctx_t *ctx = lv_obj_get_user_data(dateTimeObj);
|
||||
if (!ctx){
|
||||
ESP_LOGE(TAG,"################### Contexte non positionné");
|
||||
return;
|
||||
}
|
||||
lv_obj_t *day = lv_obj_find_by_name(parent, "day");
|
||||
lv_obj_t *month = lv_obj_find_by_name(parent, "month");
|
||||
|
||||
struct tm *t = (struct tm *)lv_subject_get_pointer(subject);
|
||||
if (!t){
|
||||
ESP_LOGE(TAG,"################### Pas de struct tm");
|
||||
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 *hour = lv_obj_find_by_name(parent, "hour");
|
||||
lv_obj_t *minute = lv_obj_find_by_name(parent, "minute");
|
||||
|
||||
char buf[4];
|
||||
bool refresh_date = false;
|
||||
bool refresh_time = false;
|
||||
|
||||
// ---- 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;
|
||||
}
|
||||
int d = timeStruct->tm_mday;
|
||||
int monthVal = timeStruct->tm_mon;
|
||||
int h = timeStruct->tm_hour;
|
||||
int m = timeStruct->tm_min;
|
||||
|
||||
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;
|
||||
}
|
||||
char buf[12];
|
||||
|
||||
if (true || refresh_date) {
|
||||
lv_spangroup_refresh(ctx->date_group);
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "%02d", d);
|
||||
lv_label_set_text(day, buf);
|
||||
|
||||
// ---- 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", monthVal+1);
|
||||
lv_label_set_text(month, 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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@ -1544,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);
|
||||
@ -1558,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);
|
||||
@ -1585,10 +1561,41 @@ void messageCardContent(lv_obj_t *cont_messages)
|
||||
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)
|
||||
{
|
||||
@ -1615,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");
|
||||
@ -1643,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");
|
||||
@ -1673,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");
|
||||
@ -1704,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");
|
||||
@ -1722,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)
|
||||
@ -1731,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)
|
||||
@ -1818,38 +1811,82 @@ 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);
|
||||
datetime_ctx_init(date_and_time);
|
||||
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);
|
||||
|
||||
|
||||
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));
|
||||
|
||||
@ -35,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)
|
||||
@ -103,6 +104,11 @@ void traiteEvt(void *arg)
|
||||
break;
|
||||
}
|
||||
|
||||
case IHM_EVT_MACHINE_TERMINEE:
|
||||
{
|
||||
draw_minuteurStop();
|
||||
}
|
||||
|
||||
case IHM_EVT_HAUTEUR_CUVE:
|
||||
{
|
||||
float hauteur = *(float *)evt->pvData;
|
||||
|
||||
@ -19,12 +19,14 @@ 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);
|
||||
@ -43,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 meteofrance audio)
|
||||
else()
|
||||
idf_component_register(SRCS "obtain_time.c" "eventsManager.c" obtain_time.c
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES mqtt esp_netif meteofrance)
|
||||
endif()
|
||||
|
||||
@ -6,7 +6,9 @@
|
||||
#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;
|
||||
@ -40,6 +42,7 @@ const char * domo_event_to_str(domo_events evt)
|
||||
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";
|
||||
}
|
||||
}
|
||||
@ -173,6 +176,10 @@ void send_event(domo_events evt, void* pDatas) {
|
||||
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: {
|
||||
@ -207,7 +214,19 @@ void send_event(domo_events evt, void* pDatas) {
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@ -15,7 +15,8 @@ typedef enum eIHMEvent_t{
|
||||
IHM_EVT_ETAT_MACHINE,
|
||||
IHM_EVT_HAUTEUR_CUVE,
|
||||
IHM_EVT_METEO_RECUE,
|
||||
IHM_EVT_TEMP_RECUE
|
||||
IHM_EVT_TEMP_RECUE,
|
||||
IHM_EVT_MACHINE_TERMINEE
|
||||
} eIHMEvent_t;
|
||||
|
||||
typedef struct IHM_EVENT
|
||||
@ -35,8 +36,18 @@ typedef enum domo_events{
|
||||
EVT_METEO_RECUE,
|
||||
EVT_TEMP_EXT,
|
||||
EVT_TEMP_INT,
|
||||
EVT_FIN_MACHINE
|
||||
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));
|
||||
|
||||
@ -54,6 +54,29 @@ 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;
|
||||
@ -73,10 +96,22 @@ void getEtatMachineStr(WashingMachineState wms, char* etat, size_t etatSize)
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ dependencies:
|
||||
type: service
|
||||
version: 1.0.4
|
||||
espressif/esp_hosted:
|
||||
component_hash: 5e1f8af8b51b47714eafb30c59bac952d6abc03125c01cb6a970f368d1e1cb83
|
||||
component_hash: 9eea9ce83444a412b4a02311f787f3639a5d29fe67e6df83863010dd68ab250b
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
@ -137,7 +137,7 @@ dependencies:
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
version: 2.11.7
|
||||
version: 2.12.0
|
||||
espressif/esp_ipa:
|
||||
component_hash: 31003e536f0d26158e10d7fcf2448b6377ce1148518287d0f34ed3b6c942c6d8
|
||||
dependencies:
|
||||
@ -217,7 +217,7 @@ dependencies:
|
||||
type: service
|
||||
version: 1.2.0~1
|
||||
espressif/esp_lvgl_port:
|
||||
component_hash: 88bbda87376ae20fabfbb5d794ed78d23b3b4a186ecfafecf2edbf06223fd6c9
|
||||
component_hash: b6360960f47b6776462e7092861b3ea66477ffb762a01baa0aecbb3d74cd50f4
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
@ -229,7 +229,7 @@ dependencies:
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
version: 2.7.1
|
||||
version: 2.7.2
|
||||
espressif/esp_sccb_intf:
|
||||
component_hash: c071b189e49f40940722aea01a5489f873385cc39cd5b14012341135b85d1a9d
|
||||
dependencies:
|
||||
@ -351,12 +351,12 @@ dependencies:
|
||||
type: service
|
||||
version: 1.20.4
|
||||
lvgl/lvgl:
|
||||
component_hash: 17e68bfd21f0edf4c3ee838e2273da840bf3930e5dbc3bfa6c1190c3aed41f9f
|
||||
component_hash: 184e532558c1c45fefed631f3e235423d22582aafb4630f3e8885c35281a49ae
|
||||
dependencies: []
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
version: 9.4.0
|
||||
version: 9.5.0
|
||||
suda-morris/am2302_rmt:
|
||||
component_hash: 890df8ebfec652eb9f8e1d612959f00a951dbe9241335e5e335fc7fb1468ea32
|
||||
dependencies:
|
||||
|
||||
@ -9,7 +9,7 @@ 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")
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include "esp_log.h"
|
||||
#include "mqtt_client.h"
|
||||
#include "stateManagement.h"
|
||||
#include "eventsManager.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
#include "esp_wifi.h"
|
||||
#endif
|
||||
@ -183,8 +184,8 @@ void splitIt(char *payload, unsigned int length, float *datas)
|
||||
|
||||
mqtt_callback mqttcb;
|
||||
|
||||
void mqtt_publish(const char *topic, const char *datas){
|
||||
esp_mqtt_client_publish(client, topic, datas, 0, 1, 0);
|
||||
void mqtt_publish(const char *topic, const char *datas, bool retain){
|
||||
esp_mqtt_client_publish(client, topic, datas, 0, 1, retain);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -238,6 +239,10 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
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);
|
||||
|
||||
@ -285,7 +290,13 @@ void mqtt_app_start(mqtt_callback callback, EventGroupHandle_t domotic_event_gro
|
||||
mqttcb=callback;
|
||||
esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker.address.uri = "mqtt://192.168.0.10",
|
||||
.network.timeout_ms = 1000};
|
||||
.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];
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
208
main/main.c
208
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"
|
||||
@ -39,6 +39,7 @@
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
#include "am2302_rmt.h"
|
||||
#include "esp_wifi.h"
|
||||
#endif
|
||||
// GPIO assignment
|
||||
#define AM2302_GPIO 4
|
||||
@ -106,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)
|
||||
{
|
||||
@ -128,11 +249,31 @@ 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);
|
||||
@ -297,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:
|
||||
@ -327,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;
|
||||
@ -352,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,
|
||||
@ -381,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,
|
||||
@ -483,7 +622,7 @@ ota_end:
|
||||
ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed");
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
*/}
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
am2302_handle_t sensor = NULL;
|
||||
@ -872,9 +1011,29 @@ 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();
|
||||
@ -888,14 +1047,24 @@ void app_main(void)
|
||||
|
||||
#else
|
||||
littlefs_mount();
|
||||
xTaskCreate(&drawIhm,"ihm_task",10000,getIHMQueueHandle(),10,NULL);
|
||||
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;
|
||||
@ -921,8 +1090,15 @@ void app_main(void)
|
||||
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()
|
||||
|
||||
Binary file not shown.
BIN
main/medias/sounds/mixkit-clear-announce-tones-2861.wav
Normal file
BIN
main/medias/sounds/mixkit-clear-announce-tones-2861.wav
Normal file
Binary file not shown.
@ -16,11 +16,13 @@ CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=8192
|
||||
CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y
|
||||
CONFIG_CACHE_L2_CACHE_LINE_128B=y
|
||||
CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y
|
||||
CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y
|
||||
CONFIG_FATFS_LFN_HEAP=y
|
||||
CONFIG_FREERTOS_HZ=1000
|
||||
CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y
|
||||
CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y
|
||||
CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM=n
|
||||
CONFIG_HEAP_POISONING_COMPREHENSIVE=y
|
||||
CONFIG_VFS_MAX_COUNT=15
|
||||
CONFIG_BSP_LCD_DPI_BUFFER_NUMS=2
|
||||
CONFIG_BSP_DISPLAY_LVGL_AVOID_TEAR=y
|
||||
|
||||
@ -1 +1 @@
|
||||
0.3
|
||||
0.0.5
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user