diff --git a/boswatch/wildcard.py b/boswatch/wildcard.py
index 91f2fea..3519502 100644
--- a/boswatch/wildcard.py
+++ b/boswatch/wildcard.py
@@ -65,8 +65,8 @@ def replaceWildcards(message, bwPacket):
"{CBRCH}": bwPacket.get("clientBranch"),
# boswatch wildcards
- "{INSRC}": bwPacket.get("mode"),
- "{TIMES}": bwPacket.get("mode"),
+ "{INSRC}": bwPacket.get("inputSource"),
+ "{TIMES}": bwPacket.get("timestamp"),
"{FREQ}": bwPacket.get("frequency"),
"{MODE}": bwPacket.get("mode"),
@@ -78,7 +78,7 @@ def replaceWildcards(message, bwPacket):
"{VEHC}": bwPacket.get("vehicle"),
"{STAT}": bwPacket.get("status"),
"{DIR}": bwPacket.get("direction"),
- "{DIRT}": bwPacket.get("dirextionText"),
+ "{DIRT}": bwPacket.get("directionText"),
"{TACI}": bwPacket.get("tacticalInfo"),
# pocsag wildcards
@@ -99,6 +99,6 @@ def replaceWildcards(message, bwPacket):
for wildcard, field in _additionalWildcards.items():
if field is not None:
- message = message.replace(wildcard, bwPacket.getField(field))
+ message = message.replace(wildcard, bwPacket.get(field))
return message
diff --git a/docu/docs/develop/packet.md b/docu/docs/develop/packet.md
index 14d2e88..e67de83 100644
--- a/docu/docs/develop/packet.md
+++ b/docu/docs/develop/packet.md
@@ -47,5 +47,5 @@ Ein BOSWatch Datenpaket wird in einem Python Dict abgebildet. In der nachfolgend
|vehicle|X||||`{VEC}`||
|status|X||||`{STAT}`||
|direction|X||||`{DIR}`||
-|dirextionText|X||||`{DIRT}`|(Fhz->Lst, Lst->Fhz)|
+|directionText|X||||`{DIRT}`|(Fhz->Lst, Lst->Fhz)|
|tacticalInfo|X||||`{TACI}`|(I, II, III, IV)|
diff --git a/docu/docs/modul/geocoding.md b/docu/docs/modul/geocoding.md
new file mode 100644
index 0000000..0acf43e
--- /dev/null
+++ b/docu/docs/modul/geocoding.md
@@ -0,0 +1,59 @@
+#
Geocoding
+---
+
+## Beschreibung
+Mit diesem Modul können einem Paket die Koordinaten eines Ortes oder einer Adresse angefügt werden.
+
+## Externe Abhängigkeiten
+- geocoder
+
+## Unterstützte Alarmtypen
+- Pocsag
+
+## Resource
+`geocoding`
+
+## Konfiguration
+
+|Feld|Beschreibung|Default|
+|----|------------|-------|
+apiProvider|Der Provider für das Geocoding|
+apiToken|Der Api-Token fuer die Geocoding-Api|
+geoRegex|Regex Capture-Group zum Herausfiltern der Adresse|
+
+#### Verfügbare Geocoding Provider
+
+|Name|Einstellungswert|
+|----|------------|
+|Mapbox|mapbox|
+|Google Maps|google|
+
+**Beispiel:**
+```yaml
+ - type: module
+ name: Geocoding Module
+ res: geocoding
+ config:
+ apiProvider: "{{ Provider für Geocoding }}"
+ apiToken: "{{ API-Key für Provider }}"
+ regex: "((?:[^ ]*,)*?)"
+```
+
+---
+## Abhängigkeiten
+
+- keine
+
+---
+## Paket Modifikationen
+
+- `address`: gefundene Adresse
+- `lat`: Latitude der Adresse
+- `lon`: Longitude der Adresse
+
+---
+## Zusätzliche Wildcards
+
+- `{ADDRESS}`: gefundene Adresse
+- `{LAT}`: Latitude der Adresse
+- `{LON}`: Longitude der Adresse
\ No newline at end of file
diff --git a/docu/docs/plugin/telegram.md b/docu/docs/plugin/telegram.md
new file mode 100644
index 0000000..3003bbe
--- /dev/null
+++ b/docu/docs/plugin/telegram.md
@@ -0,0 +1,42 @@
+# Telegram
+---
+
+## Beschreibung
+Mit diesem Plugin ist es moeglich, Telegram-Nachrichten für POCSAG-Alarmierungen zu senden.
+Außerdem werden Locations versenden, wenn die Felder `lat` und `lon` im Paket definiert sind. (beispielsweise durch das Geocoding-Modul)
+
+## Externe Abhängigkeiten
+- python-telegram-bot
+
+## Unterstütze Alarmtypen
+- Pocsag
+
+## Resource
+`telegram`
+
+## Konfiguration
+
+|Feld|Beschreibung|Default|
+|----|------------|-------|
+|message|Format der Nachricht||
+|botToken|Der Api-Key des Telegram-Bots||
+|chatIds|Liste mit Chat-Ids der Empfängers / der Emfänger-Gruppen||
+
+**Beispiel:**
+```yaml
+ - type: plugin
+ name: Telegram Plugin
+ res: telegram
+ config:
+ message: "{RIC}({SRIC})\n{MSG}"
+ botToken: "{{ Telegram Bot Token }}"
+ chatIds:
+ - "{{ Telegram Chat Id }}"
+```
+
+---
+## Abhängigkeiten
+
+- Modul geocoding (Falls in Paket vorhanden):
+ - `lat`
+ - `lon`
diff --git a/docu/mkdocs.yml b/docu/mkdocs.yml
index 611cbfe..2a9d54b 100644
--- a/docu/mkdocs.yml
+++ b/docu/mkdocs.yml
@@ -18,11 +18,13 @@ nav:
- Routing Mechanismus: information/router.md
- Changelog: changelog.md
- Module:
+ - Descriptor: modul/descriptor.md
+ - Geocoding: modul/geocoding.md
- Mode Filter: modul/mode_filter.md
- Regex Filter: modul/regex_filter.md
- - Descriptor: modul/descriptor.md
- Plugins:
- Http: plugin/http.md
+ - Telegram: plugin/telegram.md
- Entwickler:
- Eigenes Modul/Plugin schreiben: develop/ModulPlugin.md
- BOSWatch Alarmpaket Format: develop/packet.md
diff --git a/module/geocoding.py b/module/geocoding.py
new file mode 100644
index 0000000..572bc0d
--- /dev/null
+++ b/module/geocoding.py
@@ -0,0 +1,80 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+"""!
+ ____ ____ ______ __ __ __ _____
+ / __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ /
+ / __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ /_ <
+ / /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ /
+/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/
+ German BOS Information Script
+ by Bastian Schroll
+
+@file: geocoding.py
+@date: 22.02.2020
+@author: Jan Speller
+@description: Geocoding Module
+"""
+import logging
+from module.moduleBase import ModuleBase
+
+# ###################### #
+# Custom plugin includes #
+import geocoder
+import re
+# ###################### #
+
+logging.debug("- %s loaded", __name__)
+
+
+class BoswatchModule(ModuleBase):
+ """!Description of the Module"""
+ def __init__(self, config):
+ """!Do not change anything here!"""
+ super().__init__(__name__, config) # you can access the config class on 'self.config'
+
+ def doWork(self, bwPacket):
+ """!start an run of the module.
+
+ @param bwPacket: A BOSWatch packet instance"""
+ if bwPacket.get("mode") == "pocsag":
+ self.geocode(bwPacket)
+
+ return bwPacket
+
+ def geocode(self, bwPacket):
+ """!find address in message and get latitude and longitude
+
+ @param bwPacket: A BOSWatch packet instance"""
+ try:
+ addressArray = re.search(self.config.get("regex"), bwPacket.get("message"))
+ provider = self.config.get("apiProvider")
+
+ if addressArray[1] is None:
+ logging.info("No address found, skipping geocoding")
+ return bwPacket
+
+ address = addressArray[1]
+ bwPacket.set("address", address)
+ self.registerWildcard("{ADDRESS}", "address")
+ logging.info("Found address: '" + address + "' in packet")
+
+ if "mapbox" == provider:
+ logging.info("Using Mapbox as provider")
+ g = geocoder.mapbox(address, key=self.config.get("apiToken"))
+ elif "google" == provider:
+ logging.info("Using Google as provider")
+ g = geocoder.google(address, key=self.config.get("apiToken"))
+ else:
+ return bwPacket
+
+ (lat, lon) = g.latlng
+ logging.info("Found following coordinates for address: [lat=" + str(lat) + ", lon=" + str(lon) + "]")
+ bwPacket.set("lat", lat)
+ bwPacket.set("lon", lon)
+ self.registerWildcard("{LAT}", "lat")
+ self.registerWildcard("{LON}", "lon")
+
+ return bwPacket
+ except Exception as e:
+ logging.exception("Unknown Error while executing geocoding module: " + str(type(e).__name__) + ": " + str(e))
+ return bwPacket
diff --git a/plugin/telegram.py b/plugin/telegram.py
new file mode 100644
index 0000000..80ff9e7
--- /dev/null
+++ b/plugin/telegram.py
@@ -0,0 +1,66 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+"""!
+ ____ ____ ______ __ __ __ _____
+ / __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ /
+ / __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ /_ <
+ / /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ /
+/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/
+ German BOS Information Script
+ by Bastian Schroll
+
+@file: telegram.py
+@date: 20.02.2020
+@author: Jan Speller
+@description: Telegram Plugin
+"""
+import logging
+from plugin.pluginBase import PluginBase
+
+# ###################### #
+# Custom plugin includes #
+from telegram.error import (TelegramError, Unauthorized, BadRequest, TimedOut, NetworkError)
+import telegram
+# ###################### #
+
+logging.debug("- %s loaded", __name__)
+
+
+class BoswatchPlugin(PluginBase):
+ """!Description of the Plugin"""
+
+ def __init__(self, config):
+ """!Do not change anything here!"""
+ super().__init__(__name__, config) # you can access the config class on 'self.config'
+
+ def onLoad(self):
+ """!Called by import of the plugin"""
+ self.bot = telegram.Bot(token=self.config.get("botToken", default=""))
+
+ def pocsag(self, bwPacket):
+ """!Called on POCSAG alarm
+
+ @param bwPacket: bwPacket instance"""
+ msg = self.parseWildcards(self.config.get("message"))
+ if bwPacket.get("lat") is not None and bwPacket.get("lon") is not None:
+ logging.debug("Found coordinates in packet")
+ (lat, lon) = (bwPacket.get("lat"), bwPacket.get("lon"))
+
+ for chatId in self.config.get("chatIds", default=[]):
+ try:
+ # Send Message via Telegram
+ logging.info("Sending message to " + chatId)
+ self.bot.send_message(chat_id=chatId, text=msg)
+
+ # Send Location via Telegram if lat and lon are defined
+ if lat is not None and lon is not None:
+ logging.info("Sending location to " + chatId)
+ self.bot.sendLocation(chat_id=chatId, latitude=lat, longitude=lon)
+ except Unauthorized:
+ logging.exception("Error while sending Telegram Message, please Check your api-key")
+ except (TimedOut, NetworkError):
+ logging.exception("Error while sending Telegram Message, please Check your connectivity")
+ except (BadRequest, TelegramError):
+ logging.exception("Error while sending Telegram Message")
+ except Exception as e:
+ logging.exception("Unknown Error while sending Telegram Message: " + str(type(e).__name__) + ": " + str(e))