{% include 'menu.html' %}

{{ title }}


{% macro kb_link(doc) -%} {% if doc %} {% if doc is string %} 📚 KB {% elif doc is iterable %} {% for url in doc %} 📚 KB {% endfor %} {% endif %} {% endif %} {%- endmacro %} {% set non_cert_text = "NOT READY FOR CERTIFICATION" %} {% set unsterile_run_warning = "Unsterile run mode is set - a certifying run must be sterile." %}
1
Flavor
2
Schema
3
Modules
4
Tests
5
Review
{% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, message in messages %} {% endfor %} {% endif %} {% endwith %} {% if error %} {% endif %} {% if warning %} {% endif %}
{% if step_num == 1 %}

Step 1: Select Certification Flavor

Choose the type of certification you want to run.

Mandatory Module: Cloud Connectivity
Tests gateway's BLE scans & MQTT data uploads capabilities.

Mandatory Module: Edge Management
Requires at least one additional module beyond the mandatory Edge Management module.

Mandatory Modules: Cloud Connectivity + Edge Management
Requires at least one additional bridge module beyond the mandatory Edge Management module.
Tests both gateway and bridge capabilities.

Gateway Registration Test Optional

Run the standalone registration and token-refresh test for Gateway Only or Combo devices.

Open Registration Test
{% elif step_num == 2 %}

Step 2: Upload Validation Schema

Upload the JSON validation schema file for your device. 📚 KB

Select a JSON validation schema file that matches your selected flavor.
{% if flavor == 'bridge_only' or flavor == 'combo' %}
{% set api_version_field_name = cert_schema.title ~ '_api_version' %} {% set api_version_field = cert_schema.fields | selectattr('name', 'equalto', 'api_version') | first %} {% set api_version_value = form_data.get(api_version_field_name, api_version_field.default if api_version_field and api_version_field.default is not none else '') %}
Bridge API version (required for bridge and combo flavors).
{% endif %} {% if schema_path %}
Schema uploaded: {{ schema_path.split('/')[-1] }}
{% endif %} {% elif step_num == 3 %}

Step 3: Select Modules

Select the modules you want to test. Mandatory modules are pre-selected.

{% if flavor == 'bridge_only' %}
Note: Bridge only requires at least one additional module beyond the mandatory Edge Management module.
{% elif flavor == 'combo' %}
Note: Combo requires at least one additional bridge module beyond the mandatory Edge Management module.
{% endif %} {% for mod in filtered_modules %} {% set is_mandatory = mod.is_mandatory | default(False) %} {% set is_selected = mod.name in selected_modules %} {% set has_selections = selected_modules|length > 0 %} {% set mod_doc = None %} {% if mod.tests and mod.tests|length > 0 %} {% for test in mod.tests %} {% if test.meta.documentation and not mod_doc %} {% set mod_doc = test.meta.documentation %} {% endif %} {% endfor %} {% endif %}

{{ mod.tests|length }} test(s) available

{% endfor %} {% elif step_num == 4 %}

Step 4: Select Tests

Select the specific tests to run. Mandatory tests are pre-selected and cannot be deselected.

{% for mod in filtered_modules %} {% if mod.name in selected_modules %} {% set mod_id = 'mod_' ~ mod.name|replace('/', '_') %}
{{ mod.name }} ({{ mod.tests|length }} tests)
{% for t in mod.tests %} {% set test_id = 'test_' ~ t.id|replace('/','_') %} {% set is_mandatory = t.meta.mandatory | default(0) == 1 %} {% set is_selected = t.id in selected_tests %} {% set tip_id = 'tip_' ~ t.id|replace('/','_') %} {% set test_doc = t.meta.documentation %}
{% if t.tooltip %}
{{ t.tooltip }}
{% endif %}
{# Test parameters #} {% set params_list = t.meta.allSupportedValues | default([]) %} {% if params_list %} {% set has_dynamic = "dynamic_parameters" in params_list %} {% if has_dynamic %} {# Use params_list[1] as default if it exists, otherwise "1" #} {% if params_list|length > 1 %} {% set default_value = params_list[1] %} {% else %} {% set default_value = "1" %} {% endif %} {# Check if value exists in form_data (for restoring saved values) #} {% set dynamic_param_name = "params_" ~ t.id|replace('/','_') ~ "_dynamic" %} {% set saved_value = form_data.get(dynamic_param_name, default_value) %} {% endif %}
{% if has_dynamic %}
Dynamic Parameter
{# Dynamic parameter: integer input #}
{% else %}
Parameters
{# Regular parameters: checkboxes #}
{% for p in params_list %} {% set pid = test_id ~ '_p_' ~ loop.index %}
{% endfor %}
{% endif %}
{% endif %}
{% endfor %}
{% endif %} {% endfor %} {% set cert_schema = cert_schema %}

Run Parameters

{% set common_parameters = ['dut', 'gw_api_version', 'custom_broker', 'max_output_power', 'single_polarization_antenna'] %} {% if flavor in ['gw_only', 'combo'] %} {% set primary_parameters = ['dut', 'gw_api_version', 'max_output_power', 'single_polarization_antenna'] %} {% else %} {% set primary_parameters = ['dut', 'max_output_power', 'single_polarization_antenna'] %} {% endif %} {% for param_name in primary_parameters %} {% for f in cert_schema.fields %} {% if f.name != 'validation_schema' and f.name != 'tl' and f.name != 'custom_broker' and f.name == param_name %} {% set is_signal_indicator_field = f.name == 'max_output_power' or f.name == 'single_polarization_antenna' %} {% set arg_label = (f.option_strings|join(', ') if f.option_strings else f.name) %} {% set tip_id = 'help_' ~ f.name %} {% set field_name = cert_schema.title ~ '_' ~ f.name %} {% if f.is_flag %} {# For flags, check if explicitly set in form_data #} {# Empty string means unchecked, "on" means checked, None means use default #} {% set field_value = form_data.get(field_name) %} {% if field_value is none %} {# Not in form_data, use default #} {% set field_value = f.default if f.default is not none else True %} {% else %} {# In form_data: "on" or truthy = checked, empty string = unchecked #} {% set field_value = field_value if field_value else False %} {% endif %} {% else %} {% set field_value = form_data.get(field_name, f.default if f.default is not none else '') %} {% endif %} {% endif %} {% endfor %} {% endfor %} {% set cert_schema = cert_schema %} {% set broker_field_prefix = cert_schema.title ~ '_custom_broker_' %}
Custom MQTT Broker Configuration *
{% for field_key, field_default in custom_broker_defaults.items() %} {% set field_name = broker_field_prefix ~ field_key %} {% set field_value = form_data.get(field_name, field_default) %} {% set input_type = 'number' if field_key == 'port' else 'password' if field_key == 'password' else 'text' %} {% set is_required = field_key not in ['username', 'password'] %}
{% if field_key in custom_broker_help.keys() %}
{{ custom_broker_help[field_key] }}
{% endif %}
{% endfor %}
Advanced Parameters
{% for f in cert_schema.fields %} {% if f.name != 'validation_schema' and f.name != 'tl' and f.name != 'api_version' and f.name not in common_parameters %} {% set arg_label = (f.option_strings|join(', ') if f.option_strings else f.name) %} {% set tip_id = 'help_' ~ f.name %} {% set field_name = cert_schema.title ~ '_' ~ f.name %} {% set field_value = form_data.get(field_name, f.default if f.default is not none else '') %}
{% if f.widget == "select" %}
{% elif f.is_flag %}
{% elif f.name == "port" %}
{% else %}
{% endif %} {% if f.help or f.help_link %}
{{ f.help }} {% if f.help_link %} Knowledge Base {% endif %}
{% endif %}
{% endif %} {% endfor %}
{% elif step_num == 5 %}

Step 5: Review and Run

Configuration Summary

Flavor: {% if flavor == 'gw_only' %}Gateway Only {% elif flavor == 'bridge_only' %}Bridge Only {% elif flavor == 'combo' %}Combo (Gateway + Bridge) {% endif %}

Validation Schema: {{ schema_path.split('/')[-1] if schema_path else 'Not uploaded' }}

Selected Modules: {{ selected_modules|join(', ') }}

Selected Tests: {{ total_test_count }} test(s)

Certification Status: {% if is_certified %} READY FOR CERTIFICATION All mandatory modules and tests are selected {% else %} {{ non_cert_text }} {% if not unsterile_run %} Some mandatory modules or tests are missing {% endif %} {% endif %}

{% if unsterile_run %}
⚠️ Warning: {{ unsterile_run_warning }}
{% endif %} {% if not is_certified %} {% if missing_modules %}
Missing Mandatory Modules:
    {% for mod in missing_modules %}
  • {{ mod }}
  • {% endfor %}
{% endif %} {% if missing_additional_module %}
Missing Additional Module:
    {% if flavor == 'bridge_only' %}
  • Bridge Only requires at least one additional module beyond the mandatory module (edge_mgmt)
  • {% elif flavor == 'combo' %}
  • Combo requires at least one additional bridge module beyond the mandatory modules (cloud_connectivity and edge_mgmt)
  • {% endif %}
{% endif %} {% if missing_tests_details %}
Missing Mandatory Tests from Selected Modules:
    {% for test in missing_tests_details %}
  • {{ test.label }} ({{ test.module }})
  • {% endfor %}
When a module is selected, its mandatory tests must also be selected.
{% endif %} {% endif %}
Schema Verification
{% if schema_errors or schema_warnings or missing_modules_by_schema %}

Schema Status: SCHEMA DOES NOT MATCH RUN SETTINGS

{% if schema_errors %}
Errors:
    {% for err in schema_errors %}
  • {{ err }}
  • {% endfor %}
{% endif %} {% if schema_warnings %}
Warnings:
    {% for warn in schema_warnings %}
  • {{ warn }}
  • {% endfor %}
{% endif %} {% if missing_modules_by_schema %}
Missing Modules Mandatory by Schema:
    {% for mod in missing_modules_by_schema %}
  • {{ mod }}
  • {% endfor %}
These modules are declared in your validation schema but are not selected. They should be included for proper certification.
{% endif %} {% else %}

Schema Status: SCHEMA MATCHES RUN SETTINGS The uploaded schema matches the selected flavor, modules, and tests

{% endif %}

Need to make changes?

Edit Flavor Edit Schema {% if flavor != 'gw_only' %} Edit Modules {% endif %} Edit Tests
{% endif %}
{% if step_num > 1 %} {% else %}
{% endif %} {% if step_num < 5 %} {% else %}
{% endif %}
{% if step_num == 1 %}

OR Use Previous Run Settings...

Load Previous Run Settings
Select a previously exported certificate run settings file.
{% endif %}