mirror of
https://github.com/jopohl/urh.git
synced 2026-03-05 07:54:01 +01:00
* rename signalFunctions -> signal_functions * basic methods for auto interpretation * cythonize k means * reorder tests * remove check and update gitignore * estimate tolerance and implement score for choosing modulation type * use absdiff * remove comment * cythonize messsage segmentation * improve message segementation and add test for xavax * integrate OOK special case * add check if psk is possible * integrate xavax and improve score * improve noise detection * add test for noise detection multiple messages * improve noise detection * homematic fix: use percetange of signal length instead of num flanks * homematic has some trash at start of messages, which counts as flanks * additonally set score to 0 if found only one bit length lower 5 * calculate minimum bit length from tolerance * improve noise noise detection * refactor limit and propose new limit calculation * improve minimum bit length penalty * only increase score for mod_type if bit length surpasses a minimum * this way scoring loop later becomes easier and * score is more accurate as there is no division needed which does not scale well with the length of message vectors * remove demodulated complex files and demod live in tests * remove enocean.coco * add a new check to prevent PSK misclassification * add tolerance unit test * use z=2 for finding outlier free max in tolerance estimation * prevent numpy warnings * adapt threshold of unit test * normalize the score by dividing by plateau vector length * improve OOK segmentation: Use minimum pulse length instead pause length for reference * use 50 percentile for detecting n_digits in plateau rounding * add elektromaten integration test * improve center detection to deal with varying signal power levels * use 10% clustering for rect signal * calculate min and max of each cluster * return max(minima) + min(maxima) / 2 * improve the center aggregation, separate between modulation types * add validity checks if message can be ASK or FSK modulated * use a weighted mean for center estimation: 60/40 for high/low * improve bit length estimation: use decimal deviation for filtering * add scislo test * improve tolerance estimation: use 50 percentile + revert to normal mean for bitlength estimation * add haar wavelet transform * add median filter * rename to Wavelet * add signal generation with configurable snr for lab test * add method for testdata generation * prepare fsk test: generate messages and estimate parameters * improve performance of plateau length filtering * remove unused import * improve robustness * improve robustness * add fsk error plot * only append bit length if it surpasses minimum * fix plot title * improve noise level detection, prevent it from being too low * integrate all modulations to test * increase pause threshold for ook * improve tolerance estimation * improve noise detection: take maximum of all maxima of noise clusters * improve scoring algorithm to prevent PSK misclassify as FSK * use histogram based approach for center detection * modulation detection with wavelets * fix median filter when at end of data * integrate modulation detection with wavelets * improve robustness * improve psk parameters * improve psk threshold * improve robustness * swap psk angles for easier demod * better xticks * add message segmentation test and fix noise generation snr * add error print * update audi test * fix runtime warning * improve accuracy of center detection * avoid warning * remove unused functions * fine tune fsk fft threshold * update esaver test * improve fsk fft threshold * change test order * update enocean test signal * update enocean test signal * enhance bit length estimation: use a threshold divisor histogram * improve noise estimation: round to fourth digit * update enocean signal * consider special case if message pause is 0 * remove unused * improve noise detection * improve center detection * improve center detection * prevent warning * refactor * cythonize get_plateau_lengths * improve syntax * use c++ sort * optimize PSK threshold * optimize coverage * fix buffer types * integrate new auto detection routine * update test * remove unused stuff * fix tests * backward compat * backward compat * update test * add threshold for large signals for performance * update changelog * make algorithm more robust against short bit length outliers * make multi button for selecting auto detect options * update unittest
150 lines
6.3 KiB
Python
150 lines
6.3 KiB
Python
import math
|
|
|
|
from PyQt5.QtTest import QTest
|
|
from PyQt5.QtWidgets import QApplication
|
|
|
|
from tests.QtTestCase import QtTestCase
|
|
from urh.plugins.MessageBreak.MessageBreakPlugin import MessageBreakPlugin
|
|
from urh.plugins.NetworkSDRInterface.NetworkSDRInterfacePlugin import NetworkSDRInterfacePlugin
|
|
from urh.plugins.ZeroHide.ZeroHidePlugin import ZeroHidePlugin
|
|
from urh.ui.views.ZoomableGraphicView import ZoomableGraphicView
|
|
from urh.util.Formatter import Formatter
|
|
|
|
|
|
class TestPlugins(QtTestCase):
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.add_signal_to_form("esaver.coco")
|
|
self.sframe = self.form.signal_tab_controller.signal_frames[0]
|
|
self.cframe = self.form.compare_frame_controller
|
|
self.form.ui.tabWidget.setCurrentIndex(1)
|
|
self.assertEqual(self.cframe.protocol_model.row_count, 3)
|
|
|
|
def test_message_break_plugin(self):
|
|
bp = MessageBreakPlugin()
|
|
action = bp.get_action(self.cframe.ui.tblViewProtocol, self.cframe.protocol_undo_stack,
|
|
(1, 1, 4, 4), self.cframe.proto_analyzer, 0)
|
|
self.assertEqual(self.cframe.protocol_model.row_count, 3)
|
|
action.trigger()
|
|
self.assertEqual(self.cframe.protocol_model.row_count, 4)
|
|
|
|
self.cframe.protocol_undo_stack.undo()
|
|
self.assertEqual(self.cframe.protocol_model.row_count, 3)
|
|
|
|
def test_zero_hide_plugin_gui(self):
|
|
self.assertEqual(len(self.cframe.proto_analyzer.decoded_proto_bits_str[0]), 331)
|
|
zh = ZeroHidePlugin()
|
|
zh.following_zeros = 158
|
|
action = zh.get_action(self.cframe.ui.tblViewProtocol, self.cframe.protocol_undo_stack, (),
|
|
self.cframe.proto_analyzer, 0)
|
|
action.trigger()
|
|
|
|
self.assertEqual(len(self.cframe.proto_analyzer.decoded_proto_bits_str[0]), 331 - 158)
|
|
|
|
self.cframe.protocol_undo_stack.undo()
|
|
self.assertEqual(len(self.cframe.proto_analyzer.decoded_proto_bits_str[0]), 331)
|
|
|
|
def test_zero_hide_plugin_function(self):
|
|
zh = ZeroHidePlugin()
|
|
zh.following_zeros = 3
|
|
self.add_signal_to_form("ask.complex")
|
|
self.form.ui.tabWidget.setCurrentIndex(1)
|
|
test_bits = "1011001001011011011011011011011011001000000"
|
|
self.assertEqual(self.cframe.proto_analyzer.decoded_proto_bits_str[3], test_bits)
|
|
|
|
action = zh.get_action(self.cframe.ui.tblViewProtocol, self.cframe.protocol_undo_stack, (),
|
|
self.cframe.proto_analyzer, 0)
|
|
action.trigger()
|
|
self.assertEqual(self.cframe.proto_analyzer.decoded_proto_bits_str[3], "1011001001011011011011011011011011001")
|
|
|
|
def test_sdr_interface_plugin(self):
|
|
si = NetworkSDRInterfacePlugin(resume_on_full_receive_buffer=True)
|
|
test_bits = [
|
|
"10101011111",
|
|
"1010100011000111110001011001010101010101",
|
|
"1010100011000111110001011001010100100",
|
|
"1101010101011000011",
|
|
"11010101010110000110",
|
|
"11100010101001110000",
|
|
"111100000011011101010101010000101010101010100001010011010101010011"
|
|
]
|
|
|
|
for bits in test_bits:
|
|
byte_vals = si.bit_str_to_bytearray(bits)
|
|
self.assertEqual(len(byte_vals), int(math.ceil(len(bits) / 8)), msg=bits)
|
|
|
|
recalculated = si.bytearray_to_bit_str(byte_vals)
|
|
|
|
if len(bits) % 8 == 0:
|
|
self.assertEqual(bits, recalculated)
|
|
elif bits.endswith("1"):
|
|
self.assertEqual(bits, recalculated.rstrip("0"))
|
|
else:
|
|
self.assertTrue(recalculated.startswith(bits))
|
|
|
|
def test_insert_sine_plugin(self):
|
|
insert_sine_plugin = self.sframe.ui.gvSignal.insert_sine_plugin
|
|
num_samples = 10000
|
|
dialog = insert_sine_plugin.get_insert_sine_dialog(original_data=self.sframe.signal.data,
|
|
position=2000,
|
|
sample_rate=self.sframe.signal.sample_rate,
|
|
num_samples=num_samples)
|
|
|
|
graphics_view = dialog.graphicsViewSineWave # type: ZoomableGraphicView
|
|
|
|
while not dialog.doubleSpinBoxAmplitude.isEnabled():
|
|
QApplication.instance().processEvents()
|
|
QTest.qWait(10)
|
|
|
|
self.assertEqual(int(graphics_view.sceneRect().width()), self.sframe.signal.num_samples + num_samples)
|
|
self.assertEqual(insert_sine_plugin.insert_indicator.rect().width(), num_samples)
|
|
self.assertEqual(insert_sine_plugin.insert_indicator.rect().x(), 2000)
|
|
|
|
dialog.doubleSpinBoxAmplitude.setValue(0.1)
|
|
dialog.doubleSpinBoxAmplitude.editingFinished.emit()
|
|
self.assertEqual(insert_sine_plugin.amplitude, 0.1)
|
|
|
|
while not dialog.doubleSpinBoxAmplitude.isEnabled():
|
|
self.app.processEvents()
|
|
QTest.qWait(10)
|
|
|
|
dialog.doubleSpinBoxFrequency.setValue(1e6)
|
|
dialog.doubleSpinBoxFrequency.editingFinished.emit()
|
|
self.assertEqual(insert_sine_plugin.frequency, 1e6)
|
|
|
|
while not dialog.doubleSpinBoxAmplitude.isEnabled():
|
|
self.app.processEvents()
|
|
QTest.qWait(10)
|
|
|
|
dialog.doubleSpinBoxPhase.setValue(100)
|
|
dialog.doubleSpinBoxPhase.editingFinished.emit()
|
|
self.assertEqual(insert_sine_plugin.phase, 100)
|
|
|
|
while not dialog.doubleSpinBoxAmplitude.isEnabled():
|
|
self.app.processEvents()
|
|
QTest.qWait(10)
|
|
|
|
dialog.doubleSpinBoxSampleRate.setValue(2e6)
|
|
dialog.doubleSpinBoxSampleRate.editingFinished.emit()
|
|
self.assertEqual(insert_sine_plugin.sample_rate, 2e6)
|
|
|
|
while not dialog.doubleSpinBoxAmplitude.isEnabled():
|
|
self.app.processEvents()
|
|
QTest.qWait(10)
|
|
|
|
dialog.doubleSpinBoxNSamples.setValue(0.5e6)
|
|
dialog.doubleSpinBoxNSamples.editingFinished.emit()
|
|
self.assertEqual(insert_sine_plugin.num_samples, 0.5e6)
|
|
|
|
while not dialog.doubleSpinBoxAmplitude.isEnabled():
|
|
self.app.processEvents()
|
|
QTest.qWait(10)
|
|
|
|
sep = Formatter.local_decimal_seperator()
|
|
self.assertEqual(dialog.lineEditTime.text(), "250" + sep + "000m")
|
|
|
|
# Close the dialog via finished
|
|
dialog.finished.emit(0)
|
|
QApplication.instance().processEvents()
|
|
QTest.qWait(self.CLOSE_TIMEOUT)
|