Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d505c2fa97 | |||
| c3f0c148ba | |||
| 58378ea2cf | |||
| 2464d13196 | |||
| a3d0fa3d25 | |||
| 43b32b8b68 | |||
| 689d51b463 | |||
| dfbd28861e | |||
| ba266479dd | |||
| 93bffe925f | |||
|
|
c7b46b5bfe | ||
|
|
169b8d62b1 | ||
|
|
d132f39ff8 | ||
|
|
7e24eaa207 | ||
|
|
8b78cb0a25 | ||
|
|
7ff8979051 | ||
|
|
77953a3397 | ||
|
|
48aab82046 | ||
|
|
896aefde48 | ||
|
|
84bec90407 | ||
|
|
bf85c544f5 | ||
|
|
e55b74b0a2 | ||
|
|
88c3c93ae8 | ||
|
|
c81027e8e8 | ||
| ab2399ce50 | |||
| 27c2376717 | |||
| 829dcfc285 | |||
| 4abbf3abea | |||
| 3aeeff52eb | |||
| b232a0d8e1 | |||
| ad170a8aa7 | |||
| ef55ef2519 | |||
| 430f1c90fd | |||
| 1fea5e284d | |||
| 1375e82550 | |||
| 2beca08042 | |||
| a543836df4 | |||
| 4aa0daf463 | |||
| 72a58b373d | |||
| 16b277ff99 | |||
| 7715f8b153 | |||
| 20e04e0de2 | |||
| dba5b974c8 | |||
| 4ad7177c9f | |||
| 555a6c6b6a |
13
.devcontainer/Dockerfile
Normal file
@ -0,0 +1,13 @@
|
||||
ARG DOCKER_TAG=latest
|
||||
FROM espressif/idf:${DOCKER_TAG}
|
||||
|
||||
ENV LC_ALL=C.UTF-8
|
||||
ENV LANG=C.UTF-8
|
||||
|
||||
RUN apt-get update -y && apt-get install udev -y
|
||||
|
||||
RUN echo "source /opt/esp/idf/export.sh > /dev/null 2>&1" >> ~/.bashrc
|
||||
|
||||
ENTRYPOINT [ "/opt/esp/entrypoint.sh" ]
|
||||
|
||||
CMD ["/bin/bash", "-c"]
|
||||
21
.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "ESP-IDF QEMU",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile"
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"settings": {
|
||||
"terminal.integrated.defaultProfile.linux": "bash",
|
||||
"idf.espIdfPath": "/opt/esp/idf",
|
||||
"idf.toolsPath": "/opt/esp",
|
||||
"idf.gitPath": "/usr/bin/git"
|
||||
},
|
||||
"extensions": [
|
||||
"espressif.esp-idf-extension",
|
||||
"espressif.esp-idf-web"
|
||||
]
|
||||
}
|
||||
},
|
||||
"runArgs": ["--privileged"]
|
||||
}
|
||||
7
.gitignore
vendored
@ -1,2 +1,9 @@
|
||||
build/
|
||||
managed_components/
|
||||
build_slave/
|
||||
CMakeFiles/
|
||||
esp-idf/
|
||||
gdbinit/
|
||||
sdkconfig
|
||||
sdkconfig.old
|
||||
components/domotic_display/test_host/sdkconfig
|
||||
|
||||
2
.vscode/c_cpp_properties.json
vendored
@ -2,7 +2,7 @@
|
||||
"configurations": [
|
||||
{
|
||||
"name": "ESP-IDF",
|
||||
"compilerPath": "${config:idf.toolsPath}/tools/riscv32-esp-elf/esp-14.2.0_20240906/riscv32-esp-elf/bin/riscv32-esp-elf-gcc",
|
||||
"compilerPath": "${config:idf.toolsPath}/tools/xtensa-esp-elf/esp-14.2.0_20241119/xtensa-esp-elf/bin/xtensa-esp32-elf-gcc",
|
||||
"compileCommands": "${config:idf.buildPath}/compile_commands.json",
|
||||
"includePath": [
|
||||
"${config:idf.espIdfPath}/components/**",
|
||||
|
||||
131
.vscode/launch.json
vendored
@ -16,7 +16,7 @@
|
||||
"name": "Debug LVGL demo with gdb",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/bin/rgb_lcd",
|
||||
"program": "${workspaceFolder}/build/rgb_lcd",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
@ -32,6 +32,133 @@
|
||||
"miDebuggerPath": "C:\\MinGw\\bin\\gdb.exe"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Debug ihm with gdb",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "Build - Build IHM",
|
||||
"program": "${workspaceFolder}/components/domotic_display/test_host/build/nvs_host_test.elf",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
/*
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Load LVGL GDB helpers",
|
||||
"text": "source /home/marc/domotic/components/domotic_display/test_host/managed_components/lvgl__lvgl/scripts/gdb/gdbinit.py"
|
||||
}
|
||||
],*/
|
||||
"linux": {
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"osx": {
|
||||
"MIMode": "lldb"
|
||||
},
|
||||
"windows": {
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "C:\\MinGw\\bin\\gdb.exe"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Debug meteofrance with gdb",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/components/meteofrance/testHost/build/my_custom_app.elf",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
/*
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Load LVGL GDB helpers",
|
||||
"text": "source /home/marc/domotic/components/domotic_display/test_host/managed_components/lvgl__lvgl/scripts/gdb/gdbinit.py"
|
||||
}
|
||||
],*/
|
||||
"linux": {
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"osx": {
|
||||
"MIMode": "lldb"
|
||||
},
|
||||
"windows": {
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "C:\\MinGw\\bin\\gdb.exe"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Debug main with gdb",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/rgb_lcd.elf",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
/*
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Load LVGL GDB helpers",
|
||||
"text": "source /home/marc/domotic/components/domotic_display/test_host/managed_components/lvgl__lvgl/scripts/gdb/gdbinit.py"
|
||||
}
|
||||
],*/
|
||||
"linux": {
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"osx": {
|
||||
"MIMode": "lldb"
|
||||
},
|
||||
"windows": {
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "C:\\MinGw\\bin\\gdb.exe"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Debug remindme with gdb",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "Build - Build IHM",
|
||||
"program": "${workspaceFolder}/components/RemindMe/test/build/remindme_host_test.elf",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Load LVGL GDB helpers",
|
||||
"text": "source /home/marc/domotic/components/domotic_display/test_host/managed_components/lvgl__lvgl/scripts/gdb/gdbinit.py"
|
||||
}
|
||||
],
|
||||
"linux": {
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"osx": {
|
||||
"MIMode": "lldb"
|
||||
},
|
||||
"windows": {
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "C:\\MinGw\\bin\\gdb.exe"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Debug comp2 (Linux)",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/components/domotic_display/test_host/build/comp2_test",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "/usr/bin/gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty printing",
|
||||
"text": "-enable-pretty-printing"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
23
.vscode/settings.json
vendored
@ -1,18 +1,19 @@
|
||||
{
|
||||
"C_Cpp.intelliSenseEngine": "default",
|
||||
"idf.espIdfPath": "/home/marc/esp/master/esp-idf",
|
||||
"idf.pythonBinPath": "/home/marc/.espressif/python_env/idf5.3_py3.10_env/bin/python",
|
||||
"idf.espIdfPath": "/home/marc/esp/esp-idf",
|
||||
"idf.pythonBinPath": "/home/marc/.espressif/tools/python/v5.5.2/venv/bin/python3",
|
||||
"idf.toolsPath": "/home/marc/.espressif",
|
||||
"idf.customExtraPaths": "/home/marc/.espressif/tools/xtensa-esp-elf-gdb/14.2_20240403/xtensa-esp-elf-gdb/bin:/home/marc/.espressif/tools/riscv32-esp-elf-gdb/14.2_20240403/riscv32-esp-elf-gdb/bin:/home/marc/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20240530/xtensa-esp-elf/bin:/home/marc/.espressif/tools/riscv32-esp-elf/esp-13.2.0_20240530/riscv32-esp-elf/bin:/home/marc/.espressif/tools/esp32ulp-elf/2.38_20240113/esp32ulp-elf/bin:/home/marc/.espressif/tools/cmake/3.24.0/bin:/home/marc/.espressif/tools/openocd-esp32/v0.12.0-esp32-20240318/openocd-esp32/bin:/home/marc/.espressif/tools/ninja/1.11.1:/home/marc/.espressif/tools/esp-rom-elfs/20240305",
|
||||
"idf.customExtraVars": {
|
||||
"OPENOCD_SCRIPTS": "/home/marc/.espressif/tools/openocd-esp32/v0.12.0-esp32-20240318/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/",
|
||||
"IDF_TARGET": "esp32p4"
|
||||
"IDF_TARGET": "linux"
|
||||
},
|
||||
"idf.gitPath": "git",
|
||||
"idf.adapterTargetName": "esp32s3",
|
||||
"idf.openOcdConfigs": [
|
||||
"board/esp32p4-builtin.cfg"
|
||||
"interface/ftdi/esp_ftdi.cfg",
|
||||
"target/esp32.cfg"
|
||||
],
|
||||
"idf.flashType": "UART",
|
||||
"idf.port": "/dev/ttyUSB0",
|
||||
@ -105,7 +106,15 @@
|
||||
"bsp_board_extra.h": "c",
|
||||
"display.h": "c",
|
||||
"statemanagement.h": "c",
|
||||
"communication.h": "c"
|
||||
"communication.h": "c",
|
||||
"mqtt_client.h": "c"
|
||||
},
|
||||
"idf.pythonInstallPath": "/usr/bin/python3"
|
||||
"idf.pythonInstallPath": "/usr/bin/python3",
|
||||
"clangd.path": "/home/marc/.espressif/tools/esp-clang/esp-19.1.2_20250312/esp-clang/bin/clangd",
|
||||
"clangd.arguments": [
|
||||
"--background-index",
|
||||
"--query-driver=/home/marc/.espressif/tools/xtensa-esp-elf/esp-14.2.0_20241119/xtensa-esp-elf/bin/xtensa-esp32-elf-gcc",
|
||||
"--compile-commands-dir=/home/marc/domotic/build"
|
||||
],
|
||||
"idf.currentSetup": "/home/marc/.espressif/v5.5.2/esp-idf"
|
||||
}
|
||||
|
||||
43
.vscode/tasks.json
vendored
@ -33,7 +33,7 @@
|
||||
"isDefault": true
|
||||
},
|
||||
"dependsOn": "Build"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Build - Build project",
|
||||
"type": "shell",
|
||||
@ -73,6 +73,47 @@
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Build - Build IHM",
|
||||
"type": "shell",
|
||||
"command": "${config:idf.pythonBinPath} ${config:idf.espIdfPath}/tools/idf.py build",
|
||||
"windows": {
|
||||
"command": "${config:idf.pythonBinPathWin} ${config:idf.espIdfPathWin}\\tools\\idf.py build",
|
||||
"options": {
|
||||
"env": {
|
||||
"PATH": "${env:PATH};${config:idf.customExtraPaths}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/components/domotic_display/test_host/",
|
||||
"env": {
|
||||
"IDF_TARGET": "linux",
|
||||
"PATH": "${env:PATH}:${config:idf.customExtraPaths}"
|
||||
}
|
||||
},
|
||||
"problemMatcher": [
|
||||
{
|
||||
"owner": "cpp",
|
||||
"fileLocation": [
|
||||
"autoDetect",
|
||||
"${workspaceFolder}"
|
||||
],
|
||||
"pattern": {
|
||||
"regexp": "^(.*?):(\\d+):(\\d*):?\\s+(?:fatal\\s+)?(warning|error):\\s+(.*)$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3,
|
||||
"severity": 4,
|
||||
"message": 5
|
||||
}
|
||||
}
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Set ESP-IDF Target",
|
||||
"type": "shell",
|
||||
|
||||
@ -1,28 +1,63 @@
|
||||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
option(SIMULATION_QEMU "Build for QEMU simulation" OFF)
|
||||
message(STATUS "ROOT:: SIMULATION_QEMU = ${SIMULATION_QEMU}")
|
||||
# -------------------------------------------------
|
||||
# CONFIGURATION AVANT project() : uniquement CMake pur
|
||||
# -------------------------------------------------
|
||||
|
||||
# "Trim" the build. Include the minimal set of components, main and anything it depends on.
|
||||
set(COMPONENTS main)
|
||||
|
||||
|
||||
if(SIMULATION_QEMU)
|
||||
message(STATUS "SIMULATION_QEMU = ON")
|
||||
option(SIMULATION_QEMU "Build for QEMU simulation" ON)
|
||||
set(COMPONENTS
|
||||
components/meteofrance
|
||||
components/domotic_display
|
||||
managed_components/lvgl_lvgl
|
||||
main
|
||||
esp-timer
|
||||
$ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs
|
||||
)
|
||||
|
||||
else()
|
||||
message(STATUS "SIMULATION_QEMU = OFF")
|
||||
option(SIMULATION_QEMU "Build for QEMU simulation" OFF)
|
||||
# set(COMPONENTS
|
||||
# components/meteofrance
|
||||
# components/domotic_display
|
||||
# managed_components/lvgl_lvgl
|
||||
# main
|
||||
# $ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs
|
||||
# )
|
||||
endif()
|
||||
#list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/esp_timer")
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
||||
if(${IDF_TARGET} STREQUAL "esp32p4")
|
||||
set(EXTRA_COMPONENT_DIRS
|
||||
/home/marc/esp-dev-kits/examples/esp32-p4-function-ev-board/examples/common_components
|
||||
$ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs
|
||||
)
|
||||
else()
|
||||
# PROJECT_PLATFORM_LINUX
|
||||
# PROJECT_PLATFORM_ESP32
|
||||
add_compile_definitions(PROJECT_PLATFORM_LINUX)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS
|
||||
$ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/FreeRTOS
|
||||
"/home/marc/esp-protocols/common_components/linux_compat"
|
||||
"/home/marc/esp-protocols/components/mdns/tests/host_test/components"
|
||||
)
|
||||
endif()
|
||||
|
||||
project(rgb_lcd)
|
||||
|
||||
|
||||
# -------------------------------------------------
|
||||
# APRÈS project() : maintenant CONFIG_SIMULATION_QEMU existe
|
||||
# -------------------------------------------------
|
||||
|
||||
if(CONFIG_SIMULATION_QEMU)
|
||||
message(STATUS "Compilation IHM (simulation)")
|
||||
add_compile_definitions(CONFIG_SIMULATION_QEMU=1)
|
||||
|
||||
#add_custom_target(run_ihm
|
||||
# COMMAND ${CMAKE_COMMAND} -E echo "Building and launching IHM native..."
|
||||
# COMMAND ${CMAKE_COMMAND} --build ${CMAKE_SOURCE_DIR}/components/ihm --target all
|
||||
# COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_SOURCE_DIR}/components/ihm ./ihm_simulator
|
||||
#)
|
||||
else()
|
||||
message(STATUS "Compilation standard")
|
||||
#add_link_options("-Wl,--disable-non-contiguous-regions")
|
||||
add_compile_options(
|
||||
-fsanitize=address
|
||||
-fno-omit-frame-pointer
|
||||
-O0
|
||||
-g
|
||||
)
|
||||
|
||||
add_link_options(-fsanitize=address)
|
||||
endif()
|
||||
|
||||
15
FreeRTOSConfig/FreeRTOSConfig.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configCPU_CLOCK_HZ ( ( unsigned long ) 80000000 )
|
||||
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
|
||||
#define configMAX_PRIORITIES 5
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 130 )
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 64 * 1024 ) )
|
||||
#define configMAX_TASK_NAME_LEN 10
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
||||
7
Kconfig.projbuild
Normal file
@ -0,0 +1,7 @@
|
||||
menu "Simulation options"
|
||||
|
||||
config SIMULATION_QEMU
|
||||
bool "Build with QEMU simulation stubs"
|
||||
default n
|
||||
|
||||
endmenu
|
||||
@ -1,3 +1,7 @@
|
||||
docker run -v $PWD:/app -w /app lvfontconv lv_font_conv --bpp 4 --size 24 --no-compress --font Montserrat-Medium.ttf --symbols "0123456789.°èéêûCABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz :-%," --format lvgl -o montserrat_medium_24.c --font fa-solid-900.ttf --range 61461,0xf0c2,0xf575
|
||||
docker run -v $PWD:/app -w /app lvfontconv lv_font_conv --bpp 4 --size 18 --no-compress --font Montserrat-Medium.ttf --symbols "0123456789.°èéêûCABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz :-%," --format lvgl -o montserrat_medium_18.c --font fa-solid-900.ttf --range 61461,0xf0c2,0xf575
|
||||
docker run -v $PWD:/app -w /app lvfontconv lv_font_conv --bpp 4 --size 12 --no-compress --font Montserrat-Medium.ttf --symbols "0123456789.°èéêûCABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz :-%," --format lvgl -o montserrat_medium_12.c --font fa-solid-900.ttf --range 61461,0xf0c2,0xf575
|
||||
|
||||
Pour lancer avec qemu:
|
||||
idf.py qemu --graphics --qemu-extra-args "-m 8M -global driver=ssi_psram,property=is_octal,value=true" monitor
|
||||
|
||||
|
||||
8647
compile_commands.json
Normal file
5
components/RemindMe/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
idf_component_register(SRCS "RemindMe.c"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES json spiffs)
|
||||
216
components/RemindMe/RemindMe.c
Normal file
@ -0,0 +1,216 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "esp_log.h"
|
||||
#include "cJSON.h"
|
||||
#include "esp_spiffs.h"
|
||||
#include "RemindMe.h"
|
||||
#include <time.h>
|
||||
|
||||
static const char *TAG = "JSON_READER";
|
||||
|
||||
static void copy_json_string(cJSON *item,
|
||||
const char *key,
|
||||
char *dst,
|
||||
size_t dst_size)
|
||||
{
|
||||
cJSON *v = cJSON_GetObjectItem(item, key);
|
||||
if (cJSON_IsString(v) && v->valuestring)
|
||||
{
|
||||
strncpy(dst, v->valuestring, dst_size - 1);
|
||||
dst[dst_size - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
static RemindMeEvent *get_events_from_file(const char *filepath, int *count)
|
||||
{
|
||||
*count = 0;
|
||||
|
||||
FILE *f = fopen(filepath, "r");
|
||||
if (!f)
|
||||
{
|
||||
ESP_LOGE(TAG, "Impossible d'ouvrir le fichier");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
long size = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
char *json_string = malloc(size + 1);
|
||||
if (!json_string)
|
||||
{
|
||||
fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fread(json_string, 1, size, f);
|
||||
fclose(f);
|
||||
json_string[size] = 0;
|
||||
|
||||
cJSON *json = cJSON_Parse(json_string);
|
||||
free(json_string);
|
||||
|
||||
if (!cJSON_IsArray(json))
|
||||
{
|
||||
cJSON_Delete(json);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int n = cJSON_GetArraySize(json);
|
||||
if (n == 0)
|
||||
{
|
||||
cJSON_Delete(json);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RemindMeEvent *events = calloc(n, sizeof(RemindMeEvent));
|
||||
if (!events)
|
||||
{
|
||||
cJSON_Delete(json);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
cJSON *item = cJSON_GetArrayItem(json, i);
|
||||
copy_json_string(item, "evenement", events[i].evenement, sizeof(events[i].evenement));
|
||||
copy_json_string(item, "affichage", events[i].affichage, sizeof(events[i].affichage));
|
||||
copy_json_string(item, "date", events[i].date, sizeof(events[i].date));
|
||||
copy_json_string(item, "type", events[i].type, sizeof(events[i].type));
|
||||
}
|
||||
|
||||
cJSON_Delete(json);
|
||||
*count = n;
|
||||
return events;
|
||||
}
|
||||
|
||||
static void read_json_file(const char *filepath, cJSON **root)
|
||||
{
|
||||
|
||||
FILE *f = fopen(filepath, "r");
|
||||
if (!f)
|
||||
{
|
||||
ESP_LOGE(TAG, "Impossible d'ouvrir le fichier");
|
||||
return;
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
long size = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
char *json_string = malloc(size + 1);
|
||||
if (!json_string)
|
||||
{
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
|
||||
fread(json_string, 1, size, f);
|
||||
fclose(f);
|
||||
json_string[size] = 0;
|
||||
|
||||
*root = cJSON_Parse(json_string);
|
||||
free(json_string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse une date au format "YYYY-MM-DD" et retourne le timestamp
|
||||
*/
|
||||
time_t parse_date(const char *date_str)
|
||||
{
|
||||
struct tm tm = {0};
|
||||
|
||||
// Parser la date (format: YYYY-MM-DD)
|
||||
sscanf(date_str, "%d-%d-%d",
|
||||
&tm.tm_year, &tm.tm_mon, &tm.tm_mday);
|
||||
|
||||
tm.tm_year -= 1900; // Années depuis 1900
|
||||
tm.tm_mon -= 1; // Mois de 0 à 11
|
||||
tm.tm_hour = 0;
|
||||
tm.tm_min = 0;
|
||||
tm.tm_sec = 0;
|
||||
|
||||
return mktime(&tm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calcule le nombre de jours entre maintenant et la date donnée
|
||||
* Retourne un nombre négatif si la date est passée
|
||||
*/
|
||||
int days_until(const char *date_str)
|
||||
{
|
||||
// Obtenir l'heure actuelle
|
||||
time_t now;
|
||||
time(&now);
|
||||
|
||||
// Parser la date cible
|
||||
time_t target = parse_date(date_str);
|
||||
|
||||
// Calculer la différence en secondes
|
||||
double diff_seconds = difftime(target, now);
|
||||
|
||||
// Convertir en jours (arrondi)
|
||||
int days = (int)(diff_seconds / (60 * 60 * 24));
|
||||
|
||||
return days;
|
||||
}
|
||||
|
||||
RemindMeEvent *get_events(int *count)
|
||||
{
|
||||
RemindMeEvent *evts = get_events_from_file(
|
||||
"/spiffs/events.json",
|
||||
count);
|
||||
for (size_t i = 0; i < *count; i++)
|
||||
{
|
||||
sprintf(evts[i].affichage, evts[i].affichage, days_until(evts[i].date));
|
||||
}
|
||||
return evts;
|
||||
|
||||
}
|
||||
esp_err_t events_save_atomic(char *eventsJson)
|
||||
{
|
||||
FILE *f = fopen("/spiffs/events.tmp", "w");
|
||||
if (!f)
|
||||
goto error;
|
||||
|
||||
fwrite(eventsJson, 1, strlen(eventsJson), f);
|
||||
fclose(f);
|
||||
|
||||
rename("/spiffs/events.json", "/spiffs/events.bak");
|
||||
rename("/spiffs/events.tmp", "/spiffs/events.json");
|
||||
//unlink("/spiffs/events.bak");
|
||||
|
||||
free(eventsJson);
|
||||
return ESP_OK;
|
||||
|
||||
error:
|
||||
free(eventsJson);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
void add_event(RemindMeEvent e){
|
||||
int count=0;
|
||||
cJSON *root = cJSON_CreateObject();
|
||||
read_json_file("/spiffs/events.json", &root);
|
||||
printf("%s","####################### AVANT\n");
|
||||
//printf("%s\n",cJSON_Print(root));
|
||||
if (!cJSON_IsArray(root))
|
||||
{
|
||||
ESP_LOGE(TAG, "'root' n'est pas un tableau");
|
||||
return;
|
||||
}else{
|
||||
cJSON *new_event = cJSON_CreateObject();
|
||||
if (!new_event)
|
||||
return;
|
||||
|
||||
cJSON_AddStringToObject(new_event, "evenement", e.evenement);
|
||||
cJSON_AddStringToObject(new_event, "affichage", e.affichage);
|
||||
cJSON_AddStringToObject(new_event, "date", e.date);
|
||||
cJSON_AddStringToObject(new_event, "type", e.type);
|
||||
cJSON_AddItemToArray(root, new_event);
|
||||
}
|
||||
printf("%s", "####################### APRES\n");
|
||||
//printf("%s\n", cJSON_Print(root));
|
||||
char *eventsJson=cJSON_Print(root);
|
||||
events_save_atomic(eventsJson);
|
||||
}
|
||||
6
components/RemindMe/idf_component.yml
Normal file
@ -0,0 +1,6 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
## Required IDF version
|
||||
idf:
|
||||
version: '>=4.1.0'
|
||||
|
||||
19
components/RemindMe/include/RemindMe.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
typedef struct
|
||||
{
|
||||
char evenement[64];
|
||||
char affichage[128];
|
||||
char date[32];
|
||||
char type[40];
|
||||
} RemindMeEvent;
|
||||
|
||||
/**
|
||||
* Charge les événements depuis le fichier JSON
|
||||
* @param count (out) nombre d'événements chargés
|
||||
* @return pointeur vers tableau d'événements ou NULL en cas d'erreur
|
||||
*
|
||||
* ⚠️ L'appelant doit libérer la mémoire avec free()
|
||||
*/
|
||||
RemindMeEvent *get_events(int *count);
|
||||
|
||||
void add_event();
|
||||
12
components/RemindMe/test/CMakeLists.txt
Normal file
@ -0,0 +1,12 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
||||
set(COMPONENTS main)
|
||||
|
||||
list(APPEND EXTRA_COMPONENT_DIRS
|
||||
../../RemindMe
|
||||
)
|
||||
|
||||
|
||||
|
||||
project(remindme_host_test)
|
||||
10
components/RemindMe/test/dependencies.lock
Normal file
@ -0,0 +1,10 @@
|
||||
dependencies:
|
||||
idf:
|
||||
source:
|
||||
type: idf
|
||||
version: 5.5.1
|
||||
direct_dependencies:
|
||||
- idf
|
||||
manifest_hash: 2fc18f414627b3fc737adcef5ecbfa3a4f7cff55fd5f96a20734c8d5302b79ed
|
||||
target: linux
|
||||
version: 2.0.0
|
||||
4
components/RemindMe/test/main/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
idf_component_register(
|
||||
SRCS "main.c"
|
||||
REQUIRES RemindMe
|
||||
)
|
||||
28
components/RemindMe/test/main/main.c
Normal file
@ -0,0 +1,28 @@
|
||||
#include "RemindMe.h"
|
||||
#include "esp_log.h"
|
||||
int app_main(int argc, char *argv[])
|
||||
{
|
||||
int count=0;
|
||||
|
||||
RemindMeEvent *events= get_events(&count);
|
||||
if (!events)
|
||||
{
|
||||
ESP_LOGE("test", "Aucun événement chargé");
|
||||
return 0;
|
||||
} // Parcourir tous les événements
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
ESP_LOGI("test", "%s", events[i].affichage);
|
||||
}
|
||||
|
||||
RemindMeEvent e = {
|
||||
.affichage = "Test dans %d jours",
|
||||
.date="2026-12-31",
|
||||
.type="remaining_days",
|
||||
.evenement="test"
|
||||
|
||||
};
|
||||
add_event(e);
|
||||
|
||||
return 0;
|
||||
}
|
||||
9
components/RemindMe/test/test_RemindMe.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include "unity.h"
|
||||
#include "RemindMe.h"
|
||||
|
||||
TEST_CASE("Test lecture JSON", "[RemindMe]")
|
||||
{
|
||||
Event event = {0};
|
||||
esp_err_t ret = read_json_file("/spiffs/test.json", &event);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, ret);
|
||||
}
|
||||
37
components/domotic_display/.vscode/c_cpp_properties.json
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "ESP-IDF",
|
||||
"compilerPath": "${config:idf.toolsPath}/tools/xtensa-esp-elf/esp-14.2.0_20241119/xtensa-esp-elf/bin/xtensa-esp32-elf-gcc",
|
||||
"compileCommands": [
|
||||
"${config:idf.buildPath}/compile_commands.json"
|
||||
],
|
||||
"includePath": [
|
||||
"${config:idf.espIdfPath}/components/**",
|
||||
"${config:idf.espIdfPathWin}/components/**",
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": ["LV_CONF_SKIP"],
|
||||
"browse": {
|
||||
"path": [
|
||||
"${config:idf.espIdfPath}/components",
|
||||
"${config:idf.espIdfPathWin}/components",
|
||||
"${workspaceFolder}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "linux-host",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": ["LV_CONF_SKIP"],
|
||||
"compilerPath": "/usr/bin/gcc",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "gnu++17",
|
||||
"intelliSenseMode": "linux-gcc-x64"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
20
components/domotic_display/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"name": "Eclipse CDT GDB Adapter",
|
||||
"program": "${workspaceFolder}/test_host/build/nvs_host_test.elf",
|
||||
"cwd": "${workspaceFolder}/test_host",
|
||||
"linux": {
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
}
|
||||
],
|
||||
|
||||
}
|
||||
9
components/domotic_display/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"idf.pythonInstallPath": "/usr/bin/python3",
|
||||
"files.associations": {
|
||||
"model.h": "c",
|
||||
"lvgl.h": "c",
|
||||
"lv_init.h": "c",
|
||||
"lv_conf_internal.h": "c"
|
||||
}
|
||||
}
|
||||
50
components/domotic_display/CMakeLists.txt
Normal file
@ -0,0 +1,50 @@
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/fonts_symbols.cmake)
|
||||
|
||||
string(JOIN "," LVGL_SYMBOLS ${LVGL_SYMBOLS_CLASSIQUES})
|
||||
message(STATUS "LVGL SYMBOL RANGE = ${LVGL_SYMBOLS}")
|
||||
|
||||
function (make_font fontName fileName fontSize)
|
||||
execute_process(COMMAND podman run -v ${PROJECT_DIR}/components/domotic_display/fonts:/app -w /app lvfontconv lv_font_conv --bpp 4 --size ${fontSize} --no-compress --font ${fontName}.ttf --symbols "0123456789.°àéèêëûCABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz %,'!? ():/-" --format lvgl -o ${fileName}_${fontSize}.c --font fa-solid-900.ttf --range ${LVGL_SYMBOLS})
|
||||
endfunction()
|
||||
|
||||
make_font(Montserrat-Medium montserrat_medium 12 )
|
||||
make_font(Montserrat-Medium montserrat_medium 18)
|
||||
make_font(Montserrat-Medium montserrat_medium 24)
|
||||
make_font(Roboto-Medium roboto_medium 36)
|
||||
make_font(Roboto-Medium roboto_medium 72)
|
||||
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 36 --no-compress --font Roboto-Medium.ttf --symbols "0123456789.°àéèûCABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz %,'():ê/-" --format lvgl -o roboto_medium_36.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)
|
||||
if(${IDF_TARGET} STREQUAL "esp32p4" OR ${IDF_TARGET} STREQUAL "esp32s3")
|
||||
#esp32_p4_function_ev_board
|
||||
idf_component_register(SRC_DIRS . fonts
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES ${comps} esp_lvgl_port esp32_p4_function_ev_board )
|
||||
target_compile_options(${COMPONENT_LIB} PUBLIC -DLV_LVGL_H_INCLUDE_SIMPLE)
|
||||
|
||||
lvgl_port_create_c_image("images/wifi_ok.png" "images/" "ARGB8888" "NONE")
|
||||
lvgl_port_create_c_image("images/wifi_ko.png" "images/" "ARGB8888" "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_add_images(${COMPONENT_LIB} "images/")
|
||||
#littlefs_create_partition_image(littlefs images_meteo FLASH_IN_PROJECT)
|
||||
elseif(${IDF_TARGET} STREQUAL "linux")
|
||||
idf_component_register(SRC_DIRS . fonts images
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES ${comps})
|
||||
message("Including SDL2 support")
|
||||
find_package(SDL2 REQUIRED)
|
||||
target_link_libraries(${COMPONENT_LIB} PUBLIC
|
||||
-Wl,--no-as-needed
|
||||
SDL2
|
||||
-Wl,--as-needed
|
||||
)
|
||||
|
||||
target_compile_options(${COMPONENT_LIB} PUBLIC -DLV_LVGL_H_INCLUDE_SIMPLE)
|
||||
endif()
|
||||
|
||||
7
components/domotic_display/domotic_display.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include "domotic_display.h"
|
||||
|
||||
void func(void)
|
||||
{
|
||||
|
||||
}
|
||||
BIN
components/domotic_display/fonts/Roboto-Medium.ttf
Normal file
BIN
components/domotic_display/fonts/Super_Malibu.ttf
Normal file
BIN
components/domotic_display/fonts/Vlump.ttf
Normal file
1536
components/domotic_display/fonts/montserrat_medium_12.c
Normal file
2236
components/domotic_display/fonts/montserrat_medium_18.c
Normal file
3140
components/domotic_display/fonts/montserrat_medium_24.c
Normal file
5343
components/domotic_display/fonts/roboto_medium_36.c
Normal file
19194
components/domotic_display/fonts/roboto_medium_72.c
Normal file
26814
components/domotic_display/fonts/super_malibu_80.c
Normal file
22874
components/domotic_display/fonts/super_malibu_96.c
Normal file
60223
components/domotic_display/fonts/vlump_96.c
Normal file
110
components/domotic_display/fonts_symbols.cmake
Normal file
@ -0,0 +1,110 @@
|
||||
# Symboles perso
|
||||
# --- Weather ---
|
||||
set(MY_SYMBOL_CLOUD 0xf0c2) # cloud | UTF-8: "\xEF\x83\x82"
|
||||
set(MY_SYMBOL_CLOUD_SUN 0xf575) # cloud-sun | UTF-8: "\xEF\x95\xB5"
|
||||
|
||||
# --- Navigation ---
|
||||
set(MY_SYMBOL_UP 0xf077) # chevron-up | UTF-8: "\xEF\x81\xB7"
|
||||
set(MY_SYMBOL_DOWN 0xf078) # chevron-down | UTF-8: "\xEF\x81\xB8"
|
||||
|
||||
# --- Sensors ---
|
||||
set(MY_SYMBOL_THERMOMETER 0xf2ca) # thermometer | UTF-8: "\xEF\x89\xBA"
|
||||
set(MY_SYMBOL_MESSAGE 0xf27a) # message | UTF-8: "\xEF\x89\xBA"
|
||||
|
||||
# --- Location / House ---
|
||||
set(MY_THERMOMETER_IN_HOUSE 0xe1b0) # house-user | UTF-8: "\xEE\x86\xB0"
|
||||
set(MY_THERMOMETER_OUT_HOUSE 0xe1b0) # house-user | UTF-8: "\xEE\x86\xB0"
|
||||
|
||||
|
||||
# ======================================
|
||||
# LVGL symbols (FontAwesome solid mapped)
|
||||
# ======================================
|
||||
|
||||
# --- Base UI ---
|
||||
set(LV_SYMBOL_OK 0xf00c) # check
|
||||
set(LV_SYMBOL_CLOSE 0xf00d) # times
|
||||
set(LV_SYMBOL_POWER 0xf011) # power-off
|
||||
set(LV_SYMBOL_SETTINGS 0xf013) # gear
|
||||
set(LV_SYMBOL_HOME 0xf015) # home
|
||||
set(LV_SYMBOL_DOWNLOAD 0xf019) # download
|
||||
set(LV_SYMBOL_REFRESH 0xf021) # refresh
|
||||
set(LV_SYMBOL_LOCK 0xf023) # lock
|
||||
set(LV_SYMBOL_WIFI 0xf1eb) # wifi
|
||||
set(LV_SYMBOL_BELL 0xf0f3) # bell
|
||||
set(LV_SYMBOL_BATTERY_FULL 0xf240) # battery-full
|
||||
set(LV_SYMBOL_BATTERY_3 0xf241) # battery-3/4
|
||||
set(LV_SYMBOL_BATTERY_2 0xf242) # battery-1/2
|
||||
set(LV_SYMBOL_BATTERY_1 0xf243) # battery-1/4
|
||||
set(LV_SYMBOL_BATTERY_EMPTY 0xf244) # battery-empty
|
||||
|
||||
# --- Navigation ---
|
||||
set(LV_SYMBOL_LEFT 0xf060) # arrow-left
|
||||
set(LV_SYMBOL_RIGHT 0xf061) # arrow-right
|
||||
set(LV_SYMBOL_UP 0xf062) # arrow-up
|
||||
set(LV_SYMBOL_DOWN 0xf063) # arrow-down
|
||||
set(LV_SYMBOL_NEXT 0xf061) # alias RIGHT
|
||||
set(LV_SYMBOL_PREV 0xf060) # alias LEFT
|
||||
|
||||
# --- Media / Actions ---
|
||||
set(LV_SYMBOL_PLAY 0xf04b) # play
|
||||
set(LV_SYMBOL_PAUSE 0xf04c) # pause
|
||||
set(LV_SYMBOL_STOP 0xf04d) # stop
|
||||
set(LV_SYMBOL_EJECT 0xf052) # eject
|
||||
set(LV_SYMBOL_VOLUME_UP 0xf028)
|
||||
set(LV_SYMBOL_VOLUME_DOWN 0xf027)
|
||||
set(LV_SYMBOL_MUTE 0xf026)
|
||||
|
||||
# --- Information ---
|
||||
set(LV_SYMBOL_EYE_OPEN 0xf06e)
|
||||
set(LV_SYMBOL_EYE_CLOSE 0xf070)
|
||||
set(LV_SYMBOL_WARNING 0xf071)
|
||||
set(LV_SYMBOL_INFO 0xf05a)
|
||||
set(LV_SYMBOL_QUESTION 0xf128)
|
||||
|
||||
# --- Time / Status ---
|
||||
set(LV_SYMBOL_CLOCK 0xf017)
|
||||
set(LV_SYMBOL_CALENDAR 0xf073)
|
||||
|
||||
# --- List of symbols used for font generation ---
|
||||
set(LVGL_SYMBOLS_CLASSIQUES
|
||||
${LV_SYMBOL_OK}
|
||||
${LV_SYMBOL_CLOSE}
|
||||
${LV_SYMBOL_POWER}
|
||||
${LV_SYMBOL_SETTINGS}
|
||||
${LV_SYMBOL_HOME}
|
||||
${LV_SYMBOL_DOWNLOAD}
|
||||
${LV_SYMBOL_REFRESH}
|
||||
${LV_SYMBOL_LOCK}
|
||||
${LV_SYMBOL_WIFI}
|
||||
${LV_SYMBOL_BELL}
|
||||
${LV_SYMBOL_BATTERY_FULL}
|
||||
${LV_SYMBOL_BATTERY_3}
|
||||
${LV_SYMBOL_BATTERY_2}
|
||||
${LV_SYMBOL_BATTERY_1}
|
||||
${LV_SYMBOL_BATTERY_EMPTY}
|
||||
${LV_SYMBOL_LEFT}
|
||||
${LV_SYMBOL_RIGHT}
|
||||
${LV_SYMBOL_UP}
|
||||
${LV_SYMBOL_DOWN}
|
||||
${LV_SYMBOL_PLAY}
|
||||
${LV_SYMBOL_PAUSE}
|
||||
${LV_SYMBOL_STOP}
|
||||
${LV_SYMBOL_VOLUME_UP}
|
||||
${LV_SYMBOL_VOLUME_DOWN}
|
||||
${LV_SYMBOL_MUTE}
|
||||
${LV_SYMBOL_EYE_OPEN}
|
||||
${LV_SYMBOL_EYE_CLOSE}
|
||||
${LV_SYMBOL_WARNING}
|
||||
${LV_SYMBOL_INFO}
|
||||
${LV_SYMBOL_QUESTION}
|
||||
${LV_SYMBOL_CLOCK}
|
||||
${LV_SYMBOL_CALENDAR}
|
||||
|
||||
${MY_SYMBOL_CLOUD}
|
||||
${MY_SYMBOL_CLOUD_SUN}
|
||||
${MY_SYMBOL_UP}
|
||||
${MY_SYMBOL_DOWN}
|
||||
${MY_SYMBOL_THERMOMETER}
|
||||
${MY_SYMBOL_MESSAGE}
|
||||
${MY_THERMOMETER_IN_HOUSE}
|
||||
)
|
||||
28
components/domotic_display/idf_component.yml
Normal file
@ -0,0 +1,28 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
## Required IDF version
|
||||
idf:
|
||||
version: '>=4.1.0'
|
||||
# # Put list of dependencies here
|
||||
# # For components maintained by Espressif:
|
||||
# component: "~1.0.0"
|
||||
# # For 3rd party components:
|
||||
# username/component: ">=1.0.0,<2.0.0"
|
||||
# username2/component2:
|
||||
# version: "~1.0.0"
|
||||
# # For transient dependencies `public` flag can be set.
|
||||
# # `public` flag doesn't have an effect dependencies of the `main` component.
|
||||
# # All dependencies of `main` are public by default.
|
||||
# public: true
|
||||
espressif/esp_lvgl_port:
|
||||
rules:
|
||||
- if: target in ["esp32p4","esp32, "esp32s3"]
|
||||
version: ^2.7.0
|
||||
lvgl/lvgl:
|
||||
rules:
|
||||
- if: target in ["linux"]
|
||||
version: 9.4.0
|
||||
espressif/esp_lcd_qemu_rgb:
|
||||
rules:
|
||||
- if: target in ["esp32, "esp32s3"]
|
||||
version: ^1
|
||||
1858
components/domotic_display/ihm.c
Normal file
124
components/domotic_display/ihm_gateway.c
Normal file
@ -0,0 +1,124 @@
|
||||
// ihm_gateway.c
|
||||
#include "ihm_gateway.h"
|
||||
#include "ihm.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "platform_detect.h"
|
||||
#include "cJSON.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *TAG = "IHM_GW";
|
||||
|
||||
|
||||
static QueueHandle_t xIHMEventQueue = NULL;
|
||||
|
||||
QueueHandle_t getIHMQueueHandle(void) {
|
||||
return xIHMEventQueue;
|
||||
}
|
||||
|
||||
void ihm_gateway_init(void) {
|
||||
if (!xIHMEventQueue) {
|
||||
xIHMEventQueue = xQueueCreate(32, sizeof(xIHMEvent_t *));
|
||||
}
|
||||
}
|
||||
|
||||
void ihm_gateway_post_event(xIHMEvent_t *evt) {
|
||||
if (!xIHMEventQueue) return;
|
||||
|
||||
if (platform_is_pc()) {
|
||||
xQueueSend(xIHMEventQueue, &evt, 0); // non bloquant sur PC
|
||||
} else {
|
||||
xQueueSend(xIHMEventQueue, &evt, portMAX_DELAY); // bloquant ESP32
|
||||
}
|
||||
}
|
||||
|
||||
extern lv_subject_t wifiStatus;
|
||||
|
||||
void ihm_gateway_process_queue(void) {
|
||||
if (!xIHMEventQueue) return;
|
||||
|
||||
xIHMEvent_t *evt = NULL;
|
||||
|
||||
#if CONFIG_IDF_TARGET_LINUX
|
||||
while (xQueueReceive(xIHMEventQueue, &evt, pdMS_TO_TICKS(0)) == pdTRUE)
|
||||
#else
|
||||
while (xQueueReceive(xIHMEventQueue, &evt, pdMS_TO_TICKS(10)) == pdTRUE)
|
||||
#endif
|
||||
{
|
||||
if (!evt) return;
|
||||
|
||||
UBaseType_t pending = uxQueueMessagesWaiting(xIHMEventQueue);
|
||||
ESP_LOGE(TAG,"Evt recu %d. La queue comporte %d éléments à traiter", evt->eEventType, pending);
|
||||
|
||||
lv_async_call(traiteEvt, evt);
|
||||
}
|
||||
}
|
||||
|
||||
void traiteEvt(void *arg)
|
||||
{
|
||||
xIHMEvent_t *evt = (xIHMEvent_t *)arg;
|
||||
switch (evt->eEventType)
|
||||
{
|
||||
case IHM_EVT_WIFI_STATUS:
|
||||
lv_subject_set_int(&wifiStatus, *(bool *)evt->pvData);
|
||||
break;
|
||||
|
||||
case IHM_EVT_TIME_SETTED:
|
||||
draw_time(evt->pvData);
|
||||
break;
|
||||
|
||||
case IHM_EVT_OTA_STARTED:
|
||||
app_ota_display();
|
||||
break;
|
||||
|
||||
case IHM_EVT_HUMID_TEMP:
|
||||
draw_temp((char *)evt->pvData);
|
||||
break;
|
||||
|
||||
case IHM_EVT_PUISSANCE_EMISE:
|
||||
{
|
||||
int val = *(int *)evt->pvData;
|
||||
// if(val == 0) lv_chart_set_next_value(myChart, ser, LV_CHART_POINT_NONE);
|
||||
// else lv_chart_set_next_value(myChart, ser, val);
|
||||
break;
|
||||
}
|
||||
|
||||
case IHM_EVT_ETAT_MACHINE:
|
||||
{
|
||||
char *etatMachine = evt->pvData;
|
||||
cJSON *root = cJSON_Parse(etatMachine);
|
||||
bool enRoute = cJSON_GetObjectItem(root, "state")->valueint;
|
||||
int timestamp = cJSON_GetObjectItem(root, "timestamp")->valueint;
|
||||
|
||||
time_t rawtime = (time_t)timestamp;
|
||||
struct tm *heure_locale = localtime(&rawtime);
|
||||
char heureFormattee[50];
|
||||
strftime(heureFormattee, sizeof(heureFormattee), "%d/%m/%Y %H:%M:%S", heure_locale);
|
||||
|
||||
char etatFormate[90];
|
||||
snprintf(etatFormate, sizeof(etatFormate),
|
||||
enRoute ? "Machine en route depuis %s" : "Machine : Arrêt détecté depuis %s",
|
||||
heureFormattee);
|
||||
|
||||
// lv_label_set_text(lblEtatMachine, etatFormate);
|
||||
cJSON_Delete(root);
|
||||
break;
|
||||
}
|
||||
|
||||
case IHM_EVT_HAUTEUR_CUVE:
|
||||
{
|
||||
float hauteur = *(float *)evt->pvData;
|
||||
// lv_label_set_text_fmt(lblHauteurCuve, "%.0f cm", hauteur);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ESP_LOGE(TAG, "Evt inconnu");
|
||||
break;
|
||||
}
|
||||
// Nettoyage mémoire sécurisé
|
||||
if (evt->bNeedToFreeData && evt->pvData)
|
||||
free(evt->pvData);
|
||||
free(evt);
|
||||
ESP_LOGV(TAG, "Evt traité");
|
||||
}
|
||||
|
Before Width: | Height: | Size: 654 B After Width: | Height: | Size: 654 B |
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 483 B After Width: | Height: | Size: 483 B |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 372 B After Width: | Height: | Size: 372 B |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |