Skip to content

Commit

Permalink
feat: continue development
Browse files Browse the repository at this point in the history
  • Loading branch information
tomekkleszcz committed Mar 11, 2024
1 parent a03076a commit 1480d21
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 67 deletions.
3 changes: 2 additions & 1 deletion src/accessories/accessory.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { PlatformAccessory } from 'homebridge';
import { ElectroluxAccessoryController } from './controller';
import { Context } from '../definitions/context';

export class ElectroluxAccessory {
controller?: ElectroluxAccessoryController;

constructor(
readonly platformAccessory: PlatformAccessory,
readonly platformAccessory: PlatformAccessory<Context>,
controller?: ElectroluxAccessoryController
) {
this.controller = controller;
Expand Down
22 changes: 11 additions & 11 deletions src/accessories/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export abstract class ElectroluxAccessoryController {
this.appliance = _appliance;
this.capabilities = _capabilities;

// console.log(_capabilities);
this.accessory.context.capabilities = this.capabilities;
}

async sendCommand(
Expand Down Expand Up @@ -57,11 +57,11 @@ export abstract class ElectroluxAccessoryController {
getter: () => Promise<CharacteristicValue>
): () => Promise<CharacteristicValue> {
return async () => {
// if (this.appliance.connectionState === 'Disconnected') {
// throw new this.platform.api.hap.HapStatusError(
// this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE
// );
// }
if (this.appliance.connectionState === 'Disconnected') {
throw new this.platform.api.hap.HapStatusError(
this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE
);
}

return await getter();
};
Expand All @@ -71,11 +71,11 @@ export abstract class ElectroluxAccessoryController {
setter: (value: CharacteristicValue) => Promise<void>
): (value: CharacteristicValue) => Promise<void> {
return async (value: CharacteristicValue) => {
// if (this.appliance.connectionState === 'Disconnected') {
// throw new this.platform.api.hap.HapStatusError(
// this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE
// );
// }
if (this.appliance.connectionState === 'Disconnected') {
throw new this.platform.api.hap.HapStatusError(
this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE
);
}

return setter(value);
};
Expand Down
116 changes: 75 additions & 41 deletions src/accessories/devices/comfort600.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,12 @@ export class Comfort600 extends ElectroluxAccessoryController {
);

const targetHeaterCoolerStateValidValues = [
this.capabilities?.mode.values['AUTO'] !== undefined &&
this.capabilities!.mode!.values['AUTO'] !== undefined &&
this.platform.Characteristic.TargetHeaterCoolerState.AUTO,
this.capabilities?.mode.values['COOL'] !== undefined &&
this.platform.Characteristic.TargetHeaterCoolerState.COOL
// this.capabilities?.mode.values['HEAT'] !== undefined &&
// this.platform.Characteristic.TargetHeaterCoolerState.HEAT
this.capabilities!.mode!.values['COOL'] !== undefined &&
this.platform.Characteristic.TargetHeaterCoolerState.COOL,
this.capabilities!.mode!.values['HEAT'] !== undefined &&
this.platform.Characteristic.TargetHeaterCoolerState.HEAT
].filter((value) => value !== false) as number[];

this.service
Expand Down Expand Up @@ -126,41 +126,65 @@ export class Comfort600 extends ElectroluxAccessoryController {
.getCharacteristic(this.platform.Characteristic.Name)
.onGet(this.getCharacteristicValueGuard(this.getName.bind(this)));

this.service
.getCharacteristic(this.platform.Characteristic.RotationSpeed)
.setProps({
minValue: 0,
maxValue: 100,
minStep: 33.33
})
.onGet(
this.getCharacteristicValueGuard(
this.getRotationSpeed.bind(this)
if (this.capabilities?.fanSpeedState) {
const minRotationSpeedStep =
100 /
Object.entries(this.capabilities!.fanSpeedState?.values).length;

this.service
.getCharacteristic(this.platform.Characteristic.RotationSpeed)
.setProps({
minValue: 0,
maxValue: 100,
minStep: minRotationSpeedStep
})
.onGet(
this.getCharacteristicValueGuard(
this.getRotationSpeed.bind(this)
)
)
)
.onSet(
this.setCharacteristicValueGuard(
this.setRotationSpeed.bind(this)
.onSet(
this.setCharacteristicValueGuard(
this.setRotationSpeed.bind(this)
)
);
} else {
this.service.removeCharacteristic(
this.service.getCharacteristic(
this.platform.Characteristic.RotationSpeed
)
);
}

this.service
.getCharacteristic(this.platform.Characteristic.SwingMode)
.onGet(
this.getCharacteristicValueGuard(this.getSwingMode.bind(this))
)
.onSet(
this.setCharacteristicValueGuard(this.setSwingMode.bind(this))
if (this.capabilities?.verticalSwing) {
this.service
.getCharacteristic(this.platform.Characteristic.SwingMode)
.onGet(
this.getCharacteristicValueGuard(
this.getSwingMode.bind(this)
)
)
.onSet(
this.setCharacteristicValueGuard(
this.setSwingMode.bind(this)
)
);
} else {
this.service.removeCharacteristic(
this.service.getCharacteristic(
this.platform.Characteristic.SwingMode
)
);
}

this.service
.getCharacteristic(
this.platform.Characteristic.CoolingThresholdTemperature
)
.setProps({
minValue: this.capabilities!.targetTemperatureC.min,
maxValue: this.capabilities!.targetTemperatureC.max,
minStep: this.capabilities!.targetTemperatureC.step
minValue: this.capabilities?.targetTemperatureC?.min ?? 16,
maxValue: this.capabilities?.targetTemperatureC?.max ?? 32,
minStep: this.capabilities?.targetTemperatureC?.step ?? 1
})
.onGet(
this.getCharacteristicValueGuard(
Expand All @@ -178,9 +202,9 @@ export class Comfort600 extends ElectroluxAccessoryController {
this.platform.Characteristic.HeatingThresholdTemperature
)
.setProps({
minValue: this.capabilities!.targetTemperatureC.min,
maxValue: this.capabilities!.targetTemperatureC.max,
minStep: this.capabilities!.targetTemperatureC.step
minValue: this.capabilities?.targetTemperatureC?.min ?? 16,
maxValue: this.capabilities?.targetTemperatureC?.max ?? 32,
minStep: this.capabilities?.targetTemperatureC?.step ?? 1
})
.onGet(
this.getCharacteristicValueGuard(
Expand Down Expand Up @@ -229,6 +253,16 @@ export class Comfort600 extends ElectroluxAccessoryController {
return this.platform.Characteristic.CurrentHeaterCoolerState
.HEATING;
case 'auto':
if (this.capabilities?.mode?.values['HEAT'] === undefined) {
return this.appliance.properties.reported
.ambientTemperatureC >
this.appliance.properties.reported.targetTemperatureC
? this.platform.Characteristic.CurrentHeaterCoolerState
.COOLING
: this.platform.Characteristic.CurrentHeaterCoolerState
.IDLE;
}

return this.appliance.properties.reported.ambientTemperatureC >
this.appliance.properties.reported.targetTemperatureC
? this.platform.Characteristic.CurrentHeaterCoolerState
Expand Down Expand Up @@ -300,7 +334,7 @@ export class Comfort600 extends ElectroluxAccessoryController {
this.service.updateCharacteristic(
this.platform.Characteristic
.CoolingThresholdTemperature,
this.capabilities!.targetTemperatureC.max
this.capabilities?.targetTemperatureC?.max ?? 32
);
this.service.updateCharacteristic(
this.platform.Characteristic
Expand Down Expand Up @@ -364,9 +398,9 @@ export class Comfort600 extends ElectroluxAccessoryController {
case 'auto':
return 0;
case 'low':
return 33;
return 33.33;
case 'middle':
return 66;
return 66.66;
case 'high':
return 100;
}
Expand All @@ -380,11 +414,11 @@ export class Comfort600 extends ElectroluxAccessoryController {
const numberValue = value as number;

this.appliance.properties.reported.fanSpeedSetting =
value === (0 as number)
numberValue === 0
? 'auto'
: numberValue <= 33
: numberValue <= 33.34
? 'low'
: numberValue <= 66
: numberValue <= 66.67
? 'middle'
: 'high';
}
Expand Down Expand Up @@ -488,10 +522,10 @@ export class Comfort600 extends ElectroluxAccessoryController {
rotationSpeed = 0;
break;
case 'low':
rotationSpeed = 33;
rotationSpeed = 33.33;
break;
case 'middle':
rotationSpeed = 66;
rotationSpeed = 66.66;
break;
case 'high':
rotationSpeed = 100;
Expand Down Expand Up @@ -537,7 +571,7 @@ export class Comfort600 extends ElectroluxAccessoryController {
if (this.appliance.properties.reported.mode === 'auto') {
this.service.updateCharacteristic(
this.platform.Characteristic.CoolingThresholdTemperature,
32
this.capabilities?.targetTemperatureC?.max ?? 32
);
this.service.updateCharacteristic(
this.platform.Characteristic.HeatingThresholdTemperature,
Expand Down
10 changes: 8 additions & 2 deletions src/definitions/capabilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@ import { Mode } from './appliance';

export type Capabilities = {
/* Comfort 600 */
mode: {
mode?: {
values: Record<Uppercase<Mode>, Record<string, unknown>>;
};
targetTemperatureC: {
targetTemperatureC?: {
max: number;
min: number;
step: number;
};
fanSpeedState?: {
values: Record<string, unknown>;
};
verticalSwing?: {
values: Record<Uppercase<Mode>, unknown>;
};
};
5 changes: 5 additions & 0 deletions src/definitions/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Capabilities } from './capabilities';

export type Context = {
capabilities?: Capabilities | null;
};
29 changes: 17 additions & 12 deletions src/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ import { DEVICES } from './const/devices';
import { CLIENT_ID, CLIENT_SECRET } from './const/apiKey';
import Gigya, { DataCenter } from 'gigya';
import { TokenResponse } from './definitions/auth';
import { ElectroluxAccessoryController } from './accessories/controller';
import { ElectroluxAccessory } from './accessories/accessory';
import fs from 'fs';
import path from 'path';
import { IdentityProvidersResponse } from './definitions/identityProviders';
import { API_URL } from './const/url';
import { Capabilities } from './definitions/capabilities';
import { Context } from './definitions/context';

/*
HomebridgePlatform
Expand Down Expand Up @@ -92,9 +92,7 @@ export class ElectroluxDevicesPlatform implements DynamicPlatformPlugin {
This function is invoked when homebridge restores cached accessories from disk at startup.
It should be used to setup event handlers for characteristics and update respective values.
*/
configureAccessory(
accessory: PlatformAccessory<ElectroluxAccessoryController>
) {
configureAccessory(accessory: PlatformAccessory<Context>) {
this.log.info('Loading accessory from cache:', accessory.displayName);

// add the restored accessory to the accessories cache so we can track if it has already been registered
Expand Down Expand Up @@ -286,7 +284,7 @@ export class ElectroluxDevicesPlatform implements DynamicPlatformPlugin {

async getApplianceCapabilities(
applianceId: string
): Promise<Capabilities | undefined> {
): Promise<Capabilities | null> {
try {
const response = await axiosAppliance.get<Capabilities>(
`/appliances/${applianceId}/capabilities`,
Expand All @@ -300,14 +298,12 @@ export class ElectroluxDevicesPlatform implements DynamicPlatformPlugin {

return response.data;
} catch (err) {
return undefined;
return null;
}
}

/*
This is an example method showing how to register discovered accessories.
Accessories must only be registered once, previously created accessories
must not be registered again to prevent "duplicate UUID" errors.
Get the appliances from the Electrolux API and register each appliance as an accessory.
*/
async discoverDevices() {
if (!this.accessToken) {
Expand All @@ -333,9 +329,18 @@ export class ElectroluxDevicesPlatform implements DynamicPlatformPlugin {
(accessory) => accessory.platformAccessory.UUID === uuid
);

const capabilities = await this.getApplianceCapabilities(
appliance.applianceId
);
/*
Get the capabilities of the appliance from the context.
If the capabilities are not in the context, fetch them from the API.
If the capabilities equals null, that means the appliance capabilities is not supported.
*/
const capabilities =
existingAccessory?.platformAccessory.context.capabilities !==
undefined
? existingAccessory.platformAccessory.context.capabilities
: await this.getApplianceCapabilities(
appliance.applianceId
);

if (existingAccessory) {
this.log.info(
Expand Down

0 comments on commit 1480d21

Please sign in to comment.