Merge commit '56b28be7581052c9cf7ab0dbc67a2467ad603a2c'
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/
|
build/
|
||||||
managed_components/
|
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": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "ESP-IDF",
|
"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/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/**",
|
||||||
|
|||||||
131
.vscode/launch.json
vendored
@ -16,7 +16,7 @@
|
|||||||
"name": "Debug LVGL demo with gdb",
|
"name": "Debug LVGL demo with gdb",
|
||||||
"type": "cppdbg",
|
"type": "cppdbg",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceFolder}/bin/rgb_lcd",
|
"program": "${workspaceFolder}/build/rgb_lcd",
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
@ -32,6 +32,133 @@
|
|||||||
"miDebuggerPath": "C:\\MinGw\\bin\\gdb.exe"
|
"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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
18
.vscode/settings.json
vendored
@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"C_Cpp.intelliSenseEngine": "default",
|
"C_Cpp.intelliSenseEngine": "default",
|
||||||
"idf.espIdfPath": "/home/marc/esp/master/esp-idf",
|
"idf.espIdfPath": "/home/marc/esp/esp-idf",
|
||||||
"idf.pythonBinPath": "/home/marc/.espressif/python_env/idf5.3_py3.10_env/bin/python",
|
"idf.pythonBinPath": "/home/marc/.espressif/tools/python/v5.5.2/venv/bin/python3",
|
||||||
"idf.toolsPath": "/home/marc/.espressif",
|
"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.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": {
|
"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/",
|
"ESP_ROM_ELF_DIR": "/home/marc/.espressif/tools/esp-rom-elfs/20240305/",
|
||||||
"IDF_TARGET": "esp32p4"
|
"IDF_TARGET": "esp32p4"
|
||||||
},
|
},
|
||||||
@ -105,7 +105,15 @@
|
|||||||
"bsp_board_extra.h": "c",
|
"bsp_board_extra.h": "c",
|
||||||
"display.h": "c",
|
"display.h": "c",
|
||||||
"statemanagement.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
|
"isDefault": true
|
||||||
},
|
},
|
||||||
"dependsOn": "Build"
|
"dependsOn": "Build"
|
||||||
}
|
},
|
||||||
{
|
{
|
||||||
"label": "Build - Build project",
|
"label": "Build - Build project",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
@ -73,6 +73,47 @@
|
|||||||
"isDefault": true
|
"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",
|
"label": "Set ESP-IDF Target",
|
||||||
"type": "shell",
|
"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)
|
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)
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
project(rgb_lcd)
|
||||||
|
|
||||||
if(${IDF_TARGET} STREQUAL "esp32p4")
|
|
||||||
set(EXTRA_COMPONENT_DIRS
|
# -------------------------------------------------
|
||||||
/home/marc/esp-dev-kits/examples/esp32-p4-function-ev-board/examples/common_components
|
# APRÈS project() : maintenant CONFIG_SIMULATION_QEMU existe
|
||||||
$ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs
|
# -------------------------------------------------
|
||||||
)
|
|
||||||
|
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()
|
else()
|
||||||
# PROJECT_PLATFORM_LINUX
|
message(STATUS "Compilation standard")
|
||||||
# PROJECT_PLATFORM_ESP32
|
#add_link_options("-Wl,--disable-non-contiguous-regions")
|
||||||
add_compile_definitions(PROJECT_PLATFORM_LINUX)
|
add_compile_options(
|
||||||
|
-fsanitize=address
|
||||||
set(EXTRA_COMPONENT_DIRS
|
-fno-omit-frame-pointer
|
||||||
$ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs
|
-O0
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/FreeRTOS
|
-g
|
||||||
"/home/marc/esp-protocols/common_components/linux_compat"
|
|
||||||
"/home/marc/esp-protocols/components/mdns/tests/host_test/components"
|
|
||||||
)
|
)
|
||||||
endif()
|
|
||||||
|
|
||||||
project(rgb_lcd)
|
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 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 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
|
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 |