homebridge-plugin-lares4
Version:
a homebridge plugin to expose Ksenia Lares 4 home automation systems on the Apple ecosystem
88 lines • 4.58 kB
JavaScript
import { debounceWithLock, rollTo } from 'lares4-ts';
function roundPercentage(value) {
return Math.max(Math.round(value / 10)) * 10;
}
export class Lares4PlatformCover {
platform;
accessory;
service;
debouncedRollToWithLock = debounceWithLock(rollTo, 2000);
constructor(platform, accessory) {
this.platform = platform;
this.accessory = accessory;
this.accessory.getService(this.platform.Service.AccessoryInformation)
.setCharacteristic(this.platform.Characteristic.Manufacturer, 'Ksenia')
.setCharacteristic(this.platform.Characteristic.Model, 'Lares4')
.setCharacteristic(this.platform.Characteristic.SerialNumber, '12345676');
this.service = this.accessory.getService(this.platform.Service.Window) || this.accessory.addService(this.platform.Service.Window);
this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.context.details.DES);
this.service.getCharacteristic(this.platform.Characteristic.CurrentPosition)
.onGet(this.getPosition.bind(this));
this.service.getCharacteristic(this.platform.Characteristic.PositionState)
.onGet(this.getPositionState.bind(this));
this.service.getCharacteristic(this.platform.Characteristic.TargetPosition)
.onGet(this.getTargetPosition.bind(this))
.onSet(this.setTargetPosition.bind(this));
this.platform.lares4?.outputs_status_emitter.subscribe((output_status) => {
if (output_status.id === this.accessory.context.id) {
this.setStatus(output_status.status);
}
});
}
setStatus(accessoryStatus) {
const position = accessoryStatus.POS ?? '0';
const targetPosition = accessoryStatus.TPOS ?? '0';
const roundedPosition = roundPercentage(Number(position));
const roundedTargetPosition = roundPercentage(Number(targetPosition));
const state = accessoryStatus.STA ?? '';
let positionState = this.platform.Characteristic.PositionState.STOPPED;
if (state === 'UP') {
positionState = this.platform.Characteristic.PositionState.INCREASING;
}
if (state === 'DOWN') {
positionState = this.platform.Characteristic.PositionState.DECREASING;
}
const currentTargetPosition = this.service.getCharacteristic(this.platform.Characteristic.TargetPosition).value;
if (currentTargetPosition !== roundedTargetPosition) {
this.service.updateCharacteristic(this.platform.Characteristic.TargetPosition, roundedTargetPosition);
}
this.service.updateCharacteristic(this.platform.Characteristic.CurrentPosition, roundedPosition);
this.service.updateCharacteristic(this.platform.Characteristic.PositionState, positionState);
}
getPosition() {
const position = this.platform.lares4.status.outputs?.[this.accessory.context.id]?.POS ?? '0';
const roundedPosition = roundPercentage(Number(position));
return roundedPosition.toString();
}
getPositionState() {
const status = this.platform.lares4.status.outputs?.[this.accessory.context.id]?.STA ?? '0';
if (status === 'UP') {
return this.platform.Characteristic.PositionState.INCREASING;
}
if (status === 'DOWN') {
return this.platform.Characteristic.PositionState.DECREASING;
}
return this.platform.Characteristic.PositionState.STOPPED;
}
getTargetPosition() {
const position = this.platform.lares4.status.outputs?.[this.accessory.context.id]?.TPOS ?? '0';
const roundedPosition = roundPercentage(Number(position));
return roundedPosition.toString();
}
setTargetPosition(value) {
try {
const position = this.platform.lares4.status.outputs?.[this.accessory.context.id]?.POS ?? '0';
const timeout = this.platform.config.coverTimeout * 1000;
const timeout_percentage = Math.abs(Number(value) - Number(position)) / 100;
if (position === value) {
return;
}
this.debouncedRollToWithLock(timeout * timeout_percentage, this.platform.lares4, this.accessory.context.details.ID, Number(value));
this.service.updateCharacteristic(this.platform.Characteristic.TargetPosition, Number(value));
}
catch (error) {
this.platform.log.error(`Failed to set target position: ${error}`);
}
}
}
//# sourceMappingURL=Lares4PlatformCover.js.map