import type { Device as Miio } from 'miio'; const enum Power { Off, On, } const enum OperationMode { Auto = 1, Cool, Dry, Fan, Heat, } export const enum WindLevel { Auto, Level1, Level2, Level3, Level4, Level5, Level6, Level7, } export const enum Swing { Off, On, } type DeviceState = { power: Power; mode: OperationMode; settemp: number; temperature: number; wind_level: WindLevel; swing: Swing; }; export class Device { private state: DeviceState = { power: Power.Off, mode: OperationMode.Cool, settemp: 26, temperature: 26, wind_level: WindLevel.Auto, swing: Swing.Off, }; constructor( private readonly miio: Miio, ) { // } deviceId() { return this.miio.handle.api.id; } isOn() { return this.state.power === Power.On; } isOff() { return ! this.isOn(); } async turnOn() { this.state.power = Power.On; await this.miio.call('set_power', [this.state.power]); await this.refresh(); } async turnOff() { this.state.power = Power.Off; await this.miio.call('set_power', [this.state.power]); await this.refresh(); } isCooling() { return this.state.mode === OperationMode.Cool; } isHeating() { return this.state.mode === OperationMode.Heat; } async auto() { this.state.mode = OperationMode.Auto; await this.miio.call('set_mode', [this.state.mode]); await this.refresh(); } async cooling() { this.state.mode = OperationMode.Cool; await this.miio.call('set_mode', [this.state.mode]); await this.refresh(); } async heating() { this.state.mode = OperationMode.Heat; await this.miio.call('set_mode', [this.state.mode]); await this.refresh(); } async temperatureSetTo(temperature: number) { this.state.settemp = temperature; await this.miio.call('set_temp', [this.state.settemp]); await this.refresh(); } temperature() { return this.state.temperature; } targetTemperature() { return this.state.settemp; } async windLevelSetTo(level: WindLevel) { this.state.wind_level = level; await this.miio.call('set_wind_level', [level]); await this.refresh(); } windLevel() { return this.state.wind_level; } async startSwinging() { this.state.swing = Swing.On; await this.miio.call('set_swing', [this.state.swing]); await this.refresh(); } async stopSwinging() { this.state.swing = Swing.Off; await this.miio.call('set_swing', [this.state.swing]); await this.refresh(); } swinging() { return this.state.swing; } async refresh() { const attributes = Object.keys(this.state); const values = await this.miio.call('get_prop', attributes); this.state = attributes.reduce( (carry, attr, i) => ({ ...carry, [attr]: values[i] }), { ...this.state }, ); return this; } getRawState() { return this.state; } }