diff --git a/MethodicConfigurator/annotate_params.py b/MethodicConfigurator/annotate_params.py
index 31a8144..862e6fc 100755
--- a/MethodicConfigurator/annotate_params.py
+++ b/MethodicConfigurator/annotate_params.py
@@ -209,6 +209,7 @@ def format_params(param_dict: Dict[str, 'Par'], file_format: str = "missionplann
Parameters:
param_dict (Dict[str, 'Par']): A dictionary of 'Par' objects.
Each key is a parameter name and each value is a 'Par' object.
+ Par can be a simple float or a Par object with a comment.
file_format (str): Can be "missionplanner" or "mavproxy"
Returns:
@@ -303,7 +304,7 @@ def print_out(formatted_params: List[str], name: str) -> None:
print(line)
-def get_xml_data(base_url: str, directory: str, filename: str) -> ET.Element:
+def get_xml_data(base_url: str, directory: str, filename: str, vehicle_type: str) -> ET.Element:
"""
Fetches XML data from a local file or a URL.
@@ -311,6 +312,7 @@ def get_xml_data(base_url: str, directory: str, filename: str) -> ET.Element:
base_url (str): The base URL for fetching the XML file.
directory (str): The directory where the XML file is expected.
filename (str): The name of the XML file.
+ vehicle_type (str): The type of the vehicle.
Returns:
ET.Element: The root element of the parsed XML data.
@@ -336,13 +338,24 @@ def get_xml_data(base_url: str, directory: str, filename: str) -> ET.Element:
raise SystemExit("requests package is not installed") from exc
try:
# Send a GET request to the URL
- response = requests_get(base_url + filename, timeout=5)
+ url = base_url + filename
+ response = requests_get(url, timeout=5)
if response.status_code != 200:
- logging.critical("Remote URL: %s", base_url + filename)
+ logging.warning("Remote URL: %s", url)
raise requests_exceptions.RequestException(f"HTTP status code {response.status_code}")
except requests_exceptions.RequestException as e:
- logging.critical("Unable to fetch XML data: %s", e)
- raise SystemExit("unable to fetch online XML documentation") from e
+ logging.warning("Unable to fetch XML data: %s", e)
+ # Send a GET request to the URL to the fallback (DEV) URL
+ try:
+ url = BASE_URL + vehicle_type + '/' + PARAM_DEFINITION_XML_FILE
+ logging.warning("Falling back to the DEV XML file: %s", url)
+ response = requests_get(url, timeout=5)
+ if response.status_code != 200:
+ logging.critical("Remote URL: %s", url)
+ raise requests_exceptions.RequestException(f"HTTP status code {response.status_code}")
+ except requests_exceptions.RequestException as exp:
+ logging.critical("Unable to fetch XML data: %s", exp)
+ raise SystemExit("unable to fetch online XML documentation") from exp
# Get the text content of the response
xml_data = response.text
try:
@@ -695,7 +708,7 @@ def get_xml_url(vehicle_type: str, firmware_version: str) -> str:
def parse_parameter_metadata(xml_url: str, xml_dir: str, xml_file: str,
vehicle_type: str, max_line_length: int) -> Dict[str, Any]:
- xml_root = get_xml_data(xml_url, xml_dir, xml_file)
+ xml_root = get_xml_data(xml_url, xml_dir, xml_file, vehicle_type)
return create_doc_dict(xml_root, vehicle_type, max_line_length)
diff --git a/MethodicConfigurator/backend_flightcontroller.py b/MethodicConfigurator/backend_flightcontroller.py
index 7aae7d8..2b0b6d9 100644
--- a/MethodicConfigurator/backend_flightcontroller.py
+++ b/MethodicConfigurator/backend_flightcontroller.py
@@ -316,9 +316,9 @@ def __process_autopilot_version(self, m, banner_msgs) -> str:
# the banner message after the ChibiOS one contains the FC type
fc_product = ''
if os_custom_version_index is not None:
- fc_type_msgs = banner_msgs[os_custom_version_index+1].split(' ')
- if len(fc_type_msgs) >= 3:
- fc_product = fc_type_msgs[0]
+ fc_product_banner_substrings = banner_msgs[os_custom_version_index+1].split(' ')
+ if len(fc_product_banner_substrings) >= 3:
+ fc_product = fc_product_banner_substrings[0]
if fc_product != self.info.product:
logging_warning("FC product mismatch: %s (BANNER)!= %s(AUTOPILOT_VERSION)", fc_product, self.info.product)
self.info.product = fc_product # force the one from the banner because it is more reliable
diff --git a/unittests/annotate_params_test.py b/unittests/annotate_params_test.py
index 263d8a0..0b9e9b1 100755
--- a/unittests/annotate_params_test.py
+++ b/unittests/annotate_params_test.py
@@ -76,7 +76,7 @@ def test_get_xml_data_local_file(self, mock_load_param, mock_isfile, mock_open):
mock_load_param.side_effect = FileNotFoundError
# Call the function with a local file
- result = get_xml_data("/path/to/local/file/", ".", "test.xml")
+ result = get_xml_data("/path/to/local/file/", ".", "test.xml", "ArduCopter")
# Check the result
self.assertIsInstance(result, ET.Element)
@@ -97,7 +97,7 @@ def test_get_xml_data_remote_file(self, mock_get):
pass
# Call the function with a remote file
- result = get_xml_data("http://example.com/", ".", "test.xml")
+ result = get_xml_data("http://example.com/", ".", "test.xml", "ArduCopter")
# Check the result
self.assertIsInstance(result, ET.Element)
@@ -120,7 +120,7 @@ def side_effect(filename):
mock_open = mock.mock_open(read_data='')
with patch('builtins.open', mock_open):
# Call the function with a filename that exists in the script directory
- result = get_xml_data(BASE_URL, ".", PARAM_DEFINITION_XML_FILE)
+ result = get_xml_data(BASE_URL, ".", PARAM_DEFINITION_XML_FILE, "ArduCopter")
# Check the result
self.assertIsInstance(result, ET.Element)
@@ -140,7 +140,7 @@ def test_get_xml_data_no_requests_package(self):
# Call the function with a remote file
with self.assertRaises(SystemExit):
- get_xml_data("http://example.com/", ".", "test.xml")
+ get_xml_data("http://example.com/", ".", "test.xml", "ArduCopter")
@patch('requests.get')
def test_get_xml_data_request_failure(self, mock_get):
@@ -155,7 +155,7 @@ def test_get_xml_data_request_failure(self, mock_get):
# Call the function with a remote file
with self.assertRaises(SystemExit):
- get_xml_data("http://example.com/", ".", "test.xml")
+ get_xml_data("http://example.com/", ".", "test.xml", "ArduCopter")
@patch('requests.get')
def test_get_xml_data_valid_xml(self, mock_get):
@@ -164,7 +164,7 @@ def test_get_xml_data_valid_xml(self, mock_get):
mock_get.return_value.text = ""
# Call the function with a remote file
- result = get_xml_data("http://example.com/", ".", "test.xml")
+ result = get_xml_data("http://example.com/", ".", "test.xml", "ArduCopter")
# Check the result
self.assertIsInstance(result, ET.Element)
@@ -183,7 +183,7 @@ def test_get_xml_data_invalid_xml(self, mock_get):
# Call the function with a remote file
with self.assertRaises(ET.ParseError):
- get_xml_data("http://example.com/", ".", "test.xml")
+ get_xml_data("http://example.com/", ".", "test.xml", "ArduCopter")
@patch('requests.get')
@patch('os.path.isfile')
@@ -201,7 +201,7 @@ def test_get_xml_data_missing_file(self, mock_isfile, mock_get):
# Call the function with a local file
with self.assertRaises(FileNotFoundError):
- get_xml_data("/path/to/local/file/", ".", "test.xml")
+ get_xml_data("/path/to/local/file/", ".", "test.xml", "ArduCopter")
@patch('requests.get')
def test_get_xml_data_network_issue(self, mock_get):
@@ -210,7 +210,7 @@ def test_get_xml_data_network_issue(self, mock_get):
# Call the function with a remote file
with self.assertRaises(SystemExit):
- get_xml_data("http://example.com/", ".", "test.xml")
+ get_xml_data("http://example.com/", ".", "test.xml", "ArduCopter")
def test_remove_prefix(self):
# Test case 1: Normal operation