diff --git a/csdr/csdr.py b/csdr/csdr.py
index a95448b..ad4d344 100644
--- a/csdr/csdr.py
+++ b/csdr/csdr.py
@@ -198,10 +198,7 @@ class dsp(object):
"csdr limit_ff",
]
chain += last_decimation_block
- chain += [
- "csdr deemphasis_wfm_ff {audio_rate} {wfm_deemphasis_tau}",
- "csdr convert_f_s16"
- ]
+ chain += ["csdr deemphasis_wfm_ff {audio_rate} {wfm_deemphasis_tau}", "csdr convert_f_s16"]
elif self.isDigitalVoice(which):
chain += ["csdr fmdemod_quadri_cf"]
chain += last_decimation_block
@@ -460,7 +457,9 @@ class dsp(object):
def set_secondary_offset_freq(self, value):
self.secondary_offset_freq = value
if self.secondary_processes_running and self.has_pipe("secondary_shift_pipe"):
- self.pipes["secondary_shift_pipe"].write("%g\n" % (-float(self.secondary_offset_freq) / self.if_samp_rate()))
+ self.pipes["secondary_shift_pipe"].write(
+ "%g\n" % (-float(self.secondary_offset_freq) / self.if_samp_rate())
+ )
def stop_secondary_demodulator(self):
if not self.secondary_processes_running:
@@ -581,7 +580,7 @@ class dsp(object):
demodulator = self.get_secondary_demodulator()
return demodulator in ["ft8", "wspr", "jt65", "jt9", "ft4", "fst4", "fst4w"]
- def isJs8(self, demodulator = None):
+ def isJs8(self, demodulator=None):
if demodulator is None:
demodulator = self.get_secondary_demodulator()
return demodulator == "js8"
@@ -689,7 +688,11 @@ class dsp(object):
def set_squelch_level(self, squelch_level):
self.squelch_level = squelch_level
# no squelch required on digital voice modes
- actual_squelch = -150 if self.isDigitalVoice() or self.isPacket() or self.isPocsag() or self.isFreeDV() else self.squelch_level
+ actual_squelch = (
+ -150
+ if self.isDigitalVoice() or self.isPacket() or self.isPocsag() or self.isFreeDV()
+ else self.squelch_level
+ )
if self.running:
self.pipes["squelch_pipe"].write("%g\n" % (self.convertToLinear(actual_squelch)))
@@ -842,6 +845,7 @@ class dsp(object):
self.start_secondary_demodulator()
if self.has_pipe("smeter_pipe"):
+
def read_smeter():
raw = self.pipes["smeter_pipe"].readline()
if len(raw) == 0:
@@ -851,6 +855,7 @@ class dsp(object):
self.output.send_output("smeter", read_smeter)
if self.has_pipe("meta_pipe"):
+
def read_meta():
raw = self.pipes["meta_pipe"].readline()
if len(raw) == 0:
diff --git a/csdr/pipe.py b/csdr/pipe.py
index f915aef..025e287 100644
--- a/csdr/pipe.py
+++ b/csdr/pipe.py
@@ -42,6 +42,7 @@ class Pipe(object):
immediately here), resulting in empty reads until data is available. This is handled specially in the
ReadingPipe class.
"""
+
def opener(path, flags):
fd = os.open(path, flags | os.O_NONBLOCK)
os.set_blocking(fd, True)
@@ -88,7 +89,7 @@ class WritingPipe(Pipe):
except OSError as error:
# ENXIO = FIFO has not been opened for reading
if error.errno == 6:
- time.sleep(.1)
+ time.sleep(0.1)
retries += 1
else:
raise
diff --git a/owrx/__main__.py b/owrx/__main__.py
index 908767f..1903d8b 100644
--- a/owrx/__main__.py
+++ b/owrx/__main__.py
@@ -40,9 +40,7 @@ Support and info: https://groups.io/g/openwebrx
configErrors = Config.validateConfig()
if configErrors:
- logger.error(
- "your configuration contains errors. please address the following errors:"
- )
+ logger.error("your configuration contains errors. please address the following errors:")
for e in configErrors:
logger.error(e)
return
diff --git a/owrx/audio.py b/owrx/audio.py
index 9a5b07f..fd57262 100644
--- a/owrx/audio.py
+++ b/owrx/audio.py
@@ -69,7 +69,9 @@ class DecoderQueue(Queue):
with DecoderQueue.creationLock:
if DecoderQueue.sharedInstance is None:
pm = Config.get()
- DecoderQueue.sharedInstance = DecoderQueue(maxsize=pm["decoding_queue_length"], workers=pm["decoding_queue_workers"])
+ DecoderQueue.sharedInstance = DecoderQueue(
+ maxsize=pm["decoding_queue_length"], workers=pm["decoding_queue_workers"]
+ )
return DecoderQueue.sharedInstance
@staticmethod
diff --git a/owrx/bands.py b/owrx/bands.py
index 89bf293..5062202 100644
--- a/owrx/bands.py
+++ b/owrx/bands.py
@@ -17,7 +17,7 @@ class Band(object):
for (mode, freqs) in dict["frequencies"].items():
if mode not in availableModes:
logger.info(
- "Modulation \"{mode}\" is not available, bandplan bookmark will not be displayed".format(
+ 'Modulation "{mode}" is not available, bandplan bookmark will not be displayed'.format(
mode=mode
)
)
diff --git a/owrx/config.py b/owrx/config.py
index 7c084a3..f668f8e 100644
--- a/owrx/config.py
+++ b/owrx/config.py
@@ -112,9 +112,7 @@ class Config:
@staticmethod
def validateConfig():
pm = Config.get()
- errors = [
- Config.checkTempDirectory(pm)
- ]
+ errors = [Config.checkTempDirectory(pm)]
return [e for e in errors if e is not None]
diff --git a/owrx/controllers/__init__.py b/owrx/controllers/__init__.py
index 8d227c3..e1b5fbd 100644
--- a/owrx/controllers/__init__.py
+++ b/owrx/controllers/__init__.py
@@ -7,7 +7,9 @@ class Controller(object):
self.request = request
self.options = options
- def send_response(self, content, code=200, content_type="text/html", last_modified: datetime = None, max_age=None, headers=None):
+ def send_response(
+ self, content, code=200, content_type="text/html", last_modified: datetime = None, max_age=None, headers=None
+ ):
self.handler.send_response(code)
if headers is None:
headers = {}
@@ -27,7 +29,7 @@ class Controller(object):
def send_redirect(self, location, code=303, cookies=None):
self.handler.send_response(code)
if cookies is not None:
- self.handler.send_header("Set-Cookie", cookies.output(header=''))
+ self.handler.send_header("Set-Cookie", cookies.output(header=""))
self.handler.send_header("Location", location)
self.handler.end_headers()
diff --git a/owrx/controllers/assets.py b/owrx/controllers/assets.py
index 7563325..803dec9 100644
--- a/owrx/controllers/assets.py
+++ b/owrx/controllers/assets.py
@@ -13,9 +13,9 @@ logger = logging.getLogger(__name__)
class GzipMixin(object):
- def send_response(self, content, headers=None, content_type="text/html", *args, **kwargs):
+ def send_response(self, content, headers=None, content_type="text/html", *args, **kwargs):
if self.zipable(content_type) and "accept-encoding" in self.request.headers:
- accepted = [s.strip().lower() for s in self.request.headers['accept-encoding'].split(",")]
+ accepted = [s.strip().lower() for s in self.request.headers["accept-encoding"].split(",")]
if "gzip" in accepted:
if type(content) == str:
content = content.encode()
@@ -26,11 +26,7 @@ class GzipMixin(object):
super().send_response(content, headers=headers, content_type=content_type, *args, **kwargs)
def zipable(self, content_type):
- types = [
- "application/javascript",
- "text/css",
- "text/html"
- ]
+ types = ["application/javascript", "text/css", "text/html"]
return content_type in types
def gzip(self, content):
@@ -41,11 +37,11 @@ class ModificationAwareController(Controller, metaclass=ABCMeta):
@abstractmethod
def getModified(self, file):
pass
-
+
def wasModified(self, file):
try:
modified = self.getModified(file).replace(microsecond=0)
-
+
if modified is not None and "If-Modified-Since" in self.handler.headers:
client_modified = datetime.strptime(
self.handler.headers["If-Modified-Since"], "%a, %d %b %Y %H:%M:%S %Z"
@@ -54,7 +50,7 @@ class ModificationAwareController(Controller, metaclass=ABCMeta):
return False
except FileNotFoundError:
pass
-
+
return True
@@ -143,7 +139,7 @@ class CompiledAssetsController(GzipMixin, ModificationAwareController):
"lib/settings/Input.js",
"lib/settings/SdrDevice.js",
"settings.js",
- ]
+ ],
}
def indexAction(self):
diff --git a/owrx/controllers/receiverid.py b/owrx/controllers/receiverid.py
index 667c6be..10c7361 100644
--- a/owrx/controllers/receiverid.py
+++ b/owrx/controllers/receiverid.py
@@ -8,15 +8,19 @@ class ReceiverIdController(Controller):
super().__init__(handler, request, options)
self.authHeader = None
- def send_response(self, content, code=200, content_type="text/html", last_modified: datetime = None, max_age=None, headers=None):
+ def send_response(
+ self, content, code=200, content_type="text/html", last_modified: datetime = None, max_age=None, headers=None
+ ):
if self.authHeader is not None:
if headers is None:
headers = {}
- headers['Authorization'] = self.authHeader
- super().send_response(content, code=code, content_type=content_type, last_modified=last_modified, max_age=max_age, headers=headers)
+ headers["Authorization"] = self.authHeader
+ super().send_response(
+ content, code=code, content_type=content_type, last_modified=last_modified, max_age=max_age, headers=headers
+ )
pass
def handle_request(self):
if "Authorization" in self.request.headers:
- self.authHeader = ReceiverId.getResponseHeader(self.request.headers['Authorization'])
+ self.authHeader = ReceiverId.getResponseHeader(self.request.headers["Authorization"])
super().handle_request()
diff --git a/owrx/controllers/settings.py b/owrx/controllers/settings.py
index 368a167..cd68549 100644
--- a/owrx/controllers/settings.py
+++ b/owrx/controllers/settings.py
@@ -69,12 +69,16 @@ class SdrSettingsController(AdminController):
{form}
- """.format(device_name=config["name"], form=self.render_form(device_id, config))
+ """.format(
+ device_name=config["name"], form=self.render_form(device_id, config)
+ )
def render_form(self, device_id, config):
return """
- """.format(device_id=device_id, formdata=quote(json.dumps(config)))
+ """.format(
+ device_id=device_id, formdata=quote(json.dumps(config))
+ )
def indexAction(self):
self.serve_template("sdrsettings.html", **self.template_variables())
@@ -119,12 +123,18 @@ class GeneralSettingsController(AdminController):
DropdownInput(
"audio_compression",
"Audio compression",
- options=[Option("adpcm", "ADPCM"), Option("none", "None"),],
+ options=[
+ Option("adpcm", "ADPCM"),
+ Option("none", "None"),
+ ],
),
DropdownInput(
"fft_compression",
"Waterfall compression",
- options=[Option("adpcm", "ADPCM"), Option("none", "None"),],
+ options=[
+ Option("adpcm", "ADPCM"),
+ Option("none", "None"),
+ ],
),
),
Section(
@@ -196,10 +206,7 @@ class GeneralSettingsController(AdminController):
"Js8Call decoding depth",
infotext="A higher decoding depth will allow more results, but will also consume more cpu",
),
- Js8ProfileCheckboxInput(
- "js8_enabled_profiles",
- "Js8Call enabled modes"
- ),
+ Js8ProfileCheckboxInput("js8_enabled_profiles", "Js8Call enabled modes"),
),
Section(
"Background decoding",
@@ -269,9 +276,7 @@ class GeneralSettingsController(AdminController):
def processFormData(self):
data = parse_qs(self.get_body().decode("utf-8"))
- data = {
- k: v for i in GeneralSettingsController.sections for k, v in i.parse(data).items()
- }
+ data = {k: v for i in GeneralSettingsController.sections for k, v in i.parse(data).items()}
config = Config.get()
for k, v in data.items():
config[k] = v
diff --git a/owrx/controllers/status.py b/owrx/controllers/status.py
index 9e6a820..9100b34 100644
--- a/owrx/controllers/status.py
+++ b/owrx/controllers/status.py
@@ -22,7 +22,7 @@ class StatusController(ReceiverIdController):
"name": receiver.getName(),
# TODO would be better to have types from the config here
"type": type(receiver).__name__,
- "profiles": [self.getProfileStats(p) for p in receiver.getProfiles().values()]
+ "profiles": [self.getProfileStats(p) for p in receiver.getProfiles().values()],
}
return stats
@@ -38,6 +38,6 @@ class StatusController(ReceiverIdController):
},
"max_clients": pm["max_clients"],
"version": openwebrx_version,
- "sdrs": [self.getReceiverStats(r) for r in SdrService.getSources().values()]
+ "sdrs": [self.getReceiverStats(r) for r in SdrService.getSources().values()],
}
self.send_response(json.dumps(status), content_type="application/json")
diff --git a/owrx/feature.py b/owrx/feature.py
index 1a37494..8c940d2 100644
--- a/owrx/feature.py
+++ b/owrx/feature.py
@@ -152,7 +152,14 @@ class FeatureDetector(object):
# prevent X11 programs from opening windows if called from a GUI shell
env.pop("DISPLAY", None)
try:
- process = subprocess.Popen(cmd, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=tmp_dir, env=env)
+ process = subprocess.Popen(
+ cmd,
+ stdin=subprocess.DEVNULL,
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL,
+ cwd=tmp_dir,
+ env=env,
+ )
rc = process.wait()
if expected_result is None:
return rc != 32512
@@ -214,7 +221,6 @@ class FeatureDetector(object):
"""
return self.command_is_runnable("perseustest -h")
-
def has_digiham(self):
"""
To use digital voice modes, the digiham package is required. You can find the package and installation
@@ -547,4 +553,4 @@ class FeatureDetector(object):
You can find more information [here](https://github.com/jketterl/eb200_connector).
"""
- return self._check_connector("eb200_connector")
\ No newline at end of file
+ return self._check_connector("eb200_connector")
diff --git a/owrx/form/__init__.py b/owrx/form/__init__.py
index 7f59bf5..8b1fd9f 100644
--- a/owrx/form/__init__.py
+++ b/owrx/form/__init__.py
@@ -10,9 +10,7 @@ class Input(ABC):
self.infotext = infotext
def bootstrap_decorate(self, input):
- infotext = (
- "{text}".format(text=self.infotext) if self.infotext else ""
- )
+ infotext = "{text}".format(text=self.infotext) if self.infotext else ""
return """
@@ -108,9 +106,7 @@ class LocationInput(Input):
)
def parse(self, data):
- return {
- self.id: {k: float(data["{0}-{1}".format(self.id, k)][0]) for k in ["lat", "lon"]}
- }
+ return {self.id: {k: float(data["{0}-{1}".format(self.id, k)][0]) for k in ["lat", "lon"]}}
class TextAreaInput(Input):
@@ -195,9 +191,7 @@ class MultiCheckboxInput(Input):
class ServicesCheckboxInput(MultiCheckboxInput):
def __init__(self, id, label, infotext=None):
- services = [
- Option(s.modulation, s.name) for s in Modes.getAvailableServices()
- ]
+ services = [Option(s.modulation, s.name) for s in Modes.getAvailableServices()]
super().__init__(id, label, services, infotext)
diff --git a/owrx/http.py b/owrx/http.py
index 538bec9..743f2c9 100644
--- a/owrx/http.py
+++ b/owrx/http.py
@@ -1,14 +1,6 @@
from owrx.controllers.status import StatusController
-from owrx.controllers.template import (
- IndexController,
- MapController,
- FeatureController
-)
-from owrx.controllers.assets import (
- OwrxAssetsController,
- AprsSymbolsController,
- CompiledAssetsController
-)
+from owrx.controllers.template import IndexController, MapController, FeatureController
+from owrx.controllers.assets import OwrxAssetsController, AprsSymbolsController, CompiledAssetsController
from owrx.controllers.websocket import WebSocketController
from owrx.controllers.api import ApiController
from owrx.controllers.metrics import MetricsController
@@ -109,7 +101,9 @@ class Router(object):
StaticRoute("/metrics", MetricsController),
StaticRoute("/settings", SettingsController),
StaticRoute("/generalsettings", GeneralSettingsController),
- StaticRoute("/generalsettings", GeneralSettingsController, method="POST", options={"action": "processFormData"}),
+ StaticRoute(
+ "/generalsettings", GeneralSettingsController, method="POST", options={"action": "processFormData"}
+ ),
StaticRoute("/sdrsettings", SdrSettingsController),
StaticRoute("/login", SessionController, options={"action": "loginAction"}),
StaticRoute("/login", SessionController, method="POST", options={"action": "processLoginAction"}),
diff --git a/owrx/js8.py b/owrx/js8.py
index 79e1850..caee60d 100644
--- a/owrx/js8.py
+++ b/owrx/js8.py
@@ -102,15 +102,17 @@ class Js8Parser(Parser):
Map.getSharedInstance().updateLocation(
frame.callsign, LocatorLocation(frame.grid), "JS8", self.band
)
- ReportingEngine.getSharedInstance().spot({
- "callsign": frame.callsign,
- "mode": "JS8",
- "locator": frame.grid,
- "freq": self.dial_freq + frame.freq,
- "db": frame.db,
- "timestamp": frame.timestamp,
- "msg": str(frame)
- })
+ ReportingEngine.getSharedInstance().spot(
+ {
+ "callsign": frame.callsign,
+ "mode": "JS8",
+ "locator": frame.grid,
+ "freq": self.dial_freq + frame.freq,
+ "db": frame.db,
+ "timestamp": frame.timestamp,
+ "msg": str(frame),
+ }
+ )
except Exception:
logger.exception("error while parsing js8 message")
diff --git a/owrx/kiss.py b/owrx/kiss.py
index bb20489..cae7394 100644
--- a/owrx/kiss.py
+++ b/owrx/kiss.py
@@ -13,6 +13,7 @@ TFESC = 0xDD
FEET_PER_METER = 3.28084
+
class DirewolfConfig(object):
def getConfig(self, port, is_service):
pm = Config.get()
@@ -40,7 +41,7 @@ IGLOGIN {callsign} {password}
)
if pm["aprs_igate_beacon"]:
- #Format beacon lat/lon
+ # Format beacon lat/lon
lat = pm["receiver_gps"]["lat"]
lon = pm["receiver_gps"]["lon"]
direction_ns = "N" if lat > 0 else "S"
@@ -50,13 +51,13 @@ IGLOGIN {callsign} {password}
lat = "{0:02d}^{1:05.2f}{2}".format(int(lat), (lat - int(lat)) * 60, direction_ns)
lon = "{0:03d}^{1:05.2f}{2}".format(int(lon), (lon - int(lon)) * 60, direction_we)
- #Format beacon details
- symbol = str(pm["aprs_igate_symbol"]) if "aprs_igate_symbol" in pm else "R&"
- gain = "GAIN=" + str(pm["aprs_igate_gain"]) if "aprs_igate_gain" in pm else ""
- adir = "DIR=" + str(pm["aprs_igate_dir"]) if "aprs_igate_dir" in pm else ""
- comment = str(pm["aprs_igate_comment"]) if "aprs_igate_comment" in pm else "\"OpenWebRX APRS gateway\""
+ # Format beacon details
+ symbol = str(pm["aprs_igate_symbol"]) if "aprs_igate_symbol" in pm else "R&"
+ gain = "GAIN=" + str(pm["aprs_igate_gain"]) if "aprs_igate_gain" in pm else ""
+ adir = "DIR=" + str(pm["aprs_igate_dir"]) if "aprs_igate_dir" in pm else ""
+ comment = str(pm["aprs_igate_comment"]) if "aprs_igate_comment" in pm else '"OpenWebRX APRS gateway"'
- #Convert height from meters to feet if specified
+ # Convert height from meters to feet if specified
height = ""
if "aprs_igate_height" in pm:
try:
@@ -64,18 +65,21 @@ IGLOGIN {callsign} {password}
height_ft = round(height_m * FEET_PER_METER)
height = "HEIGHT=" + str(height_ft)
except:
- logger.error("Cannot parse 'aprs_igate_height', expected float: " + str(pm["aprs_igate_height"]))
+ logger.error(
+ "Cannot parse 'aprs_igate_height', expected float: " + str(pm["aprs_igate_height"])
+ )
- if((len(comment) > 0) and ((comment[0] != '"') or (comment[len(comment)-1] != '"'))):
- comment = "\"" + comment + "\""
- elif(len(comment) == 0):
- comment = "\"\""
+ if (len(comment) > 0) and ((comment[0] != '"') or (comment[len(comment) - 1] != '"')):
+ comment = '"' + comment + '"'
+ elif len(comment) == 0:
+ comment = '""'
pbeacon = "PBEACON sendto=IG delay=0:30 every=60:00 symbol={symbol} lat={lat} long={lon} {height} {gain} {adir} comment={comment}".format(
- symbol=symbol, lat=lat, lon=lon, height=height, gain=gain, adir=adir, comment=comment )
+ symbol=symbol, lat=lat, lon=lon, height=height, gain=gain, adir=adir, comment=comment
+ )
logger.info("APRS PBEACON String: " + pbeacon)
-
+
config += "\n" + pbeacon + "\n"
return config
@@ -98,7 +102,7 @@ class KissClient(object):
pass
def __init__(self, port):
- delay = .5
+ delay = 0.5
retries = 0
while True:
try:
diff --git a/owrx/modes.py b/owrx/modes.py
index 0fcf366..f544e19 100644
--- a/owrx/modes.py
+++ b/owrx/modes.py
@@ -60,24 +60,47 @@ class Modes(object):
AnalogMode("usb", "USB", bandpass=Bandpass(300, 3000)),
AnalogMode("cw", "CW", bandpass=Bandpass(700, 900)),
AnalogMode("dmr", "DMR", bandpass=Bandpass(-4000, 4000), requirements=["digital_voice_digiham"], squelch=False),
- AnalogMode("dstar", "D-Star", bandpass=Bandpass(-3250, 3250), requirements=["digital_voice_dsd"], squelch=False),
+ AnalogMode(
+ "dstar", "D-Star", bandpass=Bandpass(-3250, 3250), requirements=["digital_voice_dsd"], squelch=False
+ ),
AnalogMode("nxdn", "NXDN", bandpass=Bandpass(-3250, 3250), requirements=["digital_voice_dsd"], squelch=False),
AnalogMode("ysf", "YSF", bandpass=Bandpass(-4000, 4000), requirements=["digital_voice_digiham"], squelch=False),
AnalogMode("m17", "M17", bandpass=Bandpass(-4000, 4000), requirements=["digital_voice_m17"], squelch=False),
- AnalogMode("freedv", "FreeDV", bandpass=Bandpass(300, 3000), requirements=["digital_voice_freedv"], squelch=False),
+ AnalogMode(
+ "freedv", "FreeDV", bandpass=Bandpass(300, 3000), requirements=["digital_voice_freedv"], squelch=False
+ ),
AnalogMode("drm", "DRM", bandpass=Bandpass(-5000, 5000), requirements=["drm"], squelch=False),
DigitalMode("bpsk31", "BPSK31", underlying=["usb"]),
DigitalMode("bpsk63", "BPSK63", underlying=["usb"]),
- DigitalMode("ft8", "FT8", underlying=["usb"], bandpass=Bandpass(0, 3000), requirements=["wsjt-x"], service=True),
- DigitalMode("ft4", "FT4", underlying=["usb"], bandpass=Bandpass(0, 3000), requirements=["wsjt-x"], service=True),
- DigitalMode("jt65", "JT65", underlying=["usb"], bandpass=Bandpass(0, 3000), requirements=["wsjt-x"], service=True),
- DigitalMode("jt9", "JT9", underlying=["usb"], bandpass=Bandpass(0, 3000), requirements=["wsjt-x"], service=True),
+ DigitalMode(
+ "ft8", "FT8", underlying=["usb"], bandpass=Bandpass(0, 3000), requirements=["wsjt-x"], service=True
+ ),
+ DigitalMode(
+ "ft4", "FT4", underlying=["usb"], bandpass=Bandpass(0, 3000), requirements=["wsjt-x"], service=True
+ ),
+ DigitalMode(
+ "jt65", "JT65", underlying=["usb"], bandpass=Bandpass(0, 3000), requirements=["wsjt-x"], service=True
+ ),
+ DigitalMode(
+ "jt9", "JT9", underlying=["usb"], bandpass=Bandpass(0, 3000), requirements=["wsjt-x"], service=True
+ ),
DigitalMode(
"wspr", "WSPR", underlying=["usb"], bandpass=Bandpass(1350, 1650), requirements=["wsjt-x"], service=True
),
- DigitalMode("fst4", "FST4", underlying=["usb"], bandpass=Bandpass(0, 3000), requirements=["wsjt-x-2-3"], service=True),
- DigitalMode("fst4w", "FST4W", underlying=["usb"], bandpass=Bandpass(1350, 1650), requirements=["wsjt-x-2-3"], service=True),
- DigitalMode("js8", "JS8Call", underlying=["usb"], bandpass=Bandpass(0, 3000), requirements=["js8call"], service=True),
+ DigitalMode(
+ "fst4", "FST4", underlying=["usb"], bandpass=Bandpass(0, 3000), requirements=["wsjt-x-2-3"], service=True
+ ),
+ DigitalMode(
+ "fst4w",
+ "FST4W",
+ underlying=["usb"],
+ bandpass=Bandpass(1350, 1650),
+ requirements=["wsjt-x-2-3"],
+ service=True,
+ ),
+ DigitalMode(
+ "js8", "JS8Call", underlying=["usb"], bandpass=Bandpass(0, 3000), requirements=["js8call"], service=True
+ ),
DigitalMode(
"packet",
"Packet",
diff --git a/owrx/pskreporter.py b/owrx/pskreporter.py
index 533a251..4106648 100644
--- a/owrx/pskreporter.py
+++ b/owrx/pskreporter.py
@@ -150,10 +150,10 @@ class Uploader(object):
# id
[0x00, 0x03]
# length
- + list(length.to_bytes(2, 'big'))
+ + list(length.to_bytes(2, "big"))
+ Uploader.receieverDelimiter
# number of fields
- + list(num_fields.to_bytes(2, 'big'))
+ + list(num_fields.to_bytes(2, "big"))
# padding
+ [0x00, 0x00]
# receiverCallsign
@@ -163,9 +163,7 @@ class Uploader(object):
# decodingSoftware
+ [0x80, 0x08, 0xFF, 0xFF, 0x00, 0x00, 0x76, 0x8F]
# antennaInformation
- + (
- [0x80, 0x09, 0xFF, 0xFF, 0x00, 0x00, 0x76, 0x8F] if with_antenna else []
- )
+ + ([0x80, 0x09, 0xFF, 0xFF, 0x00, 0x00, 0x76, 0x8F] if with_antenna else [])
# padding
+ [0x00, 0x00]
)
diff --git a/owrx/receiverid.py b/owrx/receiverid.py
index c7b12b7..e21760a 100644
--- a/owrx/receiverid.py
+++ b/owrx/receiverid.py
@@ -77,6 +77,7 @@ class ReceiverId(object):
return Key(keyString)
except KeyException as e:
logger.error(e)
+
config = Config.get()
if "receiver_keys" not in config or config["receiver_keys"] is None:
return None
diff --git a/owrx/reporting.py b/owrx/reporting.py
index faa427c..32e996c 100644
--- a/owrx/reporting.py
+++ b/owrx/reporting.py
@@ -40,10 +40,12 @@ class ReportingEngine(object):
if "pskreporter_enabled" in config and config["pskreporter_enabled"]:
# inline import due to circular dependencies
from owrx.pskreporter import PskReporter
+
self.reporters += [PskReporter()]
if "wsprnet_enabled" in config and config["wsprnet_enabled"]:
# inline import due to circular dependencies
from owrx.wsprnet import WsprnetReporter
+
self.reporters += [WsprnetReporter()]
def stop(self):
diff --git a/owrx/service/__init__.py b/owrx/service/__init__.py
index 81d0877..540e3c3 100644
--- a/owrx/service/__init__.py
+++ b/owrx/service/__init__.py
@@ -137,9 +137,7 @@ class ServiceHandler(SdrSourceEventClient):
dials = [
dial
- for dial in Bandplan.getSharedInstance().collectDialFrequencies(
- frequency_range
- )
+ for dial in Bandplan.getSharedInstance().collectDialFrequencies(frequency_range)
if self.isSupported(dial["mode"])
]
@@ -150,16 +148,12 @@ class ServiceHandler(SdrSourceEventClient):
groups = self.optimizeResampling(dials, sr)
if groups is None:
for dial in dials:
- self.services.append(
- self.setupService(dial["mode"], dial["frequency"], self.source)
- )
+ self.services.append(self.setupService(dial["mode"], dial["frequency"], self.source))
else:
for group in groups:
cf = self.get_center_frequency(group)
bw = self.get_bandwidth(group)
- logger.debug(
- "group center frequency: {0}, bandwidth: {1}".format(cf, bw)
- )
+ logger.debug("group center frequency: {0}, bandwidth: {1}".format(cf, bw))
resampler_props = PropertyLayer()
resampler_props["center_freq"] = cf
resampler_props["samp_rate"] = bw
@@ -167,11 +161,7 @@ class ServiceHandler(SdrSourceEventClient):
resampler.start()
for dial in group:
- self.services.append(
- self.setupService(
- dial["mode"], dial["frequency"], resampler
- )
- )
+ self.services.append(self.setupService(dial["mode"], dial["frequency"], resampler))
# resampler goes in after the services since it must not be shutdown as long as the services are still running
self.services.append(resampler)
@@ -238,9 +228,7 @@ class ServiceHandler(SdrSourceEventClient):
results = sorted(usages, key=lambda f: f["total_bandwidth"])
for r in results:
- logger.debug(
- "splits: {0}, total: {1}".format(r["num_splits"], r["total_bandwidth"])
- )
+ logger.debug("splits: {0}, total: {1}".format(r["num_splits"], r["total_bandwidth"]))
best = results[0]
if best["num_splits"] is None:
@@ -267,7 +255,7 @@ class ServiceHandler(SdrSourceEventClient):
d.set_secondary_demodulator(mode)
d.set_audio_compression("none")
d.set_samp_rate(source.getProps()["samp_rate"])
- d.set_temporary_directory(Config.get()['temporary_directory'])
+ d.set_temporary_directory(Config.get()["temporary_directory"])
d.set_service()
d.start()
return d
diff --git a/owrx/service/schedule.py b/owrx/service/schedule.py
index 141962d..c024d33 100644
--- a/owrx/service/schedule.py
+++ b/owrx/service/schedule.py
@@ -68,6 +68,7 @@ class DatetimeScheduleEntry(ScheduleEntry):
def getNextActivation(self):
return self.startTime
+
class Schedule(ABC):
@staticmethod
def parse(props):
@@ -140,7 +141,7 @@ class DaylightSchedule(TimerangeSchedule):
degtorad = math.pi / 180
radtodeg = 180 / math.pi
- #Number of days since 01/01
+ # Number of days since 01/01
days = date.timetuple().tm_yday
# Longitudinal correction
diff --git a/owrx/source/__init__.py b/owrx/source/__init__.py
index 39c143d..111f507 100644
--- a/owrx/source/__init__.py
+++ b/owrx/source/__init__.py
@@ -82,17 +82,17 @@ class SdrSource(ABC):
for id, p in self.props["profiles"].items():
props.replaceLayer(0, self._getProfilePropertyLayer(p))
if "center_freq" not in props:
- logger.warning("Profile \"%s\" does not specify a center_freq", id)
+ logger.warning('Profile "%s" does not specify a center_freq', id)
continue
if "samp_rate" not in props:
- logger.warning("Profile \"%s\" does not specify a samp_rate", id)
+ logger.warning('Profile "%s" does not specify a samp_rate', id)
continue
if "start_freq" in props:
start_freq = props["start_freq"]
srh = props["samp_rate"] / 2
center_freq = props["center_freq"]
if start_freq < center_freq - srh or start_freq > center_freq + srh:
- logger.warning("start_freq for profile \"%s\" is out of range", id)
+ logger.warning('start_freq for profile "%s" is out of range', id)
def _getProfilePropertyLayer(self, profile):
layer = PropertyLayer()
diff --git a/owrx/source/connector.py b/owrx/source/connector.py
index 40095b0..8789cbe 100644
--- a/owrx/source/connector.py
+++ b/owrx/source/connector.py
@@ -15,18 +15,22 @@ class ConnectorSource(SdrSource):
super().__init__(id, props)
def getCommandMapper(self):
- return super().getCommandMapper().setMappings(
- {
- "samp_rate": Option("-s"),
- "tuner_freq": Option("-f"),
- "port": Option("-p"),
- "controlPort": Option("-c"),
- "device": Option("-d"),
- "iqswap": Flag("-i"),
- "rtltcp_compat": Option("-r"),
- "ppm": Option("-P"),
- "rf_gain": Option("-g"),
- }
+ return (
+ super()
+ .getCommandMapper()
+ .setMappings(
+ {
+ "samp_rate": Option("-s"),
+ "tuner_freq": Option("-f"),
+ "port": Option("-p"),
+ "controlPort": Option("-c"),
+ "device": Option("-d"),
+ "iqswap": Flag("-i"),
+ "rtltcp_compat": Option("-r"),
+ "ppm": Option("-P"),
+ "rf_gain": Option("-g"),
+ }
+ )
)
def sendControlMessage(self, changes):
diff --git a/owrx/source/direct.py b/owrx/source/direct.py
index cd36b55..e5d0024 100644
--- a/owrx/source/direct.py
+++ b/owrx/source/direct.py
@@ -32,11 +32,14 @@ class DirectSource(SdrSource, metaclass=ABCMeta):
"These depend on nmux_memory and samp_rate options in config_webrx.py"
)
- return ["nmux --bufsize %d --bufcnt %d --port %d --address 127.0.0.1" % (
- nmux_bufsize,
- nmux_bufcnt,
- self.port,
- )]
+ return [
+ "nmux --bufsize %d --bufcnt %d --port %d --address 127.0.0.1"
+ % (
+ nmux_bufsize,
+ nmux_bufcnt,
+ self.port,
+ )
+ ]
def getCommand(self):
return super().getCommand() + self.getFormatConversion() + self.getNmuxCommand()
diff --git a/owrx/source/eb200.py b/owrx/source/eb200.py
index a234a59..50ef622 100644
--- a/owrx/source/eb200.py
+++ b/owrx/source/eb200.py
@@ -8,8 +8,10 @@ class Eb200Source(ConnectorSource):
super()
.getCommandMapper()
.setBase("eb200_connector")
- .setMappings({
- "long": Flag("-l"),
- "remote": Argument(),
- })
+ .setMappings(
+ {
+ "long": Flag("-l"),
+ "remote": Argument(),
+ }
+ )
)
diff --git a/owrx/source/fifi_sdr.py b/owrx/source/fifi_sdr.py
index badf3ac..5b51558 100644
--- a/owrx/source/fifi_sdr.py
+++ b/owrx/source/fifi_sdr.py
@@ -9,9 +9,13 @@ logger = logging.getLogger(__name__)
class FifiSdrSource(DirectSource):
def getCommandMapper(self):
- return super().getCommandMapper().setBase("arecord").setMappings(
- {"device": Option("-D"), "samp_rate": Option("-r")}
- ).setStatic("-t raw -f S16_LE -c2 -")
+ return (
+ super()
+ .getCommandMapper()
+ .setBase("arecord")
+ .setMappings({"device": Option("-D"), "samp_rate": Option("-r")})
+ .setStatic("-t raw -f S16_LE -c2 -")
+ )
def getEventNames(self):
return super().getEventNames() + ["device"]
@@ -20,7 +24,7 @@ class FifiSdrSource(DirectSource):
return ["csdr convert_s16_f", "csdr gain_ff 5"]
def sendRockProgFrequency(self, frequency):
- process = Popen(["rockprog", "--vco", "-w", "--freq={}".format(frequency / 1E6)])
+ process = Popen(["rockprog", "--vco", "-w", "--freq={}".format(frequency / 1e6)])
process.communicate()
rc = process.wait()
if rc != 0:
diff --git a/owrx/source/hackrf.py b/owrx/source/hackrf.py
index a103218..9ced99e 100644
--- a/owrx/source/hackrf.py
+++ b/owrx/source/hackrf.py
@@ -8,4 +8,4 @@ class HackrfSource(SoapyConnectorSource):
return mappings
def getDriver(self):
- return "hackrf"
\ No newline at end of file
+ return "hackrf"
diff --git a/owrx/source/hpsdr.py b/owrx/source/hpsdr.py
index 50cac77..6d88c67 100644
--- a/owrx/source/hpsdr.py
+++ b/owrx/source/hpsdr.py
@@ -17,6 +17,7 @@ from owrx.command import Flag, Option
# If you omit `remote` from config_webrx.py, hpsdrconnector will use the HPSDR discovery protocol
# to find radios on your local network and will connect to the first radio it discovered.
+
class HpsdrSource(ConnectorSource):
def getCommandMapper(self):
return (
@@ -24,10 +25,11 @@ class HpsdrSource(ConnectorSource):
.getCommandMapper()
.setBase("hpsdrconnector")
.setMappings(
- {
- "tuner_freq": Option("--frequency"),
- "samp_rate": Option("--samplerate"),
- "remote": Option("--radio"),
- "rf_gain": Option("--gain"),
- })
+ {
+ "tuner_freq": Option("--frequency"),
+ "samp_rate": Option("--samplerate"),
+ "remote": Option("--radio"),
+ "rf_gain": Option("--gain"),
+ }
+ )
)
diff --git a/owrx/source/perseussdr.py b/owrx/source/perseussdr.py
index bad4f38..1e2b8ec 100644
--- a/owrx/source/perseussdr.py
+++ b/owrx/source/perseussdr.py
@@ -17,15 +17,21 @@ from owrx.command import Flag, Option
# floating points (option -p),no need for further conversions,
# so the method getFormatConversion(self) is not implemented at all.
+
class PerseussdrSource(DirectSource):
def getCommandMapper(self):
- return super().getCommandMapper().setBase("perseustest -p -d -1 -a -t 0 -o - ").setMappings(
- {
- "samp_rate": Option("-s"),
- "tuner_freq": Option("-f"),
- "attenuator": Option("-u"),
- "adc_preamp": Option("-m"),
- "adc_dither": Option("-x"),
- "wideband": Option("-w"),
- }
+ return (
+ super()
+ .getCommandMapper()
+ .setBase("perseustest -p -d -1 -a -t 0 -o - ")
+ .setMappings(
+ {
+ "samp_rate": Option("-s"),
+ "tuner_freq": Option("-f"),
+ "attenuator": Option("-u"),
+ "adc_preamp": Option("-m"),
+ "adc_dither": Option("-x"),
+ "wideband": Option("-w"),
+ }
+ )
)
diff --git a/owrx/source/rtl_tcp.py b/owrx/source/rtl_tcp.py
index 03c3109..ba6ac1f 100644
--- a/owrx/source/rtl_tcp.py
+++ b/owrx/source/rtl_tcp.py
@@ -8,9 +8,11 @@ class RtlTcpSource(ConnectorSource):
super()
.getCommandMapper()
.setBase("rtl_tcp_connector")
- .setMappings({
- "bias_tee": Flag("-b"),
- "direct_sampling": Option("-e"),
- "remote": Argument(),
- })
+ .setMappings(
+ {
+ "bias_tee": Flag("-b"),
+ "direct_sampling": Option("-e"),
+ "remote": Argument(),
+ }
+ )
)
diff --git a/owrx/source/soapy.py b/owrx/source/soapy.py
index 0c03a67..64c0713 100644
--- a/owrx/source/soapy.py
+++ b/owrx/source/soapy.py
@@ -5,11 +5,16 @@ from .connector import ConnectorSource
class SoapyConnectorSource(ConnectorSource, metaclass=ABCMeta):
def getCommandMapper(self):
- return super().getCommandMapper().setBase("soapy_connector").setMappings(
- {
- "antenna": Option("-a"),
- "soapy_settings": Option("-t"),
- }
+ return (
+ super()
+ .getCommandMapper()
+ .setBase("soapy_connector")
+ .setMappings(
+ {
+ "antenna": Option("-a"),
+ "soapy_settings": Option("-t"),
+ }
+ )
)
"""
diff --git a/owrx/users.py b/owrx/users.py
index 43e0865..0398108 100644
--- a/owrx/users.py
+++ b/owrx/users.py
@@ -29,7 +29,7 @@ class Password(ABC):
class CleartextPassword(Password):
def is_valid(self, inp: str):
- return self.pwinfo['value'] == inp
+ return self.pwinfo["value"] == inp
class User(object):
diff --git a/owrx/wsjt.py b/owrx/wsjt.py
index c432831..fb8df5b 100644
--- a/owrx/wsjt.py
+++ b/owrx/wsjt.py
@@ -99,7 +99,7 @@ class Ft4Profile(WsjtProfile):
class Fst4Profile(WsjtProfile):
- availableIntervals = [15, 30, 60, 120, 300, 900, 1800]
+ availableIntervals = [15, 30, 60, 120, 300, 900, 1800]
def __init__(self, interval):
self.interval = interval
@@ -208,7 +208,7 @@ class Decoder(ABC):
dateformat = self.profile.getTimestampFormat()
remain = instring[len(dateformat) + 1:]
try:
- ts = datetime.strptime(instring[0:len(dateformat)], dateformat)
+ ts = datetime.strptime(instring[0: len(dateformat)], dateformat)
return remain, int(
datetime.combine(datetime.utcnow().date(), ts.time()).replace(tzinfo=timezone.utc).timestamp() * 1000
)
diff --git a/owrx/wsprnet.py b/owrx/wsprnet.py
index 35bbe44..aff4fa8 100644
--- a/owrx/wsprnet.py
+++ b/owrx/wsprnet.py
@@ -43,24 +43,26 @@ class Worker(threading.Thread):
# function=wspr&date=210114&time=1732&sig=-15&dt=0.5&drift=0&tqrg=7.040019&tcall=DF2UU&tgrid=JN48&dbm=37&version=2.3.0-rc3&rcall=DD5JFK&rgrid=JN58SC&rqrg=7.040047&mode=2
# {'timestamp': 1610655960000, 'db': -23.0, 'dt': 0.3, 'freq': 7040048, 'drift': -1, 'msg': 'LA3JJ JO59 37', 'callsign': 'LA3JJ', 'locator': 'JO59', 'mode': 'WSPR'}
date = datetime.fromtimestamp(spot["timestamp"] / 1000, tz=timezone.utc)
- data = parse.urlencode({
- "function": "wspr",
- "date": date.strftime("%y%m%d"),
- "time": date.strftime("%H%M"),
- "sig": spot["db"],
- "dt": spot["dt"],
- # FST4W does not have drift
- "drift": spot["drift"] if "drift" in spot else 0,
- "tqrg": spot["freq"] / 1E6,
- "tcall": spot["callsign"],
- "tgrid": spot["locator"],
- "dbm": spot["dbm"],
- "version": openwebrx_version,
- "rcall": self.callsign,
- "rgrid": self.locator,
- # mode 2 = WSPR 2 minutes
- "mode": self._getMode(spot)
- }).encode()
+ data = parse.urlencode(
+ {
+ "function": "wspr",
+ "date": date.strftime("%y%m%d"),
+ "time": date.strftime("%H%M"),
+ "sig": spot["db"],
+ "dt": spot["dt"],
+ # FST4W does not have drift
+ "drift": spot["drift"] if "drift" in spot else 0,
+ "tqrg": spot["freq"] / 1e6,
+ "tcall": spot["callsign"],
+ "tgrid": spot["locator"],
+ "dbm": spot["dbm"],
+ "version": openwebrx_version,
+ "rcall": self.callsign,
+ "rgrid": self.locator,
+ # mode 2 = WSPR 2 minutes
+ "mode": self._getMode(spot),
+ }
+ ).encode()
request.urlopen("http://wsprnet.org/post/", data)
diff --git a/setup.py b/setup.py
index e8d7524..076750c 100644
--- a/setup.py
+++ b/setup.py
@@ -6,12 +6,24 @@ try:
from setuptools import find_namespace_packages
except ImportError:
from setuptools import PEP420PackageFinder
+
find_namespace_packages = PEP420PackageFinder.find
setup(
name="OpenWebRX",
version=str(looseversion),
- packages=find_namespace_packages(include=["owrx", "owrx.source", "owrx.service", "owrx.controllers", "owrx.property", "owrx.form", "csdr", "htdocs"]),
+ packages=find_namespace_packages(
+ include=[
+ "owrx",
+ "owrx.source",
+ "owrx.service",
+ "owrx.controllers",
+ "owrx.property",
+ "owrx.form",
+ "csdr",
+ "htdocs",
+ ]
+ ),
package_data={"htdocs": [f[len("htdocs/") :] for f in glob("htdocs/**/*", recursive=True)]},
entry_points={"console_scripts": ["openwebrx=owrx.__main__:main"]},
url="https://www.openwebrx.de/",
diff --git a/test/property/test_property_filter.py b/test/property/test_property_filter.py
index db6dfd3..0c9ac81 100644
--- a/test/property/test_property_filter.py
+++ b/test/property/test_property_filter.py
@@ -4,7 +4,6 @@ from owrx.property import PropertyLayer, PropertyFilter
class PropertyFilterTest(TestCase):
-
def testPassesProperty(self):
pm = PropertyLayer()
pm["testkey"] = "testvalue"