homebridge-homeconnect
Version:
A Homebridge plugin that connects Home Connect appliances to Apple HomeKit
83 lines • 4.51 kB
JavaScript
// Homebridge plugin for Home Connect home appliances
// Copyright © 2019-2025 Alexander Thoukydides
import { PowerState } from './api-value-types.js';
// Add a power switch to an accessory
export function HasPower(Base) {
return class HasPower extends Base {
// Accessory services
powerService;
// The power off setting to use if the appliance reports multiple
defaultOffValue;
// Mixin constructor
constructor(...args) {
super(...args);
// Add power Switch service to host the appliance's main characteristics
this.powerService = this.makeService(this.Service.Switch, 'Power', 'power');
this.powerService.setPrimaryService(true);
// Add a characteristic for the power state, initially read-only
this.powerService.getCharacteristic(this.Characteristic.On)
.setProps({ perms: ["pr" /* Perms.PAIRED_READ */, "ev" /* Perms.NOTIFY */] });
// Continue initialisation asynchronously
this.asyncInitialise('Power', this.initHasPower());
}
// Asynchronous initialisation
async initHasPower() {
// Update the status
const updateHK = this.makeSerialised(() => { this.updatePowerHK(); });
this.device.on('BSH.Common.Setting.PowerState', updateHK);
this.device.on('connected', updateHK);
// Identify the power on and off states supported by the appliance
const setting = await this.getCached('power', () => this.device.getSetting('BSH.Common.Setting.PowerState'));
const allValues = setting?.constraints?.allowedvalues ?? [];
const offValues = allValues.filter(value => value !== PowerState.On);
const powerStateOn = allValues.find(value => value === PowerState.On);
// Check whether the appliance supports off or standby
let powerStateOff = offValues[0];
if (powerStateOff === undefined) {
this.log.info('Cannot be switched off');
return;
}
// Workaround appliances incorrectly reporting multiple off settings
if (1 < offValues.length) {
if (this.defaultOffValue && offValues.includes(this.defaultOffValue)) {
this.log.debug(`Appliance reported multiple power off settings; using default (${this.defaultOffValue})`);
powerStateOff = this.defaultOffValue;
}
else {
this.log.debug(`Appliance reported multiple power off settings; using the first (${powerStateOff})`);
}
}
// Make the power state characteristic writable
if (powerStateOn === undefined)
this.log.info('Cannot be switched on');
this.log.info(`Can be ${this.defaultOffValue === PowerState.Standby ? 'placed in standby' : 'switched off'}`);
this.powerService.getCharacteristic(this.Characteristic.On)
.setProps({ perms: ["pr" /* Perms.PAIRED_READ */, "pw" /* Perms.PAIRED_WRITE */, "ev" /* Perms.NOTIFY */] })
.onSet(this.onSetBoolean(async (value) => {
const powerState = value ? powerStateOn : powerStateOff;
if (powerState !== undefined) {
this.log.info(`SET ${value ? 'On' : 'Off'}`);
await this.device.setSetting('BSH.Common.Setting.PowerState', powerState);
}
}));
}
// Deferred update of HomeKit state from Home Connect events
updatePowerHK() {
if (this.device.getItem('connected')) {
const powerOn = this.device.getItem('BSH.Common.Setting.PowerState') === PowerState.On;
this.log.info(powerOn ? 'On' : 'Off');
this.powerService.updateCharacteristic(this.Characteristic.On, powerOn);
}
else {
const powerOn = new this.platform.hb.hap.HapStatusError(-70402 /* HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
this.log.info('Disconnected (setting On error status)');
this.powerService.updateCharacteristic(this.Characteristic.On, powerOn);
}
}
// Explicitly specify the setting used to switch the appliance off
hasPowerOff(offValue) {
this.defaultOffValue = offValue;
}
};
}
//# sourceMappingURL=has-power.js.map