Alex2Node/examples/doorbell.js
David dd071548bc 2.0.0
The interface registry, generated and checked discovery, typed dispatch with
automatic error answers, message builders, proactive events and typed
helpers for every error type; the 1.x API is kept and the examples of 1.5.2
run unchanged. docs/wire-changes.md lists what a 1.x caller can observe.

On 2026-09-28 a real Alexa account drove 33 test devices on this API through
the public Alex2MQTT service: Alexa accepted the discovery of all of them,
50 of 58 cases passed, 4 had no action in the control call and 4 failed on
what the check could see, none on an answer of the library. The readme table
names the interfaces that run covered. Voice commands were not tested yet.

307 tests.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-28 22:55:23 +00:00

40 lines
1.9 KiB
JavaScript

// A doorbell: Alexa.DoorbellEventSource. It takes no directive and reports no state of the button;
// device.raise() says that somebody rang. Press Enter to ring.
//
// The event is published to <root>/event, which the Alex2MQTT service passes on to Alexa. Alexa wants 30 seconds
// between two presses of one doorbell.
//
// ALEX2MQTT_USERNAME=... ALEX2MQTT_PASSWORD=... ALEX2MQTT_ROOT_TOPIC=... node examples/doorbell.js
//
// "alex2node" is the installed package; inside this checkout it resolves to the built dist/.
const { Alex2MQTT, DoorbellEventSource } = require("alex2node");
const missing = ["ALEX2MQTT_USERNAME", "ALEX2MQTT_PASSWORD", "ALEX2MQTT_ROOT_TOPIC"].filter((name) => !process.env[name]);
if (missing.length > 0) {
console.error(`${missing.join(", ")} not set. Set the MQTT user name, the password and the root topic of your Alex2MQTT account.`);
process.exit(1);
}
const { ALEX2MQTT_USERNAME, ALEX2MQTT_PASSWORD, ALEX2MQTT_ROOT_TOPIC } = process.env;
const bridge = new Alex2MQTT(ALEX2MQTT_USERNAME, ALEX2MQTT_PASSWORD, ALEX2MQTT_ROOT_TOPIC);
bridge.on("connect", () => console.log("connected, discover the devices in the Alexa app"));
bridge.on("error", (err) => console.error("bridge:", err.message));
const device = bridge.addDevice({ endpointId: "front-doorbell", name: "Front Doorbell", categories: ["DOORBELL"] });
device.add(DoorbellEventSource);
device.state((s) => s.health("OK"));
let rangAt = 0;
process.stdin.on("data", async () => {
if (Date.now() - rangAt < 30000) {
console.log("not sent: the last press is less than 30 seconds ago");
return;
}
rangAt = Date.now();
// raise() throws for an event the device did not declare, and resolves with what became of the publish
const result = await device.raise(DoorbellEventSource, "DoorbellPress");
console.log(result.ok ? "the press was sent" : `not sent: ${result.error.message}`);
});
bridge.connect();