Six descriptors written from their pages replace the last stubs of tiers 1 and 2. A scene answers Activate and Deactivate through ctx.respond() with ActivationStarted and DeactivationStarted, the time and the cause filled in. device.raise(descriptor, name, payload) publishes DoorbellPress and the Event of a button on <root>/event with the endpoint and a new messageId; it throws a MessageError for an interface or instance the device did not declare, an event that answers a directive, a payload that does not fit and a message over 16000 bytes. TurnOn of a device with WakeOnLANController is deferred without the warning. On the wire: a doorbell has no properties object and proactivelyReported on the capability; SimpleEventSource is version 1.0, InventoryLevelSensor and WakeOnLANController version 3 (1.5.2: 1). A scene declared without options is announced as before. Alex2MQTT has no topic yet for the WakeUp event. 24 examples of the six pages are saved as fixtures. 267 tests pass, 241 before. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
137 lines
9.7 KiB
JavaScript
137 lines
9.7 KiB
JavaScript
"use strict";
|
|
// The fixed vocabularies of the Smart Home API, copied from Amazon's pages as read on 2026-09-28. The pages are under
|
|
// https://developer.amazon.com/docs/alexaplus/device-apis/. A value missing here is one Amazon added since.
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.ERROR_TYPES = exports.LIMITS = exports.CAUSES = exports.RESERVED_WORDS = exports.DISPLAY_CATEGORIES = exports.STATES = exports.ACTIONS = exports.UNITS_OF_MEASURE = exports.ASSETS = void 0;
|
|
/**
|
|
* The asset ids a friendly name can refer to: 103, the units of measure among them
|
|
* (resources-and-assets.html, "Global Alexa catalog").
|
|
*/
|
|
exports.ASSETS = [
|
|
"Alexa.Actions.Charge", "Alexa.Actions.Clean", "Alexa.Actions.Dispense", "Alexa.Actions.Dock",
|
|
"Alexa.Actions.Empty", "Alexa.Actions.Mop", "Alexa.Actions.Skip", "Alexa.Actions.Sweep", "Alexa.Actions.Vacuum",
|
|
"Alexa.Button.OffButton", "Alexa.Button.OnButton", "Alexa.Button.BrightenButton", "Alexa.Button.DimButton",
|
|
"Alexa.Button.MainButton", "Alexa.Button.TopButton", "Alexa.Button.BottomButton", "Alexa.Button.CenterButton",
|
|
"Alexa.Button.MiddleButton", "Alexa.Button.UpButton", "Alexa.Button.DownButton", "Alexa.Button.LeftButton",
|
|
"Alexa.Button.RightButton", "Alexa.Button.FirstButton", "Alexa.Button.SecondButton", "Alexa.Button.ThirdButton",
|
|
"Alexa.Button.FourthButton", "Alexa.Button.FifthButton", "Alexa.Button.SixthButton", "Alexa.Button.SeventhButton",
|
|
"Alexa.Button.EighthButton", "Alexa.Button.DoublePress", "Alexa.Button.DoublePush", "Alexa.Button.LongPress",
|
|
"Alexa.Button.LongPush", "Alexa.Button.SinglePress", "Alexa.Button.SinglePush",
|
|
"Alexa.DeviceName.AirPurifier", "Alexa.DeviceName.Camera", "Alexa.DeviceName.Fan", "Alexa.DeviceName.Router",
|
|
"Alexa.DeviceName.Shade", "Alexa.DeviceName.Shower", "Alexa.DeviceName.SpaceHeater", "Alexa.DeviceName.Washer",
|
|
"Alexa.Gesture.DoubleClick", "Alexa.Gesture.SingleClick", "Alexa.Gesture.SwipeDown", "Alexa.Gesture.SwipeLeft",
|
|
"Alexa.Gesture.SwipeRight", "Alexa.Gesture.SwipeUp", "Alexa.Gesture.Tap",
|
|
// "Gestures", plural: the page spells this one id differently from the seven above
|
|
"Alexa.Gestures.DoubleTap",
|
|
"Alexa.Setting.2GGuestWiFi", "Alexa.Setting.5GGuestWiFi", "Alexa.Setting.Auto", "Alexa.Setting.Direction",
|
|
"Alexa.Setting.DryCycle", "Alexa.Setting.FanSpeed", "Alexa.Setting.GuestWiFi", "Alexa.Setting.Heat",
|
|
"Alexa.Setting.Mode", "Alexa.Setting.Night", "Alexa.Setting.Opening", "Alexa.Setting.Oscillate",
|
|
"Alexa.Setting.Preset", "Alexa.Setting.Quiet", "Alexa.Setting.Temperature", "Alexa.Setting.WashCycle",
|
|
"Alexa.Setting.WaterTemperature",
|
|
"Alexa.Shower.HandHeld", "Alexa.Shower.RainHead",
|
|
"Alexa.Unit.Angle.Degrees", "Alexa.Unit.Angle.Radians", "Alexa.Unit.Distance.Feet", "Alexa.Unit.Distance.Inches",
|
|
"Alexa.Unit.Distance.Kilometers", "Alexa.Unit.Distance.Meters", "Alexa.Unit.Distance.Miles",
|
|
"Alexa.Unit.Distance.Yards", "Alexa.Unit.Mass.Grams", "Alexa.Unit.Mass.Kilograms", "Alexa.Unit.Percent",
|
|
"Alexa.Unit.Temperature.Celsius", "Alexa.Unit.Temperature.Degrees", "Alexa.Unit.Temperature.Fahrenheit",
|
|
"Alexa.Unit.Temperature.Kelvin", "Alexa.Unit.Volume.CubicFeet", "Alexa.Unit.Volume.CubicMeters",
|
|
"Alexa.Unit.Volume.Gallons", "Alexa.Unit.Volume.Liters", "Alexa.Unit.Volume.Pints", "Alexa.Unit.Volume.Quarts",
|
|
"Alexa.Unit.Weight.Ounces", "Alexa.Unit.Weight.Pounds",
|
|
"Alexa.Value.Close", "Alexa.Value.Delicate", "Alexa.Value.High", "Alexa.Value.Low", "Alexa.Value.Maximum",
|
|
"Alexa.Value.Medium", "Alexa.Value.Minimum", "Alexa.Value.Open", "Alexa.Value.QuickWash",
|
|
];
|
|
exports.UNITS_OF_MEASURE = exports.ASSETS.filter((id) => id.startsWith("Alexa.Unit."));
|
|
/** The phrases an action mapping gives to a directive (alexa-discovery-objects.html, "ActionMappings object"). */
|
|
exports.ACTIONS = [
|
|
"Alexa.Actions.Open", "Alexa.Actions.Close", "Alexa.Actions.Raise", "Alexa.Actions.Lower",
|
|
"Alexa.Actions.SetEcoOn", "Alexa.Actions.SetEcoOff",
|
|
];
|
|
/** The states a state mapping gives to a property value (alexa-discovery-objects.html, "StateMappings object"). */
|
|
exports.STATES = [
|
|
"Alexa.States.Open", "Alexa.States.Closed", "Alexa.States.EcoOn", "Alexa.States.EcoOff", "Alexa.States.Low",
|
|
"Alexa.States.Empty", "Alexa.States.Full", "Alexa.States.Done", "Alexa.States.Stuck",
|
|
];
|
|
/**
|
|
* The 56 display categories (alexa-discovery.html, "Display categories"). The DisplayCategory enum also keeps
|
|
* VEHICLE from 1.x, which the page no longer lists.
|
|
*/
|
|
exports.DISPLAY_CATEGORIES = [
|
|
"ACTIVITY_TRIGGER", "AIR_CONDITIONER", "AIR_FRESHENER", "AIR_PURIFIER", "AIR_QUALITY_MONITOR",
|
|
"ALEXA_VOICE_ENABLED", "AUTO_ACCESSORY", "BLUETOOTH_SPEAKER", "CAMERA", "CHRISTMAS_TREE", "COFFEE_MAKER",
|
|
"COMPUTER", "CONTACT_SENSOR", "DISHWASHER", "DOOR", "DOORBELL", "DRYER", "EXTERIOR_BLIND", "FAN", "GAME_CONSOLE",
|
|
"GARAGE_DOOR", "HEADPHONES", "HUB", "INTERIOR_BLIND", "LAPTOP", "LIGHT", "MICROWAVE", "MOBILE_PHONE",
|
|
"MOTION_SENSOR", "MUSIC_SYSTEM", "NETWORK_HARDWARE", "OTHER", "OVEN", "PHONE", "PRINTER", "REMOTE", "ROUTER",
|
|
"SCENE_TRIGGER", "SCREEN", "SECURITY_PANEL", "SECURITY_SYSTEM", "SLOW_COOKER", "SMARTLOCK", "SMARTPLUG", "SPEAKER",
|
|
"STREAMING_DEVICE", "SWITCH", "TABLET", "TEMPERATURE_SENSOR", "THERMOSTAT", "TV", "VACUUM_CLEANER", "VACUUM",
|
|
"WASHER", "WATER_HEATER", "WEARABLE",
|
|
];
|
|
/** Not to be used as a friendly name (resources-and-assets.html, "Reserved words"). */
|
|
exports.RESERVED_WORDS = [
|
|
"alarm", "alarms", "all alarms", "away mode", "bass", "camera", "date", "date today", "day", "do not disturb",
|
|
"drop in", "music", "night light", "notification", "playing", "sleep sounds", "time", "timer", "today in music",
|
|
"treble", "volume", "way f. m.",
|
|
];
|
|
/**
|
|
* Why a property changed or an event was raised (message-guide.html, "Cause object"). RULE_TRIGGER is not in that
|
|
* table; the ChangeReport examples of alexa-securitypanelcontroller.html and alexa-thermostatcontroller.html use it.
|
|
*/
|
|
exports.CAUSES = ["APP_INTERACTION", "PERIODIC_POLL", "PHYSICAL_INTERACTION", "RULE_TRIGGER", "VOICE_INTERACTION"];
|
|
/**
|
|
* What a discovery answer may hold (alexa-discovery.html, "Interface limits"; alexa-discovery-objects.html,
|
|
* "Endpoint object details" and "AdditionalAttributes object details"; alexa-scenecontroller.html, "Discovery").
|
|
*/
|
|
exports.LIMITS = {
|
|
endpointsPerCustomer: 300,
|
|
capabilitiesPerEndpoint: 100,
|
|
endpointIdLength: 256,
|
|
friendlyNameLength: 256,
|
|
sceneFriendlyNameLength: 128,
|
|
manufacturerNameLength: 128,
|
|
descriptionLength: 128,
|
|
additionalAttributeLength: 256,
|
|
cookieBytes: 5000,
|
|
};
|
|
// alexa-errorresponse.html, "Error type values". The Interface column names <namespace>.ErrorResponse; the event
|
|
// header carries the namespace and the name ErrorResponse, as the examples on the ThermostatController,
|
|
// SecurityPanelController and Safety error pages show. The other namespaces are as the table spells them.
|
|
// INVALID_VALUE is listed under Alexa and under SmartVision.ObjectDetectionSensor, SUBSCRIPTION_REQUIRED under both
|
|
// SmartVision interfaces: the first one listed is kept.
|
|
const ERROR_TYPES_BY_NAMESPACE = {
|
|
"Alexa": [
|
|
"ALREADY_IN_OPERATION", "BRIDGE_UNREACHABLE", "CLOUD_CONTROL_DISABLED", "DEVICE_STUCK", "DO_NOT_DISTURB_MODE",
|
|
"ENDPOINT_BUSY", "ENDPOINT_CONTROL_UNAVAILABLE", "ENDPOINT_LOW_POWER", "ENDPOINT_UNREACHABLE",
|
|
"EXPIRED_AUTHORIZATION_CREDENTIAL", "FIRMWARE_OUT_OF_DATE", "HARDWARE_MALFUNCTION", "INSUFFICIENT_PERMISSIONS",
|
|
"INSUFFICIENT_RESOURCE", "INTERNAL_ERROR", "INVALID_AUTHORIZATION_CREDENTIAL", "INVALID_DIRECTIVE",
|
|
"INVALID_VALUE", "MAINTENANCE_REQUIRED", "NO_SUCH_ENDPOINT", "NOT_CALIBRATED", "NOT_IN_OPERATION",
|
|
"NOT_SUPPORTED_IN_CURRENT_MODE", "NOT_SUPPORTED_WITH_CURRENT_BATTERY_CHARGE_STATE",
|
|
"PARTNER_APPLICATION_REDIRECTION", "POWER_LEVEL_NOT_SUPPORTED", "RATE_LIMIT_EXCEEDED",
|
|
"TEMPERATURE_VALUE_OUT_OF_RANGE", "TOO_MANY_FAILED_ATTEMPTS", "UNABLE_TO_CHARGE", "VALUE_OUT_OF_RANGE",
|
|
],
|
|
"Alexa.Commissionable.ReportCommissioningInformation": [
|
|
"FAILED_TO_BOOTSTRAP_COMMISSIONING_PROCESS", "MAX_COMMISSIONING_LIMIT_REACHED",
|
|
],
|
|
"Alexa.Cooking": [
|
|
"CHILD_LOCK", "COOK_DURATION_TOO_LONG", "DOOR_CLOSED_TOO_LONG", "DOOR_OPEN", "PREHEAT_REQUIRED",
|
|
"PROBE_REQUIRED", "REMOTE_START_NOT_SUPPORTED", "REMOVE_PROBE", "REMOTE_START_DISABLED",
|
|
],
|
|
"Alexa.DataController": ["DATA_DELETION_NOT_SUPPORTED", "DATA_RETRIEVAL_NOT_SUPPORTED"],
|
|
"Alexa.Safety": ["OBSTACLE_DETECTED", "SAFETY_BEAM_BREACHED"],
|
|
"Alexa.SecurityPanelController": [
|
|
"AUTHORIZATION_REQUIRED", "BYPASS_NEEDED", "NOT_READY", "UNAUTHORIZED", "UNCLEARED_ALARM", "UNCLEARED_TROUBLE",
|
|
],
|
|
"Alexa.SmartVision.ObjectDetectionSensor": ["SUBSCRIPTION_REQUIRED"],
|
|
"Alexa.SmartVision.SnapshotProvider": ["DISABLED_BY_USER"],
|
|
"Alexa.ThermostatController": [
|
|
"DUAL_SETPOINTS_UNSUPPORTED", "REQUESTED_SETPOINTS_TOO_CLOSE", "THERMOSTAT_IS_OFF",
|
|
"TRIPLE_SETPOINTS_UNSUPPORTED", "UNSUPPORTED_THERMOSTAT_MODE", "UNWILLING_TO_SET_SCHEDULE",
|
|
"UNWILLING_TO_SET_VALUE",
|
|
],
|
|
"Alexa.ThermostatController.Configuration": [
|
|
"CONFIGURATION_UPDATE_NOT_ALLOWED", "COOLING_LOCKOUT_TEMPERATURE_VALUE_OUT_OF_RANGE",
|
|
"COOLING_STAGES_EXCEEDS_LIMIT", "HEATING_LOCKOUT_TEMPERATURE_VALUE_OUT_OF_RANGE", "HEATING_STAGES_EXCEEDS_LIMIT",
|
|
"INVALID_AUXILIARY_HEATING_SYSTEM_TYPE", "INVALID_SYSTEM_TYPE", "INVALID_TARGET_STATE",
|
|
"INVALID_TEMPERATURE_SCALE", "INVALID_TERMINAL_CONNECTION", "MISSING_SETUP_INFORMATION",
|
|
],
|
|
"Alexa.ThermostatController.Schedule": ["INSUFFICIENT_SPACE"],
|
|
};
|
|
/** The 73 error types of the table, each with the namespace its ErrorResponse goes under. */
|
|
exports.ERROR_TYPES = Object.fromEntries(Object.entries(ERROR_TYPES_BY_NAMESPACE).flatMap(([namespace, types]) => types.map((type) => [type, namespace])));
|