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>
This commit is contained in:
2026-01-14 22:33:32 -08:00
parent 161fbc9b9c
commit 4237c4bdb8
17 changed files with 1158 additions and 1114 deletions
+92
View File
@@ -0,0 +1,92 @@
#!/usr/bin/env python3
"""
Test GPS extraction from T-Embed files
Demonstrates automatic GPS population from filenames
"""
import sys
from pathlib import Path
# Add project root to path
sys.path.insert(0, str(Path(__file__).parent.parent))
from src.parser.gps_extractor import GPSFilenameExtractor
def main():
"""Test GPS extraction on T-Embed files"""
print("=" * 80)
print("GPS EXTRACTION TEST - T-Embed Files")
print("=" * 80)
print()
# Find T-Embed files
tembed_dir = Path(__file__).parent.parent / 'signatures' / 't-embed-rf'
if not tembed_dir.exists():
print(f"❌ T-Embed directory not found: {tembed_dir}")
return 1
sub_files = list(tembed_dir.glob('*.sub'))
print(f"Found {len(sub_files)} .sub files")
print()
# Test extraction
extractor = GPSFilenameExtractor()
with_gps = []
without_gps = []
for sub_file in sorted(sub_files):
coords = extractor.extract(sub_file.name)
if coords:
with_gps.append((sub_file.name, coords))
print(f"{sub_file.name}")
print(f" 📍 Latitude: {coords.latitude:.6f}")
print(f" 📍 Longitude: {coords.longitude:.6f}")
print(f" 📋 Source: {coords.source}")
else:
without_gps.append(sub_file.name)
print(f"⏭️ {sub_file.name} - No GPS in filename")
print()
# Summary
print("=" * 80)
print("SUMMARY")
print("=" * 80)
print(f"Total files: {len(sub_files)}")
print(f"With GPS coords: {len(with_gps)} ({len(with_gps)/len(sub_files)*100:.1f}%)")
print(f"Without GPS coords: {len(without_gps)} ({len(without_gps)/len(sub_files)*100:.1f}%)")
print()
if with_gps:
print("Files with GPS coordinates:")
for filename, coords in with_gps:
print(f" - {filename}")
print(f" {coords.latitude:.6f}, {coords.longitude:.6f}")
print()
if without_gps:
print("Files without GPS (would need manual entry or JSON companion):")
for filename in without_gps:
print(f" - {filename}")
print()
print("=" * 80)
print("NEXT STEPS")
print("=" * 80)
print("1. Files with GPS in filename → Auto-populate coordinates")
print("2. Files without GPS → Look for companion JSON files")
print("3. If no JSON found → Require manual GPS entry during upload")
print("=" * 80)
return 0
if __name__ == '__main__':
sys.exit(main())