Skip to content
This repository has been archived by the owner on Oct 4, 2022. It is now read-only.

Refactor error handling and logger #19

Merged
merged 1 commit into from
Dec 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 43 additions & 83 deletions src/airConAccessory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ export class NatureNemoAirConAccessory {
private readonly platform: NatureRemoPlatform,
private readonly accessory: PlatformAccessory,
) {
this.name = this.accessory.context.appliance.nickname;
this.id = this.accessory.context.appliance.id;
this.deviceId = this.accessory.context.appliance.device.id;

this.accessory.category = this.platform.api.hap.Categories.AIR_CONDITIONER;

this.accessory.getService(this.platform.Service.AccessoryInformation)!
.setCharacteristic(this.platform.Characteristic.Manufacturer, this.accessory.context.appliance.model.manufacturer)
.setCharacteristic(this.platform.Characteristic.Model, this.accessory.context.appliance.model.name)
.setCharacteristic(this.platform.Characteristic.SerialNumber, this.accessory.context.appliance.id)
.setCharacteristic(this.platform.Characteristic.Name, this.accessory.context.appliance.nickname);
.setCharacteristic(this.platform.Characteristic.SerialNumber, this.id)
.setCharacteristic(this.platform.Characteristic.Name, this.name);

this.service
= this.accessory.getService(this.platform.Service.Thermostat) || this.accessory.addService(this.platform.Service.Thermostat);
Expand All @@ -39,135 +43,91 @@ export class NatureNemoAirConAccessory {
.onGet(this.getTargetTemperature.bind(this))
.onSet(this.setTargetTemperature.bind(this));

this.platform.logger.debug('[%s] id -> %s', this.accessory.context.appliance.nickname, this.accessory.context.appliance.id);
this.name = this.accessory.context.appliance.nickname;
this.id = this.accessory.context.appliance.id;
this.deviceId = this.accessory.context.appliance.device.id;
this.platform.logger.debug('[%s] id -> %s', this.name, this.id);
}

async getCurrentHeatingCoolingState(): Promise<CharacteristicValue> {
this.platform.logger.debug('getCurrentHeatingCoolingState called');
try {
const airConState = await this.platform.natureRemoApi.getAirConState(this.id);
this.platform.logger.info('[%s] Current Heater Cooler State -> %s, %s', this.name, airConState.on, airConState.mode);
return this.convertHeatingCoolingState(airConState.on, airConState.mode);
} catch (err) {
if (err instanceof Error) {
this.platform.logger.error(err.message);
}
throw err;
}
const airConState = await this.platform.natureRemoApi.getAirConState(this.id);
this.platform.logger.info('[%s] Current Heater Cooler State -> %s, %s', this.name, airConState.button || 'power-on', airConState.mode);
return this.convertHeatingCoolingState(airConState.button, airConState.mode);
}

async getTargetHeatingCoolingState(): Promise<CharacteristicValue> {
this.platform.logger.debug('getTargetHeatingCoolingState called');
try {
const airConState = await this.platform.natureRemoApi.getAirConState(this.id);
this.platform.logger.info('[%s] Target Heater Cooler State -> %s, %s', this.name, airConState.on, airConState.mode);
const state = this.convertHeatingCoolingState(airConState.on, airConState.mode);
this.state.targetHeatingCoolingState = state;
return state;
} catch (err) {
if (err instanceof Error) {
this.platform.logger.error(err.message);
}
throw err;
}
const airConState = await this.platform.natureRemoApi.getAirConState(this.id);
this.platform.logger.info('[%s] Target Heater Cooler State -> %s, %s', this.name, airConState.button || 'power-on', airConState.mode);
const state = this.convertHeatingCoolingState(airConState.button, airConState.mode);
this.state.targetHeatingCoolingState = state;
return state;
}

async setTargetHeatingCoolingState(value: CharacteristicValue): Promise<void> {
this.platform.logger.debug('setTargetHeatingCoolingState called ->', value);
if (typeof value !== 'number') {
throw new Error('value must be a number');
throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.INVALID_VALUE_IN_REQUEST);
}
if (value === this.state.targetHeatingCoolingState) {
this.platform.logger.debug('[%s] Same state. skip sending', this.name);
return;
}
this.state.targetHeatingCoolingState = value;
try {
if (value === this.platform.Characteristic.TargetHeatingCoolingState.AUTO) {
throw new Error('This plugin does not support auto');
} else if (value === this.platform.Characteristic.TargetHeatingCoolingState.OFF) {
await this.platform.natureRemoApi.setAirconPowerOff(this.id);
this.platform.logger.info('[%s] Target Heater Cooler State <- OFF', this.name);
} else {
const mode = this.convertOperationMode(value);
await this.platform.natureRemoApi.setAirconOperationMode(this.id, mode);
this.platform.logger.info('[%s] Target Heater Cooler State <- %s', this.name, mode);
}
} catch (err) {
if (err instanceof Error) {
this.platform.logger.error(err.message);
}
throw err;
if (value === this.platform.Characteristic.TargetHeatingCoolingState.AUTO) {
this.platform.logger.error('This plugin does not support auto');
throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.INVALID_VALUE_IN_REQUEST);
} else if (value === this.platform.Characteristic.TargetHeatingCoolingState.OFF) {
await this.platform.natureRemoApi.setAirconPowerOff(this.id);
this.platform.logger.info('[%s] Target Heater Cooler State <- OFF', this.name);
} else {
const mode = this.convertOperationMode(value);
await this.platform.natureRemoApi.setAirconOperationMode(this.id, mode);
this.platform.logger.info('[%s] Target Heater Cooler State <- %s', this.name, mode);
}
}

async getCurrentTemperature(): Promise<CharacteristicValue> {
try {
const sensorValue = await this.platform.natureRemoApi.getSensorValue(this.deviceId);
this.platform.logger.info('[%s] Current Temperature -> %s', this.name, sensorValue.te);
if (sensorValue.te) {
return sensorValue.te;
} else {
throw new Error('cannnot get sensor value');
}
} catch (err) {
if (err instanceof Error) {
this.platform.logger.error(err.message);
}
throw err;
const device = await this.platform.natureRemoApi.getSensorValue(this.deviceId);
if (device.newest_events.te) {
this.platform.logger.info('[%s] Current Temperature -> %s', this.name, device.newest_events.te.val);
return device.newest_events.te.val;
} else {
throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.RESOURCE_DOES_NOT_EXIST);
}
}

async getTargetTemperature(): Promise<CharacteristicValue> {
this.platform.logger.debug('getTargetTemperature called');
try {
const airConState = await this.platform.natureRemoApi.getAirConState(this.id);
this.platform.logger.info('[%s] Target Temperature -> %s', this.name, airConState.temp);
this.state.targetTemperature = parseFloat(airConState.temp);
return airConState.temp;
} catch (err) {
if (err instanceof Error) {
this.platform.logger.error(err.message);
}
throw err;
}
const airConState = await this.platform.natureRemoApi.getAirConState(this.id);
this.platform.logger.info('[%s] Target Temperature -> %s', this.name, airConState.temp);
this.state.targetTemperature = parseFloat(airConState.temp);
return airConState.temp;
}

async setTargetTemperature(value: CharacteristicValue): Promise<void> {
this.platform.logger.debug('setTargetTemperature called ->', value);
if (typeof value !== 'number') {
throw new Error('value must be a number');
throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.INVALID_VALUE_IN_REQUEST);
}
if (value === this.state.targetTemperature) {
this.platform.logger.debug('[%s] Same state. skip sending', this.name);
return;
}
this.state.targetTemperature = value;
const targetTemp = `${Math.round(value)}`;
try {
await this.platform.natureRemoApi.setAirconTemperature(this.id, targetTemp);
this.platform.logger.info('[%s] Target Temperature <- %s', this.name, targetTemp);
} catch (err) {
if (err instanceof Error) {
this.platform.logger.error(err.message);
}
throw err;
}
await this.platform.natureRemoApi.setAirconTemperature(this.id, targetTemp);
this.platform.logger.info('[%s] Target Temperature <- %s', this.name, targetTemp);
}

private convertHeatingCoolingState(on: boolean, mode: string): number {
if (!on) {
private convertHeatingCoolingState(button: string, mode: string): number {
if (button === 'power-off') {
return this.platform.Characteristic.CurrentHeatingCoolingState.OFF;
} else {
if (mode === 'warm') {
return this.platform.Characteristic.CurrentHeatingCoolingState.HEAT;
} else if (mode === 'cool') {
return this.platform.Characteristic.CurrentHeatingCoolingState.COOL;
} else {
throw new Error(`This plugin does not support ${mode}`);
throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.INVALID_VALUE_IN_REQUEST);
}
}
}
Expand All @@ -178,7 +138,7 @@ export class NatureNemoAirConAccessory {
} else if (state === this.platform.Characteristic.TargetHeatingCoolingState.COOL) {
return 'cool';
} else {
throw new Error(`This plugin does not support ${state}`);
throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.INVALID_VALUE_IN_REQUEST);
}
}
}
37 changes: 12 additions & 25 deletions src/lightAccessory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,51 +10,38 @@ export class NatureNemoLightAccessory {
private readonly platform: NatureRemoPlatform,
private readonly accessory: PlatformAccessory,
) {
this.name = this.accessory.context.appliance.nickname;
this.id = this.accessory.context.appliance.id;

this.accessory.category = this.platform.api.hap.Categories.LIGHTBULB;

this.accessory.getService(this.platform.Service.AccessoryInformation)!
.setCharacteristic(this.platform.Characteristic.Manufacturer, this.accessory.context.appliance.model.manufacturer)
.setCharacteristic(this.platform.Characteristic.Model, this.accessory.context.appliance.model.name)
.setCharacteristic(this.platform.Characteristic.SerialNumber, this.accessory.context.appliance.id)
.setCharacteristic(this.platform.Characteristic.Name, this.accessory.context.appliance.nickname);
.setCharacteristic(this.platform.Characteristic.SerialNumber, this.id)
.setCharacteristic(this.platform.Characteristic.Name, this.name);

this.service = this.accessory.getService(this.platform.Service.Lightbulb) || this.accessory.addService(this.platform.Service.Lightbulb);
this.service.getCharacteristic(this.platform.Characteristic.On)
.onGet(this.getOn.bind(this))
.onSet(this.setOn.bind(this));

this.platform.logger.debug('[%s] id -> %s', this.accessory.context.appliance.nickname, this.accessory.context.appliance.id);
this.name = this.accessory.context.appliance.nickname;
this.id = this.accessory.context.appliance.id;
this.platform.logger.debug('[%s] id -> %s', this.name, this.id);
}

async getOn(): Promise<CharacteristicValue> {
this.platform.logger.debug('getOn called');
try {
const lightState = await this.platform.natureRemoApi.getLightState(this.id);
this.platform.logger.info('[%s] On -> %s', this.name, lightState.on);
return lightState.on;
} catch (err) {
if (err instanceof Error) {
this.platform.logger.error(err.message);
}
throw err;
}
const lightState = await this.platform.natureRemoApi.getLightState(this.id);
this.platform.logger.info('[%s] Power -> %s', this.name, lightState.power);
return lightState.power === 'on';
}

async setOn(value: CharacteristicValue): Promise<void> {
this.platform.logger.debug('setOn called ->', value);
if (typeof value !== 'boolean') {
throw new Error('value must be a boolean');
}
try {
await this.platform.natureRemoApi.setLight(this.id, value);
this.platform.logger.info('[%s] On <- %s', this.name, value);
} catch (err) {
if (err instanceof Error) {
this.platform.logger.error(err.message);
}
throw err;
throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.INVALID_VALUE_IN_REQUEST);
}
await this.platform.natureRemoApi.setLight(this.id, value);
this.platform.logger.info('[%s] On <- %s', this.name, value);
}
}
Loading