Read from database for API.
This commit is contained in:
		
							
								
								
									
										30
									
								
								api_app.py
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								api_app.py
									
									
									
									
									
								
							@@ -6,6 +6,7 @@ import csv
 | 
			
		||||
import ast
 | 
			
		||||
import glob
 | 
			
		||||
import json
 | 
			
		||||
import sqlite3
 | 
			
		||||
api_app = Flask(__name__)
 | 
			
		||||
api = Api(api_app)
 | 
			
		||||
 | 
			
		||||
@@ -42,16 +43,41 @@ def read_logs(log_folder):
 | 
			
		||||
 | 
			
		||||
    return(json_array)
 | 
			
		||||
 | 
			
		||||
def dict_factory(cursor, row):
 | 
			
		||||
    d = {}
 | 
			
		||||
    for idx, col in enumerate(cursor.description):
 | 
			
		||||
        d[col[0]] = row[idx]
 | 
			
		||||
    return d
 | 
			
		||||
 | 
			
		||||
def get_db_connection():
 | 
			
		||||
    conn = sqlite3.connect('database.db')
 | 
			
		||||
    #conn.row_factory = sqlite3.Row
 | 
			
		||||
    conn.row_factory = dict_factory
 | 
			
		||||
    return conn
 | 
			
		||||
 | 
			
		||||
def select_all_frames(conn):
 | 
			
		||||
    """
 | 
			
		||||
    Query all rows in the frames table
 | 
			
		||||
    :param conn: the Connection object
 | 
			
		||||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
    cur = conn.cursor()
 | 
			
		||||
    cur.execute("SELECT * FROM frames")
 | 
			
		||||
    rows = cur.fetchall()
 | 
			
		||||
    return rows
 | 
			
		||||
 | 
			
		||||
class Packets(Resource):
 | 
			
		||||
    def get(self):
 | 
			
		||||
        data = read_logs(log_folder)
 | 
			
		||||
        #data = read_logs(log_folder)
 | 
			
		||||
        conn = get_db_connection()
 | 
			
		||||
        data = select_all_frames(conn)
 | 
			
		||||
        return {'data': data}, 200  # return data and 200 OK code
 | 
			
		||||
 | 
			
		||||
# Read config
 | 
			
		||||
config = read_config()
 | 
			
		||||
log_folder = config['Settings']['log_folder']
 | 
			
		||||
# Load logs first (just to check for errors before page loads)
 | 
			
		||||
data = read_logs(log_folder)
 | 
			
		||||
#data = read_logs(log_folder)
 | 
			
		||||
 | 
			
		||||
# Start subprocess to watch KISS connection
 | 
			
		||||
import subprocess
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										124
									
								
								kiss_and_db.py
									
									
									
									
									
								
							
							
						
						
									
										124
									
								
								kiss_and_db.py
									
									
									
									
									
								
							@@ -1,44 +1,110 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
"""
 | 
			
		||||
Send a test frame via TCP, then read & print KISS frames from a TCP Socket.
 | 
			
		||||
For use with programs like Dire Wolf.
 | 
			
		||||
From https://github.com/python-aprs/kiss3/blob/main/examples/tcp_send_recv.py
 | 
			
		||||
"""
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
from ax253 import Frame
 | 
			
		||||
import kiss
 | 
			
		||||
 | 
			
		||||
import sqlite3
 | 
			
		||||
import aprs
 | 
			
		||||
import json
 | 
			
		||||
import aprslib
 | 
			
		||||
import configparser
 | 
			
		||||
 | 
			
		||||
MYCALL = os.environ.get("MYCALL", "W1CDN")
 | 
			
		||||
KISS_HOST = os.environ.get("KISS_HOST", "192.168.0.30")
 | 
			
		||||
KISS_PORT = os.environ.get("KISS_PORT", "8001")
 | 
			
		||||
 | 
			
		||||
db_fields = ("id",
 | 
			
		||||
"addresse",
 | 
			
		||||
"alive",
 | 
			
		||||
"altitude",
 | 
			
		||||
"comment",
 | 
			
		||||
"course",
 | 
			
		||||
"created",
 | 
			
		||||
"format",
 | 
			
		||||
"frame",
 | 
			
		||||
"from",
 | 
			
		||||
"gpsfixstatus",
 | 
			
		||||
"latitude",
 | 
			
		||||
"longitude",
 | 
			
		||||
"mbits",
 | 
			
		||||
"messagecapable",
 | 
			
		||||
"message_text",
 | 
			
		||||
"mtype",
 | 
			
		||||
"object_format",
 | 
			
		||||
"object_name",
 | 
			
		||||
"path",
 | 
			
		||||
"phg",
 | 
			
		||||
"posambiguity",
 | 
			
		||||
"raw",
 | 
			
		||||
"raw_timestamp",
 | 
			
		||||
"speed",
 | 
			
		||||
"station_call",
 | 
			
		||||
"station_lat",
 | 
			
		||||
"station_lon",
 | 
			
		||||
"status",
 | 
			
		||||
"symbol",
 | 
			
		||||
"symbol_table",
 | 
			
		||||
"telemetry",
 | 
			
		||||
"timestamp",
 | 
			
		||||
"to",
 | 
			
		||||
"tEQNS",
 | 
			
		||||
"tPARM",
 | 
			
		||||
"tUNIT",
 | 
			
		||||
"via",
 | 
			
		||||
"weather",
 | 
			
		||||
"wx_raw_timestamp")
 | 
			
		||||
 | 
			
		||||
def print_frame(frame):
 | 
			
		||||
    print(Frame.from_bytes(frame))
 | 
			
		||||
def read_config():
 | 
			
		||||
    config = configparser.ConfigParser()
 | 
			
		||||
    config.read('config.ini')
 | 
			
		||||
    return config
 | 
			
		||||
 | 
			
		||||
def get_db_connection():
 | 
			
		||||
    conn = sqlite3.connect('database.db')
 | 
			
		||||
    conn.row_factory = sqlite3.Row
 | 
			
		||||
    return conn
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    ki = kiss.TCPKISS(host=KISS_HOST, port=int(KISS_PORT), strip_df_start=True)
 | 
			
		||||
    ki.start()
 | 
			
		||||
    # frame = Frame.ui(
 | 
			
		||||
    #     destination="PYKISS",
 | 
			
		||||
    #     source=MYCALL,
 | 
			
		||||
    #     path=["WIDE1-1"],
 | 
			
		||||
    #     info=">Hello World!",
 | 
			
		||||
    # )
 | 
			
		||||
    #ki.write(frame)
 | 
			
		||||
    # Write received frame to terminal
 | 
			
		||||
    ki.read(callback=print_frame, min_frames=None)
 | 
			
		||||
 | 
			
		||||
    # put some database stuff here
 | 
			
		||||
    print(Frame.from_bytes(frame))
 | 
			
		||||
    conn = get_db_connection()
 | 
			
		||||
    conn.execute('INSERT INTO frames (frame) VALUES (?)',
 | 
			
		||||
                 (Frame.from_bytes(frame)))
 | 
			
		||||
    conn.commit()
 | 
			
		||||
    conn.close()
 | 
			
		||||
    # Add the call and location of this station to the packet info
 | 
			
		||||
    config = read_config()
 | 
			
		||||
 | 
			
		||||
    ki = aprs.TCPKISS(host=KISS_HOST, port=int(KISS_PORT))
 | 
			
		||||
    ki.start()
 | 
			
		||||
 | 
			
		||||
    # Make a simple frame and send it
 | 
			
		||||
    frame = aprs.APRSFrame.ui(
 | 
			
		||||
        destination="APZ001",
 | 
			
		||||
        source=MYCALL,
 | 
			
		||||
        path=["WIDE1-1"],
 | 
			
		||||
        info=b">Hello World!",
 | 
			
		||||
    )
 | 
			
		||||
    #ki.write(frame)
 | 
			
		||||
 | 
			
		||||
    # Watch for new packets to come in
 | 
			
		||||
    while True:
 | 
			
		||||
        conn = get_db_connection()
 | 
			
		||||
        for frame in ki.read(min_frames=1):
 | 
			
		||||
            a = aprslib.parse(str(frame))
 | 
			
		||||
            a['station_call'] = config['Settings']['station_call']
 | 
			
		||||
            a['station_lat'] = config['Settings']['station_lat']
 | 
			
		||||
            a['station_lon'] = config['Settings']['station_lon']
 | 
			
		||||
            print(a)
 | 
			
		||||
            # Make this a string and deal with it later (probably a mistake)
 | 
			
		||||
            a['path'] = str(a['path'])
 | 
			
		||||
            # Build an INSERT statement based on the fields we have from the frame
 | 
			
		||||
            attrib_names = ', '.join(f'"{w}"' for w in a.keys())
 | 
			
		||||
            attrib_values = ", ".join("?" * len(a.keys()))
 | 
			
		||||
            sql = f"INSERT INTO frames ({attrib_names}) VALUES ({attrib_values})"
 | 
			
		||||
            # Insert data
 | 
			
		||||
            conn.execute(sql, list(a.values()))
 | 
			
		||||
            conn.commit()
 | 
			
		||||
 | 
			
		||||
            # TODO remove packets that are older ('created') than a limit set in config.ini
 | 
			
		||||
            # "5 minutes" also works
 | 
			
		||||
            conn.execute("DELETE FROM frames WHERE created < DATETIME('now', '"+config['Settings']['keep_time']+"')")
 | 
			
		||||
            conn.commit()
 | 
			
		||||
 | 
			
		||||
        conn.close()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    main()
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ CREATE TABLE frames (
 | 
			
		||||
    object_format TEXT,
 | 
			
		||||
    object_name TEXT,
 | 
			
		||||
    path TEXT,
 | 
			
		||||
    phg TEXT,
 | 
			
		||||
    posambiguity INT,
 | 
			
		||||
    raw TEXT,
 | 
			
		||||
    raw_timestamp TEXT,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user