// Doorbell: a button that tells Alexa when it is pressed (Alexa.DoorbellEventSource). // // The button connects the pin to ground; the internal pull-up makes the pin high while it is released. A level has // to hold for 50 ms before it counts. Every press publishes a DoorbellPress event on /event. A press while // there is no session with the broker is lost: the library prints why it was not sent. // // This event has not been tried with Alexa yet. #include #include #include // 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 = ""; const uint8_t BUTTON_PIN = 14; // D5 on a Wemos D1 mini const unsigned long DEBOUNCE_MS = 50; Alex2ESP alexa; AlexaDevice *doorbell; bool pressed = false; bool lastLevel = false; unsigned long lastEdge = 0; // 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()); } } void onDirective(AlexaDirective &directive) { if (directive.isReportState()) { directive.stateReport().addHealthProp(EndpointHealth::OK).send(); return; } directive.error(AlexaErrorType::INVALID_DIRECTIVE, "A doorbell takes no directives").send(); } void setup() { Serial.begin(74880); pinMode(BUTTON_PIN, INPUT_PULLUP); 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 doorbell = alexa.getDevice("Front Door Bell", "esp-doorbell"); doorbell->setDisplayCategory(DisplayCategory::DOORBELL); doorbell->addCapability(AlexaInterfaces::DoorbellEventSource); doorbell->addCapability(AlexaInterfaces::EndpointHealth); doorbell->onDirective(onDirective); } void loop() { alexa.loop(); bool level = digitalRead(BUTTON_PIN) == LOW; if (level != lastLevel) { lastLevel = level; lastEdge = millis(); } if (level != pressed && millis() - lastEdge >= DEBOUNCE_MS) { pressed = level; if (pressed) { Serial.println("[DOORBELL] pressed"); doorbell->doorbellPress().send(); } } }