Adding preliminary SatDump support (experts only!)

This commit is contained in:
Marat Fayzullin 2024-03-07 18:25:08 -05:00
parent 06290bdded
commit aa64129306
5 changed files with 104 additions and 1 deletions

View File

@ -1,5 +1,5 @@
from csdr.chain.demodulator import ServiceDemodulator, DialFrequencyReceiver, FixedIfSampleRateChain
from csdr.module.toolbox import Rtl433Module, MultimonModule, DumpHfdlModule, DumpVdl2Module, Dump1090Module, AcarsDecModule, RedseaModule
from csdr.module.toolbox import Rtl433Module, MultimonModule, DumpHfdlModule, DumpVdl2Module, Dump1090Module, AcarsDecModule, RedseaModule, SatDumpModule
from pycsdr.modules import FmDemod, AudioResampler, Convert, Agc, Squelch
from pycsdr.types import Format
from owrx.toolbox import TextParser, PageParser, SelCallParser, IsmParser, RdsParser
@ -210,3 +210,46 @@ class RdsDemodulator(ServiceDemodulator, DialFrequencyReceiver):
def setDialFrequency(self, frequency: int) -> None:
self.parser.setDialFrequency(frequency)
class NoaaAptDemodulator(ServiceDemodulator, DialFrequencyReceiver):
def __init__(self, satellite: int = 19, service: bool = False):
self.sampleRate = 50000
workers = [
SatDumpModule(mode = "noaa_apt", sampleRate = self.sampleRate, options = {
"satellite_number" : satellite,
"start_timestamp" : datetime.utcnow().timestamp()
})
]
# Connect all the workers
super().__init__(workers)
def getFixedAudioRate(self) -> int:
return self.sampleRate
def supportsSquelch(self) -> bool:
return False
def setDialFrequency(self, frequency: int) -> None:
# TODO: Do something with the frequency or remove method
pass
class MeteorLrptDemodulator(ServiceDemodulator, DialFrequencyReceiver):
def __init__(self, service: bool = False):
self.sampleRate = 150000
workers = [
SatDumpModule(mode = "meteor_m2-x_lrpt", sampleRate = self.sampleRate)
]
# Connect all the workers
super().__init__(workers)
def getFixedAudioRate(self) -> int:
return self.sampleRate
def supportsSquelch(self) -> bool:
return False
def setDialFrequency(self, frequency: int) -> None:
# TODO: Do something with the frequency or remove method
pass

View File

@ -174,3 +174,29 @@ class DablinModule(ExecModule):
self.serviceId = serviceId
self.setArgs(self._buildArgs())
self.restart()
class SatDumpModule(ExecModule):
def __init__(self, mode: str = "noaa_apt", sampleRate: int = 50000, frequency: int = 137000000, options = None):
# Make sure we have output folder
self.outFolder = "/tmp/satdump"
try:
os.makedirs(self.outFolder, exist_ok = True)
except:
self.outFolder = "/tmp"
# Compose command line
cmd = [
"satdump", "live", mode, self.outFolder,
"--source", "file", "--file_path", "/dev/stdin",
"--samplerate", str(sampleRate),
"--frequency", str(frequency),
"--baseband_format", "f32",
"--finish_processing",
]
# Add pipeline-specific options
if options:
for key in options.keys():
cmd.append("--" + key)
cmd.append(str(options[key]))
# Create parent object
super().__init__(Format.COMPLEX_FLOAT, Format.CHAR, cmd)

View File

@ -94,6 +94,7 @@ class FeatureDetector(object):
"selcall": ["multimon"],
"rds": ["redsea"],
"dab": ["csdreti", "dablin"],
"wxsat": ["satdump"],
"png": ["imagemagick"],
}
@ -714,3 +715,10 @@ class FeatureDetector(object):
"""
return self.command_is_runnable("multimon-ng --help")
def has_satdump(self):
"""
OpenWebRX uses [SatDump](https://github.com/SatDump/SatDump) software
suite to receive weather satellite transmissions. The `satdump`
package is available in some Linux distributions.
"""
return self.command_is_runnable("satdump --help")

View File

@ -269,6 +269,26 @@ class Modes(object):
squelch=False,
secondaryFft=False
),
DigitalMode(
"noaa-apt",
"NOAA APT",
underlying=["empty"],
bandpass=Bandpass(-25000, 25000),
requirements=["wxsat"],
service=True,
squelch=False,
secondaryFft=False
),
DigitalMode(
"meteor-lrpt",
"Meteor-M2 LRPT",
underlying=["empty"],
bandpass=Bandpass(-75000, 75000),
requirements=["wxsat"],
service=True,
squelch=False,
secondaryFft=False
),
]
@staticmethod

View File

@ -347,6 +347,12 @@ class ServiceHandler(SdrSourceEventClient):
elif mod == "adsb":
from csdr.chain.toolbox import AdsbDemodulator
return AdsbDemodulator(service=True)
elif mod == "noaa-apt":
from csdr.chain.toolbox import NoaaAptDemodulator
return NoaaAptDemodulator(service=True)
elif mod == "meteor-lrpt":
from csdr.chain.toolbox import MeteorLrptDemodulator
return MeteorLrptDemodulator(service=True)
raise ValueError("unsupported service modulation: {}".format(mod))