homebridge-loxone-proxy
Version:
Homebridge Dynamic Platform Plugin which exposes a Loxone System to Homekit.
183 lines • 6.85 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ColorLightBulb = void 0;
const LightBulb_1 = require("./LightBulb");
class ColorLightBulb extends LightBulb_1.LightBulb {
constructor() {
super(...arguments);
this.lastSetMode = '';
this.State = {
On: false,
Brightness: 0,
Hue: 0,
Saturation: 0,
ColorTemperature: 153,
};
}
setupService() {
super.setupService();
const { Characteristic } = this.platform;
this.service
.getCharacteristic(Characteristic.Hue)
.onSet(this.setHue.bind(this))
.onGet(this.getHue.bind(this));
this.service
.getCharacteristic(Characteristic.Saturation)
.onSet(this.setSaturation.bind(this))
.onGet(this.getSaturation.bind(this));
this.service
.getCharacteristic(Characteristic.ColorTemperature)
.onSet(this.setColorTemperature.bind(this))
.onGet(this.getColorTemperature.bind(this));
}
updateService(message) {
this.platform.log.debug(`[${this.device.name}] Callback state update for ColorLightBulb: ${message.value}`);
const hsvRegex = /^\W*hsv?\(([^)]*)\)\W*$/i;
const tempRegex = /^\W*temp?\(([^)]*)\)\W*$/i;
const parseParams = (params) => {
const regex = /^\s*(\d*)(\.\d+)?\s*$/;
const [mH, mS, mV] = params.map(param => param.match(regex));
if (mH && mS && mV) {
this.State.Hue = parseFloat((mH[1] || '0') + (mH[2] || ''));
this.State.Saturation = parseFloat((mS[1] || '0') + (mS[2] || ''));
this.State.Brightness = parseFloat((mV[1] || '0') + (mV[2] || ''));
this.State.On = this.State.Brightness > 0;
this.lastSetMode = 'color';
}
};
const processHSV = (value) => {
const match = value.match(hsvRegex);
if (match) {
const params = match[1].split(',');
parseParams(params);
}
};
const processTemp = (value) => {
const match = value.match(tempRegex);
if (match) {
const params = match[1].split(',');
const rgb = colorTemperatureToRGB(parseInt(params[1]));
const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
this.State.ColorTemperature = loxoneToHomekitColorTemperature(parseInt(params[1]));
this.State.Hue = 360 * hsv.h;
this.State.Saturation = hsv.s * 100;
this.State.Brightness = parseInt(params[0]);
this.State.On = this.State.Brightness > 0;
this.lastSetMode = 'colortemperature';
}
};
processHSV(message.value);
processTemp(message.value);
this.service.getCharacteristic(this.platform.Characteristic.Hue).updateValue(this.State.Hue);
this.service.getCharacteristic(this.platform.Characteristic.Saturation).updateValue(this.State.Saturation);
this.service.getCharacteristic(this.platform.Characteristic.ColorTemperature).updateValue(this.State.ColorTemperature);
this.service.getCharacteristic(this.platform.Characteristic.On).updateValue(this.State.On);
this.service.getCharacteristic(this.platform.Characteristic.Brightness).updateValue(this.State.Brightness);
}
async setColorState() {
const { device, platform, State } = this;
const { name, uuidAction } = device;
const { LoxoneHandler } = platform;
let command = '';
if (this.lastSetMode === 'color') {
command = `hsv(${State.Hue},${State.Saturation},${State.Brightness})`;
}
else if (this.lastSetMode === 'colortemperature') {
command = `temp(${State.Brightness},${homekitToLoxoneColorTemperature(State.ColorTemperature)})`;
}
platform.log.debug(`[${name}] HomeKit - send message: ${command}`);
LoxoneHandler.sendCommand(uuidAction, command);
State.On = State.Brightness > 0;
}
async setOn(value) {
if (!value) {
this.State.Brightness = 0;
this.setColorState();
}
}
async setBrightness(value) {
this.State.Brightness = value;
this.State.On = this.State.Brightness > 0;
this.setColorState();
}
async setHue(value) {
this.State.Hue = value;
this.lastSetMode = 'color';
this.setColorState();
}
async getHue() {
return this.State.Hue;
}
async setSaturation(value) {
this.State.Saturation = value;
this.lastSetMode = 'color';
this.setColorState();
}
async getSaturation() {
return this.State.Saturation;
}
async setColorTemperature(value) {
this.State.ColorTemperature = value;
this.lastSetMode = 'colortemperature';
this.setColorState();
}
async getColorTemperature() {
return this.State.ColorTemperature;
}
}
exports.ColorLightBulb = ColorLightBulb;
function homekitToLoxoneColorTemperature(ct) {
const percent = 1 - ((ct - 153) / (500 - 153));
return Math.round(2700 + ((6500 - 2700) * percent));
}
function loxoneToHomekitColorTemperature(ct) {
const percent = 1 - ((ct - 2700) / (6500 - 2700));
return Math.round(153 + ((500 - 153) * percent));
}
function colorTemperatureToRGB(kelvin) {
const temperature = kelvin / 100;
let red, green, blue;
if (temperature <= 66) {
red = 255;
green = 99.4708025861 * Math.log(temperature) - 161.1195681661;
blue = temperature <= 19 ? 0 : 138.5177312231 * Math.log(temperature - 10) - 305.0447927307;
}
else {
red = 329.698727446 * Math.pow(temperature - 60, -0.1332047592);
green = 288.1221695283 * Math.pow(temperature - 60, -0.0755148492);
blue = 255;
}
return {
r: clamp(red, 0, 255),
g: clamp(green, 0, 255),
b: clamp(blue, 0, 255),
};
}
function clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
}
function rgbToHsv(r, g, b) {
r /= 255, g /= 255, b /= 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
const d = max - min;
let h = 0;
if (d !== 0) {
switch (max) {
case r:
h = ((g - b) / d) + (g < b ? 6 : 0);
break;
case g:
h = ((b - r) / d) + 2;
break;
case b:
h = ((r - g) / d) + 4;
break;
}
h /= 6;
}
const s = max === 0 ? 0 : d / max;
const v = max;
return { h, s, v };
}
//# sourceMappingURL=ColorLightBulb.js.map