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

132 lines 5.51 kB
"use strict"; /** * Generic Device Info Retriever * Lightweight class for getting device information from any Tapo device * without needing to know the specific device type */ Object.defineProperty(exports, "__esModule", { value: true }); exports.GenericDeviceInfoRetriever = void 0; const types_1 = require("../types"); const auth_1 = require("../core/auth"); const klap_auth_1 = require("../core/klap-auth"); class GenericDeviceInfoRetriever extends types_1.BaseTapoDevice { constructor(ip, credentials) { super(ip, credentials); this.useKlap = false; this.auth = new auth_1.TapoAuth(ip, credentials); this.klapAuth = new klap_auth_1.KlapAuth(ip, credentials); } /** * Connect to the device using either KLAP or Secure Passthrough */ async connect() { console.log(`GenericDeviceInfoRetriever.connect() called for ${this.ip}`); const maxRetries = 2; let klapError; let securePassthroughError; for (let attempt = 1; attempt <= maxRetries; attempt++) { console.log(`Connection attempt ${attempt}/${maxRetries}`); // Try KLAP first (modern devices support KLAP V2) try { console.log('Trying KLAP authentication...'); await this.klapAuth.authenticate(); this.useKlap = true; console.log('KLAP authentication successful'); return; } catch (error) { klapError = error; console.log('KLAP failed:', error); // Check if it's a -1010 error and provide helpful message if (error instanceof Error && error.message.includes('-1010')) { console.log('Note: Error -1010 indicates authentication issues. Consider checking credentials or device settings.'); } } // If KLAP fails, try Secure Passthrough (older devices) if (!this.useKlap) { try { console.log('Trying Secure Passthrough authentication...'); await this.auth.authenticate(); this.useKlap = false; console.log('Secure Passthrough authentication successful'); return; } catch (error) { securePassthroughError = error; console.log('Secure Passthrough failed:', error); // Provide specific guidance for -1010 errors if (error instanceof Error && error.message.includes('-1010')) { console.log('Error -1010 troubleshooting suggestions:'); console.log('- Verify username/password in Tapo app'); console.log('- Check if device supports remote access'); console.log('- Ensure device is online and reachable'); } } } // If both protocols fail, wait before retry if (attempt < maxRetries) { console.log('Both protocols failed, waiting before retry...'); await new Promise(resolve => setTimeout(resolve, 1000)); } } // If all attempts fail, throw error throw new Error(`Failed to authenticate with device ${this.ip} after ${maxRetries} attempts. ` + `KLAP: ${klapError === null || klapError === void 0 ? void 0 : klapError.message}, Secure Passthrough: ${securePassthroughError === null || securePassthroughError === void 0 ? void 0 : securePassthroughError.message}`); } /** * Get device information - works for all device types */ async getDeviceInfo() { const request = { method: 'get_device_info' }; const response = await this.sendRequest(request); console.log(`Device info retrieved for ${this.ip}: model=${response.result.model}, deviceType=${response.result.type}`); return response.result; } /** * Disconnect and cleanup session */ async disconnect() { console.log(`GenericDeviceInfoRetriever.disconnect() called for ${this.ip}`); // Clean up session data delete this.sessionKey; delete this.sessionId; // Note: We don't need to send explicit disconnect requests for info retrieval // The session will naturally expire } /** * Send request using the appropriate protocol */ async sendRequest(request) { if (this.useKlap) { // Use KLAP protocol - need to wrap result in TapoApiResponse format const result = await this.klapAuth.secureRequest(request); return { error_code: 0, result: result }; } else { // Use Secure Passthrough protocol - need to wrap result in TapoApiResponse format const result = await this.auth.secureRequest(request); return { error_code: 0, result: result }; } } /** * Check if device is authenticated */ isAuthenticated() { if (this.useKlap) { return this.klapAuth.isAuthenticated(); } else { return this.auth.isAuthenticated(); } } } exports.GenericDeviceInfoRetriever = GenericDeviceInfoRetriever; //# sourceMappingURL=generic-device-info.js.map