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>
This commit is contained in:
parent
b083b23ab0
commit
f0ca4c1fa4
1 changed files with 61 additions and 0 deletions
61
docs/wire-changes.md
Normal file
61
docs/wire-changes.md
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
# 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 |
|
||||||
Loading…
Add table
Add a link
Reference in a new issue