import { s } from "../schema.js"; import { DeclarationError, defineInterface } from "../types.js"; // 00-14-22-01-23-45 in the example of the page; the colon is the other common way to write one const MAC_ADDRESS = /^[0-9A-Fa-f]{2}([-:][0-9A-Fa-f]{2}){5}$/; /** * A device that is switched on by a Wake-on-LAN message, which an Echo of the user sends to the MAC addresses of * the capability. The interface has no directive and no property: the device gets TurnOn of Alexa.PowerController, * answers with a DeferredResponse, sends the WakeUp event and, when it is up, the Response. * * Alex2MQTT has no topic yet that takes the WakeUp event to Alexa. */ export const WakeOnLANController = defineInterface({ namespace: "Alexa.WakeOnLANController", version: "3", doc: "https://developer.amazon.com/docs/alexaplus/device-apis/alexa-wakeonlancontroller.html", kind: "controller", tier: 2, instanced: false, properties: {}, directives: {}, events: { WakeUp: { name: "WakeUp", payload: s.object({}), topic: "response" }, }, options: s.object({ macAddresses: s.array(s.string({ pattern: MAC_ADDRESS, expects: "a MAC address like 00-14-22-01-23-45" }), { min: 1 }), }, { unknownKeys: "reject" }), // The example has a properties object without fields, which topLevel puts where properties: false left none. A // capability declared the 1.x way has no address; check() says so. discovery: ({ options: { macAddresses } }) => ({ properties: false, topLevel: { properties: {} }, ...(macAddresses && { configuration: { MACAddresses: macAddresses } }), }), validate(capability) { const addresses = capability.options.macAddresses.map((address) => address.toUpperCase().replace(/:/g, "-")); const twice = addresses.find((address, i) => addresses.indexOf(address) !== i); if (twice) throw new DeclarationError(capability, `${twice} is listed twice`); }, deferrable: true, defers: [{ namespace: "Alexa.PowerController", name: "TurnOn" }], });