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>
108 lines
7.2 KiB
JavaScript
108 lines
7.2 KiB
JavaScript
// Interfaces without a descriptor of their own. A stub names the interface with the version and the properties
|
|
// alex2node 1.5.2 put in discovery, so an endpoint that declares one is announced as before. Nothing about it is
|
|
// checked, and the version is the one 1.5.2 sent, which is not always the one on the page of the interface
|
|
// (Alexa.Speaker is "3" there). A row leaves this table when a descriptor is written from that page.
|
|
import { s } from "../schema.js";
|
|
const DEVICE_APIS = "https://developer.amazon.com/docs/alexaplus/device-apis";
|
|
const LIST_OF_INTERFACES = `${DEVICE_APIS}/list-of-interfaces.html`;
|
|
// "As of August 7, 2026, Automotive skills and the associated Alexa.AuthorizationController and
|
|
// Alexa.Automotive.VehicleData APIs are no longer available."
|
|
const DEPRECATED_FEATURES = "https://developer.amazon.com/en-US/docs/alexa/ask-overviews/deprecated-features.html";
|
|
const TABLE = [
|
|
["Alexa.ApplicationStateReporter", "1", [], "https://developer.amazon.com/docs/alexaplus/alexa-voice-service/alexa-applicationstatereporter.html"],
|
|
["Alexa.Audio.PlayQueue", "1", [], "alexa-audio-playqueue.html"],
|
|
["Alexa.AuthorizationController", "1", [], DEPRECATED_FEATURES],
|
|
["Alexa.AutomationManagement", "1", ["automationStatuses"], "alexa-automationmanagement.html"],
|
|
["Alexa.Automotive.VehicleData", "1", [], DEPRECATED_FEATURES],
|
|
// 1.5.2 announced the version "UNKNOWN"; 1.7 is what the list of interfaces gives
|
|
["Alexa.Camera.LiveViewController", "1.7", [], LIST_OF_INTERFACES],
|
|
["Alexa.CameraStreamController", "3", [], "alexa-camerastreamcontroller.html"],
|
|
["Alexa.ChannelController", "3", ["channel"], "alexa-channelcontroller.html"],
|
|
["Alexa.ColorController", "3", ["color"], "alexa-colorcontroller.html"],
|
|
["Alexa.ColorTemperatureController", "3", ["colorTemperatureInKelvin"], "alexa-colortemperaturecontroller.html"],
|
|
["Alexa.Commissionable", "1", [], "alexa-commissionable.html"],
|
|
["Alexa.ConsentManagement.ConsentRequiredReporter", "1", [], "alexa-consentrequiredreporter.html"],
|
|
["Alexa.ContactSensor", "3", ["detectionState"], "alexa-contactsensor.html"],
|
|
["Alexa.Cooking", "1", [], "alexa-cooking.html"],
|
|
["Alexa.Cooking.FoodTemperatureController", "1", [], "alexa-cooking-foodtemperaturecontroller.html"],
|
|
["Alexa.Cooking.FoodTemperatureSensor", "1", [], "alexa-cooking-foodtemperaturesensor.html"],
|
|
["Alexa.Cooking.PresetController", "1", [], "alexa-cooking-presetcontroller.html"],
|
|
["Alexa.Cooking.TemperatureController", "1", [], "alexa-cooking-temperaturecontroller.html"],
|
|
["Alexa.Cooking.TemperatureSensor", "1", [], "alexa-cooking-temperaturesensor.html"],
|
|
["Alexa.Cooking.TimeController", "1", [], "alexa-cooking-timecontroller.html"],
|
|
["Alexa.DataController", "1", [], "alexa-datacontroller.html"],
|
|
["Alexa.DeviceUsage.Estimation", "1", [], "alexa-deviceusage-estimation.html"],
|
|
["Alexa.DeviceUsage.Meter", "1", [], "alexa-deviceusage-meter.html"],
|
|
["Alexa.DoorbellEventSource", "3", [], "alexa-doorbelleventsource.html"],
|
|
["Alexa.EqualizerController", "1", [], "alexa-equalizercontroller.html"],
|
|
["Alexa.InputController", "3", [], "alexa-inputcontroller.html"],
|
|
["Alexa.InventoryLevelSensor", "1", [], "alexa-inventorylevelsensor.html"],
|
|
["Alexa.InventoryLevelUsageSensor", "1", [], "alexa-inventorylevelusagesensor.html"],
|
|
["Alexa.InventoryUsageSensor", "1", [], "alexa-inventoryusagesensor.html"],
|
|
["Alexa.KeypadController", "1", [], "alexa-keypadcontroller.html"],
|
|
["Alexa.Launcher", "1.1", [], "alexa-launcher.html"],
|
|
["Alexa.LockController", "3", [], "alexa-lockcontroller.html"],
|
|
["Alexa.Media.PlayQueue", "1", [], "alexa-media-playqueue.html"],
|
|
["Alexa.Media.Playback", "1", [], "alexa-media-playback.html"],
|
|
["Alexa.Media.Search", "1", [], "alexa-media-search.html"],
|
|
["Alexa.MotionSensor", "3", [], "alexa-motionsensor.html"],
|
|
["Alexa.PercentageController", "3", [], "alexa-percentagecontroller.html"],
|
|
["Alexa.PlaybackController", "3", [], "alexa-playbackcontroller.html"],
|
|
["Alexa.PlaybackStateReporter", "1", [], "alexa-playbackcontroller.html"],
|
|
["Alexa.PowerLevelController", "3", [], "alexa-powerlevelcontroller.html"],
|
|
["Alexa.ProactiveNotificationSource", "1", [], "alexa-proactivenotificationsource.html"],
|
|
["Alexa.RTCSessionController", "1", [], "alexa-rtcsessioncontroller.html"],
|
|
["Alexa.RecordController", "3", [], "alexa-recordcontroller.html"],
|
|
["Alexa.RemoteVideoPlayer", "1", [], "alexa-remotevideoplayer.html"],
|
|
["Alexa.SceneController", "3", [], "alexa-scenecontroller.html"],
|
|
["Alexa.SecurityPanelController", "1", [], "alexa-securitypanelcontroller.html"],
|
|
["Alexa.SecurityPanelController.Alert", "1", [], "alexa-securitypanelcontroller-alert.html"],
|
|
["Alexa.SeekController", "3", [], "alexa-seekcontroller.html"],
|
|
["Alexa.SimpleEventSource", "1", [], "alexa-simpleeventsource.html"],
|
|
["Alexa.SmartVision.ObjectDetectionSensor", "1", [], "alexa-smartvision-objectdetectionsensor.html"],
|
|
["Alexa.SmartVision.SnapshotProvider", "1", [], "alexa-smartvision-snapshotprovider.html"],
|
|
["Alexa.Speaker", "1", [], "alexa-speaker.html"],
|
|
["Alexa.StepSpeaker", "1", [], "alexa-stepspeaker.html"],
|
|
["Alexa.ThermostatController", "3.2", ["targetSetpoint", "lowerSetpoint", "upperSetpoint", "thermostatMode"], "alexa-thermostatcontroller.html"],
|
|
["Alexa.ThermostatController.Configuration", "1", [], "alexa-thermostatcontroller-configuration.html"],
|
|
["Alexa.ThermostatController.HVAC.Components", "1", [], "alexa-thermostatcontroller-hvac-components.html"],
|
|
["Alexa.ThermostatController.Schedule", "1", [], "alexa-thermostatcontroller-schedule.html"],
|
|
// "UNKNOWN" in 1.5.2 as well; the page is titled "Interface 3"
|
|
["Alexa.TimeHoldController", "3", [], "alexa-timeholdcontroller.html"],
|
|
["Alexa.UIController", "1", [], "alexa-uicontroller.html"],
|
|
["Alexa.UserPreference", "1", [], "alexa-userpreference.html"],
|
|
["Alexa.VideoRecorder", "1", [], "alexa-videorecorder.html"],
|
|
["Alexa.WakeOnLANController", "1", [], "alexa-wakeonlancontroller.html"],
|
|
];
|
|
// What 1.5.2 added to the capability object of two of them
|
|
const EXTRAS = {
|
|
// No properties object; supportsDeactivation and proactivelyReported on the capability itself
|
|
"Alexa.SceneController": ({ proactivelyReported }) => ({
|
|
properties: false,
|
|
topLevel: { supportsDeactivation: true, proactivelyReported },
|
|
}),
|
|
"Alexa.ThermostatController": () => ({
|
|
configuration: { supportedModes: ["HEAT", "COOL", "AUTO", "OFF"], supportsScheduling: false },
|
|
}),
|
|
};
|
|
function kindOf(namespace) {
|
|
if (namespace.endsWith("Sensor"))
|
|
return "sensor";
|
|
if (namespace.endsWith("EventSource"))
|
|
return "eventSource";
|
|
return "controller";
|
|
}
|
|
function stub([namespace, version, properties, page]) {
|
|
return {
|
|
namespace,
|
|
version,
|
|
doc: page.startsWith("https://") ? page : `${DEVICE_APIS}/${page}`,
|
|
kind: kindOf(namespace),
|
|
tier: 3,
|
|
instanced: false,
|
|
properties: Object.fromEntries(properties.map((name) => [name, { name, value: s.unknown() }])),
|
|
directives: {},
|
|
discovery: EXTRAS[namespace],
|
|
};
|
|
}
|
|
export const STUBS = TABLE.map(stub);
|