From a15341fdcf59af199241c1be36d991b05c00c235 Mon Sep 17 00:00:00 2001 From: Jakob Ketterl Date: Sun, 14 Jul 2019 19:32:48 +0200 Subject: [PATCH] detect and pass band information to the map --- bands.json | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++ htdocs/map.js | 9 +++-- owrx/bands.py | 32 +++++++++++++++++ owrx/map.py | 11 +++--- owrx/source.py | 8 +++-- owrx/wsjt.py | 11 ++++-- 6 files changed, 158 insertions(+), 10 deletions(-) create mode 100644 bands.json create mode 100644 owrx/bands.py diff --git a/bands.json b/bands.json new file mode 100644 index 0000000..3a6939a --- /dev/null +++ b/bands.json @@ -0,0 +1,97 @@ +[ + { + "name": "160m", + "lower_bound": 1810000, + "upper_bound": 2000000 + }, + { + "name": "80m", + "lower_bound": 3500000, + "upper_bound": 3800000 + }, + { + "name": "60m", + "lower_bound": 5351500, + "upper_bound": 3566500 + }, + { + "name": "40m", + "lower_bound": 7000000, + "upper_bound": 7200000 + }, + { + "name": "30m", + "lower_bound": 10100000, + "upper_bound": 10150000 + }, + { + "name": "20m", + "lower_bound": 14000000, + "upper_bound": 14350000 + }, + { + "name": "17m", + "lower_bound": 18068000, + "upper_bound": 18168000 + }, + { + "name": "15m", + "lower_bound": 21000000, + "upper_bound": 21450000 + }, + { + "name": "12m", + "lower_bound": 24890000, + "upper_bound": 24990000 + }, + { + "name": "10m", + "lower_bound": 28000000, + "upper_bound": 29700000 + }, + { + "name": "6m", + "lower_bound": 50030000, + "upper_bound": 51000000 + }, + { + "name": "4m", + "lower_bound": 70150000, + "upper_bound": 70200000 + }, + { + "name": "2m", + "lower_bound": 144000000, + "upper_bound": 146000000 + }, + { + "name": "70cm", + "lower_bound": 430000000, + "upper_bound": 440000000 + }, + { + "name": "23cm", + "lower_bound": 1240000000, + "upper_bound": 1300000000 + }, + { + "name": "13cm", + "lower_bound": 2320000000, + "upper_bound": 2450000000 + }, + { + "name": "9cm", + "lower_bound": 3400000000, + "upper_bound": 3475000000 + }, + { + "name": "6cm", + "lower_bound": 5650000000, + "upper_bound": 5850000000 + }, + { + "name": "3cm", + "lower_bound": 10000000000, + "upper_bound": 10500000000 + } +] \ No newline at end of file diff --git a/htdocs/map.js b/htdocs/map.js index b5f905a..6af68ca 100644 --- a/htdocs/map.js +++ b/htdocs/map.js @@ -58,6 +58,7 @@ }, getMarkerOpacityOptions(update.lastseen) )); marker.lastseen = update.lastseen; marker.mode = update.mode; + marker.band = update.band; // TODO the trim should happen on the server side if (expectedCallsign && expectedCallsign == update.callsign.trim()) { @@ -96,6 +97,7 @@ rectangle.lastseen = update.lastseen; rectangle.locator = update.location.locator; rectangle.mode = update.mode; + rectangle.band = update.band; if (expectedLocator && expectedLocator == update.location.locator) { map.panTo(center); @@ -194,7 +196,7 @@ var showLocatorInfoWindow = function(locator, pos) { if (!infowindow) infowindow = new google.maps.InfoWindow(); var inLocator = $.map(rectangles, function(r, callsign) { - return {callsign: callsign, locator: r.locator, lastseen: r.lastseen, mode: r.mode} + return {callsign: callsign, locator: r.locator, lastseen: r.lastseen, mode: r.mode, band: r.band} }).filter(function(d) { return d.locator == locator; }).sort(function(a, b){ @@ -206,7 +208,10 @@ '' ); diff --git a/owrx/bands.py b/owrx/bands.py new file mode 100644 index 0000000..c2ed79e --- /dev/null +++ b/owrx/bands.py @@ -0,0 +1,32 @@ +import json + + +class Band(object): + def __init__(self, dict): + self.name = dict["name"] + self.lower_bound = dict["lower_bound"] + self.upper_bound = dict["upper_bound"] + + def inBand(self, freq): + return self.lower_bound <= freq <= self.upper_bound + + def getName(self): + return self.name + + +class Bandplan(object): + sharedInstance = None + @staticmethod + def getSharedInstance(): + if Bandplan.sharedInstance is None: + Bandplan.sharedInstance = Bandplan() + return Bandplan.sharedInstance + + def __init__(self): + f = open("bands.json", "r") + bands_json = json.load(f) + f.close() + self.bands = [Band(d) for d in bands_json] + + def findBand(self, freq): + return next(band for band in self.bands if band.inBand(freq)) diff --git a/owrx/map.py b/owrx/map.py index 4d65a49..a6adbb6 100644 --- a/owrx/map.py +++ b/owrx/map.py @@ -1,6 +1,7 @@ from datetime import datetime, timedelta import threading, time from owrx.config import PropertyManager +from owrx.bands import Band import logging logger = logging.getLogger(__name__) @@ -45,7 +46,8 @@ class Map(object): "callsign": callsign, "location": record["location"].__dict__(), "lastseen": record["updated"].timestamp() * 1000, - "mode" : record["mode"] + "mode" : record["mode"], + "band" : record["band"].getName() if record["band"] is not None else None } for (callsign, record) in self.positions.items() ]) @@ -56,15 +58,16 @@ class Map(object): except ValueError: pass - def updateLocation(self, callsign, loc: Location, mode: str): + def updateLocation(self, callsign, loc: Location, mode: str, band: Band = None): ts = datetime.now() - self.positions[callsign] = {"location": loc, "updated": ts, "mode": mode} + self.positions[callsign] = {"location": loc, "updated": ts, "mode": mode, "band": band} self.broadcast([ { "callsign": callsign, "location": loc.__dict__(), "lastseen": ts.timestamp() * 1000, - "mode" : mode + "mode" : mode, + "band" : band.getName() if band is not None else None } ]) diff --git a/owrx/source.py b/owrx/source.py index 7a37ef6..2e2bca7 100644 --- a/owrx/source.py +++ b/owrx/source.py @@ -353,7 +353,7 @@ class DspManager(csdr.output): self.localProps = self.sdrSource.getProps().collect( "audio_compression", "fft_compression", "digimodes_fft_size", "csdr_dynamic_bufsize", "csdr_print_bufsizes", "csdr_through", "digimodes_enable", "samp_rate", "digital_voice_unvoiced_quality", - "dmr_filter", "temporary_directory" + "dmr_filter", "temporary_directory", "center_freq" ).defaults(PropertyManager.getSharedInstance()) self.dsp = csdr.dsp(self) @@ -369,6 +369,9 @@ class DspManager(csdr.output): bpf[1] = cut self.dsp.set_bpf(*bpf) + def set_dial_freq(key, value): + self.wsjtParser.setDialFrequency(self.localProps["center_freq"] + self.localProps["offset_freq"]) + self.subscriptions = [ self.localProps.getProperty("audio_compression").wire(self.dsp.set_audio_compression), self.localProps.getProperty("fft_compression").wire(self.dsp.set_fft_compression), @@ -382,7 +385,8 @@ class DspManager(csdr.output): self.localProps.getProperty("mod").wire(self.dsp.set_demodulator), self.localProps.getProperty("digital_voice_unvoiced_quality").wire(self.dsp.set_unvoiced_quality), self.localProps.getProperty("dmr_filter").wire(self.dsp.set_dmr_filter), - self.localProps.getProperty("temporary_directory").wire(self.dsp.set_temporary_directory) + self.localProps.getProperty("temporary_directory").wire(self.dsp.set_temporary_directory), + self.localProps.collect("center_freq", "offset_freq").wire(set_dial_freq) ] self.dsp.set_offset_freq(0) diff --git a/owrx/wsjt.py b/owrx/wsjt.py index 75188ac..df3eda9 100644 --- a/owrx/wsjt.py +++ b/owrx/wsjt.py @@ -9,6 +9,7 @@ from multiprocessing.connection import Pipe from owrx.map import Map, LocatorLocation import re from owrx.config import PropertyManager +from owrx.bands import Bandplan import logging logger = logging.getLogger(__name__) @@ -172,6 +173,8 @@ class WsjtParser(object): def __init__(self, handler): self.handler = handler + self.dial_freq = None + self.band = None modes = { "~": "FT8", @@ -229,7 +232,7 @@ class WsjtParser(object): # likely this just means roger roger goodbye. if m.group(2) == "RR73": return - Map.getSharedInstance().updateLocation(m.group(1), LocatorLocation(m.group(2)), mode) + Map.getSharedInstance().updateLocation(m.group(1), LocatorLocation(m.group(2)), mode, self.band) def parse_from_wsprd(self, msg): # wspr sample @@ -252,4 +255,8 @@ class WsjtParser(object): m = WsjtParser.wspr_splitter_pattern.match(msg) if m is None: return - Map.getSharedInstance().updateLocation(m.group(1), LocatorLocation(m.group(2)), "WSPR") + Map.getSharedInstance().updateLocation(m.group(1), LocatorLocation(m.group(2)), "WSPR", self.band) + + def setDialFrequency(self, freq): + self.dial_freq = freq + self.band = Bandplan.getSharedInstance().findBand(freq)