UNPKG

magichome-platform

Version:

discover, control, and receive status for magichome devices

177 lines (176 loc) 8.54 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isCommandEqual = exports.adjustCommandToAPI = exports.getAPI = exports.discoverProtoDevices = void 0; const miscUtils_1 = require("magichome-core/dist/utils/miscUtils"); const deviceTypesMap_1 = require("./deviceTypesMap"); const miscUtils_2 = require("./miscUtils"); const magichome_core_1 = require("magichome-core"); const errorTypes_1 = require("../models/errorTypes"); async function discoverProtoDevices(subnets) { let discoveredDevices = await (0, magichome_core_1.discoverDevices)(1000, subnets); for (let scans = 0; scans < 5; scans++) { if (discoveredDevices.length > 0) break; discoveredDevices = await (0, magichome_core_1.discoverDevices)(1000, subnets); } return discoveredDevices; } exports.discoverProtoDevices = discoverProtoDevices; function getAPI(deviceMetaData) { const { controllerHardwareVersion } = deviceMetaData; if (!deviceTypesMap_1.deviceTypesMap.has(controllerHardwareVersion)) throw new errorTypes_1.NoMatchingAPIError(deviceMetaData); const deviceAPI = deviceTypesMap_1.deviceTypesMap.get(controllerHardwareVersion); // if (matchingFirmwareVersions.has(controllerFirmwareVersion)) adjustedProtocols = matchingFirmwareVersions.get(controllerFirmwareVersion); return deviceAPI; } exports.getAPI = getAPI; function adjustCommandToAPI(deviceCommand, commandOptions, deviceAPI) { const { byteOrder, simultaneousCCT, hasCCT, hasColor } = deviceAPI; if (!hasColor || !commandOptions.colorAssist) return deviceCommand; let newDeviceCommand = (0, miscUtils_1.cloneDeep)(deviceCommand); newDeviceCommand.colorMask = determineColorMask(newDeviceCommand, simultaneousCCT, hasCCT); newDeviceCommand = adjustCCT(newDeviceCommand, deviceAPI); newDeviceCommand.isOn = adjustIsOn(newDeviceCommand); newDeviceCommand = setRGBOrder(newDeviceCommand, byteOrder); //this must be done last as to not interfere with the other adjustments return newDeviceCommand; } exports.adjustCommandToAPI = adjustCommandToAPI; function determineColorMask(deviceCommand, simultaneousCCT, hasCCT) { let { RGB: { red, green, blue }, CCT: { warmWhite, coldWhite }, colorMask, } = deviceCommand; if (simultaneousCCT) colorMask = magichome_core_1.ColorMask.BOTH; if (!hasCCT) colorMask = magichome_core_1.ColorMask.RGB; const colorMin = Math.min(red, green, blue); const colorMax = Math.max(red, green, blue); const whiteMax = Math.max(warmWhite, coldWhite); //catch all for when the colorMask is not explicitly defined by above conditions if (!colorMask) colorMask = colorMax >= whiteMax || colorMax - colorMin >= 1 ? magichome_core_1.ColorMask.RGB : magichome_core_1.ColorMask.CCT; return colorMask; } function setRGBOrder(deviceCommand, byteOrder) { if (byteOrder.length < 3) return deviceCommand; const { RGB: { red, green, blue }, } = deviceCommand; const colorList = [0, 0, 0]; let i = 0; for (const byte of byteOrder) { if (i > colorList.length - 1) break; switch (byte) { case "r": colorList[i] = red; break; case "g": colorList[i] = green; break; case "b": colorList[i] = blue; break; default: break; } i++; } return (0, miscUtils_1.combineDeep)(deviceCommand, { RGB: { red: colorList[0] || 0, green: colorList[1] || 0, blue: colorList[2] || 0, }, }); } //TODO: these need to be changed so this function is skippable in configuration. This is not the same as the other functions and is more subjective to personal preference //this could be done at a device object level which could be enabled/disabled on the fly from a GUI function adjustCCT(deviceCommand, deviceAPI) { let newDeviceCommand = (0, miscUtils_1.cloneDeep)(deviceCommand); const { byteOrder, simultaneousCCT } = deviceAPI; const { RGB: { red, green, blue }, CCT: { warmWhite, coldWhite }, colorMask, } = deviceCommand; const cwAdj = Math.round(coldWhite / 2), wwRedAdj = Math.round(warmWhite / 2), wwGreenAdj = Math.round(warmWhite / 6.8), wwBlueAdj = Math.round(warmWhite / 28.4); //todo handle non RGB devices, single brightness devices // simultaneousCCT, 5-colors, ColorMask set to CCT if (byteOrder.length == 5 && simultaneousCCT && colorMask == magichome_core_1.ColorMask.CCT) { /*do nothing for now */ } // non-simultaneousCCT, 5-colors, ColorMask set to CCT else if (byteOrder.length == 5 && !simultaneousCCT && colorMask == magichome_core_1.ColorMask.CCT) { /*do nothing for now */ } // non-simultaneousCCT, 5-colors, ColorMask not explicitly defined or is defined as RGB/BOTH else if (byteOrder.length == 5 && !simultaneousCCT) { /*do nothing for now*/ } // simultaneousCCT, 4-colors, ColorMask not explicitly defined or is defined as RGB/BOTH // (adjusts the color channels to account for the lack of a 2nd white channel by modifying the RGB channels to be cooler) else if (byteOrder.length == 4 && simultaneousCCT && coldWhite > 0) { newDeviceCommand = (0, miscUtils_1.combineDeep)(deviceCommand, { RGB: { red: (0, miscUtils_2.clamp)(red + cwAdj, 0, 255), green: (0, miscUtils_2.clamp)(green + cwAdj, 0, 255), blue: (0, miscUtils_2.clamp)(blue + cwAdj, 0, 255), }, CCT: { warmWhite: Math.max(coldWhite, warmWhite), coldWhite }, colorMask: magichome_core_1.ColorMask.BOTH, }); } // non-simultaneousCCT, 4-colors, ColorMask set to CCT // (adjusts for the lack of a 2nd white channel by using the highest value for both warm and cold white) else if (byteOrder.length == 4 && !simultaneousCCT && colorMask == magichome_core_1.ColorMask.CCT) { newDeviceCommand = (0, miscUtils_1.combineDeep)(deviceCommand, { CCT: { warmWhite: Math.max(warmWhite, coldWhite), coldWhite: 0 }, }); } // non-simultaneousCCT, 4-colors, ColorMask not explicitly defined or is defined as RGB // (adjusts for the lack of simultaneous CCT and RGB by adding adjustments calculated from both warmWhite and coldWhite to the RGB channels) else if (!simultaneousCCT && byteOrder.length == 4) { newDeviceCommand = (0, miscUtils_1.combineDeep)(deviceCommand, { RGB: { red: (0, miscUtils_2.clamp)(red + cwAdj + wwRedAdj, 0, 255), green: (0, miscUtils_2.clamp)(green + cwAdj + wwGreenAdj, 0, 255), blue: (0, miscUtils_2.clamp)(blue + cwAdj + wwBlueAdj, 0, 255), }, colorMask: magichome_core_1.ColorMask.RGB, }); } //non-simultaneousCCT, 3-colors, ColorMask not explicitly defined or is defined as RGB // (adjusts for the lack of simultaneous CCT and RGB by adding adjustments calculated from both warmWhite and coldWhite to the RGB channels) else if (!simultaneousCCT && byteOrder.length == 3) { newDeviceCommand = (0, miscUtils_1.combineDeep)(deviceCommand, { RGB: { red: (0, miscUtils_2.clamp)(red + cwAdj + wwRedAdj, 0, 255), green: (0, miscUtils_2.clamp)(green + cwAdj + wwGreenAdj, 0, 255), blue: (0, miscUtils_2.clamp)(blue + cwAdj + wwBlueAdj, 0, 255), }, colorMask: magichome_core_1.ColorMask.RGB, }); } return newDeviceCommand; } function adjustIsOn(deviceCommand) { let isOn = false; const { RGB: { red, green, blue }, CCT: { warmWhite, coldWhite }, } = deviceCommand; if (Math.max(red, green, blue, warmWhite, coldWhite) > 0) isOn = true; return isOn; } function isCommandEqual(colorStart, colorTarget) { let isEqual = false; try { isEqual = (0, miscUtils_1.deepEqual)(colorStart, colorTarget, ["colorMask"]); } catch (error) { console.log("Error in isCommandEqual: ", error); } return isEqual; } exports.isCommandEqual = isCommandEqual;