"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ThermostatController = exports.THERMOSTAT_MODES = void 0; const schema_js_1 = require("../schema.js"); const types_js_1 = require("../types.js"); /** alexa-property-schemas.html, "ThermostatMode values". EM_HEAT, emergency heating, came with version 3.2. */ exports.THERMOSTAT_MODES = ["AUTO", "COOL", "ECO", "EM_HEAT", "HEAT", "OFF"]; const PROPERTIES = ["targetSetpoint", "lowerSetpoint", "upperSetpoint", "thermostatMode", "adaptiveRecoveryStatus"]; // What 1.x announced for every thermostat. A declaration that leaves an option out announces the same. const MODES_OF_1X = ["HEAT", "COOL", "AUTO", "OFF"]; const PROPERTIES_OF_1X = ["targetSetpoint", "lowerSetpoint", "upperSetpoint", "thermostatMode"]; const setpoints = schema_js_1.s.object({ targetSetpoint: schema_js_1.s.optional(schema_js_1.s.temperature()), lowerSetpoint: schema_js_1.s.optional(schema_js_1.s.temperature()), upperSetpoint: schema_js_1.s.optional(schema_js_1.s.temperature()), holdUntil: schema_js_1.s.optional(schema_js_1.s.timeInterval()), }); // One setpoint for a thermostat that holds a temperature, the lower and the upper for one that holds a range, all // three for one that aims at a temperature within a range. The page marks each as not required; a payload without // any sets nothing. const setTargetTemperature = { expects: "one or more of targetSetpoint, lowerSetpoint, upperSetpoint", parse(input, path = "") { const payload = setpoints.parse(input, path); if (!payload.targetSetpoint && !payload.lowerSetpoint && !payload.upperSetpoint) throw (0, schema_js_1.mismatch)(path, this.expects, input); return payload; }, }; /** * Version 3.2. A thermostat declares the properties it has: targetSetpoint for a single setpoint, lowerSetpoint and * upperSetpoint for two, all three for a target within a range. Temperatures are reported "in the same temperature * scale (Celsius or Fahrenheit) that the thermostat is set to display". An error of errorTypes goes under the * namespace of the interface, TEMPERATURE_VALUE_OUT_OF_RANGE under Alexa * (alexa-thermostatcontroller-errorresponse.html). */ exports.ThermostatController = (0, types_js_1.defineInterface)({ namespace: "Alexa.ThermostatController", version: "3.2", doc: "https://developer.amazon.com/docs/alexaplus/device-apis/alexa-thermostatcontroller.html", kind: "controller", tier: 1, instanced: false, properties: { targetSetpoint: { name: "targetSetpoint", value: schema_js_1.s.temperature() }, lowerSetpoint: { name: "lowerSetpoint", value: schema_js_1.s.temperature() }, upperSetpoint: { name: "upperSetpoint", value: schema_js_1.s.temperature() }, thermostatMode: { name: "thermostatMode", value: schema_js_1.s.enum(...exports.THERMOSTAT_MODES) }, adaptiveRecoveryStatus: { name: "adaptiveRecoveryStatus", value: schema_js_1.s.enum("PREHEATING", "PRECOOLING", "INACTIVE"), note: "heating or cooling ahead of an entry of the schedule, of Alexa.ThermostatController.Schedule", }, }, directives: { SetTargetTemperature: { name: "SetTargetTemperature", payload: setTargetTemperature, note: "holdUntil comes only to a thermostat declared with supportsScheduling", }, AdjustTargetTemperature: { name: "AdjustTargetTemperature", payload: schema_js_1.s.object({ targetSetpointDelta: schema_js_1.s.temperature() }) }, SetThermostatMode: { name: "SetThermostatMode", payload: schema_js_1.s.object({ thermostatMode: schema_js_1.s.object({ value: schema_js_1.s.enum(...exports.THERMOSTAT_MODES) }) }), }, ResumeSchedule: { name: "ResumeSchedule", payload: schema_js_1.s.object({}), note: "en-US only" }, }, options: schema_js_1.s.object({ /** Default: HEAT, COOL, AUTO, OFF. */ supportedModes: schema_js_1.s.optional(schema_js_1.s.array(schema_js_1.s.enum(...exports.THERMOSTAT_MODES), { min: 1 })), /** The user can set a temperature for a time: SetTargetTemperature comes with holdUntil. Default: false. */ supportsScheduling: schema_js_1.s.optional(schema_js_1.s.boolean()), /** The properties the thermostat has. Default: the three setpoints and thermostatMode. */ properties: schema_js_1.s.optional(schema_js_1.s.array(schema_js_1.s.enum(...PROPERTIES), { min: 1 })), }, { unknownKeys: "reject" }), discovery({ options: { supportedModes = MODES_OF_1X, supportsScheduling = false, properties = PROPERTIES_OF_1X } }) { return { supported: properties, configuration: { supportedModes, supportsScheduling } }; }, validate(capability) { const { supportedModes = MODES_OF_1X, properties = PROPERTIES_OF_1X } = capability.options; // alexa-thermostatcontroller.html, "Configuration object": "You must include at least one of HEAT or COOL" if (!supportedModes.includes("HEAT") && !supportedModes.includes("COOL")) { throw new types_js_1.DeclarationError(capability, `supportedModes ${supportedModes.join(", ")} has neither HEAT nor COOL, Alexa wants one`); } const lists = [supportedModes, properties]; for (const list of lists) { const twice = list.find((entry, i) => list.indexOf(entry) !== i); if (twice) throw new types_js_1.DeclarationError(capability, `${twice} is listed twice`); } }, errorNamespace: "Alexa.ThermostatController", errorTypes: [ "DUAL_SETPOINTS_UNSUPPORTED", "REQUESTED_SETPOINTS_TOO_CLOSE", "THERMOSTAT_IS_OFF", "TRIPLE_SETPOINTS_UNSUPPORTED", "UNSUPPORTED_THERMOSTAT_MODE", "UNWILLING_TO_SET_SCHEDULE", "UNWILLING_TO_SET_VALUE", ], });