diff --git a/examples/ExamplePowerControllerWithErrors.js b/examples/ExamplePowerControllerWithErrors.js index ae0a35b..3b1a59e 100644 --- a/examples/ExamplePowerControllerWithErrors.js +++ b/examples/ExamplePowerControllerWithErrors.js @@ -1,77 +1,89 @@ -// Import required modules and types from the compiled TypeScript distribution (via dist/index.js) -const { - Alex2MQTT, - AlexaInterfaceType, - PowerController +const { + Alex2MQTT, + AlexaInterfaceType, + PowerController, + AlexaErrorType, } = require("../dist/index.js"); -require("dotenv").config(); // Load environment variables from .env file +require("dotenv").config(); -// Simulated in-memory device state (used for example/demo purposes) -let outputState = PowerController.OFF; // Initialize the power state to OFF +let outputState = PowerController.OFF; -// Load MQTT connection credentials and root topic from environment variables const username = process.env.MQTT_USERNAME; const password = process.env.MQTT_PASSWORD; const rootTopic = process.env.MQTT_ROOT_TOPIC; -// Create and initialize a new Alexa-to-MQTT client const alex2NodeClient = new Alex2MQTT(username, password, rootTopic, false); -alex2NodeClient.connect(); // Connect to the MQTT broker +alex2NodeClient.connect(); -// Define the device name (bedroom light) -const deviceName = "Bedroom Light"; +const errorLight = alex2NodeClient.registerDevice("bad light", "endpoint4"); +errorLight.addCapability(AlexaInterfaceType.POWER_CONTROLLER); -// Register the device with a unique endpoint ID (you can use something like "endpoint1") -const bedroomLight = alex2NodeClient.registerDevice(deviceName, "endpoint2"); +console.log(errorLight.getName()); -// Add the PowerController capability (for turning on/off the device) -bedroomLight.addCapability(AlexaInterfaceType.POWER_CONTROLLER); - -// Log the device name to verify registration -console.log(bedroomLight.getName()); +// Error cycling setup +const errorCycle = [ + AlexaErrorType.ENDPOINT_LOW_POWER, + AlexaErrorType.VALUE_OUT_OF_RANGE, + AlexaErrorType.HARDWARE_MALFUNCTION, + AlexaErrorType.BRIDGE_UNREACHABLE, + AlexaErrorType.FIRMWARE_OUT_OF_DATE, + AlexaErrorType.NOT_CALIBRATED, + AlexaErrorType.RATE_LIMIT_EXCEEDED, +]; +let currentErrorIndex = 0; /** - * Handle Alexa's ReportState directive. - * This occurs when Alexa queries the current state of the device (e.g., during routines or device status checks). + * Always return ENDPOINT_BUSY error on state queries. */ -bedroomLight.on("ReportState", (payload) => { +errorLight.on("ReportState", (payload) => { console.log("ReportState received!", payload); const { correlationToken } = payload.header; + const errorResponse = errorLight.getErrorMessage(correlationToken); - const status = bedroomLight.getStatusMessage(correlationToken); - - status - .addHealthProp("OK") // Device is healthy - .addPowerControllerProp(outputState); // Report the current power state (ON/OFF) - - status.send(); // Send the state report back to Alexa + errorResponse.setErrorMessage( + AlexaErrorType.HARDWARE_MALFUNCTION, + "The device is currently busy and cannot report its state." + ); + console.log("Sending error: HARDWARE_MALFUNCTION"); + errorResponse.send(); }); /** - * Handle incoming control directives (e.g., TurnOn, TurnOff). - * These directives come from Alexa when a user issues a command. + * Handle control directives with 90% error chance, cycling through fixed errors. */ -bedroomLight.on("Event", (directive, interfaceType) => { - console.log("Event received", { directive, interfaceType }); - - // Ensure the interfaceType is either PowerController or other valid interfaces +errorLight.on("Event", (directive, interfaceType) => { if (interfaceType === AlexaInterfaceType.POWER_CONTROLLER) { const name = directive.header.name; const token = directive.header.correlationToken; - // Update the internal state based on the command (TurnOn / TurnOff) - if (name === "TurnOn") { - outputState = PowerController.ON; - console.log("Turning ON the Bedroom Light"); - } else if (name === "TurnOff") { - outputState = PowerController.OFF; - console.log("Turning OFF the Bedroom Light"); + const shouldError = Math.random() < 0.9; + + if (shouldError) { + const errorType = errorCycle[currentErrorIndex]; + currentErrorIndex = (currentErrorIndex + 1) % errorCycle.length; + + const errorResponse = errorLight.getErrorMessage(token); + errorResponse.setErrorMessage( + errorType, + `Failed to process ${name} due to ${errorType.replace(/_/g, " ").toLowerCase()}.` + ); + console.log(`Sending error: ${errorType}`); + errorResponse.send(); + return; } - // Respond to the directive with the updated device status - const status = bedroomLight.getStatusMessage(token, true); + // Success path + if (name === "TurnOn") { + outputState = PowerController.ON; + console.log("Turning ON the Light"); + } else if (name === "TurnOff") { + outputState = PowerController.OFF; + console.log("Turning OFF the Light"); + } + + const status = errorLight.getStatusMessage(token, true); status .addHealthProp("OK") .addPowerControllerProp(outputState)