mirror of
https://github.com/jketterl/openwebrx.git
synced 2025-12-06 07:12:09 +01:00
first shot at decoding ISM data with rtl_433
This commit is contained in:
parent
687bf1c3d2
commit
0c6de7cf2a
15
csdr/chain/rtl433.py
Normal file
15
csdr/chain/rtl433.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
from owrx.ism.rtl433 import Rtl433Module, JsonParser
|
||||
from csdr.chain.demodulator import ServiceDemodulator
|
||||
|
||||
|
||||
class Rtl433(ServiceDemodulator):
|
||||
def getFixedAudioRate(self) -> int:
|
||||
return 250000
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(
|
||||
[
|
||||
Rtl433Module(),
|
||||
JsonParser(),
|
||||
]
|
||||
)
|
||||
|
|
@ -1273,6 +1273,7 @@ img.openwebrx-mirror-img
|
|||
#openwebrx-panel-digimodes[data-mode="q65"] #openwebrx-digimode-content-container,
|
||||
#openwebrx-panel-digimodes[data-mode="msk144"] #openwebrx-digimode-content-container,
|
||||
#openwebrx-panel-digimodes[data-mode="adsb"] #openwebrx-digimode-content-container,
|
||||
#openwebrx-panel-digimodes[data-mode="ism"] #openwebrx-digimode-content-container,
|
||||
#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="jt65"] #openwebrx-digimode-select-channel,
|
||||
|
|
@ -1285,7 +1286,8 @@ img.openwebrx-mirror-img
|
|||
#openwebrx-panel-digimodes[data-mode="fst4w"] #openwebrx-digimode-select-channel,
|
||||
#openwebrx-panel-digimodes[data-mode="q65"] #openwebrx-digimode-select-channel,
|
||||
#openwebrx-panel-digimodes[data-mode="msk144"] #openwebrx-digimode-select-channel,
|
||||
#openwebrx-panel-digimodes[data-mode="adsb"] #openwebrx-digimode-select-channel
|
||||
#openwebrx-panel-digimodes[data-mode="adsb"] #openwebrx-digimode-select-channel,
|
||||
#openwebrx-panel-digimodes[data-mode="ism"] #openwebrx-digimode-select-channel
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
|
@ -1302,7 +1304,8 @@ img.openwebrx-mirror-img
|
|||
#openwebrx-panel-digimodes[data-mode="fst4w"] #openwebrx-digimode-canvas-container,
|
||||
#openwebrx-panel-digimodes[data-mode="q65"] #openwebrx-digimode-canvas-container,
|
||||
#openwebrx-panel-digimodes[data-mode="msk144"] #openwebrx-digimode-canvas-container,
|
||||
#openwebrx-panel-digimodes[data-mode="adsb"] #openwebrx-digimode-canvas-container
|
||||
#openwebrx-panel-digimodes[data-mode="adsb"] #openwebrx-digimode-canvas-container,
|
||||
#openwebrx-panel-digimodes[data-mode="ism"] #openwebrx-digimode-canvas-container
|
||||
{
|
||||
height: 200px;
|
||||
margin: -10px;
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@
|
|||
<div class="openwebrx-panel openwebrx-message-panel" id="openwebrx-panel-packet-message" style="display: none; width: 619px;" data-panel-name="aprs-message"></div>
|
||||
<div class="openwebrx-panel openwebrx-message-panel" id="openwebrx-panel-pocsag-message" style="display: none; width: 619px;" data-panel-name="pocsag-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-meta-panel" id="openwebrx-panel-metadata-m17" style="display: none;" data-panel-name="metadata-m17">
|
||||
<div class="openwebrx-meta-slot">
|
||||
<div class="openwebrx-meta-user-image">
|
||||
|
|
|
|||
|
|
@ -165,10 +165,9 @@ DemodulatorPanel.prototype.updatePanels = function() {
|
|||
var mode = Modes.findByModulation(modulation);
|
||||
toggle_panel("openwebrx-panel-digimodes", modulation && (!mode || mode.secondaryFft));
|
||||
toggle_panel("openwebrx-panel-wsjt-message", ['ft8', 'wspr', 'jt65', 'jt9', 'ft4', 'fst4', 'fst4w', "q65", "msk144"].indexOf(modulation) >= 0);
|
||||
toggle_panel("openwebrx-panel-js8-message", modulation === "js8");
|
||||
toggle_panel("openwebrx-panel-packet-message", modulation === "packet");
|
||||
toggle_panel("openwebrx-panel-pocsag-message", modulation === "pocsag");
|
||||
toggle_panel('openwebrx-panel-adsb-message', modulation === 'adsb');
|
||||
['js8', 'packet', 'pocsag', 'adsb', 'ism'].forEach(function(m) {
|
||||
toggle_panel('openwebrx-panel-' + m + '-message', modulation === m);
|
||||
});
|
||||
|
||||
modulation = this.getDemodulator().get_modulation();
|
||||
var showing = 'openwebrx-panel-metadata-' + modulation;
|
||||
|
|
|
|||
|
|
@ -394,3 +394,66 @@ $.fn.adsbMessagePanel = function () {
|
|||
}
|
||||
return this.data('panel');
|
||||
};
|
||||
|
||||
IsmMessagePanel = function(el) {
|
||||
MessagePanel.call(this, el);
|
||||
this.initClearTimer();
|
||||
};
|
||||
|
||||
IsmMessagePanel.prototype = new MessagePanel();
|
||||
|
||||
IsmMessagePanel.prototype.supportsMessage = function(message) {
|
||||
return message['mode'] === 'ISM';
|
||||
};
|
||||
|
||||
IsmMessagePanel.prototype.render = function() {
|
||||
$(this.el).append($(
|
||||
'<table>' +
|
||||
'<thead><tr>' +
|
||||
'<th class="model">Model</th>' +
|
||||
'<th class="id">ID</th>' +
|
||||
'<th class="channel">Channel</th>' +
|
||||
'<th class="message">Message</th>' +
|
||||
'</tr></thead>' +
|
||||
'<tbody></tbody>' +
|
||||
'</table>'
|
||||
));
|
||||
|
||||
};
|
||||
|
||||
IsmMessagePanel.prototype.pushMessage = function(message) {
|
||||
var $t = $(this.el).find('table');
|
||||
var $b = $t.find('tbody');
|
||||
|
||||
var ifDefined = function(input, formatter) {
|
||||
if (typeof(input) !== 'undefined') {
|
||||
if (formatter) return formatter(input);
|
||||
return input;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
var mergeRemainingMessage = function(input, exclude) {
|
||||
return Object.entries(input).map(function(entry) {
|
||||
if (exclude.includes(entry[0])) return '';
|
||||
return entry[0] + ': ' + entry[1] + ';';
|
||||
}).join(' ');
|
||||
}
|
||||
|
||||
$b.append($(
|
||||
'<tr>' +
|
||||
'<td class="model">' + ifDefined(message.model) + '</td>' +
|
||||
'<td class="id">' + ifDefined(message.id) + '</td>' +
|
||||
'<td class="channel">' + ifDefined(message.channel) + '</td>' +
|
||||
'<td class="message">' + this.htmlEscape(mergeRemainingMessage(message, ['model', 'id', 'channel', 'mode', 'time'])) + '</td>' +
|
||||
'</tr>'
|
||||
));
|
||||
$t.scrollTop($t[0].scrollHeight);
|
||||
};
|
||||
|
||||
$.fn.ismMessagePanel = function() {
|
||||
if (!this.data('panel')) {
|
||||
this.data('panel', new IsmMessagePanel(this));
|
||||
}
|
||||
return this.data('panel');
|
||||
};
|
||||
|
|
@ -864,6 +864,7 @@ function on_ws_recv(evt) {
|
|||
$('#openwebrx-panel-packet-message').packetMessagePanel(),
|
||||
$('#openwebrx-panel-pocsag-message').pocsagMessagePanel(),
|
||||
$('#openwebrx-panel-adsb-message').adsbMessagePanel(),
|
||||
$('#openwebrx-panel-ism-message').ismMessagePanel(),
|
||||
$("#openwebrx-panel-js8-message").js8()
|
||||
];
|
||||
if (!panels.some(function(panel) {
|
||||
|
|
@ -1470,6 +1471,7 @@ function secondary_demod_init() {
|
|||
$('#openwebrx-panel-packet-message').packetMessagePanel();
|
||||
$('#openwebrx-panel-pocsag-message').pocsagMessagePanel();
|
||||
$('#openwebrx-panel-adsb-message').adsbMessagePanel();
|
||||
$('#openwebrx-panel-ism-message').ismMessagePanel();
|
||||
$('#openwebrx-panel-js8-message').js8();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -620,6 +620,9 @@ class DspManager(SdrSourceEventClient, ClientDemodulatorSecondaryDspEventClient)
|
|||
elif mod == "adsb":
|
||||
from csdr.chain.dump1090 import Dump1090
|
||||
return Dump1090()
|
||||
elif mod == "ism":
|
||||
from csdr.chain.rtl433 import Rtl433
|
||||
return Rtl433()
|
||||
|
||||
def setSecondaryDemodulator(self, mod):
|
||||
demodulator = self._getSecondaryDemodulator(mod)
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ class FeatureDetector(object):
|
|||
"js8call": ["js8", "js8py"],
|
||||
"drm": ["dream"],
|
||||
"dump1090": ["dump1090"],
|
||||
"ism": ["rtl_433"],
|
||||
}
|
||||
|
||||
def feature_availability(self):
|
||||
|
|
@ -591,3 +592,13 @@ class FeatureDetector(object):
|
|||
[Debian alternatives system](https://wiki.debian.org/DebianAlternatives) to achieve this.
|
||||
"""
|
||||
return self.command_is_runnable("dump1090 --version")
|
||||
|
||||
def has_rtl_433(self):
|
||||
"""
|
||||
OpenWebRX can make use of the `rtl_433` software to decode various signals in the ISM bands.
|
||||
|
||||
You can find more information [here](https://github.com/merbanan/rtl_433).
|
||||
|
||||
Debian and Ubuntu based systems should be able to install the package `rtl-433` from the package manager.
|
||||
"""
|
||||
return self.command_is_runnable("rtl_433 -h")
|
||||
|
|
|
|||
28
owrx/ism/rtl433.py
Normal file
28
owrx/ism/rtl433.py
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
from pycsdr.modules import ExecModule
|
||||
from pycsdr.types import Format
|
||||
from csdr.module import LineBasedModule
|
||||
import json
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Rtl433Module(ExecModule):
|
||||
def __init__(self):
|
||||
super().__init__(
|
||||
Format.COMPLEX_FLOAT,
|
||||
Format.CHAR,
|
||||
["rtl_433", "-r", "cf32:-", "-F", "json", "-M", "time:unix", "-C", "si"]
|
||||
)
|
||||
|
||||
|
||||
class JsonParser(LineBasedModule):
|
||||
def process(self, line):
|
||||
try:
|
||||
msg = json.loads(line.decode())
|
||||
msg["mode"] = "ISM"
|
||||
logger.debug(msg)
|
||||
return msg
|
||||
except json.JSONDecodeError:
|
||||
logger.exception("error parsing rtl433 json")
|
||||
|
|
@ -174,6 +174,14 @@ class Modes(object):
|
|||
squelch=False,
|
||||
secondaryFft=False,
|
||||
),
|
||||
DigitalMode(
|
||||
"ism",
|
||||
"ISM",
|
||||
underlying=["empty"],
|
||||
bandpass=None,
|
||||
requirements=["ism"],
|
||||
squelch=False,
|
||||
)
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
|
|
|
|||
Loading…
Reference in a new issue