def test_ook_detection(self): data = np.fromfile(get_path_for_data_file("ask.complex"), dtype=np.complex64) mod = AutoInterpretation.detect_modulation(data) self.assertEqual(mod, "OOK") data = np.fromfile(get_path_for_data_file("ASK_mod.complex"), dtype=np.complex64) mod = AutoInterpretation.detect_modulation(data) self.assertEqual(mod, "OOK")
def test_for_fsk_signal_with_little_noise_before_and_after(self): data = np.concatenate( (np.fromfile(get_path_for_data_file("fsk.complex"), dtype=np.complex64)[-1000:], np.fromfile(get_path_for_data_file("fsk.complex"), dtype=np.complex64)[0:18800])) noise_level = detect_noise_level(np.abs(data)) self.assertGreaterEqual(noise_level, 0.0005) self.assertLessEqual(noise_level, 0.009)
def test_segmentation_elektromaten(self): signal = Signal(get_path_for_data_file("elektromaten.coco"), "") segments = segment_messages_from_magnitudes(signal.iq_array.magnitudes, noise_threshold=0.0167) segments = merge_message_segments_for_ook(segments) self.assertEqual(len(segments), 11)
def test_fsk_15db_center_detection(self): data = Signal(get_path_for_data_file("FSK15.complex"), "").iq_array.data rect = afp_demod(data, 0, "FSK", 2) center = detect_center(rect) self.assertGreaterEqual(center, -0.1979) self.assertLessEqual(center, 0.1131)
def test_noisy_rect(self): data = Signal(get_path_for_data_file("fsk.complex")).iq_array.data rect = afp_demod(data, 0.008, "FSK", 2)[5:15000] center = detect_center(rect) self.assertGreaterEqual(center, -0.0587) self.assertLessEqual(center, 0.02)
def test_segmentation_for_ask(self): signal = np.fromfile(get_path_for_data_file("ask.complex"), dtype=np.complex64) segments = segment_messages_from_magnitudes(np.abs(signal), 0.02) segments = merge_message_segments_for_ook(segments) self.assertEqual(len(segments), 1) self.assertEqual(segments[0], (462, 12011))
def test_multi_messages_different_rssi(self): data = Signal( get_path_for_data_file("multi_messages_different_rssi.coco"), "").data noise_level = detect_noise_level(np.abs(data)) self.assertGreater(noise_level, 0.001) self.assertLess(noise_level, 0.002)
def test_ask50_detection(self): message_indices = [(0, 8000), (18000, 26000), (36000, 44000), (54000, 62000), (72000, 80000)] data = np.fromfile(get_path_for_data_file("ask50.complex"), dtype=np.complex64) for start, end in message_indices: mod = AutoInterpretation.detect_modulation(data[start:end]) self.assertEqual(mod, "ASK", msg="{}/{}".format(start, end))
def test_auto_interpretation_elektromaten(self): data = Signal(get_path_for_data_file("elektromaten.coco"), "").data result = AutoInterpretation.estimate(data) mod_type, bit_length = result["modulation_type"], result["bit_length"] center, noise, tolerance = result["center"], result["noise"], result["tolerance"] self.assertEqual(mod_type, "ASK") self.assertEqual(bit_length, 600) demodulated = demodulate(data, mod_type, bit_length, center, noise, tolerance, pause_threshold=8) self.assertEqual(len(demodulated), 11) for i in range(11): self.assertTrue(demodulated[i].startswith("8")) # Test with added 20% noise np.random.seed(5) noise = np.random.normal(loc=0, scale=1, size=2 * len(data)).astype(np.float32).view(np.complex64) noised_data = data + 0.2 * np.mean(np.abs(data)) * noise result = AutoInterpretation.estimate(noised_data) mod_type, bit_length = result["modulation_type"], result["bit_length"] center, noise, tolerance = result["center"], result["noise"], result["tolerance"] self.assertEqual(mod_type, "ASK") self.assertEqual(bit_length, 600) demodulated = demodulate(noised_data, mod_type, bit_length, center, noise, tolerance, pause_threshold=8) self.assertEqual(len(demodulated), 11) for i in range(11): self.assertTrue(demodulated[i].startswith("8"))
def test_ask_center_detection(self): data = Signal(get_path_for_data_file("ask.complex")).iq_array.data rect = afp_demod(data, 0.01111, "ASK", 2) center = detect_center(rect) self.assertGreaterEqual(center, 0) self.assertLessEqual(center, 0.06)
def test_fsk_detection(self): fsk_signal = np.fromfile(get_path_for_data_file("fsk.complex"), dtype=np.complex64)[5:15000] mod = AutoInterpretation.detect_modulation(fsk_signal, wavelet_scale=4, median_filter_order=7) self.assertEqual(mod, "FSK")
def test_segmentation_enocean_multiple_messages(self): signal = np.fromfile(get_path_for_data_file("enocean.complex"), dtype=np.complex64) segments = segment_messages_from_magnitudes(np.abs(signal), 0.0448) segments = merge_message_segments_for_ook(segments) self.assertEqual(len(segments), 3) self.assertEqual(segments[0], (2107, 5432)) self.assertEqual(segments[1], (20428, 23758)) self.assertEqual(segments[2], (44216, 47546))
def test_ask_center_detection(self): data = np.fromfile(get_path_for_data_file("ask.complex"), dtype=np.complex64) rect = afp_demod(data, 0.01111, 0) center = detect_center(rect) self.assertGreaterEqual(center, 0) self.assertLessEqual(center, 0.06)
def test_noisy_rect(self): data = np.fromfile(get_path_for_data_file("fsk.complex"), dtype=np.complex64) rect = afp_demod(data, 0.008, 1)[5:15000] center = detect_center(rect) self.assertGreaterEqual(center, -0.0587) self.assertLessEqual(center, 0.02)
def test_enocean_center_detection(self): data = Signal(get_path_for_data_file("enocean.complex")).iq_array.data rect = afp_demod(data, 0.05, "ASK", 2) messages = [rect[2107:5432], rect[20428:23758], rect[44216:47546]] for i, msg in enumerate(messages): center = detect_center(msg) self.assertGreaterEqual(center, 0.04, msg=str(i)) self.assertLessEqual(center, 0.072, msg=str(i))
def test_noised_homematic_center_detection(self): data = Signal(get_path_for_data_file("noised_homematic.complex"), "").iq_array.data rect = afp_demod(data, 0.0, "FSK", 2) center = detect_center(rect) self.assertGreater(center, -0.0148) self.assertLess(center, 0.0024)
def test_enocean_center_detection(self): data = np.fromfile(get_path_for_data_file("enocean.complex"), dtype=np.complex64) rect = afp_demod(data, 0.05, 0) messages = [rect[2107:5432], rect[20428:23758], rect[44216:47546]] for i, msg in enumerate(messages): center = detect_center(msg) self.assertGreaterEqual(center, 0.04, msg=str(i)) self.assertLessEqual(center, 0.072, msg=str(i))
def test_auto_interpretation_ask(self): ask_signal = np.fromfile(get_path_for_data_file("ask.complex"), dtype=np.float32) result = AutoInterpretation.estimate(ask_signal) mod_type, bit_length = result["modulation_type"], result["bit_length"] center, noise, tolerance = result["center"], result["noise"], result["tolerance"] self.assertEqual(mod_type, "ASK") self.assertEqual(bit_length, 300) self.assertGreater(tolerance, 0) self.assertLessEqual(tolerance, 6) self.assertEqual(demodulate(ask_signal, mod_type, bit_length, center, noise, tolerance)[0], "b25b6db6c80")
def test_auto_interpretation_ask(self): ask_signal = np.fromfile(get_path_for_data_file("ask.complex"), dtype=np.complex64) result = AutoInterpretation.estimate(ask_signal) mod_type, bit_length = result["modulation_type"], result["bit_length"] center, noise, tolerance = result["center"], result["noise"], result["tolerance"] self.assertEqual(mod_type, "ASK") self.assertEqual(bit_length, 300) self.assertGreater(tolerance, 0) self.assertLessEqual(tolerance, 6) self.assertEqual(demodulate(ask_signal, mod_type, bit_length, center, noise, tolerance)[0], "b25b6db6c80")
def test_auto_interpretation_fsk(self): fsk_signal = np.fromfile(get_path_for_data_file("fsk.complex"), dtype=np.complex64) result = AutoInterpretation.estimate(fsk_signal) mod_type, bit_length = result["modulation_type"], result["bit_length"] center, noise, tolerance = result["center"], result["noise"], result["tolerance"] self.assertEqual(mod_type, "FSK") self.assertEqual(bit_length, 100) self.assertGreater(tolerance, 0) self.assertLessEqual(tolerance, 5) self.assertEqual(demodulate(fsk_signal, mod_type, bit_length, center, noise, tolerance)[0], "aaaaaaaac626c626f4dc1d98eef7a427999cd239d3f18")
def test_auto_interpretation_fsk(self): fsk_signal = np.fromfile(get_path_for_data_file("fsk.complex"), dtype=np.float32) result = AutoInterpretation.estimate(fsk_signal) mod_type, bit_length = result["modulation_type"], result["bit_length"] center, noise, tolerance = result["center"], result["noise"], result["tolerance"] self.assertEqual(mod_type, "FSK") self.assertEqual(bit_length, 100) self.assertGreater(tolerance, 0) self.assertLessEqual(tolerance, 5) self.assertEqual(demodulate(fsk_signal, mod_type, bit_length, center, noise, tolerance)[0], "aaaaaaaac626c626f4dc1d98eef7a427999cd239d3f18")
def test_message_segmentation_fsk_xavax(self): signal = Signal(get_path_for_data_file("xavax.coco"), "") segments = segment_messages_from_magnitudes(np.abs(signal.data), noise_threshold=0.002) # Signal starts with overdrive, so one message more self.assertTrue(len(segments) == 6 or len(segments) == 7) if len(segments) == 7: segments = segments[1:] self.assertEqual(segments, [(275146, 293697), (321073, 338819), (618213, 1631898), (1657890, 1678041), (1803145, 1820892), (1846213, 1866364)])
def test_auto_interpretation_xavax(self): signal = Signal(get_path_for_data_file("xavax.coco"), "") result = AutoInterpretation.estimate(signal.iq_array.data) mod_type, bit_length = result["modulation_type"], result["bit_length"] center, noise, tolerance = result["center"], result["noise"], result["tolerance"] self.assertEqual(mod_type, "FSK") self.assertEqual(bit_length, 100) demod = demodulate(signal.iq_array.data, mod_type, bit_length, center, noise, tolerance) self.assertGreaterEqual(len(demod), 5) for i in range(1, len(demod)): self.assertTrue(demod[i].startswith("aaaaaaaa"))
def test_ask_50_center_detection(self): message_indices = [(0, 8000), (18000, 26000), (36000, 44000), (54000, 62000), (72000, 80000)] data = Signal(get_path_for_data_file("ask50.complex")).iq_array.data rect = afp_demod(data, 0.0509, "ASK", 2) for start, end in message_indices: center = detect_center(rect[start:end]) self.assertGreaterEqual(center, 0.4, msg="{}/{}".format(start, end)) self.assertLessEqual(center, 0.65, msg="{}/{}".format(start, end))
def test_message_segmentation_fsk_xavax(self): signal = Signal(get_path_for_data_file("xavax.coco"), "") segments = segment_messages_from_magnitudes(signal.iq_array.magnitudes, noise_threshold=0.002) # Signal starts with overdrive, so one message more self.assertTrue(len(segments) == 6 or len(segments) == 7) if len(segments) == 7: segments = segments[1:] self.assertEqual(segments, [(275146, 293697), (321073, 338819), (618213, 1631898), (1657890, 1678041), (1803145, 1820892), (1846213, 1866364)])
def test_auto_interpretation_xavax(self): signal = Signal(get_path_for_data_file("xavax.coco"), "") result = AutoInterpretation.estimate(signal.data) mod_type, bit_length = result["modulation_type"], result["bit_length"] center, noise, tolerance = result["center"], result["noise"], result["tolerance"] self.assertEqual(mod_type, "FSK") self.assertEqual(bit_length, 100) demod = demodulate(signal.data, mod_type, bit_length, center, noise, tolerance) self.assertGreaterEqual(len(demod), 5) for i in range(1, len(demod)): self.assertTrue(demod[i].startswith("aaaaaaaa"))
def test_auto_interpretation_elektromaten(self): data = Signal(get_path_for_data_file("elektromaten.complex16s"), "").iq_array result = AutoInterpretation.estimate(data) mod_type, bit_length = result["modulation_type"], result["bit_length"] center, noise, tolerance = result["center"], result["noise"], result["tolerance"] self.assertEqual(mod_type, "ASK") self.assertEqual(bit_length, 600) demodulated = demodulate(data, mod_type, bit_length, center, noise, tolerance, pause_threshold=8) self.assertEqual(len(demodulated), 11) for i in range(11): self.assertTrue(demodulated[i].startswith("8"))
def test_auto_interpretation_homematic(self): data = Signal(get_path_for_data_file("homematic.coco"), "").data result = AutoInterpretation.estimate(data) mod_type, bit_length = result["modulation_type"], result["bit_length"] center, noise, tolerance = result["center"], result["noise"], result["tolerance"] self.assertEqual(mod_type, "FSK") self.assertEqual(bit_length, 100) demodulated = demodulate(data, mod_type, bit_length, center, noise, tolerance) self.assertEqual(len(demodulated), 2) for i in range(2): self.assertTrue(demodulated[i].startswith("aaaaaaaa"))
def test_homematic_center_detection(self): data = Signal(get_path_for_data_file("homematic.coco"), "").data rect = afp_demod(data, 0.0012, 1) msg1 = rect[17719:37861] msg2 = rect[70412:99385] center1 = detect_center(msg1) self.assertGreaterEqual(center1, -0.1285) self.assertLessEqual(center1, -0.0413) center2 = detect_center(msg2) self.assertGreaterEqual(center2, -0.1377) self.assertLessEqual(center2, -0.0367)
def test_auto_interpretation_homematic(self): data = Signal(get_path_for_data_file("homematic.complex32s"), "").iq_array result = AutoInterpretation.estimate(data) mod_type, bit_length = result["modulation_type"], result["bit_length"] center, noise, tolerance = result["center"], result["noise"], result["tolerance"] self.assertEqual(mod_type, "FSK") self.assertEqual(bit_length, 100) demodulated = demodulate(data, mod_type, bit_length, center, noise, tolerance) self.assertEqual(len(demodulated), 2) for i in range(2): self.assertTrue(demodulated[i].startswith("aaaaaaaa"))
def test_auto_interpretation_enocean(self): enocean_signal = np.fromfile(get_path_for_data_file("enocean.complex"), dtype=np.float32) result = AutoInterpretation.estimate(enocean_signal) mod_type, bit_length = result["modulation_type"], result["bit_length"] center, noise, tolerance = result["center"], result["noise"], result["tolerance"] self.assertEqual(mod_type, "ASK") self.assertGreaterEqual(center, 0.0077) self.assertLessEqual(center, 0.0465) self.assertLessEqual(tolerance, 5) self.assertEqual(bit_length, 40) demod = demodulate(enocean_signal, mod_type, bit_length, center, noise, tolerance, decoding=Encoding(["WSP", settings.DECODING_ENOCEAN])) self.assertEqual(len(demod), 3) self.assertEqual(demod[0], demod[2]) self.assertEqual(demod[0], "aa9610002c1c024b")
def test_ask_50_center_detection(self): message_indices = [(0, 8000), (18000, 26000), (36000, 44000), (54000, 62000), (72000, 80000)] data = np.fromfile(get_path_for_data_file("ask50.complex"), dtype=np.complex64) rect = afp_demod(data, 0.0509, 0) for start, end in message_indices: center = detect_center(rect[start:end]) self.assertGreaterEqual(center, 0.5326, msg="{}/{}".format(start, end)) self.assertLessEqual(center, 0.9482, msg="{}/{}".format(start, end))
def test_auto_interpretation_enocean(self): enocean_signal = np.fromfile(get_path_for_data_file("enocean.complex"), dtype=np.complex64) result = AutoInterpretation.estimate(enocean_signal) mod_type, bit_length = result["modulation_type"], result["bit_length"] center, noise, tolerance = result["center"], result["noise"], result["tolerance"] self.assertEqual(mod_type, "ASK") self.assertGreaterEqual(center, 0.04) self.assertLessEqual(center, 0.066) self.assertLessEqual(tolerance, 5) self.assertEqual(bit_length, 40) demod = demodulate(enocean_signal, mod_type, bit_length, center, noise, tolerance, decoding=Encoding(["WSP", constants.DECODING_ENOCEAN])) self.assertEqual(len(demod), 3) self.assertEqual(demod[0], demod[2]) self.assertEqual(demod[0], "aa9610002c1c024b")
def test_auto_interpretation_elektromaten(self): data = Signal(get_path_for_data_file("elektromaten.coco"), "").iq_array result = AutoInterpretation.estimate(data) mod_type, bit_length = result["modulation_type"], result["bit_length"] center, noise, tolerance = result["center"], result["noise"], result[ "tolerance"] self.assertEqual(mod_type, "ASK") self.assertEqual(bit_length, 600) demodulated = demodulate(data, mod_type, bit_length, center, noise, tolerance, pause_threshold=8) self.assertEqual(len(demodulated), 11) for i in range(11): self.assertTrue(demodulated[i].startswith("8")) # Test with added 20% noise np.random.seed(5) noise = np.random.normal(loc=0, scale=1, size=2 * len(data)).astype( np.float32).view(np.complex64) noised_data = data.as_complex64() + 0.2 * np.mean( data.magnitudes) * noise result = AutoInterpretation.estimate(noised_data) mod_type, bit_length = result["modulation_type"], result["bit_length"] center, noise, tolerance = result["center"], result["noise"], result[ "tolerance"] self.assertEqual(mod_type, "ASK") self.assertEqual(bit_length, 600) demodulated = demodulate(noised_data, mod_type, bit_length, center, noise, tolerance, pause_threshold=8) self.assertEqual(len(demodulated), 11) for i in range(11): self.assertTrue(demodulated[i].startswith("8"))
def test_fsk_live_capture(self): data = Signal(get_path_for_data_file("fsk_live.coco"), "").data n = 10 moving_average_filter = Filter([1 / n for _ in range(n)], filter_type=FilterType.moving_average) filtered_data = moving_average_filter.apply_fir_filter(data) rect = afp_demod(filtered_data, 0.0175, 1) center = detect_center(rect) self.assertGreaterEqual(center, -0.0148, msg="Filtered") self.assertLessEqual(center, 0.01, msg="Filtered") rect = afp_demod(data, 0.0175, 1) center = detect_center(rect) self.assertGreaterEqual(center, -0.02, msg="Original") self.assertLessEqual(center, 0.01, msg="Original")
def test_fsk_live_capture(self): data = Signal(get_path_for_data_file("fsk_live.coco"), "").iq_array.data n = 10 moving_average_filter = Filter([1 / n for _ in range(n)], filter_type=FilterType.moving_average) filtered_data = moving_average_filter.apply_fir_filter( data.flatten()).view(np.float32) filtered_data = filtered_data.reshape((len(filtered_data) // 2, 2)) rect = afp_demod(filtered_data, 0.0175, "FSK", 2) center = detect_center(rect) self.assertGreaterEqual(center, -0.0148, msg="Filtered") self.assertLessEqual(center, 0.01, msg="Filtered") rect = afp_demod(data, 0.0175, "FSK", 2) center = detect_center(rect) self.assertGreaterEqual(center, -0.02, msg="Original") self.assertLessEqual(center, 0.01, msg="Original")
def test_for_psk_signal(self): data = Signal(get_path_for_data_file("psk_generated.complex"), "").data noise_level = detect_noise_level(np.abs(data)) self.assertGreater(noise_level, 0.0067) self.assertLessEqual(noise_level, 0.0081)
def test_segmentation_for_fsk(self): signal = np.fromfile(get_path_for_data_file("fsk.complex"), dtype=np.complex64) segments = segment_messages_from_magnitudes(np.abs(signal), 0.0009) self.assertEqual(len(segments), 1) self.assertEqual(segments[0], (0, 17742))
def test_auto_interpretation_overshoot_ook(self): data = Signal(get_path_for_data_file("ook_overshoot.coco"), "").data result = AutoInterpretation.estimate(data) self.assertEqual(result["modulation_type"], "ASK") self.assertEqual(result["bit_length"], 500)
def test_for_fsk_signal_with_little_noise_before_and_after(self): data = np.concatenate((np.fromfile(get_path_for_data_file("fsk.complex"), dtype=np.complex64)[-1000:], np.fromfile(get_path_for_data_file("fsk.complex"), dtype=np.complex64)[0:18800])) noise_level = detect_noise_level(np.abs(data)) self.assertGreaterEqual(noise_level, 0.0005) self.assertLessEqual(noise_level, 0.009)
def test_for_enocean_ask_signal(self): data = np.fromfile(get_path_for_data_file("enocean.complex"), dtype=np.complex64) noise_level = detect_noise_level(np.abs(data)) self.assertGreaterEqual(noise_level, 0.01) self.assertLessEqual(noise_level, 0.28)
def test_segmentation_elektromaten(self): signal = Signal(get_path_for_data_file("elektromaten.coco"), "") segments = segment_messages_from_magnitudes(np.abs(signal.data), noise_threshold=0.0167) segments = merge_message_segments_for_ook(segments) self.assertEqual(len(segments), 11)
def test_for_noiseless_signal(self): data = np.fromfile(get_path_for_data_file("fsk.complex"), dtype=np.complex64)[0:17639] noise_level = detect_noise_level(np.abs(data)) self.assertEqual(noise_level, 0)
def test_for_noisy_fsk_15db_signal(self): data = Signal(get_path_for_data_file("FSK15.complex"), "").data noise_level = detect_noise_level(np.abs(data)) self.assertEqual(noise_level, 0)
def test_multi_messages_different_rssi(self): data = Signal(get_path_for_data_file("multi_messages_different_rssi.coco"), "").data noise_level = detect_noise_level(np.abs(data)) self.assertGreater(noise_level, 0.001) self.assertLess(noise_level, 0.002)