#!/usr/bin/env python3 """ Test Pattern Decoder with Real RF Captures Tests the pattern-based decoder against the same weather sensor captures that failed with RTL_433 (0% decode rate). """ import sys from pathlib import Path # Add project to path sys.path.insert(0, str(Path(__file__).parent.parent)) from src.parser.sub_parser import parse_sub_file from src.matcher.pattern_decoder import get_pattern_decoder def test_pattern_decoder(test_dir="data/test_rtl433_real"): """Test pattern decoder against real weather sensor captures""" test_path = Path(test_dir) if not test_path.exists(): print(f"❌ Test directory not found: {test_dir}") return False # Get pattern decoder decoder = get_pattern_decoder() print("=" * 80) print("Testing Pattern Decoder with Real Weather Sensor Captures") print("=" * 80) print() print(f"Source: FlipperZero-Subghz-DB (previously tested with RTL_433)") print(f"RTL_433 Result: 0% decode rate (0/8 files)") print(f"Test Directory: {test_path}") print(f"Decoder Version: {decoder.get_version()}") print() # Get all .sub files sub_files = sorted(test_path.glob("*.sub")) if not sub_files: print(f"❌ No .sub files found in {test_dir}") return False print(f"Testing {len(sub_files)} weather sensor captures") print() # Test each file results = [] successful_decodes = 0 total_devices_decoded = 0 for i, sub_file in enumerate(sub_files, 1): print("─" * 80) print(f"[{i}/{len(sub_files)}] {sub_file.name}") print("─" * 80) try: # Parse .sub file metadata = parse_sub_file(str(sub_file)) print(f"Protocol: {metadata.protocol or 'RAW'}") print(f"Frequency: {metadata.frequency / 1_000_000:.3f} MHz") print(f"Format: {metadata.file_format}") if metadata.has_raw_data: print(f"RAW Data: {metadata.pulse_count} pulses") # Show first few pulses for debugging pulses = metadata.raw_data[:10] print(f"First pulses: {pulses}") else: print(f"⚠️ No RAW data - skipping") results.append({ "filename": sub_file.name, "decoded": False, "reason": "No RAW data" }) print() continue print() # Try pattern decoding print("🔍 Running Pattern Decoder...") matches = decoder.decode(metadata) if matches: successful_decodes += 1 total_devices_decoded += len(matches) print(f"✅ SUCCESS! Decoded {len(matches)} device(s):") print() for j, match in enumerate(matches, 1): print(f" Match #{j}:") print(f" Device: {match.name}") print(f" Manufacturer: {match.manufacturer or 'Unknown'}") print(f" Category: {match.category}") print(f" Confidence: {match.confidence:.2%}") print(f" Method: {match.match_method}") # Show details if match.details: print(f" Details:") for key, value in match.details.items(): print(f" {key}: {value}") print() results.append({ "filename": sub_file.name, "decoded": True, "match_count": len(matches), "matches": matches }) else: print("❌ No devices decoded") print() results.append({ "filename": sub_file.name, "decoded": False, "reason": "Pattern decoder found no matches" }) except Exception as e: print(f"❌ Error: {e}") import traceback traceback.print_exc() print() results.append({ "filename": sub_file.name, "decoded": False, "error": str(e) }) # Summary print("=" * 80) print("SUMMARY") print("=" * 80) print() total_files = len(results) success_rate = (successful_decodes / total_files * 100) if total_files > 0 else 0 print(f"Total Files: {total_files}") print(f"Successful Decodes: {successful_decodes} ({success_rate:.1f}%)") print(f"Failed Decodes: {total_files - successful_decodes}") print(f"Total Devices: {total_devices_decoded}") print() # Detailed results print("Results by File:") print() for result in results: filename = result["filename"] decoded = result.get("decoded", False) match_count = result.get("match_count", 0) if decoded: status = f"✅ {match_count} device(s) decoded" elif "error" in result: status = f"❌ Error: {result['error'][:50]}" elif "reason" in result: status = f"⚠️ {result['reason']}" else: status = "❌ No decode" print(f" {filename:<55} {status}") print() # Device breakdown if successful_decodes > 0: print("=" * 80) print("DECODED DEVICES") print("=" * 80) print() for result in results: if result.get("decoded") and result.get("matches"): print(f"{result['filename']}:") for match in result['matches']: print(f" → {match.manufacturer or 'Unknown'} {match.name} ({match.confidence:.0%})") print() # Analysis print("=" * 80) print("ANALYSIS") print("=" * 80) print() if success_rate >= 50: print("🎉 EXCELLENT! Pattern decoder is working well!") print(f" Achieved {success_rate:.1f}% decode rate with single-transmission captures") elif success_rate >= 25: print("✅ GOOD! Pattern decoder is successfully identifying devices") print(f" {success_rate:.1f}% success rate shows promise") elif success_rate > 0: print("⚠️ PARTIAL SUCCESS - Some devices decoded") print(f" {success_rate:.1f}% success rate - may need tuning") else: print("❌ NO DECODES") print(" Possible causes:") print(" - Timing patterns don't match protocol database") print(" - Signals too short for reliable analysis") print(" - Need to tune confidence thresholds") print() # Comparison with RTL_433 print("Comparison with RTL_433:") print(" RTL_433 (multi-rep decoder): 0% (0/8 files)") print(f" Pattern Decoder (single-tx): {success_rate:.1f}% ({successful_decodes}/{total_files} files)") print() if successful_decodes > 0: improvement = "SIGNIFICANT IMPROVEMENT" if success_rate > 30 else "IMPROVEMENT" print(f" Result: {improvement} ✅") print(f" Validates that pattern-based approach works for short captures!") else: print(" Result: No improvement yet (needs investigation)") print(" Next steps:") print(" - Check if timing thresholds are too strict") print(" - Add more protocols to database") print(" - Lower confidence thresholds") print() print("=" * 80) return successful_decodes > 0 if __name__ == '__main__': success = test_pattern_decoder() sys.exit(0 if success else 1)