4237c4bdb8
## 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>
88 lines
2.6 KiB
Python
88 lines
2.6 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
Re-match existing captures with device matcher
|
||
|
||
Runs the device matcher on all existing captures in the database
|
||
"""
|
||
|
||
import sys
|
||
import json
|
||
from pathlib import Path
|
||
|
||
# Add project root to path
|
||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||
|
||
from src.matcher.simple_matcher import get_matcher
|
||
|
||
|
||
def rematch_captures(storage_file):
|
||
"""Re-run device matching on existing captures"""
|
||
|
||
if not Path(storage_file).exists():
|
||
print(f"❌ Storage file not found: {storage_file}")
|
||
return 1
|
||
|
||
# Load existing captures
|
||
with open(storage_file, 'r') as f:
|
||
data = json.load(f)
|
||
|
||
captures = data.get('captures', [])
|
||
|
||
if not captures:
|
||
print("ℹ️ No captures to process")
|
||
return 0
|
||
|
||
print(f"🔄 Re-matching {len(captures)} captures...")
|
||
|
||
matcher = get_matcher()
|
||
updated_count = 0
|
||
|
||
for i, capture in enumerate(captures, 1):
|
||
frequency = capture.get('frequency', 0)
|
||
protocol = capture.get('protocol', 'RAW')
|
||
preset = capture.get('preset', 'Unknown')
|
||
|
||
# Skip if already has device data
|
||
if capture.get('device_name'):
|
||
continue
|
||
|
||
# Perform matching
|
||
matches = matcher.match(frequency, protocol, preset)
|
||
best_match = matches[0] if matches else None
|
||
|
||
if best_match:
|
||
# Update capture with device data
|
||
capture['device_name'] = best_match.device_name
|
||
capture['device_category'] = best_match.device_category
|
||
capture['match_confidence'] = best_match.confidence
|
||
capture['match_method'] = best_match.match_method
|
||
capture['device_description'] = best_match.description
|
||
capture['matched_devices'] = [
|
||
{
|
||
"device_name": m.device_name,
|
||
"category": m.device_category,
|
||
"confidence": m.confidence,
|
||
"method": m.match_method,
|
||
"description": m.description
|
||
}
|
||
for m in matches[:5]
|
||
]
|
||
updated_count += 1
|
||
|
||
print(f" [{i}/{len(captures)}] {capture['filename']}: {best_match.device_name} ({best_match.confidence:.0%})")
|
||
else:
|
||
print(f" [{i}/{len(captures)}] {capture['filename']}: No match found")
|
||
|
||
# Save updated data
|
||
with open(storage_file, 'w') as f:
|
||
json.dump(data, f, indent=2)
|
||
|
||
print(f"\n✅ Updated {updated_count}/{len(captures)} captures with device information")
|
||
|
||
return 0
|
||
|
||
|
||
if __name__ == '__main__':
|
||
STORAGE_FILE = Path(__file__).parent.parent / "data" / "captures_simple.json"
|
||
sys.exit(rematch_captures(STORAGE_FILE))
|