Fix device detection format and pipeline deployment compatibility
Device Detection Updates: - Update device series detection to use product_id mapping (0x100 -> KL520, 0x720 -> KL720) - Handle JSON dict format from kp.core.scan_devices() properly - Extract usb_port_id correctly from device descriptors - Support multiple device descriptor formats (dict, list, object) - Enhanced debug output shows Product ID for verification Pipeline Deployment Fixes: - Remove invalid preprocessor/postprocessor parameters from MultiDongle constructor - Add max_queue_size parameter support to MultiDongle - Fix pipeline stage initialization to match MultiDongle constructor - Add auto_detect parameter support for pipeline stages - Store stage processors as instance variables for future use Example Updates: - Update device_detection_example.py to show Product ID in output - Enhanced error handling and format detection Resolves pipeline deployment error: "MultiDongle.__init__() got an unexpected keyword argument 'preprocessor'" Now properly handles real device descriptors with correct product_id to series mapping. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
918b9aabd1
commit
e0169cd845
@ -49,11 +49,15 @@ class PipelineStage:
|
||||
ncpu_fw_path=config.ncpu_fw_path,
|
||||
model_path=config.model_path,
|
||||
upload_fw=config.upload_fw,
|
||||
preprocessor=config.stage_preprocessor,
|
||||
postprocessor=config.stage_postprocessor,
|
||||
auto_detect=config.auto_detect if hasattr(config, 'auto_detect') else False,
|
||||
max_queue_size=config.max_queue_size
|
||||
)
|
||||
|
||||
# Store preprocessor and postprocessor for later use
|
||||
self.stage_preprocessor = config.stage_preprocessor
|
||||
self.stage_postprocessor = config.stage_postprocessor
|
||||
self.max_queue_size = config.max_queue_size
|
||||
|
||||
# Inter-stage processors
|
||||
self.input_preprocessor = config.input_preprocessor
|
||||
self.output_postprocessor = config.output_postprocessor
|
||||
|
||||
@ -95,12 +95,40 @@ class MultiDongle:
|
||||
return []
|
||||
|
||||
devices_info = []
|
||||
|
||||
# Handle both dict and object formats
|
||||
if isinstance(device_descriptors, dict):
|
||||
# Handle JSON dict format: {"0": {...}, "1": {...}}
|
||||
print(f' - Found {len(device_descriptors)} device(s):')
|
||||
|
||||
for key, device_desc in device_descriptors.items():
|
||||
# Get device series using product_id
|
||||
series = MultiDongle._get_device_series(device_desc)
|
||||
# Use usb_port_id from the device descriptor
|
||||
port_id = device_desc.get('usb_port_id', 0)
|
||||
|
||||
device_info = {
|
||||
'port_id': port_id,
|
||||
'series': series,
|
||||
'device_descriptor': device_desc
|
||||
}
|
||||
devices_info.append(device_info)
|
||||
|
||||
print(f' [{int(key)+1}] Port ID: {port_id}, Series: {series}, Product ID: {device_desc.get("product_id", "Unknown")}')
|
||||
|
||||
elif isinstance(device_descriptors, (list, tuple)):
|
||||
# Handle list/array format
|
||||
print(f' - Found {len(device_descriptors)} device(s):')
|
||||
|
||||
for i, device_desc in enumerate(device_descriptors):
|
||||
# Get device series (e.g., KL520, KL720, etc.)
|
||||
# Get device series
|
||||
series = MultiDongle._get_device_series(device_desc)
|
||||
port_id = device_desc.port_id
|
||||
|
||||
# Extract port_id based on format
|
||||
if isinstance(device_desc, dict):
|
||||
port_id = device_desc.get('usb_port_id', device_desc.get('port_id', 0))
|
||||
else:
|
||||
port_id = getattr(device_desc, 'usb_port_id', getattr(device_desc, 'port_id', 0))
|
||||
|
||||
device_info = {
|
||||
'port_id': port_id,
|
||||
@ -110,6 +138,24 @@ class MultiDongle:
|
||||
devices_info.append(device_info)
|
||||
|
||||
print(f' [{i+1}] Port ID: {port_id}, Series: {series}')
|
||||
else:
|
||||
# Handle single device or other formats
|
||||
print(' - Found 1 device:')
|
||||
series = MultiDongle._get_device_series(device_descriptors)
|
||||
|
||||
if isinstance(device_descriptors, dict):
|
||||
port_id = device_descriptors.get('usb_port_id', device_descriptors.get('port_id', 0))
|
||||
else:
|
||||
port_id = getattr(device_descriptors, 'usb_port_id', getattr(device_descriptors, 'port_id', 0))
|
||||
|
||||
device_info = {
|
||||
'port_id': port_id,
|
||||
'series': series,
|
||||
'device_descriptor': device_descriptors
|
||||
}
|
||||
devices_info.append(device_info)
|
||||
|
||||
print(f' [1] Port ID: {port_id}, Series: {series}')
|
||||
|
||||
return devices_info
|
||||
|
||||
@ -120,16 +166,42 @@ class MultiDongle:
|
||||
@staticmethod
|
||||
def _get_device_series(device_descriptor):
|
||||
"""
|
||||
Extract device series from device descriptor.
|
||||
Extract device series from device descriptor using product_id.
|
||||
|
||||
Args:
|
||||
device_descriptor: Device descriptor from scan_devices()
|
||||
device_descriptor: Device descriptor from scan_devices() - can be dict or object
|
||||
|
||||
Returns:
|
||||
str: Device series (e.g., 'KL520', 'KL720', etc.)
|
||||
"""
|
||||
try:
|
||||
# Try to get the chip from device descriptor
|
||||
# Product ID to device series mapping
|
||||
product_id_mapping = {
|
||||
'0x100': 'KL520',
|
||||
'0x720': 'KL720',
|
||||
'0x630': 'KL630',
|
||||
'0x730': 'KL730',
|
||||
'0x540': 'KL540',
|
||||
# Add more mappings as needed
|
||||
}
|
||||
|
||||
# Handle dict format (from JSON)
|
||||
if isinstance(device_descriptor, dict):
|
||||
product_id = device_descriptor.get('product_id', '')
|
||||
if product_id in product_id_mapping:
|
||||
return product_id_mapping[product_id]
|
||||
return f'Unknown ({product_id})'
|
||||
|
||||
# Handle object format (from SDK)
|
||||
if hasattr(device_descriptor, 'product_id'):
|
||||
product_id = device_descriptor.product_id
|
||||
if isinstance(product_id, int):
|
||||
product_id = hex(product_id)
|
||||
if product_id in product_id_mapping:
|
||||
return product_id_mapping[product_id]
|
||||
return f'Unknown ({product_id})'
|
||||
|
||||
# Legacy chip-based detection (fallback)
|
||||
if hasattr(device_descriptor, 'chip'):
|
||||
chip = device_descriptor.chip
|
||||
if chip == kp.ModelNefDescriptor.KP_CHIP_KL520:
|
||||
@ -142,17 +214,8 @@ class MultiDongle:
|
||||
return 'KL730'
|
||||
elif chip == kp.ModelNefDescriptor.KP_CHIP_KL540:
|
||||
return 'KL540'
|
||||
elif chip == kp.ModelNefDescriptor.KP_CHIP_KL630_LEGACY:
|
||||
return 'KL630_LEGACY'
|
||||
elif chip == kp.ModelNefDescriptor.KP_CHIP_KL720_LEGACY:
|
||||
return 'KL720_LEGACY'
|
||||
elif chip == kp.ModelNefDescriptor.KP_CHIP_KL520_LEGACY:
|
||||
return 'KL520_LEGACY'
|
||||
|
||||
# Fallback: try to get from device descriptor attributes
|
||||
if hasattr(device_descriptor, 'product_name'):
|
||||
return device_descriptor.product_name
|
||||
|
||||
# Final fallback
|
||||
return 'Unknown'
|
||||
|
||||
except Exception as e:
|
||||
@ -195,7 +258,7 @@ class MultiDongle:
|
||||
except kp.ApiKPException as exception:
|
||||
raise Exception(f'Failed to connect devices: {str(exception)}')
|
||||
|
||||
def __init__(self, port_id: list = None, scpu_fw_path: str = None, ncpu_fw_path: str = None, model_path: str = None, upload_fw: bool = False, auto_detect: bool = False):
|
||||
def __init__(self, port_id: list = None, scpu_fw_path: str = None, ncpu_fw_path: str = None, model_path: str = None, upload_fw: bool = False, auto_detect: bool = False, max_queue_size: int = 0):
|
||||
"""
|
||||
Initialize the MultiDongle class.
|
||||
:param port_id: List of USB port IDs for the same layer's devices. If None and auto_detect=True, will auto-detect devices.
|
||||
@ -204,6 +267,7 @@ class MultiDongle:
|
||||
:param model_path: Path to the model file.
|
||||
:param upload_fw: Flag to indicate whether to upload firmware.
|
||||
:param auto_detect: Flag to auto-detect and connect to available devices.
|
||||
:param max_queue_size: Maximum size for internal queues. If 0, unlimited queues are used.
|
||||
"""
|
||||
self.auto_detect = auto_detect
|
||||
self.connected_devices_info = []
|
||||
@ -234,8 +298,11 @@ class MultiDongle:
|
||||
self.generic_inference_input_descriptor = None
|
||||
# Queues for data
|
||||
# Input queue for images to be sent
|
||||
if max_queue_size > 0:
|
||||
self._input_queue = queue.Queue(maxsize=max_queue_size)
|
||||
self._output_queue = queue.Queue(maxsize=max_queue_size)
|
||||
else:
|
||||
self._input_queue = queue.Queue()
|
||||
# Output queue for received results
|
||||
self._output_queue = queue.Queue()
|
||||
|
||||
# Threading attributes
|
||||
|
||||
@ -28,7 +28,9 @@ def example_device_scan():
|
||||
|
||||
print(f"Found {len(devices)} device(s):")
|
||||
for i, device in enumerate(devices):
|
||||
print(f" [{i+1}] Port ID: {device['port_id']}, Series: {device['series']}")
|
||||
desc = device['device_descriptor']
|
||||
product_id = desc.get('product_id', 'Unknown') if isinstance(desc, dict) else 'Unknown'
|
||||
print(f" [{i+1}] Port ID: {device['port_id']}, Series: {device['series']}, Product ID: {product_id}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error during device scan: {str(e)}")
|
||||
@ -47,7 +49,9 @@ def example_auto_connect():
|
||||
|
||||
print(f"Successfully connected to {len(connected_devices)} device(s):")
|
||||
for i, device in enumerate(connected_devices):
|
||||
print(f" [{i+1}] Port ID: {device['port_id']}, Series: {device['series']}")
|
||||
desc = device['device_descriptor']
|
||||
product_id = desc.get('product_id', 'Unknown') if isinstance(desc, dict) else 'Unknown'
|
||||
print(f" [{i+1}] Port ID: {device['port_id']}, Series: {device['series']}, Product ID: {product_id}")
|
||||
|
||||
# Disconnect devices
|
||||
import kp
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user