Adding UI for the DSC decoder.
This commit is contained in:
parent
1b9a525449
commit
8fdbf90303
|
|
@ -8,6 +8,7 @@ from pycsdr.types import Format
|
||||||
from owrx.aprs.direwolf import DirewolfModule
|
from owrx.aprs.direwolf import DirewolfModule
|
||||||
from owrx.sstv import SstvParser
|
from owrx.sstv import SstvParser
|
||||||
from owrx.fax import FaxParser
|
from owrx.fax import FaxParser
|
||||||
|
from owrx.dsc import DscParser
|
||||||
from owrx.config import Config
|
from owrx.config import Config
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -258,10 +259,11 @@ class SitorBDemodulator(SecondaryDemodulator, SecondarySelectorChain):
|
||||||
|
|
||||||
|
|
||||||
class DscDemodulator(SecondaryDemodulator, SecondarySelectorChain):
|
class DscDemodulator(SecondaryDemodulator, SecondarySelectorChain):
|
||||||
def __init__(self, baudRate=100, bandWidth=170, invert=False):
|
def __init__(self, baudRate=100, bandWidth=170, invert=False, service=False):
|
||||||
self.baudRate = baudRate
|
self.baudRate = baudRate
|
||||||
self.bandWidth = bandWidth
|
self.bandWidth = bandWidth
|
||||||
self.invert = invert
|
self.invert = invert
|
||||||
|
self.parser = DscParser(service=service)
|
||||||
# this is an assumption, we will adjust in setSampleRate
|
# this is an assumption, we will adjust in setSampleRate
|
||||||
self.sampleRate = 12000
|
self.sampleRate = 12000
|
||||||
secondary_samples_per_bit = int(round(self.sampleRate / self.baudRate))
|
secondary_samples_per_bit = int(round(self.sampleRate / self.baudRate))
|
||||||
|
|
@ -274,6 +276,7 @@ class DscDemodulator(SecondaryDemodulator, SecondarySelectorChain):
|
||||||
TimingRecovery(Format.FLOAT, secondary_samples_per_bit, loop_gain, 10),
|
TimingRecovery(Format.FLOAT, secondary_samples_per_bit, loop_gain, 10),
|
||||||
Ccir493Decoder(invert=invert),
|
Ccir493Decoder(invert=invert),
|
||||||
DscDecoder(),
|
DscDecoder(),
|
||||||
|
self.parser
|
||||||
]
|
]
|
||||||
super().__init__(workers)
|
super().__init__(workers)
|
||||||
|
|
||||||
|
|
@ -289,3 +292,4 @@ class DscDemodulator(SecondaryDemodulator, SecondarySelectorChain):
|
||||||
loop_gain = self.sampleRate / self.getBandwidth() / 5
|
loop_gain = self.sampleRate / self.getBandwidth() / 5
|
||||||
self.replace(2, Lowpass(Format.FLOAT, cutoff))
|
self.replace(2, Lowpass(Format.FLOAT, cutoff))
|
||||||
self.replace(3, TimingRecovery(Format.FLOAT, secondary_samples_per_bit, loop_gain, 10))
|
self.replace(3, TimingRecovery(Format.FLOAT, secondary_samples_per_bit, loop_gain, 10))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1360,6 +1360,45 @@ img.openwebrx-mirror-img
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#openwebrx-panel-dsc-message {
|
||||||
|
height: 310px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#openwebrx-panel-dsc-message a {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
#openwebrx-panel-dsc-message tbody {
|
||||||
|
height: 280px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#openwebrx-panel-dsc-message .timestamp {
|
||||||
|
width: 80px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#openwebrx-panel-dsc-message .src {
|
||||||
|
width: 80px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#openwebrx-panel-dsc-message .dst {
|
||||||
|
width: 80px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#openwebrx-panel-dsc-message .data {
|
||||||
|
width: 326px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#openwebrx-panel-dsc-message .message {
|
||||||
|
width: 566px;
|
||||||
|
max-width: 566px;
|
||||||
|
column-span: all;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
#openwebrx-panel-ism-message {
|
#openwebrx-panel-ism-message {
|
||||||
height: 310px;
|
height: 310px;
|
||||||
}
|
}
|
||||||
|
|
@ -1533,6 +1572,7 @@ img.openwebrx-mirror-img
|
||||||
#openwebrx-panel-digimodes[data-mode="sstv"] #openwebrx-digimode-content-container,
|
#openwebrx-panel-digimodes[data-mode="sstv"] #openwebrx-digimode-content-container,
|
||||||
#openwebrx-panel-digimodes[data-mode="fax"] #openwebrx-digimode-content-container,
|
#openwebrx-panel-digimodes[data-mode="fax"] #openwebrx-digimode-content-container,
|
||||||
#openwebrx-panel-digimodes[data-mode="ism"] #openwebrx-digimode-content-container,
|
#openwebrx-panel-digimodes[data-mode="ism"] #openwebrx-digimode-content-container,
|
||||||
|
#openwebrx-panel-digimodes[data-mode="dsc"] #openwebrx-digimode-content-container,
|
||||||
#openwebrx-panel-digimodes[data-mode="ft8"] #openwebrx-digimode-select-channel,
|
#openwebrx-panel-digimodes[data-mode="ft8"] #openwebrx-digimode-select-channel,
|
||||||
#openwebrx-panel-digimodes[data-mode="wspr"] #openwebrx-digimode-select-channel,
|
#openwebrx-panel-digimodes[data-mode="wspr"] #openwebrx-digimode-select-channel,
|
||||||
#openwebrx-panel-digimodes[data-mode="jt65"] #openwebrx-digimode-select-channel,
|
#openwebrx-panel-digimodes[data-mode="jt65"] #openwebrx-digimode-select-channel,
|
||||||
|
|
@ -1580,7 +1620,8 @@ img.openwebrx-mirror-img
|
||||||
#openwebrx-panel-digimodes[data-mode="msk144"] #openwebrx-digimode-canvas-container,
|
#openwebrx-panel-digimodes[data-mode="msk144"] #openwebrx-digimode-canvas-container,
|
||||||
#openwebrx-panel-digimodes[data-mode="sstv"] #openwebrx-digimode-canvas-container,
|
#openwebrx-panel-digimodes[data-mode="sstv"] #openwebrx-digimode-canvas-container,
|
||||||
#openwebrx-panel-digimodes[data-mode="fax"] #openwebrx-digimode-canvas-container,
|
#openwebrx-panel-digimodes[data-mode="fax"] #openwebrx-digimode-canvas-container,
|
||||||
#openwebrx-panel-digimodes[data-mode="ism"] #openwebrx-digimode-canvas-container
|
#openwebrx-panel-digimodes[data-mode="ism"] #openwebrx-digimode-canvas-container,
|
||||||
|
#openwebrx-panel-digimodes[data-mode="dsc"] #openwebrx-digimode-canvas-container
|
||||||
{
|
{
|
||||||
height: 200px;
|
height: 200px;
|
||||||
margin: -10px;
|
margin: -10px;
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,7 @@
|
||||||
<div class="openwebrx-panel openwebrx-message-panel" id="openwebrx-panel-hfdl-message" style="display: none; width: 619px;" data-panel-name="hfdl-message"></div>
|
<div class="openwebrx-panel openwebrx-message-panel" id="openwebrx-panel-hfdl-message" style="display: none; width: 619px;" data-panel-name="hfdl-message"></div>
|
||||||
<div class="openwebrx-panel openwebrx-message-panel" id="openwebrx-panel-adsb-message" style="display: none; width: 619px;" data-panel-name="adsb-message"></div>
|
<div class="openwebrx-panel openwebrx-message-panel" id="openwebrx-panel-adsb-message" style="display: none; width: 619px;" data-panel-name="adsb-message"></div>
|
||||||
<div class="openwebrx-panel openwebrx-message-panel" id="openwebrx-panel-ism-message" style="display: none; width: 619px;" data-panel-name="ism-message"></div>
|
<div class="openwebrx-panel openwebrx-message-panel" id="openwebrx-panel-ism-message" style="display: none; width: 619px;" data-panel-name="ism-message"></div>
|
||||||
|
<div class="openwebrx-panel openwebrx-message-panel" id="openwebrx-panel-dsc-message" style="display: none; width: 619px;" data-panel-name="dsc-message"></div>
|
||||||
<div class="openwebrx-panel openwebrx-message-panel" id="openwebrx-panel-rds-message" style="display: none; width: 92%; max-width: 450px;" data-panel-name="rds-message"></div>
|
<div class="openwebrx-panel openwebrx-message-panel" id="openwebrx-panel-rds-message" style="display: none; width: 92%; max-width: 450px;" data-panel-name="rds-message"></div>
|
||||||
<div class="openwebrx-panel openwebrx-meta-panel" id="openwebrx-panel-metadata-m17" style="display: none;" data-panel-name="metadata-m17">
|
<div class="openwebrx-panel openwebrx-meta-panel" id="openwebrx-panel-metadata-m17" style="display: none;" data-panel-name="metadata-m17">
|
||||||
<div class="openwebrx-meta-slot">
|
<div class="openwebrx-meta-slot">
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,7 @@ DemodulatorPanel.prototype.updatePanels = function() {
|
||||||
// Packet modes share the same panel
|
// Packet modes share the same panel
|
||||||
toggle_panel("openwebrx-panel-packet-message", ['packet', 'ais'].indexOf(modulation) >= 0);
|
toggle_panel("openwebrx-panel-packet-message", ['packet', 'ais'].indexOf(modulation) >= 0);
|
||||||
// these modes come with their own
|
// these modes come with their own
|
||||||
['js8', 'page', 'pocsag', 'sstv', 'fax', 'ism', 'rds'].forEach(function(m) {
|
['js8', 'page', 'pocsag', 'sstv', 'fax', 'ism', 'dsc', 'rds'].forEach(function(m) {
|
||||||
toggle_panel('openwebrx-panel-' + m + '-message', modulation === m);
|
toggle_panel('openwebrx-panel-' + m + '-message', modulation === m);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -562,6 +562,66 @@ $.fn.adsbMessagePanel = function() {
|
||||||
return this.data('panel');
|
return this.data('panel');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DscMessagePanel = function(el) {
|
||||||
|
MessagePanel.call(this, el);
|
||||||
|
this.initClearTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
DscMessagePanel.prototype = Object.create(MessagePanel.prototype);
|
||||||
|
|
||||||
|
DscMessagePanel.prototype.supportsMessage = function(message) {
|
||||||
|
return message['mode'] === 'DSC';
|
||||||
|
};
|
||||||
|
|
||||||
|
DscMessagePanel.prototype.render = function() {
|
||||||
|
$(this.el).append($(
|
||||||
|
'<table>' +
|
||||||
|
'<thead><tr>' +
|
||||||
|
'<th class="timestamp">Time</th>' +
|
||||||
|
'<th class="src">From</th>' +
|
||||||
|
'<th class="dst">To</th>' +
|
||||||
|
'<th class="data">Data</th>' +
|
||||||
|
'</tr></thead>' +
|
||||||
|
'<tbody></tbody>' +
|
||||||
|
'</table>'
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
DscMessagePanel.prototype.pushMessage = function(msg) {
|
||||||
|
var tstamp = 0;
|
||||||
|
var src = '*';
|
||||||
|
var dst = '*';
|
||||||
|
var data = '';
|
||||||
|
|
||||||
|
// Append report
|
||||||
|
var $b = $(this.el).find('tbody');
|
||||||
|
$b.append($(
|
||||||
|
'<tr>' +
|
||||||
|
'<td class="timestamp">' + tstamp + '</td>' +
|
||||||
|
'<td class="src">' + src + '</td>' +
|
||||||
|
'<td class="dst">' + dst + '</td>' +
|
||||||
|
'<td class="data" style="text-align:left;">' + data + '</td>' +
|
||||||
|
'</tr>'
|
||||||
|
));
|
||||||
|
|
||||||
|
// Append messsage if present
|
||||||
|
if (msg.message) {
|
||||||
|
$b.append($(
|
||||||
|
'<tr><td class="message" colspan="4">' + Utils.htmlEscape(msg.message) + '</td></tr>'
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jump list to the last received message
|
||||||
|
this.scrollToBottom();
|
||||||
|
};
|
||||||
|
|
||||||
|
$.fn.dscMessagePanel = function() {
|
||||||
|
if (!this.data('panel')) {
|
||||||
|
this.data('panel', new DscMessagePanel(this));
|
||||||
|
}
|
||||||
|
return this.data('panel');
|
||||||
|
};
|
||||||
|
|
||||||
IsmMessagePanel = function(el) {
|
IsmMessagePanel = function(el) {
|
||||||
MessagePanel.call(this, el);
|
MessagePanel.call(this, el);
|
||||||
this.initClearTimer();
|
this.initClearTimer();
|
||||||
|
|
|
||||||
|
|
@ -1169,7 +1169,7 @@ function on_ws_recv(evt) {
|
||||||
break;
|
break;
|
||||||
case 'secondary_demod':
|
case 'secondary_demod':
|
||||||
var value = json['value'];
|
var value = json['value'];
|
||||||
var panels = ['wsjt', 'packet', 'pocsag', 'page', 'sstv', 'fax', 'ism', 'hfdl', 'adsb'].map(function(id) {
|
var panels = ['wsjt', 'packet', 'pocsag', 'page', 'sstv', 'fax', 'ism', 'hfdl', 'adsb', 'dsc'].map(function(id) {
|
||||||
return $('#openwebrx-panel-' + id + '-message')[id + 'MessagePanel']();
|
return $('#openwebrx-panel-' + id + '-message')[id + 'MessagePanel']();
|
||||||
});
|
});
|
||||||
panels.push($('#openwebrx-panel-js8-message').js8());
|
panels.push($('#openwebrx-panel-js8-message').js8());
|
||||||
|
|
@ -1846,7 +1846,7 @@ function secondary_demod_init() {
|
||||||
.mousedown(secondary_demod_canvas_container_mousedown)
|
.mousedown(secondary_demod_canvas_container_mousedown)
|
||||||
.mouseenter(secondary_demod_canvas_container_mousein)
|
.mouseenter(secondary_demod_canvas_container_mousein)
|
||||||
.mouseleave(secondary_demod_canvas_container_mouseleave);
|
.mouseleave(secondary_demod_canvas_container_mouseleave);
|
||||||
['wsjt', 'packet', 'pocsag', 'page', 'sstv', 'fax', 'ism', 'hfdl', 'adsb'].forEach(function(id){
|
['wsjt', 'packet', 'pocsag', 'page', 'sstv', 'fax', 'ism', 'hfdl', 'adsb', 'dsc'].forEach(function(id){
|
||||||
$('#openwebrx-panel-' + id + '-message')[id + 'MessagePanel']();
|
$('#openwebrx-panel-' + id + '-message')[id + 'MessagePanel']();
|
||||||
})
|
})
|
||||||
$('#openwebrx-panel-js8-message').js8();
|
$('#openwebrx-panel-js8-message').js8();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
from owrx.toolbox import TextParser
|
||||||
|
from owrx.color import ColorCache
|
||||||
|
import json
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class DscParser(TextParser):
|
||||||
|
def __init__(self, service: bool = False):
|
||||||
|
# Colors will be assigned via this cache
|
||||||
|
self.colors = ColorCache()
|
||||||
|
# Construct parent object
|
||||||
|
super().__init__(filePrefix="DSC", service=service)
|
||||||
|
|
||||||
|
def parse(self, msg: bytes):
|
||||||
|
# Do not parse in service mode
|
||||||
|
if self.service:
|
||||||
|
return None
|
||||||
|
# Expect JSON data in text form
|
||||||
|
out = json.loads(msg)
|
||||||
|
# Add mode name and a color to identify the sender
|
||||||
|
out["mode"] = "DSC"
|
||||||
|
out["color"] = self.colors.getColor(out["src"])
|
||||||
|
logger.debug("{0}".format(out))
|
||||||
|
return out
|
||||||
|
|
@ -142,8 +142,7 @@ class Modes(object):
|
||||||
DigitalMode("rtty450", "RTTY-450 (50N)", underlying=["usb", "lsb"]),
|
DigitalMode("rtty450", "RTTY-450 (50N)", underlying=["usb", "lsb"]),
|
||||||
DigitalMode("rtty85", "RTTY-85 (50N)", underlying=["usb", "lsb"]),
|
DigitalMode("rtty85", "RTTY-85 (50N)", underlying=["usb", "lsb"]),
|
||||||
DigitalMode("sitorb", "SITOR-B", underlying=["usb"]),
|
DigitalMode("sitorb", "SITOR-B", underlying=["usb"]),
|
||||||
# Currently in development
|
DigitalMode("dsc", "DSC", underlying=["usb"]),
|
||||||
# DigitalMode("dsc", "DSC", underlying=["usb"]),
|
|
||||||
WsjtMode("ft8", "FT8"),
|
WsjtMode("ft8", "FT8"),
|
||||||
WsjtMode("ft4", "FT4"),
|
WsjtMode("ft4", "FT4"),
|
||||||
WsjtMode("jt65", "JT65"),
|
WsjtMode("jt65", "JT65"),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue