aboutsummaryrefslogtreecommitdiffstats
path: root/etisnoop-stat-server/server.py
diff options
context:
space:
mode:
Diffstat (limited to 'etisnoop-stat-server/server.py')
-rwxr-xr-xetisnoop-stat-server/server.py118
1 files changed, 118 insertions, 0 deletions
diff --git a/etisnoop-stat-server/server.py b/etisnoop-stat-server/server.py
new file mode 100755
index 0000000..399f31e
--- /dev/null
+++ b/etisnoop-stat-server/server.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# This is the main program that
+# - Runs rtlsdr and etisnoop for 200 ETI frames
+# and generate the stats.yml
+# - Runs a webserver
+#
+# Copyright (C) 2017
+# Matthias P. Braendli, matthias.braendli@mpb.li
+# http://www.opendigitalradio.org
+# Licence: The MIT License, see LICENCE file
+
+import sys
+from bottle import route, run, template, static_file, request
+import subprocess
+import time
+import datetime
+import multiprocessing as mp
+import threading
+import shlex
+import argparse
+import collections
+
+class StatCollector(threading.Thread):
+ def __init__(self, options):
+ threading.Thread.__init__(self)
+
+ self.num_eti_frames = int(options.num_eti_frames)
+ self.gain = int(options.gain)
+ self.freq = int(options.freq)
+ self.event_stop = threading.Event()
+
+ self.dab2eti_proc = None
+
+ self.stats_lock = threading.Lock()
+ self.stats = None
+
+ def run(self):
+ if self.gain == 0:
+ gain = ""
+ else:
+ gain = self.gain
+ dab2eti_cmdline = "dab2eti {} {} | etisnoop -s stats.yml -n {}".format(
+ self.freq, gain, self.num_eti_frames)
+
+ print("Cmdline: " + repr(dab2eti_cmdline))
+
+ while not self.event_stop.is_set():
+ print("Entering capture loop, start RX")
+ self.dab2eti_proc = subprocess.Popen(dab2eti_cmdline, shell=True)
+ ret = self.dab2eti_proc.wait()
+ print("Quit with return value {}".format(ret))
+
+ self.stats_lock.acquire()
+ try:
+ self.stats = open("stats.yml").read()
+ print("Stats loaded, {} chars".format(len(self.stats)))
+ except Exception as e:
+ self.stats = "exception: {}".format(e)
+ finally:
+ self.stats_lock.release()
+ time.sleep(15)
+
+ def stop(self):
+ print("Set stop event")
+ self.event_stop.set()
+ self.join()
+
+ def getstats(self):
+ """Return a str YAML if stats are available, or None"""
+ self.stats_lock.acquire()
+ stats = self.stats
+ self.stats_lock.release()
+ return stats
+
+
+@route('/')
+def index():
+ stats = stat_collector.getstats()
+
+ if stats is None:
+ stats = "status: not ready"
+
+ return template('index',
+ freq = cli_args.freq,
+ gain = cli_args.gain,
+ stats = stats)
+
+@route('/static/<filename:path>')
+def send_static(filename):
+ return static_file(filename, root='./static')
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(description='ETISnoop statistics')
+
+ # Options for the webserver
+ parser.add_argument('--host', default='127.0.0.1', help='socket host (default: 127.0.0.1)',required=False)
+ parser.add_argument('--port', default='8000', help='socket port (default: 8000)',required=False)
+
+ # Options for RTLSDR reception
+ parser.add_argument('--freq', help='Receive frequency', required=True)
+ parser.add_argument('--num-eti-frames',
+ default=200,
+ help='Number of ETI frames to analyse.',
+ required=False)
+ parser.add_argument('--gain', default=0,
+ help='Gain setting for rtl_sdr, 0 for auto', required=False)
+
+ cli_args = parser.parse_args()
+
+ stat_collector = StatCollector(cli_args)
+ stat_collector.start()
+
+ try:
+ run(host=cli_args.host, port=int(cli_args.port), debug=True, reloader=False)
+ finally:
+ stat_collector.stop()