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": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "ESP-IDF",
|
"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",
|
"compileCommands": "${config:idf.buildPath}/compile_commands.json",
|
||||||
"includePath": [
|
"includePath": [
|
||||||
"${config:idf.espIdfPath}/components/**",
|
"${config:idf.espIdfPath}/components/**",
|
||||||
|
|||||||
2
.vscode/launch.json
vendored
@ -37,7 +37,7 @@
|
|||||||
"type": "cppdbg",
|
"type": "cppdbg",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "Build - Build IHM",
|
"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": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
|
|||||||
5
.vscode/settings.json
vendored
@ -7,13 +7,12 @@
|
|||||||
"idf.customExtraVars": {
|
"idf.customExtraVars": {
|
||||||
"OPENOCD_SCRIPTS": "/home/marc/.espressif/tools/openocd-esp32/v0.12.0-esp32-20251215/openocd-esp32/share/openocd/scripts",
|
"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/",
|
"ESP_ROM_ELF_DIR": "/home/marc/.espressif/tools/esp-rom-elfs/20240305/",
|
||||||
"IDF_TARGET": "linux"
|
"IDF_TARGET": "esp32p4"
|
||||||
},
|
},
|
||||||
"idf.gitPath": "git",
|
"idf.gitPath": "git",
|
||||||
"idf.adapterTargetName": "esp32s3",
|
"idf.adapterTargetName": "esp32s3",
|
||||||
"idf.openOcdConfigs": [
|
"idf.openOcdConfigs": [
|
||||||
"interface/ftdi/esp_ftdi.cfg",
|
"board/esp32p4-builtin.cfg"
|
||||||
"target/esp32.cfg"
|
|
||||||
],
|
],
|
||||||
"idf.flashType": "UART",
|
"idf.flashType": "UART",
|
||||||
"idf.port": "/dev/ttyUSB0",
|
"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)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
option(SIMULATION_QEMU "Build for QEMU simulation" OFF)
|
option(SIMULATION_QEMU "Build for QEMU simulation" OFF)
|
||||||
message(STATUS "ROOT:: SIMULATION_QEMU = ${SIMULATION_QEMU}")
|
message(STATUS "ROOT:: SIMULATION_QEMU = ${SIMULATION_QEMU}")
|
||||||
@ -33,7 +84,7 @@ endif()
|
|||||||
#list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/esp_timer")
|
#list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/esp_timer")
|
||||||
|
|
||||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
project(rgb_lcd)
|
project(domotic)
|
||||||
|
|
||||||
|
|
||||||
# -------------------------------------------------
|
# -------------------------------------------------
|
||||||
@ -61,3 +112,44 @@ else()
|
|||||||
|
|
||||||
add_link_options(-fsanitize=address)
|
add_link_options(-fsanitize=address)
|
||||||
endif()
|
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)
|
#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")
|
if(${IDF_TARGET} STREQUAL "esp32p4" OR ${IDF_TARGET} STREQUAL "esp32s3")
|
||||||
#esp32_p4_function_ev_board
|
#esp32_p4_function_ev_board
|
||||||
idf_component_register(SRC_DIRS . fonts
|
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_ok.png" "images/" "AUTO" "NONE")
|
||||||
lvgl_port_create_c_image("images/mqtt_ko.png" "images/" "ARGB8888" "NONE")
|
lvgl_port_create_c_image("images/mqtt_ko.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_add_images(${COMPONENT_LIB} "images/")
|
lvgl_port_add_images(${COMPONENT_LIB} "images/")
|
||||||
#littlefs_create_partition_image(littlefs images_meteo FLASH_IN_PROJECT)
|
|
||||||
elseif(${IDF_TARGET} STREQUAL "linux")
|
elseif(${IDF_TARGET} STREQUAL "linux")
|
||||||
idf_component_register(SRC_DIRS . fonts images
|
idf_component_register(SRC_DIRS . fonts images
|
||||||
INCLUDE_DIRS "include"
|
INCLUDE_DIRS "include"
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#include "platform_detect.h"
|
#include "platform_detect.h"
|
||||||
#include "cJSON.h"
|
#include "cJSON.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
#include "washingMachineState.h"
|
||||||
|
|
||||||
static const char *TAG = "IHM_GW";
|
static const char *TAG = "IHM_GW";
|
||||||
|
|
||||||
@ -34,10 +35,11 @@ void ihm_gateway_post_event(xIHMEvent_t *evt) {
|
|||||||
|
|
||||||
extern lv_subject_t wifiStatus;
|
extern lv_subject_t wifiStatus;
|
||||||
|
|
||||||
|
static xIHMEvent_t *evt = NULL;
|
||||||
|
|
||||||
void ihm_gateway_process_queue(void) {
|
void ihm_gateway_process_queue(void) {
|
||||||
if (!xIHMEventQueue) return;
|
if (!xIHMEventQueue) return;
|
||||||
|
|
||||||
xIHMEvent_t *evt = NULL;
|
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_LINUX
|
#if CONFIG_IDF_TARGET_LINUX
|
||||||
while (xQueueReceive(xIHMEventQueue, &evt, pdMS_TO_TICKS(0)) == pdTRUE)
|
while (xQueueReceive(xIHMEventQueue, &evt, pdMS_TO_TICKS(0)) == pdTRUE)
|
||||||
@ -48,7 +50,7 @@ void ihm_gateway_process_queue(void) {
|
|||||||
if (!evt) return;
|
if (!evt) return;
|
||||||
|
|
||||||
UBaseType_t pending = uxQueueMessagesWaiting(xIHMEventQueue);
|
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);
|
lv_async_call(traiteEvt, evt);
|
||||||
}
|
}
|
||||||
@ -65,7 +67,8 @@ void traiteEvt(void *arg)
|
|||||||
|
|
||||||
case IHM_EVT_TIME_SETTED:
|
case IHM_EVT_TIME_SETTED:
|
||||||
draw_time(evt->pvData);
|
draw_time(evt->pvData);
|
||||||
break;
|
evt->bNeedToFreeData=false;
|
||||||
|
break;
|
||||||
|
|
||||||
case IHM_EVT_OTA_STARTED:
|
case IHM_EVT_OTA_STARTED:
|
||||||
app_ota_display();
|
app_ota_display();
|
||||||
@ -73,6 +76,12 @@ void traiteEvt(void *arg)
|
|||||||
|
|
||||||
case IHM_EVT_HUMID_TEMP:
|
case IHM_EVT_HUMID_TEMP:
|
||||||
draw_temp((char *)evt->pvData);
|
draw_temp((char *)evt->pvData);
|
||||||
|
evt->bNeedToFreeData=false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IHM_EVT_TEMP_RECUE:
|
||||||
|
draw_tempExt((char *)evt->pvData);
|
||||||
|
evt->bNeedToFreeData=false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IHM_EVT_PUISSANCE_EMISE:
|
case IHM_EVT_PUISSANCE_EMISE:
|
||||||
@ -86,25 +95,20 @@ void traiteEvt(void *arg)
|
|||||||
case IHM_EVT_ETAT_MACHINE:
|
case IHM_EVT_ETAT_MACHINE:
|
||||||
{
|
{
|
||||||
char *etatMachine = evt->pvData;
|
char *etatMachine = evt->pvData;
|
||||||
cJSON *root = cJSON_Parse(etatMachine);
|
WashingMachineState wms = traiteMessage(etatMachine);
|
||||||
bool enRoute = cJSON_GetObjectItem(root, "state")->valueint;
|
char etat[80];
|
||||||
int timestamp = cJSON_GetObjectItem(root, "timestamp")->valueint;
|
getEtatMachineStr(wms, etat,80);
|
||||||
|
ESP_LOGI(TAG,"Etat machine : %s", etat);
|
||||||
time_t rawtime = (time_t)timestamp;
|
draw_minuteur(etat);
|
||||||
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);
|
|
||||||
|
|
||||||
// lv_label_set_text(lblEtatMachine, etatFormate);
|
// lv_label_set_text(lblEtatMachine, etatFormate);
|
||||||
cJSON_Delete(root);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case IHM_EVT_MACHINE_TERMINEE:
|
||||||
|
{
|
||||||
|
draw_minuteurStop();
|
||||||
|
}
|
||||||
|
|
||||||
case IHM_EVT_HAUTEUR_CUVE:
|
case IHM_EVT_HAUTEUR_CUVE:
|
||||||
{
|
{
|
||||||
float hauteur = *(float *)evt->pvData;
|
float hauteur = *(float *)evt->pvData;
|
||||||
@ -112,13 +116,39 @@ void traiteEvt(void *arg)
|
|||||||
break;
|
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:
|
default:
|
||||||
ESP_LOGE(TAG, "Evt inconnu");
|
ESP_LOGE(TAG, "Evt inconnu");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Nettoyage mémoire sécurisé
|
// 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->pvData);
|
||||||
|
}
|
||||||
free(evt);
|
free(evt);
|
||||||
ESP_LOGV(TAG, "Evt traité");
|
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 draw_tabVolets();
|
||||||
void meteoCb(lv_obj_t *base_obj);
|
void meteoCb(lv_obj_t *base_obj);
|
||||||
|
void createBackBtn(lv_obj_t *ontainer);
|
||||||
|
void initHome();
|
||||||
void drawHome();
|
void drawHome();
|
||||||
|
|
||||||
void draw_time(struct tm *dateHeure);
|
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_temp(char *tempHumid);
|
||||||
|
|
||||||
|
void draw_meteo(meteo_event_payload_t *meteo);
|
||||||
|
|
||||||
void create_card();
|
void create_card();
|
||||||
|
|
||||||
void weather_data_retreived_start();
|
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);
|
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_tabHome(lv_obj_t * parent);
|
||||||
void draw_tabSettings(lv_obj_t * parent);
|
void draw_tabSettings(lv_obj_t * parent);
|
||||||
|
|
||||||
|
void suspendIHM();
|
||||||
|
|
||||||
void drawIhm(void *pvParameter);
|
void drawIhm(void *pvParameter);
|
||||||
|
|||||||
@ -10,6 +10,7 @@ list(APPEND EXTRA_COMPONENT_DIRS
|
|||||||
../../stateManagement
|
../../stateManagement
|
||||||
../../eventsManager
|
../../eventsManager
|
||||||
../../RemindMe
|
../../RemindMe
|
||||||
|
../../washingMachineState
|
||||||
)
|
)
|
||||||
|
|
||||||
idf_build_set_property(COMPILE_DEFINITIONS "NO_DEBUG_STORAGE" APPEND)
|
idf_build_set_property(COMPILE_DEFINITIONS "NO_DEBUG_STORAGE" APPEND)
|
||||||
|
|||||||
@ -2,7 +2,7 @@ dependencies:
|
|||||||
idf:
|
idf:
|
||||||
source:
|
source:
|
||||||
type: idf
|
type: idf
|
||||||
version: 5.5.2
|
version: 5.5.0
|
||||||
lvgl/lvgl:
|
lvgl/lvgl:
|
||||||
component_hash: 17e68bfd21f0edf4c3ee838e2273da840bf3930e5dbc3bfa6c1190c3aed41f9f
|
component_hash: 17e68bfd21f0edf4c3ee838e2273da840bf3930e5dbc3bfa6c1190c3aed41f9f
|
||||||
dependencies: []
|
dependencies: []
|
||||||
|
|||||||
@ -20,7 +20,7 @@ idf_component_register(SRCS
|
|||||||
"../../include"
|
"../../include"
|
||||||
"../mock"
|
"../mock"
|
||||||
WHOLE_ARCHIVE
|
WHOLE_ARCHIVE
|
||||||
REQUIRES lvgl meteofrance RemindMe)
|
REQUIRES lvgl meteofrance RemindMe washingMachineState)
|
||||||
|
|
||||||
message("Including SDL2 support")
|
message("Including SDL2 support")
|
||||||
find_package(PkgConfig REQUIRED)
|
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
|
idf_component_register(SRCS "obtain_time.c" "eventsManager.c" obtain_time.c
|
||||||
INCLUDE_DIRS "include"
|
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 "mqtt_client.h"
|
||||||
#include "obtain_time.h"
|
#include "obtain_time.h"
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include "meteofrance.h"
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32P4
|
||||||
|
#include "audio.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
EventGroupHandle_t domotic_event_group;
|
EventGroupHandle_t domotic_event_group;
|
||||||
QueueHandle_t ihm_queue;
|
QueueHandle_t ihm_queue;
|
||||||
//extern esp_mqtt_client_handle_t client;
|
extern esp_mqtt_client_handle_t client;
|
||||||
|
|
||||||
static const char *TAG = "evtMgr";
|
static const char *TAG = "evtMgr";
|
||||||
|
|
||||||
@ -25,8 +29,43 @@ void startEvtManager(){
|
|||||||
/* Tache updateTime - FIN*/
|
/* 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) {
|
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));
|
xIHMEvent_t *ihmEvt = malloc(sizeof(xIHMEvent_t));
|
||||||
if (!ihmEvt) {
|
if (!ihmEvt) {
|
||||||
@ -78,12 +117,13 @@ void send_event(domo_events evt, void* pDatas) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case EVT_BTN_VOLET:
|
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
|
free(ihmEvt); // rien à envoyer à l'IHM
|
||||||
|
ihmEvt = NULL;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case EVT_PUISSANCE_RECUE:
|
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));
|
int *data = malloc(sizeof(int));
|
||||||
if (!data) {
|
if (!data) {
|
||||||
ESP_LOGE(TAG, "malloc failed for puissance_5mn");
|
ESP_LOGE(TAG, "malloc failed for puissance_5mn");
|
||||||
@ -110,6 +150,38 @@ void send_event(domo_events evt, void* pDatas) {
|
|||||||
ihmEvt->bNeedToFreeData = true;
|
ihmEvt->bNeedToFreeData = true;
|
||||||
break;
|
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: {
|
case EVT_HAUTEUR_CUVE: {
|
||||||
float *data = malloc(sizeof(float));
|
float *data = malloc(sizeof(float));
|
||||||
if (!data) {
|
if (!data) {
|
||||||
@ -125,13 +197,49 @@ void send_event(domo_events evt, void* pDatas) {
|
|||||||
break;
|
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:
|
default:
|
||||||
ESP_LOGE(TAG, "Unhandled event type");
|
ESP_LOGE(TAG, "Unhandled event type");
|
||||||
free(ihmEvt);
|
free(ihmEvt);
|
||||||
|
ihmEvt = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ESP_LOGE(TAG, "Envoi d'un evt %i a l'IHM", ihmEvt->eEventType);
|
|
||||||
if( ihm_queue != NULL && ihmEvt){
|
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)
|
if (xQueueSendToFront(ihm_queue, &ihmEvt, pdMS_TO_TICKS(10)) != pdPASS)
|
||||||
{
|
{
|
||||||
ESP_LOGE(TAG, "La queue est pleine");
|
ESP_LOGE(TAG, "La queue est pleine");
|
||||||
@ -141,5 +249,8 @@ void send_event(domo_events evt, void* pDatas) {
|
|||||||
}
|
}
|
||||||
free(ihmEvt);
|
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_PUISSANCE_EMISE,
|
||||||
IHM_EVT_ETAT_MACHINE,
|
IHM_EVT_ETAT_MACHINE,
|
||||||
IHM_EVT_HAUTEUR_CUVE,
|
IHM_EVT_HAUTEUR_CUVE,
|
||||||
|
IHM_EVT_METEO_RECUE,
|
||||||
|
IHM_EVT_TEMP_RECUE,
|
||||||
|
IHM_EVT_MACHINE_TERMINEE
|
||||||
} eIHMEvent_t;
|
} eIHMEvent_t;
|
||||||
|
|
||||||
typedef struct IHM_EVENT
|
typedef struct IHM_EVENT
|
||||||
@ -29,8 +32,22 @@ typedef enum domo_events{
|
|||||||
EVT_BTN_VOLET,
|
EVT_BTN_VOLET,
|
||||||
EVT_PUISSANCE_RECUE,
|
EVT_PUISSANCE_RECUE,
|
||||||
EVT_ETAT_MACHINE,
|
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;
|
} domo_events;
|
||||||
void startEvtManager();
|
void startEvtManager();
|
||||||
QueueHandle_t getIHMQueueHandle();
|
QueueHandle_t getIHMQueueHandle();
|
||||||
void send_event(domo_events evt, void *pDatas);
|
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)
|
while (1)
|
||||||
{
|
{
|
||||||
time(&now);
|
time(&now);
|
||||||
setenv("TZ", "CET-1CEST,M3.5.0,M10.5.0/3", 1);
|
|
||||||
tzset();
|
|
||||||
struct tm timeinfo = {0};
|
struct tm timeinfo = {0};
|
||||||
localtime_r(&now, &timeinfo);
|
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));
|
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];
|
char icon[9];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct meteodailyforecast_data
|
typedef struct meteodailyforecast_data // Meteo "par jour"
|
||||||
{
|
{
|
||||||
|
char *type;
|
||||||
time_t datetime;
|
time_t datetime;
|
||||||
bool isValid;
|
bool isValid;
|
||||||
struct dailyforecast_prev previsions;
|
struct dailyforecast_prev previsions;
|
||||||
} meteodailyforecast_data;
|
} meteodailyforecast_data;
|
||||||
|
|
||||||
typedef struct meteoforecast_data
|
typedef struct meteoforecast_data // Meteo "par heure"
|
||||||
{
|
{
|
||||||
|
char *type;
|
||||||
time_t datetime;
|
time_t datetime;
|
||||||
bool isValid;
|
bool isValid;
|
||||||
struct forecast_prev previsions;
|
struct forecast_prev previsions;
|
||||||
} meteoforecast_data;
|
} 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 void (*weather_data_start_callback)();
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -60,7 +67,7 @@
|
|||||||
void printftemp(struct forecast_prev * tmp);
|
void printftemp(struct forecast_prev * tmp);
|
||||||
void printfdf(struct meteodailyforecast_data * tmp);
|
void printfdf(struct meteodailyforecast_data * tmp);
|
||||||
void dtToString(time_t, char *buffer);
|
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 printff(struct meteoforecast_data * tmp);
|
||||||
|
|
||||||
void on_weather_data_retrieval(weather_data_callback data_retreived_cb);
|
void on_weather_data_retrieval(weather_data_callback data_retreived_cb);
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
#include "esp_http_client.h"
|
#include "esp_http_client.h"
|
||||||
#include "esp_tls.h"
|
#include "esp_tls.h"
|
||||||
#include "stateManagement.h"
|
#include "stateManagement.h"
|
||||||
|
#include "eventsManager.h"
|
||||||
static const char *TAG = "MeteoFrance";
|
static const char *TAG = "MeteoFrance";
|
||||||
|
|
||||||
/* Constants that aren't configurable in menuconfig
|
/* Constants that aren't configurable in menuconfig
|
||||||
@ -39,8 +40,8 @@ static const char *TAG = "MeteoFrance";
|
|||||||
#define MAX_HTTP_OUTPUT_BUFFER 32000
|
#define MAX_HTTP_OUTPUT_BUFFER 32000
|
||||||
|
|
||||||
static weather_data weather;
|
static weather_data weather;
|
||||||
static struct meteodailyforecast_data dailydatas[5];
|
static struct meteodailyforecast_data dailydatas[3];
|
||||||
static struct meteoforecast_data forecastdatas[5];
|
static struct meteoforecast_data forecastdatas[3];
|
||||||
|
|
||||||
void printdftemp(struct dailyforecast_prev *tmp)
|
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);
|
//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};
|
struct tm timeinfo = {0};
|
||||||
localtime_r(&ttt, &timeinfo);
|
localtime_r(&ttt, &timeinfo);
|
||||||
strftime(buffer, MAX_SIZE, "%H:%M", &timeinfo);
|
strftime(buffer, bufSize, "%H:%M", &timeinfo);
|
||||||
//char strftime_buf[64];
|
//char strftime_buf[64];
|
||||||
//sprintf(strftime_buf, "%d %d %d", timeinfo.tm_wday, timeinfo.tm_mday, timeinfo.tm_mon + 1);
|
//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");
|
cJSON *dt = cJSON_GetObjectItem(current_element, "dt");
|
||||||
if (cJSON_IsNumber(dt))
|
if (cJSON_IsNumber(dt))
|
||||||
{
|
{
|
||||||
|
datasT.type="Daily";
|
||||||
datasT.datetime = dt->valueint;
|
datasT.datetime = dt->valueint;
|
||||||
cJSON *temps = cJSON_GetObjectItem(current_element, "T");
|
cJSON *temps = cJSON_GetObjectItem(current_element, "T");
|
||||||
datasT.previsions.min = cJSON_GetObjectItem(temps, "min")->valuedouble;
|
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");
|
cJSON *dt = cJSON_GetObjectItem(current_element, "dt");
|
||||||
if (cJSON_IsNumber(dt))
|
if (cJSON_IsNumber(dt))
|
||||||
{
|
{
|
||||||
|
datasT.type="Hourly";
|
||||||
datasT.datetime = dt->valueint;
|
datasT.datetime = dt->valueint;
|
||||||
struct tm timeinfo = {0};
|
struct tm timeinfo = {0};
|
||||||
localtime_r(&(datasT.datetime), &timeinfo);
|
localtime_r(&(datasT.datetime), &timeinfo);
|
||||||
@ -379,8 +382,13 @@ static void meteo_task(void* domotic_event_group)
|
|||||||
heap_caps_free(local_response_buffer);
|
heap_caps_free(local_response_buffer);
|
||||||
esp_http_client_cleanup(client);
|
esp_http_client_cleanup(client);
|
||||||
if(dailydatas->isValid){
|
if(dailydatas->isValid){
|
||||||
ESP_LOGV(TAG, "Données valides on appelle le cb");
|
ESP_LOGE(TAG, "Données valides on appelle le cb");
|
||||||
weather.data_retreived_cb(dailydatas, forecastdatas);
|
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);
|
vTaskDelay(weather.retreival_period / portTICK_PERIOD_MS);
|
||||||
}else{
|
}else{
|
||||||
//Ca a échoué on recommence dans 30 secondes
|
//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:
|
dependencies:
|
||||||
espressif/esp_lcd_qemu_rgb:
|
espressif/bh1750:
|
||||||
component_hash: e8981dd7399504a5ab647ce28a4876f8467c03b759895f50c24f0cb6095faaa0
|
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:
|
dependencies:
|
||||||
- name: idf
|
- name: idf
|
||||||
require: private
|
require: private
|
||||||
version: '>=5.3'
|
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:
|
source:
|
||||||
registry_url: https://components.espressif.com/
|
registry_url: https://components.espressif.com/
|
||||||
type: service
|
type: service
|
||||||
version: 1.0.2
|
version: 1.2.0~1
|
||||||
espressif/esp_lvgl_port:
|
espressif/esp_lvgl_port:
|
||||||
component_hash: f872401524cb645ee6ff1c9242d44fb4ddcfd4d37d7be8b9ed3f4e85a404efcd
|
component_hash: b6360960f47b6776462e7092861b3ea66477ffb762a01baa0aecbb3d74cd50f4
|
||||||
dependencies:
|
dependencies:
|
||||||
- name: idf
|
- name: idf
|
||||||
require: private
|
require: private
|
||||||
@ -22,22 +229,153 @@ dependencies:
|
|||||||
source:
|
source:
|
||||||
registry_url: https://components.espressif.com/
|
registry_url: https://components.espressif.com/
|
||||||
type: service
|
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:
|
idf:
|
||||||
source:
|
source:
|
||||||
type: idf
|
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:
|
lvgl/lvgl:
|
||||||
|
component_hash: 184e532558c1c45fefed631f3e235423d22582aafb4630f3e8885c35281a49ae
|
||||||
dependencies: []
|
dependencies: []
|
||||||
source:
|
source:
|
||||||
path: /home/marc/domotic/components/lvgl__lvgl
|
registry_url: https://components.espressif.com
|
||||||
type: local
|
type: service
|
||||||
version: 9.4.0
|
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:
|
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_lvgl_port
|
||||||
|
- espressif/esp_wifi_remote
|
||||||
- idf
|
- idf
|
||||||
- lvgl/lvgl
|
- joltwallet/littlefs
|
||||||
manifest_hash: 6dfd2d16dd4d21f701b251046402dbd6cb442f0c69beab0ba9af1b2ef32c7367
|
- suda-morris/am2302_rmt
|
||||||
target: esp32s3
|
manifest_hash: ff7936466302f0a070f567433bba5708f3bdab0fb5fa4b9941b77ae4ac95532c
|
||||||
|
target: esp32p4
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
|
|||||||
@ -5,16 +5,17 @@ set(comps heap nvs_flash esp_netif image_downloader fatfs protocol_examples_comm
|
|||||||
|
|
||||||
if(${IDF_TARGET} STREQUAL "esp32p4")
|
if(${IDF_TARGET} STREQUAL "esp32p4")
|
||||||
message(STATUS "SIMULATION_QEMU = OOF --> main standard")
|
message(STATUS "SIMULATION_QEMU = OOF --> main standard")
|
||||||
list(APPEND comps esp32_p4_function_ev_board sdmmc vfs littlefs app_update esp_https_ota espcoredump esp_http_server esp_wifi )
|
list(APPEND comps esp32_p4_function_ev_board sdmmc vfs littlefs app_update esp_https_ota espcoredump esp_http_server esp_wifi)
|
||||||
idf_component_register(SRCS main.c communication.c
|
idf_component_register(SRCS main.c communication.c
|
||||||
INCLUDE_DIRS "./include"
|
INCLUDE_DIRS "./include"
|
||||||
REQUIRES ${comps}
|
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")
|
EMBED_FILES "index.html")
|
||||||
|
littlefs_create_partition_image(littlefs medias FLASH_IN_PROJECT)
|
||||||
elseif(${IDF_TARGET} STREQUAL "linux")
|
elseif(${IDF_TARGET} STREQUAL "linux")
|
||||||
message(STATUS "Linux Mode --> main standard")
|
message(STATUS "Linux Mode --> main standard")
|
||||||
list(APPEND comps vfs esp_http_server)
|
list(APPEND comps vfs esp_http_server)
|
||||||
idf_component_register(SRCS main.c
|
idf_component_register(SRCS main.c communication.c
|
||||||
INCLUDE_DIRS "./include"
|
INCLUDE_DIRS "./include"
|
||||||
REQUIRES ${comps}
|
REQUIRES ${comps}
|
||||||
EMBED_TXTFILES ${PROJECT_DIR}/main/ca_cert.pem
|
EMBED_TXTFILES ${PROJECT_DIR}/main/ca_cert.pem
|
||||||
|
|||||||
@ -2,206 +2,22 @@
|
|||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "mqtt_client.h"
|
#include "mqtt_client.h"
|
||||||
#include "stateManagement.h"
|
#include "stateManagement.h"
|
||||||
|
#include "eventsManager.h"
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32P4
|
||||||
#include "esp_wifi.h"
|
#include "esp_wifi.h"
|
||||||
|
#endif
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
|
||||||
esp_mqtt_client_handle_t client;
|
|
||||||
|
|
||||||
static const char *TAG = "domo_mqtt";
|
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*/
|
/* FreeRTOS event group to signal when we are connected*/
|
||||||
static EventGroupHandle_t s_wifi_event_group;
|
static EventGroupHandle_t s_wifi_event_group;
|
||||||
|
|
||||||
/* The event group allows multiple bits for each event, but we only care about two events:
|
/* 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 are connected to the AP with an IP
|
||||||
* - we failed to connect after the maximum amount of retries */
|
* - we failed to connect after the maximum amount of retries */
|
||||||
|
#define BIT0 0x00000001
|
||||||
|
|
||||||
#define WIFI_CONNECTED_BIT BIT0
|
#define WIFI_CONNECTED_BIT BIT0
|
||||||
#define WIFI_FAIL_BIT BIT1
|
#define WIFI_FAIL_BIT BIT1
|
||||||
|
|
||||||
@ -215,7 +31,8 @@ static EventGroupHandle_t s_wifi_event_group;
|
|||||||
static int s_retry_num = 0;
|
static int s_retry_num = 0;
|
||||||
wifi_callback cb;
|
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)
|
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)
|
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);
|
typedef void (*mqtt_callback)(mqtt_evt evt, esp_mqtt_event_handle_t evt_data);
|
||||||
void wifi_init_sta(wifi_callback cb);
|
void wifi_init_sta(wifi_callback cb);
|
||||||
void mqtt_app_start(mqtt_callback cb, EventGroupHandle_t evtGroup);
|
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>
|
<h1>Developed by Mark</h1>
|
||||||
<h2>How to save and Download crash dump</h2>
|
<h2>How to save and Download crash dump</h2>
|
||||||
</br></br>
|
</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="./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="./crash">Crash</a></button>
|
||||||
</center>
|
</center>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
298
main/main.c
@ -20,10 +20,10 @@
|
|||||||
#include "ihm_gateway.h"
|
#include "ihm_gateway.h"
|
||||||
|
|
||||||
// OTA
|
// OTA
|
||||||
/*#include "esp_ota_ops.h"
|
#include "esp_ota_ops.h"
|
||||||
#include "esp_http_client.h"
|
|
||||||
#include "esp_https_ota.h"
|
#include "esp_https_ota.h"
|
||||||
*/
|
#include "esp_http_client.h"
|
||||||
|
|
||||||
// Includes personnels
|
// Includes personnels
|
||||||
//#include "wifi_logger.h"
|
//#include "wifi_logger.h"
|
||||||
#include "obtain_time.h"
|
#include "obtain_time.h"
|
||||||
@ -31,13 +31,16 @@
|
|||||||
#include "include/communication.h"
|
#include "include/communication.h"
|
||||||
#include "stateManagement.h"
|
#include "stateManagement.h"
|
||||||
//#include "driver/gpio.h"
|
//#include "driver/gpio.h"
|
||||||
//#include "am2302_rmt.h"
|
|
||||||
#include "eventsManager.h"
|
#include "eventsManager.h"
|
||||||
|
|
||||||
#include "esp_timer.h"
|
#include "esp_timer.h"
|
||||||
|
|
||||||
#include <esp_task_wdt.h>
|
#include <esp_task_wdt.h>
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32P4
|
||||||
|
#include "am2302_rmt.h"
|
||||||
|
#include "esp_wifi.h"
|
||||||
|
#endif
|
||||||
// GPIO assignment
|
// GPIO assignment
|
||||||
#define AM2302_GPIO 4
|
#define AM2302_GPIO 4
|
||||||
|
|
||||||
@ -104,8 +107,128 @@ void bh1750_init(void)
|
|||||||
bh1750 = bh1750_create(I2C_MASTER_NUM, BH1750_I2C_ADDRESS_DEFAULT, bus_handle);
|
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){
|
void mqtt_cb(mqtt_evt evt, esp_mqtt_event_handle_t event){
|
||||||
switch (evt)
|
switch (evt)
|
||||||
{
|
{
|
||||||
@ -126,16 +249,37 @@ void mqtt_cb(mqtt_evt evt, esp_mqtt_event_handle_t event){
|
|||||||
break;
|
break;
|
||||||
case MQTT_DATA_RECEIVED:
|
case MQTT_DATA_RECEIVED:
|
||||||
//lv_subject_set_int(&mqttStatus,2);
|
//lv_subject_set_int(&mqttStatus,2);
|
||||||
ESP_LOGD(TAG, "\nMQTT_EVENT_DATA");
|
ESP_LOGE(TAG, "MQTT_EVENT_DATA");
|
||||||
ESP_LOGD(TAG, "TOPIC=%.*s\n", event->topic_len, event->topic);
|
ESP_LOGE(TAG, "TOPIC=%.*s\n", event->topic_len, event->topic);
|
||||||
ESP_LOGD(TAG, "DATA=%.*s\n", event->data_len, event->data);
|
ESP_LOGE(TAG, "DATA=%.*s\n", event->data_len, event->data);
|
||||||
char *topic = strndup(event->topic, event->topic_len);
|
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)){
|
//if(lvgl_port_lock(50)){
|
||||||
float temp = strtof(event->data, NULL);
|
float temp = strtof(event->data, NULL);
|
||||||
char buff[5];
|
char buff[5];
|
||||||
sprintf(buff,"%.1f",temp);
|
sprintf(buff,"%.1f",temp);
|
||||||
|
send_event(EVT_TEMP_EXT, buff);
|
||||||
//lv_subject_copy_string(&tempExtSubj, buff);
|
//lv_subject_copy_string(&tempExtSubj, buff);
|
||||||
|
|
||||||
//lvgl_port_unlock();
|
//lvgl_port_unlock();
|
||||||
@ -294,7 +438,7 @@ extern char *days[7];
|
|||||||
extern char *months[12];
|
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) {
|
switch (evt->event_id) {
|
||||||
case HTTP_EVENT_ERROR:
|
case HTTP_EVENT_ERROR:
|
||||||
@ -324,11 +468,10 @@ extern char *months[12];
|
|||||||
}
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
extern const uint8_t server_cert_pem_start[] asm("_binary_ca_cert_pem_start");
|
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");
|
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) {
|
if (new_app_info == NULL) {
|
||||||
return ESP_ERR_INVALID_ARG;
|
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;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
void simple_ota_example_task(void *pvParameter)
|
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).
|
// Waiting until either the connection is established (WIFI_CONNECTED_BIT).
|
||||||
EventBits_t bits = xEventGroupWaitBits(domotic_event_group,
|
EventBits_t bits = xEventGroupWaitBits(domotic_event_group,
|
||||||
BIT0,
|
BIT0,
|
||||||
@ -378,8 +520,8 @@ void simple_ota_example_task(void *pvParameter)
|
|||||||
esp_http_client_config_t config = {
|
esp_http_client_config_t config = {
|
||||||
.url = "https://192.168.0.28:8070/rgb_lcd.bin",
|
.url = "https://192.168.0.28:8070/rgb_lcd.bin",
|
||||||
.timeout_ms = 30000,
|
.timeout_ms = 30000,
|
||||||
.buffer_size = 20000,
|
.buffer_size = 6144,
|
||||||
.buffer_size_tx = 20000, //TX Buffer, Main Buffer
|
.buffer_size_tx = 6144, //TX Buffer, Main Buffer
|
||||||
.event_handler = _ota_http_event_handler,
|
.event_handler = _ota_http_event_handler,
|
||||||
.keep_alive_enable = true,
|
.keep_alive_enable = true,
|
||||||
.cert_pem = (char *)server_cert_pem_start,
|
.cert_pem = (char *)server_cert_pem_start,
|
||||||
@ -480,13 +622,14 @@ ota_end:
|
|||||||
ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed");
|
ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed");
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
||||||
*/}
|
}
|
||||||
|
|
||||||
//am2302_handle_t sensor = NULL;
|
#if CONFIG_IDF_TARGET_ESP32P4
|
||||||
|
am2302_handle_t sensor = NULL;
|
||||||
|
|
||||||
void readTempHumid(void *pvParameter)
|
void readTempHumid(void *pvParameter)
|
||||||
{
|
{
|
||||||
/* float temperature = 0;
|
float temperature = 0;
|
||||||
float humidity = 0;
|
float humidity = 0;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -494,16 +637,30 @@ void readTempHumid(void *pvParameter)
|
|||||||
char buff[40];
|
char buff[40];
|
||||||
ESP_LOGI(TAG, "Temperature: %.1f °C, Humidity: %.1f %%", temperature, humidity);
|
ESP_LOGI(TAG, "Temperature: %.1f °C, Humidity: %.1f %%", temperature, humidity);
|
||||||
sprintf(buff,"%.1f °C, %.1f %%", temperature, humidity);
|
sprintf(buff,"%.1f °C, %.1f %%", temperature, humidity);
|
||||||
xIHMEvent_t m = {
|
send_event(EVT_TEMP_INT, buff);
|
||||||
.eEventType = IHM_EVT_HUMID_TEMP,
|
|
||||||
.pvData = buff
|
|
||||||
};
|
|
||||||
//xQueueSendToFront(ihm_queue,&m,5);
|
|
||||||
vTaskDelay(60000 / portTICK_PERIOD_MS);
|
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){
|
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);
|
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 forecastH3Subj;
|
||||||
extern lv_subject_t meteoStatus;
|
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");
|
/* ESP_LOGE(TAG, "debut debug");
|
||||||
printf("%lld\n", datas[0].datetime);
|
printf("%lld\n", datas[0].datetime);
|
||||||
printf("%s\n", datas[0].previsions.desc);
|
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"))
|
//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{
|
//}else{
|
||||||
//ESP_LOGE(TAG, "Impossible d'obtenir le mutex dans weather_data_retreived");
|
//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)
|
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());
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||||
|
|
||||||
ihm_gateway_init();
|
ihm_gateway_init();
|
||||||
startEvtManager();
|
startEvtManager();
|
||||||
|
|
||||||
boucleMeteo();
|
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_LINUX
|
#if CONFIG_IDF_TARGET_LINUX
|
||||||
// en mode linux on simule l'obtention de la connexion wifi
|
// en mode linux on simule l'obtention de la connexion wifi
|
||||||
xEventGroupSetBits(domotic_event_group, WIFI_CONNECTED_BIT);
|
xEventGroupSetBits(domotic_event_group, WIFI_CONNECTED_BIT);
|
||||||
@ -887,13 +1046,27 @@ void app_main(void)
|
|||||||
//drawIhm(getIHMQueueHandle());
|
//drawIhm(getIHMQueueHandle());
|
||||||
|
|
||||||
#else
|
#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
|
//et sinon on se connecte
|
||||||
ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
|
ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
|
||||||
wifi_init_sta(wifi_cb);
|
wifi_init_sta(wifi_cb);
|
||||||
//start_wifi_logger();
|
//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
|
#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;
|
TaskHandle_t xHandle = NULL;
|
||||||
BaseType_t ret1;
|
BaseType_t ret1;
|
||||||
/*ret1 = xTaskCreate(&imgdwn, "imageDownload_task", 3 * 1024, domotic_event_group, 5, &xHandle);
|
/*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);
|
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()
|
void boucleMeteo()
|
||||||
@ -1028,14 +1225,5 @@ void app_main1(void)
|
|||||||
start_webserver();
|
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 |