import { v4 as uuidv4 } from "uuid"; import { AlexaInterface, AlexaInterfaceType } from "./AlexaInterface"; import { MqttClient } from "mqtt"; export enum AlexaErrorType { ALREADY_IN_OPERATION = "ALREADY_IN_OPERATION", AUTHORIZATION_REQUIRED = "AUTHORIZATION_REQUIRED", BRIDGE_UNREACHABLE = "BRIDGE_UNREACHABLE", BYPASS_NEEDED = "BYPASS_NEEDED", CLOUD_CONTROL_DISABLED = "CLOUD_CONTROL_DISABLED", CHILD_LOCK = "CHILD_LOCK", CONFIGURATION_UPDATE_NOT_ALLOWED = "CONFIGURATION_UPDATE_NOT_ALLOWED", COOK_DURATION_TOO_LONG = "COOK_DURATION_TOO_LONG", COOLING_LOCKOUT_TEMPERATURE_VALUE_OUT_OF_RANGE = "COOLING_LOCKOUT_TEMPERATURE_VALUE_OUT_OF_RANGE", COOLING_STAGES_EXCEEDS_LIMIT = "COOLING_STAGES_EXCEEDS_LIMIT", DATA_DELETION_NOT_SUPPORTED = "DATA_DELETION_NOT_SUPPORTED", DATA_RETRIEVAL_NOT_SUPPORTED = "DATA_RETRIEVAL_NOT_SUPPORTED", DEVICE_STUCK = "DEVICE_STUCK", DISABLED_BY_USER = "DISABLED_BY_USER", DO_NOT_DISTURB_MODE = "DO_NOT_DISTURB_MODE", DOOR_CLOSED_TOO_LONG = "DOOR_CLOSED_TOO_LONG", DOOR_OPEN = "DOOR_OPEN", DUAL_SETPOINTS_UNSUPPORTED = "DUAL_SETPOINTS_UNSUPPORTED", ENDPOINT_BUSY = "ENDPOINT_BUSY", ENDPOINT_CONTROL_UNAVAILABLE = "ENDPOINT_CONTROL_UNAVAILABLE", ENDPOINT_LOW_POWER = "ENDPOINT_LOW_POWER", ENDPOINT_UNREACHABLE = "ENDPOINT_UNREACHABLE", EXCEEDED_PIN_ATTEMPTS = "EXCEEDED_PIN_ATTEMPTS", EXPIRED_AUTHORIZATION_CREDENTIAL = "EXPIRED_AUTHORIZATION_CREDENTIAL", FAILED_TO_BOOTSTRAP_COMMISSIONING_PROCESS = "FAILED_TO_BOOTSTRAP_COMMISSIONING_PROCESS", FIRMWARE_OUT_OF_DATE = "FIRMWARE_OUT_OF_DATE", HARDWARE_MALFUNCTION = "HARDWARE_MALFUNCTION", HEATING_LOCKOUT_TEMPERATURE_VALUE_OUT_OF_RANGE = "HEATING_LOCKOUT_TEMPERATURE_VALUE_OUT_OF_RANGE", HEATING_STAGES_EXCEEDS_LIMIT = "HEATING_STAGES_EXCEEDS_LIMIT", INSUFFICIENT_PERMISSIONS = "INSUFFICIENT_PERMISSIONS", INSUFFICIENT_RESOURCE = "INSUFFICIENT_RESOURCE", INSUFFICIENT_SPACE = "INSUFFICIENT_SPACE", INTERNAL_ERROR = "INTERNAL_ERROR", INVALID_AUTHORIZATION_CREDENTIAL = "INVALID_AUTHORIZATION_CREDENTIAL", INVALID_AUXILIARY_HEATING_SYSTEM_TYPE = "INVALID_AUXILIARY_HEATING_SYSTEM_TYPE", INVALID_DIRECTIVE = "INVALID_DIRECTIVE", INVALID_SYSTEM_TYPE = "INVALID_SYSTEM_TYPE", INVALID_TARGET_STATE = "INVALID_TARGET_STATE", INVALID_TEMPERATURE_SCALE = "INVALID_TEMPERATURE_SCALE", INVALID_TERMINAL_CONNECTION = "INVALID_TERMINAL_CONNECTION", INVALID_VALUE = "INVALID_VALUE", MAINTENANCE_REQUIRED = "MAINTENANCE_REQUIRED", MAX_COMMISSIONING_LIMIT_REACHED = "MAX_COMMISSIONING_LIMIT_REACHED", MISSING_SETUP_INFORMATION = "MISSING_SETUP_INFORMATION", NO_SUCH_ENDPOINT = "NO_SUCH_ENDPOINT", NOT_CALIBRATED = "NOT_CALIBRATED", NOT_IN_OPERATION = "NOT_IN_OPERATION", NOT_READY = "NOT_READY", NOT_SUPPORTED_IN_CURRENT_MODE = "NOT_SUPPORTED_IN_CURRENT_MODE", NOT_SUPPORTED_WITH_CURRENT_BATTERY_CHARGE_STATE = "NOT_SUPPORTED_WITH_CURRENT_BATTERY_CHARGE_STATE", OBSTACLE_DETECTED = "OBSTACLE_DETECTED", PARTNER_APPLICATION_REDIRECTION = "PARTNER_APPLICATION_REDIRECTION", PIN_SETUP_REQUIRED = "PIN_SETUP_REQUIRED", POWER_LEVEL_NOT_SUPPORTED = "POWER_LEVEL_NOT_SUPPORTED", PREHEAT_REQUIRED = "PREHEAT_REQUIRED", PROBE_REQUIRED = "PROBE_REQUIRED", RATE_LIMIT_EXCEEDED = "RATE_LIMIT_EXCEEDED", REMOTE_START_NOT_SUPPORTED = "REMOTE_START_NOT_SUPPORTED", REMOVE_PROBE = "REMOVE_PROBE", REMOTE_START_DISABLED = "REMOTE_START_DISABLED", REQUESTED_SETPOINTS_TOO_CLOSE = "REQUESTED_SETPOINTS_TOO_CLOSE", SAFETY_BEAM_BREACHED = "SAFETY_BEAM_BREACHED", SUBSCRIPTION_REQUIRED = "SUBSCRIPTION_REQUIRED", TEMPERATURE_VALUE_OUT_OF_RANGE = "TEMPERATURE_VALUE_OUT_OF_RANGE", THERMOSTAT_IS_OFF = "THERMOSTAT_IS_OFF", TOO_MANY_FAILED_ATTEMPTS = "TOO_MANY_FAILED_ATTEMPTS", TRIPLE_SETPOINTS_UNSUPPORTED = "TRIPLE_SETPOINTS_UNSUPPORTED", UNABLE_TO_CHARGE = "UNABLE_TO_CHARGE", UNAUTHORIZED = "UNAUTHORIZED", UNCLEARED_ALARM = "UNCLEARED_ALARM", UNSUPPORTED_THERMOSTAT_MODE = "UNSUPPORTED_THERMOSTAT_MODE", UNCLEARED_TROUBLE = "UNCLEARED_TROUBLE", UNWILLING_TO_SET_SCHEDULE = "UNWILLING_TO_SET_SCHEDULE", UNWILLING_TO_SET_VALUE = "UNWILLING_TO_SET_VALUE", VALUE_OUT_OF_RANGE = "VALUE_OUT_OF_RANGE", } export class AlexaErrorResponse { private event: any; private rootTopic: string; private endpointId: string; private mqttClient: MqttClient; constructor( correlationToken: string, rootTopic: string, endpointId: string, mqttClient: MqttClient ) { this.rootTopic = rootTopic; this.endpointId = endpointId; this.mqttClient = mqttClient; this.event = { header: { namespace: "Alexa", name: "ErrorResponse", messageId: this.generateMessageId(), correlationToken, payloadVersion: "3", }, endpoint: { endpointId, }, payload: {}, }; } private generateMessageId(): string { return uuidv4(); } setErrorMessage( type: string, message: string, otherParams: Record = {} ) { this.event.payload = { type, message, ...otherParams, }; } send(sendAsync = false) { const payload = { event: this.event, }; const topic = `${this.rootTopic}/${this.endpointId}/${ sendAsync ? "deferredResponse" : "alexaResponce" }`; //Yes this should be response but it is incorrect in both Alex2MQTT and Alex2ESP so for consistency is is wrong here too const payloadStr = JSON.stringify(payload); this.mqttClient.publish(topic, payloadStr, (err) => { if (err) { console.error( "[AlexaErrorResponse] Failed to publish status message:", err ); } else { console.log(`[AlexaErrorResponse] Sent message to ${topic}`); } }); } }