/** * Eufy Security WebSocket API Manager * * High-level API manager that provides a complete interface to the eufy-security-ws * WebSocket API. This class handles connection lifecycle, event management, command execution, * driver connection, state management, and error handling for Eufy devices. * * Acts as the main entry point for interacting with Eufy devices through the WebSocket container, * providing a clean abstraction over the raw WebSocket protocol. * * @example Basic Usage * ```typescript * const client = new ApiManager("ws://localhost:3000"); * await client.connect(); * await client.connectDriver(); * await client.startListening(); * * // Listen for device events * client.addEventListener("motion_detected", (event) => { * console.log("Motion detected on device:", event.serialNumber); * }); * * // Send commands * const devices = await client.sendCommand("server.get_devices"); * ``` * * @public * @since 1.0.0 */ import { EventType, EventCallbackForType } from "./types/events"; import type { EventSource } from "./common/constants"; import { SchemaCompatibilityInfo } from "./types/schema"; import { ResponseForCommand, SupportedCommandType, ParamsForCommand } from "./types/commands"; import { StartListeningResponse } from "./server/responses"; import { EnhancedCommandAPI } from "./api-manager-commands"; import { Logger, ILogObj } from "tslog"; /** * High-Level API Manager for Eufy Security WebSocket API * * Main interface for interacting with the eufy-security-ws container. Provides * a complete API for managing connections, handling events, and executing commands * with proper state management and error handling. * * The API Manager automatically handles: * - WebSocket connection establishment and management * - Schema version negotiation with the server * - Driver connection and initialization * - Event listener registration and dispatching * - Command execution with type safety * - Connection state tracking and error recovery * * This class is the recommended entry point for all Eufy WebSocket API operations. */ export declare class ApiManager { private logger; private client; private stateManager; /** * Enhanced command API for more elegant command execution. * Provides a fluent interface for building and executing commands. */ private _enhancedCommands?; private readonly CLIENT_MIN_SCHEMA; private readonly CLIENT_PREFERRED_SCHEMA; private eventListeners; private listenerIdCounter; private errorHandlers; private pendingCaptcha; private pendingMfa; /** * Create a new API Manager instance * * Initializes the WebSocket client, state manager, and sets up all necessary * event handlers for proper API operation. The client will be ready to connect * after construction. * * @param wsUrl - WebSocket server URL (e.g., 'ws://localhost:3000') * @param logger - Logger instance for logging */ constructor(wsUrl: string, logger: Logger); /** * Get current client state snapshot * * @returns Current state including connection status, schema info, and counters */ getState(): Readonly; /** * Subscribe to client state changes * * @param callback - Function to call when state changes occur * @returns Unsubscribe function to remove the listener */ onStateChange(callback: (state: any) => void): () => void; /** * Enhanced command API with more elegant fluent interface * * Provides builder pattern and method-based command execution: * - api.commands.device("12345").getProperties() * - api.commands.driver().connect() * - api.commands.command(DEVICE_COMMANDS.GET_PROPERTIES, { serialNumber: "12345" }) */ get commands(): EnhancedCommandAPI; /** * Register an event listener for WebSocket events * * Allows registration of event handlers with optional filtering by event source * and device serial number. Useful for listening to specific device events * or filtering events by type. * * @param eventType - Type of event to listen for (strongly typed event identifier) * @param eventCallback - Callback function to invoke when matching events occur * @param options - Optional filter criteria * @param options.source - Only process events from this source (server, driver, device, station) * @param options.serialNumber - Only process events from this device serial number * @returns Function to call to remove this event listener */ addEventListener(eventType: T, eventCallback: EventCallbackForType, options?: { source?: S; serialNumber?: string; }): () => boolean; /** * Remove a specific event listener by ID * * @deprecated Use the function returned by addEventListener() instead. * The new function-based API is more ergonomic and less error-prone. * * @param listenerId - Unique listener ID returned by addEventListener * @returns true if listener was found and removed, false otherwise */ removeEventListener(listenerId: string): boolean; /** * Remove all event listeners of a specific type * * Removes all registered listeners that match the specified event type. * Uses strongly typed event identifiers for precise filtering. * * @param eventType - Type of events to stop listening for (strongly typed event identifier) * @returns Number of listeners removed */ removeEventListenersByType(eventType: EventType): number; /** * Remove all event listeners for multiple event types * * Efficiently removes all listeners for the specified event types. * Useful for cleanup or when switching contexts. * * @param eventTypes - Array of event types to remove listeners for * @returns Number of listeners removed */ removeEventListenersByTypes(eventTypes: EventType[]): number; /** * Remove all event listeners for a particular serial number and source * * @param serialNumber - Device or station serial number to remove listeners for * @param source - (Optional) Event source to filter (e.g., 'device', 'station') * @returns Number of listeners removed */ removeEventListenersBySerialNumber(serialNumber: string, source?: EventSource): number; /** * Remove all registered event listeners * * @returns Number of listeners removed */ removeAllEventListeners(): number; /** * Get all registered event listeners (for debugging/monitoring) * * Returns a snapshot of currently registered listeners for debugging purposes. * The returned array contains read-only information about listeners. * * @returns Array of listener information (without callback functions) */ getEventListeners(): Array<{ id: string; eventType: EventType; source?: EventSource; serialNumber?: string; }>; /** * Establish connection to the WebSocket server * * Initiates connection to the server and automatically handles schema negotiation. * The connection process includes version negotiation and API schema setup. * * @throws Error if connection fails or schema negotiation fails */ connect(): Promise; /** * Disconnect from the WebSocket server * * Gracefully closes the WebSocket connection and resets driver connection state. */ disconnect(): void; /** * Check if client is fully connected and ready for API calls * * @returns true if WebSocket is connected and schema negotiation is complete */ isConnected(): boolean; /** * Check if driver connection is established * * @returns true if driver.connect command has been successfully executed */ isDriverConnected(): boolean; /** * Get current schema compatibility information * * @returns Schema negotiation details or null if not yet negotiated */ getSchemaInfo(): SchemaCompatibilityInfo | null; /** * Execute a typed command with parameters and get typed response * * Sends a command to the WebSocket API with full type safety. Commands are * validated against supported command types and proper parameter types are * enforced at compile time. Includes automatic retry with exponential backoff. * * @param command - Command constant (e.g., DEVICE_COMMANDS.GET_PROPERTIES) * @param params - Command parameters (type-checked based on command) * @returns Promise resolving to typed response data * @throws {Error} Client not ready error * @throws {Error} Unsupported command error * @throws {Error} Server error or timeout after retries * * @example * ```typescript * // Get device properties * const properties = await client.sendCommand(DEVICE_COMMANDS.GET_PROPERTIES, { * serialNumber: "T8210N20123456789" * }); * * // Commands without parameters * await client.sendCommand(DRIVER_COMMANDS.CONNECT); * ``` */ sendCommand(command: T, params?: ParamsForCommand): Promise>; /** * Connect to the Eufy driver * * Establishes connection to the Eufy cloud driver, which enables real-time * event streaming and fresh data from Eufy's cloud services. Many basic * device and station commands may work without driver connection using * cached data, but this is required for live events and cloud-based operations. * * @throws Error if client not ready or driver connection fails */ connectDriver(): Promise; /** * Start listening for real-time events * * Activates real-time event streaming from the server. Events will be * dispatched to registered event listeners. This should be called after * driver connection is established. Also updates driver connection state * based on the server response. * * @returns Promise resolving to server response with listening status * @throws Error if client not ready or command fails */ startListening(): Promise; /** * Set up all WebSocket event handlers * * Configures the WebSocket client with handlers for connection events, * version negotiation, and real-time event processing. */ private setupEventHandlers; /** * Handle server version message and perform schema negotiation * * Processes the server's version information and negotiates a compatible * API schema version. Uses minimum required schema (13) and preferred * schema (21). Sets up the API schema and marks schema setup as complete. * * @param versionMessage - Version message from server containing schema info. * @throws Error if schema incompatibility is detected. */ private handleVersionMessage; /** * Process incoming event messages and dispatch to listeners * * Routes event messages to registered event listeners based on filtering * criteria (source and serial number). Handles errors in individual * listeners without affecting others. * * @param message - Event message from server */ /** * Handle incoming event messages and dispatch to registered listeners * * Processes event messages from the WebSocket connection and dispatches them * to registered event listeners with proper filtering by event type, source, * and serial number. Optimized for performance with early filtering and * efficient iteration. * * @param message - Event message from WebSocket * @private */ private handleEventMessage; /** * Handle driver connection state events internally * * Listens for driver connected/disconnected events and updates the state manager * accordingly. This ensures that driver connection state is managed centrally * in the API manager without requiring external event handling. * * @param eventPayload - Event payload from the WebSocket event message */ private handleDriverConnectionStateEvents; /** * Handle CAPTCHA request event * * Called when the server requests CAPTCHA authentication. Extracts the CAPTCHA * information and stores it for later retrieval by the CLI. * * @param eventPayload - CAPTCHA request event payload */ private handleCaptchaRequest; /** * Handle MFA verification code request event * * Called when the server requests MFA verification. Stores the information * for later retrieval by the CLI. * * @param eventPayload - MFA request event payload */ private handleMfaRequest; /** * Generate unique message ID for command correlation * * Creates a unique identifier for each command message to enable proper * request-response correlation in the WebSocket protocol. * * @param command - Command type being sent. * @returns Unique message identifier. */ private generateMessageId; /** * Get pending CAPTCHA information * * Returns CAPTCHA information from the last CAPTCHA request event. * This is used by the CLI to display CAPTCHA information to the user. * * @returns CAPTCHA information or null if no CAPTCHA is pending */ getPendingCaptcha(): { captchaId: string; captcha: string; } | null; /** * Clear pending CAPTCHA information * * Clears any stored CAPTCHA information after it has been used. */ clearPendingCaptcha(): void; /** * Get pending MFA information * * Returns MFA information from the last MFA request event. * This is used by the CLI to display MFA information to the user. * * @returns MFA information or null if no MFA is pending */ getPendingMfa(): { methods: string[]; } | null; /** * Clear pending MFA information * * Clears any stored MFA information after it has been used. */ clearPendingMfa(): void; /** * Register error handler for WebSocket and API errors * * @param handler - Callback function to handle errors */ onError(handler: (error: Error) => void): void; } //# sourceMappingURL=api-manager.d.ts.map