1.1.0: begin(username, password, rootTopic) - the library signature now matches every example, the readme and the website (as published since 2024 no sketch could authenticate: the 64-hex password became the MQTT username). Discovery answers go out over MQTT directly, every device, resumed from loop() under heap pressure within the backend's 5 s window, instead of the 5-slot HTTP queue that silently dropped the rest (which the backend's reconcile then deleted from Alexa). JSON aligned with Alexa / alex2node: event.payload present, ActionMapping payload an object, semantics only when a capability has mappings. Pointer-stable device/capability containers (std::deque), the MQTT payload is copied by length before parsing (no write past the buffer), fragmented directive ids are ignored (a Discover is answered on its first fragment), deprecated ArduinoJson 7 calls replaced, credential Serial prints removed, ESP32 include guards (untested; the ESP8266 is the target). Examples: WIFI_PASSWORD, LED_BUILTIN fallback, string+int print fixes. library.json + library.properties restored (1.1.0; AsyncMqttClient, ArduinoJson 7, ESP Async TCP), LICENSE (MIT), a real keywords.txt, .gitattributes text=auto eol=lf (tree normalised to LF). readme: Forgejo URLs, platformio.ini snippet, Library Manager install, begin() order, INTERIOR_BLIND for blinds, 1.1.0 changelog. All five examples compile warning-free for d1_mini (PlatformIO 6.2, espressif8266) on pve-B450.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
David 2026-09-28 04:58:38 +00:00
parent 1313f47856
commit 87caad25be
20 changed files with 3117 additions and 2782 deletions

View file

@ -1,104 +1,115 @@
/*
* @title Alex2ESP Library
* @version 1.0.0
* @author David
* @license MIT
* @contributors chaos511
*
* @description The Alex2ESP library is a companion to the Alex2MQTT Alexa Skill,
* providing seamless integration between ESP-based devices and the Alex2MQTT server.
* This library connects to alex2mqtt.stormysdream.club, where the skill is hosted,
* allowing your devices to communicate effortlessly with the Alexa Voice Service
* using MQTT as the backbone.
*/
#ifndef ALEX2ESP_H
#define ALEX2ESP_H
class AlexaDevice;
#include <Arduino.h>
#include <AsyncMqttClient.h>
#include <ArduinoJson.h>
#include "AlexaDevice.h"
#include <AlexaInterface.h>
#include <vector>
#include <AlexaUtils.h>
#include <ESP8266HTTPClient.h>
enum class Alex2ESPState
{
UNINITIALIZED,
INITIALIZED,
CONNECTING,
SUBSCRIBING,
CONNECTED,
DISCONNECTED
};
class Alex2ESP
{
public:
// Constructor
Alex2ESP();
// Begin function for initialization
void begin(const char *rootTopic, const char *username, const char *password);
Alex2ESPState getState() const;
void loop();
AsyncMqttClientDisconnectReason getDisconnectReason() const;
AlexaDevice *getDevice(const String &name, const String &endpointId);
void messageSplitAndSend(String messagepackString, String topic);
private:
static const int MAX_RETRY_COUNT = 2; // Define maximum retry count
int retryCountPOST=0;
int retryCountGET=0;
boolean clearToSend=false;
AsyncMqttClient mqttClient; // MQTT client instance
String rootTopic; // Root topic for communication
String discoverTopic; // The topic we listen on for discovery messages
String discoverTopicSend; // The topic we send discovery messages
String TopicESP; // The topic we listen on for esp messages
const char *mqttUsername; // Username for authentication
const char *mqttPassword; // Password for authentication
unsigned long lastReconnectTime;
int reconnectAttempt;
HTTPClient httpGET;
HTTPClient httpPOST;
WiFiClient wifiGET;
WiFiClient wifiPOST;
JsonDocument inputDoc;
std::vector<AlexaDevice> devices; // Collection of devices
Alex2ESPState _state;
AsyncMqttClientDisconnectReason _disconnectReason;
// MQTT connection details
const char *mqttServer = "alex2mqtt.stormysdream.club";
uint16_t mqttPort = 1883;
// Internal event handlers
void onMqttConnect(bool sessionPresent);
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason);
void onSubscribe(uint16_t packetId, uint8_t qos);
void onMessage(char *topic, char *payload, AsyncMqttClientMessageProperties properties, size_t length, size_t index, size_t total);
//loop processing function
void handleMqttReconnection();
void processHttpPost();
void processHttpGet();
};
#endif // ALEX2ESP_H
/*
* @title Alex2ESP Library
* @version 1.1.0
* @author David
* @license MIT
* @contributors chaos511
*
* @description The Alex2ESP library is a companion to the Alex2MQTT Alexa Skill,
* providing seamless integration between ESP-based devices and the Alex2MQTT server.
* This library connects to alex2mqtt.stormysdream.club, where the skill is hosted,
* allowing your devices to communicate effortlessly with the Alexa Voice Service
* using MQTT as the backbone.
*/
#ifndef ALEX2ESP_H
#define ALEX2ESP_H
#include <Arduino.h>
#include <AsyncMqttClient.h>
#include <ArduinoJson.h>
#include "AlexaDevice.h"
#include "AlexaInterface.h"
#include "AlexaUtils.h"
#include <deque>
#ifdef ESP32
#include <HTTPClient.h> // ESP32: untested
#else
#include <ESP8266HTTPClient.h>
#endif
enum class Alex2ESPState
{
UNINITIALIZED,
INITIALIZED,
CONNECTING,
SUBSCRIBING,
CONNECTED,
DISCONNECTED
};
class Alex2ESP
{
public:
// Constructor
Alex2ESP();
// Begin function for initialization: MQTT username, MQTT password, root topic (the same order as alex2node)
void begin(const char *username, const char *password, const char *rootTopic);
Alex2ESPState getState() const;
void loop();
AsyncMqttClientDisconnectReason getDisconnectReason() const;
// Returns the device with this endpointId, creating it on first use. The pointer stays valid for the lifetime
// of the client: devices live in a std::deque, which never relocates its elements when another one is added.
AlexaDevice *getDevice(const String &name, const String &endpointId);
private:
static const int MAX_RETRY_COUNT = 2; // Define maximum retry count
static const unsigned long DISCOVERY_WINDOW_MS = 5000; // How long the backend keeps collecting a discovery answer
int retryCountPOST=0;
int retryCountGET=0;
size_t discoveryNext = 0; // Next device to announce while a discovery answer is still going out
bool discoveryPending = false; // publishDiscovery() stopped early (client out-queue full); loop() finishes it
unsigned long discoveryStarted = 0; // millis() when the Discover arrived
boolean clearToSend=false;
AsyncMqttClient mqttClient; // MQTT client instance
String rootTopic; // Root topic for communication
String discoverTopic; // The topic we listen on for discovery messages
String discoverTopicSend; // The topic we send discovery messages
String TopicESP; // The topic we listen on for esp messages
const char *mqttUsername; // Username for authentication
const char *mqttPassword; // Password for authentication
unsigned long lastReconnectTime;
int reconnectAttempt;
HTTPClient httpGET;
HTTPClient httpPOST;
WiFiClient wifiGET;
WiFiClient wifiPOST;
JsonDocument inputDoc;
std::deque<AlexaDevice> devices; // Collection of devices (deque: pointers handed out by getDevice stay valid)
Alex2ESPState _state;
AsyncMqttClientDisconnectReason _disconnectReason;
// MQTT connection details
const char *mqttServer = "alex2mqtt.stormysdream.club";
uint16_t mqttPort = 1883;
// Internal event handlers
void onMqttConnect(bool sessionPresent);
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason);
void onSubscribe(uint16_t packetId, uint8_t qos);
void onMessage(char *topic, char *payload, AsyncMqttClientMessageProperties properties, size_t length, size_t index, size_t total);
//loop processing function
void handleMqttReconnection();
void publishDiscovery();
void finishDiscovery();
void processHttpPost();
void processHttpGet();
};
#endif // ALEX2ESP_H