UNPKG

homebridge-jci-hitachi-platform

Version:

Homebridge platform plugin providing HomeKit support for Jci Hitachi air conditioners.

346 lines 22 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const settings_1 = require("../settings"); const types_1 = require("../types"); var ClimateCommandType; (function (ClimateCommandType) { ClimateCommandType["Power"] = "Switch"; ClimateCommandType["Mode"] = "Mode"; ClimateCommandType["CurrentTemperature"] = "IndoorTemperature"; ClimateCommandType["TargetTemperature"] = "TemperatureSetting"; ClimateCommandType["FanSpeed"] = "FanSpeed"; ClimateCommandType["VerticalWindDirectionSwitch"] = "VerticalWindDirectionSwitch"; ClimateCommandType["HorizontalWindDirectionSetting"] = "HorizontalWindDirectionSetting"; ClimateCommandType["QuickMode"] = "QuickMode"; ClimateCommandType["CleanSwitch"] = "CleanSwitch"; })(ClimateCommandType || (ClimateCommandType = {})); var ClimateFanSpeedMode; (function (ClimateFanSpeedMode) { ClimateFanSpeedMode[ClimateFanSpeedMode["Auto"] = 0] = "Auto"; ClimateFanSpeedMode[ClimateFanSpeedMode["Silent"] = 1] = "Silent"; ClimateFanSpeedMode[ClimateFanSpeedMode["Low"] = 2] = "Low"; ClimateFanSpeedMode[ClimateFanSpeedMode["Medium"] = 3] = "Medium"; ClimateFanSpeedMode[ClimateFanSpeedMode["High"] = 4] = "High"; ClimateFanSpeedMode[ClimateFanSpeedMode["Rapid"] = 5] = "Rapid"; ClimateFanSpeedMode[ClimateFanSpeedMode["Express"] = 6] = "Express"; })(ClimateFanSpeedMode || (ClimateFanSpeedMode = {})); var ClimateMode; (function (ClimateMode) { ClimateMode[ClimateMode["Cool"] = 0] = "Cool"; ClimateMode[ClimateMode["Dry"] = 1] = "Dry"; ClimateMode[ClimateMode["FanOnly"] = 2] = "FanOnly"; ClimateMode[ClimateMode["Auto"] = 3] = "Auto"; ClimateMode[ClimateMode["Heat"] = 4] = "Heat"; })(ClimateMode || (ClimateMode = {})); /** * An instance of this class is created for each accessory the platform registers. * Each accessory may expose multiple services of different service types. */ class ClimateAccessory extends types_1.JciHitachiAccessory { constructor(platform, accessory) { var _a, _b; super(platform, accessory); this.platform = platform; this.accessory = accessory; this.services = []; if (!accessory.context.device === undefined) { this.platform.log.error('Device is undefined'); return; } // Accessory Information // https://developers.homebridge.io/#/service/AccessoryInformation (_a = this.accessory.getService(this.platform.Service.AccessoryInformation)) === null || _a === void 0 ? void 0 : _a.setCharacteristic(this.platform.Characteristic.Manufacturer, 'JciHitachi TW').setCharacteristic(this.platform.Characteristic.Model, accessory.context.device.Model || 'Unknown').setCharacteristic(this.platform.Characteristic.SerialNumber, this.accessory.UUID); (_b = this.accessory.getService(this.platform.Service.AccessoryInformation)) === null || _b === void 0 ? void 0 : _b.setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.accessory.context.device.FirmwareVersion || '0'); this.services['Climate'] = this.accessory.getService(this.platform.Service.HeaterCooler) || this.accessory.addService(this.platform.Service.HeaterCooler); // This is what is displayed as the default name on the Home app this.services['Climate'].setCharacteristic(this.platform.Characteristic.Name, accessory.context.device.CustomDeviceName || '空調'); this.services['Climate'] .getCharacteristic(this.platform.Characteristic.Active) .onSet(this.setActive.bind(this)) .onGet(this.getActive.bind(this)); this.services['Climate'] .getCharacteristic(this.platform.Characteristic.CurrentTemperature) .setProps({ minValue: -100, maxValue: 100, minStep: 0.01, }); this.services['Climate'] .getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState) .onGet(this.getCurrentHeaterCoolerState.bind(this)); this.services['Climate'] .getCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState) .onSet(this.setTargetHeaterCoolerState.bind(this)); // Cooling Threshold Temperature (optional) this.services['Climate'] .getCharacteristic(this.platform.Characteristic.CoolingThresholdTemperature) .setProps({ minValue: this.accessory.context.device.TemperatureSettingMin, maxValue: this.accessory.context.device.TemperatureSettingMax, minStep: 1, }) .onSet(this.setCoolingThresholdTemperature.bind(this)); // Heating Threshold Temperature (optional) this.services['Climate'] .getCharacteristic(this.platform.Characteristic.HeatingThresholdTemperature) .setProps({ minValue: this.accessory.context.device.TemperatureSettingMin, maxValue: this.accessory.context.device.TemperatureSettingMax, minStep: 1, }) .onSet(this.setHeatingThresholdTemperature.bind(this)); this.services['Climate'] .getCharacteristic(this.platform.Characteristic.RotationSpeed) .setProps({ minValue: 0, maxValue: 6, minStep: 1, }) .onGet(this.getRotationSpeed.bind(this)) .onSet(this.setRotationSpeed.bind(this)); ///// this.services['HumiditySensor'] = this.accessory.getService(this.platform.Service.HumiditySensor) || this.accessory.addService(this.platform.Service.HumiditySensor); this.services['HumiditySensor'].getCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity) .onGet(this.getCurrentRelativeHumidity.bind(this)); ///// this.services['AirQualitySensor'] = this.accessory.getService(this.platform.Service.AirQualitySensor) || this.accessory.addService(this.platform.Service.AirQualitySensor); this.services['AirQualitySensor'].getCharacteristic(this.platform.Characteristic.AirQuality) .onGet(this.getCurrentAirQuality.bind(this)); this.services['AirQualitySensor'].getCharacteristic(this.platform.Characteristic.PM2_5Density) .onGet(this.getCurrentPM2_5Density.bind(this)); this.services['AirQualitySensor'].getCharacteristic(this.platform.Characteristic.StatusActive) .onGet(this.getActive.bind(this)); ////////// if (this.platform.jciHitachiAWSAPI.isHost) { const buttonQuickModeName = '快速運轉'; this.services['QuickMode'] = this.accessory.getServiceById(this.platform.Service.Switch, ClimateCommandType.QuickMode) || this.accessory.addService(this.platform.Service.Switch, buttonQuickModeName, ClimateCommandType.QuickMode); this.services['QuickMode'].setCharacteristic(this.platform.Characteristic.Name, buttonQuickModeName); this.services['QuickMode'].getCharacteristic(this.platform.Characteristic.On) .onSet(this.setQuickMode.bind(this)) .onGet(this.getQuickMode.bind(this)); this.services['QuickMode'].addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName); this.services['QuickMode'].setCharacteristic(this.platform.Characteristic.ConfiguredName, buttonQuickModeName); const buttonCleanSwitch = '凍結洗淨'; this.services['CleanSwitch'] = this.accessory.getServiceById(this.platform.Service.Switch, ClimateCommandType.CleanSwitch) || this.accessory.addService(this.platform.Service.Switch, buttonCleanSwitch, ClimateCommandType.CleanSwitch); this.services['CleanSwitch'].setCharacteristic(this.platform.Characteristic.Name, buttonCleanSwitch); this.services['CleanSwitch'].getCharacteristic(this.platform.Characteristic.On) .onSet(this.setCleanSwitch.bind(this)) .onGet(this.getCleanSwitch.bind(this)); this.services['CleanSwitch'].addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName); this.services['CleanSwitch'].setCharacteristic(this.platform.Characteristic.ConfiguredName, buttonCleanSwitch); } /////////// this.services['LeakSensor'] = this.accessory.getService(this.platform.Service.LeakSensor) || this.accessory.addService(this.platform.Service.LeakSensor, '凍結洗淨通知'); this.services['LeakSensor'].setCharacteristic(this.platform.Characteristic.Name, '凍結洗淨通知'); this.services['LeakSensor'].getCharacteristic(this.platform.Characteristic.LeakDetected) .onGet(this.getCleanNotification.bind(this)); this.services['LeakSensor'].addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName); this.services['LeakSensor'].setCharacteristic(this.platform.Characteristic.ConfiguredName, '凍結洗淨通知'); this.refreshDeviceStatus(); } /** * Retrieves the device status from JciHitachi and updates its characteristics. */ async refreshDeviceStatus() { var _a; this.platform.log.debug(`Accessory: Refresh status for device '${this.accessory.displayName}'`); try { this.platform.jciHitachiAWSAPI.RefeshDevice(((_a = this.accessory.context.device) === null || _a === void 0 ? void 0 : _a.ThingName) || ''); } catch (error) { this.platform.log.error('An error occurred while refreshing the device status. Turn on debug mode for more information.'); if (error) { this.platform.log.debug(error); } } // Schedule continuous device updates on the first run if (!this._refreshInterval) { this._refreshInterval = setInterval(this.refreshDeviceStatus.bind(this), settings_1.DEVICE_STATUS_REFRESH_INTERVAL); } } async getStatus(actionName) { var _a; return this.platform.jciHitachiAWSAPI.GetDeviceStatus(((_a = this.accessory.context.device) === null || _a === void 0 ? void 0 : _a.ThingName) || '', actionName); } async setStatus(actionName, value) { var _a; return this.platform.jciHitachiAWSAPI.SetDeviceStatus(((_a = this.accessory.context.device) === null || _a === void 0 ? void 0 : _a.ThingName) || '', actionName, value); } async setActive(value) { this.platform.log.debug(`Accessory: setActive() for device '${this.accessory.displayName}'`); this.setStatus(ClimateCommandType.Power, value === this.platform.Characteristic.Active.ACTIVE ? 1 : 0); this.services['Climate'].updateCharacteristic(this.platform.Characteristic.Active, value); } async getActive() { return this.accessory.context.device.SwitchOn ? this.platform.Characteristic.Active.ACTIVE : this.platform.Characteristic.Active.INACTIVE; } async getRotationSpeed() { return this.accessory.context.device.FanSpeed ? this.accessory.context.device.FanSpeed : 0; } async setRotationSpeed(value) { this.setStatus(ClimateCommandType.FanSpeed, value); this.services['Climate'].updateCharacteristic(this.platform.Characteristic.RotationSpeed, value); } async setQuickMode(value) { this.platform.log.debug(`Accessory: setQuickMode() for device '${this.accessory.displayName}' to ${value}}`); this.setStatus(ClimateCommandType.QuickMode, value ? 1 : 0); this.services['QuickMode'].updateCharacteristic(this.platform.Characteristic.On, value); } async getQuickMode() { return this.accessory.context.device.QuickMode; } async setCleanSwitch(value) { this.platform.log.debug(`Accessory: setCleanSwitch() for device '${this.accessory.displayName}' to ${value}}`); this.setStatus(ClimateCommandType.CleanSwitch, value ? 1 : 0); this.services['CleanSwitch'].updateCharacteristic(this.platform.Characteristic.On, value); } async getCleanSwitch() { return this.accessory.context.device.CleanSwitch; } async getCleanNotification() { return this.accessory.context.device.CleanNotification; } async getCurrentHeaterCoolerState() { const currentTemperature = await this.getStatus(ClimateCommandType.CurrentTemperature) || 0; const setTemperature = await this.getStatus(ClimateCommandType.TargetTemperature) || 0; const currentMode = await this.getStatus(ClimateCommandType.Mode) || 0; switch (currentMode) { // Auto case ClimateMode.Auto: // Set target state and current state (based on current temperature) this.services['Climate'].updateCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState, this.platform.Characteristic.TargetHeaterCoolerState.AUTO); if (currentTemperature < setTemperature) { this.services['Climate'].getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState) .updateValue(this.platform.Characteristic.CurrentHeaterCoolerState.HEATING); } else if (currentTemperature > setTemperature) { this.services['Climate'].getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState) .updateValue(this.platform.Characteristic.CurrentHeaterCoolerState.COOLING); } else { this.services['Climate'].getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState) .updateValue(this.platform.Characteristic.CurrentHeaterCoolerState.IDLE); } break; // Heat case ClimateMode.Heat: this.services['Climate'].updateCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState, this.platform.Characteristic.TargetHeaterCoolerState.HEAT); if (currentTemperature < setTemperature) { this.services['Climate'].getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState) .updateValue(this.platform.Characteristic.CurrentHeaterCoolerState.HEATING); } else { this.services['Climate'].getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState) .updateValue(this.platform.Characteristic.CurrentHeaterCoolerState.IDLE); } break; // Cool case ClimateMode.Cool: this.services['Climate'].updateCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState, this.platform.Characteristic.TargetHeaterCoolerState.COOL); if (currentTemperature > setTemperature) { this.services['Climate'].getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState) .updateValue(this.platform.Characteristic.CurrentHeaterCoolerState.COOLING); } else { this.services['Climate'].getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState) .updateValue(this.platform.Characteristic.CurrentHeaterCoolerState.IDLE); } break; // Dry (Dehumidifier) case ClimateMode.Dry: this.services['Climate'].getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState) .updateValue(this.platform.Characteristic.CurrentHeaterCoolerState.IDLE); this.services['Climate'].updateCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState, this.platform.Characteristic.TargetHeaterCoolerState.AUTO); break; // Fan case ClimateMode.FanOnly: this.services['Climate'].getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState) .updateValue(this.platform.Characteristic.CurrentHeaterCoolerState.IDLE); this.services['Climate'].updateCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState, this.platform.Characteristic.TargetHeaterCoolerState.AUTO); break; default: this.platform.log.error(`Unknown TargetHeaterCoolerState state: '${this.accessory.displayName}' '${currentMode}'`); break; } return this.services['Climate'].getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState).value; } async setCoolingThresholdTemperature(value) { this.platform.log.debug(`Accessory: setCoolingThresholdTemperature() for device '${this.accessory.displayName}'`); const threshold = +value; this.setStatus(ClimateCommandType.TargetTemperature, threshold); this.services['Climate'].getCharacteristic(this.platform.Characteristic.CoolingThresholdTemperature) .updateValue(value); } async setHeatingThresholdTemperature(value) { this.platform.log.debug(`Accessory: setHeatingThresholdTemperature() for device '${this.accessory.displayName}'`); const threshold = +value; this.setStatus(ClimateCommandType.TargetTemperature, threshold); this.services['Climate'].getCharacteristic(this.platform.Characteristic.HeatingThresholdTemperature) .updateValue(value); } async setTargetHeaterCoolerState(value) { this.platform.log.debug(`Accessory: setTargetHeaterCoolerState() for device '${this.accessory.displayName}'`); let mode = ClimateMode.Auto; switch (value) { case this.platform.Characteristic.TargetHeaterCoolerState.AUTO: mode = ClimateMode.Auto; break; case this.platform.Characteristic.TargetHeaterCoolerState.COOL: mode = ClimateMode.Cool; break; case this.platform.Characteristic.TargetHeaterCoolerState.HEAT: mode = ClimateMode.Heat; break; default: this.platform.log.error('Unknown TargetHeaterCoolerState', value); return; } this.setStatus(ClimateCommandType.Mode, mode); this.services['Climate'].getCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState) .updateValue(value); } async getCurrentRelativeHumidity() { return this.accessory.context.device.IndoorHumidity || 0; } async getCurrentAirQuality() { const pm25 = this.accessory.context.device.PM25 || 0; const pm25Quality = pm25 <= 35 ? 1 : (pm25 <= 53 ? 2 : (pm25 <= 70 ? 3 : (pm25 <= 150 ? 4 : 5))); return pm25Quality; } async getCurrentPM2_5Density() { return this.accessory.context.device.PM25 || 0; } async updateStatus() { var _a, _b; if (this.platform.jciHitachiAWSAPI.isConnected == false) { this.platform.log.error('AWS IoT is not connected'); this.platform.jciHitachiAWSAPI.Login(); return; } let temperatureSetting = this.accessory.context.device.TemperatureSetting || 0; if (temperatureSetting > this.accessory.context.device.TemperatureSettingMax || temperatureSetting < this.accessory.context.device.TemperatureSettingMin) { temperatureSetting = this.accessory.context.device.IndoorTemperature || this.accessory.context.device.TemperatureSettingMin; } (_a = this.accessory.getService(this.platform.Service.AccessoryInformation)) === null || _a === void 0 ? void 0 : _a.setCharacteristic(this.platform.Characteristic.Model, this.accessory.context.device.Model || 'Unknown'); (_b = this.accessory.getService(this.platform.Service.AccessoryInformation)) === null || _b === void 0 ? void 0 : _b.setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.accessory.context.device.FirmwareVersion || '0'); this.services['Climate'].updateCharacteristic(this.platform.Characteristic.Name, this.accessory.context.device.CustomDeviceName || '空調'); this.services['Climate'].updateCharacteristic(this.platform.Characteristic.Active, this.accessory.context.device.SwitchOn || 0); this.services['Climate'].updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.accessory.context.device.IndoorTemperature || 0); this.services['Climate'].updateCharacteristic(this.platform.Characteristic.CoolingThresholdTemperature, temperatureSetting); this.services['Climate'].updateCharacteristic(this.platform.Characteristic.HeatingThresholdTemperature, temperatureSetting); this.services['Climate'].updateCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState, await this.getCurrentHeaterCoolerState()); this.services['HumiditySensor'].updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, this.accessory.context.device.IndoorHumidity || 0); this.services['AirQualitySensor'].updateCharacteristic(this.platform.Characteristic.AirQuality, await this.getCurrentAirQuality()); this.services['AirQualitySensor'].updateCharacteristic(this.platform.Characteristic.PM2_5Density, this.accessory.context.device.PM25 || 0); this.services['AirQualitySensor'].updateCharacteristic(this.platform.Characteristic.StatusActive, this.accessory.context.device.SwitchOn || 0); if (this.platform.jciHitachiAWSAPI.isHost) { this.services['QuickMode'].updateCharacteristic(this.platform.Characteristic.On, this.accessory.context.device.QuickMode || 0); this.services['CleanSwitch'].updateCharacteristic(this.platform.Characteristic.On, this.accessory.context.device.CleanSwitch || 0); } } } exports.default = ClimateAccessory; //# sourceMappingURL=climate.js.map