Files
rpi-tulivision/test_custom_decoder.py
2025-09-27 22:35:56 +02:00

189 lines
6.6 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Test script for the custom IR protocol decoder
Tests the decoder against captured signal data
"""
import json
import sys
import os
from custom_ir_protocol import CustomIRProtocol
def test_decoder_with_captured_data():
"""Test the custom decoder with captured signal data"""
# Load captured signals
try:
with open("ir_analysis_20250927_190536.json", 'r') as f:
signals = json.load(f)
except FileNotFoundError:
print("Error: ir_analysis_20250927_190536.json not found!")
return False
# Create custom protocol decoder
protocol = CustomIRProtocol("TEST_CUSTOM")
print("Testing Custom IR Protocol Decoder")
print("=" * 50)
print(f"Loaded {len(signals)} captured signals")
print()
# Test signals with 71 pulses (most common)
successful_decodes = 0
failed_decodes = 0
decoded_commands = {}
for i, signal_data in enumerate(signals):
pulse_count = signal_data['pulse_count']
pulses = signal_data['pulses']
# Convert to the format expected by the decoder
# (is_pulse, duration_in_seconds)
formatted_pulses = []
for j, duration_us in enumerate(pulses):
is_pulse = (j % 2 == 0) # Alternating pulse/space
duration_seconds = duration_us / 1000000.0
formatted_pulses.append((is_pulse, duration_seconds))
# Try to decode
command = protocol.decode(formatted_pulses)
if command:
successful_decodes += 1
if command not in decoded_commands:
decoded_commands[command] = 0
decoded_commands[command] += 1
print(f"Signal {i+1:2d} ({pulse_count:2d} pulses): {command}")
else:
failed_decodes += 1
if pulse_count == 71: # Only show failed 71-pulse signals
print(f"Signal {i+1:2d} ({pulse_count:2d} pulses): FAILED TO DECODE")
print()
print("=" * 50)
print("DECODING RESULTS")
print("=" * 50)
print(f"Successful decodes: {successful_decodes}")
print(f"Failed decodes: {failed_decodes}")
print(f"Success rate: {successful_decodes/(successful_decodes+failed_decodes)*100:.1f}%")
print()
if decoded_commands:
print("Decoded commands:")
for command, count in sorted(decoded_commands.items()):
print(f" {command}: {count} occurrences")
print()
# Analyze timing patterns for failed decodes
print("Analyzing timing patterns...")
analyze_timing_patterns(signals, protocol)
return successful_decodes > 0
def analyze_timing_patterns(signals, protocol):
"""Analyze timing patterns to help debug the decoder"""
print("\nTiming analysis for 71-pulse signals:")
print("-" * 40)
for signal_data in signals:
if signal_data['pulse_count'] == 71:
pulses = signal_data['pulses']
# Check header
if len(pulses) >= 2:
header_pulse = pulses[0]
header_space = pulses[1]
print(f"Header: {header_pulse:.0f}μs pulse, {header_space:.0f}μs space")
# Check if header matches expected timing
pulse_match = protocol._is_timing_match(header_pulse, protocol.HEADER_PULSE)
space_match = protocol._is_timing_match(header_space, protocol.HEADER_SPACE)
print(f" Header pulse match: {pulse_match}")
print(f" Header space match: {space_match}")
# Analyze first few data bits
if len(pulses) >= 6:
print(" First data bits:")
for i in range(2, min(8, len(pulses)), 2):
if i + 1 < len(pulses):
pulse_time = pulses[i]
space_time = pulses[i + 1]
pulse_match = protocol._is_timing_match(pulse_time, protocol.BIT_PULSE)
space_0_match = protocol._is_timing_match(space_time, protocol.BIT_0_SPACE)
space_1_match = protocol._is_timing_match(space_time, protocol.BIT_1_SPACE)
bit_value = "?"
if space_0_match:
bit_value = "0"
elif space_1_match:
bit_value = "1"
print(f" Bit {(i-2)//2}: {pulse_time:.0f}μs pulse, {space_time:.0f}μs space -> {bit_value}")
break # Only analyze first 71-pulse signal
def create_mapping_file():
"""Create a mapping file for the decoded commands"""
# Example mapping based on common IR remote patterns
mapping = {
"CUSTOM_0000_0001": {
"command": "power_toggle",
"description": "Power on/off",
"repeatable": True
},
"CUSTOM_0000_0002": {
"command": "channel_1",
"description": "Channel 1",
"repeatable": False
},
"CUSTOM_0000_0003": {
"command": "channel_2",
"description": "Channel 2",
"repeatable": False
},
"CUSTOM_0000_0004": {
"command": "channel_3",
"description": "Channel 3",
"repeatable": False
},
"CUSTOM_0000_0005": {
"command": "volume_up",
"description": "Volume up",
"repeatable": True
},
"CUSTOM_0000_0006": {
"command": "volume_down",
"description": "Volume down",
"repeatable": True
},
"REPEAT": {
"command": "repeat_last",
"description": "Repeat last command",
"repeatable": False
}
}
with open("custom_ir_mapping.json", "w") as f:
json.dump(mapping, f, indent=2)
print("Created custom_ir_mapping.json with example mappings")
if __name__ == "__main__":
success = test_decoder_with_captured_data()
if success:
print("\nDecoder test completed successfully!")
print("You can now integrate the custom protocol into your IR system.")
create_mapping_file()
else:
print("\nDecoder test failed. Check the timing constants and protocol structure.")
print("You may need to adjust the timing values in custom_ir_protocol.py")
sys.exit(0 if success else 1)