The three generic controllers are described in full and leave the stub table (62 stubs remain). A declaration
takes an instance name, friendly names from text() and asset(), and the options of the interface: range, unit and
presets for a range; supportedModes and ordered for a mode; semantics() for all three, with actions mapped to
directives and states mapped to a value or a range of values.
Refused at device.add(), each with the endpoint, interface and instance in the message: no instance name or no
friendly name; an instance declared twice; a first friendly name or a phrase used by another capability of the
endpoint; a reserved word, an asset id that is not in the catalog; range.max not above range.min; a preset off the
precision grid or outside the range; fewer than two modes or a mode listed twice; a mapping to a directive the
interface does not have, to a payload that does not fit, to a mode that is not listed, to AdjustMode on modes
that are not ordered; SetEcoOn, SetEcoOff, EcoOn and EcoOff on anything but a toggle.
For 1.x callers: Alexa.RangeController lists rangeValue (1.5.2 sent supported: []); addSupportedModes() announces
a mode given as a string as { value } and notes it, and takes { ordered: false } as a second argument, the default
stays true as 1.5.2 sent it (device.add() defaults to false). Declared the 1.x way, the zoo fan and curtain give
the same JSON as before.
Tests: the zoo blind, whose range, unit and semantics were written by hand into the JSON of 1.5.2, is declared
with device.add() and equals that JSON plus the Alexa capability; five capability objects of Amazon's examples
are reproduced the same way. 27 examples of four pages added. npm test: 108 pass (was 85) in 10.5-11.3 s, also on
Node 18.20.8 and 20.20.2.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
101 lines
4.3 KiB
JavaScript
101 lines
4.3 KiB
JavaScript
"use strict";
|
|
// One entry per interface that is described in full: the page its examples were saved from (test/helpers/fixtures.js)
|
|
// and declarations that give capability objects of Amazon's discovery examples.
|
|
//
|
|
// namespace the interface
|
|
// page the page of the interface; test/fixtures/alexa-docs/<page>/ has its examples
|
|
// declared [{ options, example, page, n }]: device.add(descriptor, options) gives the n-th capability object of
|
|
// the interface in that discovery example. n counts from 0 and defaults to it, page defaults to the
|
|
// page of the interface. The pages of RangeController and ModeController fold their discovery
|
|
// examples away, so they were not saved: the range is taken from an example of the ToggleController
|
|
// page, and ModeController has none.
|
|
//
|
|
// test/registry/descriptors.test.js and test/device/discovery.test.js run the entries. The first one fails for a
|
|
// descriptor of tier 1 or 2 that has no entry.
|
|
const { asset, semantics, text } = require("alex2node");
|
|
|
|
const reported = { retrievable: true, proactivelyReported: true };
|
|
const inThreeLanguages = (english, spanish, french) => [text(english, "en-US"), text(spanish, "es-MX"), text(french, "fr-CA")];
|
|
|
|
module.exports = [
|
|
{ namespace: "Alexa", page: "alexa-interface", declared: [{ options: {}, example: "discovery" }] },
|
|
{ namespace: "Alexa.BrightnessController", page: "alexa-brightnesscontroller", declared: [{ options: reported, example: "discovery" }] },
|
|
{ namespace: "Alexa.EndpointHealth", page: "alexa-endpointhealth", declared: [{ options: reported, example: "discovery" }] },
|
|
{ namespace: "Alexa.ModeController", page: "alexa-modecontroller", declared: [] },
|
|
{ namespace: "Alexa.PowerController", page: "alexa-powercontroller", declared: [{ options: reported, example: "discovery" }] },
|
|
{
|
|
namespace: "Alexa.RangeController",
|
|
page: "alexa-rangecontroller",
|
|
declared: [{
|
|
page: "alexa-togglecontroller",
|
|
example: "discovery-range-and-toggle",
|
|
options: {
|
|
...reported,
|
|
instance: "SampleManufacturer.Fan.Speed",
|
|
friendlyNames: [asset("Alexa.Setting.FanSpeed"), ...inThreeLanguages("Speed", "Velocidad", "Vitesse")],
|
|
range: { min: 1, max: 10, precision: 1 },
|
|
presets: [
|
|
{
|
|
value: 10,
|
|
friendlyNames: [
|
|
asset("Alexa.Value.Maximum"), asset("Alexa.Value.High"), text("Highest"), text("Fast"), text("Alta", "es-MX"),
|
|
text("Élevée", "fr-CA"),
|
|
],
|
|
},
|
|
{
|
|
value: 1,
|
|
friendlyNames: [
|
|
asset("Alexa.Value.Minimum"), asset("Alexa.Value.Low"), text("Lowest"), text("Slow"), text("Baja", "es-MX"),
|
|
text("Faible", "fr-CA"),
|
|
],
|
|
},
|
|
],
|
|
},
|
|
}],
|
|
},
|
|
{ namespace: "Alexa.TemperatureSensor", page: "alexa-temperaturesensor", declared: [{ options: reported, example: "discovery" }] },
|
|
{
|
|
namespace: "Alexa.ToggleController",
|
|
page: "alexa-togglecontroller",
|
|
declared: [
|
|
{
|
|
example: "discovery-oven",
|
|
options: {
|
|
...reported,
|
|
nonControllable: false,
|
|
instance: "Oven.OvenLight",
|
|
friendlyNames: inThreeLanguages("Oven light", "Luz del horno", "Lumière du four"),
|
|
},
|
|
},
|
|
{
|
|
example: "discovery-oven",
|
|
n: 1,
|
|
options: {
|
|
...reported,
|
|
nonControllable: true,
|
|
instance: "Stovetop.ResidualHeat",
|
|
friendlyNames: inThreeLanguages("Stovetop is still hot", "Todavía está caliente", "Encore chaude"),
|
|
},
|
|
},
|
|
{
|
|
example: "discovery-semantics",
|
|
options: {
|
|
...reported,
|
|
instance: "GarbageCan.Lid",
|
|
friendlyNames: inThreeLanguages("Garbage can lid", "Tapa del bote de basura", "Couvercle de poubelle"),
|
|
semantics: semantics().action("Close", "TurnOff", {}).action("Open", "TurnOn", {}).state("Closed", "OFF").state("Open", "ON"),
|
|
},
|
|
},
|
|
{
|
|
example: "discovery-range-and-toggle",
|
|
options: {
|
|
...reported,
|
|
instance: "SampleManufacturer.Fan.Oscillate",
|
|
friendlyNames: [
|
|
asset("Alexa.Setting.Oscillate"), text("Rotate"), text("Rotation"), text("Girar", "es-MX"), text("Rotation", "fr-CA"),
|
|
],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
];
|