mirror of
https://github.com/30hours/3lips.git
synced 2024-11-28 13:07:36 +00:00
Lots of skeleton and TCP sockets between event/api
This commit is contained in:
parent
22e51a94e7
commit
61914d0282
7 changed files with 322 additions and 5 deletions
23
api/main.py
23
api/main.py
|
@ -2,10 +2,20 @@
|
||||||
|
|
||||||
from flask import Flask, Response, render_template, request, redirect, jsonify, send_from_directory
|
from flask import Flask, Response, render_template, request, redirect, jsonify, send_from_directory
|
||||||
import os
|
import os
|
||||||
|
import sqlite3
|
||||||
import requests
|
import requests
|
||||||
|
import time
|
||||||
|
import socket
|
||||||
|
|
||||||
|
from util.Sqlite import Sqlite
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
# init db
|
||||||
|
# sqlite = Sqlite('./db/3lips.db')
|
||||||
|
# schema = "api TEXT PRIMARY KEY, timestamp INTEGER NOT NULL"
|
||||||
|
# sqlite.create_table("data", schema)
|
||||||
|
|
||||||
# store state data
|
# store state data
|
||||||
servers = [
|
servers = [
|
||||||
{"name": "radar4", "url": "radar4.30hours.dev"},
|
{"name": "radar4", "url": "radar4.30hours.dev"},
|
||||||
|
@ -44,6 +54,11 @@ def serve_static(file):
|
||||||
|
|
||||||
@app.route("/api")
|
@app.route("/api")
|
||||||
def api():
|
def api():
|
||||||
|
api = request.query_string.decode('utf-8')
|
||||||
|
# timestamp = time.time()*1000
|
||||||
|
# sqlite.add_entry("data", api, timestamp)
|
||||||
|
send_data_to_event(api)
|
||||||
|
|
||||||
urls = request.args.getlist("url")
|
urls = request.args.getlist("url")
|
||||||
data = [{"url": 'http://' + url} for url in urls]
|
data = [{"url": 'http://' + url} for url in urls]
|
||||||
return jsonify(data)
|
return jsonify(data)
|
||||||
|
@ -54,7 +69,7 @@ def serve_map(file):
|
||||||
public_folder = os.path.join(base_dir, 'map')
|
public_folder = os.path.join(base_dir, 'map')
|
||||||
return send_from_directory(public_folder, file)
|
return send_from_directory(public_folder, file)
|
||||||
|
|
||||||
# Handle /cesium/ specifically
|
# handle /cesium/ specifically
|
||||||
@app.route('/cesium/')
|
@app.route('/cesium/')
|
||||||
def serve_cesium_index():
|
def serve_cesium_index():
|
||||||
return redirect('/cesium/index.html')
|
return redirect('/cesium/index.html')
|
||||||
|
@ -71,5 +86,11 @@ def serve_cesium_content(file):
|
||||||
print(f"Error fetching content from Apache server: {e}")
|
print(f"Error fetching content from Apache server: {e}")
|
||||||
return Response('Error fetching content from Apache server', status=500, content_type='text/plain')
|
return Response('Error fetching content from Apache server', status=500, content_type='text/plain')
|
||||||
|
|
||||||
|
def send_data_to_event(data):
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
|
# Use the service name 'event' as specified in your Docker Compose file
|
||||||
|
s.connect(('event', 12345))
|
||||||
|
s.sendall(data.encode())
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app.run(debug=True)
|
app.run(debug=True)
|
||||||
|
|
70
api/util/Sqlite.py
Normal file
70
api/util/Sqlite.py
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
"""
|
||||||
|
@file Sqlite.py
|
||||||
|
@author 30hours
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
class Sqlite:
|
||||||
|
|
||||||
|
"""
|
||||||
|
@class Sqlite
|
||||||
|
@brief A class for interacting with an SQLite database.
|
||||||
|
@see https://sqlite.org/ for more information on SQLite.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, database_path):
|
||||||
|
|
||||||
|
"""
|
||||||
|
@brief Constructor for the Sqlite class.
|
||||||
|
@param database_path (str): Path to the SQLite database.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.connection = sqlite3.connect(database_path)
|
||||||
|
self.cursor = self.connection.cursor()
|
||||||
|
|
||||||
|
def table_exists(self, table_name):
|
||||||
|
|
||||||
|
"""
|
||||||
|
@brief Check if a table if the given name exists in the database.
|
||||||
|
@param table_name (str): Name of the table.
|
||||||
|
@return bool: True if the table exists.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.cursor.execute(f"SELECT name FROM sqlite_master WHERE type='table' AND name='{table_name}'")
|
||||||
|
return self.cursor.fetchone() is not None
|
||||||
|
|
||||||
|
def execute_query(self, query, parameters=None):
|
||||||
|
|
||||||
|
"""
|
||||||
|
@brief Execute an SQL query on the database.
|
||||||
|
@param query (str): SQL query to execute.
|
||||||
|
@param parameters (tuple, optional): Parameters to bind to the query.
|
||||||
|
@return None
|
||||||
|
"""
|
||||||
|
|
||||||
|
if parameters:
|
||||||
|
self.cursor.execute(query, parameters)
|
||||||
|
else:
|
||||||
|
self.cursor.execute(query)
|
||||||
|
self.connection.commit()
|
||||||
|
|
||||||
|
def fetch_all_rows(self, query):
|
||||||
|
|
||||||
|
"""
|
||||||
|
@brief Fetch all rows resulting from an SQL query.
|
||||||
|
@param query (str): SQL query to execute.
|
||||||
|
@return list: List of tuples representing the result rows.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.cursor.execute(query)
|
||||||
|
return self.cursor.fetchall()
|
||||||
|
|
||||||
|
def close_connection(self):
|
||||||
|
|
||||||
|
"""
|
||||||
|
@brief Close the SQLite database connection.
|
||||||
|
@return None
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.connection.close()
|
40
event/algorithm/associator/AdsbAssociator.py
Normal file
40
event/algorithm/associator/AdsbAssociator.py
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
"""
|
||||||
|
@file AdsbAssociator.py
|
||||||
|
@author 30hours
|
||||||
|
"""
|
||||||
|
|
||||||
|
class AdsbAssociator:
|
||||||
|
|
||||||
|
"""
|
||||||
|
@class AdsbAssociator
|
||||||
|
@brief A class for associating a detection with ADS-B truth.
|
||||||
|
@details Uses radar detection data from a blah2 server.
|
||||||
|
@see blah2 at https://github.com/30hours/blah2.
|
||||||
|
Uses truth data in delay-Doppler space from an adsb2dd server.
|
||||||
|
@see adsb2dd at https://github.com/30hours/adsb2dd.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
"""
|
||||||
|
@brief Constructor for the AdsbAssociator class.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def process(self, assoc_detections_list):
|
||||||
|
|
||||||
|
"""
|
||||||
|
@brief Associate detections from 2+ radars.
|
||||||
|
@param assoc_detections_list (list): List of JSON associated detections.
|
||||||
|
@return str: JSON of associated detections.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def process_1_radar(self, radar_detections, adsb_detections):
|
||||||
|
|
||||||
|
"""
|
||||||
|
@brief Associate detections between 1 radar/truth pair.
|
||||||
|
@param radar_detections (str): JSON of blah2 radar detections.
|
||||||
|
@param adsb_detections (str): JSON of adsb2dd truth detections.
|
||||||
|
@return str: JSON of associated detections.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
32
event/algorithm/coordreg/EllipseParametric.py
Normal file
32
event/algorithm/coordreg/EllipseParametric.py
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
"""
|
||||||
|
@file EllipseParametric.py
|
||||||
|
@author 30hours
|
||||||
|
"""
|
||||||
|
|
||||||
|
class EllipseParametric:
|
||||||
|
|
||||||
|
"""
|
||||||
|
@class EllipseParametric
|
||||||
|
@brief A class for intersecting ellipses using a parametric approx.
|
||||||
|
@details Uses associated detections from multiple radars.
|
||||||
|
@see blah2 at https://github.com/30hours/blah2.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
"""
|
||||||
|
@brief Constructor for the EllipseParametric class.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def process(self, assoc_detections):
|
||||||
|
|
||||||
|
"""
|
||||||
|
@brief Perform coord registration using the ellipse parametric method.
|
||||||
|
@details Generate a (non arc-length) parametric ellipse for each node.
|
||||||
|
Find
|
||||||
|
@param radar_detections (str): JSON of blah2 radar detections.
|
||||||
|
@param adsb_detections (str): JSON of adsb2dd truth detections.
|
||||||
|
@return str: JSON of associated detections.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,74 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import sqlite3
|
||||||
|
import requests
|
||||||
|
import threading
|
||||||
|
import socket
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
print('testtttttt', flush=True)
|
from algorithm.associator.AdsbAssociator import AdsbAssociator
|
||||||
|
from algorithm.coordreg.EllipseParametric import EllipseParametric
|
||||||
|
from util.Sqlite import Sqlite
|
||||||
|
|
||||||
|
# init db
|
||||||
|
sqlite = Sqlite('./db/3lips.db')
|
||||||
|
|
||||||
|
# init event loop
|
||||||
|
api = []
|
||||||
|
api_update = []
|
||||||
|
|
||||||
async def event():
|
async def event():
|
||||||
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
print("Event triggered at: " + timestamp, flush=True)
|
print("Event triggered at: " + timestamp, flush=True)
|
||||||
|
|
||||||
# Create and run the event loop
|
# main event loop
|
||||||
|
#for api_x in api:
|
||||||
|
|
||||||
|
# request data from API
|
||||||
|
# response = requests.get(data_i["url_radar_detections"])
|
||||||
|
# data_i["radar_detections"] =
|
||||||
|
|
||||||
|
# API management
|
||||||
|
#if sqlite.table_exists('data'):
|
||||||
|
|
||||||
|
# add new API requests
|
||||||
|
# rows = sqlite.fetch_all_rows("SELECT * FROM data")
|
||||||
|
# for row in rows:
|
||||||
|
# print(row)
|
||||||
|
|
||||||
|
# delete old API requests
|
||||||
|
|
||||||
|
# update output data on db
|
||||||
|
|
||||||
|
# event loop
|
||||||
async def main():
|
async def main():
|
||||||
# Run the event loop
|
|
||||||
while True:
|
while True:
|
||||||
await event()
|
await event()
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
|
api = api_update
|
||||||
|
|
||||||
|
def start_event_listener():
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
|
||||||
|
server_socket.bind(('event', 12345))
|
||||||
|
server_socket.listen()
|
||||||
|
|
||||||
|
print("Event listener is waiting for connections...")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
conn, addr = server_socket.accept()
|
||||||
|
thread = threading.Thread(target=handle_client, args=(conn, addr))
|
||||||
|
thread.start()
|
||||||
|
|
||||||
|
def handle_client(conn, addr):
|
||||||
|
with conn:
|
||||||
|
print(f"Connected by {addr}")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
data = conn.recv(1024)
|
||||||
|
if not data:
|
||||||
|
break
|
||||||
|
print(f"Received data: {data.decode()}")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
threading.Thread(target=start_event_listener).start()
|
||||||
asyncio.run(main())
|
asyncio.run(main())
|
|
@ -1 +1,2 @@
|
||||||
numpy==1.26.4
|
numpy==1.26.4
|
||||||
|
requests==2.31.0
|
97
event/util/Sqlite.py
Normal file
97
event/util/Sqlite.py
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
"""
|
||||||
|
@file Sqlite.py
|
||||||
|
@author 30hours
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
class Sqlite:
|
||||||
|
|
||||||
|
"""
|
||||||
|
@class Sqlite
|
||||||
|
@brief A class for interacting with an SQLite database.
|
||||||
|
@see https://sqlite.org/ for more information on SQLite.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, database_path):
|
||||||
|
|
||||||
|
"""
|
||||||
|
@brief Constructor for the Sqlite class.
|
||||||
|
@param database_path (str): Path to the SQLite database.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.connection = sqlite3.connect(database_path)
|
||||||
|
self.cursor = self.connection.cursor()
|
||||||
|
|
||||||
|
def create_table(self, table_name, schema):
|
||||||
|
"""
|
||||||
|
@brief Create a table in the database if it doesn't exist.
|
||||||
|
@param table_name (str): Name of the table.
|
||||||
|
@param schema (str): Table schema definition.
|
||||||
|
@return None
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.cursor.execute(f"CREATE TABLE IF NOT EXISTS {table_name} ({schema});")
|
||||||
|
self.connection.commit()
|
||||||
|
|
||||||
|
def table_exists(self, table_name):
|
||||||
|
|
||||||
|
"""
|
||||||
|
@brief Check if a table if the given name exists in the database.
|
||||||
|
@param table_name (str): Name of the table.
|
||||||
|
@return bool: True if the table exists.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.cursor.execute(f"SELECT name FROM sqlite_master WHERE type='table' AND name='{table_name}'")
|
||||||
|
return self.cursor.fetchone() is not None
|
||||||
|
|
||||||
|
def add_entry(self, table_name, api, timestamp):
|
||||||
|
|
||||||
|
"""
|
||||||
|
@brief Add entry to table.
|
||||||
|
@param table_name (str): Name of the table.
|
||||||
|
@param api (str): API URL to add.
|
||||||
|
@param timestamp (Integer): Timestamp to add.
|
||||||
|
@return None
|
||||||
|
"""
|
||||||
|
|
||||||
|
connection = sqlite3.connect(self.db_name)
|
||||||
|
cursor = connection.cursor()
|
||||||
|
insert_entry_sql = "INSERT INTO {table_name} (api, timestamp) VALUES (?, ?);"
|
||||||
|
cursor.execute(insert_entry_sql, (api, timestamp))
|
||||||
|
connection.commit()
|
||||||
|
|
||||||
|
def execute_query(self, query, parameters=None):
|
||||||
|
|
||||||
|
"""
|
||||||
|
@brief Execute an SQL query on the database.
|
||||||
|
@param query (str): SQL query to execute.
|
||||||
|
@param parameters (tuple, optional): Parameters to bind to the query.
|
||||||
|
@return None
|
||||||
|
"""
|
||||||
|
|
||||||
|
if parameters:
|
||||||
|
self.cursor.execute(query, parameters)
|
||||||
|
else:
|
||||||
|
self.cursor.execute(query)
|
||||||
|
self.connection.commit()
|
||||||
|
|
||||||
|
def fetch_all_rows(self, query):
|
||||||
|
|
||||||
|
"""
|
||||||
|
@brief Fetch all rows resulting from an SQL query.
|
||||||
|
@param query (str): SQL query to execute.
|
||||||
|
@return list: List of tuples representing the result rows.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.cursor.execute(query)
|
||||||
|
return self.cursor.fetchall()
|
||||||
|
|
||||||
|
def close_connection(self):
|
||||||
|
|
||||||
|
"""
|
||||||
|
@brief Close the SQLite database connection.
|
||||||
|
@return None
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.connection.close()
|
Loading…
Reference in a new issue