registry: Lock, Color, ColorTemperature, Percentage, PowerLevel, Contact, Motion, Humidity

Eight descriptors written from their pages, each with its version, the value of its property and the payload of
every directive. Seven replace a stub; Alexa.HumiditySensor is new, as AlexaInterfaceType.HUMIDITY_SENSOR.
LockController is deferrable: defer() on a lock logs no warning.

A 1.x declaration of LockController, MotionSensor, PercentageController or PowerLevelController now lists its
property in discovery, where 1.5.2 listed none: the zoo's lock, motion sensor and heater come out as the JSON
Alexa accepted. A payload that does not fit (hue 361, 900 K) is answered with INVALID_VALUE.

48 examples of the eight pages are saved as fixtures. 191 tests pass, 168 before.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
David 2026-09-28 20:29:04 +00:00
parent feff828ec1
commit af1489696d
111 changed files with 2971 additions and 45 deletions

View file

@ -34,6 +34,8 @@ var AlexaInterfaceType;
AlexaInterfaceType["DOORBELL_EVENT_SOURCE"] = "Alexa.DoorbellEventSource";
AlexaInterfaceType["ENDPOINT_HEALTH"] = "Alexa.EndpointHealth";
AlexaInterfaceType["EQUALIZER_CONTROLLER"] = "Alexa.EqualizerController";
/** Since 2.0. */
AlexaInterfaceType["HUMIDITY_SENSOR"] = "Alexa.HumiditySensor";
AlexaInterfaceType["INPUT_CONTROLLER"] = "Alexa.InputController";
AlexaInterfaceType["INVENTORY_LEVEL_SENSOR"] = "Alexa.InventoryLevelSensor";
AlexaInterfaceType["INVENTORY_LEVEL_USAGE_SENSOR"] = "Alexa.InventoryLevelUsageSensor";

11
dist/cjs/index.js vendored
View file

@ -36,7 +36,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AlexaErrorResponse = exports.AlexaStatusMessage = exports.ThermostatMode = exports.TemperatureSensorScale = exports.PowerState = exports.DisplayCategory = exports.AlexaInterfaceType = exports.AlexaErrorType = exports.AlexaActions = exports.ActionMapping = exports.AlexaInterface = exports.MemoryPublisher = exports.topics = exports.property = exports.StateBuilder = exports.MessageError = exports.AlexaErrors = exports.AlexaError = exports.messages = exports.DisplayCategories = exports.States = exports.Actions = exports.Units = exports.Assets = exports.SemanticsBuilder = exports.semantics = exports.text = exports.asset = exports.EndpointHealth = exports.PowerController = exports.ToggleController = exports.TemperatureSensor = exports.RangeController = exports.ModeController = exports.BrightnessController = exports.Alexa = exports.SchemaError = exports.DeclarationError = exports.registry = exports.Capability = exports.Device = exports.DEFAULT_HOST = exports.Alex2MQTT = void 0;
exports.AlexaStatusMessage = exports.ThermostatMode = exports.TemperatureSensorScale = exports.PowerState = exports.DisplayCategory = exports.AlexaInterfaceType = exports.AlexaErrorType = exports.AlexaActions = exports.ActionMapping = exports.AlexaInterface = exports.MemoryPublisher = exports.topics = exports.property = exports.StateBuilder = exports.MessageError = exports.AlexaErrors = exports.AlexaError = exports.messages = exports.DisplayCategories = exports.States = exports.Actions = exports.Units = exports.Assets = exports.SemanticsBuilder = exports.semantics = exports.text = exports.asset = exports.EndpointHealth = exports.PowerController = exports.ToggleController = exports.TemperatureSensor = exports.RangeController = exports.PowerLevelController = exports.PercentageController = exports.MotionSensor = exports.ModeController = exports.LockController = exports.HumiditySensor = exports.ContactSensor = exports.ColorTemperatureController = exports.ColorController = exports.BrightnessController = exports.Alexa = exports.SchemaError = exports.DeclarationError = exports.registry = exports.Capability = exports.Device = exports.DEFAULT_HOST = exports.Alex2MQTT = void 0;
exports.AlexaErrorResponse = void 0;
// Relative specifiers carry ".js": Node's ES module loader resolves no extension, and TypeScript maps it back to the .ts.
var Alex2Node_js_1 = require("./Alex2Node.js");
Object.defineProperty(exports, "Alex2MQTT", { enumerable: true, get: function () { return __importDefault(Alex2Node_js_1).default; } });
@ -53,7 +54,15 @@ Object.defineProperty(exports, "SchemaError", { enumerable: true, get: function
var index_js_2 = require("./registry/index.js");
Object.defineProperty(exports, "Alexa", { enumerable: true, get: function () { return index_js_2.Alexa; } });
Object.defineProperty(exports, "BrightnessController", { enumerable: true, get: function () { return index_js_2.BrightnessController; } });
Object.defineProperty(exports, "ColorController", { enumerable: true, get: function () { return index_js_2.ColorController; } });
Object.defineProperty(exports, "ColorTemperatureController", { enumerable: true, get: function () { return index_js_2.ColorTemperatureController; } });
Object.defineProperty(exports, "ContactSensor", { enumerable: true, get: function () { return index_js_2.ContactSensor; } });
Object.defineProperty(exports, "HumiditySensor", { enumerable: true, get: function () { return index_js_2.HumiditySensor; } });
Object.defineProperty(exports, "LockController", { enumerable: true, get: function () { return index_js_2.LockController; } });
Object.defineProperty(exports, "ModeController", { enumerable: true, get: function () { return index_js_2.ModeController; } });
Object.defineProperty(exports, "MotionSensor", { enumerable: true, get: function () { return index_js_2.MotionSensor; } });
Object.defineProperty(exports, "PercentageController", { enumerable: true, get: function () { return index_js_2.PercentageController; } });
Object.defineProperty(exports, "PowerLevelController", { enumerable: true, get: function () { return index_js_2.PowerLevelController; } });
Object.defineProperty(exports, "RangeController", { enumerable: true, get: function () { return index_js_2.RangeController; } });
Object.defineProperty(exports, "TemperatureSensor", { enumerable: true, get: function () { return index_js_2.TemperatureSensor; } });
Object.defineProperty(exports, "ToggleController", { enumerable: true, get: function () { return index_js_2.ToggleController; } });

View file

@ -14,18 +14,34 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SchemaError = exports.s = exports.defineInterface = exports.DeclarationError = exports.SemanticsBuilder = exports.semantics = exports.text = exports.asset = exports.ToggleController = exports.TemperatureSensor = exports.RangeController = exports.PowerController = exports.ModeController = exports.EndpointHealth = exports.BrightnessController = exports.Alexa = exports.registry = void 0;
exports.SchemaError = exports.s = exports.defineInterface = exports.DeclarationError = exports.SemanticsBuilder = exports.semantics = exports.text = exports.asset = exports.ToggleController = exports.TemperatureSensor = exports.RangeController = exports.PowerLevelController = exports.PowerController = exports.PercentageController = exports.MotionSensor = exports.ModeController = exports.LockController = exports.HumiditySensor = exports.EndpointHealth = exports.ContactSensor = exports.ColorTemperatureController = exports.ColorController = exports.BrightnessController = exports.Alexa = exports.registry = void 0;
// The interfaces the library knows, by namespace.
const Alexa_js_1 = require("./interfaces/Alexa.js");
Object.defineProperty(exports, "Alexa", { enumerable: true, get: function () { return Alexa_js_1.Alexa; } });
const BrightnessController_js_1 = require("./interfaces/BrightnessController.js");
Object.defineProperty(exports, "BrightnessController", { enumerable: true, get: function () { return BrightnessController_js_1.BrightnessController; } });
const ColorController_js_1 = require("./interfaces/ColorController.js");
Object.defineProperty(exports, "ColorController", { enumerable: true, get: function () { return ColorController_js_1.ColorController; } });
const ColorTemperatureController_js_1 = require("./interfaces/ColorTemperatureController.js");
Object.defineProperty(exports, "ColorTemperatureController", { enumerable: true, get: function () { return ColorTemperatureController_js_1.ColorTemperatureController; } });
const ContactSensor_js_1 = require("./interfaces/ContactSensor.js");
Object.defineProperty(exports, "ContactSensor", { enumerable: true, get: function () { return ContactSensor_js_1.ContactSensor; } });
const EndpointHealth_js_1 = require("./interfaces/EndpointHealth.js");
Object.defineProperty(exports, "EndpointHealth", { enumerable: true, get: function () { return EndpointHealth_js_1.EndpointHealth; } });
const HumiditySensor_js_1 = require("./interfaces/HumiditySensor.js");
Object.defineProperty(exports, "HumiditySensor", { enumerable: true, get: function () { return HumiditySensor_js_1.HumiditySensor; } });
const LockController_js_1 = require("./interfaces/LockController.js");
Object.defineProperty(exports, "LockController", { enumerable: true, get: function () { return LockController_js_1.LockController; } });
const ModeController_js_1 = require("./interfaces/ModeController.js");
Object.defineProperty(exports, "ModeController", { enumerable: true, get: function () { return ModeController_js_1.ModeController; } });
const MotionSensor_js_1 = require("./interfaces/MotionSensor.js");
Object.defineProperty(exports, "MotionSensor", { enumerable: true, get: function () { return MotionSensor_js_1.MotionSensor; } });
const PercentageController_js_1 = require("./interfaces/PercentageController.js");
Object.defineProperty(exports, "PercentageController", { enumerable: true, get: function () { return PercentageController_js_1.PercentageController; } });
const PowerController_js_1 = require("./interfaces/PowerController.js");
Object.defineProperty(exports, "PowerController", { enumerable: true, get: function () { return PowerController_js_1.PowerController; } });
const PowerLevelController_js_1 = require("./interfaces/PowerLevelController.js");
Object.defineProperty(exports, "PowerLevelController", { enumerable: true, get: function () { return PowerLevelController_js_1.PowerLevelController; } });
const RangeController_js_1 = require("./interfaces/RangeController.js");
Object.defineProperty(exports, "RangeController", { enumerable: true, get: function () { return RangeController_js_1.RangeController; } });
const TemperatureSensor_js_1 = require("./interfaces/TemperatureSensor.js");
@ -37,9 +53,17 @@ const types_js_1 = require("./types.js");
const described = [
Alexa_js_1.Alexa,
BrightnessController_js_1.BrightnessController,
ColorController_js_1.ColorController,
ColorTemperatureController_js_1.ColorTemperatureController,
ContactSensor_js_1.ContactSensor,
EndpointHealth_js_1.EndpointHealth,
HumiditySensor_js_1.HumiditySensor,
LockController_js_1.LockController,
ModeController_js_1.ModeController,
MotionSensor_js_1.MotionSensor,
PercentageController_js_1.PercentageController,
PowerController_js_1.PowerController,
PowerLevelController_js_1.PowerLevelController,
RangeController_js_1.RangeController,
TemperatureSensor_js_1.TemperatureSensor,
ToggleController_js_1.ToggleController,

View file

@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ColorController = void 0;
const schema_js_1 = require("../schema.js");
const types_js_1 = require("../types.js");
// alexa-property-schemas.html, "Color"
const color = schema_js_1.s.object({
hue: schema_js_1.s.number({ min: 0, max: 360 }),
saturation: schema_js_1.s.number({ min: 0, max: 1 }),
brightness: schema_js_1.s.number({ min: 0, max: 1 }),
});
/**
* A light changes its hue and saturation and keeps the brightness it has: "ignore the brightness value of 1 in the
* directive" (alexa-colorcontroller.html, "SetColor directive example").
*/
exports.ColorController = (0, types_js_1.defineInterface)({
namespace: "Alexa.ColorController",
version: "3",
doc: "https://developer.amazon.com/docs/alexaplus/device-apis/alexa-colorcontroller.html",
kind: "controller",
tier: 1,
instanced: false,
properties: {
color: { name: "color", value: color },
},
directives: {
SetColor: { name: "SetColor", payload: schema_js_1.s.object({ color }) },
},
});

View file

@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ColorTemperatureController = void 0;
const schema_js_1 = require("../schema.js");
const types_js_1 = require("../types.js");
// alexa-colortemperaturecontroller.html, "Reportable properties": "Valid values range from 1,000 to 10,000"
const kelvin = schema_js_1.s.number({ min: 1000, max: 10000, integer: true });
/**
* The white of a tunable light. Alexa asks for 2200 (warm), 2700 (soft), 4000 (white), 5500 (daylight) and 7000
* (cool); a light that cannot show the value takes the nearest it can. A light that shows a colour answers
* NOT_SUPPORTED_IN_CURRENT_MODE with currentDeviceMode COLOR.
*/
exports.ColorTemperatureController = (0, types_js_1.defineInterface)({
namespace: "Alexa.ColorTemperatureController",
version: "3",
doc: "https://developer.amazon.com/docs/alexaplus/device-apis/alexa-colortemperaturecontroller.html",
kind: "controller",
tier: 1,
instanced: false,
properties: {
colorTemperatureInKelvin: { name: "colorTemperatureInKelvin", value: kelvin },
},
directives: {
SetColorTemperature: { name: "SetColorTemperature", payload: schema_js_1.s.object({ colorTemperatureInKelvin: kelvin }) },
IncreaseColorTemperature: { name: "IncreaseColorTemperature", payload: schema_js_1.s.object({}), note: "towards cool" },
DecreaseColorTemperature: { name: "DecreaseColorTemperature", payload: schema_js_1.s.object({}), note: "towards warm" },
},
});

View file

@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ContactSensor = void 0;
const schema_js_1 = require("../schema.js");
const types_js_1 = require("../types.js");
/**
* DETECTED is open: the two pieces of the sensor are apart. A sensor that cannot answer ReportState sends a
* ChangeReport right after discovery, so that the Alexa app shows its state (alexa-contactsensor.html).
*/
exports.ContactSensor = (0, types_js_1.defineInterface)({
namespace: "Alexa.ContactSensor",
version: "3",
doc: "https://developer.amazon.com/docs/alexaplus/device-apis/alexa-contactsensor.html",
kind: "sensor",
tier: 1,
instanced: false,
properties: {
detectionState: { name: "detectionState", value: schema_js_1.s.enum("DETECTED", "NOT_DETECTED") },
},
directives: {},
});

View file

@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HumiditySensor = void 0;
const schema_js_1 = require("../schema.js");
const types_js_1 = require("../types.js");
/** The value is an object, { value: 45.5 }, as the reports of alexa-humiditysensor.html print it. */
exports.HumiditySensor = (0, types_js_1.defineInterface)({
namespace: "Alexa.HumiditySensor",
version: "3",
doc: "https://developer.amazon.com/docs/alexaplus/device-apis/alexa-humiditysensor.html",
kind: "sensor",
tier: 1,
instanced: false,
properties: {
relativeHumidity: { name: "relativeHumidity", value: schema_js_1.s.object({ value: schema_js_1.s.number({ min: 0, max: 100 }) }) },
},
directives: {},
});

View file

@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LockController = void 0;
const schema_js_1 = require("../schema.js");
const types_js_1 = require("../types.js");
/**
* A lock that takes more than five seconds answers with a DeferredResponse first and the Response when the bolt has
* moved (alexa-lockcontroller.html, "Lock response"). The user enables unlocking by voice per device, in the Alexa app.
*/
exports.LockController = (0, types_js_1.defineInterface)({
namespace: "Alexa.LockController",
version: "3",
doc: "https://developer.amazon.com/docs/alexaplus/device-apis/alexa-lockcontroller.html",
kind: "controller",
tier: 1,
instanced: false,
properties: {
lockState: {
name: "lockState",
value: schema_js_1.s.enum("LOCKED", "UNLOCKED", "JAMMED"),
note: "JAMMED: the mechanism can reach neither LOCKED nor UNLOCKED",
},
},
directives: {
Lock: { name: "Lock", payload: schema_js_1.s.object({}) },
Unlock: { name: "Unlock", payload: schema_js_1.s.object({}) },
},
deferrable: true,
});

View file

@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MotionSensor = void 0;
const schema_js_1 = require("../schema.js");
const types_js_1 = require("../types.js");
/**
* "When a motion sensor changes to DETECTED, and then changes to NOT_DETECTED, you must wait at least 30 seconds
* before sending the second change report" (alexa-motionsensor.html, "Change reporting").
*/
exports.MotionSensor = (0, types_js_1.defineInterface)({
namespace: "Alexa.MotionSensor",
version: "3",
doc: "https://developer.amazon.com/docs/alexaplus/device-apis/alexa-motionsensor.html",
kind: "sensor",
tier: 1,
instanced: false,
properties: {
detectionState: { name: "detectionState", value: schema_js_1.s.enum("DETECTED", "NOT_DETECTED") },
},
directives: {},
});

View file

@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PercentageController = void 0;
const schema_js_1 = require("../schema.js");
const types_js_1 = require("../types.js");
/**
* For a device no other interface fits: "Use this interface only if there isn't a more specific controller
* interface that applies to your device" (alexa-percentagecontroller.html).
*/
exports.PercentageController = (0, types_js_1.defineInterface)({
namespace: "Alexa.PercentageController",
version: "3",
doc: "https://developer.amazon.com/docs/alexaplus/device-apis/alexa-percentagecontroller.html",
kind: "controller",
tier: 1,
instanced: false,
properties: {
percentage: { name: "percentage", value: schema_js_1.s.number({ min: 0, max: 100, integer: true }) },
},
directives: {
SetPercentage: {
name: "SetPercentage",
payload: schema_js_1.s.object({ percentage: schema_js_1.s.number({ min: 0, max: 100, integer: true }) }),
},
AdjustPercentage: {
name: "AdjustPercentage",
payload: schema_js_1.s.object({ percentageDelta: schema_js_1.s.number({ min: -100, max: 100, integer: true }) }),
},
},
});

View file

@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PowerLevelController = void 0;
const schema_js_1 = require("../schema.js");
const types_js_1 = require("../types.js");
/** The power of a device as a percentage, a dimmer switch for one (alexa-powerlevelcontroller.html). */
exports.PowerLevelController = (0, types_js_1.defineInterface)({
namespace: "Alexa.PowerLevelController",
version: "3",
doc: "https://developer.amazon.com/docs/alexaplus/device-apis/alexa-powerlevelcontroller.html",
kind: "controller",
tier: 1,
instanced: false,
properties: {
powerLevel: { name: "powerLevel", value: schema_js_1.s.number({ min: 0, max: 100, integer: true }) },
},
directives: {
SetPowerLevel: {
name: "SetPowerLevel",
payload: schema_js_1.s.object({ powerLevel: schema_js_1.s.number({ min: 0, max: 100, integer: true }) }),
},
AdjustPowerLevel: {
name: "AdjustPowerLevel",
payload: schema_js_1.s.object({ powerLevelDelta: schema_js_1.s.number({ min: -100, max: 100, integer: true }) }),
},
},
});

View file

@ -21,11 +21,8 @@ const TABLE = [
["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"],
@ -44,15 +41,11 @@ const TABLE = [
["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"],