homebridge-jci-hitachi-platform
Version:
Homebridge platform plugin providing HomeKit support for Jci Hitachi air conditioners.
346 lines • 22 kB
JavaScript
"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