wiliot-certificate 4.5.0__py3-none-any.whl → 4.5.0a2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. certificate/ag/wlt_types_ag_jsons/brg2brg_ota.json +211 -0
  2. certificate/ag/wlt_types_ag_jsons/brg2gw_hb.json +894 -0
  3. certificate/ag/wlt_types_ag_jsons/brg2gw_hb_sleep.json +184 -0
  4. certificate/ag/wlt_types_ag_jsons/calibration.json +490 -0
  5. certificate/ag/wlt_types_ag_jsons/custom.json +614 -0
  6. certificate/ag/wlt_types_ag_jsons/datapath.json +900 -0
  7. certificate/ag/wlt_types_ag_jsons/energy2400.json +670 -0
  8. certificate/ag/wlt_types_ag_jsons/energySub1g.json +691 -0
  9. certificate/ag/wlt_types_ag_jsons/externalSensor.json +727 -0
  10. certificate/ag/wlt_types_ag_jsons/interface.json +1095 -0
  11. certificate/ag/wlt_types_ag_jsons/powerManagement.json +1439 -0
  12. certificate/ag/wlt_types_ag_jsons/side_info_sensor.json +105 -0
  13. certificate/ag/wlt_types_ag_jsons/signal_indicator_data.json +77 -0
  14. certificate/ag/wlt_types_ag_jsons/unified_echo_ext_pkt.json +126 -0
  15. certificate/ag/wlt_types_ag_jsons/unified_echo_pkt.json +175 -0
  16. certificate/ag/wlt_types_ag_jsons/unified_sensor_pkt.json +65 -0
  17. certificate/cert_common.py +35 -65
  18. certificate/cert_config.py +18 -43
  19. certificate/cert_data_sim.py +9 -12
  20. certificate/cert_defines.py +0 -8
  21. certificate/cert_gw_sim.py +7 -32
  22. certificate/cert_mqtt.py +5 -15
  23. certificate/cert_prints.py +0 -1
  24. certificate/cert_results.py +37 -48
  25. certificate/cert_utils.py +15 -24
  26. certificate/certificate.py +5 -12
  27. certificate/certificate_cli.py +13 -10
  28. certificate/certificate_eth_test_list.txt +3 -4
  29. certificate/certificate_sanity_test_list.txt +2 -3
  30. certificate/certificate_test_list.txt +4 -4
  31. certificate/tests/calibration/interval_test/interval_test.json +0 -1
  32. certificate/tests/calibration/output_power_test/output_power_test.json +0 -1
  33. certificate/tests/calibration/pattern_test/pattern_test.json +0 -1
  34. certificate/tests/cloud_connectivity/acl_ext_adv_test/acl_ext_adv_test.json +0 -1
  35. certificate/tests/cloud_connectivity/acl_test/acl_test.json +0 -1
  36. certificate/tests/cloud_connectivity/acl_test/acl_test.py +15 -13
  37. certificate/tests/cloud_connectivity/brg_ota_test/brg_ota_test.json +1 -2
  38. certificate/tests/cloud_connectivity/brg_ota_test/brg_ota_test.py +6 -8
  39. certificate/tests/cloud_connectivity/channel_scan_behaviour_test/channel_scan_behaviour_test.json +0 -1
  40. certificate/tests/cloud_connectivity/channel_scan_behaviour_test/channel_scan_behaviour_test.py +3 -3
  41. certificate/tests/cloud_connectivity/connection_test/connection_test.json +0 -1
  42. certificate/tests/cloud_connectivity/connection_test/connection_test.py +13 -6
  43. certificate/tests/cloud_connectivity/deduplication_test/deduplication_test.json +0 -1
  44. certificate/tests/cloud_connectivity/deduplication_test/deduplication_test.py +11 -6
  45. certificate/tests/cloud_connectivity/downlink_test/downlink_test.json +0 -1
  46. certificate/tests/cloud_connectivity/downlink_test/downlink_test.py +4 -1
  47. certificate/tests/cloud_connectivity/ext_adv_stress_test/ext_adv_stress_test.json +0 -1
  48. certificate/tests/cloud_connectivity/ext_adv_stress_test/ext_adv_stress_test.py +9 -14
  49. certificate/tests/cloud_connectivity/reboot_test/reboot_test.json +0 -1
  50. certificate/tests/cloud_connectivity/reboot_test/reboot_test.py +0 -2
  51. certificate/tests/cloud_connectivity/registration_test/registration_test.json +0 -1
  52. certificate/tests/cloud_connectivity/registration_test/registration_test_cli.py +1 -1
  53. certificate/tests/cloud_connectivity/stress_test/stress_test.json +0 -1
  54. certificate/tests/cloud_connectivity/stress_test/stress_test.py +11 -15
  55. certificate/tests/cloud_connectivity/uplink_ext_adv_test/uplink_ext_adv_test.json +0 -1
  56. certificate/tests/cloud_connectivity/uplink_ext_adv_test/uplink_ext_adv_test.py +2 -1
  57. certificate/tests/cloud_connectivity/uplink_test/uplink_test.json +0 -1
  58. certificate/tests/cloud_connectivity/uplink_test/uplink_test.py +20 -27
  59. certificate/tests/datapath/aging_test/aging_test.json +0 -1
  60. certificate/tests/datapath/aging_test/aging_test.py +3 -7
  61. certificate/tests/datapath/event_ble5_test/event_ble5_test.json +2 -3
  62. certificate/tests/datapath/event_ble5_test/event_ble5_test.py +13 -7
  63. certificate/tests/datapath/event_test/event_test.json +2 -3
  64. certificate/tests/datapath/event_test/event_test.py +10 -5
  65. certificate/tests/datapath/num_of_tags_test/num_of_tags_test.json +1 -2
  66. certificate/tests/datapath/num_of_tags_test/num_of_tags_test.py +5 -9
  67. certificate/tests/datapath/output_power_test/output_power_test.json +0 -1
  68. certificate/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.json +0 -1
  69. certificate/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.py +4 -4
  70. certificate/tests/datapath/pacer_interval_test/pacer_interval_test.json +0 -1
  71. certificate/tests/datapath/pattern_test/pattern_test.json +0 -1
  72. certificate/tests/datapath/pkt_filter_ble5_chl21_test/pkt_filter_ble5_chl21_test.json +0 -1
  73. certificate/tests/datapath/pkt_filter_ble5_chl21_test/pkt_filter_ble5_chl21_test.py +5 -5
  74. certificate/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.json +0 -1
  75. certificate/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.py +5 -5
  76. certificate/tests/datapath/pkt_filter_brg2gw_ext_adv_test/pkt_filter_brg2gw_ext_adv_test.json +0 -1
  77. certificate/tests/datapath/pkt_filter_brg2gw_ext_adv_test/pkt_filter_brg2gw_ext_adv_test.py +8 -10
  78. certificate/tests/datapath/pkt_filter_gen3_test/pkt_filter_gen3_test.json +0 -1
  79. certificate/tests/datapath/pkt_filter_test/pkt_filter_test.json +0 -1
  80. certificate/tests/datapath/rssi_threshold_test/rssi_threshold_test.json +0 -1
  81. certificate/tests/datapath/rx_channel_hopping_test/rx_channel_hopping_test.json +0 -1
  82. certificate/tests/datapath/rx_channel_test/rx_channel_test.json +0 -1
  83. certificate/tests/datapath/rx_rate_gen2_test/rx_rate_gen2_test.json +0 -1
  84. certificate/tests/datapath/rx_rate_gen2_test/rx_rate_gen2_test.py +1 -1
  85. certificate/tests/datapath/rx_rate_gen3_test/rx_rate_gen3_test.json +0 -1
  86. certificate/tests/datapath/stress_gen3_test/stress_gen3_test.json +0 -1
  87. certificate/tests/datapath/stress_gen3_test/stress_gen3_test.py +0 -3
  88. certificate/tests/datapath/stress_test/stress_test.json +0 -1
  89. certificate/tests/datapath/stress_test/stress_test.py +0 -3
  90. certificate/tests/datapath/tx_repetition_test/tx_repetition_test.json +0 -1
  91. certificate/tests/edge_mgmt/action_blink_test/action_blink_test.json +0 -1
  92. certificate/tests/edge_mgmt/action_get_battery_sensor_test/action_get_battery_sensor_test.json +0 -1
  93. certificate/tests/edge_mgmt/action_get_module_test/action_get_module_test.json +0 -1
  94. certificate/tests/edge_mgmt/action_get_pof_data_test/action_get_pof_data_test.json +0 -1
  95. certificate/tests/edge_mgmt/action_gw_hb_test/action_gw_hb_test.json +0 -1
  96. certificate/tests/edge_mgmt/action_reboot_test/action_reboot_test.json +0 -1
  97. certificate/tests/edge_mgmt/action_restore_defaults_test/action_restore_defaults_test.json +0 -1
  98. certificate/tests/edge_mgmt/action_send_hb_test/action_send_hb_test.json +0 -1
  99. certificate/tests/edge_mgmt/action_send_hb_test/action_send_hb_test.py +14 -18
  100. certificate/tests/edge_mgmt/periodic_msgs_test/periodic_msgs_test.json +0 -1
  101. certificate/tests/energy2400/duty_cycle_test/duty_cycle_test.json +0 -1
  102. certificate/tests/energy2400/output_power_test/output_power_test.json +0 -1
  103. certificate/tests/energy2400/pattern_test/pattern_test.json +0 -1
  104. certificate/tests/energy2400/signal_indicator_ble5_test/signal_indicator_ble5_test.json +0 -1
  105. certificate/tests/energy2400/signal_indicator_ble5_test/signal_indicator_ble5_test.py +3 -4
  106. certificate/tests/energy2400/signal_indicator_ext_adv_test/signal_indicator_ext_adv_test.json +9 -9
  107. certificate/tests/energy2400/signal_indicator_ext_adv_test/signal_indicator_ext_adv_test.py +271 -113
  108. certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.json +0 -1
  109. certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.py +1 -1
  110. certificate/tests/energy_sub1g/duty_cycle_test/duty_cycle_test.json +0 -1
  111. certificate/tests/energy_sub1g/pattern_test/pattern_test.json +0 -1
  112. certificate/tests/pwr_mgmt/pwr_mgmt_test/pwr_mgmt_test.json +0 -1
  113. certificate/tests/sensors/ext_sensor_test/ext_sensor_test.json +0 -1
  114. certificate/tests/sensors/ext_sensor_test/ext_sensor_test.py +9 -4
  115. common/api_if/api_validation.py +0 -6
  116. common/web/templates/generator.html +79 -141
  117. common/web/web_utils.py +56 -78
  118. gui_certificate/server.py +78 -283
  119. gui_certificate/templates/cert_run.html +113 -179
  120. {wiliot_certificate-4.5.0.dist-info → wiliot_certificate-4.5.0a2.dist-info}/METADATA +22 -7
  121. {wiliot_certificate-4.5.0.dist-info → wiliot_certificate-4.5.0a2.dist-info}/RECORD +125 -109
  122. {wiliot_certificate-4.5.0.dist-info → wiliot_certificate-4.5.0a2.dist-info}/WHEEL +0 -0
  123. {wiliot_certificate-4.5.0.dist-info → wiliot_certificate-4.5.0a2.dist-info}/entry_points.txt +0 -0
  124. {wiliot_certificate-4.5.0.dist-info → wiliot_certificate-4.5.0a2.dist-info}/licenses/LICENSE +0 -0
  125. {wiliot_certificate-4.5.0.dist-info → wiliot_certificate-4.5.0a2.dist-info}/top_level.txt +0 -0
@@ -156,7 +156,6 @@
156
156
  {%- endmacro %}
157
157
 
158
158
  {% set non_cert_text = "NOT READY FOR CERTIFICATION" %}
159
- {% set unsterile_run_warning = "Unsterile run mode is set - a certifying run must be sterile." %}
160
159
 
161
160
  <!-- Progress Indicator -->
162
161
  <div class="step-indicator">
@@ -327,15 +326,12 @@
327
326
  name="modules[]"
328
327
  id="module_{{ mod.name }}"
329
328
  value="{{ mod.name }}"
330
- {% if is_selected or (is_mandatory and not has_selections) or (mod.is_mandatory_by_schema and not has_selections) %}checked{% endif %}>
329
+ {% if is_selected %}checked{% elif is_mandatory and not has_selections %}checked{% endif %}>
331
330
  <label class="form-check-label" for="module_{{ mod.name }}" style="font-weight: bold; font-size: 1.1rem;">
332
331
  {{ mod.name }}
333
332
  {% if is_mandatory %}
334
333
  <span class="mandatory-badge">Mandatory</span>
335
334
  {% endif %}
336
- {% if mod.is_mandatory_by_schema %}
337
- <span class="mandatory-badge" style="background: #0066cc;">Mandatory by Schema</span>
338
- {% endif %}
339
335
  {{ kb_link(mod_doc) }}
340
336
  </label>
341
337
  <p class="text-muted mt-1 mb-0">
@@ -420,51 +416,22 @@
420
416
  {# Test parameters #}
421
417
  {% set params_list = t.meta.allSupportedValues | default([]) %}
422
418
  {% if params_list %}
423
- {% set has_dynamic = "dynamic_parameters" in params_list %}
424
- {% if has_dynamic %}
425
- {# Use params_list[1] as default if it exists, otherwise "1" #}
426
- {% if params_list|length > 1 %}
427
- {% set default_value = params_list[1] %}
428
- {% else %}
429
- {% set default_value = "1" %}
430
- {% endif %}
431
- {# Check if value exists in form_data (for restoring saved values) #}
432
- {% set dynamic_param_name = "params_" ~ t.id|replace('/','_') ~ "_dynamic" %}
433
- {% set saved_value = form_data.get(dynamic_param_name, default_value) %}
434
- {% endif %}
435
419
  <div id="{{ test_id }}_params" class="ms-4 mt-1 ps-2 border-start d-none">
436
- {% if has_dynamic %}
437
- <div class="small text-muted mb-1">Dynamic Parameter</div>
438
- {# Dynamic parameter: integer input #}
439
- <div class="d-flex align-items-center gap-2">
440
- <label class="small" for="{{ test_id }}_dynamic_param">Value:</label>
441
- <input type="number"
442
- class="form-control form-control-sm"
443
- style="width: 100px;"
444
- id="{{ test_id }}_dynamic_param"
445
- name="params_{{ t.id|replace('/','_') }}_dynamic"
446
- value="{{ saved_value }}"
447
- min="1"
448
- step="1">
449
- </div>
450
- {% else %}
451
- <div class="small text-muted mb-1">Parameters</div>
452
- {# Regular parameters: checkboxes #}
453
- <div class="d-flex flex-wrap gap-2">
454
- {% for p in params_list %}
455
- {% set pid = test_id ~ '_p_' ~ loop.index %}
456
- <div class="form-check">
457
- <input class="form-check-input"
458
- type="checkbox"
459
- id="{{ pid }}"
460
- name="params_{{ t.id|replace('/','_') }}[]"
461
- value="{{ p }}"
462
- checked>
463
- <label class="form-check-label small" for="{{ pid }}">{{ p }}</label>
464
- </div>
465
- {% endfor %}
466
- </div>
467
- {% endif %}
420
+ <div class="small text-muted mb-1">Parameters</div>
421
+ <div class="d-flex flex-wrap gap-2">
422
+ {% for p in params_list %}
423
+ {% set pid = test_id ~ '_p_' ~ loop.index %}
424
+ <div class="form-check">
425
+ <input class="form-check-input"
426
+ type="checkbox"
427
+ id="{{ pid }}"
428
+ name="params_{{ t.id|replace('/','_') }}[]"
429
+ value="{{ p }}"
430
+ checked>
431
+ <label class="form-check-label small" for="{{ pid }}">{{ p }}</label>
432
+ </div>
433
+ {% endfor %}
434
+ </div>
468
435
  </div>
469
436
  {% endif %}
470
437
  </div>
@@ -484,7 +451,7 @@
484
451
  {% set common_parameters = ['dut', 'custom_broker'] %}
485
452
 
486
453
  {% for f in cert_schema.fields %}
487
- {% if f.name != 'validation_schema' and f.name != 'tl' and f.name != 'custom_broker' and f.name in common_parameters %}
454
+ {% if f.name != 'validation_schema' and f.name != 'tl' and f.name in common_parameters %}
488
455
  {% set arg_label = (f.option_strings|join(', ') if f.option_strings else f.name) %}
489
456
  {% set tip_id = 'help_' ~ f.name %}
490
457
  {% set field_name = cert_schema.title ~ '_' ~ f.name %}
@@ -511,6 +478,18 @@
511
478
  <input type="checkbox" class="form-check-input" id="{{ field_name }}" name="{{ field_name }}" {% if field_value %}checked{% endif %}>
512
479
  </div>
513
480
  </div>
481
+ {% elif f.name == "overwrite_defaults" %}
482
+ <div class="col-sm-4">
483
+ <textarea id="{{ field_name }}" class="form-control" name="{{ field_name }}" rows="3" placeholder="key1=value1&#10;key2=value2">{{ field_value }}</textarea>
484
+ </div>
485
+ {% elif f.name == "custom_broker" %}
486
+ <div class="col-sm-4">
487
+ <input type="file" class="form-control" id="{{ field_name }}" name="{{ field_name }}_file" accept=".json">
488
+ {% if field_value %}
489
+ {% set path_parts = field_value.replace('\\', '/').split('/') %}
490
+ <div class="form-text">Current: {{ path_parts[-1] if path_parts|length > 1 else field_value }}</div>
491
+ {% endif %}
492
+ </div>
514
493
  {% else %}
515
494
  <div class="col-sm-4">
516
495
  <input type="{{ f.type }}" class="form-control" id="{{ field_name }}" name="{{ field_name }}" value="{{ field_value }}">
@@ -530,50 +509,6 @@
530
509
  {% endif %}
531
510
  {% endfor %}
532
511
 
533
- <!-- Custom Broker Configuration -->
534
- {% set cert_schema = cert_schema %}
535
- {% set broker_field_prefix = cert_schema.title ~ '_custom_broker_' %}
536
- <div class="card mb-3">
537
- <div class="card-header d-flex align-items-center">
538
- <button class="btn btn-sm btn-link text-decoration-none test-toggle me-2 collapsed"
539
- type="button"
540
- data-bs-toggle="collapse"
541
- data-bs-target="#customBrokerConfig"
542
- aria-expanded="false">
543
- <svg class="chev" width="16" height="16" viewBox="0 0 16 16">
544
- <path d="M4.646 5.646a.5.5 0 0 1 .708 0L8 8.293l2.646-2.647a.5.5 0 1 1 .708.708L8.354 9.354a.5.5 0 0 1-.708 0L4.646 6.354a.5.5 0 0 1 0-.708z" fill="currentColor"/>
545
- </svg>
546
- </button>
547
- <strong>Custom MQTT Broker Configuration</strong>
548
- <span class="text-danger ms-2">*</span>
549
- </div>
550
- <div id="customBrokerConfig" class="collapse">
551
- <div class="card-body">
552
- {% for field_key, field_default in custom_broker_defaults.items() %}
553
- {% set field_name = broker_field_prefix ~ field_key %}
554
- {% set field_value = form_data.get(field_name, field_default) %}
555
- {% set input_type = 'number' if field_key == 'port' else 'password' if field_key == 'password' else 'text' %}
556
- {% set is_required = field_key not in ['username', 'password'] %}
557
- <div class="row mb-3">
558
- <label for="{{ field_name }}" class="col-sm-3 col-form-label">
559
- {{ field_key }}{% if is_required %} <span class="text-danger">*</span>{% endif %}
560
- </label>
561
- <div class="col-sm-4">
562
- <input type="{{ input_type }}" class="form-control" id="{{ field_name }}" name="{{ field_name }}" value="{{ field_value }}">
563
- </div>
564
- {% if field_key in custom_broker_help.keys() %}
565
- <div class="col-sm-5 d-flex align-items-center">
566
- <span class="text-muted" style="font-size: 0.875rem; font-weight: normal;">
567
- {{ custom_broker_help[field_key] }}
568
- </span>
569
- </div>
570
- {% endif %}
571
- </div>
572
- {% endfor %}
573
- </div>
574
- </div>
575
- </div>
576
-
577
512
  <div class="card mb-3">
578
513
  <div class="card-header d-flex align-items-center">
579
514
  <button class="btn btn-sm btn-link text-decoration-none test-toggle me-2 collapsed"
@@ -680,20 +615,10 @@
680
615
  <small class="text-muted d-block mt-1">All mandatory modules and tests are selected</small>
681
616
  {% else %}
682
617
  <span class="badge bg-warning text-dark">{{ non_cert_text }}</span>
683
- <small class="text-muted d-block mt-1">
684
- {% if not unsterile_run %}
685
- Some mandatory modules or tests are missing
686
- {% endif %}
687
- </small>
618
+ <small class="text-muted d-block mt-1">Some mandatory modules or tests are missing</small>
688
619
  {% endif %}
689
620
  </p>
690
621
 
691
- {% if unsterile_run %}
692
- <div class="alert alert-warning">
693
- <strong>⚠️ Warning:</strong> {{ unsterile_run_warning }}
694
- </div>
695
- {% endif %}
696
-
697
622
  {% if not is_certified %}
698
623
  {% if missing_modules %}
699
624
  <div class="alert alert-warning">
@@ -719,13 +644,12 @@
719
644
  {% endif %}
720
645
  {% if missing_tests_details %}
721
646
  <div class="alert alert-warning">
722
- <strong>Missing Mandatory Tests from Selected Modules:</strong>
647
+ <strong>Missing Mandatory Tests:</strong>
723
648
  <ul class="mb-0">
724
649
  {% for test in missing_tests_details %}
725
650
  <li>{{ test.label }} <small class="text-muted">({{ test.module }})</small></li>
726
651
  {% endfor %}
727
652
  </ul>
728
- <small class="d-block mt-2">When a module is selected, its mandatory tests must also be selected.</small>
729
653
  </div>
730
654
  {% endif %}
731
655
  {% endif %}
@@ -738,10 +662,7 @@
738
662
  <h5 class="mb-0">Schema Verification</h5>
739
663
  </div>
740
664
  <div class="card-body">
741
- {% if schema_errors or schema_warnings or missing_modules_by_schema %}
742
- <p><strong>Schema Status:</strong>
743
- <span class="badge bg-warning text-dark">SCHEMA DOES NOT MATCH RUN SETTINGS</span>
744
- </p>
665
+ {% if schema_errors or schema_warnings %}
745
666
  {% if schema_errors %}
746
667
  <div class="alert alert-danger">
747
668
  <strong>Errors:</strong>
@@ -762,26 +683,84 @@
762
683
  </ul>
763
684
  </div>
764
685
  {% endif %}
765
- {% if missing_modules_by_schema %}
766
- <div class="alert alert-warning mt-3">
767
- <strong>Missing Modules Mandatory by Schema:</strong>
768
- <ul class="mb-0">
769
- {% for mod in missing_modules_by_schema %}
770
- <li>{{ mod }}</li>
771
- {% endfor %}
772
- </ul>
773
- <small class="d-block mt-2">These modules are declared in your validation schema but are not selected. They should be included for proper certification.</small>
774
- </div>
775
- {% endif %}
776
686
  {% else %}
777
687
  <p><strong>Schema Status:</strong>
778
- <span class="badge bg-success">SCHEMA MATCHES RUN SETTINGS</span>
688
+ <span class="badge bg-success">SCHEMA MATCHES TEST CONFIGURATION</span>
779
689
  <small class="text-muted d-block mt-1">The uploaded schema matches the selected flavor, modules, and tests</small>
780
690
  </p>
781
691
  {% endif %}
692
+ </div>
693
+ </div>
694
+
695
+ <!-- Run Parameters Summary -->
696
+ {% set cert_schema = cert_schema %}
697
+ {% set cb_index = -1 %}
698
+ {% for f in cert_schema.fields %}
699
+ {% if f.name == 'custom_broker' %}
700
+ {% set cb_index = loop.index0 %}
701
+ {% endif %}
702
+ {% endfor %}
703
+ {% set has_advanced = False %}
704
+ {% for f in cert_schema.fields %}
705
+ {% if f.name != 'validation_schema' and f.name != 'tl' and cb_index >= 0 and loop.index0 > cb_index %}
706
+ {% set has_advanced = True %}
707
+ {% endif %}
708
+ {% endfor %}
709
+ {% if has_advanced %}
710
+ <div class="card mb-4">
711
+ <div class="card-header">
712
+ <h5 class="mb-0">Run Parameters</h5>
713
+ </div>
714
+ <div class="card-body">
715
+ {% for f in cert_schema.fields %}
716
+ {% if f.name != 'validation_schema' and f.name != 'tl' %}
717
+ {% set field_name = cert_schema.title ~ '_' ~ f.name %}
718
+ {% set field_value = form_data.get(field_name, f.default if f.default is not none else '') %}
719
+ {% set is_advanced = cb_index >= 0 and loop.index0 > cb_index %}
720
+
721
+ {% if not is_advanced %}
722
+ {% set arg_label = (f.option_strings|join(', ') if f.option_strings else f.name) %}
723
+ <p><strong>{{ arg_label }}:</strong>
724
+ {% if f.is_flag %}
725
+ {{ 'Yes' if field_value else 'No' }}
726
+ {% else %}
727
+ {{ field_value if field_value else '(not set)' }}
728
+ {% endif %}
729
+ </p>
730
+ {% endif %}
731
+ {% endif %}
732
+ {% endfor %}
782
733
 
734
+ {% if has_advanced %}
735
+ <div class="mb-3">
736
+ <button class="btn btn-outline-secondary btn-sm" type="button" data-bs-toggle="collapse" data-bs-target="#advancedParamsReview" aria-expanded="false" aria-controls="advancedParamsReview">
737
+ Advanced Parameters ▼
738
+ </button>
739
+ </div>
740
+ <div class="collapse" id="advancedParamsReview">
741
+ {% for f in cert_schema.fields %}
742
+ {% if f.name != 'validation_schema' and f.name != 'tl' %}
743
+ {% set field_name = cert_schema.title ~ '_' ~ f.name %}
744
+ {% set field_value = form_data.get(field_name, f.default if f.default is not none else '') %}
745
+ {% set is_advanced = cb_index >= 0 and loop.index0 > cb_index %}
746
+
747
+ {% if is_advanced %}
748
+ {% set arg_label = (f.option_strings|join(', ') if f.option_strings else f.name) %}
749
+ <p><strong>{{ arg_label }}:</strong>
750
+ {% if f.is_flag %}
751
+ {{ 'Yes' if field_value else 'No' }}
752
+ {% else %}
753
+ {{ field_value if field_value else '(not set)' }}
754
+ {% endif %}
755
+ </p>
756
+ {% endif %}
757
+ {% endif %}
758
+ {% endfor %}
759
+ </div>
760
+ {% endif %}
783
761
  </div>
784
762
  </div>
763
+ {% endif %}
785
764
 
786
765
  <!-- Edit Links -->
787
766
  <div class="mb-4">
@@ -862,10 +841,8 @@
862
841
  const mandatoryTests = {{ mandatory_tests_for_js|tojson|safe }};
863
842
  const currentSelectedModules = {{ selected_modules|tojson|safe }};
864
843
  const brgCertSchema = {{ cert_schema|tojson|safe }};
865
- const customBrokerFieldKeys = {{ custom_broker_field_keys|tojson|safe }};
866
844
 
867
845
  // Step 3: Module selection validation
868
- const mandatoryModulesBySchema = {{ mandatory_modules_by_schema_for_js|tojson|safe }};
869
846
  function checkStep3Validation() {
870
847
  if (stepNum !== 3) return;
871
848
 
@@ -884,14 +861,6 @@
884
861
  warnings.push('Missing mandatory modules: ' + missingMandatory.join(', '));
885
862
  }
886
863
 
887
- // Check if schema-mandatory modules are deselected
888
- if (mandatoryModulesBySchema && mandatoryModulesBySchema.length > 0) {
889
- const missingBySchema = mandatoryModulesBySchema.filter(m => !selectedModules.includes(m));
890
- if (missingBySchema.length > 0) {
891
- warnings.push('Missing modules mandatory by schema: ' + missingBySchema.join(', '));
892
- }
893
- }
894
-
895
864
  // Check Bridge/Combo requirement for at least one additional module
896
865
  if (selectedFlavor === 'bridge_only' || selectedFlavor === 'combo') {
897
866
  const nonMandatorySelected = selectedModules.filter(m => !mandatoryModules.includes(m));
@@ -928,33 +897,18 @@
928
897
 
929
898
  let warnings = [];
930
899
 
931
- // Check if unsterile_run is enabled
932
- const unsterileRunField = document.querySelector('input[id*="unsterile_run"], input[name*="unsterile_run"]');
933
- if (unsterileRunField && unsterileRunField.checked) {
934
- warnings.push('{{ unsterile_run_warning }}');
935
- }
936
-
937
900
  // Check if mandatory modules are deselected (from step 3)
938
901
  const missingMandatoryModules = mandatoryModules.filter(m => !selectedModules.includes(m));
939
902
  if (missingMandatoryModules.length > 0) {
940
903
  warnings.push('Missing mandatory modules: ' + missingMandatoryModules.join(', '));
941
904
  }
942
905
 
943
- // Check if schema-mandatory modules are deselected
944
- if (mandatoryModulesBySchema && mandatoryModulesBySchema.length > 0) {
945
- const missingBySchema = mandatoryModulesBySchema.filter(m => !selectedModules.includes(m));
946
- if (missingBySchema.length > 0) {
947
- warnings.push('Missing modules mandatory by schema: ' + missingBySchema.join(', '));
948
- }
949
- }
950
-
951
- // Check if mandatory tests from selected modules are deselected
952
- // When a module is selected, its mandatory tests become mandatory
906
+ // Check if mandatory tests are deselected
953
907
  const missingMandatoryTests = mandatoryTests
954
908
  .filter(t => selectedModules.includes(t.module) && !selectedTests.includes(t.id))
955
909
  .map(t => t.label + ' (' + t.module + ')');
956
910
  if (missingMandatoryTests.length > 0) {
957
- warnings.push('Missing mandatory tests from selected modules: ' + missingMandatoryTests.length + ' test(s)');
911
+ warnings.push('Missing mandatory tests: ' + missingMandatoryTests.length + ' test(s)');
958
912
  }
959
913
 
960
914
  if (warnings.length > 0) {
@@ -1081,18 +1035,6 @@
1081
1035
  if (stepNum === 3) checkStep3Validation();
1082
1036
  if (stepNum === 4) checkStep4Validation();
1083
1037
  }
1084
-
1085
- // Unsterile run checkbox change
1086
- const unsterileRunField = document.querySelector('input[id*="unsterile_run"], input[name*="unsterile_run"]');
1087
- if (unsterileRunField && e.target === unsterileRunField) {
1088
- // Show/hide warning and update validation
1089
- const warningDiv = document.getElementById('step4_warning');
1090
- const warningText = document.getElementById('step4_warning_text');
1091
- if (warningDiv && warningText) {
1092
- // Re-run validation to update warning
1093
- if (stepNum === 4) checkStep4Validation();
1094
- }
1095
- }
1096
1038
  });
1097
1039
 
1098
1040
  // Initialize params visibility for pre-checked tests
@@ -1125,26 +1067,18 @@
1125
1067
  const fieldName = `${brgCertSchema.title}_${field.name}`;
1126
1068
  let fieldValue = null;
1127
1069
 
1128
- // Special handling for custom_broker - check if all required broker fields have values (like dut)
1129
- // Username and password are optional, all other fields are required
1070
+ // Special handling for custom_broker file upload
1130
1071
  if (field.name === 'custom_broker') {
1131
- const brokerFieldPrefix = `${brgCertSchema.title}_custom_broker_`;
1132
- const optionalFields = ['username', 'password'];
1133
- let allRequiredFieldsFilled = true;
1134
- for (const brokerField of customBrokerFieldKeys) {
1135
- // Skip optional fields
1136
- if (optionalFields.includes(brokerField)) {
1137
- continue;
1138
- }
1139
- const input = document.querySelector(`input[name="${brokerFieldPrefix}${brokerField}"]`);
1140
- if (!input || !input.value || (typeof input.value === 'string' && !input.value.trim())) {
1141
- allRequiredFieldsFilled = false;
1142
- break;
1072
+ const fileInput = document.querySelector(`input[name="${fieldName}_file"]`);
1073
+ if (fileInput && fileInput.files && fileInput.files.length > 0) {
1074
+ fieldValue = fileInput.files[0].name;
1075
+ } else {
1076
+ // Check if there's a current value displayed
1077
+ const currentValueDiv = fileInput?.closest('.col-sm-4')?.querySelector('.form-text');
1078
+ if (currentValueDiv) {
1079
+ fieldValue = 'exists';
1143
1080
  }
1144
1081
  }
1145
- if (allRequiredFieldsFilled) {
1146
- fieldValue = 'configured';
1147
- }
1148
1082
  } else {
1149
1083
  // For other fields, check input/select value
1150
1084
  const inputs = document.querySelectorAll(`input[name="${fieldName}"], select[name="${fieldName}"]`);
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wiliot_certificate
3
- Version: 4.5.0
3
+ Version: 4.5.0a2
4
4
  Summary: A library for certifying Wiliot-compliant boards
5
5
  Author-email: Wiliot <support@wiliot.com>
6
6
  License-Expression: MIT
@@ -30,7 +30,7 @@ Requires-Dist: reportlab>=4.3.1
30
30
  Requires-Dist: google-api-python-client>=2.162.0
31
31
  Dynamic: license-file
32
32
 
33
- # wiliot-certificate
33
+ # wiliot-certificate Version 4.5.0
34
34
 
35
35
  <!-- Description -->
36
36
  wiliot-certificate is a Python library that provides tools for testing and certifying boards for compatibility with Wiliot’s ecosystem.
@@ -38,29 +38,32 @@ This python package includes the following tools:
38
38
  - Certification Wizard (`wlt-cert`)
39
39
  - Certificate CLI (`wlt-cert-cli`)
40
40
  - Tester Upgrade (`wlt-cert-tester-upgrade`)
41
- - Registration Certificate Test (`wlt-cert-reg`)
41
+ - Registration Certificate (`wlt-cert-reg`)
42
42
 
43
- # Versioning:
44
- wiliot-certificate versions 4.5.x are compatible with firmware version >=4.4.0 (API VERSION: 12)
43
+ # Version:
44
+ wiliot-certificate versions 4.5.0 are compatible with firmware version >=4.5.0 (API VERSION: 13)
45
45
 
46
46
  ## Installing wiliot-certificate
47
+ Install wiliot-certificate:
47
48
  ````commandline
48
49
  pip install wiliot-certificate
49
50
  ````
50
51
 
51
52
  ## Using wiliot-certificate
52
53
  ### Certification
54
+ In terminal, run:
53
55
  ````commandline
54
56
  wlt-cert
55
57
  ````
56
58
  This tool is the default to test and certify your device.
57
59
  It runs a setup wizard that walks you through the initialization steps before running the tests.
58
- You'll need a [validation schema](https://community.wiliot.com/customers/s/article/Validation-Schema) and a [tester device](https://community.wiliot.com/customers/s/article/Wiliot-Certification).
60
+ You'll need a [validation schema](https://community.wiliot.com/customers/s/article/Validation-Schema), tester device and custom broker json file ([more info here](https://community.wiliot.com/customers/s/article/Wiliot-Gateway-Certification)).
59
61
  Once set up it opens a terminal and tests your device.
60
62
 
61
63
 
62
64
 
63
65
  ### Certificate CLI
66
+ In terminal, run:
64
67
  ````commandline
65
68
  wlt-cert-cli -h
66
69
  ````
@@ -68,6 +71,7 @@ CLI version of the certificate. Use -h for details on the different arguments.
68
71
 
69
72
 
70
73
  ### Tester Upgrade
74
+ In terminal, run:
71
75
  ````commandline
72
76
  wlt-cert-tester-upgrade
73
77
  ````
@@ -75,18 +79,23 @@ Upgrades the firmware of the tester device to the version required for certifica
75
79
 
76
80
 
77
81
  ### Registration Certificate
82
+ In terminal, run:
78
83
  ````commandline
79
84
  wlt-cert-reg
80
85
  ````
81
86
  Certify the gateway registration process to Wiliot platform.
82
87
  The gateway must use Wiliot production MQTT broker, and mustn't be registered to any account on Wiliot platform.
83
- Use -h for details on the arguments (see [Registration](https://community.wiliot.com/customers/s/article/Wiliot-Certification) for more info).
88
+ Use -h for details on the arguments. [More info here](https://community.wiliot.com/customers/s/article/Wiliot-Gateway-Certification)
84
89
 
85
90
 
86
91
  ## The following capabilities are not tested in this version
87
92
  ##### Cloud Connectivity & Misc
88
93
  - Board type registered within the Board Type Management system
89
94
  - Bridge OTA progress reporting
95
+ ##### Power management
96
+ - Functionality of energize and transmit in sleep mode
97
+ ##### Edge management
98
+ - Timing of heartbeat and interface packets
90
99
  ##### Module Energy 2400
91
100
  - Functionality of energy pattern, output power and duty cycle
92
101
  ##### Module Energy SUB1G
@@ -94,6 +103,12 @@ Use -h for details on the arguments (see [Registration](https://community.wiliot
94
103
  ##### Module Datapath
95
104
  - RSSI edge cases: -127 and 0
96
105
  - Functionality of transmission pattern, output power
106
+ - Pacer interval with channel 10 and 500k modulation
107
+ - Pacer interval using GEN3 Pixels
108
+ - Packet filter: the following configuration - DEBUG, TEMP & DEBUG, TEMPS & DEBUG & ADVANCE
109
+ - Rx rate feature with extended advertising
110
+ - Functionality of adaptive pacer algorithm
111
+ - Supported Pixels for extended advertising and GEN3
97
112
  ##### Calibration
98
113
  - Functionality of output power and interval calibration
99
114
  - Functionality of calibration transmission patterns for the configuration STANDARD & EU & DISABLE