diff --git a/server/seedDatabase.js b/server/seedDatabase.js index 9c0a5a3..d069cc7 100644 --- a/server/seedDatabase.js +++ b/server/seedDatabase.js @@ -125,6 +125,22 @@ async function seedDatabase() { cooldown_period: 300, // 5 minutes between alerts min_detections: 1, time_window: 60 // 1 minute window + }, + { + user_id: adminUser.id, + name: 'Orlan Military Drone Detection Alert', + description: 'Emergency alert for any Orlan military drone detection regardless of location', + is_active: true, + device_ids: [], // All devices + drone_types: [1], // Only Orlan drones (type 1) + min_rssi: -100, // Any RSSI level + priority: 'critical', + min_threat_level: null, // No minimum threat level (will trigger on any Orlan) + alert_channels: ['sms'], + sms_phone_number: '0736419592', // Emergency contact + cooldown_period: 60, // Short cooldown for critical threats + min_detections: 1, + time_window: 30 // Short time window for immediate response } ]); diff --git a/server/services/alertService.js b/server/services/alertService.js index bc3728c..30050b2 100644 --- a/server/services/alertService.js +++ b/server/services/alertService.js @@ -59,19 +59,26 @@ class AlertService { // Adjust threat level based on drone type (if classified) const droneTypes = { 0: 'Consumer/Hobby', - 1: 'Professional/Military', - 2: 'Racing/High-speed', - 3: 'Unknown/Custom' + 1: 'Orlan/Military', // Orlan drones - highest threat + 2: 'Professional/Commercial', + 3: 'Racing/High-speed', + 4: 'Unknown/Custom' }; + // CRITICAL: Orlan drones (type 1) - ALWAYS CRITICAL regardless of distance if (droneType === 1) { - // Military/Professional drone - escalate threat + threatLevel = 'critical'; + description = 'CRITICAL THREAT: ORLAN MILITARY DRONE DETECTED - IMMEDIATE RESPONSE REQUIRED'; + actionRequired = true; + console.log(`🚨 ORLAN DRONE DETECTED - Force escalating to CRITICAL threat level (RSSI: ${rssi})`); + } else if (droneType === 2) { + // Professional/Commercial drone - escalate threat if (threatLevel === 'low') threatLevel = 'medium'; if (threatLevel === 'medium') threatLevel = 'high'; if (threatLevel === 'high') threatLevel = 'critical'; - description += ' - PROFESSIONAL/MILITARY DRONE DETECTED'; + description += ' - PROFESSIONAL/COMMERCIAL DRONE DETECTED'; actionRequired = true; - } else if (droneType === 2) { + } else if (droneType === 3) { // Racing/Fast drone - escalate if close if (rssi >= -55 && threatLevel !== 'critical') { threatLevel = 'high'; @@ -177,6 +184,12 @@ class AlertService { async shouldTriggerAlert(rule, detection, threatAssessment) { try { + // CRITICAL SECURITY: Orlan drones (type 1) ALWAYS trigger alerts regardless of any other conditions + if (detection.drone_type === 1) { + console.log(`🚨 ORLAN DRONE DETECTED - Force triggering alert for rule ${rule.name} (bypassing all filters)`); + return true; + } + // SECURITY ENHANCEMENT: Check threat level requirements if (rule.min_threat_level) { const threatLevels = { 'monitoring': 0, 'low': 1, 'medium': 2, 'high': 3, 'critical': 4 }; diff --git a/test_drone_data.py b/test_drone_data.py index f340825..a3da1d5 100644 --- a/test_drone_data.py +++ b/test_drone_data.py @@ -21,11 +21,11 @@ DEVICES = [] # Realistic drone types with characteristics DRONE_TYPES = { - 1: {"name": "DJI Mavic", "max_speed": 65, "typical_rssi": -60, "freq": [2400, 2450]}, - 2: {"name": "Racing Drone", "max_speed": 120, "typical_rssi": -55, "freq": [2400, 5800]}, - 3: {"name": "DJI Phantom", "max_speed": 50, "typical_rssi": -65, "freq": [2400, 2450]}, - 4: {"name": "Fixed Wing", "max_speed": 80, "typical_rssi": -70, "freq": [900, 2400]}, - 5: {"name": "Surveillance", "max_speed": 40, "typical_rssi": -75, "freq": [2400, 5800]} + 0: {"name": "DJI Mavic (Consumer)", "max_speed": 65, "typical_rssi": -60, "freq": [2400, 2450]}, + 1: {"name": "Orlan Military Drone", "max_speed": 150, "typical_rssi": -50, "freq": [900, 2400]}, # High threat + 2: {"name": "DJI Matrice (Professional)", "max_speed": 80, "typical_rssi": -55, "freq": [2400, 5800]}, + 3: {"name": "Racing Drone", "max_speed": 120, "typical_rssi": -55, "freq": [2400, 5800]}, + 4: {"name": "Unknown/Custom", "max_speed": 70, "typical_rssi": -65, "freq": [2400, 2450]} } def fetch_devices(): @@ -97,7 +97,21 @@ class DroneSimulator: def create_new_drone(self, device): """Create a new drone with realistic starting position""" self.drone_counter += 1 - drone_type = random.choice(list(DRONE_TYPES.keys())) + + # Drone type selection with weighted probabilities + # Orlan drones are rare (2% chance), consumer drones common (50%), others distributed + rand = random.random() + if rand < 0.02: # 2% chance for Orlan (military) + drone_type = 1 + print(f"🚨 GENERATING ORLAN MILITARY DRONE (ID: {self.drone_counter}) - High threat simulation!") + elif rand < 0.52: # 50% chance for consumer + drone_type = 0 + elif rand < 0.72: # 20% chance for professional + drone_type = 2 + elif rand < 0.92: # 20% chance for racing + drone_type = 3 + else: # 8% chance for unknown + drone_type = 4 # Start at edge of coverage area angle = random.uniform(0, 2 * math.pi)