Gestion etat machine. Manque affichage

This commit is contained in:
Marc Pasteur 2026-02-23 13:55:49 +01:00
parent f29fee752f
commit 2da4a8f94b
9 changed files with 253 additions and 141 deletions

View File

@ -19,7 +19,7 @@ make_font(Super_Malibu super_malibu 80)
#execute_process(COMMAND podman run -v /home/marc/rgb_lcd/components/domotic_display/fonts:/app -w /app lvfontconv lv_font_conv --bpp 4 --size 72 --no-compress --font Roboto-Medium.ttf --symbols "0123456789.°àéèûCABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz %,'():ê/-" --format lvgl -o roboto_medium_72.c --font fa-solid-900.ttf --range 61461,0xf0c2,0xf575)
SET(comps meteofrance eventsManager lvgl RemindMe)
SET(comps meteofrance eventsManager lvgl RemindMe washingMachineState)
if(${IDF_TARGET} STREQUAL "esp32p4" OR ${IDF_TARGET} STREQUAL "esp32s3")
#esp32_p4_function_ev_board
idf_component_register(SRC_DIRS . fonts

View File

@ -6,6 +6,7 @@
#include "platform_detect.h"
#include "cJSON.h"
#include "esp_log.h"
#include "washingMachineState.h"
static const char *TAG = "IHM_GW";
@ -86,22 +87,11 @@ void traiteEvt(void *arg)
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);
WashingMachineState wms = traiteMessage(etatMachine);
char etat[80];
getEtatMachineStr(wms, etat,80);
ESP_LOGE(TAG,"Etat machine : %s", etat);
// lv_label_set_text(lblEtatMachine, etatFormate);
cJSON_Delete(root);
break;
}

View File

@ -0,0 +1,2 @@
idf_component_register(SRCS "washingMachineState.c" PRIV_REQUIRES json
INCLUDE_DIRS "include")

View File

@ -0,0 +1,5 @@
But:
Exposer l'état de la machine à laver
Dans sa plus simple expression c'est un listener MQTT
L'état de la machine est ensuite émise via une interface
Le topic est en retain pour pouvoir garder le dernier état de la machine {etat, timestamp}

View File

@ -0,0 +1,24 @@
typedef enum {
LAVEUSE_ARRET,
LAVEUSE_REMPLISSAGE,
LAVEUSE_LAVAGE,
LAVEUSE_RINCAGE,
LAVEUSE_ESSORAGE,
LAVEUSE_TERMINEE,
LAVEUSE_ERREUR
} WMState;
typedef struct {
WMState etat; // Indique l'état de la machine
double depuis; // timestamp de l'evenement
bool ack; // Evenement acquitté ?
} WashingMachineState;
WashingMachineState traiteMessage(char *message);
void timestampToDate(double timestamp, char* dateStr, size_t dateStrSize);
WashingMachineState getEtatMachine();
void getEtatMachineStr(WashingMachineState wms, char* etat, size_t etatSize);
void acknoledge();

View File

@ -0,0 +1,75 @@
#include <stdio.h>
#include <cJSON.h>
#include <esp_log.h>
#include "washingMachineState.h"
#include <time.h>
#define TAG "WMS"
WashingMachineState wms;
WashingMachineState traiteMessage(char* message){
cJSON *root = cJSON_Parse(message);
char* json = cJSON_PrintUnformatted(root);
ESP_LOGE(TAG, "%s", json);
bool state = cJSON_IsTrue(cJSON_GetObjectItem(root, "state"));
double timestamp = cJSON_GetNumberValue(cJSON_GetObjectItem(root, "timestamp"));
bool ack = cJSON_HasObjectItem(root,"ack") && cJSON_GetNumberValue(cJSON_GetObjectItem(root,"ack"));
//char dateStr[80] ;
//timestampToDate(timestamp,dateStr,80);
wms.etat = state?LAVEUSE_LAVAGE:LAVEUSE_ARRET;
wms.depuis = timestamp;
wms.ack = ack;
cJSON_Delete(root);
return wms;
}
void timestampToDate(double timestamp, char* dateStr, size_t dateStrSize)
{
time_t ts = timestamp;
struct tm *pTime = localtime(&ts);
strftime(dateStr, dateStrSize, "%d/%m/%Y %H:%M:%S", pTime);
//printf("Date and french time : %s\n", dateStr);
}
WashingMachineState getEtatMachine(){
return wms;
}
void getEtatMachineStr(WashingMachineState wms, char* etat, size_t etatSize)
{
char* etatStr;
switch (wms.etat)
{
case LAVEUSE_ARRET:
/* code */
etatStr="Machine arretée";
break;
case LAVEUSE_LAVAGE:
/* code */
etatStr="Machine en route";
break;
default:
etatStr="Etat inconnu";
break;
}
char dateStr[30];
timestampToDate(wms.depuis,dateStr,30);
snprintf(etat,etatSize,"%s depuis %s", etatStr, dateStr);
ESP_LOGE(TAG,"%s",etat);
}
void acknoledge(){
wms.ack=true;
}

View File

@ -14,7 +14,7 @@ if(${IDF_TARGET} STREQUAL "esp32p4")
elseif(${IDF_TARGET} STREQUAL "linux")
message(STATUS "Linux Mode --> main standard")
list(APPEND comps vfs esp_http_server)
idf_component_register(SRCS main.c
idf_component_register(SRCS main.c communication.c
INCLUDE_DIRS "./include"
REQUIRES ${comps}
EMBED_TXTFILES ${PROJECT_DIR}/main/ca_cert.pem

View File

@ -2,9 +2,147 @@
#include "esp_log.h"
#include "mqtt_client.h"
#include "stateManagement.h"
#if CONFIG_IDF_TARGET_ESP32P4
#include "esp_wifi.h"
#endif
#include "esp_log.h"
/* FreeRTOS event group to signal when we are connected*/
static EventGroupHandle_t s_wifi_event_group;
/* The event group allows multiple bits for each event, but we only care about two events:
* - we are connected to the AP with an IP
* - we failed to connect after the maximum amount of retries */
#define BIT0 0x00000001
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
#define EXAMPLE_ESP_WIFI_SSID "wifimms3"
#define EXAMPLE_ESP_WIFI_PASS "mmswifi0611"
#define EXAMPLE_ESP_MAXIMUM_RETRY 5
#define ESP_WIFI_SAE_MODE WPA3_SAE_PWE_BOTH
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK
static int s_retry_num = 0;
wifi_callback cb;
#if CONFIG_IDF_TARGET_ESP32P4
#define BIT0 0x00000001
static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
{
esp_wifi_connect();
}
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
{
if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY)
{
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "retry to connect to the AP");
}
else
{
//xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
}
cb(WIFI_DISCONNECTED);
ESP_LOGI(TAG, "connect to the AP fail");
}
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
{
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
cb(WIFI_CONNECTED);
//xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
}
void wifi_init_sta(wifi_callback callback)
{
cb=callback;
//s_wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_netif_init());
//ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&wifi_event_handler,
NULL,
&instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
IP_EVENT_STA_GOT_IP,
&wifi_event_handler,
NULL,
&instance_got_ip));
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_ESP_WIFI_SSID,
.password = EXAMPLE_ESP_WIFI_PASS,
/* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (pasword len => 8).
* If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value
* to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to
* WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards.
*/
.threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,
.sae_pwe_h2e = ESP_WIFI_SAE_MODE,
.sae_h2e_identifier = "",
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "wifi_init_sta finished.");
/*
// Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
// number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above)
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
pdFALSE,
pdFALSE,
portMAX_DELAY);
// xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
// happened.
if (bits & WIFI_CONNECTED_BIT)
{
cb(CONNECTED);
}
else if (bits & WIFI_FAIL_BIT)
{
cb(CONNECT_FAIL);
ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
}
else
{
ESP_LOGE(TAG, "UNEXPECTED EVENT");
}
*/
}
#else
#include <time.h>
int64_t esp_timer_get_time(void)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (int64_t)ts.tv_sec * 1000000LL + ts.tv_nsec / 1000;
}
#endif
esp_mqtt_client_handle_t client;
@ -196,127 +334,3 @@ void mqtt_app_start(mqtt_callback callback, EventGroupHandle_t domotic_event_gro
}
/* FreeRTOS event group to signal when we are connected*/
static EventGroupHandle_t s_wifi_event_group;
/* The event group allows multiple bits for each event, but we only care about two events:
* - we are connected to the AP with an IP
* - we failed to connect after the maximum amount of retries */
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
#define EXAMPLE_ESP_WIFI_SSID "wifimms3"
#define EXAMPLE_ESP_WIFI_PASS "mmswifi0611"
#define EXAMPLE_ESP_MAXIMUM_RETRY 5
#define ESP_WIFI_SAE_MODE WPA3_SAE_PWE_BOTH
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK
static int s_retry_num = 0;
wifi_callback cb;
static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
{
esp_wifi_connect();
}
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
{
if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY)
{
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "retry to connect to the AP");
}
else
{
//xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
}
cb(WIFI_DISCONNECTED);
ESP_LOGI(TAG, "connect to the AP fail");
}
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
{
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
cb(WIFI_CONNECTED);
//xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
}
void wifi_init_sta(wifi_callback callback)
{
cb=callback;
//s_wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_netif_init());
//ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&wifi_event_handler,
NULL,
&instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
IP_EVENT_STA_GOT_IP,
&wifi_event_handler,
NULL,
&instance_got_ip));
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_ESP_WIFI_SSID,
.password = EXAMPLE_ESP_WIFI_PASS,
/* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (pasword len => 8).
* If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value
* to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to
* WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards.
*/
.threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,
.sae_pwe_h2e = ESP_WIFI_SAE_MODE,
.sae_h2e_identifier = "",
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "wifi_init_sta finished.");
/*
// Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
// number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above)
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
pdFALSE,
pdFALSE,
portMAX_DELAY);
// xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
// happened.
if (bits & WIFI_CONNECTED_BIT)
{
cb(CONNECTED);
}
else if (bits & WIFI_FAIL_BIT)
{
cb(CONNECT_FAIL);
ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
}
else
{
ESP_LOGE(TAG, "UNEXPECTED EVENT");
}
*/
}

View File

@ -894,6 +894,8 @@ void app_main(void)
//start_wifi_logger();
#endif
mqtt_app_start(mqtt_cb, domotic_event_group);
TaskHandle_t xHandle = NULL;
BaseType_t ret1;
/*ret1 = xTaskCreate(&imgdwn, "imageDownload_task", 3 * 1024, domotic_event_group, 5, &xHandle);