Add Autel EVO Lite drone SDK integration for aerial surveillance#70
Conversation
Co-authored-by: aurelianware <194855645+aurelianware@users.noreply.github.com>
Co-authored-by: aurelianware <194855645+aurelianware@users.noreply.github.com>
Co-authored-by: aurelianware <194855645+aurelianware@users.noreply.github.com>
Co-authored-by: aurelianware <194855645+aurelianware@users.noreply.github.com>
|
@copilot the checks are failing, please resolve |
…enum exports Co-authored-by: aurelianware <194855645+aurelianware@users.noreply.github.com>
Fixed in commit 4fbd47f. The CI failures were caused by ESLint errors in the drone modules - specifically exported enum values being flagged as unused. Added ✅ Build successful Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
aurelianware
left a comment
There was a problem hiding this comment.
@copilot there are conflicts, should this be resolved with a separate PR and close this one?
No need for a separate PR. The conflict is only in Recommended approach:
This is a standard dependency update conflict - very common and safe to resolve in the same PR. The drone SDK code doesn't interact with Prisma, so the version bump won't affect your changes. Would you like me to resolve the conflict now? |
There was a problem hiding this comment.
Pull request overview
This PR adds comprehensive Autel EVO Lite drone SDK integration to privaseeAI for aerial surveillance capabilities. The implementation provides a complete TypeScript-based module structure with flight control, mission planning, event handling, error recovery, and integration with the existing device system.
Key Changes:
- Complete drone SDK module with 8 submodules (types, config, control, missions, events, logger, recovery, adapters)
- Device registry extended to support 'drone' type devices
- Full documentation suite and working examples
- Environment configuration for drone connection and flight parameters
Reviewed changes
Copilot reviewed 20 out of 21 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| src/utils/deviceRegistry.ts | Added 'drone' to device type union for drone device support |
| src/utils/deviceAdapters.ts | Added documentation reference to DroneAdapter integration |
| src/drone/types/index.ts | Comprehensive TypeScript type definitions for drone telemetry, commands, missions, events |
| src/drone/recovery/ErrorHandler.ts | Error handling with automatic recovery strategies (placeholder implementations) |
| src/drone/missions/MissionPlanner.ts | Mission planning with waypoint validation and geofencing |
| src/drone/logger/FlightLogger.ts | Flight operations logging with configurable retention |
| src/drone/index.ts | Main module exports for all drone functionality |
| src/drone/events/EventEmitter.ts | Event-driven architecture for real-time telemetry and alerts |
| src/drone/control/DroneController.ts | Main flight controller (placeholder SDK integration) |
| src/drone/config/DroneConfig.ts | Configuration management with environment variable support |
| src/drone/adapters/DroneAdapter.ts | Integration adapter for privaseeAI device system |
| src/drone/README.md | Module documentation and quick start guide |
| examples/drone/*.ts | Three comprehensive usage examples (basic flight, missions, events) |
| examples/drone/README.md | Example documentation with setup instructions |
| docs/DRONE_INTEGRATION.md | Complete API documentation for all drone modules |
| docs/DRONE_SETUP.md | Setup guide and troubleshooting |
| README.md | Updated main README with drone feature highlights |
| .env.example | Added drone configuration variables |
| package-lock.json | Dependency updates (TypeScript, removed peer dependencies) |
| /** | ||
| * Get singleton instance | ||
| */ | ||
| public static getInstance(config?: Partial<LoggerConfig>): FlightLogger { | ||
| if (!FlightLogger.instance) { | ||
| FlightLogger.instance = new FlightLogger(config); |
There was a problem hiding this comment.
The singleton pattern implementation does not respect config updates after first initialization. If getInstance is called with different config parameters after the first call, those parameters will be ignored. This could lead to unexpected behavior where different parts of the system expect different logger configurations but receive the same singleton instance.
| /** | |
| * Get singleton instance | |
| */ | |
| public static getInstance(config?: Partial<LoggerConfig>): FlightLogger { | |
| if (!FlightLogger.instance) { | |
| FlightLogger.instance = new FlightLogger(config); | |
| /** | |
| * Update logger configuration at runtime | |
| */ | |
| private updateConfig(config: Partial<LoggerConfig>): void { | |
| this.config = { | |
| ...this.config, | |
| ...config, | |
| }; | |
| } | |
| /** | |
| * Get singleton instance | |
| */ | |
| public static getInstance(config?: Partial<LoggerConfig>): FlightLogger { | |
| if (!FlightLogger.instance) { | |
| FlightLogger.instance = new FlightLogger(config); | |
| } else if (config) { | |
| FlightLogger.instance.updateConfig(config); |
| if (action.fallbackStrategy) { | ||
| this.logger.info('ERROR_HANDLER', 'Executing fallback strategy', { | ||
| droneId, | ||
| fallbackStrategy: action.fallbackStrategy, | ||
| }); | ||
| await this.executeRecovery( | ||
| { strategy: action.fallbackStrategy }, | ||
| error, | ||
| droneId, | ||
| context | ||
| ); | ||
| } |
There was a problem hiding this comment.
The fallback strategy execution has no recursion depth limit. If a fallback strategy also fails and has its own fallback, this could lead to infinite recursion or stack overflow. Consider adding a maximum recursion depth parameter to prevent this.
| public static fromJSON(json: string): DroneConfigManager { | ||
| try { | ||
| const config = JSON.parse(json) as DroneConfig; | ||
| return new DroneConfigManager(config); | ||
| } catch (error) { | ||
| throw new Error(`Failed to parse configuration JSON: ${error}`); | ||
| } | ||
| } |
There was a problem hiding this comment.
The fromJSON static method creates a new instance of DroneConfigManager instead of updating the existing singleton. This breaks the singleton pattern and could lead to multiple instances with different configurations existing simultaneously, causing inconsistent behavior across the application.
| const DEFAULT_CONFIG: DroneConfig = { | ||
| connectionSettings: { | ||
| host: process.env.DRONE_HOST || 'localhost', | ||
| port: parseInt(process.env.DRONE_PORT || '8889', 10), | ||
| protocol: (process.env.DRONE_PROTOCOL as 'tcp' | 'udp' | 'websocket') || 'tcp', | ||
| apiKey: process.env.DRONE_API_KEY, | ||
| timeout: 5000, | ||
| retryAttempts: 3, | ||
| retryDelay: 1000, | ||
| }, | ||
| flightSettings: { | ||
| maxSpeed: parseFloat(process.env.DRONE_MAX_SPEED || '15'), // m/s | ||
| maxAltitude: parseFloat(process.env.DRONE_MAX_ALTITUDE || '120'), // meters | ||
| maxDistance: parseFloat(process.env.DRONE_MAX_DISTANCE || '500'), // meters | ||
| returnHomeAltitude: parseFloat(process.env.DRONE_RTH_ALTITUDE || '30'), // meters | ||
| lowBatteryWarning: 30, // percentage | ||
| criticalBatteryLevel: 15, // percentage | ||
| enableObstacleAvoidance: true, | ||
| }, | ||
| cameraSettings: { | ||
| defaultPhotoFormat: 'jpeg', | ||
| defaultVideoFormat: 'mp4', | ||
| defaultVideoResolution: '4k', | ||
| autoRecordOnTakeoff: false, | ||
| }, | ||
| privacySettings: { | ||
| enableLocalStorage: true, | ||
| encryptFlightLogs: true, | ||
| autoDeleteAfterDays: 30, | ||
| requireAuthForAccess: true, | ||
| }, | ||
| }; |
There was a problem hiding this comment.
Environment variables are only read once at module initialization time in the DEFAULT_CONFIG object. If environment variables change at runtime (e.g., through dotenv reloading or dynamic configuration), these changes won't be reflected. The configuration is effectively frozen at startup.
| // Add to command queue | ||
| this.commandQueue.push(command); | ||
|
|
||
| // Process command queue | ||
| if (!this.isProcessingCommands) { | ||
| await this.processCommandQueue(); | ||
| } | ||
|
|
||
| // Simulate command execution (replace with actual SDK command) |
There was a problem hiding this comment.
The command queue mechanism is broken. Commands are added to the queue (line 125) but processCommandQueue only waits 100ms between already-dequeued commands and doesn't actually execute them. The actual execution happens via performCommand (line 133) outside the queue processing. This means the queue doesn't enforce ordering and multiple commands could execute concurrently.
| // Add to command queue | |
| this.commandQueue.push(command); | |
| // Process command queue | |
| if (!this.isProcessingCommands) { | |
| await this.processCommandQueue(); | |
| } | |
| // Simulate command execution (replace with actual SDK command) | |
| // Execute command directly (queue processing is handled elsewhere or by the SDK layer) |
| getLogger, | ||
| LogLevel, | ||
| WaypointActionType, | ||
| } from '../src/drone'; |
There was a problem hiding this comment.
The import path '../src/drone' is incorrect for a file in the examples directory. The correct path should be '../../src/drone' to navigate up two directory levels from examples/drone/ to reach src/drone/. This will cause a module resolution error when running the example.
| } from '../src/drone'; | |
| } from '../../src/drone'; |
| getLogger, | ||
| LogLevel, | ||
| DroneEventType, | ||
| } from '../src/drone'; |
There was a problem hiding this comment.
The import path '../src/drone' is incorrect. The correct path should be '../../src/drone' to properly navigate from examples/drone/ to src/drone/. This will cause a module resolution error.
| } from '../src/drone'; | |
| } from '../../src/drone'; |
|
|
||
| async function basicFlightExample() { | ||
| // Initialize logger | ||
| const logger = getLogger({ logLevel: LogLevel.INFO }); |
There was a problem hiding this comment.
Unused variable logger.
| getLogger, | ||
| LogLevel, | ||
| DroneEventType, | ||
| } from '../src/drone'; | ||
|
|
||
| async function eventHandlingExample() { | ||
| const logger = getLogger({ logLevel: LogLevel.DEBUG }); |
There was a problem hiding this comment.
Unused variable logger.
| getLogger, | |
| LogLevel, | |
| DroneEventType, | |
| } from '../src/drone'; | |
| async function eventHandlingExample() { | |
| const logger = getLogger({ logLevel: LogLevel.DEBUG }); | |
| DroneEventType, | |
| } from '../src/drone'; | |
| async function eventHandlingExample() { |
| getLogger, | ||
| LogLevel, | ||
| WaypointActionType, | ||
| } from '../src/drone'; | ||
|
|
||
| async function missionPlanningExample() { | ||
| const logger = getLogger({ logLevel: LogLevel.INFO }); |
There was a problem hiding this comment.
Unused variable logger.
| getLogger, | |
| LogLevel, | |
| WaypointActionType, | |
| } from '../src/drone'; | |
| async function missionPlanningExample() { | |
| const logger = getLogger({ logLevel: LogLevel.INFO }); | |
| WaypointActionType, | |
| } from '../src/drone'; | |
| async function missionPlanningExample() { |
@copilot yrs please resolve conflicts |
- Resolve package-lock.json conflict by regenerating with updated Prisma 7.1.0 - Fix import paths in examples (../src/drone → ../../src/drone) - Remove unused logger variables from examples - Add event listener cleanup in DroneAdapter to prevent memory leaks - Fix singleton pattern in DroneConfig fromJSON to update existing instance - Fix singleton pattern in FlightLogger to allow config updates after init - Add recursion depth limit (3) to recovery fallback strategies - Add clarifying comments for placeholder implementations (command queue, retry logic) - All tests passing, build successful Co-authored-by: aurelianware <194855645+aurelianware@users.noreply.github.com>
Resolved in commit 0282cb3. The merge conflict has been resolved and code review issues addressed: Merge Conflict Resolution: Code Review Fixes: All checks passing - ready for review! |
Signed-off-by: aurelianware <markus@aurelianware.com>
|
@copilot can you fix the build? |
|
@copilot apply changes based on the comments in this thread |
Summary
Complete Node.js/TypeScript SDK for Autel EVO Lite drone integration with privaseeAI's privacy-focused surveillance system. Adds modular architecture for flight control, autonomous missions, real-time telemetry, and automatic error recovery with proper resource management and singleton patterns.
What changed
Core Modules (src/drone/)
Integration Points
deviceRegistry.tsto support'drone'device type.env.examplewith drone connection and flight settingsDocumentation & Examples
Bug Fixes & Code Quality
DroneConfig.fromJSON()to update existing instance instead of creating duplicatesFlightLogger.getInstance()to allow runtime configuration updatesDroneAdapter.disconnect()to prevent memory leaks../src/drone→../../src/drone)Usage Example
Testing
Uses placeholder SDK calls - ready for Autel SDK integration.
Security/Compliance
Screenshots
N/A - Backend SDK integration
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.