wiliot-certificate 1.5.1a1__py3-none-any.whl → 1.5.2a1__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 (98) hide show
  1. brg_certificate/ag/wlt_cmd_if.html +3 -2
  2. brg_certificate/brg_certificate_cli.py +18 -3
  3. brg_certificate/cert_common.py +82 -26
  4. brg_certificate/cert_data_sim.py +22 -4
  5. brg_certificate/cert_defines.py +10 -5
  6. brg_certificate/cert_gw_sim.py +4 -2
  7. brg_certificate/cert_mqtt.py +7 -6
  8. brg_certificate/cert_prints.py +14 -1
  9. brg_certificate/cert_protobuf.py +7 -7
  10. brg_certificate/cert_results.py +91 -64
  11. brg_certificate/cert_utils.py +9 -4
  12. brg_certificate/certificate_bcc_sanity_test_list.txt +10 -5
  13. brg_certificate/certificate_bcc_test_list.txt +14 -9
  14. brg_certificate/certificate_sanity_test_list.txt +10 -4
  15. brg_certificate/certificate_test_list.txt +13 -9
  16. brg_certificate/tests/calibration/interval_test/interval_test.json +2 -2
  17. brg_certificate/tests/calibration/output_power_test/output_power_test.json +3 -2
  18. brg_certificate/tests/calibration/pattern_test/pattern_test.json +2 -2
  19. brg_certificate/tests/calibration/pattern_test/pattern_test.py +25 -26
  20. brg_certificate/tests/datapath/aging_test/aging_test.json +4 -5
  21. brg_certificate/tests/datapath/aging_test/aging_test.py +39 -32
  22. brg_certificate/tests/datapath/num_of_tags_test/num_of_tags_test.json +2 -2
  23. brg_certificate/tests/datapath/num_of_tags_test/num_of_tags_test.py +12 -11
  24. brg_certificate/tests/datapath/output_power_test/output_power_test.json +2 -2
  25. brg_certificate/tests/datapath/output_power_test/output_power_test.py +2 -1
  26. brg_certificate/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.json +3 -3
  27. brg_certificate/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.py +6 -3
  28. brg_certificate/tests/datapath/pacer_interval_tags_count_test/pacer_interval_tags_count_test.json +2 -2
  29. brg_certificate/tests/datapath/pacer_interval_tags_count_test/pacer_interval_tags_count_test.py +6 -3
  30. brg_certificate/tests/datapath/pacer_interval_test/pacer_interval_test.json +2 -2
  31. brg_certificate/tests/datapath/pacer_interval_test/pacer_interval_test.py +4 -2
  32. brg_certificate/tests/datapath/pattern_test/pattern_test.json +2 -2
  33. brg_certificate/tests/datapath/pattern_test/pattern_test.py +2 -1
  34. brg_certificate/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.json +3 -3
  35. brg_certificate/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.py +12 -5
  36. brg_certificate/tests/datapath/pkt_filter_gen3_test/pkt_filter_gen3_test.json +2 -2
  37. brg_certificate/tests/datapath/pkt_filter_gen3_test/pkt_filter_gen3_test.py +11 -6
  38. brg_certificate/tests/datapath/pkt_filter_test/pkt_filter_test.json +2 -2
  39. brg_certificate/tests/datapath/pkt_filter_test/pkt_filter_test.py +11 -7
  40. brg_certificate/tests/datapath/rssi_threshold_test/rssi_threshold_test.json +3 -3
  41. brg_certificate/tests/datapath/rssi_threshold_test/rssi_threshold_test.py +7 -5
  42. brg_certificate/tests/datapath/rx_channel_test/rx_channel_test.json +2 -2
  43. brg_certificate/tests/datapath/rx_channel_test/rx_channel_test.py +7 -3
  44. brg_certificate/tests/datapath/rx_rate_gen2_test/rx_rate_gen2_test.json +3 -3
  45. brg_certificate/tests/datapath/rx_rate_gen2_test/rx_rate_gen2_test.py +107 -73
  46. brg_certificate/tests/datapath/rx_rate_gen3_test/rx_rate_gen3_test.json +3 -3
  47. brg_certificate/tests/datapath/rx_rate_gen3_test/rx_rate_gen3_test.py +128 -118
  48. brg_certificate/tests/datapath/stress_gen3_test/stress_gen3_test.json +8 -8
  49. brg_certificate/tests/datapath/stress_gen3_test/stress_gen3_test.py +102 -101
  50. brg_certificate/tests/datapath/stress_test/stress_test.json +14 -15
  51. brg_certificate/tests/datapath/stress_test/stress_test.py +102 -101
  52. brg_certificate/tests/datapath/tx_repetition_algo_test/tx_repetition_algo_test.json +2 -2
  53. brg_certificate/tests/datapath/tx_repetition_algo_test/tx_repetition_algo_test.py +7 -2
  54. brg_certificate/tests/datapath/tx_repetition_test/tx_repetition_test.json +2 -2
  55. brg_certificate/tests/datapath/tx_repetition_test/tx_repetition_test.py +8 -6
  56. brg_certificate/tests/edge_mgmt/actions_test/actions_test.json +2 -2
  57. brg_certificate/tests/edge_mgmt/actions_test/actions_test.py +2 -18
  58. brg_certificate/tests/edge_mgmt/brg2brg_ota_ble5_test/brg2brg_ota_ble5_test.json +14 -8
  59. brg_certificate/tests/edge_mgmt/brg2brg_ota_test/brg2brg_ota_test.json +13 -8
  60. brg_certificate/tests/edge_mgmt/leds_test/leds_test.json +2 -2
  61. brg_certificate/tests/edge_mgmt/leds_test/leds_test.py +22 -9
  62. brg_certificate/tests/edge_mgmt/ota_test/ota_test.json +2 -2
  63. brg_certificate/tests/edge_mgmt/ota_test/ota_test.py +6 -5
  64. brg_certificate/tests/edge_mgmt/{stat_test/stat_test.json → periodic_msgs_test/periodic_msgs_test.json} +3 -3
  65. brg_certificate/tests/edge_mgmt/{stat_test/stat_test.py → periodic_msgs_test/periodic_msgs_test.py} +4 -4
  66. brg_certificate/tests/energy2400/duty_cycle_test/duty_cycle_test.json +3 -3
  67. brg_certificate/tests/energy2400/duty_cycle_test/duty_cycle_test.py +2 -1
  68. brg_certificate/tests/energy2400/output_power_test/output_power_test.json +4 -3
  69. brg_certificate/tests/energy2400/output_power_test/output_power_test.py +2 -1
  70. brg_certificate/tests/energy2400/pattern_test/pattern_test.json +3 -3
  71. brg_certificate/tests/energy2400/pattern_test/pattern_test.py +2 -1
  72. brg_certificate/tests/energy2400/signal_indicator_ble5_10_250k_test/signal_indicator_ble5_10_250k_test.json +5 -5
  73. brg_certificate/tests/energy2400/signal_indicator_ble5_10_250k_test/signal_indicator_ble5_10_250k_test.py +109 -112
  74. brg_certificate/tests/energy2400/signal_indicator_ble5_10_500k_test/signal_indicator_ble5_10_500k_test.json +5 -5
  75. brg_certificate/tests/energy2400/signal_indicator_ble5_10_500k_test/signal_indicator_ble5_10_500k_test.py +111 -114
  76. brg_certificate/tests/energy2400/signal_indicator_sub1g_2_4_test/signal_indicator_sub1g_2_4_test.json +12 -6
  77. brg_certificate/tests/energy2400/signal_indicator_sub1g_2_4_test/signal_indicator_sub1g_2_4_test.py +45 -57
  78. brg_certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.json +4 -4
  79. brg_certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.py +158 -172
  80. brg_certificate/tests/energy_sub1g/duty_cycle_test/duty_cycle_test.json +2 -2
  81. brg_certificate/tests/energy_sub1g/duty_cycle_test/duty_cycle_test.py +2 -1
  82. brg_certificate/tests/energy_sub1g/pattern_test/pattern_test.json +4 -3
  83. brg_certificate/tests/energy_sub1g/pattern_test/pattern_test.py +2 -1
  84. brg_certificate/tests/energy_sub1g/signal_indicator_functionality_test/signal_indicator_functionality_test.json +13 -7
  85. brg_certificate/tests/energy_sub1g/signal_indicator_functionality_test/signal_indicator_functionality_test.py +117 -124
  86. brg_certificate/tests/energy_sub1g/signal_indicator_test/signal_indicator_test.json +2 -2
  87. brg_certificate/tests/energy_sub1g/signal_indicator_test/signal_indicator_test.py +2 -1
  88. brg_certificate/tests/pwr_mgmt/pwr_mgmt_test/pwr_mgmt_test.json +18 -0
  89. brg_certificate/tests/pwr_mgmt/pwr_mgmt_test/pwr_mgmt_test.py +84 -0
  90. brg_certificate/tests/sensors/ext_sensor_test/ext_sensor_test.json +21 -0
  91. brg_certificate/tests/sensors/ext_sensor_test/ext_sensor_test.py +306 -0
  92. brg_certificate/wlt_types.py +2 -1
  93. {wiliot_certificate-1.5.1a1.dist-info → wiliot_certificate-1.5.2a1.dist-info}/METADATA +40 -40
  94. {wiliot_certificate-1.5.1a1.dist-info → wiliot_certificate-1.5.2a1.dist-info}/RECORD +98 -94
  95. {wiliot_certificate-1.5.1a1.dist-info → wiliot_certificate-1.5.2a1.dist-info}/WHEEL +1 -1
  96. {wiliot_certificate-1.5.1a1.dist-info → wiliot_certificate-1.5.2a1.dist-info}/entry_points.txt +0 -0
  97. {wiliot_certificate-1.5.1a1.dist-info → wiliot_certificate-1.5.2a1.dist-info}/licenses/LICENSE +0 -0
  98. {wiliot_certificate-1.5.1a1.dist-info → wiliot_certificate-1.5.2a1.dist-info}/top_level.txt +0 -0
@@ -26,6 +26,7 @@ tr:nth-child(odd) {
26
26
  <table>
27
27
  <tr><th>Name</th><th>Shortcut</th><th>Num of Arguments</th><th>Description</th><th>Example</th></tr>
28
28
  <tr><td>energous</td><td>NONE</td><td>SKIP_ARGS_VALIDATION</td><td></td><td></td></tr>
29
+ <tr><td>esp</td><td>NONE</td><td>SKIP_ARGS_VALIDATION</td><td></td><td>!esp reset</td></tr>
29
30
  <tr><td>ant_sel_mode_set</td><td>asms</td><td>1</td><td>set antenna polarity mode, whereas 0 = random_toggle, 1 = clear, 2 = set, 3 = toggle</td><td>!ant_sel_mode_set 1</td></tr>
30
31
  <tr><td>ant_sel_set</td><td>ass</td><td>1</td><td>Set the antenna select pin to be 0 or 1</td><td>!ant_sel_set 1</td></tr>
31
32
  <tr><td>pwr_cal_set</td><td>pcs</td><td>2</td><td>Set power calibration value (used by Energous during production line)</td><td>!pwr_cal_set 127 124</td></tr>
@@ -92,9 +93,9 @@ tr:nth-child(odd) {
92
93
  <tr><td>calib_pattern</td><td>cp</td><td>1</td><td>Set new configuration for Calibration Pattern, could be - {0: 'Standard beaconing', 1: 'No beacons on channel 37', 2: 'EU pattern', 3: 'Disable communication beaconing'}</td><td>!cp 0</td></tr>
93
94
  <tr><td>signal_indicator_2_4_set</td><td>si24</td><td>2</td><td>Set a new configuration for 2.4GHz signal_indicator packets cycle. The cycle is the duration in seconds between transmission of signal indicator packets. Min - 0 , Max - 16383. 0 - disable the transmission. When the 'Signal Indicator Cycle' is 0 repetitions value is irrelevant. repetitions Min - 1, Max - 4</td><td>!si24 60 4</td></tr>
94
95
  <tr><td>signal_indicator_sub1g_set</td><td>sis</td><td>2</td><td>Set a new configuration for sub1g signal_indicator packets cycle and repetition. The cycle is the duration in seconds between transmission of signal indicator packets. Min - 0 , Max - 16383. 0 - disable the transmission. When the 'Signal Indicator Cycle' is 0 repetitions value is irrelevant. repetitions Min - 1, Max - 4</td><td>!sis 60 4</td></tr>
95
- <tr><td>test_mode_2_4_set</td><td>tm24</td><td>3</td><td>Test mode for the 2.4Ghz radio, Frequency [2400-2480 MHz]; Power (before PA that can add ~20) [+8 dBm to -12 dBm]; Test Duration [Seconds]</td><td>!tm24 2400 2 20</td></tr>
96
+ <tr><td>test_mode_2_4_set</td><td>tm24</td><td>3</td><td>Test mode for the 2.4Ghz radio, Frequency [2400-2480 MHz]; Power (before PA that can add ~20) [+8 dBm to -12 dBm]; Test Duration [Seconds]</td><td>!tm24 2400 2 30</td></tr>
96
97
  <tr><td>test_mode_sub1g_set</td><td>tms</td><td>5</td><td>Test mode for the Sub1G radio, Frequency [905000-920000 kHz], Output Power (before PA that can add ~20) ,On time [milliseconds], Off time [milliseconds]; Test Duration[Seconds]</td><td>!tms 905000 4 20 60 20</td></tr>
97
- <tr><td>test_mode_operational_2_4_set</td><td>tmo24</td><td>3</td><td>Test mode for various 2.4Ghz operational modes: Pattern [0=Beacons 37/38/39, 1=Beacons 38/38/39, 2=EU pattern]; Power [+8 dBm to -12 dBm , before PA that can add ~20 [dBm]]; Test Duration[Seconds]</td><td>!tmo24 0 2</td></tr>
98
+ <tr><td>test_mode_operational_2_4_set</td><td>tmo24</td><td>3</td><td>Test mode for various 2.4Ghz operational modes: Pattern [0=Beacons 37/38/39, 1=Beacons 38/38/39, 2=EU pattern]; Power [+8 dBm to -12 dBm , before PA that can add ~20 [dBm]]; Test Duration[Seconds]</td><td>!tmo24 0 2 30</td></tr>
98
99
  <tr><td>test_mode_operational_sub1g_set</td><td>tmos</td><td>3</td><td>Test mode for various sub1G operational modes: Pattern [0=No energy, 1=Single one 915M, 2=FCC Hopping, 3=Japan_1W, 4=Jappan_350mW, 5=Korea, 6=916.3 MHz, 7=917.5 mHz,8=Australia, 9=Israel, 10=NZ Hopping; Output Power (before PA that can add ~20); Test Duration[Seconds]</td><td>!tmos 2 4 60</td></tr>
99
100
 
100
101
  </table>
@@ -1,22 +1,37 @@
1
1
  import sys
2
2
  import os
3
3
  sys.path.insert(0, os.path.abspath(".."))
4
- from argparse import ArgumentParser
4
+ from argparse import ArgumentParser, RawDescriptionHelpFormatter
5
5
  from brg_certificate.cert_defines import DATA_REAL_TAGS, DATA_SIMULATION
6
6
  import brg_certificate.brg_certificate as brg_certificate
7
- TEST_LIST_DEFAULT_FILE = "certificate_sanity_test_list.txt"
7
+ TEST_LIST_DEFAULT_FILE = "certificate_test_list.txt"
8
8
 
9
9
  class BrgCertificateCLI:
10
10
  """Bridge Certificate CLI."""
11
11
  def __init__(self):
12
12
  self.parser = ArgumentParser(
13
13
  description="Bridge Certificate CLI",
14
+ epilog=
15
+ "run examples:\n"
16
+ " Run command example with COM PORT connection:\n"
17
+ " wlt-cert-brg --gw SIM --brg <XXXXXXXXXXXX> --port <COM_PORT>\n"
18
+ " Run command example with remote GW connection:\n"
19
+ " wlt-cert-brg --gw <YYYYYYYYYYYY> --brg <XXXXXXXXXXXX>\n"
20
+ " Run command example for running datapath module tests only:\n"
21
+ " wlt-cert-brg --gw <YYYYYYYYYYYY> --brg <XXXXXXXXXXXX> --run datapath\n"
22
+ " Run command example with sanity test list:\n"
23
+ " wlt-cert-brg --gw <YYYYYYYYYYYY> --brg <XXXXXXXXXXXX> --tl certificate_sanity_test_list.txt\n"
24
+ " Run command example with COM PORT connection for bridge with cloud connectivity:\n"
25
+ " wlt-cert-brg --gw SIM --brg_cloud_connectivity <XXXXXXXXXXXX> --tl certificate_bcc_test_list.txt --port <COM_PORT>\n"
26
+ " Run command example with remote GW connection for bridge with cloud connectivity:\n"
27
+ " wlt-cert-brg --gw <YYYYYYYYYYYY> --brg_cloud_connectivity <XXXXXXXXXXXX> --tl certificate_bcc_test_list.txt\n",
28
+ formatter_class=RawDescriptionHelpFormatter
14
29
  )
15
30
  self.parser.add_argument('--brg', '-b', default="", help='Bridge id to run on the tests')
16
31
  self.parser.add_argument('--brg_cloud_connectivity', '-bcc', default="", help='Bridge with cloud connectivity id to run on the tests')
17
32
  self.parser.add_argument('--brg1', '-b1', default="", help='Second bridge id to run on tests two bridges needed')
18
33
  self.parser.add_argument('--gw', '-g', type=str, required=True, help='GW id to run on the test, SIM prefix is used for Gateway simulation')
19
- self.parser.add_argument('--data', '-d', choices=[DATA_REAL_TAGS, DATA_SIMULATION], default=DATA_REAL_TAGS, help='Choose if data generated from real tags or by simulation')
34
+ self.parser.add_argument('--data', '-d', choices=[DATA_REAL_TAGS, DATA_SIMULATION], default=DATA_SIMULATION, help='Choose if data generated from real tags or by simulation')
20
35
  self.parser.add_argument('--port', '-p', default='', help='Enable UT using UART connection for Gateway Simulation or Data Simulation')
21
36
  self.parser.add_argument('--clean', default=False, action='store_true', help='Clean all logs')
22
37
  self.parser.add_argument('--tl', type=str, help='Test list file to use', default=TEST_LIST_DEFAULT_FILE)
@@ -15,9 +15,24 @@ DEFAULT_HDR = ag.Hdr(group_id=ag.GROUP_ID_GW2BRG)
15
15
  # Returns a 12 chars long hex string
16
16
  int2mac_get = lambda int_val: f"{int_val:012X}"
17
17
 
18
+ # Returns True if running with bridge with cloud connectivity, else False
19
+ is_bcc_running = lambda test: not (test.sim_mqttc == test.mqttc)
20
+
21
+ # Returns True if running from PyPi package, else False
22
+ is_cert_running = lambda : not (CERT_VERSION == LOCAL_DEV)
23
+
18
24
  def name_to_val(name):
19
25
  return globals()[name]
20
26
 
27
+
28
+ def get_module_by_name(modules, name):
29
+ # Get module from active modules in device (loaded from board type ag defines)
30
+ for module in modules:
31
+ if name in module.__name__:
32
+ return module
33
+ return None
34
+
35
+
21
36
  def test_prolog(test):
22
37
  """
23
38
  kicks off the test:
@@ -154,8 +169,12 @@ def get_gw_geolocation(test):
154
169
  for p in test.mqttc._userdata[PKTS].status:
155
170
  if GW_INFO in p.body:
156
171
  print_pkt(p.body)
157
- gw_lat = p.body[GW_INFO][GW_LATITUDE]
158
- gw_lng = p.body[GW_INFO][GW_LONGITUDE]
172
+ if test.protobuf:
173
+ gw_lat = p.body[GW_INFO][ENTRIES][GW_LATITUDE][NUM_VAL]
174
+ gw_lng = p.body[GW_INFO][ENTRIES][GW_LONGITUDE][NUM_VAL]
175
+ else:
176
+ gw_lat = p.body[GW_INFO][GW_LATITUDE]
177
+ gw_lng = p.body[GW_INFO][GW_LONGITUDE]
159
178
  print(f"gw_lat:{gw_lat} \ngw_lng:{gw_lng}")
160
179
  found = True
161
180
  print_update_wait()
@@ -406,7 +425,7 @@ def pacing_analysis(test, pacer_interval, df, pkt_filter_cfg=ag.PKT_FILTER_RANDO
406
425
  if pkt_filter_cfg != ag.PKT_FILTER_RANDOM_FIRST_ARRIVING_PKT:
407
426
  for pkt_type in list(df[PACKET_TYPE].unique()):
408
427
  if ((pkt_filter_cfg & (1 << pkt_type)) == 0
409
- and not (is_ble5_test and test.internal_brg and pkt_type == ag.PKT_TYPE_BLE5_EXTENDED_TEMP_ADVANCED)):
428
+ and not (is_ble5_test and (test.internal_brg or is_bcc_running(test)) and pkt_type == ag.PKT_TYPE_BLE5_EXTENDED_TEMP_ADVANCED)):
410
429
  test.rc = TEST_FAILED
411
430
  test.add_reason(f"Tag is of packet type {pkt_type} which is turned off in packet_types_mask configuration!")
412
431
  return test
@@ -414,7 +433,10 @@ def pacing_analysis(test, pacer_interval, df, pkt_filter_cfg=ag.PKT_FILTER_RANDO
414
433
  # Verify the tags count according to simulation data and pkt_filter_cfg
415
434
  tags_count = len(list(df[TAG_ID].unique()))
416
435
  if test.data == DATA_SIMULATION and num_of_pixels:
417
- if pkt_filter_cfg == ag.PKT_FILTER_TEMP_AND_ADVANCED_PKTS or pkt_filter_cfg == ag.PKT_FILTER_TEMP_AND_DEBUG_PKTS:
436
+ if is_ble5_test and is_bcc_running(test):
437
+ # In ble5 bcc packet type 2 extended uploaded as is without splitting to ble4 packets
438
+ expected_tags_count = num_of_pixels
439
+ elif pkt_filter_cfg == ag.PKT_FILTER_TEMP_AND_ADVANCED_PKTS or pkt_filter_cfg == ag.PKT_FILTER_TEMP_AND_DEBUG_PKTS:
418
440
  expected_tags_count = num_of_pixels * 2
419
441
  elif pkt_filter_cfg == ag.PKT_FILTER_TEMP_ADVANCED_AND_DEBUG_PKTS:
420
442
  expected_tags_count = num_of_pixels * 3
@@ -440,16 +462,9 @@ def pacing_analysis(test, pacer_interval, df, pkt_filter_cfg=ag.PKT_FILTER_RANDO
440
462
  failed_tags += 1
441
463
  print(f"Tag {tag} with diff_time {list(pkts.timestamp.diff().div(1000))}, avg_pacer={avg_pacer} exceeds {PACER_INTERVAL_CEIL_THRESHOLD} maximum threshold!")
442
464
  if failed_tags/tags_count > 0.2: # Fail the test on ceil threshold only when more than 20 % tag failed
465
+ test.add_reason(f"{failed_tags}/{tags_count} tags with wrong time diff")
443
466
  test.rc = TEST_FAILED
444
467
 
445
- # PASS test if only 1 tag out of many failed - this could be an issue with the tag
446
- if tags_count >= PACER_INTERVAL_MIN_TAGS_COUNT and failed_tags <= PACER_INTERVAL_MAX_FAILED_TAGS:
447
- test.rc = TEST_PASSED
448
- # Addition to understand how many tags failed in total
449
- if test.rc == TEST_FAILED:
450
- test.add_reason(f"{failed_tags}/{tags_count} tags with wrong time diff")
451
- print(test.reason)
452
- return test
453
468
  return test
454
469
 
455
470
  def reboot_config_analysis(test, expected_hash, timeout=ACTION_LONG_TIMEOUT, ble_version=None, bl_version=None):
@@ -745,19 +760,6 @@ def brg_restore_defaults_check(test):
745
760
  print_update_wait()
746
761
  return test, revived, output
747
762
 
748
- def erase_sensors(test):
749
- module = eval_pkt(f'ModuleExtSensorsV{test.active_brg.api_version}')
750
- wltpkt = WltPkt(hdr=DEFAULT_HDR, pkt=eval_pkt(f'ModuleExtSensorsV{test.active_brg.api_version}')(brg_mac=test.active_brg.id_int, msg_type=ag.BRG_MGMT_MSG_TYPE_CFG_SET, seq_id=random.randrange(99),
751
- sensor0=0, sensor1=0))
752
- print("Erasing all sensors from BRG {}".format(test.active_brg.id_int))
753
- test = cert_config.brg_configure(test=test, cfg_pkt=wltpkt)[0]
754
-
755
- if test.rc == TEST_FAILED:
756
- test.add_reason("Failed to erase sensors! Didn't receive module ext sensors pkt")
757
- else:
758
- utPrint("SUCCESS! Module ext_sensors returned to default!", "GREEN")
759
- return test
760
-
761
763
  # Pwr Mgmt
762
764
  def brg_pwr_mgmt_turn_on(test):
763
765
  utPrint("Sending pwr_mgmt static mode configuration - 30 seconds ON, 60 seconds SLEEP!", "BLUE")
@@ -814,4 +816,58 @@ def value_check_if_y(test, received_value, stage):
814
816
  if 'y' != received_value.lower():
815
817
  test.rc = TEST_FAILED
816
818
  test.add_reason(f"{stage} failed")
817
- return test
819
+ return test
820
+
821
+ # Signal Indicator functions
822
+ def dual_polarization_ant_boards_get():
823
+ return [ag.BOARD_TYPE_MINEW_SINGLE_BAND_V0, ag.BOARD_TYPE_MINEW_DUAL_BAND_V0,
824
+ ag.BOARD_TYPE_ENERGOUS_V2, ag.BOARD_TYPE_ERM_V0, ag.BOARD_TYPE_ERM_V1,
825
+ ag.BOARD_TYPE_MINEW_POE_V0]
826
+
827
+ def exp_sig_ind_pkts(tx_brg, rx_brg, cycles):
828
+ if tx_brg.board_type in dual_polarization_ant_boards_get():
829
+ tx_brg_ant_polarization_num = 2
830
+ else:
831
+ tx_brg_ant_polarization_num = 1
832
+ if rx_brg.board_type in dual_polarization_ant_boards_get():
833
+ rx_brg_ant_polarization_num = 2
834
+ else:
835
+ rx_brg_ant_polarization_num = 1
836
+
837
+ expected = cycles * tx_brg_ant_polarization_num * rx_brg_ant_polarization_num
838
+ # Allow missing 1 pkt
839
+ return [expected - 1, expected]
840
+
841
+ def exp_sig_ind_pkts2(tx_brg, rx_brg, cycles):
842
+ if tx_brg.board_type in dual_polarization_ant_boards_get():
843
+ tx_brg_ant_polarization_num = 2
844
+ else:
845
+ tx_brg_ant_polarization_num = 1
846
+ if rx_brg.board_type in dual_polarization_ant_boards_get():
847
+ rx_brg_ant_polarization_num = 2
848
+ else:
849
+ rx_brg_ant_polarization_num = 1
850
+
851
+ expected = cycles * tx_brg_ant_polarization_num * rx_brg_ant_polarization_num
852
+ return expected
853
+
854
+ def sig_ind_pkts_fail_analysis(tx_brg, rx_brg, cycles, received_pkts):
855
+
856
+ expected = exp_sig_ind_pkts2(tx_brg, rx_brg, cycles)
857
+ print(f"Expected pkts: {expected}, Received pkts: {len(received_pkts)}")
858
+ # Allow missing 25% max
859
+ if int(0.75 * expected) <= len(received_pkts) <= int(1.25 * expected):
860
+ return False
861
+ return True
862
+
863
+ def get_all_sig_ind_pkts(test=None, rx_brg=None, tx_brg=None):
864
+ if rx_brg == test.brg1:
865
+ all_sensor_packets = cert_mqtt.get_all_brg1_ext_sensor_pkts(test=test)
866
+ elif rx_brg == test.brg0:
867
+ all_sensor_packets = cert_mqtt.get_all_sensor_pkts(test=test)
868
+ signal_ind_pkts = []
869
+ for p in all_sensor_packets:
870
+ if (p[SENSOR_UUID] == f"{ag.SENSOR_SERVICE_ID_SIGNAL_INDICATOR:06X}" and
871
+ p[BRIDGE_ID] == rx_brg.id_str and p[SENSOR_ID] == tx_brg.id_alias):
872
+ signal_ind_pkts.append(p)
873
+ return signal_ind_pkts
@@ -126,13 +126,28 @@ class WiliotPixelGen3Extended:
126
126
  adva-6 adi-2 hdr-7 nonce/pkt_id-4 uid-6 mic-6 payload0-8 payload1-8 """
127
127
  return self.adva + self.adi + self.hdr.dump() + self.get_pkt_id() + self.uid + self.mic + self.payload0 + self.payload1
128
128
 
129
+ class RawData:
130
+ """Represents Explicit Data. Can be sensors, tags or anything else"""
131
+ def __init__(self, raw):
132
+ self.raw = raw
133
+
134
+ def __repr__(self) -> str:
135
+ return f'RawPkt: {self.get_pkt()}'
136
+
137
+ def set_pkt_type(self, _):
138
+ pass
139
+ def get_pkt(self):
140
+ return self.raw
141
+
129
142
  class DataSimThread(threading.Thread):
130
- def __init__(self, test, num_of_pixels, duplicates, delay, pkt_types, pixels_type=GEN2):
143
+ def __init__(self, test, num_of_pixels, duplicates, delay, pkt_types, pixels_type=GEN2, pkts=[]):
131
144
  super().__init__()
132
145
  self.test = test
133
146
  self.num_of_pixels = num_of_pixels
134
- # Create pixels list
135
- if pixels_type == GEN2:
147
+ # Create data list
148
+ if pixels_type == RAW_DATA:
149
+ self.pixels = [RawData(p) for p in pkts]
150
+ elif pixels_type == GEN2:
136
151
  self.pixels = [WiliotPixelGen2() for _ in range(self.num_of_pixels)]
137
152
  elif pixels_type == GEN3:
138
153
  self.pixels = [WiliotPixelGen3() for _ in range(self.num_of_pixels)]
@@ -165,7 +180,9 @@ class DataSimThread(threading.Thread):
165
180
  pkt.set_pkt_type(pkt_type)
166
181
 
167
182
  # Set pkt_id, in Gen3 pkt_type_1 has pkt_id_0+1
168
- if type(pkt) == WiliotPixelGen3:
183
+ if type(pkt) == RawData:
184
+ pass
185
+ elif type(pkt) == WiliotPixelGen3:
169
186
  if pkt_type == 1:
170
187
  if self.pkt_types == [0,1]:
171
188
  pkt.pkt_id += 1
@@ -194,6 +211,7 @@ class DataSimThread(threading.Thread):
194
211
  write_to_data_sim_log_file(f"{pkt}" + " {}\n".format(datetime.datetime.now().strftime("%d/%m,%H:%M:%S.%f")[:-4]))
195
212
  actual_delay = max(self.delay, self.duplicates*(PIXEL_SIM_MIN_CYCLE))
196
213
  time.sleep(actual_delay/1000)
214
+
197
215
  def stop(self):
198
216
  """Stops the thread completely"""
199
217
  self._stop_event.set()
@@ -4,16 +4,17 @@ import importlib.metadata
4
4
  # BASE_DIR should be initiated in the same dir as brg_certificate.py
5
5
  BASE_DIR = os.path.dirname(os.path.abspath(__file__))
6
6
  # CERT_VERSION handling - local/PyPi
7
+ LOCAL_DEV = "local-dev"
7
8
  if hasattr(importlib.metadata,'packages_distributions') and "wiliot-certificate" in importlib.metadata.packages_distributions():
8
9
  CERT_VERSION = importlib.metadata.version("wiliot-certificate")
9
10
  else:
10
- CERT_VERSION = "local-dev"
11
+ CERT_VERSION = LOCAL_DEV
11
12
  CERT_MQTT_LOG_FILE = "cert_mqtt_log.json"
12
13
  DATA_SIM_LOG_FILE = "data_sim_log.txt"
13
14
  UT_RESULT_FILE_HTML = "results.html"
14
15
  UT_RESULT_FILE_PDF = "results.pdf"
15
16
  UT_RESULT_FILE = "results.html"
16
- UTILS_BASE_REL_PATH = "../../../utils"
17
+ UTILS_BASE_REL_PATH = "../../../utils"
17
18
 
18
19
  # GW defines
19
20
  GW_ID = "gatewayId"
@@ -56,6 +57,7 @@ WLT_SERVER = "wiliotServer"
56
57
  PACER_INTERVAL = "pacerInterval"
57
58
  OUTPUT_POWER_2_4 = "2.4GhzOutputPower"
58
59
  USE_STAT_LOC = "useStaticLocation"
60
+ LOCATION = "location"
59
61
  GW_ENERGY_PATTERN = "energizingPattern"
60
62
  VERSION = "version"
61
63
  WIFI_VERSION = "interfaceChipSwVersion"
@@ -105,6 +107,7 @@ DATA_REAL_TAGS = 'tags'
105
107
  GEN2 = 2
106
108
  GEN3 = 3
107
109
  GEN3_EXTENDED = 4
110
+ RAW_DATA = 5
108
111
 
109
112
  # Configurable brg fields' names by modules
110
113
  # common #
@@ -230,7 +233,7 @@ ACTION_SHORT_TIMEOUT = 5
230
233
  PACER_INTERVAL_MIN_TAGS_COUNT = 20
231
234
  PACER_INTERVAL_MAX_FAILED_TAGS = 2
232
235
  PACER_INTERVAL_THRESHOLD_HIGH = 0.90
233
- PACER_INTERVAL_CEIL_THRESHOLD = 1.1
236
+ PACER_INTERVAL_CEIL_THRESHOLD = 1.2
234
237
  PACER_INTERVAL_THRESHOLD = 0.80
235
238
  PACKETS_ECHO_OFF = 16
236
239
  TEST_PASSED = 0
@@ -265,11 +268,13 @@ GW_ONLY_TEST = "gwOnlyTest" # used for gw o
265
268
  INTERNAL_BRG = "internalBridge"
266
269
  PURPOSE = "purpose"
267
270
  MANDATORY = "mandatory"
271
+ MODULE = "module"
272
+ NAME = "name"
268
273
  DOCUMENTATION = "documentation"
269
274
  ALL_SUPPORTED_VALUES = "allSupportedValues"
270
- PRE_CONFIG = "Pre config"
275
+ PRE_CONFIG = "Pre Configuration"
271
276
  TEST_BODY = "Test Body"
272
- RESTORE_CONFIG = "Restore config"
277
+ RESTORE_CONFIG = "Restore Configuration"
273
278
 
274
279
  # test reasons
275
280
  NO_PARAMS_GIVEN = "No parameters given!"
@@ -215,12 +215,14 @@ def on_message(client, userdata, message):
215
215
  # GW SIMULATOR
216
216
  ##############################################
217
217
  def parse_uart_pkts(input, mqttc, custom_broker, gw_id, seq_id):
218
- if input.startswith("p6 "):
218
+ # 3 for p6, 12 for alias_brg_id, 62 for payload, 2 for rssi
219
+ if input.startswith("p6 ") and len(input) == (3 + 12 + 62 + 2):
219
220
  # p6 1234567898761E16C6FC0000EE02093E3C71BF6DFA3C006648001CB8003A730160000E010031
220
221
  pkt = UplinkPkt(gw_id, seq_id, input.split()[1])
221
222
  mqttc.publish(custom_broker[CUSTOM_BROKER_DATA_TOPIC], payload=json.dumps(pkt.dump(), indent=4))
222
223
  return True
223
- elif input.startswith("p7 "):
224
+ # 3 for p7, 12 for alias_brg_id, 78 for payload, 6 for side info, 2 for rssi
225
+ elif input.startswith("p7 ") and len(input) == (3 + 12 + 78 + 6 + 2):
224
226
  # p7 1234567898762616C6FC05000002093E3C71BF6DFA3C006648001CB8003A730160000E0100112233445566778831
225
227
  pkt = UplinkExtendedPkt(gw_id, seq_id, input.split()[1])
226
228
  mqttc.publish(custom_broker[CUSTOM_BROKER_DATA_TOPIC], payload=json.dumps(pkt.dump(), indent=4))
@@ -287,7 +287,7 @@ def get_undecrypted_data_pkts_count(mqttc):
287
287
  undecrypted += p.body_ex['undecrypted']
288
288
  return undecrypted
289
289
 
290
- def get_all_sensor_pkts(mqttc, test, is_embedded=False):
290
+ def get_all_sensor_pkts(test, is_embedded=False):
291
291
  all_sensor_pkts = couple_sensor_data_si_coupling(test)
292
292
  all_sensor_pkts = [p for p in all_sensor_pkts if test.active_brg.id_str == p[BRIDGE_ID] and (p[IS_EMBEDDED] == is_embedded)]
293
293
  return all_sensor_pkts
@@ -339,16 +339,17 @@ def count_pkt_id_duplications(test, all_sensor_data_pkts, all_sensor_side_info_p
339
339
  coupled_pkt[PKT_ID_CTR] = pkt_ids.count(_pkt_id)
340
340
  if coupled_pkt[PKT_ID_CTR] > SENSORS_DATA_SI_DUP:
341
341
  print(f"pkt_id {_pkt_id:08X}: {coupled_pkt[PKT_ID_CTR]} occurrences")
342
- test.reason = f'Warning: {coupled_pkt[PKT_ID_CTR]} sensor data and si with pkt id 0x{_pkt_id:08X}'
342
+ #TODO: logging print(debug)
343
+ # test.reason = f'Warning: {coupled_pkt[PKT_ID_CTR]} sensor data and si with pkt id 0x{_pkt_id:08X}'
343
344
 
344
- def get_all_brg1_ext_sensor_pkts(mqttc, test=None):
345
+ def get_all_brg1_ext_sensor_pkts(test=None):
345
346
  test.active_brg = test.brg1
346
- pkts = get_all_sensor_pkts(mqttc, test)
347
+ pkts = get_all_sensor_pkts(test)
347
348
  test.active_brg = test.brg0
348
349
  return pkts
349
350
 
350
- def get_all_custom_pkts(mqttc, test=None):
351
- return get_all_sensor_pkts(mqttc, test, is_embedded=True)
351
+ def get_all_custom_pkts(test=None):
352
+ return get_all_sensor_pkts(test, is_embedded=True)
352
353
 
353
354
  def get_all_mgmt_pkts(mqttc):
354
355
  all_data_pkts = get_all_data_pkts(mqttc)
@@ -22,6 +22,7 @@ color = lambda c, t : COLORS["BOLD"]+COLORS[c]+t+COLORS["ENDC"]
22
22
  pipeline_running = lambda : True if 'BITBUCKET_BUILD_NUMBER' in os.environ else False
23
23
  camelcase_to_title = lambda s: ' '.join(word.capitalize() for word in re.split('(?=[A-Z])', s))
24
24
  SEP = '\n' + '#'*100 + '\n'
25
+ SEP2 = '\n' + '#'*100 + '\n' + '#'*100 + '\n'
25
26
  WIL_CERT_TEXT = r'''
26
27
  __ _____ _ ___ ___ _____ ____ _____ ____ _____ ___ _____ ___ ____ _ _____ _____
27
28
  \ \ / /_ _| | |_ _/ _ \_ _| / ___| ____| _ \_ _|_ _| ___|_ _/ ___| / \|_ _| ____|
@@ -65,17 +66,23 @@ def mqtt_scan_wait(test, duration):
65
66
  i += 1
66
67
  print("\n")
67
68
 
69
+ def mqtt_scan_n_create_log_file(test, duration, phase):
70
+ test.mqttc.flush_pkts()
71
+ mqtt_scan_wait(test, duration=duration)
72
+ generate_log_file(test, phase)
73
+
68
74
  def print_update_wait(secs=1):
69
75
  sys.stdout.write(".")
70
76
  sys.stdout.flush()
71
77
  time.sleep(secs)
72
78
 
73
79
  def field_functionality_pass_fail_print(test, field, value=""):
74
- print_string = "{}={}".format(field, value)
80
+ print_string = f"{field}={value}"
75
81
  if value == "":
76
82
  print_string = str(field)
77
83
  if test.rc == TEST_FAILED:
78
84
  utPrint(print_string + " functionality failed!", "RED")
85
+ utPrint(test.reason, "RED")
79
86
  elif test.rc == TEST_SKIPPED:
80
87
  utPrint(print_string + " functionality skipped!", "WARNING")
81
88
  else:
@@ -127,6 +134,12 @@ def functionality_run_print(func):
127
134
  cert_mqtt.write_to_mqtt_log_file(txt)
128
135
  cert_data_sim.write_to_data_sim_log_file(txt)
129
136
 
137
+ def phase_run_print(func):
138
+ txt = f"{SEP2}==>> Phase {func}{SEP2}\n"
139
+ utPrint(txt, "CYAN")
140
+ cert_mqtt.write_to_mqtt_log_file(txt)
141
+ cert_data_sim.write_to_data_sim_log_file(txt)
142
+
130
143
 
131
144
  def generate_print_string(fields_and_values):
132
145
  list_to_print = []
@@ -36,19 +36,19 @@ def gw_cfg_pb(msg: dict):
36
36
  pb_msg.gatewayConfig.bleSwVersion = msg[BLE_VERSION]
37
37
 
38
38
  for key, val in msg[ADDITIONAL].items():
39
- # Skip GW_MODE since it doesn't exist today and harm the parsing in PB
40
- if GW_MODE == key:
39
+ # Skip GW_MODE since it doesn't exist today and harm the parsing in PB, and skip lat & lng to create duplicate values
40
+ if key == GW_MODE or key == LAT or key == LNG:
41
41
  continue
42
42
  pb_value = wpb.GatewayConfigValue()
43
- if isinstance(val, int):
43
+ if type(val) is int:
44
44
  pb_value.integerValue = val
45
- elif isinstance(val, float):
45
+ elif type(val) is float:
46
46
  pb_value.numberValue = val
47
- elif isinstance(val, str):
47
+ elif type(val) is str:
48
48
  pb_value.stringValue = val
49
- elif isinstance(val, bool):
49
+ elif type(val) is bool:
50
50
  pb_value.boolValue = val
51
- elif isinstance(val, dict) and key == ACL:
51
+ elif type(val) is dict and key == ACL:
52
52
  pb_value.aclValue.mode_allow = ACL_DENY_VALUE if msg[ADDITIONAL][ACL][ACL_MODE] == ACL_DENY else ACL_ALLOW_VALUE
53
53
  ids_bytes = [bytes.fromhex(id) for id in msg[ADDITIONAL][ACL][ACL_BRIDGE_IDS]]
54
54
  pb_value.aclValue.ids.extend(ids_bytes)