Skip to content

Add Autel EVO Lite drone SDK integration for aerial surveillance#70

Merged
aurelianware merged 8 commits into
mainfrom
copilot/create-nodejs-project-structure
Jan 2, 2026
Merged

Add Autel EVO Lite drone SDK integration for aerial surveillance#70
aurelianware merged 8 commits into
mainfrom
copilot/create-nodejs-project-structure

Conversation

Copilot AI commented Jan 1, 2026

Copy link
Copy Markdown
Contributor

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/)

  • types/ - TypeScript definitions: 14 interfaces, 7 enums for telemetry, commands, missions, events
  • config/ - Singleton configuration manager with env var integration, validation, and runtime updates
  • control/ - DroneController: takeoff/land, GPS navigation, camera ops, telemetry streaming with placeholder command queue
  • missions/ - MissionPlanner: waypoint missions, validation, geofencing, distance/duration calc
  • events/ - Pub/sub event system with 15+ event types, history tracking, typed listeners
  • logger/ - FlightLogger with 5 log levels, flight tracking, categorized logging, runtime config updates
  • recovery/ - Auto-recovery with 6 strategies (retry, RTH, emergency land, hover, abort, continue) and recursion depth limiting (max 3 levels)
  • adapters/ - DroneAdapter implementing DeviceAdapter interface with proper event listener cleanup

Integration Points

  • Updated deviceRegistry.ts to support 'drone' device type
  • Extended .env.example with drone connection and flight settings
  • Updated main README with drone features section
  • Merged Prisma 7.1.0 dependency updates from main branch

Documentation & Examples

  • docs/DRONE_INTEGRATION.md (10KB) - Complete API reference
  • docs/DRONE_SETUP.md (4KB) - Setup and troubleshooting
  • examples/drone/ - 3 working examples with corrected import paths: basic flight, mission planning, event handling

Bug Fixes & Code Quality

  • Fixed singleton pattern in DroneConfig.fromJSON() to update existing instance instead of creating duplicates
  • Fixed singleton pattern in FlightLogger.getInstance() to allow runtime configuration updates
  • Added event listener cleanup in DroneAdapter.disconnect() to prevent memory leaks
  • Added recursion depth limit (3) to recovery fallback strategies to prevent stack overflow
  • Fixed incorrect import paths in all example files (../src/drone../../src/drone)
  • Removed unused logger variables from example files
  • Added clarifying comments for placeholder implementations (command queue, retry logic with Math.random)

Usage Example

import { createDroneController, getMissionPlanner } from '../../src/drone';

// Basic flight control
const drone = createDroneController('surveillance-1');
await drone.connect({ host: '192.168.1.100', port: 8889 });
await drone.takeoff(10);
await drone.moveToPosition(37.7749, -122.4194, 30, 8);
await drone.takePhoto();
await drone.land();

// Autonomous mission
const planner = getMissionPlanner();
const mission = planner.createMission('Perimeter', waypoints);
planner.setGeofence(mission.id, center, 300);
if (planner.validateMission(mission.id).isValid) {
  // Execute mission
}

Testing

  • ✅ TypeScript compilation verified
  • ✅ Vite build successful
  • ✅ All tests passing (5/5)
  • ✅ ESLint clean (warnings only, no errors)
  • ✅ Merge conflict resolved (package-lock.json with Prisma 7.1.0)
  • ✅ Code review feedback addressed (memory leaks, singleton patterns, recursion limits)

Uses placeholder SDK calls - ready for Autel SDK integration.

Security/Compliance

  • No secrets committed
  • Logging avoids PHI (unless PHI_ENABLED + private endpoints + KV configured)
  • Privacy-first: encrypted logs, local storage, configurable retention, API key auth
  • Event listeners properly cleaned up to prevent memory leaks
  • Recursion limits prevent stack overflow in error recovery

Screenshots

N/A - Backend SDK integration

Original prompt

Create a Node.js project structure for integrating Autel EVO Lite drone SDK with a privacy-focused surveillance system called privaseeAI. The structure should include:

  • Separate modules for drone control, mission planning, and event handling
  • Configuration management for drone connection settings
  • Logging system for flight operations
  • Error handling and recovery mechanisms
  • TypeScript support with proper typing
  • Environment variable management for API keys and drone credentials

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 4 commits January 1, 2026 12:37
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 AI changed the title [WIP] Create project structure for Autel EVO Lite integration Add Autel EVO Lite drone SDK integration for aerial surveillance Jan 1, 2026
Copilot AI requested a review from aurelianware January 1, 2026 12:48
@aurelianware

Copy link
Copy Markdown
Owner

@copilot the checks are failing, please resolve

…enum exports

Co-authored-by: aurelianware <194855645+aurelianware@users.noreply.github.com>

Copilot AI commented Jan 1, 2026

Copy link
Copy Markdown
Contributor Author

@copilot the checks are failing, please resolve

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 eslint-disable comments for enum exports and fixed any type annotations. All checks now passing:

✅ Build successful
✅ Tests passing (5/5)
✅ TypeScript compilation successful
✅ ESLint clean (warnings only, no errors)

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:

  • checkpoint.prisma.io
    • Triggering command: /usr/local/bin/node /usr/local/bin/node /home/REDACTED/work/privaseeAI/privaseeAI/node_modules/prisma/build/child {&#34;product&#34;:&#34;prisma&#34;,&#34;version&#34;:&#34;6.19.0&#34;,&#34;cli_install_type&#34;:&#34;local&#34;,&#34;information&#34;:&#34;&#34;,&#34;local_timestamp&#34;:&#34;2026-01-01T19:01:29Z&#34;,&#34;project_hash&#34;:&#34;1cfe4b26&#34;,&#34;cli_path&#34;:&#34;/home/REDACTED/work/privaseeAI/privaseeAI/node_modules/.bin/prisma&#34;,&#34;cli_path_hash&#34;:&#34;902d9007&#34;, (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI requested a review from aurelianware January 1, 2026 19:07
@aurelianware
aurelianware marked this pull request as ready for review January 1, 2026 19:10
Copilot AI review requested due to automatic review settings January 1, 2026 19:11

@aurelianware aurelianware left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot there are conflicts, should this be resolved with a separate PR and close this one?

Copilot AI commented Jan 1, 2026

Copy link
Copy Markdown
Contributor Author

@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 package-lock.json due to Prisma dependency updates (6.19.0 → 7.1.0) that were merged to main. This is a simple conflict to resolve:

Recommended approach:

  1. Merge main into this branch
  2. Resolve the package-lock.json conflict by regenerating it: npm install --package-lock-only
  3. Verify builds and tests still pass
  4. Push the merge commit

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?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)

Comment on lines +61 to +66
/**
* Get singleton instance
*/
public static getInstance(config?: Partial<LoggerConfig>): FlightLogger {
if (!FlightLogger.instance) {
FlightLogger.instance = new FlightLogger(config);

Copilot AI Jan 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
/**
* 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);

Copilot uses AI. Check for mistakes.
Comment on lines +262 to +273
if (action.fallbackStrategy) {
this.logger.info('ERROR_HANDLER', 'Executing fallback strategy', {
droneId,
fallbackStrategy: action.fallbackStrategy,
});
await this.executeRecovery(
{ strategy: action.fallbackStrategy },
error,
droneId,
context
);
}

Copilot AI Jan 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +193 to +200
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}`);
}
}

Copilot AI Jan 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +7 to +38
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,
},
};

Copilot AI Jan 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment thread src/drone/control/DroneController.ts Outdated
Comment on lines +124 to +132
// 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)

Copilot AI Jan 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
// 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)

Copilot uses AI. Check for mistakes.
Comment thread examples/drone/mission-planning.ts Outdated
getLogger,
LogLevel,
WaypointActionType,
} from '../src/drone';

Copilot AI Jan 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
} from '../src/drone';
} from '../../src/drone';

Copilot uses AI. Check for mistakes.
Comment thread examples/drone/event-handling.ts Outdated
getLogger,
LogLevel,
DroneEventType,
} from '../src/drone';

Copilot AI Jan 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
} from '../src/drone';
} from '../../src/drone';

Copilot uses AI. Check for mistakes.
Comment thread examples/drone/basic-flight.ts Outdated

async function basicFlightExample() {
// Initialize logger
const logger = getLogger({ logLevel: LogLevel.INFO });

Copilot AI Jan 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable logger.

Copilot uses AI. Check for mistakes.
Comment thread examples/drone/event-handling.ts Outdated
Comment on lines +14 to +20
getLogger,
LogLevel,
DroneEventType,
} from '../src/drone';

async function eventHandlingExample() {
const logger = getLogger({ logLevel: LogLevel.DEBUG });

Copilot AI Jan 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable logger.

Suggested change
getLogger,
LogLevel,
DroneEventType,
} from '../src/drone';
async function eventHandlingExample() {
const logger = getLogger({ logLevel: LogLevel.DEBUG });
DroneEventType,
} from '../src/drone';
async function eventHandlingExample() {

Copilot uses AI. Check for mistakes.
Comment thread examples/drone/mission-planning.ts Outdated
Comment on lines +16 to +22
getLogger,
LogLevel,
WaypointActionType,
} from '../src/drone';

async function missionPlanningExample() {
const logger = getLogger({ logLevel: LogLevel.INFO });

Copilot AI Jan 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable logger.

Suggested change
getLogger,
LogLevel,
WaypointActionType,
} from '../src/drone';
async function missionPlanningExample() {
const logger = getLogger({ logLevel: LogLevel.INFO });
WaypointActionType,
} from '../src/drone';
async function missionPlanningExample() {

Copilot uses AI. Check for mistakes.
@aurelianware

Copy link
Copy Markdown
Owner

@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 package-lock.json due to Prisma dependency updates (6.19.0 → 7.1.0) that were merged to main. This is a simple conflict to resolve:

Recommended approach:

  1. Merge main into this branch
  2. Resolve the package-lock.json conflict by regenerating it: npm install --package-lock-only
  3. Verify builds and tests still pass
  4. Push the merge commit

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?

@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>

Copilot AI commented Jan 1, 2026

Copy link
Copy Markdown
Contributor Author

@copilot there are conflicts, should this be resolved with a separate PR and close this one?
...

Resolved in commit 0282cb3. The merge conflict has been resolved and code review issues addressed:

Merge Conflict Resolution:
✅ Merged main branch with Prisma 7.1.0 updates
✅ Regenerated package-lock.json with updated dependencies
✅ Build and tests passing

Code Review Fixes:
✅ Fixed import paths in all examples (changed ../src/drone../../src/drone)
✅ Removed unused logger variables from example files
✅ Added event listener cleanup in DroneAdapter to prevent memory leaks
✅ Fixed singleton patterns in DroneConfig and FlightLogger
✅ Added recursion depth limit (3) to prevent infinite fallback loops
✅ Added clarifying comments for placeholder implementations

All checks passing - ready for review!

Signed-off-by: aurelianware <markus@aurelianware.com>
@aurelianware

aurelianware commented Jan 1, 2026

Copy link
Copy Markdown
Owner

@copilot can you fix the build?

@aurelianware

Copy link
Copy Markdown
Owner

@copilot apply changes based on the comments in this thread

@aurelianware
aurelianware merged commit 30dda90 into main Jan 2, 2026
1 of 8 checks passed
@aurelianware
aurelianware deleted the copilot/create-nodejs-project-structure branch January 2, 2026 02:59
Copilot AI requested a review from aurelianware January 2, 2026 03:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants