Examples

Connect a device to Alex2MQTT — pick your platform below to see a working example.

Steps to Configure Your Account

  1. Install the Alex2MQTT skill and link it to your Amazon account.
  2. Visit /MQTT_Credentials to retrieve your MQTT username, password, and root topic.

Connecting to MQTT

Once you have the MQTT credentials, you can connect to the server using any standard MQTT client and listen for events. Most MQTT events are sent directly from Amazon's API to ensure compatibility with the latest devices.

Additional Resources

For more information on specific device payloads, refer to Amazon's device APIs documentation.

Example Code

Choose a platform to see how to expose a device.

Using the Alex2ESP library, version 2.0, for the ESP8266 (Arduino / PlatformIO; it has not been tried on an ESP32). Add the library and its two dependencies to platformio.ini (the repo is not in the PlatformIO registry yet):

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

The library's examples/Light/Light.ino: one lamp that answers TurnOn, TurnOff and ReportState. Fill in your Wi-Fi SSID/password and the three values from /MQTT_Credentials; the serial monitor runs at 74880 baud. Directives and answers travel over MQTT only.

// Light: a lamp that Alexa switches on and off (Alexa.PowerController).
//
// The lamp is the on-board LED. One handler gets every directive of the device: it answers ReportState with the
// state of the lamp, carries out TurnOn and TurnOff, and refuses anything else.
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Alex2ESP.h>

// Wi-Fi and the credentials of your Alex2MQTT account
const char *WIFI_SSID = "";
const char *WIFI_PASSWORD = "";

const char *ALEXA_USERNAME = "";
const char *ALEXA_PASSWORD = "";
const char *ALEXA_ROOT_TOPIC = "";

// The on-board LED: GPIO2 on a Wemos D1 mini, lit when the pin is low
#ifndef LED_BUILTIN
#define LED_BUILTIN 2
#endif

Alex2ESP alexa;
bool lampOn = false;

// Joins the Wi-Fi network and returns after 30 s at the latest. Without a connection the sketch carries on: the
// ESP8266 keeps trying, and alexa.loop() opens the MQTT session once Wi-Fi is up.
void connectWiFi()
{
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.printf("\n[WIFI] Connecting to \"%s\"\n", WIFI_SSID);

  unsigned long started = millis();
  while (WiFi.status() != WL_CONNECTED && millis() - started < 30000)
  {
    delay(100);
  }

  if (WiFi.status() == WL_CONNECTED)
  {
    Serial.printf("[WIFI] Connected, IP address %s\n", WiFi.localIP().toString().c_str());
  }
  else
  {
    Serial.printf("[WIFI] No connection after 30 s (status %d): check WIFI_SSID and WIFI_PASSWORD. Still trying.\n",
                  WiFi.status());
  }
}

// The state of the lamp: what the answer to a directive and the answer to ReportState carry
void sendState(AlexaStatusMessage message)
{
  message.addHealthProp(EndpointHealth::OK)
      .addPowerControllerProp(lampOn ? PowerController::ON : PowerController::OFF)
      .send();
}

void onDirective(AlexaDirective &directive)
{
  if (directive.isReportState())
  {
    sendState(directive.stateReport());
    return;
  }

  if (directive.type == AlexaInterfaceType::POWER_CONTROLLER && (directive.is("TurnOn") || directive.is("TurnOff")))
  {
    lampOn = directive.is("TurnOn");
    digitalWrite(LED_BUILTIN, lampOn ? LOW : HIGH);
    sendState(directive.response());
    return;
  }

  directive.error(AlexaErrorType::INVALID_DIRECTIVE, "This lamp switches on and off").send();
}

void setup()
{
  Serial.begin(74880);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);

  connectWiFi();

  // MQTT user name, MQTT password, root topic
  alexa.begin(ALEXA_USERNAME, ALEXA_PASSWORD, ALEXA_ROOT_TOPIC);

  // The name Alexa shows, and the id of the endpoint: every device of an account has its own
  AlexaDevice *lamp = alexa.getDevice("Desk Lamp", "esp-light");
  lamp->setDisplayCategory(DisplayCategory::LIGHT);
  lamp->addCapability(AlexaInterfaces::PowerController);
  lamp->addCapability(AlexaInterfaces::EndpointHealth);
  lamp->onDirective(onDirective);
}

void loop()
{
  alexa.loop();
}