Skip to content

Implement motor test plugin#1016

Merged
amilcarlucas merged 1 commit into
masterfrom
motor_test_plugin
Nov 5, 2025
Merged

Implement motor test plugin#1016
amilcarlucas merged 1 commit into
masterfrom
motor_test_plugin

Conversation

@amilcarlucas

Copy link
Copy Markdown
Collaborator

Adds tests

Copilot AI review requested due to automatic review settings November 3, 2025 20:09
@github-actions

github-actions Bot commented Nov 3, 2025

Copy link
Copy Markdown
Contributor

☂️ Python Coverage

current status: ✅

Overall Coverage

Lines Covered Coverage Threshold Status
9113 7597 83% 80% 🟢

New Files

File Coverage Status
ardupilot_methodic_configurator/plugin_constants.py 100% 🟢
ardupilot_methodic_configurator/plugin_factory.py 60% 🟢
ardupilot_methodic_configurator/plugin_protocol.py 100% 🟢
TOTAL 87% 🟢

Modified Files

File Coverage Status
ardupilot_methodic_configurator/main.py 76% 🟢
ardupilot_methodic_configurator/backend_filesystem_configuration_steps.py 90% 🟢
ardupilot_methodic_configurator/configuration_manager.py 77% 🟢
ardupilot_methodic_configurator/frontend_tkinter_parameter_editor.py 68% 🟢
TOTAL 78% 🟢

updated for commit: 5b9d1c6 by action🐍

@github-actions

github-actions Bot commented Nov 3, 2025

Copy link
Copy Markdown
Contributor

Test Results

    3 files  ± 0      3 suites  ±0   2m 45s ⏱️ -4s
2 029 tests +21  2 027 ✅ +21  2 💤 ±0  0 ❌ ±0 
6 087 runs  +63  6 081 ✅ +63  6 💤 ±0  0 ❌ ±0 

Results for commit 5b9d1c6. ± Comparison against base commit f9fed24.

♻️ This comment has been updated with latest results.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds a plugin architecture to the parameter editor, enabling step-specific UI extensions to be displayed alongside the parameter table. The first plugin implementation is a motor test UI that appears during the motor configuration step.

Key changes:

  • Introduced a plugin configuration schema allowing steps to declare UI plugins with placement options (left/top)
  • Implemented dynamic layout switching to accommodate plugins alongside the parameter table
  • Added motor test plugin integration for the "15_motor.param" configuration step

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
configuration_steps_schema.json Added plugin schema definition with name and placement properties
configuration_steps_ArduCopter.json Configured motor_test plugin for the motor configuration step
backend_filesystem_configuration_steps.py Added get_plugin() method to retrieve plugin configuration for a file
configuration_manager.py Added plugin API methods: get_plugin() and create_plugin_data_model()
frontend_tkinter_parameter_editor.py Implemented dynamic layout switching and plugin loading logic
test_configuration_manager.py Added tests for create_plugin_data_model() with various scenarios
test_frontend_tkinter_parameter_editor.py Added tests for __load_plugin() method covering success and error cases

)

def __update_plugin_layout(self, plugin: Optional[dict]) -> None:
"""Update the plugin layout based on the current plugin."""

Copilot AI Nov 3, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The __update_plugin_layout method lacks a docstring explaining its parameters, return value, and behavior. Add a docstring describing the plugin parameter (dict with 'name' and 'placement' keys or None) and explaining that it recreates the layout when the plugin changes.

Suggested change
"""Update the plugin layout based on the current plugin."""
"""
Update the plugin layout based on the current plugin.
This method destroys and recreates the parameter area container and its contents
depending on the provided plugin configuration.
Parameters:
plugin (Optional[dict]): Either None, or a dictionary with at least the keys
'name' (str) and 'placement' (str, either 'left' or 'top'). If None, no plugin
is loaded and the default layout is used.
Returns:
None
Side Effects:
Destroys and recreates the parameter area container and its child widgets.
Recreates the parameter table in the new layout.
"""

Copilot uses AI. Check for mistakes.
Comment on lines +494 to +495
self.parameter_editor_table = ParameterEditorTable(self.parameter_container, self.configuration_manager, self)
self.parameter_editor_table.pack(side="top", fill="both", expand=True)

Copilot AI Nov 3, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter table is recreated every time the plugin layout changes. This may cause issues if the table holds any state (like scroll position or user selections). Consider whether the table state needs to be preserved and restored, or document that state is intentionally reset.

Copilot uses AI. Check for mistakes.
ttk.Label(parent_frame, text="Motor test requires flight controller connection").pack()
return

MotorTestView(parent_frame, model, self) # type: ignore[arg-type]

Copilot AI Nov 3, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type: ignore[arg-type] comment suggests a type mismatch. The issue is that ParameterEditorWindow is passed where BaseWindow is expected. Since ParameterEditorWindow inherits from BaseWindow, this should type-check correctly. Verify that the type hint on MotorTestView.__init__ is correct and remove the type ignore comment if possible.

Suggested change
MotorTestView(parent_frame, model, self) # type: ignore[arg-type]
MotorTestView(parent_frame, model, self)

Copilot uses AI. Check for mistakes.
def get_plugin(self, filename: str) -> Optional[dict]:
return self._local_filesystem.get_plugin(filename)

def create_plugin_data_model(self, plugin_name: str) -> Optional[object]:

Copilot AI Nov 3, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return type Optional[object] is too generic and provides no type safety for callers. Consider using a Union type of specific model classes (e.g., Optional[MotorTestDataModel]) or defining a base class/protocol for plugin data models.

Copilot uses AI. Check for mistakes.
def get_plugin(self, filename: str) -> Optional[dict]:
return self._local_filesystem.get_plugin(filename)

def create_plugin_data_model(self, plugin_name: str) -> Optional[object]:

Copilot AI Nov 3, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The plugin_name parameter should be validated. Consider adding type checking or documentation about what happens when plugin_name is None or an empty string, since the tests check these cases but the implementation may not handle them explicitly.

Copilot uses AI. Check for mistakes.
@amilcarlucas amilcarlucas force-pushed the motor_test_plugin branch 4 times, most recently from fd8ea91 to 57309f5 Compare November 5, 2025 19:56
@amilcarlucas amilcarlucas requested a review from Copilot November 5, 2025 19:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Uses dependency injection via plugin factory to avoid circular dependencies
Adds tests
@amilcarlucas amilcarlucas merged commit e29f848 into master Nov 5, 2025
32 checks passed
@amilcarlucas amilcarlucas deleted the motor_test_plugin branch November 5, 2025 21:37
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.

2 participants