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
|
||||
import os
|
||||
import sqlite3
|
||||
import requests
|
||||
import time
|
||||
import socket
|
||||
|
||||
from util.Sqlite import Sqlite
|
||||
|
||||
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
|
||||
servers = [
|
||||
{"name": "radar4", "url": "radar4.30hours.dev"},
|
||||
|
@ -44,6 +54,11 @@ def serve_static(file):
|
|||
|
||||
@app.route("/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")
|
||||
data = [{"url": 'http://' + url} for url in urls]
|
||||
return jsonify(data)
|
||||
|
@ -54,7 +69,7 @@ def serve_map(file):
|
|||
public_folder = os.path.join(base_dir, 'map')
|
||||
return send_from_directory(public_folder, file)
|
||||
|
||||
# Handle /cesium/ specifically
|
||||
# handle /cesium/ specifically
|
||||
@app.route('/cesium/')
|
||||
def serve_cesium_index():
|
||||
return redirect('/cesium/index.html')
|
||||
|
@ -71,5 +86,11 @@ def serve_cesium_content(file):
|
|||
print(f"Error fetching content from Apache server: {e}")
|
||||
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__":
|
||||
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 sqlite3
|
||||
import requests
|
||||
import threading
|
||||
import socket
|
||||
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():
|
||||
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
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():
|
||||
# Run the event loop
|
||||
|
||||
while True:
|
||||
await event()
|
||||
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__":
|
||||
threading.Thread(target=start_event_listener).start()
|
||||
asyncio.run(main())
|
|
@ -1 +1,2 @@
|
|||
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