Files
giglez/scripts/archive/test_tembed_matching.py
Trilltechnician 4237c4bdb8 Phase 1 & 2: Cleanup redundant code and integrate pattern decoder
## Phase 1: Code Cleanup (~1,859 lines removed)

**Deleted Redundant Matchers:**
-  strategies_orm.py (356 lines) - Old ORM-based strategies
-  simple_matcher.py (351 lines) - Replaced by strategies.py
-  rtl433_matcher.py (352 lines) - Replaced by strategies.py

**Archived Old Scripts:**
- Moved 11 one-time analysis/import scripts to scripts/archive/
- Scripts: analyze_flipper_signatures, analyze_tembed_files, identify_tembed_devices,
  import_flipper_sqlite, import_tembed_signatures, match_tembed_with_db,
  match_with_flipper_db, rematch_captures, test_gps_extraction,
  test_tembed_matching, test_wardriving_import

**Consolidated API:**
- Renamed main.py → main_orm_legacy.py (archived old ORM-based API)
- main_simple.py is now the primary production API

## Phase 2: Pattern Decoder Integration 

**CRITICAL FIX: Pattern decoder now integrated into production API!**

**Changes:**
1. Updated main_simple.py to use unified SignatureMatcher
2. Added 6 strategies to matcher pipeline:
   - ExactMatcher (protocol + frequency)
   - FrequencyMatcher (frequency-based)
   - BitPatternMatcher (data patterns)
   - TimingMatcher (timing-based)
   - RTL433DecoderStrategy (RTL_433 decoder)
   - PatternBasedStrategy (NEW! Pattern decoder for short captures)

3. Created MockDB class for simplified mode (no real database)
4. Replaced old get_matcher() with get_matcher_engine()
5. Updated upload handler to use MatchResult format
6. All matches now include confidence scores and match methods

**Result:**
- Pattern decoder is NOW ACTIVE in production 🎉
- Unified matching pipeline with 6 strategies
- Cleaner codebase (-1,859 lines)
- Single source of truth for matching logic

🎉 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-14 22:33:32 -08:00

154 lines
4.5 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Test T-Embed signature matching
This script:
1. Imports T-Embed signatures into database (if not already imported)
2. Tests matching engine against the same files
3. Shows matching accuracy and confidence scores
"""
import sys
from pathlib import Path
# Add project root to path
sys.path.insert(0, str(Path(__file__).parent.parent))
from src.parser.sub_parser import SubFileParser
from src.matcher.strategies_orm import (
FrequencyMatcherORM,
TimingMatcherORM,
RAWPatternMatcherORM,
ExactMatcherORM
)
from src.database.connection import get_session
def test_matching():
"""Test signature matching with T-Embed files"""
print("="*70)
print("T-Embed Signature Matching Test")
print("="*70)
print()
# Get database session
session = get_session()
# Initialize parser and matchers
parser = SubFileParser()
matchers = [
('Exact', ExactMatcherORM(session)),
('Frequency', FrequencyMatcherORM(session, tolerance_hz=10000)),
('Timing', TimingMatcherORM(session)),
('RAW Pattern', RAWPatternMatcherORM(session, min_samples=10))
]
# Find T-Embed files
tembed_dir = Path(__file__).parent.parent / 'signatures' / 't-embed-rf'
sub_files = sorted(tembed_dir.glob('*.sub'))
print(f"Found {len(sub_files)} .sub files\n")
total_files = 0
total_matches = 0
# Test each file
for sub_file in sub_files:
print("-"*70)
print(f"File: {sub_file.name}")
# Parse file
try:
metadata = parser.parse(str(sub_file))
except Exception as e:
print(f" ❌ Parse error: {e}\n")
continue
# Skip empty files
if metadata.frequency == 0 or (metadata.file_format == 'RAW' and not metadata.raw_data):
print(f" ⏭️ Skipped: Empty capture\n")
continue
total_files += 1
# Show signal info
print(f"\nSignal Info:")
print(f" Frequency: {metadata.frequency/1e6:.2f} MHz")
print(f" Protocol: {metadata.protocol or 'RAW'}")
print(f" Format: {metadata.file_format}")
if metadata.raw_data:
abs_timings = [abs(t) for t in metadata.raw_data]
print(f" RAW Samples: {len(metadata.raw_data)}")
print(f" Timing Range: {min(abs_timings)}-{max(abs_timings)} μs")
print(f" Avg Timing: {sum(abs_timings)/len(abs_timings):.1f} μs")
# Try each matcher
print(f"\nMatching Results:")
file_matched = False
for matcher_name, matcher in matchers:
try:
matches = matcher.match(metadata)
if matches:
file_matched = True
print(f"\n {matcher_name} Matcher: {len(matches)} match(es)")
# Show top 3 matches
for i, match in enumerate(matches[:3], 1):
print(f" {i}. {match.device_name}")
print(f" Manufacturer: {match.manufacturer}")
print(f" Confidence: {match.confidence:.2%}")
print(f" Method: {match.match_method}")
# Show match details
if match.match_details:
for key, value in match.match_details.items():
if key != 'signature_id':
print(f" {key}: {value}")
except Exception as e:
print(f" ❌ {matcher_name} error: {e}")
if file_matched:
total_matches += 1
print(f"\n ✅ File matched successfully!")
else:
print(f"\n ⚠️ No matches found")
print()
# Summary
print("="*70)
print("MATCHING SUMMARY")
print("="*70)
print(f"Files tested: {total_files}")
print(f"Files matched: {total_matches}")
if total_files > 0:
match_rate = (total_matches / total_files) * 100
print(f"Match rate: {match_rate:.1f}%")
if match_rate == 100:
print("\n✅ Perfect! All files matched to signatures")
elif match_rate >= 75:
print(f"\n✅ Good! Most files matched")
elif match_rate >= 50:
print(f"\n⚠️ Moderate: Some files unmatched")
else:
print(f"\n❌ Low match rate - may need more signatures or tuning")
else:
print("\n⚠️ No valid files to test")
print("="*70)
session.close()
if __name__ == '__main__':
test_matching()