Alex2ESP/examples/README.md
David c3d02f462e Announce a doorbell with proactivelyReported and a scene with supportsDeactivation
An interface without properties says beside its name what Alexa has to know
of it; the library left both out. With a board and Alexa on 2026-09-28 the
discovery of a doorbell was accepted (202), the endpoint was not listed, and
its DoorbellPress was answered with 500 INTERNAL_SERVICE_EXCEPTION.

DoorbellEventSource now always carries "proactivelyReported": true.
SceneController carries "supportsDeactivation", false until the sketch calls
setSupportsDeactivation(true); on another interface the call is refused and
logged. The Scene example says that it can be undone.

148 host tests. Light: static RAM 30,616 B, flash 332,705 B (+140 B).

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

112 lines
5.9 KiB
Markdown

# Examples
One folder per kind of device. Every sketch is complete: Wi-Fi, the MQTT session, one device (MultiDevice: two) with
its own endpoint id and name, and one handler for its directives.
| Sketch | Device | Interfaces | Endpoint id |
|---|---|---|---|
| [Light](Light/Light.ino) | a lamp, on and off | PowerController | `esp-light` |
| [DimmableLight](DimmableLight/DimmableLight.ino) | a lamp with PWM brightness | PowerController, BrightnessController | `esp-dimmable-light` |
| [ColorTemperatureLight](ColorTemperatureLight/ColorTemperatureLight.ino) | a lamp with a warm and a cold channel, 2200 K to 7000 K | PowerController, BrightnessController, ColorTemperatureController | `esp-white-light` |
| [ColorLight](ColorLight/ColorLight.ino) | an RGB lamp | PowerController, BrightnessController, ColorController | `esp-color-light` |
| [TemperatureSensor](TemperatureSensor/TemperatureSensor.ino) | a thermometer; a ChangeReport after a change of more than 0.5 degrees, at most one a minute | TemperatureSensor | `esp-temperature` |
| [ContactSensor](ContactSensor/ContactSensor.ino) | a door contact on a GPIO; a ChangeReport on every change | ContactSensor | `esp-contact` |
| [Blind](Blind/Blind.ino) | a blind with a position of 0 to 100 and the words open, close, raise, lower | RangeController `Blind.Lift` with semantics | `esp-blind` |
| [Thermostat](Thermostat/Thermostat.ino) | HEAT, COOL, AUTO and OFF, one setpoint or two, the errors of the thermostat | ThermostatController, TemperatureSensor | `esp-thermostat` |
| [Lock](Lock/Lock.ino) | a bolt that takes 3 s: DeferredResponse, then the answer from `loop()` | LockController | `esp-lock` |
| [Scene](Scene/Scene.ino) | a scene that switches two outputs | SceneController | `esp-scene` |
| [Doorbell](Doorbell/Doorbell.ino) | a button on a GPIO; DoorbellPress on every press | DoorbellEventSource | `esp-doorbell` |
| [MultiDevice](MultiDevice/MultiDevice.ino) | two lamps, two endpoints, one handler | PowerController | `esp-multi-left`, `esp-multi-right` |
Every device announces EndpointHealth as well and reports `connectivity` with its state.
The sketches in [`legacy/`](legacy/) are the examples of 1.x, unchanged. They use `registerEvent()` and the
`Add...Prop()` names and are kept to show that a 1.x sketch compiles against 2.0. New sketches start from the ones
above.
## Before flashing
Fill in the five constants at the top of the sketch: the Wi-Fi network and the MQTT user name, password and root
topic of your Alex2MQTT account.
```cpp
const char *WIFI_SSID = "";
const char *WIFI_PASSWORD = "";
const char *ALEXA_USERNAME = "";
const char *ALEXA_PASSWORD = "";
const char *ALEXA_ROOT_TOPIC = "";
```
Two boards with the same endpoint id on one account are one device to Alexa. Change the id and the name in
`getDevice()` when you flash a sketch a second time.
Each sketch names the pins it uses by GPIO number, with the label of the Wemos D1 mini in a comment. The serial
output is at 74880 baud.
## Wi-Fi
`connectWiFi()` waits for the network for 30 s at the most. Without a connection it prints the status and the two
constants to check, and the sketch carries on: the ESP8266 keeps trying to join, and `alexa.loop()` opens the MQTT
session once Wi-Fi is up.
## Building
Arduino IDE: a sketch is a folder with an `.ino` of the same name, which is how the IDE opens it.
PlatformIO: copy the `.ino` into `src/` of a project that has the library in `lib_deps`, or make the folder of the
sketch the source directory of the project (`src_dir`, or the environment variable of the same meaning). In a
project with a `d1_mini` environment and the library:
```
PLATFORMIO_SRC_DIR=/path/to/Alex2ESP/examples/Light pio run -e d1_mini
```
This is how the sizes below were built. The sketches define every function before it is used and include `Arduino.h`, so they are also valid as a `.cpp`
file.
## Size
Static RAM and flash as PlatformIO reports them for `d1_mini` (espressif8266 4.2.1, Arduino core 3.1.2,
AsyncMqttClient 0.9.0, ArduinoJson 7.4.3), built from this folder as committed, with empty credentials and the default
log level. A D1 mini has 81,920 bytes of RAM; what is not static is the heap.
| Sketch | Static RAM (bytes) | Flash (bytes) |
|---|---:|---:|
| Light | 30,616 | 332,565 |
| DimmableLight | 30,692 | 336,765 |
| ColorTemperatureLight | 30,808 | 337,489 |
| ColorLight | 30,748 | 338,657 |
| TemperatureSensor | 30,572 | 333,213 |
| ContactSensor | 30,584 | 332,861 |
| Blind | 30,860 | 336,525 |
| Thermostat | 31,044 | 337,517 |
| Lock | 30,648 | 333,441 |
| Scene | 30,640 | 333,277 |
| Doorbell | 30,584 | 333,013 |
| MultiDevice | 30,672 | 332,725 |
| legacy/basicLight | 30,520 | 333,989 |
| legacy/lightWithBrightness | 30,648 | 337,929 |
| legacy/lightWithColorTemp | 30,828 | 338,653 |
| legacy/tempSensor | 30,412 | 332,781 |
| legacy/blindControl | 30,568 | 335,261 |
## What has been tried
The sketches of this folder were compiled with PlatformIO, with 0 warnings. They have not been built with the
Arduino IDE and have not run on a board yet. What each announces
in discovery is checked by the host tests in `test/test_examples`.
With this library on a Wemos D1 mini, a real Alexa account and other sketches (2026-09-28), Alexa discovered and
drove PowerController, BrightnessController, ColorTemperatureController and one instance each of ToggleController,
RangeController and ModeController. Not tried with Alexa from this library: ColorController, ThermostatController,
LockController and the deferred answer, SceneController, the ChangeReports and DoorbellPress. Voice commands have
not been tried.
## Limits
- Doorbell, ContactSensor: an event or a change while there is no session with the broker is not sent later.
- Lock: the answer after the DeferredResponse is sent once. If the session is lost while the bolt moves, Alexa gets
the state with its next ReportState.
- Blind, Scene, Thermostat, the lamps: the state is kept in RAM and starts from the values in the sketch after a
reset.