From c331d140470cc67d012a116d16e3352698d50286 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Sat, 4 Apr 2015 21:47:09 +0200 Subject: [PATCH 1/7] added simple HTTP request if alarm send a HTTP request to an url you want --- README.md | 1 + boswatch.py | 30 ++++++++++++++++++++++++++---- config.ini | 19 ++++++++++++++----- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 813b208..71b4605 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Python Script to Recive and Decode German BOS Information with rtl_fm and multim - Filtering double alarms with adjustable time - FMS and ZVEI validation (plausibility test) - MySQL Database Support for FMS and ZVEI +- simple HTTP request at alarm to URL you want - All configurations in seperate File "config.ini" - simple Web Frontend with Data Parsing diff --git a/boswatch.py b/boswatch.py index 824d95a..464bc91 100644 --- a/boswatch.py +++ b/boswatch.py @@ -14,12 +14,12 @@ import subprocess #import os import mysql import mysql.connector +import httplib import argparse #for parse the args import ConfigParser #for parse the config file import re #Regex - def curtime(format="%Y-%m-%d %H:%M:%S"): return time.strftime(format) @@ -126,6 +126,12 @@ try: tableFMS = config.get("MySQL", "tableFMS") tableZVEI = config.get("MySQL", "tableZVEI") tablePOC = config.get("MySQL", "tablePOC") + + #HTTPrequest config + useHTTPrequest = int(config.get("Module", "useHTTPrequest")) #use HTTPrequest support? + if useHTTPrequest: #only if HTTPrequest is active + url = config.get("HTTPrequest", "url") + except: stop_script("config reading error") exit(0) @@ -212,10 +218,18 @@ try: fms_time_old = timestamp #save last time if useMySQL: #only if MySQL is active + if args.verbose: print "FMS to MySQL" cursor = connection.cursor() cursor.execute("INSERT INTO "+tableFMS+" (time,service,country,location,vehicle,status,direction,tsi) VALUES (%s,%s,%s,%s,%s,%s,%s,%s)",(curtime(),fms_service,fms_country,fms_location,fms_vehicle,fms_status,fms_direction,fms_tsi)) cursor.close() connection.commit() + + if useHTTPrequest: #only if HTTPrequest is active + httprequest = httplib.HTTPConnection(url) + httprequest.request("HEAD", "/") + httpresponse = httprequest.getresponse() + if args.verbose: print httpresponse.status, httpresponse.reason + elif args.verbose: #Invalid error only in verbose mode print "No valid FMS: "+fms_id elif args.verbose: #crc error only in verbose mode @@ -238,14 +252,22 @@ try: zvei_time_old = timestamp #save last time if useMySQL: #only if MySQL is active + if args.verbose: print "ZVEI to MySQL" cursor = connection.cursor() cursor.execute("INSERT INTO "+tableZVEI+" (time,zvei) VALUES (%s,%s)",(curtime(),zvei_id)) cursor.close() connection.commit() - + + if useHTTPrequest: #only if HTTPrequest is active + httprequest = httplib.HTTPConnection(url) + httprequest.request("HEAD", "/") + httpresponse = httprequest.getresponse() + if args.verbose: print httpresponse.status, httpresponse.reason + elif args.verbose: #Invalid error only in verbose mode print "No valid ZVEI: "+zvei_id - except KeyboardInterrupt: - stop_script("Keyboard Interrupt") \ No newline at end of file + stop_script("Keyboard Interrupt") +except: + stop_script("other Error") \ No newline at end of file diff --git a/config.ini b/config.ini index 561ddf8..98969de 100644 --- a/config.ini +++ b/config.ini @@ -3,26 +3,35 @@ ######################## [FMS] -#time to ignore same alarm in a row in seconds +#time to ignore same alarm in a row (sek) double_ignore_time = 10 [ZVEI] -#time to ignore same alarm in a row in seconds +#time to ignore same alarm in a row (sek) double_ignore_time = 5 #can take on or off the modules (0|1) [Module] useMySQL = 0 #useAudiorecord = 0 -#useHTTPrequest = 0 +useHTTPrequest = 0 -#Data for MySQL connection [MySQL] +#Data for MySQL connection dbserver = localhost dbuser = root dbpassword = root database = boswatch +#tables in the database tableFMS = bos_fms tableZVEI = bos_zvei -tablePOC = bos_pocsag \ No newline at end of file +tablePOC = bos_pocsag + +#[Audiorecord] +#recording time (sek) +#record_time = 30 + +[HTTPrequest] +#url without http:// ! +url = www.google.de \ No newline at end of file From 818309740e4412d7ec538ef17fe99b3abd299ebb Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Sat, 4 Apr 2015 22:08:51 +0200 Subject: [PATCH 2/7] added global log function --- boswatch.py | 65 +++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/boswatch.py b/boswatch.py index 464bc91..69e8ac4 100644 --- a/boswatch.py +++ b/boswatch.py @@ -23,20 +23,24 @@ import re #Regex def curtime(format="%Y-%m-%d %H:%M:%S"): return time.strftime(format) +def log(msg): + if args.verbose: print "[LOG "+curtime("%H:%M:%S")+"] "+msg + def stop_script(err): print "" print "ERR: "+err try: if useMySQL: #only if MySQL is active - if args.verbose: print "disconnect MySQL" + log("disconnect MySQL") connection.close() rtl_fm.terminate() - if args.verbose: print "rtl_fm terminated" + log("rtl_fm terminated") multimon_ng.terminate() - if args.verbose: print "multimon-ng terminated" - if args.verbose: print "exiting BOSWatch" + log("multimon-ng terminated") + log("exiting BOSWatch") except: - pass + log("Error in cleaning") + exit(0) #With -h or --help you get the Args help @@ -51,11 +55,6 @@ parser.add_argument("-s", "--squelch", help="Level of Squelch", type=int, defaul parser.add_argument("-v", "--verbose", help="Shows more Information", action="store_true") args = parser.parse_args() - - - - - #Read Data from Args, Put it into working Variables and Display them print(" ____ ____ ______ __ __ __ ") @@ -107,7 +106,7 @@ print "" try: #ConfigParser - if args.verbose: print "reading config file" + log("reading config file") try: config = ConfigParser.ConfigParser() config.read("./config.ini") @@ -134,19 +133,17 @@ try: except: stop_script("config reading error") - exit(0) if useMySQL: #only if MySQL is active - if args.verbose: print "connect to MySQL database" + log("connect to MySQL database") try: connection = mysql.connector.connect(host = str(dbserver), user = str(dbuser), passwd = str(dbpassword), db = str(database)) except: print "MySQL connect error" - exit(0) #variables pre-load - if args.verbose: print "pre-load variables" + log("pre-load variables") fms_id = 0 fms_id_old = 0 fms_time_old = 0 @@ -156,7 +153,7 @@ try: zvei_time_old = 0 - if args.verbose: print "starting rtl_fm" + log("starting rtl_fm") try: rtl_fm = subprocess.Popen("rtl_fm -d "+str(device)+" -f "+str(freq)+" -M fm -s 22050 -p "+str(error)+" -E DC -F 0 -l "+str(squelch)+" -g 100", #stdin=rtl_fm.stdout, @@ -165,10 +162,9 @@ try: shell=True) except: stop_script("cannot start rtl_fm") - exit(0) #multimon_ng = subprocess.Popen("aplay -r 22050 -f S16_LE -t raw", - if args.verbose: print "starting multimon-ng" + log("starting multimon-ng") try: multimon_ng = subprocess.Popen("multimon-ng "+str(demodulation)+" -f alpha -t raw /dev/stdin - ", stdin=rtl_fm.stdout, @@ -177,10 +173,9 @@ try: shell=True) except: stop_script("cannot start multimon-ng") - exit(0) - if args.verbose: print "start decoding" + log("start decoding") print "" while True: #RAW Data from Multimon-NG @@ -196,7 +191,7 @@ try: #FMS Decoder Section #check FMS: -> check CRC -> validate -> check double alarm -> print -> (MySQL) if "FMS:" in decoded: - if args.verbose: print "recived FMS" + log("recived FMS") fms_service = decoded[19] #Organisation fms_country = decoded[36] #Bundesland @@ -210,7 +205,7 @@ try: fms_id = fms_service+fms_country+fms_location+fms_vehicle+fms_status+fms_direction #build FMS id if re.search("[0-9a-f]{2}[0-9]{6}[0-9a-f]{1}[01]{1}", fms_id): #if FMS is valid if fms_id == fms_id_old and timestamp < fms_time_old + fms_double_ignore_time: #check for double alarm - if args.verbose: print "FMS double alarm: "+fms_id_old + log("FMS double alarm: "+fms_id_old) fms_time_old = timestamp #in case of double alarm, fms_double_ignore_time set new else: print curtime("%H:%M:%S")+" BOS:"+fms_service+" Bundesland:"+fms_country+" Ort:"+fms_location+" Fahrzeug:"+fms_vehicle+" Status:"+fms_status+" Richtung:"+fms_direction+" TKI:"+fms_tsi @@ -218,7 +213,7 @@ try: fms_time_old = timestamp #save last time if useMySQL: #only if MySQL is active - if args.verbose: print "FMS to MySQL" + log("FMS to MySQL") cursor = connection.cursor() cursor.execute("INSERT INTO "+tableFMS+" (time,service,country,location,vehicle,status,direction,tsi) VALUES (%s,%s,%s,%s,%s,%s,%s,%s)",(curtime(),fms_service,fms_country,fms_location,fms_vehicle,fms_status,fms_direction,fms_tsi)) cursor.close() @@ -228,23 +223,24 @@ try: httprequest = httplib.HTTPConnection(url) httprequest.request("HEAD", "/") httpresponse = httprequest.getresponse() - if args.verbose: print httpresponse.status, httpresponse.reason + #if args.verbose: print httpresponse.status, httpresponse.reason + log("FMS to HTTP") - elif args.verbose: #Invalid error only in verbose mode - print "No valid FMS: "+fms_id - elif args.verbose: #crc error only in verbose mode - print "CRC incorrect" + else: + log("No valid FMS: "+fms_id) + else: + log("CRC incorrect") #ZVEI Decoder Section #check ZVEI: -> validate -> check double alarm -> print -> (MySQL) if "ZVEI2:" in decoded: - if args.verbose: print "recived ZVEI" + log("recived ZVEI") zvei_id = decoded[7:12] #ZVEI Code if re.search("[0-9F]{5}", zvei_id): #if ZVEI is valid if zvei_id == zvei_id_old and timestamp < zvei_time_old + zvei_double_ignore_time: #check for double alarm - if args.verbose: print "ZVEI double alarm: "+zvei_id_old + log("ZVEI double alarm: "+zvei_id_old) zvei_time_old = timestamp #in case of double alarm, zvei_double_ignore_time set new else: print curtime("%H:%M:%S")+" 5-Ton: "+zvei_id @@ -252,7 +248,7 @@ try: zvei_time_old = timestamp #save last time if useMySQL: #only if MySQL is active - if args.verbose: print "ZVEI to MySQL" + log("ZVEI to MySQL") cursor = connection.cursor() cursor.execute("INSERT INTO "+tableZVEI+" (time,zvei) VALUES (%s,%s)",(curtime(),zvei_id)) cursor.close() @@ -262,10 +258,11 @@ try: httprequest = httplib.HTTPConnection(url) httprequest.request("HEAD", "/") httpresponse = httprequest.getresponse() - if args.verbose: print httpresponse.status, httpresponse.reason + #if args.verbose: print httpresponse.status, httpresponse.reason + log("ZVEI to HTTP") - elif args.verbose: #Invalid error only in verbose mode - print "No valid ZVEI: "+zvei_id + else: + log("No valid ZVEI: "+zvei_id) except KeyboardInterrupt: stop_script("Keyboard Interrupt") From 2446ab0073aa9004e7f70ee7b9305f3f58c0fbca Mon Sep 17 00:00:00 2001 From: Schrolli91 Date: Sat, 4 Apr 2015 22:58:10 +0200 Subject: [PATCH 3/7] Update README.md --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 71b4605..5866b05 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,12 @@ Python Script to Recive and Decode German BOS Information with rtl_fm and multimon-NG -**Please** only use Code from **master-Branch** - thats the only stable! +**Please** only use Code from **master**-Branch - thats **the only stable!** + +unless you are developer you can use the develop-Branch - may be unstable! ### Features -#####Implemented Features: +##### Implemented Features: - FMS and ZVEI decoding and Displaying - Filtering double alarms with adjustable time - FMS and ZVEI validation (plausibility test) @@ -14,7 +16,7 @@ Python Script to Recive and Decode German BOS Information with rtl_fm and multim - All configurations in seperate File "config.ini" - simple Web Frontend with Data Parsing -#####Features for the Future: +##### Features for the Future: - extensive filtering options - POCSAG 512,1200,2400 support (need RAW data from multimon-ng) - automatic Audio recording at alarm @@ -84,4 +86,4 @@ At the end you can find the Programm in `/home/pi/bos/BOSWatch` Thanks to smith_fms and McBo from [Funkmeldesystem.de - Forum](http://www.funkmeldesystem.de/) for Inspiration and Groundwork! -######Greetz Schrolli +###### Greetz Schrolli From 919f04aa74e6eab79abc917e5a2c8ca3607ba2e4 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Sat, 4 Apr 2015 23:32:51 +0200 Subject: [PATCH 4/7] insert Loglevel insert the Loglevel: [INFO] for the display output [LOG] for a logfile (not now) [ERROR] for program errors --- boswatch.py | 151 ++++++++++++++++++++++++++++------------------------ 1 file changed, 81 insertions(+), 70 deletions(-) diff --git a/boswatch.py b/boswatch.py index 69e8ac4..3d7d2e3 100644 --- a/boswatch.py +++ b/boswatch.py @@ -23,24 +23,12 @@ import re #Regex def curtime(format="%Y-%m-%d %H:%M:%S"): return time.strftime(format) -def log(msg): - if args.verbose: print "[LOG "+curtime("%H:%M:%S")+"] "+msg - -def stop_script(err): - print "" - print "ERR: "+err - try: - if useMySQL: #only if MySQL is active - log("disconnect MySQL") - connection.close() - rtl_fm.terminate() - log("rtl_fm terminated") - multimon_ng.terminate() - log("multimon-ng terminated") - log("exiting BOSWatch") - except: - log("Error in cleaning") - exit(0) +#Loglevel +#[LOG] for the logfile +#[INFO] normal display +#[ERROR] errors +def log(msg, level="log"): + if args.verbose: print curtime("%H:%M:%S")+" ["+level.upper()+"] "+msg #With -h or --help you get the Args help @@ -112,7 +100,7 @@ try: config.read("./config.ini") fms_double_ignore_time = int(config.get("FMS", "double_ignore_time")) zvei_double_ignore_time = int(config.get("ZVEI", "double_ignore_time")) - + #MySQL config useMySQL = int(config.get("Module", "useMySQL")) #use MySQL support? if useMySQL: #only if MySQL is active @@ -120,39 +108,39 @@ try: dbuser = config.get("MySQL", "dbuser") dbpassword = config.get("MySQL", "dbpassword") database = config.get("MySQL", "database") - + #MySQL tables tableFMS = config.get("MySQL", "tableFMS") tableZVEI = config.get("MySQL", "tableZVEI") tablePOC = config.get("MySQL", "tablePOC") - + #HTTPrequest config useHTTPrequest = int(config.get("Module", "useHTTPrequest")) #use HTTPrequest support? if useHTTPrequest: #only if HTTPrequest is active url = config.get("HTTPrequest", "url") except: - stop_script("config reading error") - - + log("config reading error","error") + + if useMySQL: #only if MySQL is active log("connect to MySQL database") try: connection = mysql.connector.connect(host = str(dbserver), user = str(dbuser), passwd = str(dbpassword), db = str(database)) except: - print "MySQL connect error" - + log("MySQL connect error","error") + #variables pre-load log("pre-load variables") fms_id = 0 fms_id_old = 0 fms_time_old = 0 - + zvei_id = 0 zvei_id_old = 0 zvei_time_old = 0 - - + + log("starting rtl_fm") try: rtl_fm = subprocess.Popen("rtl_fm -d "+str(device)+" -f "+str(freq)+" -M fm -s 22050 -p "+str(error)+" -E DC -F 0 -l "+str(squelch)+" -g 100", @@ -161,7 +149,7 @@ try: stderr=open('log.txt','a'), shell=True) except: - stop_script("cannot start rtl_fm") + log("cannot start rtl_fm","error") #multimon_ng = subprocess.Popen("aplay -r 22050 -f S16_LE -t raw", log("starting multimon-ng") @@ -172,9 +160,9 @@ try: stderr=open('log.txt','a'), shell=True) except: - stop_script("cannot start multimon-ng") - - + log("cannot start multimon-ng","error") + + log("start decoding") print "" while True: @@ -182,9 +170,9 @@ try: #ZVEI2: 25832 #FMS: 43f314170000 (9=Rotkreuz 3=Bayern 1 Ort 0x25=037FZG 7141Status 3=Einsatz Ab 0=FZG->LST2=III(mit NA,ohneSIGNAL)) CRC correct\n' decoded = str(multimon_ng.stdout.readline()) #Get line data from multimon stdout - + if True: #if input data avalable - + timestamp = int(time.time())#Get Timestamp #if args.verbose: print "RAW: "+decoded #for verbose mode, print Raw input data @@ -200,7 +188,7 @@ try: fms_status = decoded[84] #Status fms_direction = decoded[101] #Richtung fms_tsi = decoded[114:117] #Taktische Kruzinformation - + if "CRC correct" in decoded: #check CRC is correct fms_id = fms_service+fms_country+fms_location+fms_vehicle+fms_status+fms_direction #build FMS id if re.search("[0-9a-f]{2}[0-9]{6}[0-9a-f]{1}[01]{1}", fms_id): #if FMS is valid @@ -208,30 +196,36 @@ try: log("FMS double alarm: "+fms_id_old) fms_time_old = timestamp #in case of double alarm, fms_double_ignore_time set new else: - print curtime("%H:%M:%S")+" BOS:"+fms_service+" Bundesland:"+fms_country+" Ort:"+fms_location+" Fahrzeug:"+fms_vehicle+" Status:"+fms_status+" Richtung:"+fms_direction+" TKI:"+fms_tsi + log(curtime("%H:%M:%S")+" BOS:"+fms_service+" Bundesland:"+fms_country+" Ort:"+fms_location+" Fahrzeug:"+fms_vehicle+" Status:"+fms_status+" Richtung:"+fms_direction+" TKI:"+fms_tsi,"info") fms_id_old = fms_id #save last id fms_time_old = timestamp #save last time - - if useMySQL: #only if MySQL is active - log("FMS to MySQL") - cursor = connection.cursor() - cursor.execute("INSERT INTO "+tableFMS+" (time,service,country,location,vehicle,status,direction,tsi) VALUES (%s,%s,%s,%s,%s,%s,%s,%s)",(curtime(),fms_service,fms_country,fms_location,fms_vehicle,fms_status,fms_direction,fms_tsi)) - cursor.close() - connection.commit() - - if useHTTPrequest: #only if HTTPrequest is active - httprequest = httplib.HTTPConnection(url) - httprequest.request("HEAD", "/") - httpresponse = httprequest.getresponse() - #if args.verbose: print httpresponse.status, httpresponse.reason - log("FMS to HTTP") + log("FMS to MySQL") + try: + if useMySQL: #only if MySQL is active + cursor = connection.cursor() + cursor.execute("INSERT INTO "+tableFMS+" (time,service,country,location,vehicle,status,direction,tsi) VALUES (%s,%s,%s,%s,%s,%s,%s,%s)",(curtime(),fms_service,fms_country,fms_location,fms_vehicle,fms_status,fms_direction,fms_tsi)) + cursor.close() + connection.commit() + except: + log("FMS cannot insert","error") + + log("FMS to HTTP") + try: + if useHTTPrequest: #only if HTTPrequest is active + httprequest = httplib.HTTPConnection(url) + httprequest.request("HEAD", "/") + httpresponse = httprequest.getresponse() + #if args.verbose: print httpresponse.status, httpresponse.reason + except: + log("FMS cannot request","error") + else: log("No valid FMS: "+fms_id) else: log("CRC incorrect") - - + + #ZVEI Decoder Section #check ZVEI: -> validate -> check double alarm -> print -> (MySQL) if "ZVEI2:" in decoded: @@ -243,28 +237,45 @@ try: log("ZVEI double alarm: "+zvei_id_old) zvei_time_old = timestamp #in case of double alarm, zvei_double_ignore_time set new else: - print curtime("%H:%M:%S")+" 5-Ton: "+zvei_id + log(curtime("%H:%M:%S")+" 5-Ton: "+zvei_id,"info") zvei_id_old = zvei_id #save last id zvei_time_old = timestamp #save last time - - if useMySQL: #only if MySQL is active - log("ZVEI to MySQL") - cursor = connection.cursor() - cursor.execute("INSERT INTO "+tableZVEI+" (time,zvei) VALUES (%s,%s)",(curtime(),zvei_id)) - cursor.close() - connection.commit() - if useHTTPrequest: #only if HTTPrequest is active - httprequest = httplib.HTTPConnection(url) - httprequest.request("HEAD", "/") - httpresponse = httprequest.getresponse() - #if args.verbose: print httpresponse.status, httpresponse.reason - log("ZVEI to HTTP") + log("ZVEI to MySQL") + try: + if useMySQL: #only if MySQL is active + log("ZVEI to MySQL") + cursor = connection.cursor() + cursor.execute("INSERT INTO "+tableZVEI+" (time,zvei) VALUES (%s,%s)",(curtime(),zvei_id)) + cursor.close() + connection.commit() + except: + log("ZVEI cannot insert","error") + log("ZVEI to HTTP") + try: + if useHTTPrequest: #only if HTTPrequest is active + httprequest = httplib.HTTPConnection(url) + httprequest.request("HEAD", "/") + httpresponse = httprequest.getresponse() + #if args.verbose: print httpresponse.status, httpresponse.reason + except: + log("ZVEI cannot request","error") + else: log("No valid ZVEI: "+zvei_id) - + except KeyboardInterrupt: - stop_script("Keyboard Interrupt") + log("Keyboard Interrupt","error") except: - stop_script("other Error") \ No newline at end of file + log("other Error","error") +finally: + if useMySQL: #only if MySQL is active + log("disconnect MySQL") + connection.close() + rtl_fm.terminate() + log("rtl_fm terminated") + multimon_ng.terminate() + log("multimon-ng terminated") + log("exiting BOSWatch") + exit(0) \ No newline at end of file From bd7ce55b39c0924447d1a6865940b790bba1c2c5 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Sun, 5 Apr 2015 00:15:32 +0200 Subject: [PATCH 5/7] Logfile and better Error handling Logfile log_bos.txt seperate Logfiles for rtl_fm an multimon (log_rtl.txt, log_mon.txt) better error handling and more log messages --- boswatch.py | 214 +++++++++++++++++++++++++++++----------------------- 1 file changed, 120 insertions(+), 94 deletions(-) diff --git a/boswatch.py b/boswatch.py index 3d7d2e3..0b90075 100644 --- a/boswatch.py +++ b/boswatch.py @@ -20,6 +20,8 @@ import argparse #for parse the args import ConfigParser #for parse the config file import re #Regex + +# Functions def curtime(format="%Y-%m-%d %H:%M:%S"): return time.strftime(format) @@ -28,71 +30,94 @@ def curtime(format="%Y-%m-%d %H:%M:%S"): #[INFO] normal display #[ERROR] errors def log(msg, level="log"): - if args.verbose: print curtime("%H:%M:%S")+" ["+level.upper()+"] "+msg + log_entry = curtime("%H:%M:%S")+" ["+level.upper()+"] "+msg - -#With -h or --help you get the Args help -#ArgsParser -parser = argparse.ArgumentParser(prog="boswatch.py", description="BOSWatch is a Python Script to Recive and Decode German BOS Information with rtl_fm and multimon-NG", epilog="More Options you can find in the extern config.ini File in this Folder") -#parser.add_argument("-c", "--channel", help="BOS Channel you want to listen") -parser.add_argument("-f", "--freq", help="Frequency you want to listen", required=True) -parser.add_argument("-d", "--device", help="Device you want to use (Check with rtl_test)", type=int, default=0) -parser.add_argument("-e", "--error", help="Frequency-Error of your Device in PPM", type=int, default=0) -parser.add_argument("-a", "--demod", help="Demodulation Functions", choices=['FMS', 'ZVEI', 'POC512', 'POC1200', 'POC2400'], required=True, nargs="+") -parser.add_argument("-s", "--squelch", help="Level of Squelch", type=int, default=0) -parser.add_argument("-v", "--verbose", help="Shows more Information", action="store_true") -args = parser.parse_args() - - -#Read Data from Args, Put it into working Variables and Display them -print(" ____ ____ ______ __ __ __ ") -print(" / __ )/ __ \/ ___/ | / /___ _/ /______/ /_ b") -print(" / __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ e") -print(" / /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / t") -print(" /_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ a") -print(" German BOS Information Script ") -print(" by Bastian Schroll ") -print("") - -freq = args.freq -print "Frequency: "+freq + if not level == "log" or args.verbose: + print log_entry + + bos_log = open("log_bos.txt", "a") + bos_log.write(log_entry+"\n") + bos_log.close() -#channel = args.channel -#print("Frequency: ",channel) -device = args.device -print "Device-ID: "+str(device) +try: -error = args.error -print "Error in PPM: "+str(error) + try: + bos_log = open("log_bos.txt", "w") + rtl_log = open("log_rtl.txt", "w") + mon_log = open("log_mon.txt", "w") + bos_log.write("##### "+curtime()+" #####\n\n") + rtl_log.write("##### "+curtime()+" #####\n\n") + mon_log.write("##### "+curtime()+" #####\n\n") + bos_log.close() + rtl_log.close() + mon_log.close() + except: + log("cannot clear logfiles","error") -demodulation = "" -print "Active Demods: "+str(len(args.demod)) -if "FMS" in args.demod: - demodulation += "-a FMSFSK " - print "- FMS" -if "ZVEI" in args.demod: - demodulation += "-a ZVEI2 " - print "- ZVEI" -if "POC512" in args.demod: - demodulation += "-a POCSAG512 " - print "- POC512" -if "POC1200" in args.demod: - demodulation += "-a POCSAG1200 " - print "- POC1200" -if "POC2400" in args.demod: - demodulation += "-a POCSAG2400 " - print "- POC2400" + try: + #With -h or --help you get the Args help + #ArgsParser + parser = argparse.ArgumentParser(prog="boswatch.py", description="BOSWatch is a Python Script to Recive and Decode German BOS Information with rtl_fm and multimon-NG", epilog="More Options you can find in the extern config.ini File in this Folder") + #parser.add_argument("-c", "--channel", help="BOS Channel you want to listen") + parser.add_argument("-f", "--freq", help="Frequency you want to listen", required=True) + parser.add_argument("-d", "--device", help="Device you want to use (Check with rtl_test)", type=int, default=0) + parser.add_argument("-e", "--error", help="Frequency-Error of your Device in PPM", type=int, default=0) + parser.add_argument("-a", "--demod", help="Demodulation Functions", choices=['FMS', 'ZVEI', 'POC512', 'POC1200', 'POC2400'], required=True, nargs="+") + parser.add_argument("-s", "--squelch", help="Level of Squelch", type=int, default=0) + parser.add_argument("-v", "--verbose", help="Shows more Information", action="store_true") + args = parser.parse_args() + except: + log("cannot parse Args","error") -squelch = args.squelch -print "Squelch: "+str(squelch) + #Read Data from Args, Put it into working Variables and Display them + print(" ____ ____ ______ __ __ __ ") + print(" / __ )/ __ \/ ___/ | / /___ _/ /______/ /_ b") + print(" / __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ e") + print(" / /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / t") + print(" /_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ a") + print(" German BOS Information Script ") + print(" by Bastian Schroll ") + print("") -if args.verbose: - print("Verbose Mode!") + freq = args.freq + print "Frequency: "+freq + + #channel = args.channel + #print("Frequency: ",channel) -print "" - -try: + device = args.device + print "Device-ID: "+str(device) + + error = args.error + print "Error in PPM: "+str(error) + + demodulation = "" + print "Active Demods: "+str(len(args.demod)) + if "FMS" in args.demod: + demodulation += "-a FMSFSK " + print "- FMS" + if "ZVEI" in args.demod: + demodulation += "-a ZVEI2 " + print "- ZVEI" + if "POC512" in args.demod: + demodulation += "-a POCSAG512 " + print "- POC512" + if "POC1200" in args.demod: + demodulation += "-a POCSAG1200 " + print "- POC1200" + if "POC2400" in args.demod: + demodulation += "-a POCSAG2400 " + print "- POC2400" + + squelch = args.squelch + print "Squelch: "+str(squelch) + + if args.verbose: + print("Verbose Mode!") + + print "" + #ConfigParser log("reading config file") try: @@ -122,14 +147,6 @@ try: except: log("config reading error","error") - - if useMySQL: #only if MySQL is active - log("connect to MySQL database") - try: - connection = mysql.connector.connect(host = str(dbserver), user = str(dbuser), passwd = str(dbpassword), db = str(database)) - except: - log("MySQL connect error","error") - #variables pre-load log("pre-load variables") fms_id = 0 @@ -139,14 +156,21 @@ try: zvei_id = 0 zvei_id_old = 0 zvei_time_old = 0 - - + + if useMySQL: #only if MySQL is active + log("connect to MySQL database") + try: + connection = mysql.connector.connect(host = str(dbserver), user = str(dbuser), passwd = str(dbpassword), db = str(database)) + except: + log("MySQL connect error","error") + + log("starting rtl_fm") try: rtl_fm = subprocess.Popen("rtl_fm -d "+str(device)+" -f "+str(freq)+" -M fm -s 22050 -p "+str(error)+" -E DC -F 0 -l "+str(squelch)+" -g 100", #stdin=rtl_fm.stdout, stdout=subprocess.PIPE, - stderr=open('log.txt','a'), + stderr=open('log_rtl.txt','a'), shell=True) except: log("cannot start rtl_fm","error") @@ -157,7 +181,7 @@ try: multimon_ng = subprocess.Popen("multimon-ng "+str(demodulation)+" -f alpha -t raw /dev/stdin - ", stdin=rtl_fm.stdout, stdout=subprocess.PIPE, - stderr=open('log.txt','a'), + stderr=open('log_mon.txt','a'), shell=True) except: log("cannot start multimon-ng","error") @@ -196,29 +220,30 @@ try: log("FMS double alarm: "+fms_id_old) fms_time_old = timestamp #in case of double alarm, fms_double_ignore_time set new else: - log(curtime("%H:%M:%S")+" BOS:"+fms_service+" Bundesland:"+fms_country+" Ort:"+fms_location+" Fahrzeug:"+fms_vehicle+" Status:"+fms_status+" Richtung:"+fms_direction+" TKI:"+fms_tsi,"info") + log("BOS:"+fms_service+" Bundesland:"+fms_country+" Ort:"+fms_location+" Fahrzeug:"+fms_vehicle+" Status:"+fms_status+" Richtung:"+fms_direction+" TKI:"+fms_tsi,"info") fms_id_old = fms_id #save last id fms_time_old = timestamp #save last time - - log("FMS to MySQL") - try: - if useMySQL: #only if MySQL is active + + if useMySQL: #only if MySQL is active + log("FMS to MySQL") + try: cursor = connection.cursor() cursor.execute("INSERT INTO "+tableFMS+" (time,service,country,location,vehicle,status,direction,tsi) VALUES (%s,%s,%s,%s,%s,%s,%s,%s)",(curtime(),fms_service,fms_country,fms_location,fms_vehicle,fms_status,fms_direction,fms_tsi)) cursor.close() connection.commit() - except: - log("FMS cannot insert","error") + except: + log("FMS cannot insert","error") - log("FMS to HTTP") - try: - if useHTTPrequest: #only if HTTPrequest is active + + if useHTTPrequest: #only if HTTPrequest is active + log("FMS to HTTP") + try: httprequest = httplib.HTTPConnection(url) httprequest.request("HEAD", "/") httpresponse = httprequest.getresponse() #if args.verbose: print httpresponse.status, httpresponse.reason - except: - log("FMS cannot request","error") + except: + log("FMS cannot request","error") else: log("No valid FMS: "+fms_id) @@ -237,30 +262,31 @@ try: log("ZVEI double alarm: "+zvei_id_old) zvei_time_old = timestamp #in case of double alarm, zvei_double_ignore_time set new else: - log(curtime("%H:%M:%S")+" 5-Ton: "+zvei_id,"info") + log("5-Ton: "+zvei_id,"info") zvei_id_old = zvei_id #save last id zvei_time_old = timestamp #save last time - log("ZVEI to MySQL") - try: - if useMySQL: #only if MySQL is active - log("ZVEI to MySQL") + + if useMySQL: #only if MySQL is active + log("ZVEI to MySQL") + try: cursor = connection.cursor() cursor.execute("INSERT INTO "+tableZVEI+" (time,zvei) VALUES (%s,%s)",(curtime(),zvei_id)) cursor.close() connection.commit() - except: - log("ZVEI cannot insert","error") + except: + log("ZVEI cannot insert","error") + - log("ZVEI to HTTP") - try: - if useHTTPrequest: #only if HTTPrequest is active + if useHTTPrequest: #only if HTTPrequest is active + log("ZVEI to HTTP") + try: httprequest = httplib.HTTPConnection(url) httprequest.request("HEAD", "/") httpresponse = httprequest.getresponse() #if args.verbose: print httpresponse.status, httpresponse.reason - except: - log("ZVEI cannot request","error") + except: + log("ZVEI cannot request","error") else: log("No valid ZVEI: "+zvei_id) @@ -268,7 +294,7 @@ try: except KeyboardInterrupt: log("Keyboard Interrupt","error") except: - log("other Error","error") + log("unknown Error","error") finally: if useMySQL: #only if MySQL is active log("disconnect MySQL") From 3bb87f978295ac13c6f7f089a9511952735375c8 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Sun, 5 Apr 2015 00:54:41 +0200 Subject: [PATCH 6/7] nicer install.sh and other little things --- README.md | 9 +++---- boswatch.py | 25 +++++++++---------- install.sh | 70 ++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 66 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 5866b05..b8fb0a0 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ unless you are developer you can use the develop-Branch - may be unstable! - simple HTTP request at alarm to URL you want - All configurations in seperate File "config.ini" - simple Web Frontend with Data Parsing +- Logfiles for better Troubleshooting ##### Features for the Future: - extensive filtering options @@ -46,9 +47,6 @@ usage: boswatch.py [-h] -f FREQ [-d DEVICE] [-e ERROR] -a {FMS,ZVEI,POC512,POC1200,POC2400} [{FMS,ZVEI,POC512,POC1200,POC2400} ...] [-s SQUELCH] [-v] -BOSWatch is a Python Script to Recive and Decode BOS Information with rtl_fm -and multimon-NG - optional arguments: -h, --help show this help message and exit -f FREQ, --freq FREQ Frequency you want to listen @@ -62,8 +60,6 @@ optional arguments: -s SQUELCH, --squelch SQUELCH Level of Squelch -v, --verbose Shows more Information - -More Options you can find in the extern config.ini File in this Folder ``` ### Installation @@ -75,6 +71,9 @@ You can easy install BOSWatch with the install.sh Script. Now the script downloads and compile all needed data. At the end you can find the Programm in `/home/pi/bos/BOSWatch` +Caution, script don't install a Webserver with PHP and MySQL. +So you have to make up manually if you want to use MySQL support. + ### Requirements - RTL_SDR (rtl_fm) - Multimon-NG diff --git a/boswatch.py b/boswatch.py index 0b90075..f10dec6 100644 --- a/boswatch.py +++ b/boswatch.py @@ -71,20 +71,20 @@ try: log("cannot parse Args","error") #Read Data from Args, Put it into working Variables and Display them - print(" ____ ____ ______ __ __ __ ") - print(" / __ )/ __ \/ ___/ | / /___ _/ /______/ /_ b") - print(" / __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ e") - print(" / /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / t") - print(" /_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ a") - print(" German BOS Information Script ") - print(" by Bastian Schroll ") - print("") + print " ____ ____ ______ __ __ __ " + print " / __ )/ __ \/ ___/ | / /___ _/ /______/ /_ b" + print " / __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ e" + print " / /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / t" + print " /_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ a" + print " German BOS Information Script " + print " by Bastian Schroll " + print "" freq = args.freq print "Frequency: "+freq #channel = args.channel - #print("Frequency: ",channel) + #print "Frequency: ",channel device = args.device print "Device-ID: "+str(device) @@ -114,7 +114,7 @@ try: print "Squelch: "+str(squelch) if args.verbose: - print("Verbose Mode!") + print "Verbose Mode!" print "" @@ -188,7 +188,6 @@ try: log("start decoding") - print "" while True: #RAW Data from Multimon-NG #ZVEI2: 25832 @@ -201,7 +200,7 @@ try: #if args.verbose: print "RAW: "+decoded #for verbose mode, print Raw input data #FMS Decoder Section - #check FMS: -> check CRC -> validate -> check double alarm -> print -> (MySQL) + #check FMS: -> check CRC -> validate -> check double alarm -> log -> (MySQL) if "FMS:" in decoded: log("recived FMS") @@ -252,7 +251,7 @@ try: #ZVEI Decoder Section - #check ZVEI: -> validate -> check double alarm -> print -> (MySQL) + #check ZVEI: -> validate -> check double alarm -> log -> (MySQL) if "ZVEI2:" in decoded: log("recived ZVEI") diff --git a/install.sh b/install.sh index ee392be..bdc408d 100644 --- a/install.sh +++ b/install.sh @@ -1,69 +1,99 @@ #!/bin/sh clear -echo "" -echo " ##########################" -echo " # #" -echo " # BOSWatch Installer #" -echo " # #" -echo " ##########################" +echo " ____ ____ ______ __ __ __ " +echo " / __ )/ __ \/ ___/ | / /___ _/ /______/ /_ " +echo " / __ / / / /\__ \| | /| / / __ / __/ ___/ __ \ " +echo " / /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / " +echo " /_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ " +echo " German BOS Information Script " +echo " by Bastian Schroll " echo "" echo "This may take a several minutes... Don't panic!" echo "" -echo "Caution, script don't installed a Webserver with PHP and MySQL" +echo "Caution, script don't install a Webserver with PHP and MySQL" echo "So you have to make up manually if you want to use MySQL support" -echo "" mkdir -p /home/pi/bos/install -echo "[ 1/10] [#---------] make a apt-get update..." +tput cup 13 15 +echo "[ 1/10] [#---------]" +tput cup 15 5 +echo "-> make a apt-get update................" apt-get update > /home/pi/bos/install/setup_log.txt 2>&1 -echo "[ 2/10] [##--------] download GIT an other stuff..." +tput cup 13 15 +echo "[ 2/10] [##--------]" +tput cup 15 5 +echo "-> download GIT an other stuff.........." apt-get -y install git cmake build-essential libusb-1.0 qt4-qmake libpulse-dev libx11-dev sox >> /home/pi/bos/install/setup_log.txt 2>&1 -echo "[ 3/10] [###-------] download rtl_fm..." +tput cup 13 15 +echo "[ 3/10] [###-------]" +tput cup 15 5 +echo "-> download rtl_fm......................" cd /home/pi/bos/install git clone git://git.osmocom.org/rtl-sdr.git >> /home/pi/bos/install/setup_log.txt 2>&1 cd rtl-sdr/ -echo "[ 4/10] [####------] compile rtl_fm..." +tput cup 13 15 +echo "[ 4/10] [####------]" +tput cup 15 5 +echo "-> compile rtl_fm......................" mkdir -p build && cd build cmake ../ -DINSTALL_UDEV_RULES=ON >> /home/pi/bos/install/setup_log.txt 2>&1 make >> /home/pi/bos/install/setup_log.txt 2>&1 make install >> /home/pi/bos/install/setup_log.txt 2>&1 ldconfig >> /home/pi/bos/install/setup_log.txt 2>&1 -echo "[ 5/10] [#####-----] download multimon-ng..." +tput cup 13 15 +echo "[ 5/10] [#####-----]" +tput cup 15 5 +echo "-> download multimon-ng................" cd /home/pi/bos/install git clone https://github.com/EliasOenal/multimonNG.git >> /home/pi/bos/install/setup_log.txt 2>&1 cd multimonNG/ -echo "[ 6/10] [######----] compile multimon-ng..." +tput cup 13 15 +echo "[ 6/10] [######----]" +tput cup 15 5 +echo "-> compile multimon-ng................." mkdir -p build cd build qmake ../multimon-ng.pro >> /home/pi/bos/install/setup_log.txt 2>&1 make >> /home/pi/bos/install/setup_log.txt 2>&1 make install >> /home/pi/bos/install/setup_log.txt 2>&1 -echo "[ 7/10] [#######---] download MySQL Connector for Python..." +tput cup 13 15 +echo "[ 7/10] [#######---]" +tput cup 15 5 +echo "-> download MySQL Connector for Python." cd /home/pi/bos/install wget "http://dev.mysql.com/get/Downloads/Connector-Python/mysql-connector-python-1.0.9.tar.gz/from/http://cdn.mysql.com/" -O mysql-connector.tar >> /home/pi/bos/install/setup_log.txt 2>&1 tar xfv mysql-connector.tar >> /home/pi/bos/install/setup_log.txt 2>&1 cd mysql-connector-python* -echo "[ 8/10] [########--] install MySQL Connector for Python..." +tput cup 13 15 +echo "[ 8/10] [########--]" +tput cup 15 5 +echo "-> install MySQL Connector for Python.." chmod +x ./setup.py ./setup.py install >> /home/pi/bos/install/setup_log.txt 2>&1 -echo "[ 9/10] [#########-] download BOSWatch..." +tput cup 13 15 +echo "[ 9/10] [#########-]" +tput cup 15 5 +echo "-> download BOSWatch..................." cd /home/pi/bos git clone https://github.com/Schrolli91/BOSWatch >> /home/pi/bos/install/setup_log.txt 2>&1 -echo "[10/10] [##########] configure..." +tput cup 13 15 +echo "[10/10] [##########]" +tput cup 15 5 +echo "-> configure..........................." cd BOSWatch chmod +x * echo "# blacklist the DVB drivers to avoid conflict with the SDR driver\n blacklist dvb_usb_rtl28xxu \n blacklist rtl2830\n blacklist dvb_usb_v2\n blacklist dvb_core" >> /etc/modprobe.d/boswatch_blacklist_sdr.conf -echo "" +tput cup 17 1 echo "BOSWatch are now in /home/pi/bos/BOSWatch/" -echo "Install ready!" +echo "Install ready!" \ No newline at end of file From 5d5d2f6d9b344edba0dc6adbf1e2be05e34b7f22 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Sun, 5 Apr 2015 01:05:14 +0200 Subject: [PATCH 7/7] little change for release --- install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install.sh b/install.sh index bdc408d..23eac5a 100644 --- a/install.sh +++ b/install.sh @@ -1,5 +1,6 @@ #!/bin/sh -clear +tput clear +tput civis echo " ____ ____ ______ __ __ __ " echo " / __ )/ __ \/ ___/ | / /___ _/ /______/ /_ " echo " / __ / / / /\__ \| | /| / / __ / __/ ___/ __ \ "