UNPKG

magichome-platform

Version:

discover, control, and receive status for magichome devices

222 lines (221 loc) 9.49 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BaseController = void 0; const magichome_core_1 = require("magichome-core"); const platformUtils_1 = require("../utils/platformUtils"); const colorConversions_1 = require("../utils/colorConversions"); const { POWER, ANIMATION_FRAME, LED } = magichome_core_1.CommandType; const DEFAULT_COMMAND_OPTIONS = { waitForResponse: false, maxRetries: 0, commandType: LED, isEightByteProtocol: false, colorAssist: true, }; class BaseController { // Buffering-related properties get ledStateRGB() { if (this._ledStateRGB === null) { throw Error('ledStateRGB is null'); } //return a deep copy of the ledStateRGB return (0, magichome_core_1.cloneDeep)(this._ledStateRGB); } set ledStateRGB(ledStateRGB) { if (ledStateRGB === null) { throw Error('Trying to set ledStateRGB but it is null'); } this._ledStateRGB = (0, magichome_core_1.cloneDeep)(ledStateRGB); } get ledStateHSV() { if (this._ledStateRGB === null) { throw Error('ledStateRGB is null and cannot be converted to HSV'); } const HSV = (0, colorConversions_1.RGBtoHSV)(this._ledStateRGB.RGB); //iterate through the rgb values and if all are 0, then the hue data has been lost and we need to use the last known hue const allRGBValuesAreZero = Object.values(this._ledStateRGB.RGB).every(value => value === 0); if (allRGBValuesAreZero) { HSV.hue = this.lastKnownHue; } return { isOn: this._ledStateRGB.isOn, HSV, CCT: this._ledStateRGB.CCT }; // already a deep copy from the ledStateRGB } get command() { return { get: (partial) => { return (0, magichome_core_1.combineDeep)(magichome_core_1.DEFAULT_COMMAND, partial); }, }; } get fullDeviceInformation() { if (this.deviceBundle.completeDevice.fetchStateResponse.deviceMetaData === null) { throw Error('DeviceMetaData is null'); } if (this.deviceBundle.completeDevice.protoDevice === null) { throw Error('ProtoDevice is null'); } if (this.deviceBundle.completeDevice.fetchStateResponse.ledStateRGB === null) { throw Error('DeviceState is null'); } if (this.deviceAPI === null) { throw Error('DeviceAPI is null'); } return { deviceAPI: this.deviceAPI, protoDevice: this.deviceBundle.completeDevice.protoDevice, ledStateRGB: this.ledStateRGB, deviceMetaData: this.deviceBundle.completeDevice.fetchStateResponse.deviceMetaData, }; } get deviceManager() { if (this._deviceManager === null) { throw Error('DeviceManager is null'); } return this._deviceManager; } set deviceManager(deviceManager) { this._deviceManager = deviceManager; } constructor(deviceBundle) { this.deviceBundle = deviceBundle; this._ledStateRGB = null; this.lastKnownHue = 0; this.lastOutboundCommand = null; this._deviceManager = null; this.manuallyControlled = false; this.id = null; this.animationList = []; this.deviceManager = deviceBundle.deviceManager; this.ledStateRGB = deviceBundle.completeDevice.fetchStateResponse.ledStateRGB; //already cloning the ledStateRGB at the setter this.deviceAPI = (0, platformUtils_1.getAPI)(deviceBundle.completeDevice.fetchStateResponse.deviceMetaData); this.id = deviceBundle.completeDevice.protoDevice.uniqueId; } async setOn(value, maxRetries = 0) { // Use our buffered partial update with just the isOn property const deviceCommand = (0, magichome_core_1.mergeDeep)(magichome_core_1.DEFAULT_COMMAND, { isOn: value }); return await this.deviceManager.sendCommand(deviceCommand, this.generateCommandOptions(POWER, maxRetries)); } async setLEDRGB(deviceCommandRGB, maxRetries = 0, colorAssist = true) { const commandOptions = this.generateCommandOptions(LED, maxRetries, colorAssist); return await this.sendCommandRGB(deviceCommandRGB, commandOptions); } async setLEDHSV(deviceCommandHSV, maxRetries = 0, colorAssist = true) { if (deviceCommandHSV.HSV.hue !== undefined) { this.lastKnownHue = deviceCommandHSV.HSV.hue; } const deviceCommandRGB = this.hsvCommandToRGB(deviceCommandHSV); return await this.setLEDRGB(deviceCommandRGB, maxRetries, colorAssist); } hsvCommandToRGB(deviceCommandHSV) { const rgb = (0, colorConversions_1.HSVtoRGB)(deviceCommandHSV.HSV); return { isOn: deviceCommandHSV.isOn, RGB: rgb, CCT: deviceCommandHSV.CCT }; } async sendCommandRGB(deviceCommand, commandOptions) { const newDeviceCommand = (0, platformUtils_1.adjustCommandToAPI)(deviceCommand, commandOptions, this.deviceAPI); (0, magichome_core_1.mergeDeep)(this.lastOutboundCommand, newDeviceCommand); await this.deviceManager.sendCommand(newDeviceCommand, commandOptions); // this.ledStateRGB = completeResponse.fetchStateResponse.ledStateRGB; // return completeResponse; } generateCommandOptions(commandType, maxRetries = 0, colorAssist = true) { let commandOptions = (0, magichome_core_1.combineDeep)(DEFAULT_COMMAND_OPTIONS, { isEightByteProtocol: this.deviceAPI.isEightByteProtocol, commandType, }); if (maxRetries > 0) { commandOptions = (0, magichome_core_1.combineDeep)(commandOptions, { maxRetries, waitForResponse: true }); } if (!colorAssist) { commandOptions = (0, magichome_core_1.combineDeep)(commandOptions, { colorAssist: false }); } return commandOptions; } async fetchDeviceStateRGB() { let scans = 0, fetchStateResponse; do { fetchStateResponse = await this.deviceManager.queryState(); const byteOrder = this.deviceAPI.byteOrder; if (byteOrder[0] === 'g' && byteOrder[1] === 'r' && byteOrder[2] === 'b') { const { red, green, blue } = fetchStateResponse.ledStateRGB.RGB; fetchStateResponse.ledStateRGB.RGB = { red: green, green: red, blue }; } scans++; } while (fetchStateResponse?.ledStateRGB == null && scans < 5); if (scans >= 5) { throw Error('fetchStateRGB - No response given'); } if (typeof fetchStateResponse == 'undefined') { throw Error('fetchStateRGB - No response given'); } this.ledStateRGB = fetchStateResponse.ledStateRGB; return fetchStateResponse.ledStateRGB; } async fetchDeviceStateHSV() { const state = await this.fetchDeviceStateRGB(); return { isOn: state.isOn, HSV: (0, colorConversions_1.RGBtoHSV)(state.RGB), CCT: state.CCT }; } //#region Animation getAnimationList() { return this.animationList; } hasAnimation(animationName) { return this.animationList.includes(animationName); } appendAnimationList(animationName) { if (Array.isArray(animationName)) { animationName.forEach((name) => { if (!this.animationList.includes(name)) { this.animationList.push(name); } }); } else if (!this.animationList.includes(animationName)) { this.animationList.push(animationName); } } removeAnimationFromList(animationName) { if (Array.isArray(animationName)) { animationName.forEach((name) => { const index = this.animationList.indexOf(name); if (index > -1) { this.animationList.splice(index, 1); } }); } else { const index = this.animationList.indexOf(animationName); if (index > -1) { this.animationList.splice(index, 1); } } } setLEDColorAnimation(color) { // console.log(this.fullDeviceInformation.protoDevice.) const COLOR = { red: 0, green: 0, blue: 0, warmWhite: 0, coldWhite: 0, }; // Use a type assertion to handle the index access for (const colorKey in color) { const key = colorKey; const typedKey = colorKey; COLOR[typedKey] = color[key]; } const deviceCommand = { isOn: true, RGB: { red: COLOR.red, green: COLOR.green, blue: COLOR.blue }, CCT: { warmWhite: COLOR.warmWhite, coldWhite: COLOR.coldWhite }, }; const commandOptions = { waitForResponse: false, isEightByteProtocol: this.deviceAPI.isEightByteProtocol, maxRetries: 0, commandType: ANIMATION_FRAME, colorAssist: true, }; this.sendCommandRGB(deviceCommand, commandOptions); } } exports.BaseController = BaseController;