#!/usr/bin/env python3 """ Add Stockholm Castle Device Script Creates a fake detection device positioned over Stockholm Castle for testing purposes. """ import requests import json import os from datetime import datetime # Disable SSL warnings for self-signed certificates import warnings warnings.filterwarnings('ignore', message='Unverified HTTPS request') # Configuration from environment variables # Tests default to localhost:3002 for local development API_BASE_URL = os.getenv('API_BASE_URL', 'http://localhost:3002/api') BASE_PATH = os.getenv('VITE_BASE_PATH', '').rstrip('/') # Authentication configuration - Optional for local testing USERNAME = os.getenv('TEST_USERNAME', 'admin') PASSWORD = os.getenv('TEST_PASSWORD', 'admin123') SKIP_AUTH = os.getenv('SKIP_AUTH', 'false').lower() == 'true' # Set to 'true' to skip authentication # If BASE_PATH is set, construct the full URL if BASE_PATH and not API_BASE_URL.endswith('/api'): # Extract domain from API_BASE_URL and add base path domain = API_BASE_URL.replace('/api', '').replace('/drones/api', '').replace('/uggla/api', '') API_BASE_URL = f"{domain}{BASE_PATH}/api" print(f"šŸ”— Using API Base URL: {API_BASE_URL}") if SKIP_AUTH: print("āš ļø AUTHENTICATION DISABLED - Running in local test mode") # Stockholm Castle coordinates STOCKHOLM_CASTLE_LAT = 59.326668 STOCKHOLM_CASTLE_LON = 18.071944 # Global variable to store authentication token AUTH_TOKEN = None def authenticate(): """Authenticate with the API and get access token""" global AUTH_TOKEN if SKIP_AUTH: return True login_data = { "username": USERNAME, "password": PASSWORD } try: print(f"šŸ” Authenticating as user: {USERNAME}") # Add tenant header for localhost requests headers = {"Content-Type": "application/json"} if "localhost" in API_BASE_URL: headers["x-tenant-id"] = "uamils-ab" print(f"šŸ¢ Using tenant: uamils-ab") response = requests.post(f"{API_BASE_URL}/users/login", json=login_data, headers=headers, verify=False) if response.status_code == 200: data = response.json() AUTH_TOKEN = data.get('data', {}).get('token') if AUTH_TOKEN: print("āœ… Authentication successful") return True else: print("āŒ No token received in response") print(f"Response data: {data}") return False else: print(f"āŒ Authentication failed: {response.status_code}") print(f"Response: {response.text}") return False except Exception as e: print(f"āŒ Authentication error: {e}") return False def get_auth_headers(): """Get headers with authentication token""" headers = {"Content-Type": "application/json"} # Add tenant header for localhost requests if "localhost" in API_BASE_URL: headers["x-tenant-id"] = "uamils-ab" if SKIP_AUTH: return headers if AUTH_TOKEN: headers["Authorization"] = f"Bearer {AUTH_TOKEN}" return headers def get_next_device_id(): """Get the next available device ID""" try: if SKIP_AUTH: # Try without authentication first for local testing response = requests.get(f"{API_BASE_URL}/devices/map", verify=False) else: response = requests.get(f"{API_BASE_URL}/devices", headers=get_auth_headers(), verify=False) if response.status_code == 200: data = response.json() devices = data.get('data', []) if devices: max_id = max(device['id'] for device in devices) return max_id + 1 else: return 1001 # Start with a high number for test devices else: print(f"āš ļø Could not fetch existing devices: {response.status_code}") return 1001 # Default starting ID except Exception as e: print(f"āš ļø Error fetching devices: {e}") return 1001 # Default starting ID def create_stockholm_device(): """Create a device positioned over Stockholm Castle""" # Use device_id=1 for Stockholm Castle as requested device_id = "1" # Device data for Stockholm Castle device_data = { "id": device_id, "name": f"Stockholm Castle Detector {device_id}", "geo_lat": STOCKHOLM_CASTLE_LAT, "geo_lon": STOCKHOLM_CASTLE_LON, "location_description": "Stockholm Castle (Stockholms slott), Sweden - Royal Palace detector for airspace monitoring", "heartbeat_interval": 300, # 5 minutes "firmware_version": "1.0.0-test", "installation_date": datetime.now().isoformat(), "notes": "Test device for Stockholm Castle airspace monitoring - Created by add_stockholm_device.py script" } try: print("šŸ° Creating Stockholm Castle detector device...") print(f"šŸ“ Location: {STOCKHOLM_CASTLE_LAT:.6f}, {STOCKHOLM_CASTLE_LON:.6f}") print(f"šŸ†” Device ID: {device_id}") response = requests.post(f"{API_BASE_URL}/devices", json=device_data, headers=get_auth_headers(), verify=False) if response.status_code == 201: created_device = response.json() print("āœ… Stockholm Castle device created successfully!") print(f"šŸ“± Device Name: {device_data['name']}") print(f"šŸ“ Coordinates: {STOCKHOLM_CASTLE_LAT:.6f}, {STOCKHOLM_CASTLE_LON:.6f}") print(f"šŸ° Location: Stockholm Castle, Sweden") print(f"šŸ†” Device ID: {device_id}") print("\nšŸŽÆ Device is ready for drone detection testing!") return created_device else: print(f"āŒ Failed to create device: {response.status_code}") print(f"Response: {response.text}") return None except Exception as e: print(f"āŒ Error creating device: {e}") return None def approve_device_if_needed(device_id): """Approve the device if the approval system is enabled""" try: approval_data = {"approved": True} response = requests.post(f"{API_BASE_URL}/devices/{device_id}/approve", json=approval_data, headers=get_auth_headers(), verify=False) if response.status_code == 200: print(f"āœ… Device {device_id} approved successfully") return True else: print(f"āš ļø Device approval response: {response.status_code}") # This might fail if approval isn't required, which is fine return True except Exception as e: print(f"āš ļø Device approval error (might not be required): {e}") return True def main(): """Main function to create Stockholm Castle device""" print("=" * 70) print("šŸ° STOCKHOLM CASTLE DEVICE CREATOR") print("=" * 70) print("Creating a test detector device positioned over Stockholm Castle") print("This device can be used for drone detection testing and simulation") print("=" * 70) # Authenticate first (unless skipped) if not SKIP_AUTH and not authenticate(): print("āŒ Authentication failed. Cannot proceed.") print("Please check:") print("1. Is the server running?") print("2. Are the credentials correct?") print(f" Username: {USERNAME}") print("3. Set TEST_USERNAME and TEST_PASSWORD environment variables if needed") print("4. Or set SKIP_AUTH=true to skip authentication for local testing") return # Create the device device = create_stockholm_device() if device: device_id = device.get('data', {}).get('id') or device.get('id') if device_id: # Try to approve the device if approval system is enabled approve_device_if_needed(device_id) print("\n" + "=" * 70) print("āœ… STOCKHOLM CASTLE DEVICE CREATED SUCCESSFULLY") print("=" * 70) print("Usage instructions:") print("1. The device is now available in your dashboard") print("2. You can use this device ID in test scripts") print("3. Run drone detection tests targeting Stockholm Castle area") print("4. Monitor the device status and detections on the map view") print("\nDevice Details:") print(f"šŸ†” Device ID: {device_id}") print(f"šŸ“ Latitude: {STOCKHOLM_CASTLE_LAT:.6f}") print(f"šŸ“ Longitude: {STOCKHOLM_CASTLE_LON:.6f}") print(f"šŸ° Location: Stockholm Castle, Sweden") print("=" * 70) else: print("\nāŒ Failed to create Stockholm Castle device") print("Please check the error messages above and try again") if __name__ == "__main__": try: main() except KeyboardInterrupt: print("\n\nāš ļø Stockholm Castle device creation interrupted by user") except Exception as e: print(f"\nāŒ Error during device creation: {e}")