openwebrx/owrx/feature.py

718 lines
27 KiB
Python
Raw Normal View History

import subprocess
from functools import reduce
2020-09-20 19:30:18 +02:00
from operator import and_
2019-06-15 13:29:59 +02:00
import re
from distutils.version import LooseVersion, StrictVersion
import inspect
2021-02-11 19:31:44 +01:00
from owrx.config.core import CoreConfig
from owrx.config import Config
import shlex
import os
from datetime import datetime, timedelta
import logging
logger = logging.getLogger(__name__)
class UnknownFeatureException(Exception):
pass
class FeatureCache(object):
sharedInstance = None
@staticmethod
def getSharedInstance():
if FeatureCache.sharedInstance is None:
FeatureCache.sharedInstance = FeatureCache()
return FeatureCache.sharedInstance
def __init__(self):
self.cache = {}
self.cachetime = timedelta(hours=2)
def has(self, feature):
if feature not in self.cache:
return False
now = datetime.now()
if self.cache[feature]["valid_to"] < now:
return False
return True
def get(self, feature):
return self.cache[feature]["value"]
def set(self, feature, value):
valid_to = datetime.now() + self.cachetime
self.cache[feature] = {"value": value, "valid_to": valid_to}
class FeatureDetector(object):
features = {
# core features; we won't start without these
"core": ["csdr"],
# different types of sdrs and their requirements
"rtl_sdr": ["rtl_connector"],
"rtl_sdr_soapy": ["soapy_connector", "soapy_rtl_sdr"],
"rtl_tcp": ["rtl_tcp_connector"],
2019-12-27 11:37:12 +01:00
"sdrplay": ["soapy_connector", "soapy_sdrplay"],
2020-05-30 22:58:31 +02:00
"hackrf": ["soapy_connector", "soapy_hackrf"],
2021-09-17 18:58:48 +02:00
"perseussdr": ["perseustest", "nmux"],
2019-12-27 11:37:12 +01:00
"airspy": ["soapy_connector", "soapy_airspy"],
"airspyhf": ["soapy_connector", "soapy_airspyhf"],
2023-10-15 12:31:59 +02:00
"afedri": ["soapy_connector", "soapy_afedri"],
2020-01-10 19:54:53 +01:00
"lime_sdr": ["soapy_connector", "soapy_lime_sdr"],
2021-09-17 18:58:48 +02:00
"fifi_sdr": ["alsa", "rockprog", "nmux"],
"pluto_sdr": ["soapy_connector", "soapy_pluto_sdr"],
2020-02-09 13:59:37 +01:00
"soapy_remote": ["soapy_connector", "soapy_remote"],
"uhd": ["soapy_connector", "soapy_uhd"],
2020-05-10 00:03:14 +02:00
"radioberry": ["soapy_connector", "soapy_radioberry"],
2020-07-09 15:39:33 +02:00
"fcdpp": ["soapy_connector", "soapy_fcdpp"],
2022-01-12 15:48:06 +01:00
"bladerf": ["soapy_connector", "soapy_bladerf"],
2020-11-27 18:49:33 +01:00
"sddc": ["sddc_connector"],
2020-11-02 13:11:54 +01:00
"hpsdr": ["hpsdr_connector"],
2021-02-03 03:21:09 +01:00
"runds": ["runds_connector"],
# optional features and their requirements
2021-09-17 18:58:48 +02:00
"digital_voice_digiham": ["digiham", "codecserver_ambe"],
"digital_voice_freedv": ["freedv_rx"],
2023-06-30 11:58:34 +02:00
"digital_voice_m17": ["m17_demod"],
2021-09-17 18:58:48 +02:00
"wsjt-x": ["wsjtx"],
"wsjt-x-2-3": ["wsjtx_2_3"],
"wsjt-x-2-4": ["wsjtx_2_4"],
2023-02-14 15:38:33 +01:00
"msk144": ["msk144decoder"],
2021-09-17 18:58:48 +02:00
"packet": ["direwolf"],
"pocsag": ["digiham"],
"js8call": ["js8", "js8py"],
2021-09-17 18:58:48 +02:00
"drm": ["dream"],
"dump1090": ["dump1090"],
"ism": ["rtl_433"],
2023-09-03 23:48:56 +02:00
"dumphfdl": ["dumphfdl"],
2023-09-04 19:02:43 +02:00
"dumpvdl2": ["dumpvdl2"],
"redsea": ["redsea"],
"dab": ["csdreti", "dablin"],
"mqtt": ["paho_mqtt"],
}
def feature_availability(self):
return {name: self.is_available(name) for name in FeatureDetector.features}
def feature_report(self):
def requirement_details(name):
available = self.has_requirement(name)
return {
"available": available,
# as of now, features are always enabled as soon as they are available. this may change in the future.
"enabled": available,
"description": self.get_requirement_description(name),
}
def feature_details(name):
return {
"available": self.is_available(name),
"requirements": {name: requirement_details(name) for name in self.get_requirements(name)},
}
return {name: feature_details(name) for name in FeatureDetector.features}
def is_available(self, feature):
return self.has_requirements(self.get_requirements(feature))
def get_failed_requirements(self, feature):
return [req for req in self.get_requirements(feature) if not self.has_requirement(req)]
def get_requirements(self, feature):
try:
return FeatureDetector.features[feature]
except KeyError:
raise UnknownFeatureException('Feature "{0}" is not known.'.format(feature))
def has_requirements(self, requirements):
passed = True
for requirement in requirements:
passed = passed and self.has_requirement(requirement)
return passed
def _get_requirement_method(self, requirement):
methodname = "has_" + requirement
if hasattr(self, methodname) and callable(getattr(self, methodname)):
return getattr(self, methodname)
return None
def has_requirement(self, requirement):
cache = FeatureCache.getSharedInstance()
if cache.has(requirement):
return cache.get(requirement)
method = self._get_requirement_method(requirement)
result = False
if method is not None:
result = method()
else:
logger.error("detection of requirement {0} not implement. please fix in code!".format(requirement))
cache.set(requirement, result)
return result
def get_requirement_description(self, requirement):
return inspect.getdoc(self._get_requirement_method(requirement))
def command_is_runnable(self, command, expected_result=None):
tmp_dir = CoreConfig().get_temporary_directory()
cmd = shlex.split(command)
env = os.environ.copy()
# prevent X11 programs from opening windows if called from a GUI shell
env.pop("DISPLAY", None)
try:
2021-01-20 17:01:46 +01:00
process = subprocess.Popen(
cmd,
stdin=subprocess.DEVNULL,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
cwd=tmp_dir,
env=env,
)
while True:
try:
rc = process.wait(10)
break
except subprocess.TimeoutExpired:
logger.warning("feature check command \"%s\" did not return after 10 seconds!", command)
process.kill()
if expected_result is None:
return rc != 32512
else:
return rc == expected_result
except FileNotFoundError:
return False
def has_csdr(self):
"""
2024-06-15 18:24:29 +02:00
OpenWebRX uses the demodulator and pipeline tools provided by the
[csdr project](https://github.com/jketterl/csdr).
2020-08-26 20:07:58 +02:00
2024-06-15 18:24:29 +02:00
In addition, [pycsdr](https://github.com/jketterl/pycsdr) must be installed to provide python bindings for the
csdr library.
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`python3-csdr`.
2021-09-17 18:58:48 +02:00
"""
2024-02-03 12:00:19 +01:00
required_version = LooseVersion("0.19.0")
2020-08-26 20:07:58 +02:00
try:
from pycsdr.modules import csdr_version
2021-09-17 18:58:48 +02:00
from pycsdr.modules import version as pycsdr_version
return (
LooseVersion(csdr_version) >= required_version and
LooseVersion(pycsdr_version) >= required_version
)
2021-09-17 18:58:48 +02:00
except ImportError:
2020-08-26 20:07:58 +02:00
return False
def has_nmux(self):
"""
2024-06-15 18:24:29 +02:00
Nmux is a tool provided by the csdr project. It is used for internal multiplexing of the IQ data streams.
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`nmux`.
"""
return self.command_is_runnable("nmux --help")
2020-03-15 17:24:36 +01:00
def has_perseustest(self):
"""
2024-06-15 18:24:29 +02:00
To use a Microtelecom Perseus HF receiver, you need the `perseustest` utility from
[libperseus-sdr](https://github.com/Microtelecom/libperseus-sdr).
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`perseus-tools`.
2020-03-15 17:24:36 +01:00
"""
return self.command_is_runnable("perseustest -h")
2020-03-15 17:24:36 +01:00
def has_digiham(self):
"""
2024-06-15 18:24:29 +02:00
To use digital voice modes, [digiham](https://github.com/jketterl/digiham) is required.
2024-06-15 18:24:29 +02:00
In addition, [pydigiham](https://github.com/jketterl/pydigiham) must be installed to provide python bindings
for the digiham library.
2024-06-15 18:24:29 +02:00
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`python3-digiham`.
"""
required_version = LooseVersion("0.6")
2019-06-15 13:29:59 +02:00
2021-09-17 18:58:48 +02:00
try:
from digiham.modules import digiham_version as digiham_version
from digiham.modules import version as pydigiham_version
return (
LooseVersion(digiham_version) >= required_version
and LooseVersion(pydigiham_version) >= required_version
)
2021-09-17 18:58:48 +02:00
except ImportError:
return False
2021-05-17 23:57:37 +02:00
def _check_connector(self, command, required_version):
owrx_connector_version_regex = re.compile("^{} version (.*)$".format(re.escape(command)))
2019-11-21 15:31:37 +01:00
try:
process = subprocess.Popen([command, "--version"], stdout=subprocess.PIPE)
matches = owrx_connector_version_regex.match(process.stdout.readline().decode())
if matches is None:
return False
version = LooseVersion(matches.group(1))
process.wait(1)
return version >= required_version
except FileNotFoundError:
return False
2021-05-17 23:57:37 +02:00
def _check_owrx_connector(self, command):
return self._check_connector(command, LooseVersion("0.7"))
2021-05-17 23:57:37 +02:00
2019-11-21 15:31:37 +01:00
def has_rtl_connector(self):
"""
2024-06-15 18:24:29 +02:00
The [owrx_connector](https://github.com/jketterl/owrx_connector) offers direct interfacing between your
hardware and OpenWebRX.
2024-06-15 18:24:29 +02:00
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`owrx-connector`.
"""
2021-05-17 23:57:37 +02:00
return self._check_owrx_connector("rtl_connector")
def has_rtl_tcp_connector(self):
"""
2024-06-15 18:24:29 +02:00
The [owrx_connector](https://github.com/jketterl/owrx_connector) offers direct interfacing between your
hardware and OpenWebRX.
2024-06-15 18:24:29 +02:00
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`owrx-connector`.
"""
2021-05-17 23:57:37 +02:00
return self._check_owrx_connector("rtl_tcp_connector")
2019-11-21 15:31:37 +01:00
def has_soapy_connector(self):
"""
2024-06-15 18:24:29 +02:00
The [owrx_connector](https://github.com/jketterl/owrx_connector) offers direct interfacing between your
hardware and OpenWebRX.
2024-06-15 18:24:29 +02:00
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`owrx-connector`.
2019-11-21 15:31:37 +01:00
"""
2021-05-17 23:57:37 +02:00
return self._check_owrx_connector("soapy_connector")
2019-12-27 11:37:12 +01:00
def _has_soapy_driver(self, driver):
try:
process = subprocess.Popen(["soapy_connector", "--listdrivers"], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
drivers = [line.decode().strip() for line in process.stdout]
process.wait(1)
2019-12-28 01:24:07 +01:00
return driver in drivers
except FileNotFoundError:
return False
2019-12-27 11:37:12 +01:00
2020-01-10 23:31:51 +01:00
def has_soapy_rtl_sdr(self):
"""
2024-06-15 18:24:29 +02:00
The [SoapyRTLSDR](https://github.com/pothosware/SoapyRTLSDR/wiki) module can be used as an alternative to
rtl_connector.
2024-06-15 18:24:29 +02:00
Debian and Ubuntu users should be able to install the package `soapysdr-module-rtlsdr` from their distribution.
"""
return self._has_soapy_driver("rtlsdr")
2020-01-10 23:31:51 +01:00
def has_soapy_sdrplay(self):
2019-12-27 11:37:12 +01:00
"""
2024-06-15 18:24:29 +02:00
The [SoapySDRPlay3](https://github.com/pothosware/SoapySDRPlay3) module is required for interfacing with
SDRPlay devices (RSP1\\*, RSP2\\*, RSPDuo)
2019-12-27 11:37:12 +01:00
"""
return self._has_soapy_driver("sdrplay")
2019-12-27 11:37:12 +01:00
def has_soapy_airspy(self):
"""
2024-06-15 18:24:29 +02:00
The [SoapyAirspy](https://github.com/pothosware/SoapyAirspy/wiki) module is required for interfacing with
Airspy devices (Airspy R2, Airspy Mini).
2019-12-27 11:37:12 +01:00
2024-06-15 18:24:29 +02:00
Debian and Ubuntu users should be able to install the package `soapysdr-module-airspy` from their distribution.
2019-12-27 11:37:12 +01:00
"""
return self._has_soapy_driver("airspy")
def has_soapy_airspyhf(self):
"""
2024-06-15 18:24:29 +02:00
The [SoapyAirspyHF](https://github.com/pothosware/SoapyAirspyHF/wiki) module is required for interfacing with
Airspy HF devices (Airspy HF+, Airspy HF discovery).
2019-12-27 11:37:12 +01:00
2024-06-15 18:24:29 +02:00
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`soapysdr-module-airspyhf`.
2019-12-27 11:37:12 +01:00
"""
return self._has_soapy_driver("airspyhf")
2023-10-15 12:31:59 +02:00
def has_soapy_afedri(self):
"""
2024-06-15 18:24:29 +02:00
The [SoapyAfedri](https://github.com/alexander-sholohov/SoapyAfedri) module allows using Afedri SDR-Net devices
with SoapySDR.
2023-10-15 12:31:59 +02:00
2024-06-15 18:24:29 +02:00
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`soapysdr-module-afedri`.
2023-10-15 12:31:59 +02:00
"""
return self._has_soapy_driver("afedri")
2020-01-10 19:54:53 +01:00
def has_soapy_lime_sdr(self):
"""
2024-06-15 18:24:29 +02:00
The [LimeSuite](https://github.com/myriadrf/LimeSuite) installs - amongst other software - a Soapy driver for
the LimeSDR device series.
2020-01-10 19:54:53 +01:00
2024-06-15 18:24:29 +02:00
Debian and Ubuntu users should be able to install the package `soapysdr-module-lms7` from their distribution.
2020-01-10 19:54:53 +01:00
"""
return self._has_soapy_driver("lime")
2020-01-10 19:54:53 +01:00
def has_soapy_pluto_sdr(self):
"""
2024-06-15 18:24:29 +02:00
The [SoapyPlutoSDR](https://github.com/pothosware/SoapyPlutoSDR) module is required for interfacing with
PlutoSDR devices.
2024-06-15 18:24:29 +02:00
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`soapysdr-module-plutosdr`.
"""
return self._has_soapy_driver("plutosdr")
2020-02-09 13:59:37 +01:00
def has_soapy_remote(self):
"""
2024-06-15 18:24:29 +02:00
SoapyRemote allows the usage of remote SDR devices over the network using SoapySDRServer.
2020-02-09 13:59:37 +01:00
You can get the code and find additional information [here](https://github.com/pothosware/SoapyRemote/wiki).
2024-06-15 18:24:29 +02:00
Debian and Ubuntu users should be able to install the package `soapysdr-module-remote` from their distribution.
2020-02-09 13:59:37 +01:00
"""
return self._has_soapy_driver("remote")
def has_soapy_uhd(self):
"""
2024-06-15 18:24:29 +02:00
The [SoapyUHD](https://github.com/pothosware/SoapyUHD/wiki) module allows using UHD / USRP devices with
SoapySDR.
2024-06-15 18:24:29 +02:00
Debian and Ubuntu users should be able to install the package `soapysdr-module-uhd` from their distribution.
"""
return self._has_soapy_driver("uhd")
2020-05-10 00:03:14 +02:00
def has_soapy_radioberry(self):
"""
The Radioberry is a SDR hat for the Raspberry Pi.
You can find more information, along with its SoapySDR module [here](https://github.com/pa3gsb/Radioberry-2.x).
2024-06-15 18:24:29 +02:00
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`soapysdr-module-radioberry`.
2020-05-10 00:03:14 +02:00
"""
return self._has_soapy_driver("radioberry")
2020-05-30 22:58:31 +02:00
def has_soapy_hackrf(self):
"""
2024-06-15 18:24:29 +02:00
[SoapyHackRF](https://github.com/pothosware/SoapyHackRF/wiki) allows HackRF devices to be used with SoapySDR.
2020-05-30 22:58:31 +02:00
2024-06-15 18:24:29 +02:00
Debian and Ubuntu users should be able to install the package `soapysdr-module-hackrf` from their distribution.
2020-05-30 22:58:31 +02:00
"""
return self._has_soapy_driver("hackrf")
2020-07-09 15:39:33 +02:00
def has_soapy_fcdpp(self):
"""
2024-06-15 18:24:29 +02:00
The [SoapyFCDPP](https://github.com/pothosware/SoapyFCDPP) module allows the use of the Funcube Dongle Pro+.
2020-07-09 15:39:33 +02:00
2024-06-15 18:24:29 +02:00
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`soapysdr-module-fcdpp`.
2020-07-09 15:39:33 +02:00
"""
return self._has_soapy_driver("fcdpp")
2022-01-12 15:48:06 +01:00
def has_soapy_bladerf(self):
"""
2024-06-15 18:24:29 +02:00
The [SoapyBladeRF](https://github.com/pothosware/SoapyBladeRF) module allows the use of Blade RF devices.
2022-01-12 15:48:06 +01:00
2024-06-15 18:24:29 +02:00
Debian and Ubuntu users should be able to install the package `soapysdr-module-bladerf` from their distribution.
2022-01-12 15:48:06 +01:00
"""
return self._has_soapy_driver("bladerf")
def has_m17_demod(self):
2020-12-08 16:59:49 +01:00
"""
2024-06-15 18:24:29 +02:00
OpenWebRX uses the [M17 Demodulator](https://github.com/mobilinkd/m17-cxx-demod) to demodulate M17 digital
voice signals.
2020-12-08 16:59:49 +01:00
2024-06-15 18:24:29 +02:00
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`m17-demod`.
2020-12-08 16:59:49 +01:00
"""
2023-06-30 11:58:34 +02:00
return self.command_is_runnable("m17-demod", 0)
def has_direwolf(self):
2019-12-27 11:37:12 +01:00
"""
OpenWebRX uses the [direwolf](https://github.com/wb2osz/direwolf) software modem to decode Packet Radio and
2024-06-15 18:24:29 +02:00
report data back to APRS-IS.
2019-06-22 18:20:01 +02:00
2024-06-15 18:24:29 +02:00
Debian and Ubuntu users should be able to install the package `direwolf` from their distribution.
"""
2024-06-15 18:24:29 +02:00
return self.command_is_runnable("direwolf --help")
def has_wsjtx(self):
"""
To decode FT8 and other digimodes, you need to install the WSJT-X software suite. Please check the
2023-02-14 15:37:37 +01:00
[WSJT-X homepage](https://wsjt.sourceforge.io/) for ready-made packages or instructions
on how to build from source.
2024-06-15 18:24:29 +02:00
Debian and Ubuntu users can also install the `wsjtx` package provided by the distribution.
"""
return reduce(and_, map(self.command_is_runnable, ["jt9", "wsprd"]), True)
def _has_wsjtx_version(self, required_version):
wsjt_version_regex = re.compile("^WSJT-X (.*)$")
try:
process = subprocess.Popen(["wsjtx_app_version", "--version"], stdout=subprocess.PIPE)
matches = wsjt_version_regex.match(process.stdout.readline().decode())
if matches is None:
return False
version = LooseVersion(matches.group(1))
process.wait(1)
return version >= required_version
except FileNotFoundError:
return False
def has_wsjtx_2_3(self):
"""
Newer digital modes (e.g. FST4, FST4) require WSJT-X in at least version 2.3.
"""
return self.has_wsjtx() and self._has_wsjtx_version(LooseVersion("2.3"))
2021-02-03 19:33:02 +01:00
def has_wsjtx_2_4(self):
"""
WSJT-X version 2.4 introduced the Q65 mode.
"""
return self.has_wsjtx() and self._has_wsjtx_version(LooseVersion("2.4"))
2023-02-14 15:38:33 +01:00
def has_msk144decoder(self):
"""
2024-06-15 18:24:29 +02:00
To decode the MSK144 digimode please install
[msk144decoder](https://github.com/alexander-sholohov/msk144decoder).
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`msk144decoder`.
2023-02-14 15:38:33 +01:00
"""
return self.command_is_runnable("msk144decoder")
2020-04-12 13:10:23 +02:00
def has_js8(self):
"""
2024-06-15 18:24:29 +02:00
To decode JS8, you will need to install [JS8Call](http://js8call.com/).
2020-05-03 12:09:36 +02:00
2024-06-15 18:24:29 +02:00
Debian and Ubuntu users should be able to install the package `js8call` from their distribution.
2020-04-12 13:10:23 +02:00
"""
return self.command_is_runnable("js8")
def has_js8py(self):
"""
2024-06-15 18:24:29 +02:00
OpenWebRX uses [js8py](https://github.com/jketterl/js8py) to decode binary JS8 messages into readable text.
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`python3-js8py`.
"""
2022-11-30 01:16:12 +01:00
required_version = StrictVersion("0.2")
try:
from js8py.version import strictversion
return strictversion >= required_version
except ImportError:
return False
def has_alsa(self):
"""
Some SDR receivers are identifying themselves as a soundcard. In order to read their data, OpenWebRX relies
2024-06-15 18:24:29 +02:00
on the Alsa library.
Debian and Ubuntu users should be able to install the package `alsa-utils` from their distribution.
"""
return self.command_is_runnable("arecord --help")
2020-05-14 21:40:28 +02:00
def has_rockprog(self):
"""
2024-06-15 18:24:29 +02:00
The `rockprog` executable is required to send commands to your FiFiSDR. It needs to be installed separately.
2020-05-14 21:40:28 +02:00
You can find instructions and downloads [here](https://o28.sischa.net/fifisdr/trac/wiki/De%3Arockprog).
"""
return self.command_is_runnable("rockprog")
def has_freedv_rx(self):
2020-08-07 22:58:24 +02:00
"""
2024-06-15 18:24:29 +02:00
The `freedv_rx` executable is required to demodulate FreeDV digital transmissions. It comes together with the
2020-08-07 22:58:24 +02:00
codec2 library, but it's only a supplemental part and not installed by default or contained in its packages.
To install it, you will need to compile codec2 from source and manually install freedv\\_rx.
2020-08-07 22:58:24 +02:00
Detailed installation instructions are available on the
[OpenWebRX wiki](https://github.com/jketterl/openwebrx/wiki/FreeDV-demodulator-notes).
2024-06-15 18:24:29 +02:00
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`codec2`.
2020-08-07 22:58:24 +02:00
"""
return self.command_is_runnable("freedv_rx")
2020-09-04 18:09:02 +02:00
def has_dream(self):
2020-09-04 20:27:12 +02:00
"""
In order to be able to decode DRM broadcasts, OpenWebRX needs the "dream" DRM decoder.
2024-06-15 18:24:29 +02:00
A custom set of commands is recommended when compiling from source. Detailed installation instructions are
available on the [OpenWebRX wiki](https://github.com/jketterl/openwebrx/wiki/DRM-demodulator-notes).
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`dream-headless`.
2020-09-04 20:27:12 +02:00
"""
return self.command_is_runnable("dream --help", 0)
2020-11-02 13:11:54 +01:00
2020-11-27 18:39:10 +01:00
def has_sddc_connector(self):
2020-11-27 18:49:33 +01:00
"""
The sddc_connector allows connectivity with SDR devices powered by libsddc, e.g. RX666, RX888, HF103.
You can find more information [here](https://github.com/jketterl/sddc_connector).
"""
2021-05-17 23:57:37 +02:00
return self._check_connector("sddc_connector", LooseVersion("0.1"))
2020-11-12 23:45:39 +01:00
2020-11-02 13:11:54 +01:00
def has_hpsdr_connector(self):
"""
2024-06-15 18:24:29 +02:00
The [HPSDR Connector](https://github.com/jancona/hpsdrconnector) is required to interface OpenWebRX with
Hermes Lite 2, Red Pitaya, and similar networked SDR devices.
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`hpsdrconnector`.
2020-11-02 13:11:54 +01:00
"""
return self.command_is_runnable("hpsdrconnector -h")
2020-11-30 00:34:44 +01:00
2021-02-03 03:21:09 +01:00
def has_runds_connector(self):
2020-11-30 00:34:44 +01:00
"""
2024-06-15 18:24:29 +02:00
To use radios supporting R&S radios via EB200 or Ammos, you need to install
[runds_connector](https://github.com/jketterl/runds_connector).
2020-11-30 00:34:44 +01:00
2024-06-15 18:24:29 +02:00
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`runds-connector`.
2020-11-30 00:34:44 +01:00
"""
2021-05-17 23:57:37 +02:00
return self._check_connector("runds_connector", LooseVersion("0.2"))
def has_codecserver_ambe(self):
2021-08-03 19:52:49 +02:00
"""
2024-06-15 18:24:29 +02:00
[Codecserver](https://github.com/jketterl/codecserver) is used to decode audio data from digital voice modes using the AMBE codec.
NOTE: this feature flag checks both the availability of codecserver as well as the availability of the AMBE
codec in the configured codecserer instance.
2024-06-15 18:24:29 +02:00
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`codecserver`.
2021-08-03 19:52:49 +02:00
"""
2021-09-29 17:23:23 +02:00
config = Config.get()
2021-09-29 17:23:23 +02:00
server = ""
if "digital_voice_codecserver" in config:
2021-09-29 17:23:23 +02:00
server = config["digital_voice_codecserver"]
try:
2021-09-29 17:23:23 +02:00
from digiham.modules import MbeSynthesizer
2021-09-29 17:23:23 +02:00
return MbeSynthesizer.hasAmbe(server)
except ImportError:
return False
except ConnectionError:
return False
2023-07-02 00:43:54 +02:00
except RuntimeError as e:
logger.exception("Codecserver error while checking for AMBE support:")
return False
def has_dump1090(self):
"""
To be able to decode Mode-S and ADS-B traffic originating from airplanes, you need to install the dump1090
decoder. There is a number of forks available, any version that supports the `--ifile` and `--iformat` arguments
should work.
Recommended fork: [dump1090 by Flightaware](https://github.com/flightaware/dump1090)
2023-09-06 00:37:59 +02:00
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`dump1090-fa-minimal`.
If you are running a different fork, please make sure that the command `dump1090` (without suffixes) runs the
version you would like to use. You can use symbolic links or the
[Debian alternatives system](https://wiki.debian.org/DebianAlternatives) to achieve this.
"""
return self.command_is_runnable("dump1090 --version")
def has_rtl_433(self):
"""
2024-06-15 18:24:29 +02:00
OpenWebRX can make use of [`rtl_433`](https://github.com/merbanan/rtl_433) to decode various signals in the
ISM bands.
2024-06-15 18:24:29 +02:00
Debian and Ubuntu users should be able to install the package `rtl-433` from their distribution.
"""
return self.command_is_runnable("rtl_433 -h")
2023-09-03 23:48:56 +02:00
def has_dumphfdl(self):
"""
2024-06-15 18:24:29 +02:00
OpenWebRX supports decoding HFDL airplane communications using
[`dumphfdl`](https://github.com/szpajder/dumphfdl).
2023-09-06 00:37:59 +02:00
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`dumphfdl`.
2023-09-03 23:48:56 +02:00
"""
return self.command_is_runnable("dumphfdl --version")
2023-09-04 19:02:43 +02:00
def has_dumpvdl2(self):
"""
2024-06-15 18:24:29 +02:00
OpenWebRX supports decoding VDL Mode 2 airplane communications using
[`dumpvdl2`](https://github.com/szpajder/dumpvdl2).
2023-09-06 00:37:59 +02:00
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`dumpvdl2`.
2023-09-04 19:02:43 +02:00
"""
return self.command_is_runnable("dumpvdl2 --version")
def has_redsea(self):
"""
2024-06-15 18:24:29 +02:00
OpenWebRX can decode RDS data on WFM broadcast station if the [`redsea`](https://github.com/windytan/redsea)
decoder is available.
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`redsea`.
"""
return self.command_is_runnable("redsea --version")
def has_csdreti(self):
"""
2024-01-27 16:36:14 +01:00
To decode DAB broadcast signals, OpenWebRX needs the ETI decoder from the
[`csdr-eti`](https://github.com/jketterl/csdr-eti) project, together with the
associated python bindings from [`pycsdr-eti`](https://github.com/jketterl/pycsdr-eti).
2024-06-15 18:24:29 +02:00
If you are using the OpenWebRX Debian or Ubuntu repository, you should be able to install the package
`python3-csdr-eti`.
"""
required_version = LooseVersion("0.1")
try:
from csdreti.modules import csdreti_version
from csdreti.modules import version as pycsdreti_version
return (
LooseVersion(csdreti_version) >= required_version
and LooseVersion(pycsdreti_version) >= required_version
)
except ImportError:
return False
def has_dablin(self):
"""
2024-01-27 16:36:14 +01:00
To decode DAB broadcast signals, OpenWebRX needs the [`dablin`](https://github.com/Opendigitalradio/dablin)
decoding software.
2024-06-15 18:24:29 +02:00
Debian and Ubuntu users should be able to install the package `dablin` from their distribution.
"""
return self.command_is_runnable("dablin -h")
def has_paho_mqtt(self):
2024-02-17 00:52:35 +01:00
"""
OpenWebRX can pass decoded signal data to an MQTT broker for processing in third-party applications. To be able
to do this, the [paho-mqtt](https://pypi.org/project/paho-mqtt/) library is required.
2024-06-15 18:24:29 +02:00
Debian and Ubuntu users should be able to install the package `python3-paho-mqtt` from their distribution.
2024-02-17 00:52:35 +01:00
"""
try:
from paho.mqtt import __version__
return True
except ImportError:
return False