homebridge-pentair-intellicenter-ai
Version:
Homebridge plugin for the Pentair IntelliCenter pool control system (maintained with AI assistance)
227 lines (226 loc) • 11.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CircuitAccessory = void 0;
const types_1 = require("./types");
const uuid_1 = require("uuid");
const settings_1 = require("./settings");
const constants_1 = require("./constants");
const util_1 = require("./util");
const MODEL = 'Circuit';
/**
* 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.
*/
class CircuitAccessory {
constructor(platform, accessory) {
this.platform = platform;
this.accessory = accessory;
this.initializeContext();
this.setupAccessoryInformation();
this.setupService();
this.configureServiceCharacteristics();
this.configureFanService();
}
initializeContext() {
this.module = this.accessory.context.module;
this.panel = this.accessory.context.panel;
this.circuit = this.accessory.context.circuit;
this.pumpCircuit = this.accessory.context.pumpCircuit;
}
setupAccessoryInformation() {
const serial = this.module ? `${this.panel.id}.${this.module.id}.${this.circuit.id}` : `${this.panel.id}.${this.circuit.id}`;
this.accessory
.getService(this.platform.Service.AccessoryInformation)
.setCharacteristic(this.platform.Characteristic.Manufacturer, settings_1.MANUFACTURER)
.setCharacteristic(this.platform.Characteristic.Model, MODEL)
.setCharacteristic(this.platform.Characteristic.SerialNumber, serial);
}
setupService() {
if (types_1.CircuitType.IntelliBrite === this.circuit.type) {
this.service =
this.accessory.getService(this.platform.Service.Lightbulb) || this.accessory.addService(this.platform.Service.Lightbulb);
this.setupLightbulbCharacteristics();
}
else {
this.service = this.accessory.getService(this.platform.Service.Switch) || this.accessory.addService(this.platform.Service.Switch);
}
}
setupLightbulbCharacteristics() {
this.service.getCharacteristic(this.platform.Characteristic.Hue).onSet(this.setColorHue.bind(this)).onGet(this.getColorHue.bind(this));
this.service
.getCharacteristic(this.platform.Characteristic.Saturation)
.onSet(this.setColorSaturation.bind(this))
.onGet(this.getColorSaturation.bind(this));
this.service
.getCharacteristic(this.platform.Characteristic.ColorTemperature)
.onSet(this.setColorTemperature.bind(this))
.onGet(this.getColorTemperature.bind(this));
this.service
.getCharacteristic(this.platform.Characteristic.Brightness)
.onSet(this.setBrightness.bind(this))
.onGet(this.getBrightness.bind(this));
}
configureServiceCharacteristics() {
this.service.setCharacteristic(this.platform.Characteristic.Name, this.circuit.name);
this.service.updateCharacteristic(this.platform.Characteristic.On, this.getCircuitStatus());
this.service.getCharacteristic(this.platform.Characteristic.On).onSet(this.setOn.bind(this)).onGet(this.getOn.bind(this));
}
configureFanService() {
const fanService = this.accessory.getService(this.platform.Service.Fan);
if (this.pumpCircuit && this.platform.getConfig().supportVSP) {
this.service = fanService || this.accessory.addService(this.platform.Service.Fan);
this.service
.getCharacteristic(this.platform.Characteristic.RotationSpeed)
.onSet(this.setSpeed.bind(this))
.onGet(this.getSpeed.bind(this))
.updateValue(this.convertSpeedToPowerLevel());
}
else if (fanService) {
this.platform.log.info(`Removing VSP Fan service from ${this.circuit.name} due to config`);
this.accessory.removeService(fanService);
}
}
/**
* 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) {
this.platform.log.info(`Setting ${this.circuit.name} to ${value}`);
const command = {
command: types_1.IntelliCenterRequestCommand.SetParamList,
messageID: (0, uuid_1.v4)(),
objectList: [
{
objnam: this.circuit.id,
params: { [constants_1.STATUS_KEY]: value ? types_1.CircuitStatus.On : types_1.CircuitStatus.Off },
},
],
};
this.platform.sendCommandNoWait(command);
}
async setColorHue(value) {
// Wait for saturation first. 10ms chosen arbitrarily.
await this.platform.delay(10);
const saturation = this.accessory.context.saturation;
this.platform.log.info(`Setting ${this.circuit.name} hue to ${value}. Saturation is ${saturation}`);
this.accessory.context.color = (0, util_1.getIntelliBriteColor)(value, saturation);
const command = {
command: types_1.IntelliCenterRequestCommand.SetParamList,
messageID: (0, uuid_1.v4)(),
objectList: [
{
objnam: this.circuit.id,
params: { [constants_1.ACT_KEY]: this.accessory.context.color.intellicenterCode },
},
],
};
this.platform.sendCommandNoWait(command);
this.accessory.context.saturation = this.accessory.context.color.saturation;
this.service.updateCharacteristic(this.platform.Characteristic.Hue, this.accessory.context.color.hue);
this.service.updateCharacteristic(this.platform.Characteristic.Saturation, this.accessory.context.color.saturation);
}
async setColorSaturation(value) {
this.platform.log.info(`Setting ${this.circuit.name} saturation to ${value}`);
this.accessory.context.saturation = value;
}
async setColorTemperature(value) {
this.platform.log.warn(`Ignoring color temperature on ${this.circuit.name} to ${value}`);
this.service.updateCharacteristic(this.platform.Characteristic.ColorTemperature, constants_1.DEFAULT_COLOR_TEMPERATURE);
}
async setBrightness(value) {
this.platform.log.warn(`Ignoring brightness value on ${this.circuit.name} to ${value}`);
this.service.updateCharacteristic(this.platform.Characteristic.Brightness, constants_1.DEFAULT_BRIGHTNESS);
}
async getColorHue() {
var _a, _b;
return (_b = (_a = this.accessory.context.color) === null || _a === void 0 ? void 0 : _a.hue) !== null && _b !== void 0 ? _b : types_1.Color.White.saturation;
}
async getColorSaturation() {
var _a, _b;
return (_b = (_a = this.accessory.context.color) === null || _a === void 0 ? void 0 : _a.saturation) !== null && _b !== void 0 ? _b : types_1.Color.White.saturation;
}
async getBrightness() {
return constants_1.DEFAULT_BRIGHTNESS;
}
async getColorTemperature() {
return constants_1.DEFAULT_COLOR_TEMPERATURE;
}
/**
* 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 possbile. 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() {
return this.getCircuitStatus();
}
getCircuitStatus() {
var _a, _b;
if ((_b = (_a = this.accessory.context) === null || _a === void 0 ? void 0 : _a.circuit) === null || _b === void 0 ? void 0 : _b.status) {
this.platform.log.debug(`Circuit ${this.circuit.name} status is ${this.accessory.context.circuit.status}`);
return this.accessory.context.circuit.status === types_1.CircuitStatus.On;
}
return false;
}
async setSpeed(value) {
var _a;
if (!this.pumpCircuit) {
this.platform.log.error('Tried to set speed when pump circuit is undefined.');
return;
}
const convertedValue = this.convertPowerLevelToSpeed(value);
this.platform.log.info(`Setting speed for ${(_a = this.pumpCircuit.pump) === null || _a === void 0 ? void 0 : _a.name} to ${value} converted/rounded to: ${convertedValue} ` +
`${this.pumpCircuit.speedType}`);
const command = {
command: types_1.IntelliCenterRequestCommand.SetParamList, //Weirdly required.
messageID: (0, uuid_1.v4)(),
objectList: [
{
objnam: this.pumpCircuit.id,
params: { [constants_1.SPEED_KEY]: `${convertedValue}` },
},
],
};
this.platform.sendCommandNoWait(command);
}
async getSpeed() {
return this.convertSpeedToPowerLevel();
}
convertSpeedToPowerLevel() {
var _a, _b;
if (!((_a = this.pumpCircuit) === null || _a === void 0 ? void 0 : _a.speed)) {
return 0;
}
const min = this.pumpCircuit.speedType === types_1.PumpSpeedType.GPM ? this.pumpCircuit.pump.minFlow : this.pumpCircuit.pump.minRpm;
const max = this.pumpCircuit.speedType === types_1.PumpSpeedType.GPM ? this.pumpCircuit.pump.maxFlow : this.pumpCircuit.pump.maxRpm;
const range = max - min;
const current = ((_b = this.pumpCircuit.speed) !== null && _b !== void 0 ? _b : min) - min;
const value = (current / range) * 100;
const result = Math.round(value);
this.platform.log.debug(`Converted speed value from ${this.pumpCircuit.speed} ${this.pumpCircuit.speedType} to ${result}`);
return result;
}
convertPowerLevelToSpeed(powerLevel) {
if (!this.pumpCircuit) {
this.platform.log.error('Cannot convert power level when pumpCircuit is null');
return 0;
}
const min = this.pumpCircuit.speedType === types_1.PumpSpeedType.GPM ? this.pumpCircuit.pump.minFlow : this.pumpCircuit.pump.minRpm;
const max = this.pumpCircuit.speedType === types_1.PumpSpeedType.GPM ? this.pumpCircuit.pump.maxFlow : this.pumpCircuit.pump.maxRpm;
const range = max - min;
const fromMin = (powerLevel / 100) * range;
const value = min + fromMin;
const result = this.pumpCircuit.speedType === types_1.PumpSpeedType.GPM ? Math.round(value) : Math.round(value / 50) * 50;
this.platform.log.debug(`Converted power level from ${powerLevel} to ${result} ${this.pumpCircuit.speedType}`);
return result;
}
}
exports.CircuitAccessory = CircuitAccessory;
//# sourceMappingURL=circuitAccessory.js.map