From 24dc216bba36aa08321f8fd578eb4302cd67432d Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Fri, 3 Apr 2015 22:55:35 +0200 Subject: [PATCH 01/12] delete ununsed file --- raspoc.sql | 72 ------------------------------------------------------ 1 file changed, 72 deletions(-) delete mode 100644 raspoc.sql diff --git a/raspoc.sql b/raspoc.sql deleted file mode 100644 index a2d848d..0000000 --- a/raspoc.sql +++ /dev/null @@ -1,72 +0,0 @@ --- phpMyAdmin SQL Dump --- version 3.4.11.1deb2+deb7u1 --- http://www.phpmyadmin.net --- --- Host: localhost --- Erstellungszeit: 03. Apr 2015 um 11:16 --- Server Version: 5.5.41 --- PHP-Version: 5.4.39-0+deb7u1 - -SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; -SET time_zone = "+00:00"; - - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; - --- --- Datenbank: `raspoc` --- - --- -------------------------------------------------------- - --- --- Tabellenstruktur für Tabelle `ras_fms_hist` --- - -CREATE TABLE IF NOT EXISTS `ras_fms_hist` ( - `ID` int(11) NOT NULL AUTO_INCREMENT, - `time` datetime NOT NULL, - `service` varchar(1) NOT NULL, - `country` varchar(2) NOT NULL, - `location` varchar(2) NOT NULL, - `vehicle` varchar(4) NOT NULL, - `status` varchar(1) NOT NULL, - `direction` varchar(1) NOT NULL, - `tsi` varchar(3) NOT NULL, - PRIMARY KEY (`ID`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; - --- -------------------------------------------------------- - --- --- Tabellenstruktur für Tabelle `ras_pocsag_hist` --- - -CREATE TABLE IF NOT EXISTS `ras_pocsag_hist` ( - `ID` int(11) NOT NULL AUTO_INCREMENT, - `time` datetime NOT NULL, - `ric` varchar(7) NOT NULL DEFAULT '0', - `funktion` int(1) NOT NULL, - `text` text NOT NULL, - KEY `ID` (`ID`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; - --- -------------------------------------------------------- - --- --- Tabellenstruktur für Tabelle `ras_zvei_hist` --- - -CREATE TABLE IF NOT EXISTS `ras_zvei_hist` ( - `ID` int(11) NOT NULL AUTO_INCREMENT, - `time` datetime NOT NULL, - `zvei` varchar(5) NOT NULL DEFAULT '0', - PRIMARY KEY (`ID`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; - -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; From b05e19e12ad929e48060d5851c6e4d0d6533e566 Mon Sep 17 00:00:00 2001 From: Schrolli91 Date: Fri, 3 Apr 2015 23:06:20 +0200 Subject: [PATCH 02/12] Update README.md --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c82c505..69b5caa 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # BOSWatch Python Script to Recive and Decode German BOS Information with rtl_fm ans multimon-NG +**Please** only use Code from **master-Branch** - thats the only stable! + ### Features #####Implementeted Features: - FMS and ZVEI decoding and Displaying @@ -61,5 +63,13 @@ optional arguments: More Options you can find in the extern config.ini File in this Folder ``` +### Requirements +- RTL_SDR (rtl_fm) +- Multimon-NG + +##### optional +- Webserver with PHP +- MySQL Database Server + Thanks to smith_fms and McBo from [Funkmeldesystem.de - Forum](http://www.funkmeldesystem.de/) for Inspiration and Groundwork! -Greetz Schrolli \ No newline at end of file +Greetz Schrolli From 90b5de8acd41acc9129afe5a481d2663f7b175c3 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Fri, 3 Apr 2015 23:11:54 +0200 Subject: [PATCH 03/12] spelling error ans -> and --- README.md | 3 ++- boswatch.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 69b5caa..1593c3f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # BOSWatch -Python Script to Recive and Decode German BOS Information with rtl_fm ans multimon-NG +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! @@ -66,6 +66,7 @@ More Options you can find in the extern config.ini File in this Folder ### Requirements - RTL_SDR (rtl_fm) - Multimon-NG +- MySQL Connector for Python ##### optional - Webserver with PHP diff --git a/boswatch.py b/boswatch.py index 91ccf77..393d987 100644 --- a/boswatch.py +++ b/boswatch.py @@ -3,7 +3,7 @@ ##### Info ##### # BOSWatch -# Python Script to Recive and Decode BOS Information with rtl_fm and multimon-NG +# Python Script to Recive and Decode German BOS Information with rtl_fm and multimon-NG # For more Information see the README.md ##### Info ##### @@ -40,7 +40,7 @@ def stop_script(err): #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 ans multimon-NG", epilog="More Options you can find in the extern config.ini File in this Folder") +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) From 4587355b4fc357b02f5d3afc106c14e455b9ef8a Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Sat, 4 Apr 2015 12:20:40 +0200 Subject: [PATCH 04/12] added install.sh Script added a automatic installation script for BOSWatch --- README.md | 12 ++++++++-- install.sh | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 install.sh diff --git a/README.md b/README.md index 1593c3f..7046932 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Python Script to Recive and Decode German BOS Information with rtl_fm and multim **Please** only use Code from **master-Branch** - thats the only stable! ### Features -#####Implementeted Features: +#####Implemented Features: - FMS and ZVEI decoding and Displaying - Filtering double alarms with adjustable time - FMS and ZVEI validation (plausibility test) @@ -14,7 +14,7 @@ Python Script to Recive and Decode German BOS Information with rtl_fm and multim #####Features for the Future: - extensive filtering options -- POCSAG 512,1200,2400 support +- POCSAG 512,1200,2400 support (need RAW data from multimon-ng) - automatic Audio recording at alarm - Web Frontend with configuration @@ -63,6 +63,14 @@ optional arguments: More Options you can find in the extern config.ini File in this Folder ``` +### Installation +You can easy install BOSWatch with the install.sh Script. +Download it in any Folder you want. +Make it executeable `sudo chmod +x install.sh` +And use the script `sudo sh install.sh` +Now the script downloads and compile all needed data. +At the end you can find the Programm in `/home/pi/bos/BOSWatch` + ### Requirements - RTL_SDR (rtl_fm) - Multimon-NG diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..ee392be --- /dev/null +++ b/install.sh @@ -0,0 +1,69 @@ +#!/bin/sh +clear +echo "" +echo " ##########################" +echo " # #" +echo " # BOSWatch Installer #" +echo " # #" +echo " ##########################" +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 "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..." +apt-get update > /home/pi/bos/install/setup_log.txt 2>&1 + +echo "[ 2/10] [##--------] 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..." +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..." +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..." +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..." +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..." +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..." +chmod +x ./setup.py +./setup.py install >> /home/pi/bos/install/setup_log.txt 2>&1 + +echo "[ 9/10] [#########-] 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..." +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 "" +echo "BOSWatch are now in /home/pi/bos/BOSWatch/" +echo "Install ready!" From 15122206fed92c8b89e86499f9e0173e7587e680 Mon Sep 17 00:00:00 2001 From: Schrolli91 Date: Sat, 4 Apr 2015 12:22:52 +0200 Subject: [PATCH 05/12] Update README.md --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7046932..fb2eb5a 100644 --- a/README.md +++ b/README.md @@ -65,9 +65,10 @@ More Options you can find in the extern config.ini File in this Folder ### Installation You can easy install BOSWatch with the install.sh Script. -Download it in any Folder you want. -Make it executeable `sudo chmod +x install.sh` -And use the script `sudo sh install.sh` +- Download the install.sh in any Folder you want. +- Make it executeable `sudo chmod +x install.sh` +- And use the script `sudo sh install.sh` + Now the script downloads and compile all needed data. At the end you can find the Programm in `/home/pi/bos/BOSWatch` From 433e1471488e1d41e256b2d899ceee8086c0830d Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Sat, 4 Apr 2015 14:03:46 +0200 Subject: [PATCH 06/12] edit FMS validation --- boswatch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boswatch.py b/boswatch.py index 393d987..0570f0b 100644 --- a/boswatch.py +++ b/boswatch.py @@ -194,7 +194,7 @@ try: 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-9]{8}[0-9a-f]{1}[01]{1}", fms_id): #if FMS is valid + 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 fms_time_old = timestamp #in case of double alarm, fms_double_ignore_time set new From 5b25e098e7f72c4b11a2636b70cd8d71d5dc9a15 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Sat, 4 Apr 2015 14:34:59 +0200 Subject: [PATCH 07/12] Web Service, Country and Direction parsing --- www/config.php | 2 +- www/index.php | 16 +++++++----- www/parser.php | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 www/parser.php diff --git a/www/config.php b/www/config.php index f0b96e5..e78cee2 100644 --- a/www/config.php +++ b/www/config.php @@ -2,7 +2,7 @@ $dbhost = "localhost"; $dbuser = "root"; -$dbpassword = "root"; +$dbpassword = ""; $database = "boswatch"; $tableFMS = "bos_fms"; diff --git a/www/index.php b/www/index.php index 15a7573..a02cf78 100644 --- a/www/index.php +++ b/www/index.php @@ -1,7 +1,7 @@ @@ -9,34 +9,36 @@ $db_link = mysqli_connect ($dbhost, $dbuser, $dbpassword, $database); BOSWatch + -
+

BOSWatch

Last alarms for FMS and ZVEI (max. 50)

-
+
Last FMS alarms '; + echo ''; while ($data = mysqli_fetch_array( $db_erg, MYSQL_ASSOC)) { + $fms_id = $data['service'].$data['country'].$data['location'].$data['vehicle'].$data['status'].$data['direction']; echo ""; echo ""; echo ""; - echo ""; - echo ""; + echo ""; + echo ""; echo ""; echo ""; echo ""; - echo ""; + echo ""; echo ""; echo ""; } diff --git a/www/parser.php b/www/parser.php new file mode 100644 index 0000000..f74713f --- /dev/null +++ b/www/parser.php @@ -0,0 +1,69 @@ + "Unbekannt", + "1" => "Polizei", + "2" => "Bundesgrenzschutz", + "3" => "Bundeskriminalamt", + "4" => "Katastrophenschutz", + "5" => "Zoll", + "6" => "Feuerwehr", + "7" => "Technisches Hilfswerk", + "8" => "Arbeiter-Samariter-Bund", + "9" => "Deutsches Rotes Kreuz", + "a" => "Johanniter-Unfall-Hilfe", + "b" => "Malteser-Hilfsdienst", + "c" => "Deutsche Lebensrettungsgesellschaft", + "d" => "Rettungsdienst", + "e" => "Zivilschutz", + "f" => "Fernwirktelegramm", + ); + + //Data for Country Parsing + $country = array( + "0" => "Sachsen", + "1" => "Bund", + "2" => "Baden-Württemberg", + "3" => "Bayern I", + "4" => "Berlin", + "5" => "Bremen", + "6" => "Hamburg", + "7" => "Hessen", + "8" => "Niedersachsen", + "9" => "Nordrhein-Westfalen", + "a" => "Rheinland-Pflaz", + "b" => "Schleswig-Holstein", + "c" => "Saarland", + "d" => "Bayern II", + "e" => "Meck-Pom/Sachsen-Anhalt", + "f" => "Brandenburg/Thüringen", + ); + + switch ($mode) { + case "service": + return $service[substr($fms,0,1)]; + break; + + case "country": + return $country[substr($fms,1,1)]; + break; + + case "direction": + if(substr($fms,9,1) == 1){ + return "L-F"; + }elseif(substr($fms,9,1) == 0){ + return "F-L"; + } + break; + + default: + return "Parser: mode error!"; + } + } + +?> \ No newline at end of file From d613e26ec103fcce2b977c1da8bac6da0d6651ed Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Sat, 4 Apr 2015 16:03:32 +0200 Subject: [PATCH 08/12] insert a BOSWatch logo --- .gitignore | 1 + gfx/logo.png | Bin 0 -> 53434 bytes 2 files changed, 1 insertion(+) create mode 100644 .gitignore create mode 100644 gfx/logo.png diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ac7b2b5 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.psd \ No newline at end of file diff --git a/gfx/logo.png b/gfx/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..732f0364f5386e026fa1095f1f09d632dd8dfa4c GIT binary patch literal 53434 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 z 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 N;OXk;vd$@?2>`dbA*=uZ literal 0 HcmV?d00001 From cfaa8229c63e802b30df322c04bd22a4efe87135 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Sat, 4 Apr 2015 16:18:27 +0200 Subject: [PATCH 09/12] logo in Script --- boswatch.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/boswatch.py b/boswatch.py index 0570f0b..9bddc10 100644 --- a/boswatch.py +++ b/boswatch.py @@ -50,13 +50,19 @@ 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("#########################") -print("# #") -print("# BOSWatch beta #") -print("# #") -print("#########################") +print(" ____ ____ ______ __ __ __ ") +print(" / __ )/ __ \/ ___/ | / /___ _/ /______/ /_ b") +print(" / __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ e") +print(" / /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / t") +print(" /_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ a") +print(" German BOS Information Script ") print("") freq = args.freq From 98932c1efeaa9de9d17e2dd617b24ddc0161ccfe Mon Sep 17 00:00:00 2001 From: Schrolli91 Date: Sat, 4 Apr 2015 16:24:54 +0200 Subject: [PATCH 10/12] Update README.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index fb2eb5a..54c27bc 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -# BOSWatch +![# BOSWatch](/gfx/logo.png) + 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! @@ -10,26 +11,25 @@ Python Script to Recive and Decode German BOS Information with rtl_fm and multim - FMS and ZVEI validation (plausibility test) - MySQL Database Support for FMS and ZVEI - All configurations in seperate File "config.ini" -- simple Web Frontend +- simple Web Frontend with Data Parsing #####Features for the Future: - extensive filtering options - POCSAG 512,1200,2400 support (need RAW data from multimon-ng) - automatic Audio recording at alarm -- Web Frontend with configuration +- Web Frontend with Overview and configuration ### Configuration ##### boswatch.py -You can set the ignore time for double alarms in seconds. - -To use the script with MySQL Support, you must edit the "config.ini". -Now set "useMySQL = 1" and the Userdata to your local MySQL Database. +The configuration for the Script you can find in config.ini +- You can set the ignore time for double alarms in seconds. +- To use the script with MySQL Support set "useMySQL = 1" and the Userdata to your local MySQL Database. For the other Functions see "Usage" below. ##### Web Frontend Put the Files in Folder /wwww/ into your local Webserver Folder (/var/www/). -Now you must edit the "config.php" with your Userdata to yout local Database. +Now you must edit the "config.php" with your Userdata to your local Database. ### Usage `sudo python boswatch.py -f 85.235M -a FMS ZVEI -s 50` From a4e7d6f3f6d71788783d307d519141e42b87e67f Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Sat, 4 Apr 2015 19:10:50 +0200 Subject: [PATCH 11/12] directory structure and web-time format --- README.md | 2 +- {gfx => www/gfx}/logo.png | Bin www/index.php | 20 +++++++++++++------- www/parser.php | 4 ++-- 4 files changed, 16 insertions(+), 10 deletions(-) rename {gfx => www/gfx}/logo.png (100%) diff --git a/README.md b/README.md index 54c27bc..836ca18 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![# BOSWatch](/gfx/logo.png) +![# BOSWatch](/www/gfx/logo.png) Python Script to Recive and Decode German BOS Information with rtl_fm and multimon-NG diff --git a/gfx/logo.png b/www/gfx/logo.png similarity index 100% rename from gfx/logo.png rename to www/gfx/logo.png diff --git a/www/index.php b/www/index.php index a02cf78..b962b07 100644 --- a/www/index.php +++ b/www/index.php @@ -15,7 +15,7 @@ $db_link = mysqli_connect ($dbhost, $dbuser, $dbpassword, $database);
-

BOSWatch

+ BOSWatch
Last alarms for FMS and ZVEI (max. 50)

@@ -25,14 +25,17 @@ $db_link = mysqli_connect ($dbhost, $dbuser, $dbpassword, $database); $sql = "SELECT id, time, service, country, location, vehicle, status, direction, tsi FROM ".$tableFMS." ORDER BY id DESC LIMIT 50"; $db_erg = mysqli_query( $db_link, $sql ); - echo '
". $data['id'] . "". $data['time'] . "". $data['service'] . "". $data['country'] . "". parse("service",$fms_id) . "". parse("country",$fms_id) . "". $data['location'] . "". $data['vehicle'] . "". $data['status'] . "". $data['direction'] . "". parse("direction",$fms_id) . "". $data['tsi'] . "
'; while ($data = mysqli_fetch_array( $db_erg, MYSQL_ASSOC)) { + + $time = strtotime($data['time']); + $time = date("d.m.Y H:i:s", $time); + $fms_id = $data['service'].$data['country'].$data['location'].$data['vehicle'].$data['status'].$data['direction']; echo ""; echo ""; - echo ""; + echo ""; echo ""; echo ""; echo ""; @@ -51,14 +54,17 @@ $db_link = mysqli_connect ($dbhost, $dbuser, $dbpassword, $database); '; while ($data = mysqli_fetch_array( $db_erg, MYSQL_ASSOC)) { - echo ""; + + $time = strtotime($data['time']); + $time = date("d.m.Y H:i:s", $time); + + echo ""; echo ""; - echo ""; + echo ""; echo ""; echo ""; } diff --git a/www/parser.php b/www/parser.php index f74713f..e1242ad 100644 --- a/www/parser.php +++ b/www/parser.php @@ -55,9 +55,9 @@ case "direction": if(substr($fms,9,1) == 1){ - return "L-F"; + return "L->F"; }elseif(substr($fms,9,1) == 0){ - return "F-L"; + return "F->L"; } break; From 7dd61db384f42f099f6e8ee2770490e3349a4c12 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Sat, 4 Apr 2015 19:21:42 +0200 Subject: [PATCH 12/12] prepared config.ini for module support --- README.md | 3 ++- boswatch.py | 4 +++- config.ini | 32 ++++++++++++++++++-------------- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 836ca18..813b208 100644 --- a/README.md +++ b/README.md @@ -82,4 +82,5 @@ At the end you can find the Programm in `/home/pi/bos/BOSWatch` - MySQL Database Server Thanks to smith_fms and McBo from [Funkmeldesystem.de - Forum](http://www.funkmeldesystem.de/) for Inspiration and Groundwork! -Greetz Schrolli + +######Greetz Schrolli diff --git a/boswatch.py b/boswatch.py index 9bddc10..824d95a 100644 --- a/boswatch.py +++ b/boswatch.py @@ -3,6 +3,7 @@ ##### Info ##### # BOSWatch +# Autor: Bastian Schroll # Python Script to Recive and Decode German BOS Information with rtl_fm and multimon-NG # For more Information see the README.md ##### Info ##### @@ -63,6 +64,7 @@ print(" / __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ e") print(" / /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / t") print(" /_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ a") print(" German BOS Information Script ") +print(" by Bastian Schroll ") print("") freq = args.freq @@ -113,7 +115,7 @@ try: zvei_double_ignore_time = int(config.get("ZVEI", "double_ignore_time")) #MySQL config - useMySQL = int(config.get("MySQL", "useMySQL")) #use MySQL support? + useMySQL = int(config.get("Module", "useMySQL")) #use MySQL support? if useMySQL: #only if MySQL is active dbserver = config.get("MySQL", "dbserver") dbuser = config.get("MySQL", "dbuser") diff --git a/config.ini b/config.ini index 9cf5251..561ddf8 100644 --- a/config.ini +++ b/config.ini @@ -2,23 +2,27 @@ # BOSWatch Config File # ######################## -#Data for MySQL connection -#useMySQL = (0|1) -[MySQL] -useMySQL = 0 -dbserver = localhost -dbuser = root -dbpassword = root -database = boswatch - -tableFMS = bos_fms -tableZVEI = bos_zvei -tablePOC = bos_pocsag - [FMS] #time to ignore same alarm in a row in seconds double_ignore_time = 10 [ZVEI] #time to ignore same alarm in a row in seconds -double_ignore_time = 5 \ No newline at end of file +double_ignore_time = 5 + +#can take on or off the modules (0|1) +[Module] +useMySQL = 0 +#useAudiorecord = 0 +#useHTTPrequest = 0 + +#Data for MySQL connection +[MySQL] +dbserver = localhost +dbuser = root +dbpassword = root +database = boswatch + +tableFMS = bos_fms +tableZVEI = bos_zvei +tablePOC = bos_pocsag \ No newline at end of file
". $data['id'] . "". $data['time'] . "". $time . "". parse("service",$fms_id) . "". parse("country",$fms_id) . "". $data['location'] . "
". $data['id'] . "". $data['time'] . "". $time . "". $data['zvei'] . "