diff --git a/client/src/pages/Devices.jsx b/client/src/pages/Devices.jsx index 2fa07da..2e903c0 100644 --- a/client/src/pages/Devices.jsx +++ b/client/src/pages/Devices.jsx @@ -566,9 +566,11 @@ const DeviceModal = ({ device, onClose, onSave }) => { try { if (device) { - // Update existing device - exclude read-only fields and filter out empty strings + // Update existing device - include coordinates and other editable fields const updateData = { name: formData.name, + geo_lat: formData.geo_lat ? parseFloat(formData.geo_lat) : null, + geo_lon: formData.geo_lon ? parseFloat(formData.geo_lon) : null, location_description: formData.location_description || null, notes: formData.notes || null }; diff --git a/debug_device_status.py b/debug_device_status.py index c5f4c62..9ed142d 100644 --- a/debug_device_status.py +++ b/debug_device_status.py @@ -100,8 +100,14 @@ def debug_device_status(): print(f" Active: {stockholm_device.get('is_active', False)}") print(f" Approved: {stockholm_device.get('is_approved', False)}") print(f" Coordinates: {stockholm_device.get('geo_lat', 'N/A')}, {stockholm_device.get('geo_lon', 'N/A')}") + print(f" Location: {stockholm_device.get('location_description', 'N/A')}") print(f" Last Heartbeat: {stockholm_device.get('last_heartbeat', 'Never')}") print(f" Heartbeat Interval: {stockholm_device.get('heartbeat_interval', 'Not set')} seconds") + print(f" Firmware Version: {stockholm_device.get('firmware_version', 'N/A')}") + print(f" Installation Date: {stockholm_device.get('installation_date', 'N/A')}") + print(f" Notes: {stockholm_device.get('notes', 'N/A')}") + print(f" Created: {stockholm_device.get('created_at', 'N/A')}") + print(f" Updated: {stockholm_device.get('updated_at', 'N/A')}") # Calculate status manually if stockholm_device.get('last_heartbeat'): @@ -133,7 +139,9 @@ def debug_device_status(): print("Available devices:") for device in devices: coords = f"({device.get('geo_lat', 'N/A')}, {device.get('geo_lon', 'N/A')})" - print(f" - ID {device['id']}: {device.get('name', 'Unnamed')} at {coords}") + status = "✅ Active" if device.get('is_active') else "❌ Inactive" + approved = "✅ Approved" if device.get('is_approved') else "⚠️ Pending" + print(f" - ID {device['id']}: {device.get('name', 'Unnamed')} at {coords} | {status} | {approved}") else: print(f"❌ No devices found") else: diff --git a/register_devices.py b/register_devices.py new file mode 100644 index 0000000..3838669 --- /dev/null +++ b/register_devices.py @@ -0,0 +1,197 @@ +#!/usr/bin/env python3 +""" +Device Registration Script +Pre-registers drone detection devices with proper names and locations +""" + +import requests +import json +import os +from datetime import datetime + +# Configuration +API_BASE_URL = os.getenv('API_BASE_URL', 'http://localhost:3002/api') +USERNAME = os.getenv('TEST_USERNAME', 'admin') +PASSWORD = os.getenv('TEST_PASSWORD', 'admin123') + +# Device locations matching drone_simulator.py +DEVICE_REGISTRATIONS = [ + { + "id": 1941875381, + "name": "SecureGuard-001", + "geo_lat": 59.3293, + "geo_lon": 18.0686, + "location_description": "Stockholm Central Station", + "category": "transportation_hubs" + }, + { + "id": 1941875382, + "name": "SecureGuard-002", + "geo_lat": 59.6519, + "geo_lon": 17.9186, + "location_description": "Arlanda Airport", + "category": "airports" + }, + { + "id": 1941875383, + "name": "SecureGuard-003", + "geo_lat": 58.5342, + "geo_lon": 14.5219, + "location_description": "Karlsborg Fortress", + "category": "military_bases" + }, + { + "id": 1941875384, + "name": "SecureGuard-004", + "geo_lat": 59.3267, + "geo_lon": 18.0717, + "location_description": "Swedish Parliament", + "category": "government" + }, + { + "id": 1941875385, + "name": "SecureGuard-005", + "geo_lat": 57.6628, + "geo_lon": 12.2944, + "location_description": "Landvetter Airport", + "category": "airports" + } +] + +def authenticate(): + """Authenticate with the API and get access token""" + try: + login_data = { + "username": USERNAME, + "password": PASSWORD + } + + response = requests.post(f"{API_BASE_URL}/users/login", json=login_data, timeout=10) + + if response.status_code == 200: + data = response.json() + if data.get('success') and 'data' in data and 'token' in data['data']: + token = data['data']['token'] + print("✅ Authentication successful") + return token + else: + print("❌ Login failed: Invalid response format") + return None + else: + print(f"❌ Login failed: HTTP {response.status_code}") + print(f" Response: {response.text}") + return None + + except Exception as e: + print(f"❌ Authentication error: {e}") + return None + +def register_device(token, device_data): + """Register a single device""" + try: + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {token}" + } + + # Check if device already exists + response = requests.get(f"{API_BASE_URL}/devices/{device_data['id']}", headers=headers, timeout=10) + + if response.status_code == 200: + # Device exists, update it + print(f"📝 Updating existing device {device_data['id']}: {device_data['name']}") + + update_data = { + "name": device_data["name"], + "geo_lat": device_data["geo_lat"], + "geo_lon": device_data["geo_lon"], + "location_description": device_data["location_description"], + "is_approved": True, + "is_active": True + } + + response = requests.put(f"{API_BASE_URL}/devices/{device_data['id']}", + json=update_data, headers=headers, timeout=10) + + if response.status_code == 200: + print(f"✅ Device {device_data['id']} updated successfully") + return True + else: + print(f"❌ Failed to update device {device_data['id']}: {response.status_code}") + print(f" Response: {response.text}") + return False + + elif response.status_code == 404: + # Device doesn't exist, create it + print(f"➕ Creating new device {device_data['id']}: {device_data['name']}") + + create_data = { + "id": device_data["id"], + "name": device_data["name"], + "geo_lat": device_data["geo_lat"], + "geo_lon": device_data["geo_lon"], + "location_description": device_data["location_description"], + "heartbeat_interval": 300, + "is_approved": True, + "is_active": True + } + + response = requests.post(f"{API_BASE_URL}/devices", + json=create_data, headers=headers, timeout=10) + + if response.status_code == 201: + print(f"✅ Device {device_data['id']} created successfully") + return True + else: + print(f"❌ Failed to create device {device_data['id']}: {response.status_code}") + print(f" Response: {response.text}") + return False + else: + print(f"❌ Error checking device {device_data['id']}: {response.status_code}") + return False + + except Exception as e: + print(f"❌ Error registering device {device_data['id']}: {e}") + return False + +def main(): + print("🔧 DRONE DETECTION DEVICE REGISTRATION") + print("=" * 50) + print(f"🔗 API URL: {API_BASE_URL}") + print(f"👤 Username: {USERNAME}") + print(f"⏰ Registration Time: {datetime.now()}") + print() + + # Authenticate + token = authenticate() + if not token: + print("❌ Failed to authenticate. Exiting.") + return + + print() + print("📋 Registering devices...") + print("-" * 30) + + success_count = 0 + total_count = len(DEVICE_REGISTRATIONS) + + for device_data in DEVICE_REGISTRATIONS: + if register_device(token, device_data): + success_count += 1 + + print() + print("📊 REGISTRATION SUMMARY") + print("-" * 30) + print(f"✅ Successfully registered: {success_count}/{total_count}") + print(f"❌ Failed: {total_count - success_count}/{total_count}") + + if success_count == total_count: + print() + print("🎉 All devices registered successfully!") + print("📍 You can now run drone_simulator.py and devices will appear on the map with proper names and locations.") + else: + print() + print("⚠️ Some devices failed to register. Check the errors above.") + +if __name__ == "__main__": + main()