From 7100d43d9ec3918685c4c05300666ec4d5422e17 Mon Sep 17 00:00:00 2001 From: Jakob Ketterl Date: Thu, 30 May 2019 17:19:46 +0200 Subject: [PATCH] show callsigns for ham radio dmr ids --- config_webrx.py | 2 ++ htdocs/openwebrx.js | 10 ++++++++- owrx/meta.py | 54 +++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/config_webrx.py b/config_webrx.py index 0a76aad..98bcb0a 100644 --- a/config_webrx.py +++ b/config_webrx.py @@ -80,6 +80,8 @@ digimodes_fft_size=1024 # determines the quality, and thus the cpu usage, for the ambe codec used by digital voice modes # if you're running on a Raspi (up to 3B+) you'll want to leave this on 1 digital_voice_unvoiced_quality = 1 +# enables lookup of DMR ids using the radioid api +digital_voice_dmr_id_lookup = True """ Note: if you experience audio underruns while CPU usage is 100%, you can: diff --git a/htdocs/openwebrx.js b/htdocs/openwebrx.js index 7c9d237..3808f92 100644 --- a/htdocs/openwebrx.js +++ b/htdocs/openwebrx.js @@ -1318,7 +1318,15 @@ function update_metadata(meta) { if (meta.slot) { var html = 'Timeslot: ' + meta.slot; if (meta.type) html += ' Typ: ' + meta.type; - if (meta.source && meta.target) html += ' Source: ' + meta.source + ' Target: ' + meta.target; + if (meta.additional && meta.additional.callsign) { + html += ' Source: ' + meta.additional.callsign; + if (meta.additional.fname) { + html += ' (' + meta.additional.fname + ')'; + } + } else if (meta.source) { + html += ' Source: ' + meta.source; + } + if (meta.target) html += ' Target: ' + meta.target; update = function(_, el) { var slotEl = el.getElementsByClassName('slot-' + meta.slot); if (!slotEl.length) { diff --git a/owrx/meta.py b/owrx/meta.py index b99f646..bdb1eab 100644 --- a/owrx/meta.py +++ b/owrx/meta.py @@ -1,7 +1,57 @@ +from owrx.config import PropertyManager +from urllib import request +import json +from datetime import datetime, timedelta +import logging + +logger = logging.getLogger(__name__) + +class DmrMetaEnricher(object): + def __init__(self): + self.cache = {} + self.cacheTimeout = timedelta(seconds = 86400) + def cacheEntryValid(self, id): + if not id in self.cache: return False + entry = self.cache[id] + return entry["timestamp"] + self.cacheTimeout > datetime.now() + def enrich(self, meta): + if not PropertyManager.getSharedInstance()["digital_voice_dmr_id_lookup"]: return None + if not "source" in meta: return None + source = meta["source"] + if not self.cacheEntryValid(source): + try: + logger.debug("requesting DMR metadata for id=%s", source) + res = request.urlopen("https://www.radioid.net/api/dmr/user/?id={0}".format(source), timeout=5).read() + data = json.loads(res.decode("utf-8")) + self.cache[source] = { + "timestamp": datetime.now(), + "data": data + } + except json.JSONDecodeError: + self.cache[source] = { + "timestamp": datetime.now(), + "data": None + } + data = self.cache[source]["data"] + if "count" in data and data["count"] > 0 and "results" in data: + return data["results"][0] + return None + + class MetaParser(object): + enrichers = { + "DMR": DmrMetaEnricher() + } def __init__(self, handler): self.handler = handler def parse(self, meta): fields = meta.split(";") - dict = {v[0] : "".join(v[1:]) for v in map(lambda x: x.split(":"), fields)} - self.handler.write_metadata(dict) \ No newline at end of file + meta = {v[0] : "".join(v[1:]) for v in map(lambda x: x.split(":"), fields)} + + if "protocol" in meta: + protocol = meta["protocol"] + if protocol in MetaParser.enrichers: + additional_data = MetaParser.enrichers[protocol].enrich(meta) + if additional_data is not None: meta["additional"] = additional_data + self.handler.write_metadata(meta) +