Alex2Node/CHANGELOG.md
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

118 lines
5.9 KiB
Markdown

# Changelog
The format is that of [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the versions follow
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.0.0] - 2026-09-28
Every call of 1.5.2 is kept. What a 1.x program can observe is under "Changed", and
[docs/wire-changes.md](docs/wire-changes.md) has each row with the test that pins it.
### Added
- A registry that describes each Alexa interface as data: version, properties, directives, events, options. 32
interfaces are described, 39 are named with the version 1.5.2 announced. The readme has the table.
- Discovery is written from the registry. `bridge.addDevice()` and `device.add()` throw a `DeclarationError` for
what Alexa would reject, and `device.check()` lists it for a device declared the 1.x way.
- RangeController, ModeController and ToggleController with instances, friendly names from `asset()` and `text()`,
presets, and `semantics()` for open, close, raise and lower.
- Handlers: `capability.on()`, `device.onDirective()`, `device.onReportState()`, with `ctx.respond()`,
`ctx.report()`, `ctx.defer()` and `ctx.error()`. `device.state()` gives the context of every answer.
- `device.changeReport(cause, fill)` for a ChangeReport, and `device.raise()` for DoorbellPress and the events of
SimpleEventSource and WakeOnLANController, published to `<root>/event`.
- `AlexaError`, and `AlexaErrors` with a function for each of the 73 error types.
- Message builders under `messages`, and `StateBuilder`.
- `MemoryPublisher`, the `publisher` option and `bridge.receive()`, to test a device without a broker.
- The options `alexaInterface`, `answerWithinMs` and `answerUnknownEndpoints`; the events `unanswered` and
`unknownEndpoint`.
- An ES module build next to the CommonJS one, each with its declarations.
- One example file for each recipe on the 2.0 API. The examples of 1.5.2 are in `examples/legacy`.
### Changed
- Node.js 18 is the oldest version the package runs on.
- Discovery lists the `Alexa` interface on every endpoint. Alexa is told of every endpoint once more.
- `Alexa.EndpointHealth` is announced with version `3.1`, not `3.3`.
- Speaker, StepSpeaker, EqualizerController, PlaybackController, PlaybackStateReporter, InputController,
ChannelController, LockController, MotionSensor and PowerLevelController are announced with the version and the
properties of their interface.
- `addSupportedModes()` with strings announces `{ value }` objects, with a warning.
- `new ActionMapping()` with a string as payload parses a JSON string, with a warning, and throws for another.
- The bridge subscribes to `<root>/discover` and `<root>/+/alexaDirective`, not to `<root>/#`.
- A directive or a discovery request with the `messageId` of one of the last 60 seconds is dropped.
- A second answer for one `correlationToken` is refused.
- A directive that nothing answers is answered with `INTERNAL_ERROR` after 6.5 seconds.
- A listener that throws or rejects answers the directive with `INTERNAL_ERROR`, and the `error` event has what
was thrown.
- A directive for a device without a listener or a handler is answered with `INVALID_DIRECTIVE`.
- An ErrorResponse goes under the namespace its type is documented under, not always under `Alexa`.
- `getErrorMessage(token).send()` without `setErrorMessage()` sends `INTERNAL_ERROR`, not an empty payload.
- A ChangeReport without a changed property is not published. A property that changed is not listed in the
context as well.
- A DeferredResponse has no `context` key, and a ChangeReport no empty `correlationToken`.
- `registerDevice()` before `connect()` returns the device.
- The fourth argument of `new AlexaStatusMessage()` and `new AlexaErrorResponse()` is a `Publisher`, not the mqtt
client.
- `uuid` is no longer a dependency.
### Deprecated
- The client argument of `new Device(client, ...)`: it is ignored, with a warning once. Removed in 3.0.
- `device.setMqttClient()`: it does nothing, with a warning once. Removed in 3.0.
## [1.5.2] - 2026-09-28
### Added
- Type declarations ship with the package.
- A LICENSE file (MIT).
### Changed
- `send()` never rejects: it resolves with the topic, or with `""` when the publish failed, and the error goes to
the `error` event of the bridge.
- `registerDevice()` with an endpointId that is registered returns the existing device, with a warning.
- ThermostatController discovery lists `targetSetpoint` and no longer `adaptiveRecoveryStatus`.
- An interface without a property list is noted through the log hook, not printed to stderr.
### Fixed
- Devices registered before `disconnect()` publish through the connection of the next `connect()`.
- The examples: `require("alex2node")`, an `error` listener in each, the correlationToken read from the header in
BlindControl, Fahrenheit reported as Fahrenheit in the thermostat.
## 1.5.1 - 2026-09-22
### Added
- The events `connect`, `offline`, `reconnect` and `close`, and `bridge.connected`.
- The options `host`, `mqtt` and `log`.
- `device.getChangeReport(cause)`, published to `<root>/changeReport`.
- SceneController in discovery, and `device.sendSceneResponse()`.
- `addCapability(type, { retrievable, proactivelyReported, instance })`.
- `unregisterDevice()`, `clearDevices()`, `getDevices()`, `getDevice()`, `disconnect()`, the events `discover` and
`directive`, and `lastDiscoveryAt`.
- Tests against a broker in the test process.
### Changed
- `send()` returns a promise and no longer logs to the console.
### Fixed
- A broker that is away no longer ends the process: `error` is emitted only when there is a listener.
## 1.5.0
As it was published to npm. It came into this repository on 2026-09-22.
### Changed
- The power example reports brightness and mode.
## Before 1.5.0
Not tagged in this repository. The history has the initial release on 2025-04-20, and in May 2025 the thermostat,
deferred responses, error responses, the `error` event, ModeController and ToggleController.
[1.5.2]: https://git.stormysdream.club/apps/Alex2Node/src/tag/v1.5.2