From 5e86b40f380a628a117f69ac8767e65036c2d991 Mon Sep 17 00:00:00 2001 From: W1CDN Date: Thu, 13 Apr 2023 17:16:16 -0500 Subject: [PATCH 01/10] Stub out a KISS connection. It seems to simultaneously run the API and keep the KISS connection open in the background. --- api_app.py | 4 ++++ kiss_and_db.py | 39 +++++++++++++++++++++++++++++++++++++++ requirements.txt | 2 -- 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 kiss_and_db.py diff --git a/api_app.py b/api_app.py index 0b117ca..1eabbd1 100644 --- a/api_app.py +++ b/api_app.py @@ -53,6 +53,10 @@ log_folder = config['Settings']['log_folder'] # Load logs first (just to check for errors before page loads) data = read_logs(log_folder) +# Start subprocess to watch KISS connection +import subprocess +subprocess.Popen(["python3","kiss_and_db.py"]) + api.add_resource(Packets, '/packets') # and '/locations' is our entry point for Locations if __name__ == '__main__': diff --git a/kiss_and_db.py b/kiss_and_db.py new file mode 100644 index 0000000..fa2aa75 --- /dev/null +++ b/kiss_and_db.py @@ -0,0 +1,39 @@ +#!/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 + + +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") + + +def print_frame(frame): + print(Frame.from_bytes(frame)) + + +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 + + +if __name__ == "__main__": + main() diff --git a/requirements.txt b/requirements.txt index baf9fc7..8fc2f61 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,2 @@ flask flask_restful -pandas -numpy From b4bc632dedc51f6f74a261d98c7b2d52c534c13b Mon Sep 17 00:00:00 2001 From: W1CDN Date: Thu, 13 Apr 2023 20:46:28 -0500 Subject: [PATCH 02/10] Snapshot. --- db_test.py | 14 ++++++++++++++ init_db.py | 19 +++++++++++++++++++ kiss_and_db.py | 7 ++++++- schema.sql | 7 +++++++ tcp_send_recv.py | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 db_test.py create mode 100644 init_db.py create mode 100644 schema.sql create mode 100644 tcp_send_recv.py diff --git a/db_test.py b/db_test.py new file mode 100644 index 0000000..e098f01 --- /dev/null +++ b/db_test.py @@ -0,0 +1,14 @@ +import sqlite3 + +def get_db_connection(): + conn = sqlite3.connect('database.db') + conn.row_factory = sqlite3.Row + return conn + +frame1 = "W1CDN-1>APDW16,K0UND-2*:;147.390GF*111111z4755.45N/09700.58Wr147.390MHz +060 https://www.wa0jxt.org/" + +conn = get_db_connection() +conn.execute('INSERT INTO frames (frame) VALUES (?)', + (frame1,)) +conn.commit() +conn.close() diff --git a/init_db.py b/init_db.py new file mode 100644 index 0000000..cf2eaf7 --- /dev/null +++ b/init_db.py @@ -0,0 +1,19 @@ +import sqlite3 + +connection = sqlite3.connect('database.db') + +with open('schema.sql') as f: + connection.executescript(f.read()) + +cur = connection.cursor() + +# cur.execute("INSERT INTO posts (title, content) VALUES (?, ?)", +# ('First Post', 'Content for the first post') +# ) +# +# cur.execute("INSERT INTO posts (title, content) VALUES (?, ?)", +# ('Second Post', 'Content for the second post') +# ) + +connection.commit() +connection.close() diff --git a/kiss_and_db.py b/kiss_and_db.py index fa2aa75..5c596e8 100644 --- a/kiss_and_db.py +++ b/kiss_and_db.py @@ -33,7 +33,12 @@ def main(): 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() if __name__ == "__main__": main() diff --git a/schema.sql b/schema.sql new file mode 100644 index 0000000..e658834 --- /dev/null +++ b/schema.sql @@ -0,0 +1,7 @@ +DROP TABLE IF EXISTS frames; + +CREATE TABLE frames ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + frame TEXT NOT NULL +); diff --git a/tcp_send_recv.py b/tcp_send_recv.py new file mode 100644 index 0000000..bf09b0e --- /dev/null +++ b/tcp_send_recv.py @@ -0,0 +1,49 @@ + + + #!/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. +""" +import os +import sqlite3 +from ax253 import Frame +import kiss + + +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") + +def get_db_connection(): + conn = sqlite3.connect('database.db') + conn.row_factory = sqlite3.Row + return conn + +def print_frame(frame): + print(Frame.from_bytes(frame)) + a = str(Frame.from_bytes(frame)) + dir(frame) + return(a) + +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) + ki.read(callback=print_frame, min_frames=None) + + conn = get_db_connection() + print(ki.read(callback=print_frame, min_frames=None),) + #conn.execute('INSERT INTO frames (frame) VALUES (?)', + # ((,)) + conn.commit() + conn.close() + +if __name__ == "__main__": + main() From 4f83f76bf571ed3fdaddb665e9cb3a26f26021a6 Mon Sep 17 00:00:00 2001 From: W1CDN Date: Thu, 13 Apr 2023 21:11:01 -0500 Subject: [PATCH 03/10] Switch to aprs3 package. --- tcp_kiss_send_recv.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 tcp_kiss_send_recv.py diff --git a/tcp_kiss_send_recv.py b/tcp_kiss_send_recv.py new file mode 100644 index 0000000..4280f7a --- /dev/null +++ b/tcp_kiss_send_recv.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +import os +import sqlite3 +import aprs +import json + + +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") + +def get_db_connection(): + conn = sqlite3.connect('database.db') + conn.row_factory = sqlite3.Row + return conn + +def main(): + ki = aprs.TCPKISS(host=KISS_HOST, port=int(KISS_PORT)) + ki.start() + frame = aprs.APRSFrame.ui( + destination="APZ001", + source=MYCALL, + path=["WIDE1-1"], + info=b">Hello World!", + ) + ki.write(frame) + while True: + for frame in ki.read(min_frames=1): + print(repr(frame)) + a = str(frame) + print(a) + conn = get_db_connection() + conn.execute('INSERT INTO frames (frame) VALUES (?)', + (a,)) + conn.commit() + conn.close() + +if __name__ == "__main__": + main() From b06b87fe4e98638a1179651bb82811109cfea0c0 Mon Sep 17 00:00:00 2001 From: W1CDN Date: Thu, 13 Apr 2023 21:38:51 -0500 Subject: [PATCH 04/10] Barely parse a frame. --- tcp_kiss_send_recv.py | 9 ++++---- tcp_send_recv.py | 49 ------------------------------------------- 2 files changed, 5 insertions(+), 53 deletions(-) delete mode 100644 tcp_send_recv.py diff --git a/tcp_kiss_send_recv.py b/tcp_kiss_send_recv.py index 4280f7a..88522db 100644 --- a/tcp_kiss_send_recv.py +++ b/tcp_kiss_send_recv.py @@ -3,6 +3,7 @@ import os import sqlite3 import aprs import json +import aprslib MYCALL = os.environ.get("MYCALL", "W1CDN") @@ -26,12 +27,12 @@ def main(): ki.write(frame) while True: for frame in ki.read(min_frames=1): - print(repr(frame)) - a = str(frame) + #print(repr(frame)) + a = aprslib.parse(str(frame)) print(a) conn = get_db_connection() - conn.execute('INSERT INTO frames (frame) VALUES (?)', - (a,)) + # conn.execute('INSERT INTO frames (frame) VALUES (?)', + # (a,)) conn.commit() conn.close() diff --git a/tcp_send_recv.py b/tcp_send_recv.py deleted file mode 100644 index bf09b0e..0000000 --- a/tcp_send_recv.py +++ /dev/null @@ -1,49 +0,0 @@ - - - #!/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. -""" -import os -import sqlite3 -from ax253 import Frame -import kiss - - -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") - -def get_db_connection(): - conn = sqlite3.connect('database.db') - conn.row_factory = sqlite3.Row - return conn - -def print_frame(frame): - print(Frame.from_bytes(frame)) - a = str(Frame.from_bytes(frame)) - dir(frame) - return(a) - -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) - ki.read(callback=print_frame, min_frames=None) - - conn = get_db_connection() - print(ki.read(callback=print_frame, min_frames=None),) - #conn.execute('INSERT INTO frames (frame) VALUES (?)', - # ((,)) - conn.commit() - conn.close() - -if __name__ == "__main__": - main() From 63963c0ade8e0e4d2bb27bfacd80632c45d39bad Mon Sep 17 00:00:00 2001 From: W1CDN Date: Fri, 14 Apr 2023 22:06:48 -0500 Subject: [PATCH 05/10] Store frames in database, remove frames older than chosen age. --- config.ini | 3 ++ db_test.py | 14 -------- schema.sql | 38 +++++++++++++++++++- tcp_kiss_send_recv.py | 83 +++++++++++++++++++++++++++++++++++++++---- 4 files changed, 116 insertions(+), 22 deletions(-) delete mode 100644 db_test.py diff --git a/config.ini b/config.ini index 61ac29d..b4f65fe 100644 --- a/config.ini +++ b/config.ini @@ -7,3 +7,6 @@ log_folder = logs/ station_call = W1CDN-1 station_lat = 47.941500 station_lon = -97.027000 + +# How long to keep packets (frames) e.g., "2 days", "5 minutes" +keep_time = "2 days" diff --git a/db_test.py b/db_test.py deleted file mode 100644 index e098f01..0000000 --- a/db_test.py +++ /dev/null @@ -1,14 +0,0 @@ -import sqlite3 - -def get_db_connection(): - conn = sqlite3.connect('database.db') - conn.row_factory = sqlite3.Row - return conn - -frame1 = "W1CDN-1>APDW16,K0UND-2*:;147.390GF*111111z4755.45N/09700.58Wr147.390MHz +060 https://www.wa0jxt.org/" - -conn = get_db_connection() -conn.execute('INSERT INTO frames (frame) VALUES (?)', - (frame1,)) -conn.commit() -conn.close() diff --git a/schema.sql b/schema.sql index e658834..f9ee929 100644 --- a/schema.sql +++ b/schema.sql @@ -2,6 +2,42 @@ DROP TABLE IF EXISTS frames; CREATE TABLE frames ( id INTEGER PRIMARY KEY AUTOINCREMENT, + addresse TEXT, + alive INT, + altitude REAL, + comment TEXT, + course REAL, created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - frame TEXT NOT NULL + format TEXT, + frame TEXT, + "from" TEXT, + gpsfixstatus TEXT, + latitude REAL, + longitude REAL, + mbits INT, + messagecapable INT, + message_text TEXT, + mtype TEXT, + object_format TEXT, + object_name TEXT, + path TEXT, + posambiguity INT, + raw TEXT, + raw_timestamp TEXT, + speed REAL, + station_call TEXT, + station_lat REAL, + station_lon REAL, + status TEXT, + symbol TEXT, + symbol_table TEXT, + telemetry TEXT, + timestamp INT, + "to" TEXT, + tEQNS TEXT, + tPARM TEXT, + tUNIT TEXT, + via TEXT, + weather TEXT, + wx_raw_timestamp TIMESTAMP ); diff --git a/tcp_kiss_send_recv.py b/tcp_kiss_send_recv.py index 88522db..4e6fe5a 100644 --- a/tcp_kiss_send_recv.py +++ b/tcp_kiss_send_recv.py @@ -4,37 +4,106 @@ 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", +"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 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(): + + # 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) + #ki.write(frame) + + # Watch for new packets to come in while True: + conn = get_db_connection() for frame in ki.read(min_frames=1): - #print(repr(frame)) 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) - conn = get_db_connection() - # conn.execute('INSERT INTO frames (frame) VALUES (?)', - # (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() - conn.close() + + # 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() From 6e6693bfbc519db9526da34eae523a5ee77d1e30 Mon Sep 17 00:00:00 2001 From: W1CDN Date: Sat, 15 Apr 2023 13:27:00 -0500 Subject: [PATCH 06/10] Read from database for API. --- api_app.py | 30 +++++++++++- kiss_and_db.py | 124 +++++++++++++++++++++++++++++++++++++------------ schema.sql | 1 + 3 files changed, 124 insertions(+), 31 deletions(-) diff --git a/api_app.py b/api_app.py index 1eabbd1..338662b 100644 --- a/api_app.py +++ b/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 diff --git a/kiss_and_db.py b/kiss_and_db.py index 5c596e8..8a3aa63 100644 --- a/kiss_and_db.py +++ b/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() diff --git a/schema.sql b/schema.sql index f9ee929..d861dcf 100644 --- a/schema.sql +++ b/schema.sql @@ -21,6 +21,7 @@ CREATE TABLE frames ( object_format TEXT, object_name TEXT, path TEXT, + phg TEXT, posambiguity INT, raw TEXT, raw_timestamp TEXT, From 14effc97461d331ff112455f66fc23e4a1971826 Mon Sep 17 00:00:00 2001 From: W1CDN Date: Sat, 15 Apr 2023 14:20:07 -0500 Subject: [PATCH 07/10] Try to get working on production. --- kiss_and_db.py | 7 +++++-- requirements.txt | 2 ++ start-aprs_api.sh | 0 3 files changed, 7 insertions(+), 2 deletions(-) mode change 100644 => 100755 start-aprs_api.sh diff --git a/kiss_and_db.py b/kiss_and_db.py index 8a3aa63..c00cfcc 100644 --- a/kiss_and_db.py +++ b/kiss_and_db.py @@ -90,9 +90,12 @@ def main(): # 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_names = ', '.join(f'"{w}"' for w in a.keys()) + attrib_names = ', '.join('"%s"' % w for w in a.keys()) attrib_values = ", ".join("?" * len(a.keys())) - sql = f"INSERT INTO frames ({attrib_names}) VALUES ({attrib_values})" + #sql = f"INSERT INTO frames ({attrib_names}) VALUES ({attrib_values})" + sql = "INSERT INTO frames ("+attrib_names+") VALUES ("+attrib_values+")" + print(sql) # Insert data conn.execute(sql, list(a.values())) conn.commit() diff --git a/requirements.txt b/requirements.txt index 8fc2f61..85407aa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,4 @@ flask flask_restful +aprs +aprslib diff --git a/start-aprs_api.sh b/start-aprs_api.sh old mode 100644 new mode 100755 From 7453d5059874065326d8ae97968ae35930e353f1 Mon Sep 17 00:00:00 2001 From: W1CDN Date: Sat, 15 Apr 2023 16:37:31 -0500 Subject: [PATCH 08/10] Update waitress IP to make it work on production. --- api_waitress.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api_waitress.py b/api_waitress.py index 015c602..126faf7 100644 --- a/api_waitress.py +++ b/api_waitress.py @@ -9,4 +9,4 @@ os.chdir(this_files_dir) # `url_prefix` is optional, but useful if you are serving app on a sub-dir # behind a reverse-proxy. -serve(api_app, host='127.0.0.1', port=5001) +serve(api_app, host='0.0.0.0', port=5001) From ef5765e87f2e89e84a51bb9dab90ffd57c7cf022 Mon Sep 17 00:00:00 2001 From: W1CDN Date: Sun, 16 Apr 2023 10:04:48 -0500 Subject: [PATCH 09/10] Add missing fields and try to catch sqlite errors. --- kiss_and_db.py | 23 +++++++++++++++-------- schema.sql | 7 ++++++- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/kiss_and_db.py b/kiss_and_db.py index c00cfcc..b84d421 100644 --- a/kiss_and_db.py +++ b/kiss_and_db.py @@ -31,6 +31,11 @@ db_fields = ("id", "object_name", "path", "phg", +"phg_dir", +"phg_gain", +"phg_height", +"phg_power", +"phg_range", "posambiguity", "raw", "raw_timestamp", @@ -95,15 +100,17 @@ def main(): attrib_values = ", ".join("?" * len(a.keys())) #sql = f"INSERT INTO frames ({attrib_names}) VALUES ({attrib_values})" sql = "INSERT INTO frames ("+attrib_names+") VALUES ("+attrib_values+")" - print(sql) - # Insert data - conn.execute(sql, list(a.values())) - conn.commit() + try: + # 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() + # 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() + except: + print("Error with SQLite!") conn.close() diff --git a/schema.sql b/schema.sql index d861dcf..6027d4c 100644 --- a/schema.sql +++ b/schema.sql @@ -21,7 +21,12 @@ CREATE TABLE frames ( object_format TEXT, object_name TEXT, path TEXT, - phg TEXT, + phg REAL, + phg_dir TEXT, + phg_gain REAL, + phg_height REAL, + phg_power REAL, + phg_range REAL, posambiguity INT, raw TEXT, raw_timestamp TEXT, From 2ca627f973a970ee730d4e545914950f8e93a9a3 Mon Sep 17 00:00:00 2001 From: W1CDN Date: Sun, 16 Apr 2023 16:45:22 -0500 Subject: [PATCH 10/10] Add kiss stuff to config. --- config.ini | 7 +++++++ kiss_and_db.py | 23 ++++++++++++++--------- schema.sql | 1 + 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/config.ini b/config.ini index b4f65fe..647b245 100644 --- a/config.ini +++ b/config.ini @@ -10,3 +10,10 @@ station_lon = -97.027000 # How long to keep packets (frames) e.g., "2 days", "5 minutes" keep_time = "2 days" + +# KISS settings +kiss_host = 192.168.0.30 +kiss_port = 8001 + +# Development settings (not operational yet) +mycall = W1CDN-15 diff --git a/kiss_and_db.py b/kiss_and_db.py index b84d421..a8c7072 100644 --- a/kiss_and_db.py +++ b/kiss_and_db.py @@ -6,10 +6,6 @@ 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", @@ -44,6 +40,7 @@ db_fields = ("id", "station_lat", "station_lon", "status", +"subpacket", "symbol", "symbol_table", "telemetry", @@ -70,18 +67,22 @@ def main(): # Add the call and location of this station to the packet info config = read_config() + # 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") - ki = aprs.TCPKISS(host=KISS_HOST, port=int(KISS_PORT)) + + ki = aprs.TCPKISS(host=config['Settings']['kiss_host'], port=int(config['Settings']['kiss_port'])) ki.start() # Make a simple frame and send it frame = aprs.APRSFrame.ui( destination="APZ001", - source=MYCALL, + source=config['Settings']['mycall'], path=["WIDE1-1"], info=b">Hello World!", ) - #ki.write(frame) + ki.write(frame) # Watch for new packets to come in while True: @@ -94,11 +95,15 @@ def main(): print(a) # Make this a string and deal with it later (probably a mistake) a['path'] = str(a['path']) + # Store true/false as 1/0 + if 'alive' in a: + if a['alive'] == True: + a['alive'] = 1 + else: + a['alive'] = 0 # Build an INSERT statement based on the fields we have from the frame - #attrib_names = ', '.join(f'"{w}"' for w in a.keys()) attrib_names = ', '.join('"%s"' % w for w in a.keys()) attrib_values = ", ".join("?" * len(a.keys())) - #sql = f"INSERT INTO frames ({attrib_names}) VALUES ({attrib_values})" sql = "INSERT INTO frames ("+attrib_names+") VALUES ("+attrib_values+")" try: # Insert data diff --git a/schema.sql b/schema.sql index 6027d4c..91e5b43 100644 --- a/schema.sql +++ b/schema.sql @@ -35,6 +35,7 @@ CREATE TABLE frames ( station_lat REAL, station_lon REAL, status TEXT, + subpacket TEXT, symbol TEXT, symbol_table TEXT, telemetry TEXT,