UNPKG

@dotwee/homebridge-z2m

Version:

Expose your Zigbee devices to HomeKit with ease, by integrating Zigbee2MQTT with Homebridge.

177 lines 8.44 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.convertMiredColorTemperatureToXY = exports.convertMiredColorTemperatureToHueSat = exports.convertXyToHueSat = exports.convertHueSatToXy = void 0; const color_convert = __importStar(require("color-convert")); const helpers_1 = require("./helpers"); // The functions in this file are mostly based on the documentation/code provided by Philips Hue. // See: https://developers.meethue.com/develop/application-design-guidance/color-conversion-formulas-rgb-to-xy-and-back/ function gammaCorrection(v) { return v > 0.04045 ? Math.pow((v + 0.055) / (1.0 + 0.055), 2.4) : v / 12.92; } function reverseGammaCorrection(v) { return v <= 0.0031308 ? 12.92 * v : (1.0 + 0.055) * Math.pow(v, 1.0 / 2.4) - 0.055; } function convertHueSatToXy(hue, saturation) { const rgb = color_convert.hsv.rgb([hue, saturation, 100]); const red = gammaCorrection(rgb[0] / 255); const green = gammaCorrection(rgb[1] / 255); const blue = gammaCorrection(rgb[2] / 255); const X = red * 0.664511 + green * 0.154324 + blue * 0.162028; const Y = red * 0.283881 + green * 0.668433 + blue * 0.047685; const Z = red * 0.000088 + green * 0.07231 + blue * 0.986039; const xyzSum = X + Y + Z; // Round values to at most 5 decimal places, as Zigbee seems to define a 16 bit unsigned integer // for these values, which makes the smallest possible step 1/65535 (or approximately 0.000015) const x = (0, helpers_1.roundToDecimalPlaces)(X / xyzSum, 5); const y = (0, helpers_1.roundToDecimalPlaces)(Y / xyzSum, 5); return [x, y]; } exports.convertHueSatToXy = convertHueSatToXy; function convertXyToHueSat(x, y) { // Based on: https://developers.meethue.com/develop/application-design-guidance/color-conversion-formulas-rgb-to-xy-and-back/ const z = 1.0 - x - y; const Y = 1.0; const X = (Y / y) * x; const Z = (Y / y) * z; // sRGB D65 conversion let r = X * 1.656492 - Y * 0.354851 - Z * 0.255038; let g = -X * 0.707196 + Y * 1.655397 + Z * 0.036152; let b = X * 0.051713 - Y * 0.121364 + Z * 1.01153; // Remove negative values const m = Math.min(r, g, b); if (m < 0.0) { r -= m; g -= m; b -= m; } // Normalize if (r > b && r > g && r > 1.0) { // red is too big g = g / r; b = b / r; r = 1.0; } else if (g > b && g > r && g > 1.0) { // green is too big r = r / g; b = b / g; g = 1.0; } else if (b > r && b > g && b > 1.0) { // blue is too big r = r / b; g = g / b; b = 1.0; } // Gamma correction r = reverseGammaCorrection(r); g = reverseGammaCorrection(g); b = reverseGammaCorrection(b); // Maximize const max = Math.max(r, g, b); r = r === max ? 255 : 255 * (r / max); g = g === max ? 255 : 255 * (g / max); b = b === max ? 255 : 255 * (b / max); const hsv = color_convert.rgb.hsv([r, g, b]); return [hsv[0], hsv[1]]; } exports.convertXyToHueSat = convertXyToHueSat; function convertMiredColorTemperatureToHueSat(temperature) { const xy = convertMiredColorTemperatureToXY(temperature); return convertXyToHueSat(xy[0], xy[1]); } exports.convertMiredColorTemperatureToHueSat = convertMiredColorTemperatureToHueSat; function convertMiredColorTemperatureToXY(temperature) { // Based on MiredColorTemperatureToXY from: // https://github.com/dresden-elektronik/deconz-rest-plugin/blob/78939ac4ee4b0646fbf542a0f6e83ee995f1a875/colorspace.cpp const TEMPERATURE_TO_X_TEMPERATURE_THRESHOLD = 4000; const TEMPERATURE_TO_Y_FIRST_TEMPERATURE_THRESHOLD = 2222; const TEMPERATURE_TO_Y_SECOND_TEMPERATURE_THRESHOLD = 4000; const TEMPERATURE_TO_X_FIRST_FACTOR_FIRST_EQUATION = 17440695910400; const TEMPERATURE_TO_X_SECOND_FACTOR_FIRST_EQUATION = 15358885888; const TEMPERATURE_TO_X_THIRD_FACTOR_FIRST_EQUATION = 57520658; const TEMPERATURE_TO_X_FOURTH_FACTOR_FIRST_EQUATION = 11790; const TEMPERATURE_TO_X_FIRST_FACTOR_SECOND_EQUATION = 198301902438400; const TEMPERATURE_TO_X_SECOND_FACTOR_SECOND_EQUATION = 138086835814; const TEMPERATURE_TO_X_THIRD_FACTOR_SECOND_EQUATION = 14590587; const TEMPERATURE_TO_X_FOURTH_FACTOR_SECOND_EQUATION = 15754; const TEMPERATURE_TO_Y_FIRST_FACTOR_FIRST_EQUATION = 18126; const TEMPERATURE_TO_Y_SECOND_FACTOR_FIRST_EQUATION = 22087; const TEMPERATURE_TO_Y_THIRD_FACTOR_FIRST_EQUATION = 35808; const TEMPERATURE_TO_Y_FOURTH_FACTOR_FIRST_EQUATION = 3312; const TEMPERATURE_TO_Y_FIRST_FACTOR_SECOND_EQUATION = 15645; const TEMPERATURE_TO_Y_SECOND_FACTOR_SECOND_EQUATION = 22514; const TEMPERATURE_TO_Y_THIRD_FACTOR_SECOND_EQUATION = 34265; const TEMPERATURE_TO_Y_FOURTH_FACTOR_SECOND_EQUATION = 2744; const TEMPERATURE_TO_Y_FIRST_FACTOR_THIRD_EQUATION = 50491; const TEMPERATURE_TO_Y_SECOND_FACTOR_THIRD_EQUATION = 96229; const TEMPERATURE_TO_Y_THIRD_FACTOR_THIRD_EQUATION = 61458; const TEMPERATURE_TO_Y_FOURTH_FACTOR_THIRD_EQUATION = 6062; let localX = 0; let localY = 0; const temp = 1000000 / temperature; if (TEMPERATURE_TO_X_TEMPERATURE_THRESHOLD > temp) { localX = TEMPERATURE_TO_X_THIRD_FACTOR_FIRST_EQUATION / temp + TEMPERATURE_TO_X_FOURTH_FACTOR_FIRST_EQUATION - TEMPERATURE_TO_X_SECOND_FACTOR_FIRST_EQUATION / temp / temp - TEMPERATURE_TO_X_FIRST_FACTOR_FIRST_EQUATION / temp / temp / temp; } else { localX = TEMPERATURE_TO_X_SECOND_FACTOR_SECOND_EQUATION / temp / temp + TEMPERATURE_TO_X_THIRD_FACTOR_SECOND_EQUATION / temp + TEMPERATURE_TO_X_FOURTH_FACTOR_SECOND_EQUATION - TEMPERATURE_TO_X_FIRST_FACTOR_SECOND_EQUATION / temp / temp / temp; } if (TEMPERATURE_TO_Y_FIRST_TEMPERATURE_THRESHOLD > temp) { localY = (TEMPERATURE_TO_Y_THIRD_FACTOR_FIRST_EQUATION * localX) / 65536 - (TEMPERATURE_TO_Y_FIRST_FACTOR_FIRST_EQUATION * localX * localX * localX) / 281474976710656 - (TEMPERATURE_TO_Y_SECOND_FACTOR_FIRST_EQUATION * localX * localX) / 4294967296 - TEMPERATURE_TO_Y_FOURTH_FACTOR_FIRST_EQUATION; } else if (TEMPERATURE_TO_Y_SECOND_TEMPERATURE_THRESHOLD > temp) { localY = (TEMPERATURE_TO_Y_THIRD_FACTOR_SECOND_EQUATION * localX) / 65536 - (TEMPERATURE_TO_Y_FIRST_FACTOR_SECOND_EQUATION * localX * localX * localX) / 281474976710656 - (TEMPERATURE_TO_Y_SECOND_FACTOR_SECOND_EQUATION * localX * localX) / 4294967296 - TEMPERATURE_TO_Y_FOURTH_FACTOR_SECOND_EQUATION; } else { localY = (TEMPERATURE_TO_Y_THIRD_FACTOR_THIRD_EQUATION * localX) / 65536 + (TEMPERATURE_TO_Y_FIRST_FACTOR_THIRD_EQUATION * localX * localX * localX) / 281474976710656 - (TEMPERATURE_TO_Y_SECOND_FACTOR_THIRD_EQUATION * localX * localX) / 4294967296 - TEMPERATURE_TO_Y_FOURTH_FACTOR_THIRD_EQUATION; } localY *= 4; localX /= 0xffff; localY /= 0xffff; return [Math.round(localX * 10000) / 10000, Math.round(localY * 10000) / 10000]; } exports.convertMiredColorTemperatureToXY = convertMiredColorTemperatureToXY; //# sourceMappingURL=colorhelper.js.map