Alex2Node/docs/wire-changes.md
David f0ca4c1fa4 docs: wire-changes.md, what a 1.x caller can observe in 2.0
The table of DESIGN 6.1 with what the work since added: 26 rows in four
groups (discovery, messages, directives, calls and types), each with the
behaviour of 1.5.2, the one of 2.0, what to do and the test that pins it.
Three rows are pinned by no test and say so: the order of the keys in the
JSON text and the two toJSON() types.
One change of the design is listed as not done: the 1.x temperature
helpers do not round the converted Celsius value.
The file feeds the migration section of the readme and the changelog.

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

7.7 KiB

What a 1.x caller can observe in 2.0

Every call shape of 1.5.2 is kept. This file lists what behaves differently: on the wire, in what a call returns, and in the types. It is the source of the migration section of the readme and of the 2.0.0 changelog. "Test" names the file under test/ that pins the row; a row with - is pinned by none.

The topics are unchanged: <root>/discover, <root>/discover_r, <root>/<endpointId>/alexaDirective, <root>/<endpointId>/alexaResponce, <root>/<endpointId>/deferredResponse, <root>/changeReport.

Discovery

Change 1.5.2 2.0 What to do Test
The Alexa interface is announced not listed every endpoint ends with { "type": "AlexaInterface", "interface": "Alexa", "version": "3" }, which Amazon requires a test that compares the capability list gets one more entry; new Alex2MQTT(..., { alexaInterface: false }) leaves it out. Alexa is told of every endpoint once more device/discovery.test.js
Version of Alexa.EndpointHealth 3.3 3.1, the version of the interface page nothing discovery.test.js
Interfaces that 1.5.2 announced with version 1 or with no property Alexa.Speaker, Alexa.StepSpeaker, Alexa.EqualizerController, Alexa.PlaybackController, Alexa.PlaybackStateReporter, Alexa.InputController, Alexa.ChannelController: version 1 and no property; Alexa.LockController, Alexa.MotionSensor, Alexa.PowerLevelController: no property the version and the properties of the interface page a caller that replaced getJSON() to correct the capability can drop the replacement; a replaced getJSON() is still what discovery lists registry/entertainment.test.js, device/discovery.test.js, compat/capabilities.test.js
addSupportedModes(["a", "b"]) the strings were announced as they were [{ "value": "a" }, { "value": "b" }], and a warning through the log hook pass { value, modeResources } device/discovery.test.js
new ActionMapping(actions, name, payload) with a string as payload the string was announced, quoted a JSON string is parsed, with a warning through the log hook; any other string throws a DeclarationError pass the object compat/capabilities.test.js
A discovery request that arrives twice answered twice a request with the messageId of one that came in the last 60 s is dropped; a request without a messageId is answered every time nothing transport.test.js
What Alexa would reject in a declaration published as declared published as declared, and each problem is logged once through the log hook at discovery; device.check() returns the lines read the log after the first discovery device/validate.test.js

Messages

Change 1.5.2 2.0 What to do Test
DeferredResponse "context": null no context key nothing compat/messages.test.js
ChangeReport header "correlationToken": "" no correlationToken nothing; the backend builds its own header compat/messages.test.js
ChangeReport without a changed property published, and dropped by the backend not published: send() resolves "" and the error event names the endpoint add the changed property before unchanged(); send no report when nothing changed compat/messages.test.js
A property that is both changed and in the context of a ChangeReport listed in both listed in payload.change.properties only nothing messages/build.test.js
Namespace of an ErrorResponse always Alexa the namespace the error type is documented under: THERMOSTAT_IS_OFF goes under Alexa.ThermostatController, UNAUTHORIZED under Alexa.SecurityPanelController, OBSTACLE_DETECTED under Alexa.Safety setErrorMessage(type, message, extra, { namespace }) names another compat/messages.test.js, messages/errors.test.js
getErrorMessage(token).send() without setErrorMessage() an ErrorResponse with an empty payload INTERNAL_ERROR with the message "the device answered with an error and did not say which" call setErrorMessage() compat/messages.test.js
Order of the keys in the JSON text context before event event before context compare the parsed message, not its text -

Directives

Change 1.5.2 2.0 What to do Test
Subscriptions <root>/# <root>/discover and <root>/+/alexaDirective nothing; the log hook no longer sees what the bridge itself published subscriptions.test.js
A second answer for one correlationToken published refused: send() resolves "" and the error event says the directive was answered before. One DeferredResponse and one answer after it pass answer once dispatch/dispatch.test.js
A directive that arrives twice handled twice a directive with the messageId of one that came for the endpoint in the last 60 s is dropped nothing dispatch/dispatch.test.js
A directive nothing answers Alexa waits until the backend gives up after 7 s INTERNAL_ERROR after 6.5 s, and the bridge emits unanswered and error answer in the listener, or send a DeferredResponse first; answerWithinMs: 0 turns it off dispatch/dispatch.test.js
A listener that throws or rejects the exception left the library and could end the process the directive is answered with INTERNAL_ERROR and the error event carries what was thrown nothing dispatch/dispatch.test.js
A directive for a device with no Event or ReportState listener and no handler no answer INVALID_DIRECTIVE. A device with a 1.x listener keeps the answer to itself nothing dispatch/dispatch.test.js

Calls and types

Change 1.5.2 2.0 What to do Test
registerDevice() before connect() threw returns the device; what it sends before the bridge is connected resolves "" and the error event says to call connect() nothing connection.test.js
new Device(client, ...) the device published through client client is ignored. A client that is not null is reported once: through the log hook of the bridge, or as a DeprecationWarning with the code ALEX2NODE_DEVICE_CLIENT make the device with addDevice() or registerDevice(), or set device.publisher. Removed in 3.0 compat/deprecations.test.js
device.setMqttClient(client) gave the device the client of a new connection does nothing, and says so once (code ALEX2NODE_SET_MQTT_CLIENT): the devices of a bridge publish over disconnect() and connect() without it remove the call. Removed in 3.0 compat/deprecations.test.js
new AlexaStatusMessage(token, root, endpointId, client, ...), new AlexaErrorResponse(token, root, endpointId, client) the fourth argument was the mqtt client it is a Publisher: an object with publish(topic, message) that resolves { ok, topic, error? } build the messages with device.getStatusMessage(), getErrorMessage() and getChangeReport(), which are unchanged compat/messages.test.js
Type of AlexaStatusMessage.toJSON() { event: any; context: { properties } | null } { event: any; context?: { properties } } read context as optional -
Type of AlexaErrorResponse.toJSON() { event: any } ErrorResponseMessage, typed down to the payload nothing -
capability.on(name, handler) without a function - throws a DeclarationError that says what it got 2.0 API only dispatch/dispatch.test.js

In the design, not in the code

Change State
addThermostatControllerProp and addTemperatureSensorProp round the converted Celsius value to two decimals not done: 68 °F is sent as 20, 70 °F as 21.11111111111111, as in 1.5.2