Adding preliminary SatDump support (experts only!)
This commit is contained in:
parent
06290bdded
commit
aa64129306
|
|
@ -1,5 +1,5 @@
|
||||||
from csdr.chain.demodulator import ServiceDemodulator, DialFrequencyReceiver, FixedIfSampleRateChain
|
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.modules import FmDemod, AudioResampler, Convert, Agc, Squelch
|
||||||
from pycsdr.types import Format
|
from pycsdr.types import Format
|
||||||
from owrx.toolbox import TextParser, PageParser, SelCallParser, IsmParser, RdsParser
|
from owrx.toolbox import TextParser, PageParser, SelCallParser, IsmParser, RdsParser
|
||||||
|
|
@ -210,3 +210,46 @@ class RdsDemodulator(ServiceDemodulator, DialFrequencyReceiver):
|
||||||
|
|
||||||
def setDialFrequency(self, frequency: int) -> None:
|
def setDialFrequency(self, frequency: int) -> None:
|
||||||
self.parser.setDialFrequency(frequency)
|
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
|
||||||
|
|
|
||||||
|
|
@ -174,3 +174,29 @@ class DablinModule(ExecModule):
|
||||||
self.serviceId = serviceId
|
self.serviceId = serviceId
|
||||||
self.setArgs(self._buildArgs())
|
self.setArgs(self._buildArgs())
|
||||||
self.restart()
|
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)
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,7 @@ class FeatureDetector(object):
|
||||||
"selcall": ["multimon"],
|
"selcall": ["multimon"],
|
||||||
"rds": ["redsea"],
|
"rds": ["redsea"],
|
||||||
"dab": ["csdreti", "dablin"],
|
"dab": ["csdreti", "dablin"],
|
||||||
|
"wxsat": ["satdump"],
|
||||||
"png": ["imagemagick"],
|
"png": ["imagemagick"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -714,3 +715,10 @@ class FeatureDetector(object):
|
||||||
"""
|
"""
|
||||||
return self.command_is_runnable("multimon-ng --help")
|
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")
|
||||||
|
|
|
||||||
|
|
@ -269,6 +269,26 @@ class Modes(object):
|
||||||
squelch=False,
|
squelch=False,
|
||||||
secondaryFft=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
|
@staticmethod
|
||||||
|
|
|
||||||
|
|
@ -347,6 +347,12 @@ class ServiceHandler(SdrSourceEventClient):
|
||||||
elif mod == "adsb":
|
elif mod == "adsb":
|
||||||
from csdr.chain.toolbox import AdsbDemodulator
|
from csdr.chain.toolbox import AdsbDemodulator
|
||||||
return AdsbDemodulator(service=True)
|
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))
|
raise ValueError("unsupported service modulation: {}".format(mod))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue