add js8 decoding if available

This commit is contained in:
Jakob Ketterl 2020-04-12 13:10:23 +02:00
parent 0e8715b5a1
commit ddfd85c586
7 changed files with 72 additions and 15 deletions

View File

@ -8,7 +8,8 @@
"ft8": 1840000,
"wspr": 1836600,
"jt65": 1838000,
"jt9": 1839000
"jt9": 1839000,
"js8": 1842000
}
},
{
@ -21,7 +22,8 @@
"wspr": 3592600,
"jt65": 3570000,
"jt9": 3572000,
"ft4": [3568000, 3575000]
"ft4": [3568000, 3575000],
"js8": 3578000
}
},
{
@ -43,7 +45,8 @@
"wspr": 7038600,
"jt65": 7076000,
"jt9": 7078000,
"ft4": 7047500
"ft4": 7047500,
"js8": 7078000
}
},
{
@ -56,7 +59,8 @@
"wspr": 10138700,
"jt65": 10138000,
"jt9": 10140000,
"ft4": 10140000
"ft4": 10140000,
"js8": 10130000
}
},
{
@ -69,7 +73,8 @@
"wspr": 14095600,
"jt65": 14076000,
"jt9": 14078000,
"ft4": 14080000
"ft4": 14080000,
"js8": 14078000
}
},
{
@ -82,7 +87,8 @@
"wspr": 18104600,
"jt65": 18102000,
"jt9": 18104000,
"ft4": 18104000
"ft4": 18104000,
"js8": 18104000
}
},
{
@ -95,7 +101,8 @@
"wspr": 21094600,
"jt65": 21076000,
"jt9": 21078000,
"ft4": 21140000
"ft4": 21140000,
"js8": 21078000
}
},
{
@ -108,7 +115,8 @@
"wspr": 24924600,
"jt65": 24917000,
"jt9": 24919000,
"ft4": 24919000
"ft4": 24919000,
"js8": 24922000
}
},
{
@ -121,7 +129,8 @@
"wspr": 28124600,
"jt65": 28076000,
"jt9": 28078000,
"ft4": 28180000
"ft4": 28180000,
"js8": 28078000
}
},
{
@ -134,7 +143,8 @@
"wspr": 50293000,
"jt65": 50310000,
"jt9": 50312000,
"ft4": 50318000
"ft4": 50318000,
"js8": 50318000
}
},
{

View File

@ -30,6 +30,7 @@ from functools import partial
from owrx.kiss import KissClient, DirewolfConfig
from owrx.wsjt import Ft8Chopper, WsprChopper, Jt9Chopper, Jt65Chopper, Ft4Chopper
from owrx.js8 import Js8Chopper
import logging
@ -450,6 +451,7 @@ class dsp(object):
if self.isWsjtMode():
smd = self.get_secondary_demodulator()
chopper_cls = None
output_name = "wsjt_demod"
if smd == "ft8":
chopper_cls = Ft8Chopper
elif smd == "wspr":
@ -460,10 +462,13 @@ class dsp(object):
chopper_cls = Jt9Chopper
elif smd == "ft4":
chopper_cls = Ft4Chopper
elif smd == "js8":
chopper_cls = Js8Chopper
output_name = "js8_demod"
if chopper_cls is not None:
chopper = chopper_cls(self, self.secondary_process_demod.stdout)
chopper.start()
self.output.send_output("wsjt_demod", chopper.read)
self.output.send_output(output_name, chopper.read)
elif self.isPacket():
# we best get the ax25 packets from the kiss socket
kiss = KissClient(self.direwolf_port)
@ -576,7 +581,7 @@ class dsp(object):
def isWsjtMode(self, demodulator=None):
if demodulator is None:
demodulator = self.get_secondary_demodulator()
return demodulator in ["ft8", "wspr", "jt65", "jt9", "ft4"]
return demodulator in ["ft8", "wspr", "jt65", "jt9", "ft4", "js8"]
def isPacket(self, demodulator=None):
if demodulator is None:

View File

@ -193,6 +193,7 @@
<option value="jt65" data-feature="wsjt-x">JT65</option>
<option value="jt9" data-feature="wsjt-x">JT9</option>
<option value="ft4" data-feature="wsjt-x">FT4</option>
<option value="js8" data-feature="js8call">JS8Call</option>
<option value="packet" data-feature="packet">Packet</option>
<option value="pocsag" data-feature="pocsag">Pocsag</option>
</select>

View File

@ -1305,7 +1305,7 @@ function update_wsjt_panel(msg) {
};
var linkedmsg = msg['msg'];
var matches;
if (['FT8', 'JT65', 'JT9', 'FT4'].indexOf(msg['mode']) >= 0) {
if (['FT8', 'JT65', 'JT9', 'FT4', 'JS8'].indexOf(msg['mode']) >= 0) {
matches = linkedmsg.match(/(.*\s[A-Z0-9]+\s)([A-R]{2}[0-9]{2})$/);
if (matches && matches[2] !== 'RR73') {
linkedmsg = html_escape(matches[1]) + '<a href="map?locator=' + matches[2] + '" target="_blank">' + matches[2] + '</a>';
@ -2019,6 +2019,7 @@ function demodulator_digital_replace(subtype) {
case "jt65":
case "jt9":
case "ft4":
case "js8":
secondary_demod_start(subtype);
demodulator_analog_replace('usb', true);
break;
@ -2045,7 +2046,7 @@ function demodulator_digital_replace(subtype) {
demodulator_buttons_update();
$('#openwebrx-panel-digimodes').attr('data-mode', subtype);
toggle_panel("openwebrx-panel-digimodes", true);
toggle_panel("openwebrx-panel-wsjt-message", ['ft8', 'wspr', 'jt65', 'jt9', 'ft4'].indexOf(subtype) >= 0);
toggle_panel("openwebrx-panel-wsjt-message", ['ft8', 'wspr', 'jt65', 'jt9', 'ft4', 'js8'].indexOf(subtype) >= 0);
toggle_panel("openwebrx-panel-packet-message", subtype === "packet");
toggle_panel("openwebrx-panel-pocsag-message", subtype === "pocsag");
updateHash();

View File

@ -1,6 +1,6 @@
from owrx.config import Config
from owrx.meta import MetaParser
from owrx.wsjt import WsjtParser
from owrx.js8 import Js8Parser
from owrx.aprs import AprsParser
from owrx.pocsag import PocsagParser
from owrx.source import SdrSource
@ -22,6 +22,7 @@ class DspManager(csdr.output):
"wsjt_demod": WsjtParser(self.handler),
"packet_demod": AprsParser(self.handler),
"pocsag_demod": PocsagParser(self.handler),
"js8_demod": Js8Parser(self.handler),
}
self.props = PropertyStack()

View File

@ -40,6 +40,7 @@ class FeatureDetector(object):
"wsjt-x": ["wsjtx", "sox"],
"packet": ["direwolf", "sox"],
"pocsag": ["digiham", "sox"],
"js8call": ["js8", "sox"],
}
def feature_availability(self):
@ -370,6 +371,12 @@ class FeatureDetector(object):
"""
return reduce(and_, map(self.command_is_runnable, ["jt9", "wsprd"]), True)
def has_js8(self):
"""
To decode JS8, you will need to install [JS8Call](http://js8call.com/)
"""
return self.command_is_runnable("js8")
def has_alsa(self):
"""
Some SDR receivers are identifying themselves as a soundcard. In order to read their data, OpenWebRX relies

32
owrx/js8.py Normal file
View File

@ -0,0 +1,32 @@
from .wsjt import WsjtChopper
from .parser import Parser
import re
import logging
logger = logging.getLogger(__name__)
class Js8Chopper(WsjtChopper):
def getInterval(self):
return 15
def getFileTimestampFormat(self):
return "%y%m%d_%H%M%S"
def decoder_commandline(self, file):
return ["js8", "--js8", "-d", str(self.decoding_depth("js8")), file]
class Js8Parser(Parser):
decoderRegex = re.compile(" ?<Decode(Started|Debug|Finished)>")
def parse(self, raw):
freq, raw_msg = raw
self.setDialFrequency(freq)
msg = raw_msg.decode().rstrip()
if Js8Parser.decoderRegex.match(msg):
return
if msg.startswith(" EOF on input file"):
return
logger.debug(msg)