Alex2ESP firmware — imported with full history from github.com/chaos511/Alex2ESP (2026-09-18)
Find a file
David 87caad25be 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>
2026-09-28 04:58:38 +00:00
examples 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. 2026-09-28 04:58:38 +00:00
src 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. 2026-09-28 04:58:38 +00:00
.gitattributes 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. 2026-09-28 04:58:38 +00:00
.gitignore initial release 2024-12-18 16:44:06 -06:00
keywords.txt 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. 2026-09-28 04:58:38 +00:00
library.json 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. 2026-09-28 04:58:38 +00:00
library.properties 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. 2026-09-28 04:58:38 +00:00
LICENSE 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. 2026-09-28 04:58:38 +00:00
readme.md 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. 2026-09-28 04:58:38 +00:00

Alex2ESP

Alex2ESP is a lightweight Arduino/PlatformIO library for integrating ESP8266 microcontrollers with Amazon Alexa smart home APIs through the Alex2MQTT skill. The library simplifies the process of creating Alexa-compatible devices using MQTT.

Supported target: ESP8266 (developed and tested on a Wemos D1 mini). ESP32: untested - the code carries include guards for it, but it has never been compiled or run there.

For more details on how to configure Alex2ESP, visit Alex2MQTT Documentation.


Features

  • Supports "All" Alexa smart home capabilities.
  • Provides action mapping for advanced directive customization including Open,Close,Raise,and Lower commands.
  • Allows custom JSON injection in both discovery and state reporting to allow for unsupported devices.
  • Event-driven architecture for handling Alexa directives.

Alternatives

one of the most popular library for controlling esp like devices using alexa is FauxmoESP however FauxmoESP works by emulating a light bulb so it is limited in what commands it accepts.


Quick Start

Installation

The library lives on Forgejo at https://git.stormysdream.club/platformio/Alex2ESP (public). It is not in the PlatformIO registry or the Arduino Library Manager: install it from git.

PlatformIO

[env:d1_mini]
platform = espressif8266
board = d1_mini
framework = arduino
monitor_speed = 74880
lib_deps =
    https://git.stormysdream.club/platformio/Alex2ESP.git
    marvinroger/AsyncMqttClient@^0.9.0
    bblanchon/ArduinoJson@^7

To pin a release instead of main, append the tag: https://git.stormysdream.club/platformio/Alex2ESP.git#v1.1.0. AsyncMqttClient pulls in ESPAsyncTCP by itself; if PlatformIO notes that more than one ESPAsyncTCP package matches, add esp32async/ESPAsyncTCP@^2.0.0 to lib_deps to pick one explicitly. The examples print at 74880 baud, the ESP8266 boot-ROM rate, so the boot messages stay readable in the same monitor.

Arduino IDE

Download the repository as a ZIP (https://git.stormysdream.club/platformio/Alex2ESP/archive/main.zip) and add it with Sketch -> Include Library -> Add .ZIP Library. Install AsyncMqttClient, ArduinoJson (7.x) and ESP Async TCP (by ESP32Async) from the Library Manager. Install the ESP8266 board package and select your board (for example LOLIN(WEMOS) D1 R2 & mini).

Then include the library in your project:

#include <Alex2ESP.h>

Complete sketches are in examples/: basicLight.cpp, lightWithBrightness.cpp, lightWithColorTemp.cpp, tempSensor.cpp and blindControl.cpp. Every example joins Wi-Fi with WiFi.begin(WIFI_SSID, WIFI_PASSWORD); fill in the SSID, the password and your Alex2MQTT credentials before flashing.


Creating a Basic Device

Example: Light Control

Here’s how to create a simple device that controls a light:

First create an instance of the alexa client and initilize it with your MQTT Credentials

Alex2ESP alexClient;

Credentials can be found at https://alex2mqtt.stormysdream.club/ after logging in with amazon. begin() takes the MQTT username, the MQTT password and the root topic, in that order (the same order as alex2node's new Alex2MQTT(username, password, rootTopic)).

  alexClient.begin(ALEXA_USERNAME, ALEXA_PASSWORD, ALEXA_ROOT_TOPIC);

Once initilized you can begin to add virtual devices, in this example we add a power controller to toggle a light


  AlexaDevice* device1 = alexClient.getDevice("Test Lamp", "ESP-01");
  device1->setDisplayCategory(DisplayCategory::LIGHT);
  device1->addCapability(AlexaInterfaceType::POWER_CONTROLLER);

  device1->registerEvent("ReportState", [](const JsonDocument& directive, const AlexaInterfaceType& type) {
    // Build and send status report
    device1->buildStatusMessage(directive["header"]["correlationToken"])
      .AddHealthProp(EndpointHealth::OK)
      .AddPowerControllerProp(outputState)
      .send();
  });

  // Register event listener for "Event" directive to handle state changes
  device1->registerEvent("Event", [](const JsonDocument& directive, const AlexaInterfaceType& type) {
    if (type == AlexaInterfaceType::POWER_CONTROLLER) {
      if (directive["header"]["name"] == "TurnOn") {
        outputState = PowerController::ON;
        Serial.println("Turning ON");
      } else if (directive["header"]["name"] == "TurnOff") {
        outputState = PowerController::OFF;
        Serial.println("Turning OFF");
      }

      // Send the updated state after change
      device1->buildStatusMessage(directive["header"]["correlationToken"], true)
        .AddHealthProp(EndpointHealth::OK)
        .AddPowerControllerProp(outputState)
        .send();
    }
  });

The pointers returned by getDevice() and addCapability() stay valid for the lifetime of the client, so keeping them in globals and adding more devices or capabilities later is fine.


Example: Toggle Controller for Blinds

Alex2ESP also supports action mapping so we can map keywords such as "open" and "close" to a toggle controller For a comprehensive list of Alexa actions and mappings, visit the Alexa Developer Documentation

AlexaDevice* device = alexClient.getDevice("Bedroom Blinds", "ESP-01");
device->setDisplayCategory(DisplayCategory::INTERIOR_BLIND);

AlexaInterface* toggleController = device->addCapability(AlexaInterfaceType::TOGGLE_CONTROLLER);
toggleController->setInstance("ESP-01.Toggle");
toggleController->addFriendlyName("Bedroom Blinds", "en-US");

ActionMapping closeMapping({AlexaActions::Close}, "TurnOn");
ActionMapping openMapping({AlexaActions::Open}, "TurnOff");
toggleController->addActionMapping(closeMapping);
toggleController->addActionMapping(openMapping);

An ActionMapping takes an optional third argument, the directive payload as JSON text (for example "{\"rangeValue\": 0}" for a RangeController). It is emitted as an object in the discovery response and omitted when empty.


How it talks to Alex2MQTT

  • Discovery. On <root>/discover the library answers with one discovery object per device, published straight to <root>/discover_r over MQTT (no HTTP round trip, no queue slot). The backend accepts one endpoint object per message and collects everything that arrives within 1 s for Alexa's discovery answer (up to 5 s for its proactive AddOrUpdate push), so all devices are published back to back the moment the request arrives. Each object sits on the heap (about 1 KB) until the broker acknowledges it; when the MQTT client refuses another one (free heap under 4 KB), the library prints [Alex2ESP] discovery publish deferred at <endpointId> and sends the rest from loop() as the queue drains, for up to 5 s after the request. [Alex2ESP] discovery gave up: N device(s) not announced means those devices missed this answer - on the backend's proactive discovery that can remove them from Alexa until the next one.
  • Directives. A directive arrives as a short id on <root>/<endpointId>/alexaDirective_e; the library fetches the full directive over HTTP, fires ReportState or Event (and DirectiveReceived, if registered), and your status report is queued for an HTTP POST that the backend republishes on <root>/<endpointId>/alexaResponce, replacing {REPLACE_WITH_DATETIME} with the current time.
  • Limits. The send queue holds 5 reports of up to 2047 bytes each. send() returns false and prints a [Alex2ESP] line on Serial when a report does not fit or the queue is full; nothing is ever sent truncated. Debug logging of the library's internals is compiled in by defining Alex2ESP_DEBUG in AlexaUtils.cpp; credentials are never printed.

Interface Types

Alexa Interface Type Status
AlexaInterfaceType::ENDPOINT_HEALTH Fully Supported
AlexaInterfaceType::POWER_CONTROLLER Fully Supported
AlexaInterfaceType::BRIGHTNESS_CONTROLLER Fully Supported
AlexaInterfaceType::TOGGLE_CONTROLLER Fully Supported
AlexaInterfaceType::TEMPERATURE_SENSOR Fully Supported
AlexaInterfaceType::COLOR_TEMPERATURE_CONTROLLER Fully Supported
AlexaInterfaceType::AUTOMATION_MANAGEMENT Supported*
AlexaInterfaceType::CHANNEL_CONTROLLER Supported*
AlexaInterfaceType::COLOR_CONTROLLER Supported*
AlexaInterfaceType::CONTACT_SENSOR Supported*
AlexaInterfaceType::APPLICATION_STATE_REPORTER Supported*
AlexaInterfaceType::AUDIO_PLAY_QUEUE Supported*
AlexaInterfaceType::AUTHORIZATION_CONTROLLER Supported*
AlexaInterfaceType::AUTOMOTIVE_VEHICLE_DATA Supported*
AlexaInterfaceType::CAMERA_LIVE_VIEW_CONTROLLER Supported*
AlexaInterfaceType::CAMERA_STREAM_CONTROLLER Supported*
AlexaInterfaceType::COMMISSIONABLE Supported*
AlexaInterfaceType::CONSENT_MANAGEMENT_CONSENT_REQUIRED_REPORTER Supported*
AlexaInterfaceType::COOKING Supported*
AlexaInterfaceType::DATA_CONTROLLER Supported*
AlexaInterfaceType::DEVICE_USAGE_ESTIMATION Supported*
AlexaInterfaceType::DEVICE_USAGE_METER Supported*
AlexaInterfaceType::DOORBELL_EVENT_SOURCE Supported*
AlexaInterfaceType::EQUALIZER_CONTROLLER Supported*
AlexaInterfaceType::INPUT_CONTROLLER Supported*
AlexaInterfaceType::INVENTORY_LEVEL_SENSOR Supported*
AlexaInterfaceType::INVENTORY_LEVEL_USAGE_SENSOR Supported*
AlexaInterfaceType::INVENTORY_USAGE_SENSOR Supported*
AlexaInterfaceType::KEYPAD_CONTROLLER Supported*
AlexaInterfaceType::LAUNCHER Supported*
AlexaInterfaceType::LOCK_CONTROLLER Supported*
AlexaInterfaceType::MEDIA_PLAYBACK Supported*
AlexaInterfaceType::MEDIA_SEARCH Supported*
AlexaInterfaceType::MODE_CONTROLLER Supported*
AlexaInterfaceType::MOTION_SENSOR Supported*
AlexaInterfaceType::PERCENTAGE_CONTROLLER Supported*
AlexaInterfaceType::PLAYBACK_CONTROLLER Supported*
AlexaInterfaceType::PLAYBACK_STATE_REPORTER Supported*
AlexaInterfaceType::PROACTIVE_NOTIFICATION_SOURCE Supported*
AlexaInterfaceType::RANGE_CONTROLLER Supported*
AlexaInterfaceType::RECORD_CONTROLLER Supported*
AlexaInterfaceType::REMOTE_VIDEO_PLAYER Supported*
AlexaInterfaceType::RTC_SESSION_CONTROLLER Supported*
AlexaInterfaceType::SCENE_CONTROLLER Supported*
AlexaInterfaceType::SECURITY_PANEL_CONTROLLER Supported*
AlexaInterfaceType::SEEK_CONTROLLER Supported*
AlexaInterfaceType::SIMPLE_EVENT_SOURCE Supported*
AlexaInterfaceType::SMART_VISION_OBJECT_DETECTION_SENSOR Supported*
AlexaInterfaceType::SMART_VISION_SNAPSHOT_PROVIDER Supported*
AlexaInterfaceType::SPEAKER Supported*
AlexaInterfaceType::STEP_SPEAKER Supported*
AlexaInterfaceType::THERMOSTAT_CONTROLLER Supported*
AlexaInterfaceType::THERMOSTAT_CONTROLLER_CONFIGURATION Supported*
AlexaInterfaceType::THERMOSTAT_CONTROLLER_HVAC_COMPONENTS Supported*
AlexaInterfaceType::THERMOSTAT_CONTROLLER_SCHEDULE Supported*
AlexaInterfaceType::TIME_HOLD_CONTROLLER Supported*
AlexaInterfaceType::UI_CONTROLLER Supported*
AlexaInterfaceType::USER_PREFERENCE Supported*
AlexaInterfaceType::VIDEO_RECORDER Supported*
AlexaInterfaceType::WAKE_ON_LAN_CONTROLLER Supported*

(*Partial support or limited implementation advanced configuration is required)


Advanced usage

For devices with limited or partial support, Alex2ESP provides functions that allow you to attach custom JSON objects to the status report. For example, to report the status of a PowerController type, you can use the AddPowerControllerProp function. However, if a specific "add props" function does not exist for your use case, you can utilize the AddContextProp function to pass a custom JSON object.

For instance, to manually report the state of a PowerController, you can use the following code:

    JsonDocument doc;

    doc["namespace"] = "Alexa.PowerController";
    doc["name"] = "powerState";
    doc["value"] = "ON";
    doc["timeOfSample"] = "{REPLACE_WITH_DATETIME}"; // Alex2MQTT server wil do the replace
    doc["uncertaintyInMilliseconds"] = 0;
    AddContextProp(doc.as<JsonObject>())

Changelog

1.1.0

Behaviour changes:

  • begin() now takes (username, password, rootTopic), the order every example and this readme always used (and the order alex2node uses). 1.0.0 declared (rootTopic, username, password), so a sketch written from the examples could not authenticate with the broker.
  • Discovery answers go straight to MQTT (<root>/discover_r), one object per device, all devices at once; if the MQTT client cannot take another object (free heap under 4 KB) the rest is sent from loop() as the client's queue drains, for up to 5 s. 1.0.0 pushed them one per loop() through a 5-slot HTTP queue and silently dropped the sixth device onwards, which the backend then removed from Alexa.
  • AlexaStatusMessage::send() returns bool: an oversized report (over 2047 bytes) or a full queue is reported on Serial and dropped instead of being sent truncated. AlexaUtils::enqueue() refuses packets that would not fit instead of truncating them.
  • Discovery JSON: semantics is emitted only when a capability has action mappings; an ActionMapping directive payload is emitted as a JSON object (parsed from the text you pass) or omitted when empty, instead of the string "{}".
  • Response/StateReport events include the required "payload": {}.
  • Devices and capabilities are stored in std::deque; pointers from getDevice()/addCapability() no longer dangle once another device or capability is added.
  • The MQTT payload is copied using its length (no write past the client's buffer); fragmented directive ids are ignored (a Discover is answered on its first fragment, its payload is unused).
  • begin() no longer prints the MQTT credentials to Serial in debug builds.
  • DirectiveReceived no longer prints "No event registered" when the sketch has not registered it.
  • Removed: Alex2ESP::messageSplitAndSend (declared, never defined) and AlexaStatusMessage::setEndpointId (did nothing).
  • Reported softwareVersion/firmwareVersion in the discovery attributes are now 1.1.0.

Examples: WiFi.begin(WIFI_SSID, WIFI_PASSWORD) (1.0.0 could only join open networks), LED_BUILTIN fallback, fixed brightness/colour-temperature Serial output, blinds use DisplayCategory::INTERIOR_BLIND.

Packaging: library.json and library.properties restored with the Forgejo URL and the dependencies, LICENSE (MIT), a real keywords.txt, LF line endings (.gitattributes), ArduinoJson 7 deprecated calls replaced (warning-free build). ESP8266 is the supported target; ESP32 is untested.


Contributing

Feel free to submit pull requests or issues for feature requests and bug fixes.


License

This project is licensed under the MIT License. See the LICENSE file for details.