UNPKG

node-red-contrib-tplink-tapo-connect-api

Version:

This unofficial node-RED node allows connection to TP-Link Tapo devices. This project has been enhanced with AI support to enable new features. Starting with v0.50, we have added support for the KLAP protocol. To prioritize the operation of this node, we

260 lines 8.27 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BulbDevice = void 0; const base_device_1 = require("./base-device"); const protocol_selector_1 = require("../core/protocol-selector"); const auth_1 = require("../core/auth"); const klap_auth_1 = require("../core/klap-auth"); /** * Bulb device implementation using composition pattern * Single responsibility: Bulb-specific device behavior */ class BulbDevice extends base_device_1.BaseDevice { constructor(ip, credentials, deviceModel) { super(ip, credentials, deviceModel); } /** * Initialize session based on selected protocol */ async initializeSession(protocol) { try { if (protocol === protocol_selector_1.ProtocolType.KLAP) { await this.initializeKlapSession(); } else { await this.initializePassthroughSession(); } } catch (error) { throw new Error(`Failed to initialize ${protocol} session: ${error.message}`); } } /** * Initialize KLAP session */ async initializeKlapSession() { var _a, _b, _c, _d; if (!this.klapAuth) { this.klapAuth = new klap_auth_1.KlapAuth(this.ip, this.credentials); } await this.klapAuth.authenticate(); const sessionData = { sessionId: ((_b = (_a = this.klapAuth).getSessionId) === null || _b === void 0 ? void 0 : _b.call(_a)) || undefined, token: ((_d = (_c = this.klapAuth).getToken) === null || _d === void 0 ? void 0 : _d.call(_c)) || undefined, expiresAt: Date.now() + 1800000 // 30 minutes }; await this.sessionManager.initializeSession(sessionData); } /** * Initialize Passthrough session */ async initializePassthroughSession() { var _a, _b; if (!this.auth) { this.auth = new auth_1.TapoAuth(this.ip, this.credentials); } const session = await this.auth.authenticate(); const sessionData = { sessionId: session.sessionId, token: session.token, cookies: ((_b = (_a = this.auth).getCookies) === null || _b === void 0 ? void 0 : _b.call(_a)) || undefined, expiresAt: Date.now() + 1800000 // 30 minutes }; await this.sessionManager.initializeSession(sessionData); } /** * Set light effect (if supported) */ async setLightEffect(effect) { if (!this.capabilities.hasLightEffects) { throw new Error('Light effects not supported by this device'); } if (!this.lightingController) { throw new Error('Lighting controller not available'); } return this.lightingController.setLightEffect(effect); } /** * Get predefined light effects */ getPredefinedEffects() { if (!this.capabilities.hasLightEffects) { return []; } return [ { name: 'Aurora', enable: true, brightness: 100, custom: 0, segments: [0] }, { name: 'Bubbling Cauldron', enable: true, brightness: 100, custom: 0, segments: [0] }, { name: 'Candy Cane', enable: true, brightness: 100, custom: 0, segments: [0] }, { name: 'Flicker', enable: true, brightness: 100, custom: 0, segments: [0] }, { name: 'Grandma\'s Christmas Lights', enable: true, brightness: 100, custom: 0, segments: [0] }, { name: 'Hanukkah', enable: true, brightness: 100, custom: 0, segments: [0] }, { name: 'Haunted Mansion', enable: true, brightness: 100, custom: 0, segments: [0] }, { name: 'Icicle', enable: true, brightness: 100, custom: 0, segments: [0] }, { name: 'Lightning', enable: true, brightness: 100, custom: 0, segments: [0] }, { name: 'Ocean', enable: true, brightness: 100, custom: 0, segments: [0] }, { name: 'Rainbow', enable: true, brightness: 100, custom: 0, segments: [0] }, { name: 'Spring', enable: true, brightness: 100, custom: 0, segments: [0] } ]; } /** * Turn off light effect */ async turnOffLightEffect() { if (!this.capabilities.hasLightEffects) { throw new Error('Light effects not supported by this device'); } await this.setLightEffect({ name: 'Off', enable: false }); } /** * Get bulb-specific status */ async getBulbStatus() { const deviceInfo = await this.getDeviceInfo(); const deviceInfoAny = deviceInfo; const status = { isOn: deviceInfo.device_on || false }; if (deviceInfoAny.brightness !== undefined) { status.brightness = deviceInfoAny.brightness; } const colorMode = this.determineColorMode(deviceInfoAny); if (colorMode) { status.colorMode = colorMode; } if (deviceInfoAny.hue !== undefined) { status.hue = deviceInfoAny.hue; } if (deviceInfoAny.saturation !== undefined) { status.saturation = deviceInfoAny.saturation; } if (deviceInfoAny.color_temp !== undefined) { status.colorTemp = deviceInfoAny.color_temp; } if (this.capabilities.hasLightEffects) { status.hasEffectActive = this.hasActiveEffect(deviceInfoAny); } return status; } /** * Determine current color mode */ determineColorMode(deviceInfo) { if (!this.capabilities.hasColorControl) { return undefined; } // If hue and saturation are present and saturation > 0, it's color mode if (deviceInfo.hue !== undefined && deviceInfo.saturation !== undefined && deviceInfo.saturation > 0) { return 'color'; } // If color temperature is set, it's white mode if (deviceInfo.color_temp !== undefined) { return 'white'; } return undefined; } /** * Check if there's an active light effect */ hasActiveEffect(deviceInfo) { if (!this.capabilities.hasLightEffects) { return false; } // Check if lighting_effect is present and enabled return deviceInfo.lighting_effect && deviceInfo.lighting_effect.enable === true; } /** * Set bulb to white mode with specific temperature */ async setWhiteMode(temperature = 4000, brightness) { if (!this.capabilities.hasColorTemperature) { throw new Error('Color temperature control not supported by this device'); } await this.setColorTemperature(temperature, brightness); } /** * Set bulb to color mode with specific color */ async setColorMode(hue, saturation = 100, brightness) { if (!this.capabilities.hasColorControl) { throw new Error('Color control not supported by this device'); } await this.setColorHSV(hue, saturation, brightness); } } exports.BulbDevice = BulbDevice; //# sourceMappingURL=bulb-device.js.map