homebridge-panasonic-ac-platform
Version:
Homebridge platform plugin providing HomeKit support for Panasonic Comfort Cloud devices.
793 lines • 62.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* An instance of this class is created for each accessory the platform registers.
* Each accessory may expose multiple services of different service types.
*/
class IndoorUnitAccessory {
constructor(platform, accessory) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
this.platform = platform;
this.accessory = accessory;
this.sendDeviceUpdatePayload = {};
// Individual config for each device (if exists).
if (this.platform.platformConfig.devices) {
this.deviceConfig = this.platform.platformConfig.devices.find((item) => { var _a; return item.name === ((_a = accessory.context.device) === null || _a === void 0 ? void 0 : _a.deviceName); })
|| this.platform.platformConfig.devices.find((item) => { var _a; return item.name === ((_a = accessory.context.device) === null || _a === void 0 ? void 0 : _a.deviceGuid); });
}
// Accessory Information
(_a = this.accessory.getService(this.platform.Service.AccessoryInformation)) === null || _a === void 0 ? void 0 : _a.setCharacteristic(this.platform.Characteristic.Manufacturer, 'Panasonic').setCharacteristic(this.platform.Characteristic.Model, ((_b = accessory.context.device) === null || _b === void 0 ? void 0 : _b.deviceModuleNumber) || 'Unknown').setCharacteristic(this.platform.Characteristic.SerialNumber, ((_c = accessory.context.device) === null || _c === void 0 ? void 0 : _c.deviceGuid) || 'Unknown');
// Heater Cooler
// https://developers.homebridge.io/#/service/HeaterCooler
this.service = this.accessory.getService(this.platform.Service.HeaterCooler)
|| this.accessory.addService(this.platform.Service.HeaterCooler);
// Characteristics configuration
// Each service must implement at-minimum the "required characteristics"
// See https://developers.homebridge.io/#/service/HeaterCooler
// Name (optional)
// This is what is displayed as the default name on the Home app
this.service.setCharacteristic(this.platform.Characteristic.Name, ((_d = accessory.context.device) === null || _d === void 0 ? void 0 : _d.deviceName) || 'Unnamed');
// Active (required)
this.service.getCharacteristic(this.platform.Characteristic.Active).onSet(this.setActive.bind(this));
// Current Temperature (required)
this.service.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
.setProps({ minValue: -100, maxValue: 100, minStep: 0.01 });
// Target Heater-Cooler State (required)
this.service
.getCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState)
.onSet(this.setTargetHeaterCoolerState.bind(this));
// Rotation Speed (optional)
this.service
.getCharacteristic(this.platform.Characteristic.RotationSpeed)
.setProps({ minValue: 0, maxValue: 8, minStep: 1 })
.onSet(this.setRotationSpeed.bind(this));
// Swing Mode (optional)
this.service
.getCharacteristic(this.platform.Characteristic.SwingMode)
.onSet(this.setSwingMode.bind(this));
// Cooling Threshold Temperature (optional)
this.service
.getCharacteristic(this.platform.Characteristic.CoolingThresholdTemperature)
.setProps({ minValue: 16, maxValue: 30, minStep: 0.5 })
.onSet(this.setThresholdTemperature.bind(this));
// Heating Threshold Temperature (optional)
this.service
.getCharacteristic(this.platform.Characteristic.HeatingThresholdTemperature)
.setProps({ minValue: ((_e = this.deviceConfig) === null || _e === void 0 ? void 0 : _e.minHeatingTemperature) || 16, maxValue: 30, minStep: 0.5 })
.onSet(this.setThresholdTemperature.bind(this));
// Additional sensors and switches
// Inside temp.
if ((_f = this.deviceConfig) === null || _f === void 0 ? void 0 : _f.exposeInsideTemp) {
this.exposeInsideTemp = this.accessory.getService(this.accessory.displayName + ' inside temp')
|| this.accessory.addService(this.platform.Service.TemperatureSensor, this.accessory.displayName + ' inside temp', 'exposeInsideTemp');
this.exposeInsideTemp.setCharacteristic(this.platform.Characteristic.ConfiguredName, this.accessory.displayName + ' inside temp');
this.platform.log.debug(`${this.accessory.displayName}: add inside temp sensor`);
}
else {
const removeInsideTemp = this.accessory.getService(this.accessory.displayName + ' inside temp');
if (removeInsideTemp) {
this.accessory.removeService(removeInsideTemp);
this.platform.log.debug(`${this.accessory.displayName}: remove inside temp sensor`);
}
}
// Outdoor temp.
if ((_g = this.deviceConfig) === null || _g === void 0 ? void 0 : _g.exposeOutdoorTemp) {
this.exposeOutdoorTemp = this.accessory.getService(this.accessory.displayName + ' out temp')
|| this.accessory.addService(this.platform.Service.TemperatureSensor, this.accessory.displayName + ' out temp', 'exposeOutdoorTemp');
this.exposeOutdoorTemp.setCharacteristic(this.platform.Characteristic.ConfiguredName, this.accessory.displayName + ' out temp');
this.platform.log.debug(`${this.accessory.displayName}: add outdoor temp sensor`);
}
else {
const removeOutdoorTemp = this.accessory.getService(this.accessory.displayName + ' out temp');
if (removeOutdoorTemp) {
this.accessory.removeService(removeOutdoorTemp);
this.platform.log.debug(`${this.accessory.displayName}: remove outdoor temp sensor`);
}
}
// Power (on/off)
if ((_h = this.deviceConfig) === null || _h === void 0 ? void 0 : _h.exposePower) {
this.exposePower = this.accessory.getService(this.accessory.displayName + ' power')
|| this.accessory.addService(this.platform.Service.Switch, this.accessory.displayName + ' power', 'exposePower');
this.exposePower.setCharacteristic(this.platform.Characteristic.ConfiguredName, this.accessory.displayName + ' power');
this.exposePower
.getCharacteristic(this.platform.Characteristic.On)
.onSet(this.setPower.bind(this));
this.platform.log.debug(`${this.accessory.displayName}: add power (on/off) switch`);
}
else {
const removePower = this.accessory.getService(this.accessory.displayName + ' power');
if (removePower) {
this.accessory.removeService(removePower);
this.platform.log.debug(`${this.accessory.displayName}: remove power (on/off) switch`);
}
}
// Nanoe
if ((_j = this.deviceConfig) === null || _j === void 0 ? void 0 : _j.exposeNanoe) {
this.exposeNanoe = this.accessory.getService(this.accessory.displayName + ' nanoe')
|| this.accessory.addService(this.platform.Service.Switch, this.accessory.displayName + ' nanoe', 'exposeNanoe');
this.exposeNanoe.setCharacteristic(this.platform.Characteristic.ConfiguredName, this.accessory.displayName + ' nanoe');
this.exposeNanoe
.getCharacteristic(this.platform.Characteristic.On)
.onSet(this.setNanoe.bind(this));
this.platform.log.debug(`${this.accessory.displayName}: add nanoe switch`);
}
else {
const removeNanoe = this.accessory.getService(this.accessory.displayName + ' nanoe');
if (removeNanoe) {
this.accessory.removeService(removeNanoe);
this.platform.log.debug(`${this.accessory.displayName}: remove nanoe switch`);
}
}
// Inside cleaning
if (((_k = this.deviceStatusFull) === null || _k === void 0 ? void 0 : _k.insideCleaning) && ((_l = this.deviceConfig) === null || _l === void 0 ? void 0 : _l.exposeInsideCleaning)) {
this.exposeInsideCleaning = this.accessory.getService(this.accessory.displayName + ' inside cleaning')
|| this.accessory.addService(this.platform.Service.Switch, this.accessory.displayName + ' inside cleaning', 'exposeInsideCleaning');
this.exposeInsideCleaning.setCharacteristic(this.platform.Characteristic.ConfiguredName, this.accessory.displayName + ' inside cleaning');
this.exposeInsideCleaning
.getCharacteristic(this.platform.Characteristic.On)
.onSet(this.setInsideCleaning.bind(this));
this.platform.log.debug(`${this.accessory.displayName}: add inside cleaning switch`);
}
else {
const removeInsideCleaning = this.accessory.getService(this.accessory.displayName + ' inside cleaning');
if (removeInsideCleaning) {
this.accessory.removeService(removeInsideCleaning);
this.platform.log.debug(`${this.accessory.displayName}: remove inside cleaning switch`);
}
}
// Eco Navi
if ((_m = this.deviceConfig) === null || _m === void 0 ? void 0 : _m.exposeEcoNavi) {
this.exposeEcoNavi = this.accessory.getService(this.accessory.displayName + ' eco navi')
|| this.accessory.addService(this.platform.Service.Switch, this.accessory.displayName + ' eco navi', 'exposeEcoNavi');
this.exposeEcoNavi.setCharacteristic(this.platform.Characteristic.ConfiguredName, this.accessory.displayName + ' eco navi');
this.exposeEcoNavi
.getCharacteristic(this.platform.Characteristic.On)
.onSet(this.setEcoNavi.bind(this));
this.platform.log.debug(`${this.accessory.displayName}: add eco navi switch`);
}
else {
const removeEcoNavi = this.accessory.getService(this.accessory.displayName + ' eco navi');
if (removeEcoNavi) {
this.accessory.removeService(removeEcoNavi);
this.platform.log.debug(`${this.accessory.displayName}: remove eco navi switch`);
}
}
// Eco Function
if ((_o = this.deviceConfig) === null || _o === void 0 ? void 0 : _o.exposeEcoFunction) {
this.exposeEcoFunction = this.accessory.getService(this.accessory.displayName + ' eco function')
|| this.accessory.addService(this.platform.Service.Switch, this.accessory.displayName + ' eco function', 'exposeEcoFunction');
this.exposeEcoFunction.setCharacteristic(this.platform.Characteristic.ConfiguredName, this.accessory.displayName + ' eco function');
this.exposeEcoFunction
.getCharacteristic(this.platform.Characteristic.On)
.onSet(this.setEcoFunction.bind(this));
this.platform.log.debug(`${this.accessory.displayName}: add eco function switch`);
}
else {
const removeEcoFunction = this.accessory.getService(this.accessory.displayName + ' eco function');
if (removeEcoFunction) {
this.accessory.removeService(removeEcoFunction);
this.platform.log.debug(`${this.accessory.displayName}: remove eco function switch`);
}
}
// Cool mode
if ((_p = this.deviceConfig) === null || _p === void 0 ? void 0 : _p.exposeCoolMode) {
this.exposeCoolMode = this.accessory.getService(this.accessory.displayName + ' cool mode')
|| this.accessory.addService(this.platform.Service.Switch, this.accessory.displayName + ' cool mode', 'exposeCoolMode');
this.exposeCoolMode.setCharacteristic(this.platform.Characteristic.ConfiguredName, this.accessory.displayName + ' cool mode');
this.exposeCoolMode
.getCharacteristic(this.platform.Characteristic.On)
.onSet(this.setCoolMode.bind(this));
this.platform.log.debug(`${this.accessory.displayName}: add cool mode switch`);
}
else {
const removeCoolMode = this.accessory.getService(this.accessory.displayName + ' cool mode');
if (removeCoolMode) {
this.accessory.removeService(removeCoolMode);
this.platform.log.debug(`${this.accessory.displayName}: remove cool mode switch`);
}
}
// Heat mode
if ((_q = this.deviceConfig) === null || _q === void 0 ? void 0 : _q.exposeHeatMode) {
this.exposeHeatMode = this.accessory.getService(this.accessory.displayName + ' heat mode')
|| this.accessory.addService(this.platform.Service.Switch, this.accessory.displayName + ' heat mode', 'exposeHeatMode');
this.exposeHeatMode.setCharacteristic(this.platform.Characteristic.ConfiguredName, this.accessory.displayName + ' heat mode');
this.exposeHeatMode
.getCharacteristic(this.platform.Characteristic.On)
.onSet(this.setHeatMode.bind(this));
this.platform.log.debug(`${this.accessory.displayName}: add heat mode switch`);
}
else {
const removeHeatMode = this.accessory.getService(this.accessory.displayName + ' heat mode');
if (removeHeatMode) {
this.accessory.removeService(removeHeatMode);
this.platform.log.debug(`${this.accessory.displayName}: remove heat mode switch`);
}
}
// Dry mode
if ((_r = this.deviceConfig) === null || _r === void 0 ? void 0 : _r.exposeDryMode) {
this.exposeDryMode = this.accessory.getService(this.accessory.displayName + ' dry mode')
|| this.accessory.addService(this.platform.Service.Switch, this.accessory.displayName + ' dry mode', 'exposeDryMode');
this.exposeDryMode.setCharacteristic(this.platform.Characteristic.ConfiguredName, this.accessory.displayName + ' dry mode');
this.exposeDryMode
.getCharacteristic(this.platform.Characteristic.On)
.onSet(this.setDryMode.bind(this));
this.platform.log.debug(`${this.accessory.displayName}: add dry mode switch`);
}
else {
const removeDryMode = this.accessory.getService(this.accessory.displayName + ' dry mode');
if (removeDryMode) {
this.accessory.removeService(removeDryMode);
this.platform.log.debug(`${this.accessory.displayName}: remove dry mode switch`);
}
}
// Fan Mode
if ((_s = this.deviceConfig) === null || _s === void 0 ? void 0 : _s.exposeFanMode) {
this.exposeFanMode = this.accessory.getService(this.accessory.displayName + ' fan mode')
|| this.accessory.addService(this.platform.Service.Switch, this.accessory.displayName + ' fan mode', 'exposeFanMode');
this.exposeFanMode.setCharacteristic(this.platform.Characteristic.ConfiguredName, this.accessory.displayName + ' fan mode');
this.exposeFanMode
.getCharacteristic(this.platform.Characteristic.On)
.onSet(this.setFanMode.bind(this));
this.platform.log.debug(`${this.accessory.displayName}: add fan mode switch`);
}
else {
const removeFanMode = this.accessory.getService(this.accessory.displayName + ' fan mode');
if (removeFanMode) {
this.accessory.removeService(removeFanMode);
this.platform.log.debug(`${this.accessory.displayName}: remove fan mode switch`);
}
}
// Nanoe Stand Alone Mode
if ((_t = this.deviceConfig) === null || _t === void 0 ? void 0 : _t.exposeNanoeStandAloneMode) {
this.exposeNanoeStandAloneMode = this.accessory.getService(this.accessory.displayName + ' nanoe stand alone mode')
|| this.accessory.addService(this.platform.Service.Switch, this.accessory.displayName + ' nanoe stand alone mode', 'exposeNanoeStandAloneMode');
this.exposeNanoeStandAloneMode.setCharacteristic(this.platform.Characteristic.ConfiguredName, this.accessory.displayName + ' nanoe stand alone mode');
this.exposeNanoeStandAloneMode
.getCharacteristic(this.platform.Characteristic.On)
.onSet(this.setNanoeStandAloneMode.bind(this));
this.platform.log.debug(`${this.accessory.displayName}: add nanoe stand alone mode switch`);
}
else {
const removeNanoeStandAloneMode = this.accessory.getService(this.accessory.displayName + ' nanoe stand alone mode');
if (removeNanoeStandAloneMode) {
this.accessory.removeService(removeNanoeStandAloneMode);
this.platform.log.debug(`${this.accessory.displayName}: remove nanoe stand alone mode switch`);
}
}
// Quiet Mode
if ((_u = this.deviceConfig) === null || _u === void 0 ? void 0 : _u.exposeQuietMode) {
this.exposeQuietMode = this.accessory.getService(this.accessory.displayName + ' quiet mode')
|| this.accessory.addService(this.platform.Service.Switch, this.accessory.displayName + ' quiet mode', 'exposeQuietMode');
this.exposeQuietMode.setCharacteristic(this.platform.Characteristic.ConfiguredName, this.accessory.displayName + ' quiet mode');
this.exposeQuietMode
.getCharacteristic(this.platform.Characteristic.On)
.onSet(this.setQuietMode.bind(this));
this.platform.log.debug(`${this.accessory.displayName}: add quiet mode switch`);
}
else {
const removeQuietMode = this.accessory.getService(this.accessory.displayName + ' quiet mode');
if (removeQuietMode) {
this.accessory.removeService(removeQuietMode);
this.platform.log.debug(`${this.accessory.displayName}: remove quiet mode switch`);
}
}
// Powerful mode
if ((_v = this.deviceConfig) === null || _v === void 0 ? void 0 : _v.exposePowerfulMode) {
this.exposePowerfulMode = this.accessory.getService(this.accessory.displayName + ' powerful mode')
|| this.accessory.addService(this.platform.Service.Switch, this.accessory.displayName + ' powerful mode', 'exposePowerfulMode');
this.exposePowerfulMode.setCharacteristic(this.platform.Characteristic.ConfiguredName, this.accessory.displayName + ' powerful mode');
this.exposePowerfulMode
.getCharacteristic(this.platform.Characteristic.On)
.onSet(this.setPowerfulMode.bind(this));
this.platform.log.debug(`${this.accessory.displayName}: add powerful mode switch`);
}
else {
const removePowerfulMode = this.accessory.getService(this.accessory.displayName + ' powerful mode');
if (removePowerfulMode) {
this.accessory.removeService(removePowerfulMode);
this.platform.log.debug(`${this.accessory.displayName}: remove powerful mode switch`);
}
}
// Swing Up Down
if ((_w = this.deviceConfig) === null || _w === void 0 ? void 0 : _w.exposeSwingUpDown) {
this.exposeSwingUpDown = this.accessory.getService(this.accessory.displayName + ' swing up down')
|| this.accessory.addService(this.platform.Service.Switch, this.accessory.displayName + ' swing up down', 'exposeSwingUpDown');
this.exposeSwingUpDown.setCharacteristic(this.platform.Characteristic.ConfiguredName, this.accessory.displayName + ' swing up down');
this.exposeSwingUpDown
.getCharacteristic(this.platform.Characteristic.On)
.onSet(this.setSwingUpDown.bind(this));
this.platform.log.debug(`${this.accessory.displayName}: add swing up down switch`);
}
else {
const removeSwingUpDown = this.accessory.getService(this.accessory.displayName + ' swing up down');
if (removeSwingUpDown) {
this.accessory.removeService(removeSwingUpDown);
this.platform.log.debug(`${this.accessory.displayName}: remove swing up down switch`);
}
}
// Swing Left Right
if ((_x = this.deviceConfig) === null || _x === void 0 ? void 0 : _x.exposeSwingLeftRight) {
this.exposeSwingLeftRight = this.accessory.getService(this.accessory.displayName + ' swing left right')
|| this.accessory.addService(this.platform.Service.Switch, this.accessory.displayName + ' swing left right', 'exposeSwingLeftRight');
this.exposeSwingLeftRight.setCharacteristic(this.platform.Characteristic.ConfiguredName, this.accessory.displayName + ' swing left right');
this.exposeSwingLeftRight
.getCharacteristic(this.platform.Characteristic.On)
.onSet(this.setSwingLeftRight.bind(this));
this.platform.log.debug(`${this.accessory.displayName}: add swing left right switch`);
}
else {
const removeSwingLeftRight = this.accessory.getService(this.accessory.displayName + ' swing left right');
if (removeSwingLeftRight) {
this.accessory.removeService(removeSwingLeftRight);
this.platform.log.debug(`${this.accessory.displayName}: remove swing left right switch`);
}
}
// Fan speed
if ((_y = this.deviceConfig) === null || _y === void 0 ? void 0 : _y.exposeFanSpeed) {
this.exposeFanSpeed = this.accessory.getService(this.accessory.displayName + ' fan speed')
|| this.accessory.addService(this.platform.Service.Fan, this.accessory.displayName + ' fan speed', 'exposeFanSpeed');
this.exposeFanSpeed.setCharacteristic(this.platform.Characteristic.ConfiguredName, this.accessory.displayName + ' fan speed');
this.exposeFanSpeed
.getCharacteristic(this.platform.Characteristic.On)
.onSet(this.setFanSpeed.bind(this));
this.exposeFanSpeed
.getCharacteristic(this.platform.Characteristic.RotationSpeed)
.onSet(this.setFanSpeed.bind(this));
this.platform.log.debug(`${this.accessory.displayName}: add fan speed slider`);
}
else {
const removeFanSpeed = this.accessory.getService(this.accessory.displayName + ' fan speed');
if (removeFanSpeed) {
this.accessory.removeService(removeFanSpeed);
this.platform.log.debug(`${this.accessory.displayName}: remove fan speed slider`);
}
}
// Update characteristic values asynchronously instead of using onGet handlers
this.refreshDeviceStatus();
}
// ===============================================================================================================================================
/**
* Retrieves the device status from Comfort Cloud and updates its characteristics.
*/
async refreshDeviceStatus() {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
let logOutput = '';
this.platform.log.debug(`${this.accessory.displayName}: refresh status`);
try {
this.deviceStatusFull = await this.platform.comfortCloud.getDeviceStatus(this.accessory.context.device.deviceGuid, this.accessory.displayName);
this.deviceStatus = this.deviceStatusFull.parameters;
// Active
if (this.deviceStatus.operate !== undefined) {
const active = this.deviceStatus.operate === 1
? this.platform.Characteristic.Active.ACTIVE
: this.platform.Characteristic.Active.INACTIVE;
this.service.updateCharacteristic(this.platform.Characteristic.Active, active);
logOutput += `${(active === 1) ? 'On' : 'Off'}`;
}
// Current Temperature
// If the temperature of the indoor unit is not available,
// default values will be used: 8°C for heating and 30°C for cooling and else.
// Temperature of 126 or higher from the API = null/failure
if (this.deviceStatus.insideTemperature < 126) {
this.service.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.deviceStatus.insideTemperature);
logOutput += `, Inside Temp. ${this.deviceStatus.insideTemperature}`;
}
else {
logOutput += ', Inside Temp. not available';
this.platform.log.debug(`${this.accessory.displayName}: Inside temperature is not available - setting default temperature`);
this.service.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, (this.deviceStatus.operationMode === 3) ? 8 : 30);
}
// Inside temperature for virtual sensor
if (this.exposeInsideTemp && this.deviceStatus.insideTemperature < 126) {
(_a = this.exposeInsideTemp) === null || _a === void 0 ? void 0 : _a.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.deviceStatus.insideTemperature);
}
// Outdoor temperature for logs
if (this.deviceStatus.outTemperature >= 126) {
logOutput += ', Outdoor Temp. not available';
}
else {
logOutput += `, Outdoor Temp. ${this.deviceStatus.outTemperature}`;
}
// Outdoor temperature for virtual sensor
// Only check and set if the user wants to display the virtual sensor showing temp from outdoor unit.
if (this.exposeOutdoorTemp && this.deviceStatus.outTemperature < 126) {
(_b = this.exposeOutdoorTemp) === null || _b === void 0 ? void 0 : _b.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.deviceStatus.outTemperature);
}
// Current Heater-Cooler State and Target Heater-Cooler State
const currentTemp = this.service.getCharacteristic(this.platform.Characteristic.CurrentTemperature).value;
const setTemp = this.deviceStatus.temperatureSet;
const { operationMode } = this.deviceStatus;
const modes = {
0: { log: 'Auto Mode', target: 'AUTO', current: currentTemp < setTemp ? 'HEATING' : currentTemp > setTemp ? 'COOLING' : 'IDLE' },
3: { log: 'Heat Mode', target: 'HEAT', current: currentTemp < setTemp ? 'HEATING' : 'IDLE' },
2: { log: 'Cool Mode', target: 'COOL', current: currentTemp > setTemp ? 'COOLING' : 'IDLE' },
1: { log: 'Dry Mode', target: 'AUTO', current: 'IDLE' },
4: { log: 'Fan Mode', target: 'AUTO', current: 'IDLE' },
};
if (modes[operationMode]) {
const { log, target, current } = modes[operationMode];
logOutput += `, ${log}`;
this.service.updateCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState, this.platform.Characteristic.TargetHeaterCoolerState[target]);
this.service.updateCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState, this.platform.Characteristic.CurrentHeaterCoolerState[current]);
}
else {
this.platform.log.error(`Unknown operation mode: '${operationMode}'`);
}
// Rotation Speed
/**
* 1) The fanSpeed value in the Comfort Cloud payload doesn't always reflect
* the current operation mode. For example, when switching from
* fan speed 4 to Quiet Mode, the fanSpeed in the payload will remain 4.
* Based on tests, ecoMode seems to take precedence and we'll check it first.
*
* 2) HomeKit automatically moves the slider into the 0 position when
* the device is switched off. We don't have to handle this case manually.
*
* 3) See README for the mapping of Comfort Cloud payload to slider position.
*/
// Check status only when device is on
if (this.deviceStatus.operate === 1) {
let sliderValue = 8; // default AUTO
if (this.deviceStatus.ecoMode === 2) {
sliderValue = 1; // Quiet Mode
logOutput += ', Speed 1 (Quiet Mode)';
}
else if (this.deviceStatus.ecoMode === 1) {
sliderValue = 7; // Powerful Mode
logOutput += ', Speed 5 (Powerful Mode)';
}
else if (this.deviceStatus.ecoMode === 0) {
const fanSpeedMap = { 0: 8, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6 };
sliderValue = fanSpeedMap[this.deviceStatus.fanSpeed] || 8;
logOutput += `, Speed ${this.deviceStatus.fanSpeed || 'Auto'}`;
}
this.service.getCharacteristic(this.platform.Characteristic.RotationSpeed)
.updateValue(sliderValue);
}
// Swing Mode
if (this.deviceStatus.fanAutoMode !== 1) {
this.service.getCharacteristic(this.platform.Characteristic.SwingMode)
.updateValue(this.platform.Characteristic.SwingMode.SWING_ENABLED);
}
else {
this.service.getCharacteristic(this.platform.Characteristic.SwingMode)
.updateValue(this.platform.Characteristic.SwingMode.SWING_DISABLED);
}
// Expose additional features
const isOn = this.deviceStatus.operate === 1;
(_c = this.exposePower) === null || _c === void 0 ? void 0 : _c.updateCharacteristic(this.platform.Characteristic.On, isOn);
(_d = this.exposeNanoe) === null || _d === void 0 ? void 0 : _d.updateCharacteristic(this.platform.Characteristic.On, this.deviceStatus.nanoe === 2);
(_e = this.exposeInsideCleaning) === null || _e === void 0 ? void 0 : _e.updateCharacteristic(this.platform.Characteristic.On, this.deviceStatus.insideCleaning === 2);
(_f = this.exposeEcoNavi) === null || _f === void 0 ? void 0 : _f.updateCharacteristic(this.platform.Characteristic.On, this.deviceStatus.ecoNavi === 2);
(_g = this.exposeEcoFunction) === null || _g === void 0 ? void 0 : _g.updateCharacteristic(this.platform.Characteristic.On, this.deviceStatus.ecoFunctionData === 2);
(_h = this.exposeAutoMode) === null || _h === void 0 ? void 0 : _h.updateCharacteristic(this.platform.Characteristic.On, isOn && this.deviceStatus.operationMode === 0);
(_j = this.exposeCoolMode) === null || _j === void 0 ? void 0 : _j.updateCharacteristic(this.platform.Characteristic.On, isOn && this.deviceStatus.operationMode === 2);
(_k = this.exposeHeatMode) === null || _k === void 0 ? void 0 : _k.updateCharacteristic(this.platform.Characteristic.On, isOn && this.deviceStatus.operationMode === 3);
(_l = this.exposeDryMode) === null || _l === void 0 ? void 0 : _l.updateCharacteristic(this.platform.Characteristic.On, isOn && this.deviceStatus.operationMode === 1);
(_m = this.exposeFanMode) === null || _m === void 0 ? void 0 : _m.updateCharacteristic(this.platform.Characteristic.On, isOn && this.deviceStatus.operationMode === 4
&& this.deviceStatus.lastSettingMode === 1);
(_o = this.exposeNanoeStandAloneMode) === null || _o === void 0 ? void 0 : _o.updateCharacteristic(this.platform.Characteristic.On, isOn && this.deviceStatus.operationMode === 4
&& this.deviceStatus.lastSettingMode === 2);
(_p = this.exposeSwingUpDown) === null || _p === void 0 ? void 0 : _p.updateCharacteristic(this.platform.Characteristic.On, [0, 2].includes(this.deviceStatus.fanAutoMode));
(_q = this.exposeSwingLeftRight) === null || _q === void 0 ? void 0 : _q.updateCharacteristic(this.platform.Characteristic.On, [0, 3].includes(this.deviceStatus.fanAutoMode));
if (isOn) {
(_r = this.exposeQuietMode) === null || _r === void 0 ? void 0 : _r.updateCharacteristic(this.platform.Characteristic.On, this.deviceStatus.ecoMode === 2);
(_s = this.exposePowerfulMode) === null || _s === void 0 ? void 0 : _s.updateCharacteristic(this.platform.Characteristic.On, this.deviceStatus.ecoMode === 1);
}
// Expose fan speed
if (this.exposeFanSpeed) {
const isOn = this.deviceStatus.operate === 1;
const fanSpeed = this.deviceStatus.fanSpeed;
const speedMap = { 1: 10, 2: 30, 3: 50, 4: 70, 5: 90 };
const rotationSpeed = isOn ? (speedMap[fanSpeed] || 100) : 0;
this.exposeFanSpeed.updateCharacteristic(this.platform.Characteristic.On, isOn);
this.exposeFanSpeed.updateCharacteristic(this.platform.Characteristic.RotationSpeed, rotationSpeed);
}
// Cooling Threshold Temperature (optional)
// Heating Threshold Temperature (optional)
this.service.getCharacteristic(this.platform.Characteristic.HeatingThresholdTemperature)
.updateValue(setTemp);
this.service.getCharacteristic(this.platform.Characteristic.CoolingThresholdTemperature)
.updateValue(setTemp);
// log
if (this.platform.platformConfig.logsLevel >= 1) {
this.platform.log.info(`${this.accessory.displayName}: ${logOutput}.`);
}
}
catch (error) {
this.platform.log.error('An error occurred while refreshing the device status. '
+ 'Turn on debug mode for more information.');
// Only log if a Promise rejection reason was provided.
// Some errors are already logged at source.
if (error) {
this.platform.log.debug(error);
}
// if you need to return an error to show the device as "Not Responding" in the Home app:
// throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
/**
* We should be able to pass an error object to the function to mark a service/accessory
* as 'Not Responding' in the Home App.
* (Only needs to be set on a single/primary characteristic of an accessory,
* and needs to be updated with a valid value when the accessory is available again.
* The error message text is for internal use only, and is not passed to the Home App.)
*
* Problem: The Typescript definitions suggest this is not permitted - commenting for now.
*/
/*
this.service.updateCharacteristic(
this.platform.Characteristic.Active,
new Error('Exception occurred in refreshDeviceStatus()'),
);
*/
}
// Set refresh inteval
clearTimeout(this.timerRefreshDeviceStatus);
this.timerRefreshDeviceStatus = null;
const isActive = this.service.getCharacteristic(this.platform.Characteristic.Active).value === 1;
const refreshWhenOn = (_u = (_t = this.deviceConfig) === null || _t === void 0 ? void 0 : _t.refreshWhenOn) !== null && _u !== void 0 ? _u : 10;
const refreshWhenOff = (_w = (_v = this.deviceConfig) === null || _v === void 0 ? void 0 : _v.refreshWhenOff) !== null && _w !== void 0 ? _w : 60;
if ((isActive === true && refreshWhenOn !== 0) || (isActive === false && refreshWhenOff !== 0)) {
this.timerRefreshDeviceStatus = setTimeout(this.refreshDeviceStatus.bind(this), isActive ? refreshWhenOn * 60000 : refreshWhenOff * 60000);
}
}
// ===============================================================================================================================================
/**
* Handle 'SET' requests from HomeKit
* These are sent when the user changes the state of an accessory,
* for example, turning on a Light bulb.
*/
async setActive(value) {
this.platform.log.debug(`${this.accessory.displayName}: setActive()`);
const parameters = {
operate: value === this.platform.Characteristic.Active.ACTIVE ? 1 : 0,
};
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: ${value === this.platform.Characteristic.Active.ACTIVE ? 'set On' : 'set Off'}`);
this.sendDeviceUpdate(this.accessory.context.device.deviceGuid, parameters);
}
async setTargetHeaterCoolerState(value) {
this.platform.log.debug(`${this.accessory.displayName}: setTargetHeaterCoolerState()`);
const parameters = {
operate: 1,
};
switch (value) {
case this.platform.Characteristic.TargetHeaterCoolerState.AUTO:
if (this.platform.platformConfig.autoMode === 'fan') {
parameters.operationMode = 4;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Fan Mode`);
}
else if (this.platform.platformConfig.autoMode === 'dry') {
parameters.operationMode = 1;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Dry mode`);
}
else {
parameters.operationMode = 0;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Auto mode`);
}
break;
case this.platform.Characteristic.TargetHeaterCoolerState.COOL:
parameters.operationMode = 2;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Mode Cool`);
break;
case this.platform.Characteristic.TargetHeaterCoolerState.HEAT:
parameters.operationMode = 3;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Mode Heat`);
break;
default:
this.platform.log.error(`${this.accessory.displayName}: Unknown TargetHeaterCoolerState`, value);
return;
}
this.sendDeviceUpdate(this.accessory.context.device.deviceGuid, parameters);
}
async setRotationSpeed(value) {
this.platform.log.debug(`${this.accessory.displayName}: setRotationSpeed()`);
const parameters = {};
switch (value) {
// See README for the mapping of slider position to Comfort Cloud payload.
case 0:
// HomeKit independently switches off the accessory
// in this case, which triggers setActive().
// Nothing to handle here, but documenting for clarity.
break;
case 1:
parameters.ecoMode = 2;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Quiet Mode`);
break;
case 2:
case 3:
case 4:
case 5:
case 6:
parameters.ecoMode = 0;
parameters.fanSpeed = value - 1;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Fan speed ${value - 1}`);
break;
case 7:
parameters.ecoMode = 1;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Powerful Mode`);
break;
case 8:
parameters.ecoMode = 0;
parameters.fanSpeed = 0;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Auto Mode`);
break;
default:
parameters.ecoMode = 0;
parameters.fanSpeed = 0;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Auto Mode`);
break;
}
this.sendDeviceUpdate(this.accessory.context.device.deviceGuid, parameters);
}
async setSwingMode(value) {
var _a, _b, _c, _d;
this.platform.log.debug(`${this.accessory.displayName}: setSwingMode()`);
const parameters = {};
if (value === this.platform.Characteristic.SwingMode.SWING_ENABLED) {
parameters.fanAutoMode = 0;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Swing mode Auto`);
}
else if (value === this.platform.Characteristic.SwingMode.SWING_DISABLED) {
parameters.fanAutoMode = 1;
parameters.airSwingUD = (((_a = this.deviceConfig) === null || _a === void 0 ? void 0 : _a.swingDefaultUD) !== null) ? (_b = this.deviceConfig) === null || _b === void 0 ? void 0 : _b.swingDefaultUD : 2;
parameters.airSwingLR = (((_c = this.deviceConfig) === null || _c === void 0 ? void 0 : _c.swingDefaultLR) !== null) ? (_d = this.deviceConfig) === null || _d === void 0 ? void 0 : _d.swingDefaultLR : 2;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Swing mode Off`);
}
this.sendDeviceUpdate(this.accessory.context.device.deviceGuid, parameters);
}
// set Power (on/off)
async setPower(value) {
this.platform.log.debug(`${this.accessory.displayName}: setPower()`);
const parameters = {};
if (value) {
parameters.operate = 1;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Power On`);
}
else {
parameters.operate = 0;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Power Off`);
}
this.sendDeviceUpdate(this.accessory.context.device.deviceGuid, parameters);
}
// set Nanoe
async setNanoe(value) {
this.platform.log.debug(`${this.accessory.displayName}: setNanoe()`);
const parameters = {};
if (value) {
parameters.nanoe = 2;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Nanoe On`);
}
else {
parameters.nanoe = 1;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Nanoe Off`);
}
this.sendDeviceUpdate(this.accessory.context.device.deviceGuid, parameters);
}
// set Inside Cleaning
async setInsideCleaning(value) {
this.platform.log.debug(`${this.accessory.displayName}: setInsideCleaning()`);
const parameters = {};
if (value) {
parameters.insideCleaning = 2;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Inside Cleaning On`);
}
else {
parameters.insideCleaning = 1;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Inside Cleaning Off`);
}
this.sendDeviceUpdate(this.accessory.context.device.deviceGuid, parameters);
}
// set Eco Navi
async setEcoNavi(value) {
this.platform.log.debug(`${this.accessory.displayName}: setEcoNavi()`);
const parameters = {};
if (value) {
parameters.ecoNavi = 2;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Eco Navi On`);
}
else {
parameters.ecoNavi = 1;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Eco Navi Off`);
}
this.sendDeviceUpdate(this.accessory.context.device.deviceGuid, parameters);
}
// set Eco Function
async setEcoFunction(value) {
this.platform.log.debug(`${this.accessory.displayName}: setEcoFunction()`);
const parameters = {};
if (value) {
parameters.ecoFunctionData = 2;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Eco Function On`);
}
else {
parameters.ecoFunctionData = 1;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Eco Function Off`);
}
this.sendDeviceUpdate(this.accessory.context.device.deviceGuid, parameters);
}
// set Auto Mode
async setAutoMode(value) {
this.platform.log.debug(`${this.accessory.displayName}: setAutoMode()`);
const parameters = {};
if (value) {
parameters.operate = 1;
parameters.operationMode = 0;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Auto Mode On`);
}
else {
parameters.operate = 0;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Auto Mode Off`);
}
this.sendDeviceUpdate(this.accessory.context.device.deviceGuid, parameters);
}
// set Cool Mode
async setCoolMode(value) {
this.platform.log.debug(`${this.accessory.displayName}: setCoolMode()`);
const parameters = {};
if (value) {
parameters.operate = 1;
parameters.operationMode = 2;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Cool Mode On`);
}
else {
parameters.operate = 0;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Cool Mode Off`);
}
this.sendDeviceUpdate(this.accessory.context.device.deviceGuid, parameters);
}
// set Heat Mode
async setHeatMode(value) {
this.platform.log.debug(`${this.accessory.displayName}: setHeatMode()`);
const parameters = {};
if (value) {
parameters.operate = 1;
parameters.operationMode = 3;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Heat Mode On`);
}
else {
parameters.operate = 0;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Heat Mode Off`);
}
this.sendDeviceUpdate(this.accessory.context.device.deviceGuid, parameters);
}
// set Dry Mode
async setDryMode(value) {
this.platform.log.debug(`${this.accessory.displayName}: setDryMode()`);
const parameters = {};
if (value) {
parameters.operate = 1;
parameters.operationMode = 1;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Dry Mode On`);
}
else {
parameters.operate = 0;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Dry Mode Off`);
}
this.sendDeviceUpdate(this.accessory.context.device.deviceGuid, parameters);
}
// set Fan Mode
async setFanMode(value) {
this.platform.log.debug(`${this.accessory.displayName}: setFanMode()`);
const parameters = {};
if (value) {
parameters.operate = 1;
parameters.operationMode = 4;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Fan Mode On`);
}
else {
parameters.operate = 0;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Fan Mode Off`);
}
this.sendDeviceUpdate(this.accessory.context.device.deviceGuid, parameters);
}
// set Nanoe Stand Alone Mode
async setNanoeStandAloneMode(value) {
this.platform.log.debug(`${this.accessory.displayName}: setNanoeStandAloneMode()`);
const parameters = {};
if (value) {
parameters.operate = 1;
parameters.operationMode = 5;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.displayName}: Nanoe Stand Alone Mode On`);
}
else {
parameters.operate = 0;
this.platform.log[(this.platform.platformConfig.logsLevel >= 1) ? 'info' : 'debug'](`${this.accessory.disp