diff --git a/MethodicConfigurator/backend_filesystem.py b/MethodicConfigurator/backend_filesystem.py index 3a9e086..e806a76 100644 --- a/MethodicConfigurator/backend_filesystem.py +++ b/MethodicConfigurator/backend_filesystem.py @@ -13,6 +13,7 @@ from os import listdir as os_listdir from os import makedirs as os_makedirs from os import rename as os_rename +from os import walk as os_walk from os import sep as os_sep from shutil import copy2 as shutil_copy2 @@ -53,6 +54,7 @@ from backend_filesystem_vehicle_components import VehicleComponents from backend_filesystem_configuration_steps import ConfigurationSteps +from middleware_template_overview import TemplateOverview TOOLTIP_MAX_LENGTH = 105 @@ -663,6 +665,30 @@ def supported_vehicles(): return ['AP_Periph', 'AntennaTracker', 'ArduCopter', 'ArduPlane', 'ArduSub', 'Blimp', 'Heli', 'Rover', 'SITL'] + @staticmethod + def find_vehicle_components_dirs(base_dir="vehicle_templates"): + """ + Finds all subdirectories of base_dir containing a "vehicle_components.json" file, + creates a dictionary where the keys are the subdirectory names (relative to base_dir) + and the values are instances of VehicleComponents. + + :param base_dir: The base directory to start searching from. + :return: A dictionary mapping subdirectory paths to VehicleComponents instances. + """ + vehicle_components_dict = {} + file_to_find = VehicleComponents().vehicle_components_json_filename + for root, _dirs, files in os_walk(base_dir): + if file_to_find in files: + relative_path = os_path.relpath(root, base_dir) + vehicle_components = VehicleComponents() + comp_data = vehicle_components.load_vehicle_components_json_data(root) + if comp_data: + comp_data = comp_data.get('Components', {}) + vehicle_components_overview = TemplateOverview() + vehicle_components_dict[relative_path] = \ + vehicle_components_overview.load_vehicle_components(comp_data) + return vehicle_components_dict + @staticmethod def add_argparse_arguments(parser): parser.add_argument('-t', '--vehicle-type', diff --git a/MethodicConfigurator/frontend_tkinter_template_overview_window.py b/MethodicConfigurator/frontend_tkinter_template_overview_window.py new file mode 100644 index 0000000..2dfde50 --- /dev/null +++ b/MethodicConfigurator/frontend_tkinter_template_overview_window.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 + +''' +This file is part of Ardupilot methodic configurator. https://github.com/ArduPilot/MethodicConfigurator + +(C) 2024 Amilcar do Carmo Lucas + +SPDX-License-Identifier: GPL-3 +''' + +import tkinter as tk +from tkinter import ttk + +from middleware_template_overview import TemplateOverview + +class TemplateOverviewWindow: + def __init__(self): + self.window = tk.Tk() + self.window.title("ArduPilot methodic configurator - Template Overview") + self.window.geometry("600x400") + + self.template_overview = TemplateOverview() + + # Define the columns for the Treeview + columns = ("FC Manufacturer", "FC Model", "TOW Min [KG]", "TOW Max [KG]", "RC Protocol", "Telemetry Model", "ESC Protocol", "Prop Diameter [inches]", "GNSS Model") + self.tree = ttk.Treeview(self.window, columns=columns, show='headings') + for col in columns: + self.tree.heading(col, text=col) + + # Populate the Treeview with data from the template overview + for item in self.template_overview.__dict__.values(): + self.tree.insert('', 'end', values=(item)) + + self.tree.pack(fill=tk.BOTH, expand=True) + + self.window.mainloop() + +if __name__ == "__main__": + app = TemplateOverviewWindow() diff --git a/MethodicConfigurator/middleware_template_overview.py b/MethodicConfigurator/middleware_template_overview.py new file mode 100644 index 0000000..7faee14 --- /dev/null +++ b/MethodicConfigurator/middleware_template_overview.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 + +''' +This file is part of Ardupilot methodic configurator. https://github.com/ArduPilot/MethodicConfigurator + +(C) 2024 Amilcar do Carmo Lucas + +SPDX-License-Identifier: GPL-3 +''' + +class TemplateOverview: + def __init__(self): + self.fc_manufacturer = None + self.fc_model = None + self.tow_min_kg = None + self.tow_max_kg = None + self.rc_protocol = None + self.telemetry_model = None + self.esc_protocol = None + self.prop_diameter_inches = None + self.gnss_model = None + + def load_template_overview(self, components_data: dict): + self.fc_manufacturer = components_data.get('Flight Controller', {}).get('Product', {}).get('Manufacturer') + self.fc_model = components_data.get('Flight Controller', {}).get('Product', {}).get('Model') + self.tow_min_kg = components_data.get('Frame', {}).get('Product', {}).get('tow_min_kg') + self.tow_max_kg = components_data.get('Frame', {}).get('Product', {}).get('tow_max_kg') + self.rc_protocol = components_data.get('RC Receiver', {}).get('Product', {}).get('Model') + self.telemetry_model = components_data.get('Telemetry', {}).get('Product', {}).get('Model') + self.esc_protocol = components_data.get('Battery Monitor', {}).get('Product', {}).get('Manufacturer') + self.prop_diameter_inches = components_data.get('Battery Monitor', {}).get('Product', {}).get('Model') + self.gnss_model = components_data.get('Battery', {}).get('Specifications', {}).get('Model')