From 16183700c0218238f2f320afe898a99047561841 Mon Sep 17 00:00:00 2001 From: Michael Clemens Date: Tue, 8 Dec 2020 01:00:58 +0100 Subject: [PATCH] added callsign stalking, made things nicer, fixed bugs added config file --- config.py | 10 +++++++ pyBMNotify.py | 83 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 59 insertions(+), 34 deletions(-) create mode 100644 config.py diff --git a/config.py b/config.py new file mode 100644 index 0000000..0b56b7d --- /dev/null +++ b/config.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python + +# adapt the following variables to your needs +talkgroups = [91, 262] # Talkgroups to monitor +callsigns = ["N0CALL", "N0C4LL"] # Callsigns to monitor +min_duration = 2 # Min. duration of a QSO to qualify for a push notification +min_silence = 300 # Min. time in seconds after the last QSO before a new push notification will be send +# Pushover configuration +pushover_token = "" # Your Pushover API token +pushover_user = "" # Your Pushover user key diff --git a/pyBMNotify.py b/pyBMNotify.py index 4af2da8..6c3f183 100644 --- a/pyBMNotify.py +++ b/pyBMNotify.py @@ -1,64 +1,79 @@ +#!/usr/bin/env python from socketIO_client import SocketIO import json import datetime as dt import time +import config as cfg +import http.client, urllib -id = "" -last_activity = {} +last_TG_activity = {} +last_OM_activity = {} - -# adapt the following variables to your needs -talkgroups = [91, 98002] # Talkgroups to monitor -#dmr_ids = [2637550] -callsigns = ["DL6MHC", "OE1MEW"] -min_duration = 2 # Min. duration of QSO to qualify for a push notification -min_silence = 300 # Min. time in seconds after the last QSO before a new push notification will be send. - def on_connect(): - print('connect') + print('Connecting to the Brandmeister API') def on_disconnect(): - print('disconnect') + print('Disconnected') def on_reconnect(): - print('reconnect') + print('Reconnecting') + +def push_message(msg): + if cfg.pushover_token != "" and cfg.pushover_user != "": + conn = http.client.HTTPSConnection("api.pushover.net:443") + conn.request("POST", "/1/messages.json", + urllib.parse.urlencode({ + "token": cfg.pushover_token, + "user": cfg.pushover_user, + "message": msg, + }), { "Content-type": "application/x-www-form-urlencoded" }) + conn.getresponse() def construct_message(c): tg = c["DestinationID"] out = "" duration = c["Stop"] - c["Start"] - #print(c["DestinationName"]) # convert unix time stamp to human readable format time = dt.datetime.utcfromtimestamp(c["Start"]).strftime("%Y/%m/%d %H:%M") # construct text message from various QSO properties out += c["SourceCall"] + ' (' + c["SourceName"] + ') was active on ' out += str(tg) + ' (' + c["DestinationName"] + ') at ' out += time + ' (' + str(duration) + ' seconds)' - #print(json.dumps(call,separators=(',',':'),sort_keys=True,indent=4)) - # remember ID to prevent doublets - #id = call["SessionID"] - #last_activity[tg] = call["Start"] - # finally print out the text message - print(out) + # finally return the text message + return out def on_mqtt(*args): - global id # get json data of QSO call = json.loads(args[0]['payload']) - #print(json.dumps(call,separators=(',',':'),sort_keys=True,indent=4)) - # check if talkgroup is one of those to be monitored, if QSO has already been - # ended and the same QSO has already been handled tg = call["DestinationID"] - if call["SourceCall"] in callsigns: - construct_message(call) - elif tg in talkgroups and call["Stop"] > 0 and id != call["SessionID"] and (tg not in last_activity or (last_activity[tg] + min_silence) < call["Start"]): - # calculate duration of QSO - duration = call["Stop"] - call["Start"] - # only proceed if QSO has the configured min. duration - if duration >= min_duration: - construct_message(call) - id = call["SessionID"] - last_activity[tg] = call["Start"] + callsign = call["SourceCall"] + start_time = call["Start"] + stop_time = call["Stop"] + msg = "" + # check if callsign is monitored, the over has already been finished + # and the person was inactive for n seconds + if callsign in cfg.callsigns: + if callsign not in last_OM_activity or (last_OM_activity[callsign] + cfg.min_silence) < start_time: + # If the activity has happened in a monitored TG, remember the QSO start time stamp + if tg in cfg.talkgroups and stop_time > 0: + last_TG_activity[tg] = start_time + # remember the QSO's time stamp of this particular DMR user + last_OM_activity[callsign] = start_time + msg = construct_message(call) + # Continue if the talkgroup is monitored, the over has been finished and there was no activity + # during the last n seconds in this talkgroup + elif tg in cfg.talkgroups and stop_time > 0: + if tg not in last_TG_activity or (last_TG_activity[tg] + cfg.min_silence) < start_time: + # calculate duration of key down + duration = stop_time - start_time + # only proceed if the key down has been long enough + if duration >= cfg.min_duration: + last_TG_activity[tg] = start_time + msg = construct_message(call) + # finally write the message to the console and send a push notification + if msg != "": + print(construct_message(call)) + push_message(construct_message(call)) socket = SocketIO('https://api.brandmeister.network/lh') socket.on('connect', on_connect)