connect via MQTTS

Signed-off-by: Peter Siegmund <developer@mars3142.org>
This commit is contained in:
2026-01-25 02:15:05 +01:00
parent e01006cd49
commit 81141d8859
22 changed files with 246 additions and 8 deletions

View File

@@ -5,3 +5,5 @@ include($ENV{IDF_PATH}/tools/cmake/project.cmake)
idf_build_set_property(BOOTLOADER_EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_LIST_DIR}/bootloader_components_extra/" APPEND)
project(system_control)
target_add_binary_data(${PROJECT_NAME}.elf "main/isrgrootx1.pem" TEXT)

View File

@@ -3,4 +3,6 @@ idf_component_register(
INCLUDE_DIRS "include"
PRIV_REQUIRES
persistence-manager
my_mqtt_client
app_update
)

View File

@@ -1,9 +1,14 @@
#include "message_manager.h"
#include "my_mqtt_client.h"
#include <esp_app_desc.h>
#include <esp_log.h>
#include <esp_mac.h>
#include <esp_system.h>
#include <freertos/FreeRTOS.h>
#include <freertos/queue.h>
#include <freertos/task.h>
#include <persistence_manager.h>
#include <sdkconfig.h>
#include <string.h>
#define MESSAGE_QUEUE_LENGTH 16
@@ -98,6 +103,15 @@ static void message_manager_task(void *param)
message_listeners[i](&msg);
}
}
uint8_t mac[6];
esp_read_mac(mac, ESP_MAC_WIFI_STA);
const esp_app_desc_t *app_desc = esp_app_get_description();
char topic[60];
snprintf(topic, sizeof(topic), "device/%s/%02x%02x", app_desc->project_name, mac[4], mac[5]);
char *data = "{\"key\":\"value\"}";
mqtt_client_publish(topic, data, strlen(data), 0, false);
}
}
}

View File

@@ -0,0 +1,7 @@
idf_component_register(
SRCS "src/my_mqtt_client.c"
INCLUDE_DIRS "include"
REQUIRES
mqtt
app_update
)

View File

@@ -0,0 +1,21 @@
menu "MQTT Client Settings"
config MQTT_CLIENT_BROKER_URL
string "MQTT Broker URL (TLS)"
default "mqtts://example.com:8883"
help
Die Adresse des MQTT-Brokers (z.B. mqtts://broker.example.com:8883)
config MQTT_CLIENT_USERNAME
string "MQTT Username"
default "user"
help
Benutzername für die Authentifizierung (optional)
config MQTT_CLIENT_PASSWORD
string "MQTT Password"
default "password"
help
Passwort für die Authentifizierung (optional)
endmenu

View File

@@ -0,0 +1,18 @@
# MQTT Client Component for ESP-IDF
Diese Komponente stellt eine einfache MQTT-Client-Implementierung bereit, die Daten an einen TLS-gesicherten MQTT-Broker sendet.
## Dateien
- mqtt_client.c: Implementierung des MQTT-Clients
- mqtt_client.h: Header-Datei
- CMakeLists.txt: Build-Konfiguration
- Kconfig: Konfiguration für die Komponente
## Abhängigkeiten
- ESP-IDF (empfohlen: >= v4.0)
- Komponenten: esp-mqtt, esp-tls
## Nutzung
1. Füge die Komponente in dein Projekt ein.
2. Passe die Konfiguration in `Kconfig` an.
3. Binde die Komponente in deinem Code ein und nutze die API aus `mqtt_client.h`.

View File

@@ -0,0 +1,2 @@
dependencies:
espressif/mqtt: ^1.0.0

View File

@@ -0,0 +1,14 @@
#pragma once
#include <stdbool.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
void mqtt_client_start(void);
void mqtt_client_publish(const char *topic, const char *data, size_t len, int qos, bool retain);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,122 @@
#include "my_mqtt_client.h"
#include "esp_app_desc.h"
#include "esp_err.h"
#include "esp_interface.h"
#include "esp_log.h"
#include "esp_mac.h"
#include "esp_system.h"
#include "mqtt_client.h"
#include "sdkconfig.h"
static const char *TAG = "mqtt_client";
static esp_mqtt_client_handle_t client = NULL;
extern const uint8_t isrgrootx1_pem_start[] asm("_binary_isrgrootx1_pem_start");
extern const uint8_t isrgrootx1_pem_end[] asm("_binary_isrgrootx1_pem_end");
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
esp_mqtt_event_handle_t event = event_data;
int msg_id;
switch ((esp_mqtt_event_id_t)event_id)
{
case MQTT_EVENT_CONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
msg_id = esp_mqtt_client_subscribe(client, "topic/qos0", 0);
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
msg_id = esp_mqtt_client_subscribe(client, "topic/qos1", 1);
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
msg_id = esp_mqtt_client_unsubscribe(client, "topic/qos1");
ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
break;
case MQTT_EVENT_SUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d, return code=0x%02x ", event->msg_id, (uint8_t)*event->data);
msg_id = esp_mqtt_client_publish(client, "topic/qos0", "data", 0, 0, 0);
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
break;
case MQTT_EVENT_UNSUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_PUBLISHED:
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_DATA:
ESP_LOGI(TAG, "MQTT_EVENT_DATA:");
ESP_LOGI(TAG, "TOPIC=%.*s\r\n", event->topic_len, event->topic);
ESP_LOGI(TAG, "DATA=%.*s\r\n", event->data_len, event->data);
break;
case MQTT_EVENT_ERROR:
ESP_LOGE(TAG, "MQTT_EVENT_ERROR");
if (event->error_handle)
{
ESP_LOGE(TAG, "error_type: %d", event->error_handle->error_type);
ESP_LOGE(TAG, "esp-tls error code: 0x%x", event->error_handle->esp_tls_last_esp_err);
ESP_LOGE(TAG, "tls_stack_err: 0x%x", event->error_handle->esp_tls_stack_err);
ESP_LOGE(TAG, "transport_sock_errno: %d", event->error_handle->esp_transport_sock_errno);
}
break;
default:
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
break;
}
}
void mqtt_client_start(void)
{
ESP_LOGI(TAG, "Starte MQTT-Client mit URI: %s", CONFIG_MQTT_CLIENT_BROKER_URL);
uint8_t mac[6];
esp_read_mac(mac, ESP_MAC_WIFI_STA);
const esp_app_desc_t *app_desc = esp_app_get_description();
char client_id[60];
snprintf(client_id, sizeof(client_id), "%s/%02x%02x", app_desc->project_name, mac[4], mac[5]);
const esp_mqtt_client_config_t mqtt_cfg = {
.broker.address.uri = CONFIG_MQTT_CLIENT_BROKER_URL,
.broker.verification.certificate = (const char *)isrgrootx1_pem_start,
.broker.verification.certificate_len = isrgrootx1_pem_end - isrgrootx1_pem_start,
.credentials.username = CONFIG_MQTT_CLIENT_USERNAME,
.credentials.client_id = client_id,
.credentials.authentication.password = CONFIG_MQTT_CLIENT_PASSWORD,
};
client = esp_mqtt_client_init(&mqtt_cfg);
if (client == NULL)
{
ESP_LOGE(TAG, "Fehler bei esp_mqtt_client_init!");
return;
}
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
esp_err_t err = esp_mqtt_client_start(client);
if (err != ESP_OK)
{
ESP_LOGE(TAG, "esp_mqtt_client_start fehlgeschlagen: %s", esp_err_to_name(err));
}
else
{
ESP_LOGI(TAG, "MQTT-Client gestartet");
}
}
void mqtt_client_publish(const char *topic, const char *data, size_t len, int qos, bool retain)
{
if (client)
{
int msg_id = esp_mqtt_client_publish(client, topic, data, len, qos, retain);
ESP_LOGI(TAG, "Publish: topic=%s, msg_id=%d, qos=%d, retain=%d, len=%d", topic, msg_id, qos, retain, (int)len);
}
else
{
ESP_LOGW(TAG, "Publish aufgerufen, aber Client ist nicht initialisiert!");
}
}

View File

@@ -372,7 +372,8 @@ void start_simulation_task(void)
{
stop_simulation_task();
simulation_config_t *config = (simulation_config_t *)heap_caps_malloc(sizeof(simulation_config_t), 0);
simulation_config_t *config =
(simulation_config_t *)heap_caps_malloc(sizeof(simulation_config_t), MALLOC_CAP_DEFAULT);
if (config == NULL)
{
ESP_LOGE(TAG, "Failed to allocate memory for simulation config.");

View File

@@ -1,10 +1,10 @@
idf_component_register(SRCS
main.cpp
app_task.cpp
button_handling.c
i2c_checker.c
hal/u8g2_esp32_hal.c
INCLUDE_DIRS "."
src/main.cpp
src/app_task.cpp
src/button_handling.c
src/i2c_checker.c
src/hal/u8g2_esp32_hal.c
INCLUDE_DIRS "include"
PRIV_REQUIRES
analytics
insa
@@ -21,6 +21,7 @@ idf_component_register(SRCS
app_update
rmaker_common
driver
my_mqtt_client
)
spiffs_create_partition_image(storage ../storage FLASH_IN_PROJECT)

View File

@@ -0,0 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----

View File

@@ -8,6 +8,7 @@
#include "i2c_checker.h"
#include "led_status.h"
#include "message_manager.h"
#include "my_mqtt_client.h"
#include "persistence_manager.h"
#include "simulator.h"
#include "ui/ClockScreenSaver.h"
@@ -252,6 +253,8 @@ void app_task(void *args)
wifi_manager_init();
mqtt_client_start();
message_manager_register_listener(on_message_received);
start_simulation();

View File

@@ -7,7 +7,7 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "u8g2_esp32_hal.h"
#include "hal/u8g2_esp32_hal.h"
static const char *TAG = "u8g2_hal";
static const unsigned int I2C_TIMEOUT_MS = 1000;