@homebridge-plugins/homebridge-smarthq
Version:
The SmartHQ plugin allows you to interact with SmartHQ Devices in HomeKit and with Siri.
575 lines • 28.6 kB
JavaScript
import axios from 'axios';
import { interval, startWith } from 'rxjs';
import { ERD_TYPES, } from '../settings.js';
import { deviceBase } from './device.js';
var PowerState;
(function (PowerState) {
PowerState["ON"] = "01";
PowerState["OFF"] = "00";
})(PowerState || (PowerState = {}));
var TemperatureUnit;
(function (TemperatureUnit) {
TemperatureUnit["FAHRENHEIT"] = "00";
TemperatureUnit["CELSIUS"] = "01";
})(TemperatureUnit || (TemperatureUnit = {}));
var FanSetting;
(function (FanSetting) {
FanSetting["AUTO"] = "01";
FanSetting["LOW"] = "02";
FanSetting["MED"] = "04";
FanSetting["HIGH"] = "08";
})(FanSetting || (FanSetting = {}));
var FilterStatus;
(function (FilterStatus) {
FilterStatus["OK"] = "00";
FilterStatus["CLEAN"] = "01";
})(FilterStatus || (FilterStatus = {}));
var OperationMode;
(function (OperationMode) {
OperationMode["COOL"] = "00";
OperationMode["FAN_ONLY"] = "01";
OperationMode["ENERGY_SAVER"] = "02";
OperationMode["DRY"] = "04";
})(OperationMode || (OperationMode = {}));
export class SmartHQAirConditioner extends deviceBase {
platform;
accessory;
device;
// HeaterCooler service
HEATER_COOLER_SVC_NAME = 'AIR_CONDITIONER';
heaterCoolerSvc;
// Mode SwitchServices
MODE_SWITCH_SVC_PREFIX = 'AIR_CONDITIONER_MODE';
modeSwitchSvc;
constructor(platform, accessory, device) {
super(platform, accessory, device);
this.platform = platform;
this.accessory = accessory;
this.device = device;
// HeaterCooler service
this.heaterCoolerSvc = this.accessory.getService(this.HEATER_COOLER_SVC_NAME)
?? this.accessory.addService(this.platform.Service.HeaterCooler, accessory.displayName, this.HEATER_COOLER_SVC_NAME);
// Mode SwitchServices
this.modeSwitchSvc = {
[OperationMode.COOL]: this.accessory.getService(`${this.MODE_SWITCH_SVC_PREFIX}_COOL`)
?? this.accessory.addService(this.platform.Service.Switch, `${accessory.displayName} Cool Mode`, `${this.MODE_SWITCH_SVC_PREFIX}_COOL`),
[OperationMode.FAN_ONLY]: this.accessory.getService(`${this.MODE_SWITCH_SVC_PREFIX}_FAN_ONLY`)
?? this.accessory.addService(this.platform.Service.Switch, `${accessory.displayName} Fan Only Mode`, `${this.MODE_SWITCH_SVC_PREFIX}_FAN_ONLY`),
[OperationMode.ENERGY_SAVER]: this.accessory.getService(`${this.MODE_SWITCH_SVC_PREFIX}_ENERGY_SAVER`)
?? this.accessory.addService(this.platform.Service.Switch, `${accessory.displayName} Energy Saver Mode`, `${this.MODE_SWITCH_SVC_PREFIX}_ENERGY_SAVER`),
[OperationMode.DRY]: this.accessory.getService(`${this.MODE_SWITCH_SVC_PREFIX}_DRY`)
?? this.accessory.addService(this.platform.Service.Switch, `${accessory.displayName} Dry Mode`, `${this.MODE_SWITCH_SVC_PREFIX}_DRY`),
};
// Active
this.heaterCoolerSvc
.getCharacteristic(this.platform.Characteristic.Active)
.onGet(this.handleGetActive.bind(this))
.onSet(this.handleSetActive.bind(this));
// Current mode
this.heaterCoolerSvc
.getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState)
.setProps({
validValues: [
this.platform.Characteristic.CurrentHeaterCoolerState.INACTIVE,
this.platform.Characteristic.CurrentHeaterCoolerState.IDLE,
this.platform.Characteristic.CurrentHeaterCoolerState.COOLING,
],
})
.onGet(this.handleGetCurrentHeaterCoolerState.bind(this));
// Target mode (COOL only)
this.heaterCoolerSvc
.getCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState)
.setProps({
validValues: [
this.platform.Characteristic.TargetHeaterCoolerState.COOL,
],
})
.onGet(this.handleGetTargetHeaterCoolerState.bind(this))
.onSet(this.handleSetTargetHeaterCoolerState.bind(this));
// Ambient temp
this.heaterCoolerSvc
.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
.onGet(this.handleGetCurrentTemperature.bind(this));
// Target temperature
this.heaterCoolerSvc
.getCharacteristic(this.platform.Characteristic.CoolingThresholdTemperature)
.setProps({
minValue: 17.7778, // 64F
maxValue: 30, // 86F
})
.onGet(this.handleGetCoolingThresholdTemperature.bind(this))
.onSet(this.handleSetCoolingThresholdTemperature.bind(this));
// Rotation speed
this.heaterCoolerSvc
.getCharacteristic(this.platform.Characteristic.RotationSpeed)
.onGet(this.handleGetRotationSpeed.bind(this))
.onSet(this.handleSetRotationSpeed.bind(this));
// Display units
this.heaterCoolerSvc
.getCharacteristic(this.platform.Characteristic.TemperatureDisplayUnits)
.onGet(this.handleGetTemperatureDisplayUnits.bind(this))
.onSet(this.handleSetTemperatureDisplayUnits.bind(this));
// Filter
this.heaterCoolerSvc
.getCharacteristic(this.platform.Characteristic.FilterChangeIndication)
.onGet(this.handleGetFilterChangeIndication.bind(this));
// Modes
for (const mode of Object.values(OperationMode)) {
this.modeSwitchSvc[mode]
.getCharacteristic(this.platform.Characteristic.On)
.onGet(this.handleGetOperationMode.bind(this, mode))
.onSet(this.handleSetOperationMode.bind(this, mode));
}
// Start an update interval to refresh state
interval(this.deviceRefreshRate * 1000)
.pipe(startWith(0))
.subscribe(this.refreshState.bind(this));
}
// API
async getErdValue(erd) {
try {
const response = await axios.get(`/appliance/${this.accessory.context.device.applianceId}/erd/${erd}`);
return response.data.value;
}
catch (cause) {
throw new Error(axios.isAxiosError(cause) && cause.response
? `Failed to fetch ERD: ${cause.response.data.message}`
: `Failed to fetch ERD: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
}
}
async setErdValue(erd, value) {
try {
await axios.post(`/appliance/${this.accessory.context.device.applianceId}/erd/${erd}`, {
kind: 'appliance#erdListEntry',
userId: this.accessory.context.userId,
applianceId: this.accessory.context.device.applianceId,
erd,
value,
});
this.platform.log.debug(`[${this.accessory.displayName}] Set ERD ${erd}=${value}`);
}
catch (cause) {
throw new Error(axios.isAxiosError(cause) && cause.response
? `Failed to set ERD value for ${erd}: ${cause.response.data.message}`
: `Failed to set ERD value for ${erd}: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
}
}
async getPowerState() {
const erdValue = await this.getErdValue(ERD_TYPES.AIR_CONDITIONER_POWER_STATUS);
return erdValue;
}
async setPowerState(value) {
await this.setErdValue(ERD_TYPES.AIR_CONDITIONER_POWER_STATUS, value);
this.platform.log.debug(`[${this.accessory.displayName}] Set power state to ${value}`);
}
async getAmbientTemperature() {
try {
const erdValue = await this.getErdValue(ERD_TYPES.AIR_CONDITIONER_AMBIENT_TEMPERATURE);
const temperatureInFahrenheit = Number.parseInt(erdValue, 16); // erdValue is a hex string representing the temperature in Fahrenheit
return this.fahrenheitToCelsius(temperatureInFahrenheit); // homekit expects Celsius
}
catch (cause) {
throw new Error(`Failed to get current temperature: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
}
}
async getTemperature() {
try {
const erdValue = await this.getErdValue(ERD_TYPES.AIR_CONDITIONER_TARGET_TEMPERATURE);
const temperatureInFahrenheit = Number.parseInt(erdValue, 16); // erdValue is a hex string representing the temperature in Fahrenheit
return this.fahrenheitToCelsius(temperatureInFahrenheit); // homekit expects Celsius
}
catch (cause) {
throw new Error(`Failed to get target temperature: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
}
}
async setTemperature(value) {
try {
const temperatureInFahrenheit = this.celsiusToFahrenheit(value);
const hexTemperature = temperatureInFahrenheit.toString(16).padStart(4, '0').toUpperCase(); // Convert to hex and ensure it's 4 characters long
await this.setErdValue(ERD_TYPES.AIR_CONDITIONER_TARGET_TEMPERATURE, hexTemperature);
this.platform.log.debug(`[${this.accessory.displayName}] Set temperature to ${value}°C (${temperatureInFahrenheit}°F)`);
}
catch (cause) {
throw new Error(`Failed to set target temperature: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
}
}
async getTemperatureDisplayUnits() {
try {
const value = await this.getErdValue(ERD_TYPES.AIR_CONDITIONER_TEMPERATURE_UNIT);
return value;
}
catch (cause) {
throw new Error(`Failed to get temperature display units: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
}
}
async setTemperatureDisplayUnits(value) {
try {
await this.setErdValue(ERD_TYPES.AIR_CONDITIONER_TEMPERATURE_UNIT, value);
this.platform.log.debug(`[${this.accessory.displayName}] Set temperature display units to ${value}`);
}
catch (cause) {
throw new Error(`Failed to set temperature display units: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
}
}
async getOperationMode() {
try {
const value = await this.getErdValue(ERD_TYPES.AIR_CONDITIONER_OPERATION_MODE);
return value;
}
catch (cause) {
throw new Error(`Failed to get operation mode: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
}
}
async setOperationMode(value) {
try {
await this.setErdValue(ERD_TYPES.AIR_CONDITIONER_OPERATION_MODE, value);
this.platform.log.debug(`[${this.accessory.displayName}] Set operation mode to ${value}`);
}
catch (cause) {
throw new Error(`Failed to set operation mode: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
}
}
async getFanSetting() {
try {
const value = await this.getErdValue(ERD_TYPES.AIR_CONDITIONER_FAN_SETTING);
return value;
}
catch (cause) {
throw new Error(`Failed to get fan setting: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
}
}
async setFanSetting(value) {
try {
await this.setErdValue(ERD_TYPES.AIR_CONDITIONER_FAN_SETTING, value);
this.platform.log.debug(`[${this.accessory.displayName}] Set fan setting to ${value}`);
}
catch (cause) {
throw new Error(`Failed to set fan setting: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
}
}
async getFilterStatus() {
try {
const value = await this.getErdValue(ERD_TYPES.AIR_CONDITIONER_FILTER_STATUS);
return value;
}
catch (cause) {
throw new Error(`Failed to get filter status: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
}
}
// Characteristic handlers
// active
async handleGetActive() {
try {
const powerState = await this.getPowerState();
return powerState === PowerState.ON
? this.platform.Characteristic.Active.ACTIVE
: this.platform.Characteristic.Active.INACTIVE;
}
catch (cause) {
const error = new Error(`Failed to handle get active: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
this.platform.log.error(`[${this.accessory.displayName}] ${error.message}`);
throw error;
}
}
async handleSetActive(value) {
try {
const [powerState, ambientTemperature, targetTemperature, operationMode] = await Promise.all([
this.getPowerState(),
this.getAmbientTemperature(),
this.getTemperature(),
this.getOperationMode(),
]);
if (value === this.platform.Characteristic.Active.ACTIVE) {
// If the air conditioner is currently off, turn it on
if (powerState === PowerState.OFF) {
await this.setPowerState(PowerState.ON);
// There's a bug (feature?) in SmartHQ where it resets operation mode when turning on the air conditioner
// so we need to set it back to the previous mode
await this.setOperationMode(operationMode);
}
// Keep mode switches in sync
for (const mode of Object.values(OperationMode)) {
this.modeSwitchSvc[mode].updateCharacteristic(this.platform.Characteristic.On, mode === operationMode);
}
// Update CurrentHeaterCoolerState
this.heaterCoolerSvc.updateCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState, ambientTemperature <= targetTemperature
? this.platform.Characteristic.CurrentHeaterCoolerState.IDLE
: this.platform.Characteristic.CurrentHeaterCoolerState.COOLING);
return;
}
if (powerState === PowerState.ON) {
await this.setPowerState(PowerState.OFF);
}
// Keep mode switches in sync
for (const mode of Object.values(OperationMode)) {
this.modeSwitchSvc[mode].updateCharacteristic(this.platform.Characteristic.On, false);
}
// Keep TargetHeaterCoolerState in sync
this.heaterCoolerSvc.updateCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState, this.platform.Characteristic.CurrentHeaterCoolerState.INACTIVE);
}
catch (cause) {
const error = new Error(`Failed to handle set active: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
this.platform.log.error(`[${this.accessory.displayName}] ${error.message}`);
throw error;
}
}
async handleGetCurrentHeaterCoolerState() {
try {
const [powerState, ambientTemperature, targetTemperature] = await Promise.all([
this.getPowerState(),
this.getAmbientTemperature(),
this.getTemperature(),
]);
if (powerState === PowerState.OFF) {
return this.platform.Characteristic.CurrentHeaterCoolerState.INACTIVE;
}
if (ambientTemperature <= targetTemperature) {
return this.platform.Characteristic.CurrentHeaterCoolerState.IDLE;
}
// Keep TargetHeaterCoolerState in sync
this.heaterCoolerSvc.updateCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState, this.platform.Characteristic.TargetHeaterCoolerState.COOL);
return this.platform.Characteristic.CurrentHeaterCoolerState.COOLING;
}
catch (cause) {
const error = new Error(`Failed to handle get current heater cooler state: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
this.platform.log.error(`[${this.accessory.displayName}] ${error.message}`);
throw error;
}
}
async handleGetTargetHeaterCoolerState() {
try {
// Cool is the only supported state for an air conditioner
return this.platform.Characteristic.TargetHeaterCoolerState.COOL;
}
catch (cause) {
const error = new Error(`Failed to handle get target heater cooler state: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
this.platform.log.error(`[${this.accessory.displayName}] ${error.message}`);
throw error;
}
}
async handleSetTargetHeaterCoolerState(_value) {
try {
const powerState = await this.getPowerState();
// Turn on the air conditioner if it's currently off
if (powerState === PowerState.OFF) {
await this.setPowerState(PowerState.ON);
}
// Keep CurrentHeaterCoolerState in sync with TargetHeaterCoolerState
this.heaterCoolerSvc.updateCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState, this.platform.Characteristic.CurrentHeaterCoolerState.COOLING);
}
catch (cause) {
const error = new Error(`Failed to handle set target heater cooler state: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
this.platform.log.error(`[${this.accessory.displayName}] ${error.message}`);
throw error;
}
}
async handleGetCurrentTemperature() {
try {
const value = await this.getAmbientTemperature();
return value;
}
catch (cause) {
const error = new Error(`Failed to handle get current temperature: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
this.platform.log.error(`[${this.accessory.displayName}] ${error.message}`);
throw error;
}
}
async handleGetCoolingThresholdTemperature() {
try {
const value = await this.getTemperature();
return value;
}
catch (cause) {
const error = new Error(`Failed to handle get cooling threshold temperature: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
this.platform.log.error(`[${this.accessory.displayName}] ${error.message}`);
throw error;
}
}
async handleSetCoolingThresholdTemperature(value) {
try {
const targetTemperature = Number.parseInt(value, 10);
await this.setTemperature(targetTemperature);
}
catch (cause) {
const error = new Error(`Failed to handle set cooling threshold temperature: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
this.platform.log.error(`[${this.accessory.displayName}] ${error.message}`);
throw error;
}
}
async handleGetRotationSpeed() {
try {
const value = await this.getFanSetting();
switch (value) {
case FanSetting.AUTO:
return 0;
case FanSetting.LOW:
return 33;
case FanSetting.MED:
return 66;
case FanSetting.HIGH:
return 100;
default:
throw new Error(`Unknown fan setting: ${value}`);
}
}
catch (cause) {
const error = new Error(`Failed to handle get fan setting: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
this.platform.log.error(`[${this.accessory.displayName}] ${error.message}`);
throw error;
}
}
async handleSetRotationSpeed(value) {
try {
const speed = value;
// AUTO
if (speed === 0) {
await this.setFanSetting(FanSetting.AUTO);
return;
}
// LOW
if (speed <= 33) {
await this.setFanSetting(FanSetting.LOW);
return;
}
// MED
if (speed <= 66) {
await this.setFanSetting(FanSetting.MED);
return;
}
// HIGH
await this.setFanSetting(FanSetting.HIGH);
}
catch (cause) {
const error = new Error(`Failed to handle set fan setting: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
this.platform.log.error(`[${this.accessory.displayName}] ${error.message}`);
throw error;
}
}
async handleGetTemperatureDisplayUnits() {
try {
const value = await this.getTemperatureDisplayUnits();
return value === TemperatureUnit.FAHRENHEIT
? this.platform.Characteristic.TemperatureDisplayUnits.FAHRENHEIT
: this.platform.Characteristic.TemperatureDisplayUnits.CELSIUS;
}
catch (cause) {
const error = new Error(`Failed to handle get temperature display units: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
this.platform.log.error(`[${this.accessory.displayName}] ${error.message}`);
throw error;
}
}
async handleSetTemperatureDisplayUnits(value) {
try {
const temperatureUnit = value === this.platform.Characteristic.TemperatureDisplayUnits.FAHRENHEIT
? TemperatureUnit.FAHRENHEIT
: TemperatureUnit.CELSIUS;
await this.setTemperatureDisplayUnits(temperatureUnit);
}
catch (cause) {
const error = new Error(`Failed to handle set temperature display units: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
this.platform.log.error(`[${this.accessory.displayName}] ${error.message}`);
throw error;
}
}
async handleGetFilterChangeIndication() {
try {
const value = await this.getFilterStatus();
return value === FilterStatus.OK
? this.platform.Characteristic.FilterChangeIndication.FILTER_OK
: this.platform.Characteristic.FilterChangeIndication.CHANGE_FILTER;
}
catch (cause) {
const error = new Error(`Failed to handle get filter change indication: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
this.platform.log.error(`[${this.accessory.displayName}] ${error.message}`);
throw error;
}
}
async handleGetOperationMode(mode) {
try {
const value = await this.getOperationMode();
return value === mode;
}
catch (cause) {
const error = new Error(`Failed to handle get operation mode ${mode}: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
this.platform.log.error(`[${this.accessory.displayName}] ${error.message}`);
throw error;
}
}
async handleSetOperationMode(mode, value) {
try {
const [powerState, currentOperationMode] = await Promise.all([
this.getPowerState(),
this.getOperationMode(),
]);
// turn on the Air Conditioner if it's currently off
if (value && powerState === PowerState.OFF) {
await this.setPowerState(PowerState.ON);
// Keep Active in sync
this.heaterCoolerSvc.updateCharacteristic(this.platform.Characteristic.Active, this.platform.Characteristic.Active.ACTIVE);
// Keep CurrentHeaterCoolerState in sync
this.heaterCoolerSvc.updateCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState, this.platform.Characteristic.CurrentHeaterCoolerState.COOLING);
// Keep TargetHeaterCoolerState in sync
this.heaterCoolerSvc.updateCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState, this.platform.Characteristic.TargetHeaterCoolerState.COOL);
// turn off the Air Conditioner if the user turned off the current mode
}
else if (!value && currentOperationMode === mode && powerState === PowerState.ON) {
await this.setPowerState(PowerState.OFF);
// Keep Active in sync
this.heaterCoolerSvc.updateCharacteristic(this.platform.Characteristic.Active, this.platform.Characteristic.Active.INACTIVE);
// Keep CurrentHeaterCoolerState in sync
this.heaterCoolerSvc.updateCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState, this.platform.Characteristic.CurrentHeaterCoolerState.INACTIVE);
}
if (value) {
await this.setOperationMode(mode);
}
// switch the rest off
for (const m of Object.values(OperationMode)) {
this.modeSwitchSvc[m].updateCharacteristic(this.platform.Characteristic.On, m === mode);
}
}
catch (cause) {
const error = new Error(`Failed to handle set operation mode ${mode}: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
this.platform.log.error(`[${this.accessory.displayName}] ${error.message}`);
throw error;
}
}
// Refresh state
async refreshState() {
try {
// active
this.heaterCoolerSvc.updateCharacteristic(this.platform.Characteristic.Active, await this.handleGetActive());
// Current mode
this.heaterCoolerSvc.updateCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState, await this.handleGetCurrentHeaterCoolerState());
// Target mode
this.heaterCoolerSvc.updateCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState, await this.handleGetTargetHeaterCoolerState());
// Ambient temp
this.heaterCoolerSvc.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, await this.handleGetCurrentTemperature());
// Target temperature
this.heaterCoolerSvc.updateCharacteristic(this.platform.Characteristic.CoolingThresholdTemperature, await this.handleGetCoolingThresholdTemperature());
// Rotation speed
this.heaterCoolerSvc.updateCharacteristic(this.platform.Characteristic.RotationSpeed, await this.handleGetRotationSpeed());
// Display units
this.heaterCoolerSvc.updateCharacteristic(this.platform.Characteristic.TemperatureDisplayUnits, await this.handleGetTemperatureDisplayUnits());
// Filter
this.heaterCoolerSvc.updateCharacteristic(this.platform.Characteristic.FilterChangeIndication, await this.handleGetFilterChangeIndication());
// Modes
for (const mode of Object.values(OperationMode)) {
this.modeSwitchSvc[mode].updateCharacteristic(this.platform.Characteristic.On, await this.handleGetOperationMode(mode));
}
this.platform.log.debug(`[${this.accessory.displayName}] Refreshed state`);
}
catch (cause) {
const error = new Error(`Failed to refresh state for ${this.accessory.displayName}: ${cause instanceof Error ? cause.message : 'An unknown error occurred'}`, { cause });
this.platform.log.error(`[${this.accessory.displayName}] ${error.message}`);
throw error;
}
}
// Helpers
fahrenheitToCelsius(fahrenheit) {
return (fahrenheit - 32) * 5 / 9;
}
celsiusToFahrenheit(celsius) {
return (celsius * 9 / 5) + 32;
}
}
//# sourceMappingURL=airConditioner.js.map