diff --git a/CHANGELOG.md b/CHANGELOG.md index d9fe7003..08e102b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,9 @@ # Changelog + ### __[2.x]__ - unreleased ##### Added +- Plugin zur automatischen Audio Aufnahme bei Alarm (ZVEI) [#327](https://github.com/Schrolli91/BOSWatch/pull/327) ##### Changed ##### Deprecated ##### Removed diff --git a/boswatch.py b/boswatch.py old mode 100755 new mode 100644 index df1e5e6d..681e41b0 --- a/boswatch.py +++ b/boswatch.py @@ -57,6 +57,7 @@ parser.add_argument("-u", "--usevarlog", help="Use '/var/log/boswatch' for logfiles instead of subdir 'log' in BOSWatch directory", action="store_true") parser.add_argument("-v", "--verbose", help="Show more information", action="store_true") parser.add_argument("-q", "--quiet", help="Show no information. Only logfiles", action="store_true") + # We need this argument for testing (skip instantiate of rtl-fm and multimon-ng): parser.add_argument("-t", "--test", help=argparse.SUPPRESS, action="store_true") args = parser.parse_args() @@ -166,6 +167,7 @@ logging.debug("Branch: %s",globalVars.branch) logging.debug("Build Date: %s",globalVars.buildDate) logging.debug("Python Vers: %s",sys.version) + logging.debug("BOSWatch given arguments") if args.test: logging.debug(" - Test-Mode!") @@ -335,9 +337,40 @@ logging.debug("cannot start rtl_fm", exc_info=True) exit(1) + #duplicate rtl_fm stdout for the record plugin and multimon-ng + pipe_r, pipe_w = os.pipe() + tee = subprocess.Popen(["tee", "/dev/fd/{}".format(pipe_w)], + stdin=rtl_fm.stdout, stdout=subprocess.PIPE) + + + # + # Start audioplaybackstream for the record plugin + # + if (globalVars.config.get("Plugins", "record") == "1"): + try: + if not args.test: + logging.debug("starting playbackaudiostream") + command = "" + command = "aplay -t raw -r 22050 -D pulse -f S16_LE /dev/stdin" + playbackstream = subprocess.Popen(command.split(), + stdin=tee.stdout, + stdout=subprocess.PIPE, + stderr=open(globalVars.log_path+"playbackstream.log","a"), + shell=False) + time.sleep(3) + else: + logging.warning("!!! Test-Mode: !!! Playbackstream not started !!!") + except: + logging.critical("cannot start playbackstream") + logging.debug("cannot start playbackstream", exc_info=True) + exit(1) + else: + logging.debug("record plugin not activated. activate it in the config.ini") + # # Start multimon # + try: if not args.test: logging.debug("starting multimon-ng") @@ -346,7 +379,7 @@ command = globalVars.config.get("BOSWatch","multimon_path") command = command+"multimon-ng "+str(demodulation)+" -f alpha -t raw /dev/stdin - " multimon_ng = subprocess.Popen(command.split(), - stdin=rtl_fm.stdout, + stdin=pipe_r, stdout=subprocess.PIPE, stderr=open(globalVars.log_path+"multimon.log","a"), shell=False) diff --git a/config/config.template.ini b/config/config.template.ini index 7a959f27..17b144a1 100644 --- a/config/config.template.ini +++ b/config/config.template.ini @@ -163,6 +163,7 @@ FFAgent = 0 Pushover = 0 Telegram = 0 yowsup = 0 +record = 0 # for developing - template-module template = 0 @@ -414,6 +415,11 @@ zvei_message = %DATE% %TIME%: %ZVEI% poc_message = %MSG% +[record] +#duration in seconds +rec_duration = 40 +#filepath = #INSERT FILE PATH HERE# ex: /home/user/BOSWatch/recordings/ + ##################### ##### Not ready yet # ##################### diff --git a/includes/globalVars.py b/includes/globalVars.py index f5d416ad..55a693e6 100644 --- a/includes/globalVars.py +++ b/includes/globalVars.py @@ -13,7 +13,6 @@ branch = "dev" buildDate = "unreleased" - # Global variables config = 0 script_path = "" diff --git a/plugins/record/record.py b/plugins/record/record.py new file mode 100644 index 00000000..bf83f0ec --- /dev/null +++ b/plugins/record/record.py @@ -0,0 +1,118 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- + +""" + +@author: DK5RA Alex(trollkopp) + +@requires: arecord >= 1.1.3 +""" + +# ADD THIS TO YOUR Pulseaudio config file /etc/pulse/default.pa +# load-module module-null-sink sink_name=playbackstream +# update-sink-proplist playbackstream device.description=playbackstream +# load-module module-loopback sink=playbackstream +# set-default-sink playbackstream +# set-default-source playbackstream.monitor + + +# +# Imports +# + +import logging # Global logger +from includes import globalVars # Global variables + + +import os # for log mkdir +import time # for time.sleep() +import subprocess # for starting record + +# Helper function, uncomment to use +from includes.helper import timeHandler +from includes.helper import wildcardHandler +from includes.helper import configHandler + +## +# +# onLoad (init) function of plugin +# 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 + + @requires: nothing + + @return: nothing + @exception: Exception if init has an fatal error so that the plugin couldn't work + + """ + + try: + ########## User onLoad CODE ########## + pass + ########## User onLoad CODE ########## + except: + logging.error("unknown error") + logging.debug("unknown error", exc_info=True) + raise + +## +# +# Main function of plugin +# will be called by the alarmHandler +# +def run(typ,freq,data): + """ + This function is the implementation of the Plugin. + + If necessary the configuration hast to be set in the config.ini. + + @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 for dispatch + @type freq: string + @keyword freq: frequency of the SDR Stick + + @requires: If necessary the configuration hast to be set in the config.ini. + + @return: nothing + @exception: nothing, make sure this function will never thrown an exception + """ + try: + if configHandler.checkConfig("record"): #read and debug the config (let empty if no config used) + + logging.debug(globalVars.config.get("Plugins", "record")) +# logging.debug(globalVars.config.get("template", "test2")) + rec_duration = globalVars.config.get("record", "rec_duration") + if (globalVars.config.get("Plugins", "record") == "1"): + ########## User Plugin CODE ########## + if typ == "FMS": + logging.warning("%s not supported", typ) + elif typ == "ZVEI": + logging.debug("record plugin: detected ZVEI decode") + timestamp = str(timeHandler.getDate())+"-"+str(timeHandler.getTime()) + zveicode = "%ZVEI%" + zveicode = wildcardHandler.replaceWildcards(zveicode, data) + filename = "aufnahme_"+"5-ton"+str(zveicode)+"_"+str(timestamp)+".wav" + rec_filepath = globalVars.config.get("record", "filepath") + logging.debug(filename) + logging.debug(rec_filepath) + command = "" + command = command+"arecord -D pulse -f cd -d "+str(rec_duration)+" -c 1 "+str(rec_filepath)+str(filename)+"" + recordstream = subprocess.Popen(command.split(), + stderr=open(globalVars.log_path+"record.log","a"), + shell=False) + elif typ == "POC": + logging.warning("%s not supported", typ) + else: + logging.warning("Invalid Typ: %s", typ) + ########## User Plugin CODE ########## + else: + logging.debug("record plugin not activated. activate it in the config.ini") + except: + logging.error("unknown error") + logging.debug("unknown error", exc_info=True)