homebridge-poolcontroller-clocklear
Version:
A (semi) private Homebridge plugin for my custom Pool Controller app
119 lines (118 loc) • 5.58 kB
JavaScript
/**
* Platform Accessory
* An instance of this class is created for each accessory your platform registers
* Each accessory may expose multiple services of different service types.
*/
export class RelayAccessory {
platform;
accessory;
relayId;
asyncUpdates;
service;
state;
constructor(platform, accessory, relayId, asyncUpdates, initialState) {
this.platform = platform;
this.accessory = accessory;
this.relayId = relayId;
this.asyncUpdates = asyncUpdates;
this.state = initialState;
// set accessory information
this.accessory.getService(this.platform.Service.AccessoryInformation)
.setCharacteristic(this.platform.Characteristic.Manufacturer, 'LocklearTech')
.setCharacteristic(this.platform.Characteristic.Model, 'Pool Controller Relay')
.setCharacteristic(this.platform.Characteristic.SerialNumber, `SN-${relayId.toString().padStart(3, '0')}`);
this.service = this.accessory.getService(this.platform.Service.Switch) || this.accessory.addService(this.platform.Service.Switch);
// set the service name, this is what is displayed as the default name on the Home app
this.service.setCharacteristic(this.platform.Characteristic.Name, initialState.name);
// each service must implement at-minimum the "required characteristics" for the given service type
// see https://developers.homebridge.io/#/service/Lightbulb
// register handlers for the On/Off Characteristic
this.service.getCharacteristic(this.platform.Characteristic.On)
.onSet(this.setOn.bind(this)) // SET - bind to the `setOn` method below
.onGet(this.getOn.bind(this)); // GET - bind to the `getOn` method below
if (this.asyncUpdates === true) {
/**
* Updating characteristics values asynchronously.
* Check for relay states every N seconds and update the state of the accessory.
*/
const updateRelayState = async () => {
try {
// Query the state of the relay from the pool controller
const relayState = await this.platform.client.getRelayState(this.relayId);
if (relayState) {
this.state = relayState;
this.service.updateCharacteristic(this.platform.Characteristic.On, relayState.state === 1);
}
}
catch (error) {
this.platform.log.error(`Failed to update state of relay ${this.relayId}: ${error}`);
}
finally {
// Schedule the next update
setTimeout(updateRelayState, 300000); // 5 minutes
}
};
// Start the first update
updateRelayState();
}
}
/**
* Handle "SET" requests from HomeKit
* These are sent when the user changes the state of an accessory, for example, turning on a Light bulb.
*/
async setOn(value) {
// TODO: may need to modify the API to allow setting a specific state instead of simply toggling
const setting = value;
if (setting && this.state.state === 1) {
// Already on, nothing to do
return;
}
if (!setting && this.state.state === 0) {
// Already off, nothing to do
return;
}
// Toggle the relay
const newState = await this.platform.client.toggleRelay(this.relayId);
if (!newState) {
throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
}
this.state = newState;
this.platform.log.debug(`Relay ${this.relayId} Set Characteristic On ->`, value);
}
/**
* Handle the "GET" requests from HomeKit
* These are sent when HomeKit wants to know the current state of the accessory, for example, checking if a Light bulb is on.
*
* GET requests should return as fast as possible. A long delay here will result in
* HomeKit being unresponsive and a bad user experience in general.
*
* If your device takes time to respond you should update the status of your device
* asynchronously instead using the `updateCharacteristic` method instead.
* @example
* this.service.updateCharacteristic(this.platform.Characteristic.On, true)
*/
async getOn() {
if (this.asyncUpdates === true) {
const isOn = this.state.state === 1;
this.platform.log.debug(`Relay ${this.relayId} Get Characteristic On ->`, isOn);
return isOn;
}
else {
try {
// Query the state of the relay from the pool controller
const relayState = await this.platform.client.getRelayState(this.relayId);
if (relayState) {
this.state = relayState;
// this.service.updateCharacteristic(this.platform.Characteristic.On, relayState.state === 1);
return relayState.state === 1;
}
}
catch (error) {
throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
}
// Fallback to whatever the latest state said
return this.state.state === 1;
}
}
}
//# sourceMappingURL=platformAccessory.js.map