Skip to content

Conversation

@YumTaha
Copy link

@YumTaha YumTaha commented Jul 18, 2025

Fixes #1

🎯 Summary

This PR addresses critical bugs in the TUI (Text User Interface) application that prevent normal operation:

  1. TUI API compatibility issues - prevents TUI from launching
  2. TUI data structure compatibility - fixes firmware info display
  3. TUI error handling improvements - graceful shutdown and device communication
  4. TUI dependency management - automatic installation of required packages

📋 Related Issues

  • Resolves TUI AttributeError: DeviceTemplateManager has no attribute 'query_dtdl_model'
  • Addresses TUI firmware info display issues due to data structure changes
  • Improves TUI error handling for device communication timeouts
  • Fixes TUI dependency installation issues

🐛 Detailed Error Analysis and Fixes

TUI Errors Encountered

1. API Compatibility Error - DeviceTemplateManager

Error Type: AttributeError: type object 'DeviceTemplateManager' has no attribute 'query_dtdl_model'

Full Stack Trace:

File "stdatalog_TUI.py", line 152, in load_device_template
    dev_template_json = DeviceTemplateManager.query_dtdl_model(board_id, fw_id)
AttributeError: type object 'DeviceTemplateManager' has no attribute 'query_dtdl_model'

Root Cause: TUI was using wrong API class. The method exists on DeviceCatalogManager, not DeviceTemplateManager.

API Analysis:

# DeviceTemplateManager (wrong class) - Available methods:
['get_component', 'get_components', 'get_components_name_list', 'get_root_component']

# DeviceCatalogManager (correct class) - Available methods:
['query_dtdl_model', 'get_device_model', 'add_dtdl_model', 'update_catalog', ...]

Fix Applied:

# Before (AttributeError)
from stdatalog_pnpl.DTDL.device_template_manager import DeviceTemplateManager
dev_template_json = DeviceTemplateManager.query_dtdl_model(board_id, fw_id)

# After (works correctly)
from stdatalog_pnpl.DTDL.device_template_manager import DeviceTemplateManager, DeviceCatalogManager
dev_template_json = DeviceCatalogManager.query_dtdl_model(board_id, fw_id)

2. TUI Data Structure Compatibility Error

Error Type: AttributeError: 'dict' object has no attribute 'fw_info'

Root Cause: TUI expected firmware info as object attributes but SDK returns nested dictionary structure.

Data Structure Analysis:

# Expected by TUI (object attributes):
device.fw_info.alias
device.fw_info.part_number

# Actual SDK structure (nested dictionary):
{
    'firmware_info': {
        'alias': 'STWIN_BOX_001',
        'part_number': 'FP-SNS-DATALOG2',
        'fw_name': 'FP-SNS-DATALOG2_Datalog2',
        ...
    }
}

Specific Errors:

# tui_views.py - Line 225
AttributeError: 'dict' object has no attribute 'fw_info'
    at dev.fw_info.alias

# Multiple locations accessing firmware info
AttributeError: 'dict' object has no attribute 'alias'
    at self._hsd_info_model.selected_fw_info.alias

Fix Applied:

# Added module-level helper function
def get_fw_info_value(fw_info_dict, key, default_value="Unknown"):
    """
    Helper function to safely extract values from firmware info dictionary.
    """
    if fw_info_dict is None:
        return default_value
    
    # Handle nested structure
    if isinstance(fw_info_dict, dict) and 'firmware_info' in fw_info_dict:
        return fw_info_dict['firmware_info'].get(key, default_value)
    # Handle direct firmware_info dict
    elif isinstance(fw_info_dict, dict):
        return fw_info_dict.get(key, default_value)
    else:
        return default_value

# Before (AttributeError)
alias = dev.fw_info.alias
part_number = dev.fw_info.part_number

# After (safe dictionary access)
alias = get_fw_info_value(dev, 'alias')
part_number = get_fw_info_value(dev, 'part_number')

3. TUI Stop Logging Error

Error Type: stdatalog_core.HSD_utils.exceptions.EmptyCommandResponse: get_device_status

Full Stack Trace:

File "stdatalog_TUI.py", line 264, in stop_log
    HSDLink.save_json_device_file(self.hsd_link, self.selected_device_id, self.output_acquisition_path)
File "HSDLink_v2.py", line 401, in save_json_device_file
    res = self.get_device_status(d_id)
File "PnPLHSD_com_manager.py", line 156, in get_device_status
    raise EmptyCommandResponse("get_device_status")
EmptyCommandResponse: get_device_status

Root Cause: After stopping logging, device needs time to transition from logging to idle state before responding to status requests.

Fix Applied:

# Before (immediate failure)
HSDLink.stop_log(self.hsd_link, self.selected_device_id)
HSDLink.save_json_device_file(self.hsd_link, self.selected_device_id, self.output_acquisition_path)

# After (retry mechanism with delays)
HSDLink.stop_log(self.hsd_link, self.selected_device_id)
import time
for attempt in range(3):  # Try up to 3 times
    try:
        if attempt > 0:
            time.sleep(0.5)  # Wait 500ms between attempts
        HSDLink.save_json_device_file(self.hsd_link, self.selected_device_id, self.output_acquisition_path)
        break  # Success, exit the retry loop
    except Exception as e:
        if attempt == 2:  # Last attempt
            log.warning(f"Could not save device config JSON file after {attempt + 1} attempts: {e}")

4. TUI Quit Crash Error

Error Type: stdatalog_core.HSD_utils.exceptions.EmptyCommandResponse during shutdown

Full Stack Trace:

File "tui_views.py", line 454, in _update
    self._hsd_info_model.update_sensor_list()
File "stdatalog_TUI.py", line 199, in update_sensor_list
    self.sensor_list = HSDLink.get_sensor_list(self.hsd_link, self.selected_device_id, only_active=True)
EmptyCommandResponse: get_device_status

Root Cause: TUI framework continues calling update methods even after user clicks quit and HSD link is deleted.

Fix Applied:

# Added shutdown flag
is_shutting_down = False

# Updated update_sensor_list with shutdown check
def update_sensor_list(self):
    if self.is_shutting_down or self.selected_device_id is None:
        return
    try:
        self.sensor_list = HSDLink.get_sensor_list(self.hsd_link, self.selected_device_id, only_active=True)
    except Exception as e:
        log.warning(f"Could not update sensor list: {e}")

# Updated _stop_and_quit to set shutdown flag
def _stop_and_quit(self):
    self._hsd_info_model.is_shutting_down = True  # Prevent further updates
    # ... rest of cleanup

# Updated _update method to check shutdown flag
def _update(self, frame_no):
    if self._hsd_info_model.is_shutting_down:
        return  # Exit early if shutting down
    # ... rest of update logic

5. TUI Dependency Errors

Error Type: ImportError: No module named 'asciimatics' and ImportError: No module named 'win32api'

Root Cause: Missing TUI dependencies not installed by default SDK installation.

Fix Applied:

# Added automatic dependency installation
try:
    __import__("asciimatics")
except ImportError:
    log.info("Installing required asciimatics package...")
    subprocess.check_call([sys.executable, "-m", "pip", "install", "asciimatics"])

# Also resolved pywin32 post-install scripts issue
python -m pip install --force-reinstall pywin32
python Scripts/pywin32_postinstall.py -install

Summary of Error Categories

  • API Errors: 1 AttributeError from wrong class usage
  • Data Structure Errors: Multiple AttributeErrors from object vs dictionary access
  • Communication Errors: 2 EmptyCommandResponse timeouts
  • Dependency Errors: 2 ImportErrors from missing packages

🔧 Changes Made

TUI API Fixes (2 files)

  • stdatalog_TUI.py:

    • Fixed import to include DeviceCatalogManager
    • Updated load_device_template() to use correct API method
    • Added retry mechanism for device config JSON saving
    • Improved error handling for sensor list updates
    • Added shutdown flag for graceful exit
  • tui_views.py:

    • Added module-level helper function for firmware info access
    • Fixed data structure compatibility (attribute → dictionary access)
    • Updated device list display logic
    • Added shutdown checks to prevent crashes during quit

API Fix:

# Before (AttributeError)
dev_template_json = DeviceTemplateManager.query_dtdl_model(board_id, fw_id)

# After (works correctly)  
dev_template_json = DeviceCatalogManager.query_dtdl_model(board_id, fw_id)

Data Structure Fix:

# Before (assumes object attributes)
alias = dev.fw_info.alias

# After (handles dictionary structure)
alias = get_fw_info_value(dev, 'alias')

🧪 Testing

TUI Testing

  • ✅ TUI launches successfully without crashes
  • ✅ Device detection and connection working
  • ✅ Sensor data logging functional
  • ✅ Start/Stop/Quit operations work correctly
  • ✅ Device config JSON files saved properly
  • ✅ Firmware info displays correctly

System Testing

  • ✅ Python 3.13.5 compatibility confirmed
  • ✅ All dependencies (asciimatics, pywin32) working
  • ✅ Device communication stable
  • ✅ Data acquisition and file saving functional

🏗️ Architecture/Design

Error Handling Strategy

  • Defensive Programming: Added null/empty checks before file operations
  • Graceful Degradation: Applications continue working when optional operations fail
  • User Experience: Clear error messages and no unexpected crashes

API Compatibility

  • Correct Class Usage: Using DeviceCatalogManager for device template queries
  • Data Structure Adaptation: Supporting both object and dictionary access patterns
  • Backward Compatibility: Changes don't break existing functionality

Resource Management

  • Connection Cleanup: Proper HSD link disposal during shutdown
  • Thread Safety: Added shutdown flags to prevent race conditions
  • Memory Management: Proper file handle and resource cleanup

📖 Documentation

Code Comments

  • Added inline documentation for complex error handling logic
  • Documented API method selections and rationale
  • Explained data structure compatibility approaches

Error Messages

  • Improved logging for troubleshooting device communication issues
  • Added specific warnings for optional feature failures (UCF files, etc.)
  • Clear separation between critical errors and informational warnings

🔄 Backward Compatibility

  • ✅ All changes are backward compatible
  • ✅ No breaking changes to public APIs
  • ✅ Existing configurations and workflows preserved
  • ✅ Default behavior maintained for all operations

🎯 Impact Assessment

User Impact

  • TUI Users: TUI now functional (was completely broken)
  • Data Integrity: Complete data capture with device configs
  • Reliability: Much more stable operation overall

Developer Impact

  • Code Maintenance: Improved error handling patterns
  • Debugging: Better logging for troubleshooting
  • API Usage: Correct API methods documented and used

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Comments added for complex logic
  • Corresponding documentation updated
  • No new warnings generated
  • All tests pass (manual testing completed)
  • No breaking changes introduced
  • Error handling improved
  • Resource cleanup implemented

🔍 Files Changed

TUI Applications (2 files):
├── stdatalog_examples/gui_applications/stdatalog/TUI/stdatalog_TUI.py
└── stdatalog_examples/gui_applications/stdatalog/TUI/Views/tui_views.py

🚀 Before/After Comparison

Before

  • ❌ TUI completely non-functional (AttributeError on startup)
  • ❌ TUI crashes when stopping logging
  • ❌ TUI crashes when quitting application
  • ❌ Device config JSON files not saved properly
  • ❌ Missing dependencies prevent TUI launch

After

  • ✅ TUI launches and runs successfully
  • ✅ Complete data logging workflow functional
  • ✅ Graceful error handling throughout
  • ✅ All files saved correctly with retry mechanisms
  • ✅ Automatic dependency installation

Summary: This PR transforms the TUI application from completely broken to fully functional and robust, significantly improving user experience and data integrity while maintaining full backward compatibility.

YumTaha added 6 commits July 18, 2025 09:43
- Resolves AttributeError preventing TUI from launching
- Changes DeviceTemplateManager to DeviceCatalogManager for device template loading
- Adds proper import for DeviceCatalogManager
- Makes TUI fully functional for device data logging
- Add get_fw_info_value() helper for safe firmware info dictionary access
- Fix device list display to use dictionary keys instead of object attributes
- Add retry mechanism for device config JSON saving with 500ms delays
- Implement shutdown flag to prevent race conditions during quit
- Enhance sensor list updates with proper error handling
- Add validation checks before accessing file paths
- Prevents IndexError when users cancel file selection dialogs
- Affects 5 GUI widget components: HSDLogControlWidget, ComponentWidget, 
  DeviceTemplateLoadingWidget, CommandWidget, HSDPlotLinesWidget
- Maintains existing functionality while adding robustness
Updated the Readme.md file to correct all references from demo_gui.py to the actual filename stdatalog_data_segmentation_GUI.py. The changes include:
@YumTaha YumTaha closed this by deleting the head repository Jul 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TUI API Compatibility Issue - DeviceTemplateManager.query_dtdl_model() Not Found

1 participant