UNPKG

homebridge-loxone-proxy

Version:

Homebridge Dynamic Platform Plugin which exposes a Loxone System to Homekit.

194 lines 7.32 kB
"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 = 'color'; this.lastOnBrightness = 100; 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'; this.rememberOnBrightness(); } }; 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'; this.rememberOnBrightness(); } }; 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; const command = this.lastSetMode === 'colortemperature' ? `temp(${State.Brightness},${homekitToLoxoneColorTemperature(State.ColorTemperature)})` : `hsv(${State.Hue},${State.Saturation},${State.Brightness})`; platform.log.debug(`[${name}] HomeKit - send message: ${command}`); LoxoneHandler.sendCommand(uuidAction, command); State.On = State.Brightness > 0; this.rememberOnBrightness(); } async setOn(value) { if (!value) { this.rememberOnBrightness(); this.State.Brightness = 0; return this.setColorState(); } this.State.On = true; if (this.State.Brightness === 0) { this.State.Brightness = this.lastOnBrightness; return this.setColorState(); } } async setBrightness(value) { this.State.Brightness = value; this.State.On = this.State.Brightness > 0; return this.setColorState(); } async setHue(value) { this.State.Hue = value; this.lastSetMode = 'color'; return this.setColorState(); } async getHue() { return this.State.Hue; } async setSaturation(value) { this.State.Saturation = value; this.lastSetMode = 'color'; return this.setColorState(); } async getSaturation() { return this.State.Saturation; } async setColorTemperature(value) { this.State.ColorTemperature = value; this.lastSetMode = 'colortemperature'; return this.setColorState(); } async getColorTemperature() { return this.State.ColorTemperature; } rememberOnBrightness() { if (this.State.Brightness > 0) { this.lastOnBrightness = this.State.Brightness; } } } 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