diff --git a/.gitignore b/.gitignore index 3b70e903..f37fd5c5 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ log/ \.pydevproject \.settings/ + +\.idea/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 447246f5..9530fae5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,20 @@ # Changelog +### __[v2.4]__ - 17.08.2018 +##### Added +- Config Eintrag um Port für MySQL Plugin festzulegen [#345](https://github.com/Schrolli91/BOSWatch/pull/345) +- FMS und ZVEI Support für Pushover Plugin [#352](https://github.com/Schrolli91/BOSWatch/pull/352) +- Benutzerdefinierte Nachrichten für Pushover Plugin in config [#352](https://github.com/Schrolli91/BOSWatch/pull/352) +##### Changed +- multicastAlarm Plugin - RICs die von multicastAlarm genutzt werden, müssen nicht mehr in der config bei allow_ric bzw. filter_range_start/filter_range_end berücksichtigt werden. [#357](https://github.com/Schrolli91/BOSWatch/pull/357) +- FFAgent Plugin - Debug Logging für die alarmHeaders eingebaut zwecks Troubleshooting [#354](https://github.com/Schrolli91/BOSWatch/pull/354) +- multicastAlarm Plugin - Buffer nach jedem Alarm löschen - erlaubt in kombination mit "doubleFilter_check_msg" die Verwendung in Netzen, die zwischen multicastAlarm RICs auch normale Alarme senden. #370(https://github.com/Schrolli91/BOSWatch/pull/370) +##### Fixed +- Fehler beim Auslesen der netIdent_RIC im MySQL Plugin [#347](https://github.com/Schrolli91/BOSWatch/pull/347) +- FFAgent Plugin - Typo bei alarmHeaders für Live Betrieb gefixt [#354](https://github.com/Schrolli91/BOSWatch/pull/354) + -### __[2.3]__ - 22.12.2017 +### __[v2.3]__ - 22.12.2017 ##### Added - zuschaltbare POCSAG Multicast-Alarm Funktionalität [#307](https://github.com/Schrolli91/BOSWatch/pull/307) - Flag in Config um nur letzte Net Ident oder gesamte Historie zu speichern [#317](https://github.com/Schrolli91/BOSWatch/pull/317) @@ -48,7 +61,7 @@ Zum schreiben des Changelog's siehe: http://keepachangelog.com/de/1.0.0/ -### __[version]__ - date +### __[v#.#]__ - date ##### Added ##### Changed ##### Deprecated diff --git a/citest/config.httpRequest.ini b/citest/config.httpRequest.ini index 665a66e0..512070ab 100644 --- a/citest/config.httpRequest.ini +++ b/citest/config.httpRequest.ini @@ -174,8 +174,10 @@ template = 0 [MySQL] # MySQL configuration +#default port: 3306 dbserver = localhost -dbuser = root +dbport = 3306 +dbuser = boswatch dbpassword = root database = boswatch diff --git a/citest/config.mysql.ini b/citest/config.mysql.ini index 317d3d91..bad62e6b 100644 --- a/citest/config.mysql.ini +++ b/citest/config.mysql.ini @@ -174,7 +174,9 @@ template = 0 [MySQL] # MySQL configuration +#default port: 3306 dbserver = localhost +dbport = 3306 dbuser = boswatch dbpassword = root database = boswatch diff --git a/config/config.template.ini b/config/config.template.ini index bbb6e95f..11a6caf3 100644 --- a/config/config.template.ini +++ b/config/config.template.ini @@ -144,7 +144,7 @@ multicastAlarm = 0 # time limit for alarms that do not belong to the multicastAlarm sequence in seconds multicastAlarm_ignore_time = 15 -# multicastAlarm delimiter RIC (usually used as a starting point for a alarm sequence) (can be empty) +# multicastAlarm delimiter RIC (usually used as a starting point for a alarm sequence). Needs to be empty if multicastAlarms are interrupted by normal alarms. multicastAlarm_delimiter_ric = # multicastAlarm RIC that is used to send the text message @@ -191,7 +191,9 @@ template = 0 [MySQL] # MySQL configuration +#default port: 3306 dbserver = localhost +dbport = 3306 dbuser = boswatch dbpassword = root database = boswatch @@ -375,14 +377,24 @@ api_key = # Pushover Userkey or Groupkey to receive message user_key = -# Title of the message -title = BOSWatch Message - +# Section for POCSAG # Adapt Pocsag Subric (a,b,c,d) to Pushover Priorities (see https://pushover.net/api#priority) -SubA = 0 -SubB = 2 -SubC = 1 -SubD = 0 +SubA = 1 +SubB = 1 +SubC = 2 +SubD = -2 +poc_title = Alarm: %RIC%%LPAR%%FUNCCHAR%%RPAR% +poc_message = %DATE% %TIME% - %DESCR%: %MSG% + +# Section for ZVEI +zvei_prio = 1 +zvei_title = Alarm: %ZVEI% +zvei_message = %DATE% %TIME%: %ZVEI% + +# Section for FMS +fms_prio = 1 +fms_title = FMS: %FMS% +fms_message = %DATE% %TIME%: %FMS%%BR%Status: %STATUS% - Direction: %DIRT% - TSI: %TSI% %LPAR%%DESCR%%RPAR% # how often should Pushover re-alert in seconds (emergency-messages) retry = 30 @@ -474,6 +486,7 @@ test2 = 123456 # %RIC% = POCSAG RIC # %FUNC% = POCSAG function/Subric (1-4) # %FUNCCHAR% = POCSAG function/Subric als character (a-d) +# %FUNCTEXT% = POCSAG static Subric message (see [POC]) # %MSG% = Message of the POCSAG telegram # %BITRATE% = Bitrate of the POCSAG telegram # %DESCR% = Description, if description-module is used diff --git a/exampleAddOns/simpleWeb/mysql.class.php b/exampleAddOns/simpleWeb/mysql.class.php index 69d5fbdb..a74b4b6e 100644 --- a/exampleAddOns/simpleWeb/mysql.class.php +++ b/exampleAddOns/simpleWeb/mysql.class.php @@ -23,16 +23,16 @@ function __construct($host, $user, $password, $database, $show_error = 1) { $this->show_error = $show_error; - @$this->conn = mysql_connect($host, $user, $password); + @$this->conn = mysqli_connect($host, $user, $password); if ($this->conn == false) { - $this->error("Keine Verbindung zum Datenbank Server!", mysql_error()); + $this->error("Keine Verbindung zum Datenbank Server!", mysqli_error($this->conn)); return false; } - if (!@mysql_select_db($database, $this->conn)) + if (!@mysqli_select_db($this->conn, $database)) { - $this->error("Datenbank nicht gefunden!", mysql_error()); + $this->error("Datenbank nicht gefunden!", mysqli_error($this->conn)); return false; } return true; @@ -41,17 +41,17 @@ function __construct($host, $user, $password, $database, $show_error = 1) /** * Database::query() * - * F�hrt einen MySQL Query aus + * Fuehrt einen MySQL Query aus * - * @param mixed $query Auszuf�hrender Query + * @param mixed $query Auszufuehrender Query * @return Result-Handler/FALSE */ function query($query) { - $this->result = @mysql_query($query, $this->conn); + $this->result = @mysqli_query($this->conn, $query); if ($this->result == false) { - $this->error("Fehlerhafte Datenbank Anfrage!", mysql_error()); + $this->error("Fehlerhafte Datenbank Anfrage!", mysqli_error($this->conn)); return false; } return $this->result; @@ -60,51 +60,51 @@ function query($query) /** * Database::fetchAssoc() * - * Liefert alle gefundnen Datens�tze als Assoc + * Liefert alle gefundnen Datensaetze als Assoc * * @param mixed $result Externer Result-Handler - * @return gefundene Datens�tze als Assoc + * @return gefundene Datensaetze als Assoc */ function fetchAssoc($result = null) { if ($result != null) { - return @mysql_fetch_assoc($result); + return @mysqli_fetch_assoc($result); } else { - return @mysql_fetch_assoc($this->result); + return @mysqli_fetch_assoc($this->result); } } /** * Database::count() * - * Z�hlt alle gefundenen Datens�tze + * Zaehlt alle gefundenen Datensaetze * * @param mixed $result Externer Result-Handler - * @return Anzahl gefundener Datens�tze + * @return Anzahl gefundener Datensaetze */ function count($result = null) { if ($result != null) { - return @mysql_num_rows($result); + return @mysqli_num_rows($result); } else { - return @mysql_num_rows($this->result); + return @mysqli_num_rows($this->result); } } /** * Database::closeConnection() * - * Schlie�t die bestehende MySQL Verbindung + * Schliesst die bestehende MySQL Verbindung * * @return TRUE/FALSE */ function closeConnection() { - if (!@mysql_close($this->conn)) + if (!@mysqli_close($this->conn)) { $this->error("Verbindung zur Datenbank konnte nicht getrennt werden!", mysql_error()); return false; diff --git a/includes/decoders/poc.py b/includes/decoders/poc.py index da863186..30a0e22e 100644 --- a/includes/decoders/poc.py +++ b/includes/decoders/poc.py @@ -62,11 +62,23 @@ def isAllowed(poc_id): return True else: allowed = 0 + # 5.) Implementation for multicastAlarm + if globalVars.config.get("multicastAlarm", "multicastAlarm_delimiter_ric"): + if poc_id in globalVars.config.get("multicastAlarm", "multicastAlarm_delimiter_ric"): + logging.info("RIC %s as multicastAlarm delimiter", poc_id) + return True + else: + allowed = 0 + if globalVars.config.get("multicastAlarm", "multicastAlarm_ric"): + if poc_id in globalVars.config.get("multicastAlarm", "multicastAlarm_ric"): + logging.info("RIC %s as multicastAlarm message", poc_id) + return True + else: + allowed = 0 if allowed == 0: return False return True - ## # # POCSAG decoder function diff --git a/includes/globalVars.py b/includes/globalVars.py index 23f9377c..a809c195 100644 --- a/includes/globalVars.py +++ b/includes/globalVars.py @@ -9,9 +9,9 @@ """ # version info -versionNr = "2.3" +versionNr = "2.4" branch = "master" -buildDate = "22/12/2017" +buildDate = "17.08.2018" # Global variables diff --git a/includes/multicastAlarm.py b/includes/multicastAlarm.py index 40a83443..8aafadd0 100644 --- a/includes/multicastAlarm.py +++ b/includes/multicastAlarm.py @@ -29,7 +29,7 @@ def newEntrymultiList(data): timestamp = int(time.time()) # multicastAlarm processing if enabled and delimiter RIC has been received if data['ric'] == globalVars.config.get("multicastAlarm", "multicastAlarm_delimiter_ric"): - multiList = [] + del multiList[:] logging.debug("delimiter RIC received - buffer cleared") else: multiList.append([data, timestamp]) @@ -61,3 +61,5 @@ def multicastAlarmExec(freq, data): except: logging.error("processing alarm failed") logging.debug("processing alarm failed", exc_info=True) + del multiList[:] + logging.debug("multicastAlarm finished - buffer cleared") diff --git a/plugins/FFAgent/FFAgent.py b/plugins/FFAgent/FFAgent.py index 8dcff856..561ca869 100644 --- a/plugins/FFAgent/FFAgent.py +++ b/plugins/FFAgent/FFAgent.py @@ -132,9 +132,10 @@ def run(typ,freq,data): "selectiveCallCode": selectiveCallCode, "hmac": hmac.new(webApiKey, webApiToken + selectiveCallCode + accessToken + alarmData, digestmod=hashlib.sha256).hexdigest() } + logging.debug(alarmHeaders) if globalVars.config.get("FFAgent", "live") == "1": - r = requests.post(url, data=alarmData, headers=headers, verify=serverCertFile, cert=(clientCertFile, clientCertPass)) + r = requests.post(url, data=alarmData, headers=alarmHeaders, verify=serverCertFile, cert=(clientCertFile, clientCertPass)) else: r = requests.post(url, data=alarmData, headers=alarmHeaders, verify=serverCertFile) diff --git a/plugins/MySQL/MySQL.py b/plugins/MySQL/MySQL.py index 3d4db163..c38410f1 100644 --- a/plugins/MySQL/MySQL.py +++ b/plugins/MySQL/MySQL.py @@ -91,7 +91,7 @@ def run(typ,freq,data): # Connect to MySQL # logging.debug("connect to MySQL") - connection = mysql.connector.connect(host = globalVars.config.get("MySQL","dbserver"), user = globalVars.config.get("MySQL","dbuser"), passwd = globalVars.config.get("MySQL","dbpassword"), db = globalVars.config.get("MySQL","database"), charset='utf8') + connection = mysql.connector.connect(host = globalVars.config.get("MySQL","dbserver"), port = globalVars.config.get("MySQL","dbport"), user = globalVars.config.get("MySQL","dbuser"), passwd = globalVars.config.get("MySQL","dbpassword"), db = globalVars.config.get("MySQL","database"), charset='utf8') cursor = connection.cursor() except: logging.error("cannot connect to MySQL") @@ -111,7 +111,7 @@ def run(typ,freq,data): elif typ == "POC": if isSignal(data["ric"]): - if globalVars.config.getint("POC","netIdent_histry"): + if globalVars.config.getint("POC","netIdent_history"): cursor.execute("INSERT INTO "+globalVars.config.get("MySQL","tableSIG")+" (time,ric) VALUES (NOW(), '"+data["ric"]+"');") else: cursor.execute("UPDATE "+globalVars.config.get("MySQL","tableSIG")+" SET time = NOW() WHERE ric = '"+data["ric"]+"';") diff --git a/plugins/Pushover/Pushover.py b/plugins/Pushover/Pushover.py index 1f97c956..d220de6e 100644 --- a/plugins/Pushover/Pushover.py +++ b/plugins/Pushover/Pushover.py @@ -9,13 +9,15 @@ @requires: Pushover-Configuration has to be set in the config.ini """ -import logging # Global logger -import httplib #for the HTTP request +import logging # Global logger +import httplib # for the HTTP request import urllib from includes import globalVars # Global variables -#from includes.helper import timeHandler +# from includes.helper import timeHandler from includes.helper import configHandler +from includes.helper import wildcardHandler + ## # @@ -23,16 +25,16 @@ # will be called one time by the pluginLoader on start # def onLoad(): - """ - While loading the plugins by pluginLoader.loadPlugins() - this onLoad() routine is called one time for initialize the plugin + """ + While loading the plugins by pluginLoader.loadPlugins() + this onLoad() routine is called one time for initialize the plugin - @requires: nothing + @requires: nothing - @return: nothing - """ - # nothing to do for this plugin - return + @return: nothing + """ + # nothing to do for this plugin + return ## @@ -40,82 +42,112 @@ def onLoad(): # Main function of Pushover-plugin # will be called by the alarmHandler # -def run(typ,freq,data): - """ - This function is the implementation of the Pushover-Plugin. - It will send the data to Pushover API - - @type typ: string (FMS|ZVEI|POC) - @param typ: Typ of the dataset - @type data: map of data (structure see readme.md in plugin folder) - @param data: Contains the parameter - @type freq: string - @keyword freq: frequency of the SDR Stick - - @requires: Pushover-Configuration has to be set in the config.ini - - @return: nothing - """ - try: - if configHandler.checkConfig("Pushover"): #read and debug the config - - try: - # - # Pushover-Request - # - logging.debug("send Pushover %s", typ) - - if data["function"] == '1': - priority = globalVars.config.get("Pushover", "SubA") - elif data["function"] == '2': - priority = globalVars.config.get("Pushover", "SubB") - elif data["function"] == '3': - priority = globalVars.config.get("Pushover", "SubC") - elif data["function"] == '4': - priority = globalVars.config.get("Pushover", "SubD") - else: - priority = 0 - - conn = httplib.HTTPSConnection("api.pushover.net:443") - conn.request("POST", "/1/messages.json", - urllib.urlencode({ - "token": globalVars.config.get("Pushover", "api_key"), - "user": globalVars.config.get("Pushover", "user_key"), - "message": ""+data["description"]+"
"+data["msg"].replace(";", "
"), - "html": globalVars.config.get("Pushover", "html"), - "title": globalVars.config.get("Pushover", "title"), - "priority": priority, - "retry": globalVars.config.get("Pushover", "retry"), - "expire": globalVars.config.get("Pushover", "expire") - }),{"Content-type": "application/x-www-form-urlencoded"}) - - except: - logging.error("cannot send Pushover request") - logging.debug("cannot send Pushover request", exc_info=True) - return - - else: - try: - # - # check Pushover-Response - # - response = conn.getresponse() - if str(response.status) == "200": #Check Pushover Response and print a Log or Error - logging.debug("Pushover response: %s - %s" , str(response.status), str(response.reason)) - else: - logging.warning("Pushover response: %s - %s" , str(response.status), str(response.reason)) - except: #otherwise - logging.error("cannot get Pushover response") - logging.debug("cannot get Pushover response", exc_info=True) - return - - finally: - logging.debug("close Pushover-Connection") - try: - request.close() - except: - pass - - except: - logging.error("unknown error") - logging.debug("unknown error", exc_info=True) +def run(typ, freq, data): + """ + This function is the implementation of the Pushover-Plugin. + It will send the data to Pushover API + + @type typ: string (FMS|ZVEI|POC) + @param typ: Typ of the dataset + @type data: map of data (structure see readme.md in plugin folder) + @param data: Contains the parameter + @type freq: string + @keyword freq: frequency of the SDR Stick + + @requires: Pushover-Configuration has to be set in the config.ini + + @return: nothing + """ + try: + if configHandler.checkConfig("Pushover"): # read and debug the config + + if typ == "FMS": + # + # building message for FMS + # + + message = globalVars.config.get("Pushover", "fms_message") + title = globalVars.config.get("Pushover", "fms_title") + priority = globalVars.config.get("Pushover", "fms_prio") + logging.debug("Sending message: %s", message) + + elif typ == "ZVEI": + # + # building message for ZVEI + # + message = globalVars.config.get("Pushover", "zvei_message") + title = globalVars.config.get("Pushover", "zvei_title") + priority = globalVars.config.get("Pushover", "zvei_prio") + logging.debug("Sending message: %s", message) + + elif typ == "POC": + + # + # Pushover-Request + # + logging.debug("send Pushover for %s", typ) + + if data["function"] == '1': + priority = globalVars.config.get("Pushover", "SubA") + elif data["function"] == '2': + priority = globalVars.config.get("Pushover", "SubB") + elif data["function"] == '3': + priority = globalVars.config.get("Pushover", "SubC") + elif data["function"] == '4': + priority = globalVars.config.get("Pushover", "SubD") + else: + priority = 0 + message = globalVars.config.get("Pushover", "poc_message") + title = globalVars.config.get("Pushover", "poc_title") + + else: + logging.warning("Invalid type: %s", typ) + + try: + # replace the wildcards + message = wildcardHandler.replaceWildcards(message, data) + title = wildcardHandler.replaceWildcards(title, data) + + # start the connection + conn = httplib.HTTPSConnection("api.pushover.net:443") + conn.request("POST", "/1/messages.json", + urllib.urlencode({ + "token": globalVars.config.get("Pushover", "api_key"), + "user": globalVars.config.get("Pushover", "user_key"), + "message": message, + "html": globalVars.config.get("Pushover", "html"), + "title": title, + "priority": priority, + "retry": globalVars.config.get("Pushover", "retry"), + "expire": globalVars.config.get("Pushover", "expire") + }), {"Content-type": "application/x-www-form-urlencoded"}) + + except: + logging.error("cannot send Pushover request") + logging.debug("cannot send Pushover request", exc_info=True) + return + + try: + # + # check Pushover-Response + # + response = conn.getresponse() + if str(response.status) == "200": # Check Pushover Response and print a Log or Error + logging.debug("Pushover response: %s - %s", str(response.status), str(response.reason)) + else: + logging.warning("Pushover response: %s - %s", str(response.status), str(response.reason)) + except: # otherwise + logging.error("cannot get Pushover response") + logging.debug("cannot get Pushover response", exc_info=True) + return + + finally: + logging.debug("close Pushover-Connection") + try: + request.close() + except: + pass + + except: + logging.error("unknown error") + logging.debug("unknown error", exc_info=True)