work on pc from main !

This commit is contained in:
Marc Pasteur 2026-02-06 18:39:36 +01:00
parent 93bffe925f
commit ba266479dd
36 changed files with 1442 additions and 138 deletions

54
.vscode/launch.json vendored
View File

@ -60,6 +60,60 @@
"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",

View File

@ -1,7 +1,7 @@
{
"C_Cpp.intelliSenseEngine": "default",
"idf.espIdfPath": "/home/marc/esp/esp-idf",
"idf.pythonBinPath": "/home/marc/.espressif/python_env/idf5.5_py3.10_env/bin/python",
"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": {

View File

@ -5,6 +5,8 @@ message(STATUS "ROOT:: SIMULATION_QEMU = ${SIMULATION_QEMU}")
# CONFIGURATION AVANT project() : uniquement CMake pur
# -------------------------------------------------
if(SIMULATION_QEMU)
message(STATUS "SIMULATION_QEMU = ON")
option(SIMULATION_QEMU "Build for QEMU simulation" ON)
@ -19,12 +21,20 @@ if(SIMULATION_QEMU)
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")
# 🚨 Rien d'autre avant ces deux lignes !
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(rgb_lcd)
# -------------------------------------------------
# APRÈS project() : maintenant CONFIG_SIMULATION_QEMU existe
# -------------------------------------------------
@ -40,5 +50,5 @@ if(CONFIG_SIMULATION_QEMU)
#)
else()
message(STATUS "Compilation standard")
add_link_options("-Wl,--disable-non-contiguous-regions")
add_link_options("-Wl,--disable-non-contiguous-regions -lSDL2")
endif()

View File

@ -19,12 +19,12 @@ make_font(Super_Malibu super_malibu 80)
#execute_process(COMMAND podman run -v /home/marc/rgb_lcd/components/domotic_display/fonts:/app -w /app lvfontconv lv_font_conv --bpp 4 --size 72 --no-compress --font Roboto-Medium.ttf --symbols "0123456789.°àéèûCABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz %,'():ê/-" --format lvgl -o roboto_medium_72.c --font fa-solid-900.ttf --range 61461,0xf0c2,0xf575)
SET(comps meteofrance eventsManager lvgl RemindMe)
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 meteofrance eventsManager lvgl esp_lvgl_port)
REQUIRES ${comps} esp_lvgl_port)
target_compile_options(${COMPONENT_LIB} PUBLIC -DLV_LVGL_H_INCLUDE_SIMPLE)
lvgl_port_create_c_image("images/wifi_ok.png" "images/" "ARGB8888" "NONE")
@ -33,5 +33,10 @@ if(${IDF_TARGET} STREQUAL "esp32p4" OR ${IDF_TARGET} STREQUAL "esp32s3")
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})
target_compile_options(${COMPONENT_LIB} PUBLIC -DLV_LVGL_H_INCLUDE_SIMPLE)
endif()

View File

@ -18,5 +18,11 @@ dependencies:
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 ["esp32p4","esp32, "esp32s3"]
version: ^1

View File

@ -539,7 +539,7 @@ void showMeteoIcon(const char *icon, lv_obj_t *desc_icon, int childNr)
char *result = malloc(sizeOfStr);
snprintf(result,sizeOfStr, "%s%s.png", str1, icon);
ESP_LOGV(TAG,"On affiche l'image %s", result);
lv_image_set_src(img, "A:/home/marc/domotic/components/domotic_display/images_meteo/p4j.png");
lv_image_set_src(img, "A:/home/marc/esp/domotic/domotic/components/domotic_display/images_meteo/p4j.png");
free(result);
}

View File

@ -38,6 +38,4 @@ void draw_tabCuve(lv_obj_t * parent);
void draw_tabHome(lv_obj_t * parent);
void draw_tabSettings(lv_obj_t * parent);
void drawIhm(void *pvParameter);

View File

@ -3,7 +3,6 @@ cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(COMPONENTS main)
# This test app doesn't require FreeRTOS, using mock instead
list(APPEND EXTRA_COMPONENT_DIRS
# "$ENV{IDF_PATH}/tools/mocks/freertos/"
"$ENV{IDF_PATH}/tools/mocks/esp_timer"
@ -14,18 +13,18 @@ list(APPEND EXTRA_COMPONENT_DIRS
)
idf_build_set_property(COMPILE_DEFINITIONS "NO_DEBUG_STORAGE" APPEND)
project(nvs_host_test)
project(host_test)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/coverage_report/index.html"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMAND gcovr --root $ENV{IDF_PATH}/components/nvs_flash --html-details
--exclude ${CMAKE_CURRENT_SOURCE_DIR}/managed_components/*
-o ${CMAKE_CURRENT_BINARY_DIR}/coverage_report/index.html ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generate coverage report"
)
#add_custom_command(
# OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/coverage_report/index.html"
# WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
# COMMAND gcovr --root $ENV{IDF_PATH}/components/nvs_flash --html-details
# --exclude ${CMAKE_CURRENT_SOURCE_DIR}/managed_components/*
# -o ${CMAKE_CURRENT_BINARY_DIR}/coverage_report/index.html ${CMAKE_CURRENT_BINARY_DIR}
# COMMENT "Generate coverage report"
# )
add_custom_target(coverage
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
DEPENDS "coverage_report/index.html"
)
#add_custom_target(coverage
# WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
# DEPENDS "coverage_report/index.html"
# )

View File

@ -1,3 +1,11 @@
set(requires json esp_http_client esp-tls esp_timer)
idf_build_get_property(target IDF_TARGET)
if(${target} STREQUAL "linux")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/esp_timer" )
else()
list(APPEND requires esp_timer)
endif()
idf_component_register(SRCS "image_downloader.c"
INCLUDE_DIRS "include"
REQUIRES json esp_http_client esp-tls esp_timer )
REQUIRES ${requires} )

View File

@ -199,12 +199,12 @@ void imgdwn(void *domotic_event_group) {
if (source_buf == NULL) {
ESP_LOGE(TAG, "Initial alloc source_buf failed!");
}
printf("Free heap after buffers allocation: %"PRIu16"\n", xPortGetFreeHeapSize());
printf("Free heap after buffers allocation: %zu\n", xPortGetFreeHeapSize());
download();
heap_caps_free(source_buf);
printf("Free heap after buffers allocation: %"PRIu16"\n", xPortGetFreeHeapSize());
printf("Free heap after buffers allocation: %zu\n", xPortGetFreeHeapSize());
vTaskDelay(3600000 / portTICK_PERIOD_MS);
}else{

View File

@ -412,7 +412,7 @@ void initialise_weather_data_retrieval(unsigned long retreival_period, void* dom
// http_client_on_process_chunk(&http_client, process_chunk);
// http_client_on_disconnected(&http_client, disconnected);
TaskHandle_t xHandle = NULL;
BaseType_t ret1 = xTaskCreatePinnedToCore(&http_request_task, "http_meteof", 5 * 1024, domotic_event_group, 5, &xHandle, 1);
BaseType_t ret1 = xTaskCreatePinnedToCore(&http_request_task, "http_meteof", 5 * 1024, domotic_event_group, 5, &xHandle, 0);
if(ret1!=pdPASS ){
ESP_LOGE(TAG, "Impossible de creer la tache %"PRIi16, ret1);
}

View File

@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(COMPONENTS main)
# This test app doesn't require FreeRTOS, using mock instead
list(APPEND EXTRA_COMPONENT_DIRS
# "$ENV{IDF_PATH}/tools/mocks/freertos/"
"$ENV{IDF_PATH}/tools/mocks/esp_timer"
../../meteofrance
../../stateManagement
../../eventsManager
../../RemindMe
)
project(my_custom_app C)

View File

@ -0,0 +1,10 @@
dependencies:
idf:
source:
type: idf
version: 5.5.2
direct_dependencies:
- idf
manifest_hash: 2fc18f414627b3fc737adcef5ecbfa3a4f7cff55fd5f96a20734c8d5302b79ed
target: linux
version: 2.0.0

View File

@ -0,0 +1,13 @@
set(LV_BUILD_USE_KCONFIG ON)
idf_component_register(SRCS main.c ../../meteofrance.c
INCLUDE_DIRS
"../../include"
WHOLE_ARCHIVE
REQUIRES stateManagement freertos json esp_http_client esp-tls
EMBED_TXTFILES ../../../../main/ca_cert.pem
)
# Currently 'main' for IDF_TARGET=linux is defined in freertos component.
# Since we are using a freertos mock here, need to let Catch2 provide 'main'.
#target_link_libraries(${COMPONENT_LIB} PRIVATE Catch2WithMain)

View File

@ -0,0 +1,45 @@
#include <stddef.h>
#include "meteofrance.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_event.h"
#define BIT0 0x00000001
#define WIFI_CONNECTED_BIT BIT0
int main1(int argc, char const *argv[])
{
/* code */
return 0;
}
void weather_data_retreived_start()
{
//if (display_lock("weather_data_retreived_start"))
//{
//ESP_LOGE(TAG,"Mutex obtenu dans weather_data_retreived_start");
//lv_subject_set_int(&meteoStatus, 1);
ESP_LOGE("","Subject setted weather_data_retreived_start");
//display_unlock("weather_data_retreived_start");
//}else{
// ESP_LOGE(TAG,"Impossible d'obtenir le mutex dans weather_data_retreived_start");
//}
}
void weather_data_retreived(struct meteodailyforecast_data dailyDatas[3], struct meteoforecast_data datas[3])
{
}
EventGroupHandle_t domotic_event_group;
int app_main(int argc, char *argv[]) {
ESP_ERROR_CHECK(esp_event_loop_create_default());
domotic_event_group = xEventGroupCreate();
on_weather_data_retrieval_start(weather_data_retreived_start);
on_weather_data_retrieval(weather_data_retreived);
initialise_weather_data_retrieval(30000, domotic_event_group);
xEventGroupSetBits(domotic_event_group, WIFI_CONNECTED_BIT);
return 0;
}

View File

@ -0,0 +1,3 @@
{
"idf.pythonInstallPath": "/usr/bin/python3"
}

View File

@ -0,0 +1 @@
idf_component_register(SRC_DIRS main REQUIRES domotic_display)

View File

@ -0,0 +1,14 @@
[
{
"evenement": "Fête",
"affichage": "Noel est dans %d jour(s)",
"date": "2025-12-25",
"type": "remaining_days"
},
{
"evenement": "Ecole",
"affichage": "La rentrée est dans %d jour(s)",
"date": "2026-01-05",
"type": "remaining_days"
}
]

View File

@ -0,0 +1,5 @@
dependencies:
lvgl/lvgl:
version: 9.4.0
#espressif/esp32_p4_function_ev_board:
# version: "4.1.*"

View File

@ -0,0 +1,45 @@
set(LV_BUILD_USE_KCONFIG ON)
idf_component_register(SRCS
"test_ihm.c"
"../../ihm.c"
"../../ihm_gateway.c"
"../../lv_theme_domotic.c"
"../../model.c"
"driver_backends.c"
"sdl.c"
"../../fonts/montserrat_medium_12.c"
"../../fonts/montserrat_medium_18.c"
"../../fonts/montserrat_medium_24.c"
"../../fonts/roboto_medium_36.c"
"../../fonts/roboto_medium_72.c"
"../../fonts/vlump_96.c"
"../../fonts/super_malibu_80.c"
"../../images/wifi_ko.c"
"../../images/wifi_ok.c"
INCLUDE_DIRS
"../../include"
"../mock"
WHOLE_ARCHIVE
REQUIRES lvgl meteofrance RemindMe)
message("Including SDL2 support")
find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL2 REQUIRED sdl2)
pkg_check_modules(SDL2_IMAGE REQUIRED SDL2_image)
list(APPEND PKG_CONFIG_LIB ${SDL2_LIBRARIES} ${SDL2_IMAGE_LIBRARIES})
list(APPEND PKG_CONFIG_INC ${SDL2_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS})
target_compile_options(${COMPONENT_LIB} PUBLIC --coverage -DLV_LVGL_H_INCLUDE_SIMPLE )
target_link_libraries(${COMPONENT_LIB} PUBLIC ${PKG_CONFIG_LIB} --coverage)
target_include_directories(${COMPONENT_LIB} PRIVATE ${CMAKE_SOURCE_DIR}/mock ${PKG_CONFIG_INC})
target_link_libraries(${COMPONENT_LIB} PRIVATE bsd)
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
target_compile_options(${COMPONENT_LIB} PRIVATE -std=gnu++20)
endif()
# Currently 'main' for IDF_TARGET=linux is defined in freertos component.
# Since we are using a freertos mock here, need to let Catch2 provide 'main'.
#target_link_libraries(${COMPONENT_LIB} PRIVATE Catch2WithMain)

View File

@ -0,0 +1,97 @@
/**
* @file backends.h
*
* Interface for abstration layer of a device backend
*
* Copyright (c) 2025 EDGEMTech Ltd.
*
* Author: EDGEMTech Ltd, Erik Tagirov (erik.tagirov@edgemtech.ch)
*
*/
#ifndef BACKENDS_H
#define BACKENDS_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/* Prototype of the display initialization functions */
typedef lv_display_t *(*display_init_t)(void);
/* Prototype of the run loop */
typedef void (*run_loop_t)(void);
/* Represents a display driver handle */
typedef struct {
display_init_t init_display; /* The display creation/initialization function */
run_loop_t run_loop; /* The run loop of the driver handle */
lv_display_t *display; /* The LVGL display that was created */
} display_backend_t;
/* Prototype for the initialization of an indev driver backend */
typedef lv_indev_t *(*indev_init_t)(lv_display_t *display);
/* Represents an indev driver backend */
typedef struct {
indev_init_t init_indev;
} indev_backend_t;
/* Regroup all different types of driver backend */
typedef union {
display_backend_t *display;
indev_backend_t *indev;
} backend_handle_t;
/* Define each type of driver backend */
typedef enum {
BACKEND_DISPLAY,
BACKEND_INDEV
} backend_type_t;
/* Driver backend descriptor */
typedef struct {
backend_handle_t *handle;
char *name;
backend_type_t type;
} backend_t;
/* Prototype used to register a backend */
typedef int (*backend_init_t)(backend_t *);
/**********************
* GLOBAL PROTOTYPES
**********************/
/* Graphics backends */
int backend_init_fbdev(backend_t *backend);
int backend_init_drm(backend_t *backend);
int backend_init_sdl(backend_t *backend);
int backend_init_glfw3(backend_t *backend);
int backend_init_wayland(backend_t *backend);
int backend_init_x11(backend_t *backend);
/* Input device driver backends */
int backend_init_evdev(backend_t *backend);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*BACKEND_H*/

View File

@ -0,0 +1,281 @@
/**
* @file driver_backends.c
*
* Copyright (c) 2025 EDGEMTech Ltd.
*
* Author: EDGEMTech Ltd, Erik Tagirov (erik.tagirov@edgemtech.ch)
*/
/*********************
* INCLUDES
*********************/
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#include "lvgl.h"
#include "simulator_util.h"
#include "simulator_settings.h"
#include "driver_backends.h"
#include "backends.h"
/*********************
* DEFINES
*********************/
/* Catch configuration errors at compile time - checks if no backend was selected */
#if LV_USE_SDL == 0 && \
LV_USE_WAYLAND == 0 && \
LV_USE_LINUX_DRM == 0 && \
LV_USE_GLFW == 0 && \
LV_USE_X11 == 0 && \
LV_USE_LINUX_FBDEV == 0
#endif
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/* The default backend is the one that will end up at index 0
* To add support for a new driver backend add the declaration
* and append an entry to the available_backends array
*/
backend_init_t available_backends[] = {
#if LV_USE_LINUX_FBDEV
backend_init_fbdev,
#endif
#if LV_USE_LINUX_DRM
backend_init_drm,
#endif
backend_init_sdl,
#if LV_USE_WAYLAND
backend_init_wayland,
#endif
#if LV_USE_X11
backend_init_x11,
#endif
#if LV_USE_GLFW
backend_init_glfw3,
#endif
#if LV_USE_EVDEV
backend_init_evdev,
#endif
NULL /* Sentinel */
};
/* Contains the backend descriptors */
static backend_t *backends[sizeof(available_backends) / sizeof(available_backends[0])];
/* Set once the user selects a backend - or it is set to the default backend */
static backend_t *sel_display_backend = NULL;
/**********************
* GLOBAL VARIABLES
**********************/
/* Contains global simulator settings common to each backend */
simulator_settings_t settings;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void driver_backends_register(void)
{
int i;
backend_init_t init_backend;
backend_t *b;
i = 0;
if (backends[i] != NULL) {
/* backends are already registered - leave */
return;
}
while ((init_backend = available_backends[i]) != NULL) {
b = malloc(sizeof(backend_t));
LV_ASSERT_NULL(b);
b->handle = malloc(sizeof(backend_handle_t));
init_backend = available_backends[i];
LV_ASSERT_NULL(init_backend);
init_backend(b);
backends[i] = b;
i++;
}
}
int driver_backends_init_backend(char *backend_name)
{
backend_t *b;
int i;
display_backend_t *dispb;
indev_backend_t *indevb;
if (backends[0] == NULL) {
LV_LOG_ERROR("Please call driver_backends_register first");
return -1;
}
if (backend_name == NULL) {
/*
* Set default display backend - which is the first defined
* item in available_backends array
*/
LV_ASSERT_NULL(backends[0]);
b = backends[0];
if (b->type != BACKEND_DISPLAY) {
LV_LOG_ERROR("The default backend: %s is not a display driver backend", b->name);
return -1;
}
backend_name = backends[0]->name;
}
i = 0;
while ((b = backends[i]) != NULL) {
/* Check if such a backend exists */
if (strcmp(b->name, backend_name) == 0) {
if (b->type == BACKEND_DISPLAY) {
/* Initialize the display */
dispb = b->handle->display;
LV_ASSERT_NULL(dispb->init_display);
dispb->display = dispb->init_display();
if (dispb->display == NULL) {
LV_LOG_ERROR("Failed to init display with %s backend", b->name);
return -1;
}
sel_display_backend = b;
LV_LOG_INFO("Initialized %s display backend", b->name);
break;
} else if (b->type == BACKEND_INDEV) {
/* Initialize input device */
indevb = b->handle->indev;
LV_ASSERT_NULL(indevb->init_indev);
/* The display driver backend - has to be initialized first */
if (sel_display_backend == NULL) {
LV_LOG_ERROR(
"Failed to init indev backend: %s - display needs to be initialized",
b->name);
return -1;
}
LV_LOG_INFO("Initialized %s indev backend", b->name);
dispb = sel_display_backend->handle->display;
LV_ASSERT_NULL(dispb->display);
indevb->init_indev(dispb->display);
break;
}
}
i++;
}
return 0;
}
int driver_backends_print_supported(void)
{
int i;
backend_t *b;
i = 0;
if (backends[i] == NULL) {
LV_LOG_ERROR("Please call driver_backends_register first");
return -1;
}
b = backends[i];
fprintf(stdout, "Default backend: %s\n", b->name);
fprintf(stdout, "Supported backends: ");
while ((b = backends[i++]) != NULL) {
fprintf(stdout, "%s ", b->name);
}
fprintf(stdout, "\n");
return 0;
}
int driver_backends_is_supported(char *backend_name)
{
char c;
backend_t *b;
char *name = backend_name;
int i = 0;
while ((c = *backend_name) != '\0') {
*backend_name = toupper(c);
backend_name++;
}
while ((b = backends[i++]) != NULL) {
if (strcmp(b->name, name) == 0) {
return 1;
}
}
return 0;
}
void driver_backends_run_loop(void)
{
display_backend_t *dispb;
if (sel_display_backend != NULL && sel_display_backend->handle->display != NULL) {
dispb = sel_display_backend->handle->display;
dispb->run_loop();
} else {
LV_LOG_ERROR("No backend has been selected - initialize the backend first");
}
}
/**********************
* STATIC FUNCTIONS
**********************/

View File

@ -0,0 +1,93 @@
/**
* @file driver_backends.h
*
* provides an abstration to support multiple graphical
* driver backends at the same time whitout recompiling everything
* each time
*
* E.g: this means LVGL can be compiled with both SDL or X11
*
* - see backend.h for the details on the interface.
* - see the files in display_backends directory for examples
* on how to use each driver
*
* Copyright (c) 2025 EDGEMTech Ltd.
*
* Author: EDGEMTech Ltd, Erik Tagirov (erik.tagirov@edgemtech.ch)
*/
#ifndef DRIVER_BACKENDS_H
#define DRIVER_BACKENDS_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/*
* Register all available backends
* This function must be called first before any other
* function
*/
void driver_backends_register(void);
/**
* Initialize the specified backend
* @description in case of a display driver backend
* - create the lv_display, in case of a indev driver backend
* create an input device
*
* @param backend_name the name of the backend to initialize FBDEV,DRM etc
* @return 0 on success, -1 on error
*/
int driver_backends_init_backend(char *backend_name);
/**
* @brief Checks if a backend exists and is supported
* @param backend_name the backend name to check
* @return 1 is supported, 0 not supported or invalid name
*/
int driver_backends_is_supported(char *backend_name);
/**
* @brief Print supported backends
* @description Prints a list of supported backends
*
* @return -1 if an error occurred, 0 on success
*/
int driver_backends_print_supported(void);
/**
* @brief Enter the run loop
* @description enter the run loop of the selected backend
*/
void driver_backends_run_loop(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*DRIVER_BACKENDS_H*/

View File

@ -0,0 +1,5 @@
dependencies:
lvgl/lvgl:
version: 9.4.0
#espressif/esp32_p4_function_ev_board:
# version: "4.1.*"

View File

@ -0,0 +1,115 @@
/**
* @file sdl.c
*
* The backend for the SDL simulator
*
* Based on the original file from the repository
*
* - Move to a separate file
* 2025 EDGEMTech Ltd.
*
* Author: EDGEMTech Ltd, Erik Tagirov (erik.tagirov@edgemtech.ch)
*
*/
/*********************
* INCLUDES
*********************/
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
#include "lvgl.h"
#include "simulator_util.h"
#include "simulator_settings.h"
#include "backends.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* EXTERNAL VARIABLES
**********************/
extern simulator_settings_t settings;
/**********************
* STATIC PROTOTYPES
**********************/
static void run_loop_sdl(void);
static lv_display_t *init_sdl(void);
/**********************
* STATIC VARIABLES
**********************/
static char *backend_name = "SDL";
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Register the backend
* @param backend the backend descriptor
* @description configures the descriptor
*/
int backend_init_sdl(backend_t *backend)
{
LV_ASSERT_NULL(backend);
backend->handle->display = malloc(sizeof(display_backend_t));
LV_ASSERT_NULL(backend->handle->display);
backend->handle->display->init_display = init_sdl;
backend->handle->display->run_loop = run_loop_sdl;
backend->name = backend_name;
backend->type = BACKEND_DISPLAY;
return 0;
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Initialize the SDL display driver
*
* @return the LVGL display
*/
static lv_display_t *init_sdl(void)
{
lv_display_t *disp;
disp = lv_sdl_window_create(settings.window_width, settings.window_height);
if (disp == NULL) {
return NULL;
}
return disp;
}
/**
* The run loop of the SDL driver
*/
static void run_loop_sdl(void)
{
uint32_t idle_time;
/* Handle LVGL tasks */
while (true) {
/* Returns the time to the next timer execution */
idle_time = lv_timer_handler();
usleep(idle_time * 1000);
}
}

View File

@ -0,0 +1,53 @@
/**
* @file simulator_settings.h
*
* global simulator settings
*
* The simulator settings is a global variable defined in
* simulator_settings.c
*
* Copyright (c) 2025 EDGEMTech Ltd.
*
* Author: EDGEMTech Ltd, Erik Tagirov (erik.tagirov@edgemtech.ch)
*
*/
#ifndef SIMULATOR_SETTINGS_H
#define SIMULATOR_SETTINGS_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef struct {
uint32_t window_width;
uint32_t window_height;
bool maximize;
bool fullscreen;
} simulator_settings_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*SIMULATOR_SETTINGS_H*/

View File

@ -0,0 +1,66 @@
/**
* @file simulator_util.c
*
* Utility functions
* Copyright (c) 2025 EDGEMTech Ltd.
*
* Based on the original file from the repo
*
* Author: EDGEMTech Ltd, Erik Tagirov (erik.tagirov@edgemtech.ch)
*
*/
/*********************
* INCLUDES
*********************/
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
const char *getenv_default(const char *name, const char *default_val)
{
const char* value = getenv(name);
return value ? value : default_val;
}
void die(const char *msg, ...)
{
va_list args;
va_start(args, msg);
vfprintf(stderr, msg, args);
va_end(args);
exit(EXIT_FAILURE);
}
/**********************
* STATIC FUNCTIONS
**********************/

View File

@ -0,0 +1,62 @@
/**
* @file simulator_util.h
*
* simulator_util.h - Header file for the utility functions
* used by the simulator
*
* Copyright (c) 2025 EDGEMTech Ltd.
*
* Author: EDGEMTech Ltd, Erik Tagirov (erik.tagirov@edgemtech.ch)
*/
#ifndef SIMULATOR_UTIL_H
#define SIMULATOR_UTIL_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include <stdarg.h>
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* @description Wrapper around getenv(3), allowing to set a default value
* @param name The name of the environment variable
* @param dflt The default value to set if the variable is not present.
* @return default value or value of environment variable.
*/
const char *getenv_default(const char *name, const char *default_val);
/**
* @description Centralized exit point, called due to an error
* @param msg The message to display on stderr before killing the program
* @param ... Values for the format string.
*/
void die(const char *msg, ...);
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*SIMULATOR_UTIL_H*/

View File

@ -0,0 +1,229 @@
#define LV_USE_SDL 1
#define LV_FONT_DEFAULT &roboto_medium_36
#include <stdio.h>
#include "ihm.h"
#include "mqtt_client.h"
#include "backends.h"
#include <unistd.h>
#include "driver_backends.h"
#include "simulator_util.h"
#include "simulator_settings.h"
#include "esp_log.h"
#include "eventsManager.h"
#include "RemindMe.h"
#include "ihm_gateway.h"
#include "platform_detect.h"
esp_mqtt_client_handle_t client;
SemaphoreHandle_t lvgl_mux;
/* contains the name of the selected backend if user
* has specified one on the command line */
static char *selected_backend;
/* Global simulator settings, defined in lv_linux_backend.c */
extern simulator_settings_t settings;
void die(const char *msg, ...)
{
va_list args;
va_start(args, msg);
vfprintf(stderr, msg, args);
va_end(args);
exit(EXIT_FAILURE);
}
/**
* @brief Print LVGL version
*/
static void print_lvgl_version(void)
{
fprintf(stdout, "%d.%d.%d-%s\n",
LVGL_VERSION_MAJOR,
LVGL_VERSION_MINOR,
LVGL_VERSION_PATCH,
LVGL_VERSION_INFO);
}
/**
* @brief Print usage information
*/
static void print_usage(void)
{
fprintf(stdout, "\nlvglsim [-V] [-B] [-b backend_name] [-W window_width] [-H window_height]\n\n");
fprintf(stdout, "-V print LVGL version\n");
fprintf(stdout, "-B list supported backends\n");
}
/**
* @brief Configure simulator
* @description process arguments recieved by the program to select
* appropriate options
* @param argc the count of arguments in argv
* @param argv The arguments
*/
static void configure_simulator(int argc, char **argv)
{
int opt = 0;
selected_backend = NULL;
driver_backends_register();
const char *env_w = getenv("LV_SIM_WINDOW_WIDTH");
const char *env_h = getenv("LV_SIM_WINDOW_HEIGHT");
/* Default values */
settings.window_width = atoi(env_w ? env_w : "1024");
settings.window_height = atoi(env_h ? env_h : "600");
/* Parse the command-line options. */
while ((opt = getopt (argc, argv, "b:fmW:H:BVh")) != -1) {
switch (opt) {
case 'h':
print_usage();
exit(EXIT_SUCCESS);
break;
case 'V':
print_lvgl_version();
exit(EXIT_SUCCESS);
break;
case 'B':
driver_backends_print_supported();
exit(EXIT_SUCCESS);
break;
case 'b':
if (driver_backends_is_supported(optarg) == 0) {
die("error no such backend: %s\n", optarg);
}
selected_backend = strdup(optarg);
break;
case 'W':
settings.window_width = atoi(optarg);
break;
case 'H':
settings.window_height = atoi(optarg);
break;
case ':':
print_usage();
die("Option -%c requires an argument.\n", optopt);
break;
case '?':
print_usage();
die("Unknown option -%c.\n", optopt);
}
}
}
int app_main1(int argc, char *argv[]) {
// Détecte la plateforme
bool isPC = platform_is_pc();
// Init gateway
ihm_gateway_init();
startEvtManager();
if (isPC) {
// PC / SDL : loop dans le thread principal
/* Initialize LVGL. */
lv_init();
configure_simulator(argc, argv);
/* Initialize the configured backend */
if (driver_backends_init_backend(selected_backend) == -1) {
die("Failed to initialize display backend");
}
lv_sdl_mouse_create();
lv_sdl_keyboard_create();
lv_sdl_mousewheel_create();
lv_sdl_mousewheel_create();
time_t now;
struct tm timeinfo;
time(&now);
localtime_r(&now, &timeinfo);
lv_subject_init_pointer(&timeSubj, &timeinfo);
drawIhm(NULL);
} else {
// ESP32 : créer task FreeRTOS
xTaskCreate(drawIhm, "LVGL", 256*1024, NULL, 3, NULL);
}
// Exemple : poster un événement
xIHMEvent_t *evt = malloc(sizeof(*evt));
evt->eEventType = 1;
evt->pvData = strdup("Hello LVGL");
evt->bNeedToFreeData = true;
ihm_gateway_post_event(evt);
return 0;
}
int app_main2(int argc, char *argv[])
{
/* code */
printf("hello\n");
lvgl_mux = xSemaphoreCreateRecursiveMutex();
assert(lvgl_mux);
init_display_ihm();
//size_t watermark = uxTaskGetStackHighWaterMark(NULL);
//ESP_LOGI("STACK", "Remaining stack: %d bytes", watermark);
/*lv_timer_t *clock_timer = lv_timer_create(clock_timer_cb, 1000, NULL);*/
//draw_ihm();
startEvtManager();
int count=0;
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);
}
xTaskCreate(drawIhm, "LVGL", 14 * 1024, getIHMQueueHandle(), 3, NULL);
//drawIhm(getIHMQueueHandle());
send_event(EVT_WIFI_CONNECTED,NULL);
meteodailyforecast_data dts = {
.datetime= time(NULL),
.isValid= true,
.previsions = {
.desc = "Ensoleillé",
.icon = "p4j",
.max = 12.40f,
.min = 3.30f
}
};
/*
extern lv_subject_t forecastD1Subj;
extern lv_subject_t forecastD2Subj;
extern lv_subject_t forecastD3Subj;
ESP_LOGI("test_ihm", "Setting forecastD1Subj");
lv_subject_set_pointer(&forecastD1Subj, &dts);
lv_subject_set_pointer(&forecastD2Subj, &dts);
lv_subject_set_pointer(&forecastD3Subj, &dts);
*/
/* Enter the run loop of the selected backend */
driver_backends_run_loop();
//drawIhm(getIHMQueueHandle());
return 0;
}

View File

@ -0,0 +1,6 @@
int bsp_display_lock(int arg){
return 1;
}
void bsp_display_unlock(){
}

View File

@ -0,0 +1,29 @@
#define BIT0 0x00000001
#define WIFI_CONNECTED_BIT BIT0
typedef enum {
WIFI_EVENT_WIFI_READY = 0, /**< WiFi ready */
WIFI_EVENT_SCAN_DONE, /**< finish scanning AP */
WIFI_EVENT_STA_START, /**< station start */
WIFI_EVENT_STA_STOP, /**< station stop */
WIFI_EVENT_STA_CONNECTED, /**< station connected to AP */
WIFI_EVENT_STA_DISCONNECTED, /**< station disconnected from AP */
WIFI_EVENT_STA_AUTHMODE_CHANGE, /**< the auth mode of AP connected by station changed */
WIFI_EVENT_STA_GOT_IP, /**< station got IP from connected AP */
WIFI_EVENT_STA_WPS_ER_SUCCESS, /**< station wps succeeds in enrollee mode */
WIFI_EVENT_STA_WPS_ER_FAILED, /**< station wps fails in enrollee mode */
WIFI_EVENT_STA_WPS_ER_TIMEOUT, /**< station wps timeout in enrollee mode */
WIFI_EVENT_STA_WPS_ER_PIN, /**< station wps pin code in enrollee mode */
WIFI_EVENT_AP_START, /**< soft-AP start */
WIFI_EVENT_AP_STOP, /**< soft-AP stop */
WIFI_EVENT_AP_STACONNECTED, /**< a station connected to soft-AP */
WIFI_EVENT_AP_STADISCONNECTED, /**< a station disconnected from soft-AP */
WIFI_EVENT_AP_PROBEREQRECVED, /**< Receive probe request packet in soft-AP interface */
WIFI_EVENT_AP_STA_GOT_IP6, /**< station or ap interface v6IP addr is preferred */
WIFI_EVENT_ETH_START, /**< ethernet start */
WIFI_EVENT_ETH_STOP, /**< ethernet stop */
WIFI_EVENT_ETH_CONNECTED, /**< ethernet phy link up */
WIFI_EVENT_ETH_DISCONNECTED, /**< ethernet phy link down */
WIFI_EVENT_ETH_GOT_IP, /**< ethernet got IP from connected AP */
WIFI_EVENT_MAX
} wifi_event_id_t;

View File

@ -1,7 +1,7 @@
idf_build_get_property(python SIMULATION_QEMU)
message(STATUS "The Python interpreter is: ${python}")
set(comps heap nvs_flash esp_netif image_downloader fatfs protocol_examples_common mqtt)
set(comps heap nvs_flash esp_netif image_downloader fatfs protocol_examples_common mqtt meteofrance domotic_display RemindMe)
if(${IDF_TARGET} STREQUAL "esp32p4")
message(STATUS "SIMULATION_QEMU = OOF --> main standard")
@ -11,9 +11,28 @@ if(${IDF_TARGET} STREQUAL "esp32p4")
REQUIRES ${comps}
EMBED_TXTFILES ${PROJECT_DIR}/main/ca_cert.pem
EMBED_FILES "index.html")
elseif(${IDF_TARGET} STREQUAL "linux")
message(STATUS "Linux Mode --> main standard")
list(APPEND comps vfs esp_http_server)
idf_component_register(SRCS main.c
INCLUDE_DIRS "./include"
REQUIRES ${comps}
EMBED_TXTFILES ${PROJECT_DIR}/main/ca_cert.pem
EMBED_FILES "index.html")
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 --coverage -DLV_LVGL_H_INCLUDE_SIMPLE )
else()
message(STATUS "SIMULATION_QEMU = On vide le main")
idf_component_register(SRCS test_main.c)
idf_component_register(SRCS test_main.c PRIV_REQUIRES meteofrance)
return()
endif()

View File

@ -25,4 +25,8 @@ dependencies:
version: 9.4.0
#espressif/esp32_p4_function_ev_board:
# version: "4.1.*"
espressif/esp32_p4_function_ev_board: '*'
espressif/esp32_p4_function_ev_board:
version: '*'
rules:
- if: target in ["esp32p4"]

View File

@ -8,33 +8,30 @@
#include "esp_event.h"
#include "nvs_flash.h"
#include <locale.h>
#include "esp_vfs_fat.h"
#include "sdmmc_cmd.h"
#include <stdio.h>
#include "bh1750.h"
#include <math.h>
#include "esp_http_server.h"
#include "bsp/esp-bsp.h"
#include "main.h"
#include "ihm.h"
#include "ihm_gateway.h"
// OTA
#include "esp_ota_ops.h"
/*#include "esp_ota_ops.h"
#include "esp_http_client.h"
#include "esp_https_ota.h"
*/
// Includes personnels
#include "wifi_logger.h"
//#include "wifi_logger.h"
#include "obtain_time.h"
#include "image_downloader.h"
#include "include/communication.h"
#include "stateManagement.h"
#include "driver/gpio.h"
#include "am2302_rmt.h"
//#include "driver/gpio.h"
//#include "am2302_rmt.h"
#include "eventsManager.h"
#include "esp_timer.h"
@ -44,7 +41,7 @@
// GPIO assignment
#define AM2302_GPIO 4
#include "esp_littlefs.h"
//#include "esp_littlefs.h"
#define MOUNT_POINT "/sdcard"
// Pin assignments can be set in menuconfig, see "SD SPI Example Configuration" menu.
@ -59,7 +56,7 @@
#define I2C_MASTER_NUM I2C_NUM_0 /*!< I2C port number for master dev */
#define I2C_MASTER_FREQ_HZ 100000 /*!< I2C master clock frequency */
static bh1750_handle_t bh1750 = NULL;
//static bh1750_handle_t bh1750 = NULL;
static const char *TAG = "domoTic";
@ -76,7 +73,7 @@ static void wifiStatus_obs_cb(lv_observer_t * observer, lv_subject_t * subject);
lv_subject_t mqttStatus;
lv_subject_t wifiStatus;
//lv_subject_t wifiStatus;
extern lv_subject_t tempIntSubj;
extern lv_subject_t tempExtSubj;
@ -84,7 +81,7 @@ extern lv_subject_t hauteurCuveSubj;
extern lv_subject_t hauteurCuveEvolSubj;
void init_display(){
lvgl_port_cfg_t lvgl_cfg = ESP_LVGL_PORT_INIT_CONFIG();
/* lvgl_port_cfg_t lvgl_cfg = ESP_LVGL_PORT_INIT_CONFIG();
lvgl_cfg.task_priority=15;
bsp_display_cfg_t cfg = {
.lvgl_port_cfg = lvgl_cfg,
@ -104,28 +101,31 @@ void init_display(){
bsp_display_brightness_set(50);
mainState.display_init=true;
*/
}
/**
* @brief i2c master initialization
*/
static void i2c_bus_init(i2c_master_bus_handle_t *bus_handle)
/* static void i2c_bus_init(i2c_master_bus_handle_t *bus_handle)
{
i2c_master_bus_config_t conf;
conf.sda_io_num = (gpio_num_t)I2C_MASTER_SDA_IO;
conf.flags.enable_internal_pullup=true;
conf.scl_io_num = (gpio_num_t)I2C_MASTER_SCL_IO;
conf.i2c_port=I2C_NUM_0;
conf.clk_source = I2C_CLK_SRC_DEFAULT;
conf.glitch_ignore_cnt = 7;
ESP_ERROR_CHECK(i2c_new_master_bus(&conf, bus_handle));
// i2c_master_bus_config_t conf;
// conf.sda_io_num = (gpio_num_t)I2C_MASTER_SDA_IO;
// conf.flags.enable_internal_pullup=true;
// conf.scl_io_num = (gpio_num_t)I2C_MASTER_SCL_IO;
// conf.i2c_port=I2C_NUM_0;
// conf.clk_source = I2C_CLK_SRC_DEFAULT;
// conf.glitch_ignore_cnt = 7;
// ESP_ERROR_CHECK(i2c_new_master_bus(&conf, bus_handle));
}
*/
void bh1750_init(void)
{
/*
i2c_master_bus_handle_t bus_handle;
i2c_bus_init(&bus_handle);
bh1750 = bh1750_create(I2C_MASTER_NUM, BH1750_I2C_ADDRESS_DEFAULT, bus_handle);
*/
}
@ -133,47 +133,47 @@ void mqtt_cb(mqtt_evt evt, esp_mqtt_event_handle_t event){
switch (evt)
{
case MQTT_CONNECTED:
if(lvgl_port_lock(50)){
//if(lvgl_port_lock(50)){
ESP_LOGV(TAG,"Statut mqttStatus 1");
lv_subject_set_int(&mqttStatus,1);
lvgl_port_unlock();
}
//lv_subject_set_int(&mqttStatus,1);
//lvgl_port_unlock();
//}
break;
case MQTT_DISCONNECTED:
if(lvgl_port_lock(50)){
//if(lvgl_port_lock(50)){
ESP_LOGE(TAG,"Statut mqttStatus 0");
lv_subject_set_int(&mqttStatus,0);
lvgl_port_unlock();
}
//lv_subject_set_int(&mqttStatus,0);
//lvgl_port_unlock();
//}
esp_mqtt_client_reconnect(event->client);
break;
case MQTT_DATA_RECEIVED:
lv_subject_set_int(&mqttStatus,2);
//lv_subject_set_int(&mqttStatus,2);
ESP_LOGD(TAG, "\nMQTT_EVENT_DATA");
ESP_LOGD(TAG, "TOPIC=%.*s\n", event->topic_len, event->topic);
ESP_LOGD(TAG, "DATA=%.*s\n", event->data_len, event->data);
char *topic = strndup(event->topic, event->topic_len);
if (strcmp(topic, topicTempExt) == 0)
{
if(lvgl_port_lock(50)){
//if(lvgl_port_lock(50)){
float temp = strtof(event->data, NULL);
char buff[5];
sprintf(buff,"%.1f",temp);
lv_subject_copy_string(&tempExtSubj, buff);
//lv_subject_copy_string(&tempExtSubj, buff);
lvgl_port_unlock();
}
//lvgl_port_unlock();
//}
}
else if (strcmp(topic, topicTempInt) == 0)
{
if(lvgl_port_lock(0)){
//if(lvgl_port_lock(0)){
// on retransforme en float pour ne garder que la partie entiere de la température
float temp = strtof(event->data, NULL);
char buff[5];
sprintf(buff,"%.1f",temp);
lv_subject_copy_string(&tempIntSubj, buff);
lvgl_port_unlock();
}
//lv_subject_copy_string(&tempIntSubj, buff);
//lvgl_port_unlock();
//}
}
/*else if (strncmp(event->topic, topicHauteurCuveEvol, event->topic_len) == 0)
{
@ -227,7 +227,7 @@ void mqtt_cb(mqtt_evt evt, esp_mqtt_event_handle_t event){
char *datas = strndup(event->data, event->data_len);
if(strcmp(datas,"restart")==0){
ESP_LOGI(TAG," Commande 'restart' recue");
esp_restart();
//esp_restart();
}
}
else
@ -235,10 +235,10 @@ void mqtt_cb(mqtt_evt evt, esp_mqtt_event_handle_t event){
ESP_LOGE(TAG, "None match :-( %s", topic);
}
free(topic);
if (lvgl_port_lock(50)){
lv_subject_set_int(&mqttStatus,3);
lvgl_port_unlock();
}
//if (lvgl_port_lock(50)){
//lv_subject_set_int(&mqttStatus,3);
//lvgl_port_unlock();
//}
break;
default:
@ -255,7 +255,7 @@ struct state mainState={
void mount_sd_card()
{
// Options for mounting the filesystem.
/* // Options for mounting the filesystem.
// If format_if_mount_failed is set to true, SD card will be partitioned and
// formatted in case when mounting fails.
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
@ -311,13 +311,13 @@ void mount_sd_card()
// Card has been initialized, print its properties
sdmmc_card_print_info(stdout, card);
}
*/}
extern char *days[7];
extern char *months[12];
esp_err_t _ota_http_event_handler(esp_http_client_event_t *evt)
/* esp_err_t _ota_http_event_handler(esp_http_client_event_t *evt)
{
switch (evt->event_id) {
case HTTP_EVENT_ERROR:
@ -347,11 +347,11 @@ esp_err_t _ota_http_event_handler(esp_http_client_event_t *evt)
}
return ESP_OK;
}
*/
extern const uint8_t server_cert_pem_start[] asm("_binary_ca_cert_pem_start");
extern const uint8_t server_cert_pem_end[] asm("_binary_ca_cert_pem_end");
static esp_err_t validate_image_header(esp_app_desc_t *new_app_info)
/* static esp_err_t validate_image_header(esp_app_desc_t *new_app_info)
{
if (new_app_info == NULL) {
return ESP_ERR_INVALID_ARG;
@ -372,12 +372,12 @@ static esp_err_t validate_image_header(esp_app_desc_t *new_app_info)
return ESP_OK;
}
*/
void simple_ota_example_task(void *pvParameter)
{
ESP_LOGE(TAG,"En attente connexion wifi");
/* ESP_LOGE(TAG,"En attente connexion wifi");
// Waiting until either the connection is established (WIFI_CONNECTED_BIT).
EventBits_t bits = xEventGroupWaitBits(domotic_event_group,
BIT0,
@ -503,13 +503,13 @@ ota_end:
ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed");
vTaskDelete(NULL);
}
}
*/}
am2302_handle_t sensor = NULL;
//am2302_handle_t sensor = NULL;
void readTempHumid(void *pvParameter)
{
float temperature = 0;
/* float temperature = 0;
float humidity = 0;
while (1)
{
@ -524,7 +524,7 @@ void readTempHumid(void *pvParameter)
//xQueueSendToFront(ihm_queue,&m,5);
vTaskDelay(60000 / portTICK_PERIOD_MS);
}
*/
}
void alloc_fail(size_t size, uint32_t caps, const char * function_name){
@ -538,16 +538,16 @@ bool ecranEteint=true;
// Ce timer permet d'eteindre l'ecran "arretAuto" apres la derniere présence détectée
esp_timer_handle_t presence_timer;
static void IRAM_ATTR gpio_isr_handler(void* arg)
/* static void IRAM_ATTR gpio_isr_handler(void* arg)
{
uint32_t gpio_num = (uint32_t) arg;
xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}
*/
float maxBrightness = 100;
static void gpio_task_example(void* arg)
/* static void gpio_task_example(void* arg)
{
uint32_t io_num;
int delay=50;
@ -574,10 +574,10 @@ static void gpio_task_example(void* arg)
}
}
}
#define GPIO_INPUT_IO_0 CONFIG_GPIO_INPUT_CAPTEUR_PIR
*/#define GPIO_INPUT_IO_0 CONFIG_GPIO_INPUT_CAPTEUR_PIR
void initPirSensor(){
//create a queue to handle gpio event from isr
/* //create a queue to handle gpio event from isr
gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
//start gpio task
xTaskCreate(gpio_task_example, "gpio_task_example", 5000, NULL, 10, NULL);
@ -591,11 +591,11 @@ void initPirSensor(){
ESP_ERROR_CHECK(gpio_config(&gpioconf));
gpio_install_isr_service(0);
gpio_isr_handler_add(GPIO_INPUT_IO_0,gpio_isr_handler,(void*)(GPIO_INPUT_IO_0));
*/
}
/* Ce timer permet d'eteindre l'ecran apres @arretAuto de présence*/
static void presence_timer_callback(void* arg)
/* static void presence_timer_callback(void* arg)
{
int64_t time_since_boot = esp_timer_get_time();
for (int i = maxBrightness; i >= 0; i-=2)
@ -608,7 +608,7 @@ static void presence_timer_callback(void* arg)
}
ecranEteint=true;
}
*/
static esp_err_t download_get_handler(httpd_req_t *req) {
httpd_resp_set_type(req, "application/octet-stream");
httpd_resp_set_hdr(req, "Content-Disposition",
@ -749,27 +749,27 @@ void weather_data_retreived(struct meteodailyforecast_data dailyDatas[3], struct
printf("%f\n", datas[2].previsions.value);
ESP_LOGE(TAG, "fin debug");
*/
if (display_lock("weather_data_retreived"))
{
//if (display_lock("weather_data_retreived"))
//{
ESP_LOGV("MeteoFrance", "------------------------------------- Set des subjects J --------------------------------");
// Prévisions des 3 prochains jours
lv_subject_set_pointer(&forecastD1Subj, &dailyDatas[0]);
lv_subject_set_pointer(&forecastD2Subj, &dailyDatas[1]);
lv_subject_set_pointer(&forecastD3Subj, &dailyDatas[2]);
//lv_subject_set_pointer(&forecastD1Subj, &dailyDatas[0]);
//lv_subject_set_pointer(&forecastD2Subj, &dailyDatas[1]);
//lv_subject_set_pointer(&forecastD3Subj, &dailyDatas[2]);
ESP_LOGV("MeteoFrance", "------------------------------------- Set des subjects H--------------------------------");
// Prévisions des 3 prochains jours
ESP_LOGV("MeteoFrance", "Pointeur %lli", datas[0].datetime);
lv_subject_set_pointer(&forecastH1Subj, &datas[0]);
lv_subject_set_pointer(&forecastH2Subj, &datas[1]);
lv_subject_set_pointer(&forecastH3Subj, &datas[2]);
//lv_subject_set_pointer(&forecastH1Subj, &datas[0]);
//lv_subject_set_pointer(&forecastH2Subj, &datas[1]);
// lv_subject_set_pointer(&forecastH3Subj, &datas[2]);
lv_subject_set_int(&meteoStatus, 0);
display_unlock("weather_data_retreived");
//lv_subject_set_int(&meteoStatus, 0);
//display_unlock("weather_data_retreived");
ESP_LOGV(TAG, "------------------------------------- Fin Set des subjects --------------------------------");
}else{
//}else{
ESP_LOGE(TAG, "Impossible d'obtenir le mutex dans weather_data_retreived");
}
//}
}
void weather_data_retreived_start()
@ -777,7 +777,7 @@ void weather_data_retreived_start()
//if (display_lock("weather_data_retreived_start"))
//{
//ESP_LOGE(TAG,"Mutex obtenu dans weather_data_retreived_start");
lv_subject_set_int(&meteoStatus, 1);
//lv_subject_set_int(&meteoStatus, 1);
ESP_LOGE(TAG,"Subject setted weather_data_retreived_start");
//display_unlock("weather_data_retreived_start");
//}else{
@ -788,7 +788,7 @@ void weather_data_retreived_start()
LV_IMAGE_DECLARE(mqtt_ok);
LV_IMAGE_DECLARE(mqtt_ko);
static void mqttStatus_obs_cb(lv_observer_t * observer, lv_subject_t * subject)
/* static void mqttStatus_obs_cb(lv_observer_t * observer, lv_subject_t * subject)
{
ESP_LOGV(TAG, "On passe dans le callback de chgt de statut; %li", lv_subject_get_int(subject));
if(lvgl_port_lock(0)){
@ -825,7 +825,7 @@ static void mqttStatus_obs_cb(lv_observer_t * observer, lv_subject_t * subject)
//lv_obj_t * btn = lv_observer_get_target(observer);
}
*/
typedef struct {
float Lmin; // lux min (ex. 1)
@ -878,7 +878,7 @@ int32_t map_value(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min, in
}
void lightSensorTask(void *pvParameter){
float bh1750_data;
/* float bh1750_data;
while(1){
ESP_ERROR_CHECK(bh1750_get_data(bh1750, &bh1750_data));
//maxBrightness = map_value(bh1750_data, 0,300,0, 100);
@ -893,43 +893,59 @@ void lightSensorTask(void *pvParameter){
bsp_display_brightness_set(maxBrightness);
vTaskDelay(pdMS_TO_TICKS(100));
}
*/
}
static lv_display_t *display;
static lv_indev_t *mouse;
static lv_indev_t *mouse_wheel;
static lv_indev_t *keyboard;
void app_main(void)
{
esp_task_wdt_deinit(); // désactive le task watchdog
printf("Hello from sim\n");
lv_init();
display = lv_sdl_window_create(1024, 600);
mouse = lv_sdl_mouse_create();
mouse_wheel = lv_sdl_mousewheel_create();
keyboard = lv_sdl_keyboard_create();
ihm_gateway_init();
startEvtManager();
drawIhm(NULL);
/* Create widgets on the screen */
//lv_demo_widgets();
}
void app_main1(void)
{
//esp_task_wdt_deinit(); // désactive le task watchdog
vTaskDelay(pdMS_TO_TICKS(10000)); // laisse le temps d'attacher GDB
bh1750_measure_mode_t cmd_measure;
//bh1750_measure_mode_t cmd_measure;
startEvtManager();
init_display();
const esp_timer_create_args_t periodic_timer_args = {
/* const esp_timer_create_args_t periodic_timer_args = {
.callback = &presence_timer_callback,
/* name is optional, but may help identify the timer when debugging */
// name is optional, but may help identify the timer when debugging
.name = "presence"
};
ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &presence_timer));
/* Start the timers */
// Start the timers
ESP_ERROR_CHECK(esp_timer_start_once(presence_timer, 30*1000*1000));
*/
initPirSensor();
printf("Minimum free heap size: %" PRIu32 " bytes\n", esp_get_minimum_free_heap_size());
printf("Free heap size: %" PRIu32 " bytes\n", esp_get_free_heap_size());
heap_caps_print_heap_info(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
heap_caps_register_failed_alloc_callback(alloc_fail);
printf("1- Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
esp_log_level_set("wifi", ESP_LOG_ERROR);
esp_log_level_set(TAG, ESP_LOG_VERBOSE);
//mount_sd_card();
bsp_sdcard_mount();
/* bsp_sdcard_mount();
ESP_LOGI(TAG, "Initializing LittleFS");
@ -965,7 +981,7 @@ void app_main(void)
ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used);
}
// On affiche au plus tot l'ecran de démarrage
*/ // On affiche au plus tot l'ecran de démarrage
// ESP_ERROR_CHECK(esp_lcd_panel_mirror(lcd_panel,true,true));
xTaskCreatePinnedToCore(&drawIhm,"ihm_task",10000,getIHMQueueHandle(),10,NULL,0);
@ -981,19 +997,19 @@ void app_main(void)
ESP_ERROR_CHECK(ret);
ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
wifi_init_sta(wifi_cb);
//wifi_init_sta(wifi_cb);
//start_wifi_logger();
//wifi_log_e("test", "%s %d %f", "hello world wifi logger", 43, 45.341223242); // write log over wifi with log level -> ERROR
esp_log_level_set("tcp_handler", ESP_LOG_NONE);
printf("8b - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
printf("8b - Free heap after buffers allocation: %zu\n", xPortGetFreeHeapSize());
printf("9 - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
printf("9 - Free heap after buffers allocation: %zu\n", xPortGetFreeHeapSize());
/* Ensure to disable any WiFi power save mode, this allows best throughput
* and hence timings for overall OTA operation.
*/
esp_wifi_set_ps(WIFI_PS_NONE);
xTaskCreatePinnedToCore(&simple_ota_example_task, "ota__task", 8192, NULL, 6, NULL,0);
//esp_wifi_set_ps(WIFI_PS_NONE);
//xTaskCreatePinnedToCore(&simple_ota_example_task, "ota__task", 8192, NULL, 6, NULL,0);
on_weather_data_retrieval(weather_data_retreived);
on_weather_data_retrieval_start(weather_data_retreived_start);
@ -1008,20 +1024,21 @@ void app_main(void)
}
mqtt_app_start(mqtt_cb, domotic_event_group);
//mqtt_app_start(mqtt_cb, domotic_event_group);
//start_wifi_logger();
//wifi_log_e("test", "%s %d %f", "hello world wifi logger", 43, 45.341223242); // write log over wifi with log level -> ERROR }
lv_subject_init_int(&mqttStatus,-1);
lv_subject_add_observer_obj(&mqttStatus, mqttStatus_obs_cb, NULL, NULL);
//lv_subject_init_int(&mqttStatus,-1);
//lv_subject_add_observer_obj(&mqttStatus, mqttStatus_obs_cb, NULL, NULL);
while(!mainState.wifi_init){
vTaskDelay(pdTICKS_TO_MS(10));
}
start_webserver();
// Configuration de la sonde Temp/Humid.
/* // Configuration de la sonde Temp/Humid.
am2302_config_t am2302_config = {
.gpio_num = AM2302_GPIO,
};
@ -1030,5 +1047,5 @@ void app_main(void)
};
ESP_ERROR_CHECK(am2302_new_sensor_rmt(&am2302_config, &rmt_config, &sensor));
xTaskCreate(&readTempHumid, "read_temp_task", 8192, NULL, 5, NULL);
*/
}

View File

@ -1,12 +1,9 @@
#include <stdio.h>
#include "meteofrance.h"
#include "eventsManager.h"
#include "esp_lcd_panel_ops.h"
#include "esp_lcd_qemu_rgb.h"
#include "lvgl.h"
#include "esp_log.h"
#include "ihm.h"
#include "esp_heap_caps.h"
extern EventGroupHandle_t domotic_event_group;