From f21ed2f2af36945ba03bdb98564d9d95da9f22a2 Mon Sep 17 00:00:00 2001 From: Alexander Borg Date: Mon, 18 Aug 2025 07:29:33 +0200 Subject: [PATCH] Fix jwt-token --- test_drone_data.py | 169 ++++++++++++++++++++++++++++- test_orlan_detection.py | 234 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 402 insertions(+), 1 deletion(-) create mode 100644 test_orlan_detection.py diff --git a/test_drone_data.py b/test_drone_data.py index a3da1d5..94d2f72 100644 --- a/test_drone_data.py +++ b/test_drone_data.py @@ -277,6 +277,169 @@ def send_detection(detection_data): print(f"āŒ Network error: {e}") return False +def simulate_orlan_detection_test(): + """ + Test Orlan military drone detection system + Spawns an Orlan 50km from device, slowly approaches until hovering overhead + Tests critical alert escalation for high-threat drones + """ + print("=" * 70) + print("🚨 ORLAN MILITARY DRONE DETECTION TEST") + print("=" * 70) + print("Test Scenario:") + print("• Starting position: 50km away (undetectable)") + print("• Drone type: Orlan Military (type 1)") + print("• Approach pattern: Straight line to target") + print("• Detection threshold: ~25km range") + print("• Critical alerts: Auto-escalated for Orlan type") + print("• End position: Directly overhead (0m)") + print("=" * 70) + + if not DEVICES: + print("āŒ No devices available for testing!") + return + + # Use the first device as target + target_device = DEVICES[0] + print(f"šŸŽÆ Target Device: {target_device['name']}") + print(f"šŸ“ Target Location: {target_device['lat']:.6f}, {target_device['lon']:.6f}") + + # Calculate starting position 50km away (due north) + start_distance = 50.0 # km + start_lat = target_device['lat'] + (start_distance / 111.0) # ~111km per degree latitude + start_lon = target_device['lon'] # Same longitude + + print(f"šŸ›« Orlan Starting Position: {start_lat:.6f}, {start_lon:.6f}") + print(f"šŸ“ Initial Distance: {start_distance:.1f}km") + + # Detection range parameters + max_detection_range = 25.0 # km + min_rssi_threshold = -95 + + def is_detectable(distance): + """Check if drone is within detectable range""" + if distance > max_detection_range: + return False + # Calculate RSSI for Orlan (military grade) + base_rssi = -50 # Stronger than civilian drones + rssi = base_rssi - (20 * 2.3 * math.log10(max(distance, 0.001))) + return rssi >= min_rssi_threshold + + def calculate_orlan_rssi(distance_km): + """Calculate RSSI for Orlan military drone""" + if distance_km < 0.001: + return -25 + base_rssi = -50 # Military grade transmission + path_loss_exponent = 2.3 + rssi = base_rssi - (20 * path_loss_exponent * math.log10(distance_km)) + return max(int(rssi), -100) + + # Verify starting position is undetectable + if is_detectable(start_distance): + print("āš ļø WARNING: Starting position is within detection range!") + else: + print("āœ… Starting position confirmed undetectable") + + print("\n" + "=" * 70) + print("STARTING ORLAN APPROACH SIMULATION") + print("=" * 70) + + # Simulation parameters + total_steps = 50 + final_distance = 0.0 # Directly overhead + drone_id = 3000 # Unique ID for Orlan test + + detection_started = False + critical_alerts_started = False + + try: + for step in range(1, total_steps + 1): + # Calculate current distance (exponential approach) + progress = step / total_steps + distance_km = start_distance * (1 - progress) ** 1.8 + final_distance * progress ** 1.8 + + # Calculate current position + current_lat = start_lat + (target_device['lat'] - start_lat) * progress + current_lon = start_lon + (target_device['lon'] - start_lon) * progress + + # Check if detectable + detectable = is_detectable(distance_km) + rssi = calculate_orlan_rssi(distance_km) + + if detectable: + if not detection_started: + print(f"\nšŸ” FIRST DETECTION at {distance_km:.1f}km - Orlan entered detection range!") + detection_started = True + + # Send detection using EXACT standard payload format + detection_data = { + "device_id": target_device["id"], + "geo_lat": current_lat, + "geo_lon": current_lon, + "device_timestamp": int(time.time() * 1000), + "drone_type": 1, # Orlan/Military type + "rssi": rssi, + "freq": 24, # 2.4 GHz + "drone_id": drone_id + } + + try: + response = requests.post(f"{API_BASE_URL}/detections", json=detection_data) + if response.status_code == 201: + status = "🚨 CRITICAL ALERT" if distance_km <= 5 else "āš ļø DETECTED" + print(f"{status} - Step {step}/{total_steps}: Distance={distance_km:.1f}km, RSSI={rssi}dBm") + + # Show escalation messages + if distance_km <= 5 and not critical_alerts_started: + print(f"🚨 CRITICAL ALERT: Orlan within {distance_km:.1f}km - AUTO-ESCALATED!") + critical_alerts_started = True + elif distance_km <= 1: + print(f"šŸ”„ IMMEDIATE THREAT: Orlan within facility perimeter!") + elif distance_km <= 0.1: + print(f"šŸ’„ DIRECTLY OVERHEAD: Orlan at {distance_km*1000:.0f}m altitude!") + else: + print(f"āŒ Failed to send detection: {response.status_code}") + except Exception as e: + print(f"āŒ Error sending detection: {e}") + else: + # Outside detection range + print(f"šŸ“” Step {step}/{total_steps}: Distance={distance_km:.1f}km (undetectable, RSSI={rssi}dBm)") + + # Variable delay based on distance + if distance_km > 30: + delay = 2.0 + elif distance_km > 15: + delay = 1.5 + elif distance_km > 5: + delay = 1.0 + else: + delay = 0.8 + + time.sleep(delay) + + print("\n" + "=" * 70) + print("🚨 ORLAN DETECTION TEST COMPLETED") + print("=" * 70) + print("Test Summary:") + print(f"• Starting distance: {start_distance:.1f}km (undetectable)") + print(f"• Detection range: ~{max_detection_range:.1f}km") + print(f"• Final position: Directly overhead") + print(f"• Target device: {target_device['name']}") + print(f"• Total steps: {total_steps}") + print("") + print("Expected Results:") + print("āœ… No detections sent while >25km away") + print("āœ… First detection when entering detection range") + print("āœ… Critical alerts auto-escalated for Orlan (type 1)") + print("āœ… All Orlan alerts bypass distance/RSSI rules") + print("āœ… Real-time tracking visible on dashboard") + print("=" * 70) + + except KeyboardInterrupt: + print("\n\nāš ļø Orlan detection test interrupted by user") + except Exception as e: + print(f"\nāŒ Error during Orlan detection test: {e}") + def simulate_realistic_scenario(duration_minutes=10): """Simulate realistic drone scenario with persistent tracking""" print(f"🚁 Starting realistic drone simulation for {duration_minutes} minutes...") @@ -405,9 +568,10 @@ def main(): print("1. Realistic scenario (persistent drones, RSSI changes, movement)") print("2. Single approaching drone (watch RSSI strengthen)") print("3. Departing drone (watch RSSI weaken)") + print("4. 🚨 Orlan military drone detection test (50km approach)") try: - choice = input("\nEnter choice (1-3): ").strip() + choice = input("\nEnter choice (1-4): ").strip() if choice == "1": duration = input("Duration in minutes (default: 10): ").strip() @@ -422,6 +586,9 @@ def main(): print("šŸ›« Simulating departing drone (RSSI will weaken)...") # Implementation for departing drone + elif choice == "4": + simulate_orlan_detection_test() + else: print("Invalid choice") diff --git a/test_orlan_detection.py b/test_orlan_detection.py new file mode 100644 index 0000000..aef4520 --- /dev/null +++ b/test_orlan_detection.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python3 +""" +Orlan Detection Test Script +Tests the critical alert system for Orlan military drones by simulating +a long-distance approach from undetectable range to directly overhead. + +Test Scenario: +- Starts 50km away (beyond detection range) +- Slowly approaches target device +- Triggers critical alerts as it enters detection range +- Ends with drone hovering directly above target +""" + +import requests +import json +import time +import math +from datetime import datetime + +# Configuration +API_BASE_URL = "http://selfservice.cqers.com/drones/api" + +# Detection range parameters (approximate) +MAX_DETECTION_RANGE_KM = 25.0 # Maximum range for drone detection +MIN_RSSI_THRESHOLD = -95 # Minimum RSSI for detection + +def haversine_distance(lat1, lon1, lat2, lon2): + """Calculate distance between two points in kilometers""" + R = 6371 # Earth's radius in kilometers + + dlat = math.radians(lat2 - lat1) + dlon = math.radians(lon2 - lon1) + + a = (math.sin(dlat/2) * math.sin(dlat/2) + + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * + math.sin(dlon/2) * math.sin(dlon/2)) + c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a)) + + return R * c + +def rssi_from_distance(distance_km): + """Calculate RSSI based on distance for Orlan drone""" + # Orlan drones have powerful military-grade transmission systems + # Base RSSI at 1km = -55 dBm (stronger than civilian drones) + base_rssi = -55 + path_loss_exponent = 2.3 # Lower path loss due to military equipment + + if distance_km < 0.001: # Less than 1 meter + return -25 + + rssi = base_rssi - (20 * path_loss_exponent * math.log10(distance_km)) + return max(rssi, -100) # Cap at -100 dBm + +def is_detectable(distance_km): + """Check if drone is within detectable range""" + rssi = rssi_from_distance(distance_km) + return distance_km <= MAX_DETECTION_RANGE_KM and rssi >= MIN_RSSI_THRESHOLD + +def fetch_devices(): + """Fetch devices from API""" + try: + response = requests.get(f"{API_BASE_URL}/devices/map") + if response.status_code == 200: + data = response.json() + return data.get('data', []) + except Exception as e: + print(f"Error fetching devices: {e}") + return [] + +def send_detection(device, drone_lat, drone_lon, distance_km, step, total_steps): + """Send a detection to the API using EXACT standard payload format""" + rssi = rssi_from_distance(distance_km) + + # Use the EXACT standard payload format - NEVER change this! + detection_data = { + "device_id": device["id"], + "geo_lat": drone_lat, + "geo_lon": drone_lon, + "device_timestamp": int(time.time() * 1000), # Current timestamp in milliseconds + "drone_type": 1, # Orlan/Military type + "rssi": int(rssi), + "freq": 24, # Orlan operates on 2.4 GHz (24 = 2400 MHz) + "drone_id": 2000 + step # Unique drone ID for tracking + } + + try: + response = requests.post(f"{API_BASE_URL}/detections", json=detection_data) + if response.status_code == 201: + status = "🚨 CRITICAL ALERT" if distance_km <= 5 else "āš ļø DETECTED" if is_detectable(distance_km) else "šŸ“” MONITORING" + print(f"{status} - Step {step}/{total_steps}: Distance={distance_km:.1f}km, RSSI={rssi:.0f}dBm") + return True + else: + print(f"Failed to send detection: {response.status_code}") + return False + except Exception as e: + print(f"Error sending detection: {e}") + return False + +def calculate_position_along_path(start_lat, start_lon, end_lat, end_lon, progress): + """Calculate position along great circle path""" + # Simple linear interpolation for this test + lat = start_lat + (end_lat - start_lat) * progress + lon = start_lon + (end_lon - start_lon) * progress + return lat, lon + +def run_orlan_detection_test(): + """Run the comprehensive Orlan detection test""" + print("=" * 70) + print("🚨 ORLAN MILITARY DRONE DETECTION TEST") + print("=" * 70) + print("Test Scenario:") + print("• Starting position: 50km away (undetectable)") + print("• Approach pattern: Straight line to target") + print("• Detection threshold: ~25km range") + print("• Critical alerts: <5km from target") + print("• End position: Directly overhead (0m)") + print("=" * 70) + + # Fetch devices + devices = fetch_devices() + if not devices: + print("āŒ No devices found!") + return + + # Use the first device as target + target_device = devices[0] + print(f"šŸŽÆ Target Device: {target_device['name']}") + print(f"šŸ“ Target Location: {target_device['geo_lat']:.6f}, {target_device['geo_lon']:.6f}") + + # Calculate starting position 50km away (due north for simplicity) + start_distance = 50.0 # km + # Move 50km north of target + start_lat = target_device['geo_lat'] + (start_distance / 111.0) # ~111km per degree latitude + start_lon = target_device['geo_lon'] # Same longitude + + print(f"šŸ›« Orlan Starting Position: {start_lat:.6f}, {start_lon:.6f}") + print(f"šŸ“ Initial Distance: {start_distance:.1f}km") + + # Verify starting position is undetectable + if is_detectable(start_distance): + print("āš ļø WARNING: Starting position is within detection range!") + else: + print("āœ… Starting position confirmed undetectable") + + print("\n" + "=" * 70) + print("STARTING ORLAN APPROACH SIMULATION") + print("=" * 70) + + # Simulation parameters + total_steps = 50 # More steps for gradual approach + final_distance = 0.0 # Directly overhead + + detection_started = False + critical_alerts_started = False + + for step in range(1, total_steps + 1): + # Calculate current distance using exponential approach for realistic acceleration + progress = step / total_steps + + # Use exponential curve for realistic approach - slower at distance, faster when close + distance_km = start_distance * (1 - progress) ** 1.8 + final_distance * progress ** 1.8 + + # Calculate current position + current_lat, current_lon = calculate_position_along_path( + start_lat, start_lon, + target_device['geo_lat'], target_device['geo_lon'], + progress + ) + + # Check detection status + detectable = is_detectable(distance_km) + + # Send detection only if within detectable range + if detectable: + if not detection_started: + print(f"\nšŸ” FIRST DETECTION at {distance_km:.1f}km - Orlan has entered detection range!") + detection_started = True + + success = send_detection(target_device, current_lat, current_lon, distance_km, step, total_steps) + + if not success: + print(f"āŒ Failed to send detection at step {step}") + continue + + # Show escalation messages + if distance_km <= 5 and not critical_alerts_started: + print(f"🚨 CRITICAL ALERT THRESHOLD REACHED at {distance_km:.1f}km!") + critical_alerts_started = True + elif distance_km <= 1: + print(f"šŸ”„ IMMEDIATE THREAT: Orlan within {distance_km:.1f}km!") + elif distance_km <= 0.1: + print(f"šŸ’„ DIRECTLY OVERHEAD: Orlan at {distance_km*1000:.0f}m altitude!") + else: + # Outside detection range + print(f"šŸ“” Step {step}/{total_steps}: Distance={distance_km:.1f}km (undetectable, RSSI={rssi_from_distance(distance_km):.0f}dBm)") + + # Variable delay based on distance + if distance_km > 30: + delay = 2.0 # 2 seconds for very long range + elif distance_km > 15: + delay = 1.5 # 1.5 seconds for long range + elif distance_km > 5: + delay = 1.0 # 1 second for medium range + else: + delay = 0.8 # Faster updates for critical proximity + + time.sleep(delay) + + print("\n" + "=" * 70) + print("🚨 ORLAN DETECTION TEST COMPLETED") + print("=" * 70) + print("Test Summary:") + print(f"• Starting distance: {start_distance:.1f}km (undetectable)") + print(f"• Detection range entered: ~{MAX_DETECTION_RANGE_KM:.1f}km") + print(f"• Critical alerts triggered: <5km") + print(f"• Final position: Directly overhead") + print(f"• Target device: {target_device['name']}") + print(f"• Total simulation steps: {total_steps}") + print("") + print("Expected Results:") + print("āœ… No detections sent while >25km away") + print("āœ… First detection when entering ~25km range") + print("āœ… Critical alerts triggered for Orlan type (drone_type=1)") + print("āœ… All alerts escalated regardless of distance/RSSI") + print("āœ… Real-time tracking visible on dashboard") + print("=" * 70) + +if __name__ == "__main__": + try: + run_orlan_detection_test() + except KeyboardInterrupt: + print("\n\nāš ļø Orlan detection test interrupted by user") + except Exception as e: + print(f"\nāŒ Error during Orlan detection test: {e}")