Adding repeater bookmarks and markers, based on RepeaterBook.com.
This commit is contained in:
parent
d7174dea77
commit
187b2a7e6e
|
|
@ -204,5 +204,5 @@ defaultConfig = PropertyLayer(
|
|||
wsprnet_callsign="N0CALL",
|
||||
paging_filter=True,
|
||||
eibi_bookmarks_range=0,
|
||||
repeater_range=100,
|
||||
repeater_range=0,
|
||||
).readonly()
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ from owrx.feature import FeatureDetector
|
|||
from owrx.version import openwebrx_version
|
||||
from owrx.bands import Bandplan
|
||||
from owrx.bookmarks import Bookmarks
|
||||
from owrx.repeaters import Repeaters
|
||||
from owrx.eibi import EIBI
|
||||
from owrx.map import Map
|
||||
from owrx.property import PropertyStack, PropertyDeleted
|
||||
|
|
@ -215,9 +216,13 @@ class OpenWebRxReceiverClient(OpenWebRxClient, SdrSourceEventClient):
|
|||
dial_frequencies = Bandplan.getSharedInstance().collectDialFrequencies(frequencyRange)
|
||||
bookmarks = [b.__dict__() for b in Bookmarks.getSharedInstance().getBookmarks(frequencyRange)]
|
||||
# Search EIBI schedule for bookmarks, if enabled
|
||||
eibi_range = self.stack["eibi_bookmarks_range"]
|
||||
if eibi_range > 0:
|
||||
bookmarks += [b.__dict__() for b in EIBI.getSharedInstance().currentBookmarks(frequencyRange, rangeKm=eibi_range)]
|
||||
range = self.stack["eibi_bookmarks_range"]
|
||||
if range > 0:
|
||||
bookmarks += [b.__dict__() for b in EIBI.getSharedInstance().currentBookmarks(frequencyRange, rangeKm=range)]
|
||||
# Search RepeaterBook for bookmarks, if enabled
|
||||
range = self.stack["repeater_range"]
|
||||
if range > 0:
|
||||
bookmarks += [b.__dict__() for b in Repeaters.getSharedInstance().getBookmarks(frequencyRange, rangeKm=range)]
|
||||
self.write_dial_frequencies(dial_frequencies)
|
||||
self.write_bookmarks(bookmarks)
|
||||
|
||||
|
|
|
|||
|
|
@ -215,11 +215,11 @@ class GeneralSettingsController(SettingsFormController):
|
|||
),
|
||||
NumberInput(
|
||||
"repeater_range",
|
||||
"Repeater search range",
|
||||
"Repeater bookmarks range",
|
||||
infotext="Specifies the distance from the receiver location to "
|
||||
+ "search RepeaterBook.com for repeaters. Set to 0 to disable "
|
||||
+ "repeater search.",
|
||||
validator=RangeValidator(0, 300),
|
||||
+ "search RepeaterBook.com for repeaters when creating automatic "
|
||||
+ "bookmarks. Set to 0 to disable automatic repeater bookmarks.",
|
||||
validator=RangeValidator(0, 100),
|
||||
append="km",
|
||||
),
|
||||
),
|
||||
|
|
|
|||
12
owrx/eibi.py
12
owrx/eibi.py
|
|
@ -225,9 +225,9 @@ class EIBI(object):
|
|||
# Make sure freq2>freq1
|
||||
(f1, f2) = frequencyRange
|
||||
if f1>f2:
|
||||
f = f1
|
||||
f1 = f2
|
||||
f2 = f
|
||||
f = f1
|
||||
f1 = f2
|
||||
f2 = f
|
||||
|
||||
# Get entries active at the current time + 1 hour
|
||||
now = datetime.utcnow()
|
||||
|
|
@ -235,12 +235,14 @@ class EIBI(object):
|
|||
date = now.year * 10000 + now.month * 100 + now.day
|
||||
t1 = now.hour * 100 + now.minute
|
||||
t2 = t1 + hours * 100
|
||||
result = {}
|
||||
|
||||
# Get receiver location for computing distance
|
||||
pm = Config.get()
|
||||
rxPos = (pm["receiver_gps"]["lat"], pm["receiver_gps"]["lon"])
|
||||
|
||||
# No result yet
|
||||
result = {}
|
||||
|
||||
logger.debug("Creating bookmarks for {0}-{1}kHz within {2}km...".format(f1//1000, f2//1000, rangeKm))
|
||||
|
||||
# Search for current entries
|
||||
|
|
@ -253,7 +255,7 @@ class EIBI(object):
|
|||
# Check if entry active and within frequency range
|
||||
f = entry["freq"]
|
||||
entryActive = (
|
||||
f >= f1 and f <= f2 and entry["days"][day] != "."
|
||||
f1 <= f <= f2 and entry["days"][day] != "."
|
||||
and (entry["date1"] == 0 or entry["date1"] <= date)
|
||||
and (entry["date2"] == 0 or entry["date2"] >= date)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from owrx.version import openwebrx_version
|
|||
from owrx.map import Map, Location
|
||||
from owrx.aprs import getSymbolData
|
||||
from owrx.eibi import EIBI
|
||||
from owrx.repeaters import Repeaters
|
||||
from json import JSONEncoder
|
||||
from datetime import datetime
|
||||
|
||||
|
|
@ -107,6 +108,7 @@ class Markers(object):
|
|||
self.markers = {}
|
||||
self.rxmarkers = {}
|
||||
self.txmarkers = {}
|
||||
self.remarkers = {}
|
||||
|
||||
# Load miscellaneous markers from local files
|
||||
for file in self.fileList:
|
||||
|
|
@ -129,11 +131,15 @@ class Markers(object):
|
|||
# Load current schedule from the EIBI database
|
||||
self.txmarkers = self.loadCurrentTransmitters()
|
||||
|
||||
# Load repeaters from the Repeaters database
|
||||
self.remarkers = self.loadRepeaters()
|
||||
|
||||
# Update map with markers
|
||||
logger.debug("Updating map...")
|
||||
self.updateMap(self.markers)
|
||||
self.updateMap(self.rxmarkers)
|
||||
self.updateMap(self.txmarkers)
|
||||
self.updateMap(self.remarkers)
|
||||
|
||||
#
|
||||
# Main Loop
|
||||
|
|
@ -246,8 +252,6 @@ class Markers(object):
|
|||
cache.update(self.scrapeWebSDR())
|
||||
logger.debug("Scraping OpenWebRX website...")
|
||||
cache.update(self.scrapeOWRX())
|
||||
logger.debug("Scraping RepeaterBook website...")
|
||||
cache.update(self.scrapeRepeaterBook())
|
||||
|
||||
# Save parsed data into a file, if there is anything to save
|
||||
if cache:
|
||||
|
|
@ -260,6 +264,29 @@ class Markers(object):
|
|||
# Following functions scrape data from websites and internal databases
|
||||
#
|
||||
|
||||
def loadRepeaters(self, rangeKm: int = 100):
|
||||
# No result yet
|
||||
result = {}
|
||||
# Refresh / load repeaters database, as needed
|
||||
Repeaters.getSharedInstance().refresh()
|
||||
# Load repeater sites from repeaters database
|
||||
for entry in Repeaters.getSharedInstance().getAllInRange(rangeKm):
|
||||
rl = MarkerLocation({
|
||||
"type" : "feature",
|
||||
"mode" : "Repeaters",
|
||||
"id" : entry["name"],
|
||||
"lat" : entry["lat"],
|
||||
"lon" : entry["lon"],
|
||||
"freq" : entry["freq"],
|
||||
"mmode" : entry["mode"],
|
||||
"status" : entry["status"],
|
||||
"updated" : entry["updated"],
|
||||
"comment" : entry["comment"]
|
||||
})
|
||||
result[rl.getId()] = rl
|
||||
# Done
|
||||
return result
|
||||
|
||||
def loadCurrentTransmitters(self):
|
||||
#url = "https://www.short-wave.info/index.php?txsite="
|
||||
url = "https://www.google.com/search?q="
|
||||
|
|
@ -432,58 +459,3 @@ class Markers(object):
|
|||
# Done
|
||||
return result
|
||||
|
||||
def scrapeRepeaterBook(self, url: str = "https://www.repeaterbook.com/api/export.php?qtype=prox&dunit=km&lat={lat}&lng={lon}&dist={range}"):
|
||||
result = {}
|
||||
try:
|
||||
pm = Config.get()
|
||||
lat = pm["receiver_gps"]["lat"]
|
||||
lon = pm["receiver_gps"]["lon"]
|
||||
dist = pm["repeater_range"]
|
||||
url = url.format(lat = lat, lon = lon, range = dist)
|
||||
hdrs = { "User-Agent": "OpenWebRX+/" + openwebrx_version }
|
||||
req = urllib.request.Request(url, headers = hdrs)
|
||||
data = urllib.request.urlopen(req).read().decode("utf-8")
|
||||
data = json.loads(data)
|
||||
# Ignore empty or invalid responses
|
||||
if "results" not in data:
|
||||
return result
|
||||
# For every entry in the response...
|
||||
for entry in data["results"]:
|
||||
# Get location
|
||||
lat = float(entry["Lat"])
|
||||
lon = float(entry["Long"])
|
||||
# Guess main operating mode, prefer free modes
|
||||
if "FM Analog" in entry and entry["FM Analog"]=="Yes":
|
||||
mmode = "fm"
|
||||
elif "M17" in entry and entry["M17"]=="Yes":
|
||||
mmode = "m17"
|
||||
elif "DMR" in entry and entry["DMR"]=="Yes":
|
||||
mmode = "dmr"
|
||||
elif "D-Star" in entry and entry["D-Star"]=="Yes":
|
||||
mmode = "dstar"
|
||||
elif "System Fusion" in entry and entry["System Fusion"]=="Yes":
|
||||
mmode = "ysf"
|
||||
elif "NXDN" in entry and entry["NXDN"]=="Yes":
|
||||
mmode = "nxdn"
|
||||
else:
|
||||
mmode = "fm"
|
||||
# Create marker
|
||||
rl = MarkerLocation({
|
||||
"type" : "feature",
|
||||
"mode" : "Repeaters",
|
||||
"id" : entry["Callsign"],
|
||||
"lat" : lat,
|
||||
"lon" : lon,
|
||||
"freq" : int(float(entry["Frequency"]) * 1000000),
|
||||
"mmode" : mmode,
|
||||
"status" : entry["Operational Status"],
|
||||
"updated" : entry["Last Update"],
|
||||
"comment" : entry["Notes"]
|
||||
})
|
||||
result[rl.getId()] = rl
|
||||
|
||||
except Exception as e:
|
||||
logger.debug("scrapeRepeaterBook() exception: {0}".format(e))
|
||||
|
||||
# Done
|
||||
return result
|
||||
|
|
|
|||
|
|
@ -646,13 +646,22 @@ class SdrDeviceDescription(object):
|
|||
NumberInput("initial_squelch_level", "Initial squelch level", append="dBFS"),
|
||||
NumberInput(
|
||||
"eibi_bookmarks_range",
|
||||
"Automatic bookmarks range",
|
||||
"Shortwave bookmarks range",
|
||||
infotext="Specifies the distance from the receiver location to "
|
||||
+ "search EIBI schedules for stations when creating automatic "
|
||||
+ "bookmarks. Set to 0 to disable automatic bookmarks.",
|
||||
+ "bookmarks. Set to 0 to disable automatic EIBI bookmarks.",
|
||||
validator=RangeValidator(0, 25000),
|
||||
append="km",
|
||||
),
|
||||
NumberInput(
|
||||
"repeater_range",
|
||||
"Repeater bookmarks range",
|
||||
infotext="Specifies the distance from the receiver location to "
|
||||
+ "search RepeaterBook.com for repeaters when creating automatic "
|
||||
+ "bookmarks. Set to 0 to disable automatic repeater bookmarks.",
|
||||
validator=RangeValidator(0, 100),
|
||||
append="km",
|
||||
),
|
||||
]
|
||||
|
||||
def hasAgc(self):
|
||||
|
|
@ -680,7 +689,7 @@ class SdrDeviceDescription(object):
|
|||
return ["name", "center_freq", "samp_rate", "start_freq", "start_mod", "tuning_step"]
|
||||
|
||||
def getProfileOptionalKeys(self):
|
||||
return ["initial_squelch_level", "rf_gain", "lfo_offset", "waterfall_levels", "eibi_bookmarks_range"]
|
||||
return ["initial_squelch_level", "rf_gain", "lfo_offset", "waterfall_levels", "eibi_bookmarks_range", "repeater_range"]
|
||||
|
||||
def getDeviceSection(self):
|
||||
return OptionalSection(
|
||||
|
|
|
|||
Loading…
Reference in New Issue