wiliot-certificate 1.3.0a1__py3-none-any.whl → 1.4.0a1__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 (184) hide show
  1. brg_certificate/__init__.py +0 -0
  2. brg_certificate/ag/energous_v0_defines.py +925 -0
  3. brg_certificate/ag/energous_v1_defines.py +931 -0
  4. brg_certificate/ag/energous_v2_defines.py +925 -0
  5. brg_certificate/ag/energous_v3_defines.py +925 -0
  6. brg_certificate/ag/energous_v4_defines.py +925 -0
  7. brg_certificate/ag/fanstel_lan_v0_defines.py +925 -0
  8. brg_certificate/ag/fanstel_lte_v0_defines.py +925 -0
  9. brg_certificate/ag/fanstel_wifi_v0_defines.py +925 -0
  10. brg_certificate/ag/minew_lte_v0_defines.py +925 -0
  11. brg_certificate/ag/wlt_cmd_if.html +102 -0
  12. brg_certificate/ag/wlt_types.html +6114 -0
  13. brg_certificate/ag/wlt_types_ag.py +7840 -0
  14. brg_certificate/ag/wlt_types_ag_jsons/brg2brg_ota.json +142 -0
  15. brg_certificate/ag/wlt_types_ag_jsons/brg2gw_hb.json +785 -0
  16. brg_certificate/ag/wlt_types_ag_jsons/brg2gw_hb_sleep.json +139 -0
  17. brg_certificate/ag/wlt_types_ag_jsons/calibration.json +394 -0
  18. brg_certificate/ag/wlt_types_ag_jsons/custom.json +515 -0
  19. brg_certificate/ag/wlt_types_ag_jsons/datapath.json +672 -0
  20. brg_certificate/ag/wlt_types_ag_jsons/energy2400.json +550 -0
  21. brg_certificate/ag/wlt_types_ag_jsons/energySub1g.json +595 -0
  22. brg_certificate/ag/wlt_types_ag_jsons/externalSensor.json +598 -0
  23. brg_certificate/ag/wlt_types_ag_jsons/interface.json +938 -0
  24. brg_certificate/ag/wlt_types_ag_jsons/powerManagement.json +1234 -0
  25. brg_certificate/ag/wlt_types_ag_jsons/side_info_sensor.json +105 -0
  26. brg_certificate/ag/wlt_types_ag_jsons/signal_indicator_data.json +77 -0
  27. brg_certificate/ag/wlt_types_ag_jsons/unified_echo_ext_pkt.json +61 -0
  28. brg_certificate/ag/wlt_types_ag_jsons/unified_echo_pkt.json +110 -0
  29. brg_certificate/brg_certificate.py +191 -0
  30. brg_certificate/brg_certificate_cli.py +47 -0
  31. brg_certificate/cert_common.py +828 -0
  32. brg_certificate/cert_config.py +395 -0
  33. brg_certificate/cert_data_sim.py +188 -0
  34. brg_certificate/cert_defines.py +337 -0
  35. brg_certificate/cert_gw_sim.py +285 -0
  36. brg_certificate/cert_mqtt.py +373 -0
  37. brg_certificate/cert_prints.py +181 -0
  38. brg_certificate/cert_protobuf.py +88 -0
  39. brg_certificate/cert_results.py +300 -0
  40. brg_certificate/cert_utils.py +358 -0
  41. brg_certificate/certificate_sanity_test_list.txt +36 -0
  42. brg_certificate/certificate_test_list.txt +43 -0
  43. brg_certificate/config/eclipse.json +10 -0
  44. brg_certificate/config/hivemq.json +10 -0
  45. brg_certificate/config/mosquitto.json +10 -0
  46. brg_certificate/config/mosquitto.md +95 -0
  47. brg_certificate/config/wiliot-dev.json +10 -0
  48. brg_certificate/restore_brg.py +59 -0
  49. brg_certificate/tests/calibration/interval_test/interval_test.json +13 -0
  50. brg_certificate/tests/calibration/interval_test/interval_test.py +28 -0
  51. brg_certificate/tests/calibration/output_power_test/output_power_test.json +13 -0
  52. brg_certificate/tests/calibration/output_power_test/output_power_test.py +28 -0
  53. brg_certificate/tests/calibration/pattern_test/pattern_test.json +13 -0
  54. brg_certificate/tests/calibration/pattern_test/pattern_test.py +70 -0
  55. brg_certificate/tests/datapath/adaptive_pacer_algo_test/adaptive_pacer_algo_test.json +13 -0
  56. brg_certificate/tests/datapath/adaptive_pacer_algo_test/adaptive_pacer_algo_test.py +76 -0
  57. brg_certificate/tests/datapath/num_of_tags_test/num_of_tags_test.json +13 -0
  58. brg_certificate/tests/datapath/num_of_tags_test/num_of_tags_test.py +83 -0
  59. brg_certificate/tests/datapath/output_power_test/output_power_test.json +13 -0
  60. brg_certificate/tests/datapath/output_power_test/output_power_test.py +27 -0
  61. brg_certificate/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.json +13 -0
  62. brg_certificate/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.py +43 -0
  63. brg_certificate/tests/datapath/pacer_interval_tags_count_test/pacer_interval_tags_count_test.json +13 -0
  64. brg_certificate/tests/datapath/pacer_interval_tags_count_test/pacer_interval_tags_count_test.py +63 -0
  65. brg_certificate/tests/datapath/pacer_interval_test/pacer_interval_test.json +13 -0
  66. brg_certificate/tests/datapath/pacer_interval_test/pacer_interval_test.py +50 -0
  67. brg_certificate/tests/datapath/pattern_test/pattern_test.json +13 -0
  68. brg_certificate/tests/datapath/pattern_test/pattern_test.py +28 -0
  69. brg_certificate/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.json +13 -0
  70. brg_certificate/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.py +51 -0
  71. brg_certificate/tests/datapath/pkt_filter_gen3_test/pkt_filter_gen3_test.json +13 -0
  72. brg_certificate/tests/datapath/pkt_filter_gen3_test/pkt_filter_gen3_test.py +54 -0
  73. brg_certificate/tests/datapath/pkt_filter_test/pkt_filter_test.json +13 -0
  74. brg_certificate/tests/datapath/pkt_filter_test/pkt_filter_test.py +55 -0
  75. brg_certificate/tests/datapath/rssi_threshold_test/rssi_threshold_test.json +13 -0
  76. brg_certificate/tests/datapath/rssi_threshold_test/rssi_threshold_test.py +73 -0
  77. brg_certificate/tests/datapath/rx_channel_test/rx_channel_test.json +13 -0
  78. brg_certificate/tests/datapath/rx_channel_test/rx_channel_test.py +41 -0
  79. brg_certificate/tests/datapath/rx_rate_gen2_test/rx_rate_gen2_test.json +21 -0
  80. brg_certificate/tests/datapath/rx_rate_gen2_test/rx_rate_gen2_test.py +184 -0
  81. brg_certificate/tests/datapath/rx_rate_gen3_test/rx_rate_gen3_test.json +21 -0
  82. brg_certificate/tests/datapath/rx_rate_gen3_test/rx_rate_gen3_test.py +210 -0
  83. brg_certificate/tests/datapath/stress_gen3_test/stress_gen3_test.json +30 -0
  84. brg_certificate/tests/datapath/stress_gen3_test/stress_gen3_test.py +203 -0
  85. brg_certificate/tests/datapath/stress_test/stress_test.json +30 -0
  86. brg_certificate/tests/datapath/stress_test/stress_test.py +210 -0
  87. brg_certificate/tests/datapath/tx_repetition_algo_test/tx_repetition_algo_test.json +13 -0
  88. brg_certificate/tests/datapath/tx_repetition_algo_test/tx_repetition_algo_test.py +113 -0
  89. brg_certificate/tests/datapath/tx_repetition_test/tx_repetition_test.json +13 -0
  90. brg_certificate/tests/datapath/tx_repetition_test/tx_repetition_test.py +79 -0
  91. brg_certificate/tests/edge_mgmt/actions_test/actions_test.json +13 -0
  92. brg_certificate/tests/edge_mgmt/actions_test/actions_test.py +432 -0
  93. brg_certificate/tests/edge_mgmt/brg2brg_ota_ble5_test/brg2brg_ota_ble5_test.json +13 -0
  94. brg_certificate/tests/edge_mgmt/brg2brg_ota_ble5_test/brg2brg_ota_ble5_test.py +94 -0
  95. brg_certificate/tests/edge_mgmt/brg2brg_ota_test/brg2brg_ota_test.json +13 -0
  96. brg_certificate/tests/edge_mgmt/brg2brg_ota_test/brg2brg_ota_test.py +87 -0
  97. brg_certificate/tests/edge_mgmt/leds_test/leds_test.json +13 -0
  98. brg_certificate/tests/edge_mgmt/leds_test/leds_test.py +210 -0
  99. brg_certificate/tests/edge_mgmt/ota_test/ota_test.json +13 -0
  100. brg_certificate/tests/edge_mgmt/ota_test/ota_test.py +83 -0
  101. brg_certificate/tests/edge_mgmt/stat_test/stat_test.json +13 -0
  102. brg_certificate/tests/edge_mgmt/stat_test/stat_test.py +48 -0
  103. brg_certificate/tests/energy2400/duty_cycle_test/duty_cycle_test.json +13 -0
  104. brg_certificate/tests/energy2400/duty_cycle_test/duty_cycle_test.py +26 -0
  105. brg_certificate/tests/energy2400/output_power_test/output_power_test.json +13 -0
  106. brg_certificate/tests/energy2400/output_power_test/output_power_test.py +27 -0
  107. brg_certificate/tests/energy2400/pattern_test/pattern_test.json +13 -0
  108. brg_certificate/tests/energy2400/pattern_test/pattern_test.py +28 -0
  109. brg_certificate/tests/energy2400/signal_indicator_ble5_test/signal_indicator_ble5_test.json +13 -0
  110. brg_certificate/tests/energy2400/signal_indicator_ble5_test/signal_indicator_ble5_test.py +398 -0
  111. brg_certificate/tests/energy2400/signal_indicator_sub1g_2_4_test/signal_indicator_sub1g_2_4_test.json +13 -0
  112. brg_certificate/tests/energy2400/signal_indicator_sub1g_2_4_test/signal_indicator_sub1g_2_4_test.py +153 -0
  113. brg_certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.json +13 -0
  114. brg_certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.py +264 -0
  115. brg_certificate/tests/energy_sub1g/duty_cycle_test/duty_cycle_test.json +13 -0
  116. brg_certificate/tests/energy_sub1g/duty_cycle_test/duty_cycle_test.py +27 -0
  117. brg_certificate/tests/energy_sub1g/pattern_test/pattern_test.json +13 -0
  118. brg_certificate/tests/energy_sub1g/pattern_test/pattern_test.py +26 -0
  119. brg_certificate/tests/energy_sub1g/signal_indicator_functionality_test/signal_indicator_functionality_test.json +13 -0
  120. brg_certificate/tests/energy_sub1g/signal_indicator_functionality_test/signal_indicator_functionality_test.py +397 -0
  121. brg_certificate/tests/energy_sub1g/signal_indicator_test/signal_indicator_test.json +13 -0
  122. brg_certificate/tests/energy_sub1g/signal_indicator_test/signal_indicator_test.py +27 -0
  123. brg_certificate/wltPb_pb2.py +72 -0
  124. brg_certificate/wltPb_pb2.pyi +227 -0
  125. brg_certificate/wlt_types.py +114 -0
  126. gw_certificate/api/extended_api.py +7 -1531
  127. gw_certificate/api_if/200/data.json +106 -0
  128. gw_certificate/api_if/200/logs.json +12 -0
  129. gw_certificate/api_if/200/status.json +47 -0
  130. gw_certificate/api_if/201/data.json +98 -0
  131. gw_certificate/api_if/201/logs.json +12 -0
  132. gw_certificate/api_if/201/status.json +53 -0
  133. gw_certificate/api_if/202/data.json +83 -0
  134. gw_certificate/api_if/202/logs.json +12 -0
  135. gw_certificate/api_if/202/status.json +60 -0
  136. gw_certificate/api_if/203/data.json +85 -0
  137. gw_certificate/api_if/203/logs.json +12 -0
  138. gw_certificate/api_if/203/status.json +63 -0
  139. gw_certificate/api_if/204/data.json +85 -0
  140. gw_certificate/api_if/204/logs.json +12 -0
  141. gw_certificate/api_if/204/status.json +63 -0
  142. gw_certificate/api_if/205/data.json +85 -0
  143. gw_certificate/api_if/205/logs.json +12 -0
  144. gw_certificate/api_if/205/status.json +63 -0
  145. gw_certificate/api_if/api_validation.py +0 -2
  146. gw_certificate/common/analysis_data_bricks.py +18 -1413
  147. gw_certificate/common/debug.py +0 -21
  148. gw_certificate/common/utils.py +1 -212
  149. gw_certificate/common/utils_defines.py +0 -87
  150. gw_certificate/gw_certificate.py +9 -7
  151. gw_certificate/gw_certificate_cli.py +39 -23
  152. gw_certificate/interface/4.4.52_app.zip +0 -0
  153. gw_certificate/interface/4.4.52_sd_bl_app.zip +0 -0
  154. gw_certificate/interface/ble_simulator.py +0 -32
  155. gw_certificate/interface/if_defines.py +1 -0
  156. gw_certificate/interface/mqtt.py +96 -19
  157. gw_certificate/interface/nrfutil-linux +0 -0
  158. gw_certificate/interface/nrfutil-mac +0 -0
  159. gw_certificate/interface/nrfutil.exe +0 -0
  160. gw_certificate/interface/pkt_generator.py +0 -82
  161. gw_certificate/interface/uart_if.py +73 -43
  162. gw_certificate/templates/results.html +1 -1
  163. gw_certificate/tests/__init__.py +1 -2
  164. gw_certificate/tests/actions.py +134 -9
  165. gw_certificate/tests/connection.py +10 -5
  166. gw_certificate/tests/downlink.py +2 -4
  167. gw_certificate/tests/generic.py +62 -12
  168. gw_certificate/tests/registration.py +78 -27
  169. gw_certificate/tests/static/generated_packet_table.py +12 -48
  170. gw_certificate/tests/static/packet_table.csv +10048 -10048
  171. gw_certificate/tests/static/references.py +2 -1
  172. gw_certificate/tests/static/uplink_defines.py +0 -7
  173. gw_certificate/tests/throughput.py +7 -12
  174. gw_certificate/tests/uplink.py +83 -43
  175. {wiliot_certificate-1.3.0a1.dist-info → wiliot_certificate-1.4.0a1.dist-info}/METADATA +59 -8
  176. wiliot_certificate-1.4.0a1.dist-info/RECORD +198 -0
  177. {wiliot_certificate-1.3.0a1.dist-info → wiliot_certificate-1.4.0a1.dist-info}/WHEEL +1 -1
  178. wiliot_certificate-1.4.0a1.dist-info/entry_points.txt +3 -0
  179. wiliot_certificate-1.4.0a1.dist-info/top_level.txt +2 -0
  180. gw_certificate/interface/packet_error.py +0 -22
  181. wiliot_certificate-1.3.0a1.dist-info/RECORD +0 -51
  182. wiliot_certificate-1.3.0a1.dist-info/entry_points.txt +0 -2
  183. wiliot_certificate-1.3.0a1.dist-info/top_level.txt +0 -1
  184. {wiliot_certificate-1.3.0a1.dist-info → wiliot_certificate-1.4.0a1.dist-info}/LICENSE +0 -0
@@ -1,6 +1,5 @@
1
1
  import datetime
2
2
  import logging
3
- import os
4
3
  import colorama
5
4
  import tabulate
6
5
  import pprint
@@ -41,23 +40,3 @@ def debug_print(txt, pretty=False, center=False, tab=False, color=None, enable=T
41
40
  log.info(txt)
42
41
  else:
43
42
  print(datetime.datetime.now().strftime("[%d/%m/%Y, %H:%M:%S]: ") + txt)
44
-
45
- def is_databricks():
46
- """returns if running in databricks"""
47
- try:
48
- get_ipython().__class__.__name__
49
- return True
50
- except NameError:
51
- return False
52
-
53
-
54
- def is_databricks():
55
- try:
56
- from IPython import get_ipython
57
- if "IPKernelApp" not in get_ipython().config:
58
- return False
59
- if "VSCODE_PID" in os.environ:
60
- return False
61
- return True
62
- except Exception as e:
63
- return False
@@ -1,219 +1,8 @@
1
+
1
2
  # External libraries
2
- import math
3
- import pandas as pd
4
- import numpy as np
5
3
  import datetime
6
- from collections import defaultdict
7
-
8
- from gw_certificate.common.debug import is_databricks
9
-
10
- try:
11
- from zoneinfo import ZoneInfo # will run only in python 3.9+
12
- except ImportError:
13
- from backports.zoneinfo import ZoneInfo # backport to python < 3.9
14
-
15
- # CSV Parsing
16
- def get_ref_tags(csv_filepath):
17
- # TODO - fix to insert header if not given
18
- """
19
- returns an array of tags externalIds from a csv including one column of all the tags
20
- :type csv_filepath: string
21
- :param csv_filepath: filepath to csv with one column including all the tags
22
- output type: array
23
- output param: array of tags externalIds from a csv
24
- """
25
- tags_list = pd.read_csv(csv_filepath)
26
- tags_list = tags_list.to_dict()
27
- res = defaultdict(list)
28
- for key in tags_list.keys():
29
- for idx in tags_list[key]:
30
- if type(tags_list[key][idx]) == str and len(tags_list[key][idx]) == 31:
31
- res[key].append(tags_list[key][idx])
32
- return res
33
-
34
- def get_bridges_from_csv(csv_filepath):
35
- """
36
- :type csv_filepath: string
37
- :param csv_filepath: bridges names csv file path
38
- """
39
- if csv_filepath is None:
40
- return None
41
- bridges_df = pd.read_csv(csv_filepath)
42
- zones_dict = bridges_df.to_dict('list')
43
- return zones_dict
44
4
 
45
5
  # Date & Time Related
46
- def convert_datetime_to_timestamp(year=2022, month=1, day=1, hour=0, minute=0, seconds=0, micro_secs=0,
47
- hours_from_utc=0):
48
- """
49
- returns the timestamp of Israeli datetime
50
- :type year: int
51
- :param year: year of desired datetime
52
- :type month: int
53
- :param month: month of desired datetime
54
- :type day: int
55
- :param day: day of desired datetime
56
- :type hour: int
57
- :param hour: hour of desired datetime
58
- :type minute: int
59
- :param minute: minute of desired datetime
60
- :type seconds: int
61
- :param seconds: seconds of desired datetime
62
- :type micro_secs: int
63
- :param micro_secs: micro seconds of desired datetime
64
- :type hours_from_utc: int
65
- :param hours_from_utc: hours difference from UTC timezone
66
- :returns: timestamp in UTC
67
- """
68
-
69
- dt = datetime.datetime(year, month, day, hour, minute, seconds, micro_secs)
70
- # getting the timestamp
71
- ts = datetime.datetime.timestamp(dt)
72
- # if runs in data bricks - subtract hours_from_utc hours to transfer to relevant time zone
73
- if is_databricks():
74
- ts = ts - 3600 * hours_from_utc
75
- # convert to ms
76
- ts_in_ms = math.ceil(ts * 1000)
77
- return ts_in_ms
78
-
79
- def mstimestamp_to_timezone(timestamp, timezone='Israel', milli=True, hour=True, return_datetime=False):
80
- """
81
- :type timestamp: float / str / int
82
- :param timestamp: millisecond timestamp
83
- :type timezone: str
84
- :param timezone: ZoneInfo Timestamp name, defaults to Israel
85
- :type milli: bool
86
- :param milli: if false, omits millisecond from result
87
- :type return_datetime: bool
88
- :param return_datetime: whether to return datetime
89
- :rtype: str | datetime
90
- :return: String of datetime in timezone | datetime object in timezone
91
- """
92
- server_timezone = ZoneInfo("Etc/UTC")
93
- chosen_timezone = ZoneInfo(timezone)
94
- if timestamp == 0 or np.isnan(timestamp):
95
- return None
96
- try:
97
- timestamp = float(timestamp)
98
- except ValueError as e:
99
- raise ValueError(f'Timestamp {timestamp} could not be converted to float!' + e)
100
- dt = datetime.datetime.fromtimestamp(timestamp / 1000)
101
- dt.replace(tzinfo=server_timezone)
102
- if return_datetime:
103
- return dt.astimezone(chosen_timezone)
104
- if hour:
105
- if milli:
106
- dt = dt.astimezone(chosen_timezone).strftime('%Y-%m-%d %H:%M:%S.%f %Z')
107
- else:
108
- dt = dt.astimezone(chosen_timezone).strftime('%Y-%m-%d %H:%M:%S %Z')
109
- else:
110
- dt = dt.astimezone(chosen_timezone).strftime('%Y-%m-%d')
111
- return dt
112
-
113
- def convert_timestamp_to_datetime(timestamp, up_to_sec_res=False):
114
- """
115
- converts timestamp to datetime
116
- :param timestamp: timestamp
117
- :type timestamp: str
118
- :param up_to_sec_res: if true will return the datetime in a resolution of seconds
119
- :type up_to_sec_res: bool
120
- """
121
- num_digits = len(str(int(float(timestamp))))
122
- timestamp = float(timestamp)
123
- timestamp = timestamp * math.pow(10, ((num_digits*-1) + 10))
124
- dt = datetime.datetime.fromtimestamp(float(timestamp))
125
- if up_to_sec_res:
126
- dt = dt - datetime.timedelta(microseconds=dt.microsecond)
127
- return dt
128
-
129
- def datetime_to_timezone(dt, timezone='Israel'):
130
- return dt.astimezone(ZoneInfo(timezone))
131
-
132
-
133
6
  def current_timestamp():
134
7
  """returns current timestamp (UTC) in milliseconds"""
135
8
  return datetime.datetime.timestamp(datetime.datetime.now()) * 1000
136
-
137
-
138
- def timestamp_timedelta(method=False, **kwargs):
139
- now = datetime.datetime.now()
140
- if method:
141
- calc = now + datetime.timedelta(**kwargs)
142
- else:
143
- calc = now - datetime.timedelta(**kwargs)
144
- return calc.timestamp() * 1000
145
-
146
-
147
- def string_to_bool(string):
148
- if string == 'True':
149
- return True
150
- if string == 'False':
151
- return False
152
- else:
153
- raise ValueError('Value not equal to True or False!')
154
-
155
-
156
- def filter_namedtuple(namedtuple, keys, val_type=int):
157
- """
158
- gets named tuple (from DataFrame.itertuples) and returns a dictionary of filtered keys from named tuple,
159
- filtering out keys which have NaN values
160
- :type namedtuple: Named Tuple
161
- :param namedtuple: named tuple to filter
162
- :type keys: list
163
- :param keys: keys to filter from named tuple
164
- :rtype: dict
165
- :return: dictionary of keys and values filtered from named tuple
166
- """
167
- d = dict()
168
- for k in keys:
169
- try:
170
- val = getattr(namedtuple, k)
171
- if pd.isna(val):
172
- continue
173
- if str(val).replace('.', '').isnumeric():
174
- val = val_type(val)
175
- d[k] = val
176
- except AttributeError:
177
- continue
178
- return d
179
-
180
-
181
- def parse_si_packet(df):
182
- def from_twos_complement(value):
183
- if value>(pow(2,7)):
184
- return value-(1<<8)
185
- else:
186
- return value
187
-
188
- df['band'] = df.rawPacket.apply(lambda x: x[16:18])=="01"
189
- dfn = pd.DataFrame()
190
- # add column of output power
191
- for band in df['band'].unique():
192
- tmp = df[df['band']==band]
193
- if band: # sub1g is 8 bit positive number
194
- tmp = tmp.assign(tx_outputpower=tmp.rawPacket.apply(lambda x: int(x[14:16], 16)))
195
- else: # ble is 8 bit negative 2's complement number
196
- tmp = tmp.assign(tx_outputpower=tmp.rawPacket.apply(lambda x: from_twos_complement(int(x[14:16], 16))))
197
- dfn = pd.concat([dfn, tmp])
198
- # add columns of tx and rx antena
199
- df['tx_ant'] = df.rawPacket.apply(lambda x: x[18:20])
200
- df['rx_ant'] = df.rawPacket.apply(lambda x: x[20:22])
201
- df['rssi'] = -df['rssi']
202
- return df
203
-
204
-
205
- def match_bridge_ids(bridge_ids, alias_bridge_ids):
206
- # Convert hex IDs to integers
207
- bridge_ints = {bid: int(bid, 16) for bid in bridge_ids}
208
- alias_ints = {abid: int(abid, 16) for abid in alias_bridge_ids}
209
- matches = {}
210
- for alias, alias_int in alias_ints.items():
211
- cnt = 0
212
- for bridge, bridge_int in bridge_ints.items():
213
- # Check if aliasBridgeId matches bridgeId exactly, or with the first bit modified
214
- if (alias_int == bridge_int or alias_int == (bridge_int | 0xC00000000000)):
215
- cnt = cnt + 1
216
- matches[alias] = bridge
217
- if alias not in matches:
218
- matches[alias] = None
219
- return matches
@@ -1,102 +1,15 @@
1
1
  # Brownout / OTA Defines
2
2
  SEP = "#" * 50
3
- MINUTES_TO_BROWN_OUT = 5
4
- TABLES_SYNC_MINUTES = 70
5
- MINUTES_FOR_LC = 2
6
- LATEST_FW = "1.9.0"
7
- SINGLE_BAT_BO_DICT = {"2.4GhzOutputPower": 2, 'txPeriodMs': 75, 'rxTxPeriodMs': 255, 'energyPattern': 25}
8
- DUAL_BAT_BO_DICT = {"2.4GhzOutputPower": 2, 'txPeriodMs': 75, 'rxTxPeriodMs': 255, 'energyPattern': 50}
9
- LEGACY_BO_DICT = {'energyPattern': 17, 'rxTxPeriodMs': 99}
10
- # BO_DICT_PREV = {'energyPattern': 36}
11
3
  BO_DICT = {
12
4
  'datapath': {'config': {'pktFilter': 'Disable forwarding'}},
13
5
  'energy2400': {'config': {'energyPattern2400': 'No Energizing'}},
14
6
  'energySub1g': {'config': {'sub1gEnergyPattern': 'No Energizing'}},
15
7
  'calibration': {'config': {'calibPattern': 'Disable calibration beaconing'}}
16
8
  }
17
-
18
-
19
- # Configuration tool / change Brg/Gw Defines
20
- ATC_GW_CONFIG = {
21
- 'wifi': {'gwDataSrc': 'Bridges only (ch38)',
22
- 'pacerInterval': 60,
23
- 'txPeriodMs': 3,
24
- 'rxTxPeriodMs': 90,
25
- 'energizingPattern': 17,
26
- "2.4GhzOutputPower": 8},
27
- 'lte': {},
28
- 'mobile': {},
29
- 'unknown': {}}
30
- ATC_REGION_DICT = {
31
- 'IL': {
32
- 'sub1GhzFrequency': 919100,
33
- 'energyPattern': 50
34
- }
35
- }
36
-
37
- energy_patterns = [18, 25, 26]
38
- energy_patterns_db = {17: 50, 18: 51, 25: 56, 26: 57}
39
- gw_rx_channel = {17: "Bridges only (ch39)", 18: "Bridges only (ch38)", 24: "Bridges only (ch39)",
40
- 25: "Bridges only (ch39)", 26: "Bridges only (ch39)", 51: "Bridges only (ch38)",
41
- 55: "Bridges only (ch39)", 56: "Bridges only (ch39)", 57: "Bridges only (ch39)",
42
- 50: "Bridges only (ch39)"}
43
- shifted_brg_energy_patterns = [33, 34, 35, 58, 59, 60]
44
- shifted_gw_energizing_patterns = [33]
45
- lc_output_powers = [14, 17, 20, 23, 26, 29, 32]
46
- fp_duty_cycles = [0.1, 0.15, 0.2, 0.25, 0.3]
47
-
48
- # Power Mgmt
49
- EXIT_POWER_MGMT_GW_DICT = {
50
- 'gwDataSrc': gw_rx_channel[17],
51
- 'txPeriodMs': 3,
52
- 'rxTxPeriodMs': 15,
53
- 'energizingPattern': 17,
54
- 'gwMgmtMode': 'active'
55
- }
56
- KEEP_ALIVE_PERIOD = 30 # seconds
57
- KEEP_ALIVE_SCAN_DURATION = 300 # in millisecond
58
- SEC_TO_SEND = 2
59
9
  BROADCAST_DST_MAC = 'FFFFFFFFFFFF'
60
10
 
61
11
  colors = ['red', 'blue', 'yellow', 'cyan', 'green', 'brown', 'orange', 'pink', 'purple', 'black']
62
12
 
63
13
  # Test Tool
64
- WH_OWNER = '832742983939'
65
- INIT_GW_CONFIG = {
66
- 'wifi':{'gwDataSrc': gw_rx_channel[18],
67
- 'gwDataMode': gw_rx_channel[18]},
68
- 'lte':{},
69
- 'mobile':{},
70
- 'unknown':{}}
71
- INIT_BRG_CONFIG = {
72
- 'calibration': {'config': {'calibPattern': 'Disable calibration beaconing', 'calibInterval': 10, 'calibOutputPower': 2}},
73
- 'externalSensor': {'config': {'adType0': 0, 'adType1': 0, 'uuidLsb0': 0, 'uuidLsb1': 0, 'uuidMsb0': 0, 'uuidMsb1': 0, 'sensor0Scramble': 0, 'sensor1Scramble': 0}},
74
- 'energy2400': {'config': {'dutyCycle': 30, 'outputPower': 2, 'energyPattern2400': 'No Energizing'}},
75
- 'datapath': {'config': {'pktFilter': 'Disable forwarding', 'txRepetition': 0, 'adaptivePacer': 0, 'pacerInterval': 15, 'unifiedEchoPkt': 0, 'commOutputPower': 2, 'globalPacingGroup': 0}},
76
- 'powerManagement': {'config': {'staticLedsOn': 1, 'dynamicLedsOn': 1, 'staticOnDuration': 0, 'dynamicOnDuration': 0, 'staticKeepAliveScan': 300, 'staticSleepDuration': 0, 'dynamicKeepAliveScan': 300, 'dynamicSleepDuration': 0, 'staticKeepAlivePeriod': 20, 'dynamicKeepAlivePeriod': 20}},
77
- 'energySub1g': {'config': {'cycle': 15, 'dutyCycle': 30, 'outputPower': 29, 'sub1gEnergyPattern': 'No Energizing'}},
78
- }
79
-
80
- # prev init cfg for prev brgs version (lower then version 4.0)
81
- INIT_BRG_PREV_CONFIG = {
82
- 'energy2400': {'config': {'txPeriod': 5, 'rxTxPeriod': 15, 'outputPower': 2, 'energyPattern': 36}},
83
- 'datapath': {'config': {'txRepetition': 0, 'pacerInterval': 15, 'globalPacingGroup': 0}},
84
- 'energySub1g': {'config': {'frequency': 919100, 'outputPower': 32}}
85
- }
86
-
87
- BRG_KEYS = ['calibPattern','calibInterval','calibOutputPower',
88
- 'adType0','adType1','uuidLsb0','uuidLsb1','uuidMsb0','uuidMsb1','sensor0Scramble','sensor1Scramble',
89
- 'txPeriod','rxTxPeriod','2.4GhzOutputPower','energyPattern','sub1GhzFrequency','sub1GhzOutputPower',
90
- 'dutyCycle','outputPower','energyPattern2400','pktFilter','txRepetition','adaptivePacer','pktTypesMask',
91
- 'pacerInterval','unifiedEchoPkt','commOutputPower','globalPacingGroup',
92
- 'staticLedsOn','dynamicLedsOn','staticOnDuration','dynamicOnDuration','staticKeepAliveScan','staticSleepDuration',
93
- 'dynamicKeepAliveScan','dynamicSleepDuration','staticKeepAlivePeriod','dynamicKeepAlivePeriod',
94
- 'cycle','dutyCycle','outputPower','sub1gEnergyPattern']
95
- GW_KEYS = ['gwDataSrc', 'gwDataMode']
96
14
  GW_DATA_SRC = 'gwDataSrc'
97
15
  GW_DATA_MODE = 'gwDataMode'
98
- GW_KEYS_THIN = ['dataCoupling', 'useStaticLocation', 'gwMgmtMode']
99
- GW_SHARED_KEYS = ['gw_2.4GhzOutputPower', 'gw_txPeriodMs', 'gw_pacerInterval', 'gw_energizingPattern',
100
- 'gw_rxTxPeriodMs']
101
- TIME_COLUMNS = ['endTimestamp', 'startTimestamp', 'receivedTestConfigTimestamp']
102
- TEST_CONFIG_COLUMNS = ['testId', 'testTimeMins', 'gatewaysIncluded', 'bridgesIncluded']
@@ -41,16 +41,17 @@ class TemplateEngine:
41
41
 
42
42
 
43
43
  class GWCertificate:
44
- def __init__(self, gw_id, owner_id, tests:list = TESTS_DEFAULT, topic_suffix='', update_fw=False, stress_pps=None, aggregation_time=0, env='prod'):
44
+ def __init__(self, gw_id, owner_id, actions:list, tests:list, topic_suffix='', update_fw=False, stress_pps=None,
45
+ aggregation_time=0, env='prod'):
45
46
  # Runtime
46
47
  self.env_dirs = WiliotDir()
47
48
  self.current_datetime = datetime.datetime.now().strftime('%Y%m%d_%H%M%S')
48
49
  self.certificate_dir = os.path.join(self.env_dirs.get_wiliot_root_app_dir(), 'gw-certificate', self.current_datetime)
49
50
  self.env_dirs.create_dir(self.certificate_dir)
50
- self.start_timestamp = initialize_logger(self.certificate_dir)
51
- self.logger_filepath = os.path.join(self.certificate_dir, f'{self.start_timestamp}.log')
52
- self.mqtt_logger_filepath = os.path.join(self.certificate_dir, f'{self.start_timestamp}_mqtt.log')
53
- self.sniffer_logger_filepath = os.path.join(self.certificate_dir, f'{self.start_timestamp}_sniffer.log')
51
+ self.logger_filename = initialize_logger(self.certificate_dir)
52
+ self.logger_filepath = os.path.join(self.certificate_dir, f'{self.logger_filename}.log')
53
+ self.mqtt_logger_filepath = os.path.join(self.certificate_dir, f'{self.logger_filename}_mqtt.log')
54
+ self.sniffer_logger_filepath = os.path.join(self.certificate_dir, f'{self.logger_filename}_sniffer.log')
54
55
  self.result_html_path = os.path.join(self.certificate_dir, f'results_{self.current_datetime}.html')
55
56
  self.template_engine = TemplateEngine()
56
57
  self.env = env
@@ -66,6 +67,7 @@ class GWCertificate:
66
67
  self.gw_capabilities = GWCapabilities()
67
68
  self.stress_pps = stress_pps
68
69
  self.aggregation_time = aggregation_time
70
+ self.actions = actions
69
71
 
70
72
  # UART-related. Require only when running tests that need it
71
73
  self.use_uart = not all(test in TESTS_NO_UART for test in tests)
@@ -74,11 +76,10 @@ class GWCertificate:
74
76
  self.uart_comports = get_uart_ports()
75
77
  debug_print(f'UART Ports:{self.uart_comports}')
76
78
  if len(self.uart_comports) < 1:
77
- raise GWCertificateError('A Wiliot tester board must be connected to USB!')
79
+ raise GWCertificateError('A Wiliot certification kit must be connected to USB!')
78
80
 
79
81
  for port in self.uart_comports:
80
82
  try:
81
- # TODO Fix UARTInterface firmware update and then call it with the flag set to True
82
83
  self.uart = UARTInterface(port, update_fw=update_fw)
83
84
  break
84
85
  except UARTError as e:
@@ -102,6 +103,7 @@ class GWCertificate:
102
103
  # if (type(test) == DownlinkTest and self.gw_capabilities.downlinkSupported == False):
103
104
  # debug_print(f'# Skipping {type(test)} since it is not a supported capability. #')
104
105
  # continue
106
+ test.prepare_test()
105
107
  test.run()
106
108
  test.end_test()
107
109
 
@@ -2,32 +2,37 @@
2
2
  import time
3
3
  from argparse import ArgumentParser
4
4
 
5
+ from gw_certificate.common.debug import debug_print
5
6
  from gw_certificate.gw_certificate import GWCertificate, GW_CERT_VERSION
6
- from gw_certificate.tests import TESTS, TESTS_DEFAULT
7
- from gw_certificate.tests.throughput import STRESS_DEFAULT_PPS
7
+ from gw_certificate.tests import TESTS
8
+ from gw_certificate.tests.actions import ACTIONS_STAGES
9
+ from gw_certificate.tests.throughput import STRESS_DEFAULT_PPS, StressTest
8
10
  from gw_certificate.tests.registration import REG_CERT_OWNER_ID, RegistrationTest
9
11
  from gw_certificate.tests.uplink import UplinkTest
10
- from gw_certificate.tests.throughput import StressTest
12
+
13
+ def filter_by_args(args_list, list_to_filter):
14
+ chosen_list = []
15
+ for entry in list_to_filter:
16
+ for arg in args_list:
17
+ if arg in entry.__name__.lower() and entry not in chosen_list:
18
+ chosen_list.append(entry)
19
+ return chosen_list
11
20
 
12
21
  def filter_tests(tests_names):
13
- chosen_tests = []
14
- if tests_names == []:
15
- return TESTS_DEFAULT
16
- for test_class in TESTS:
17
- for test_name in tests_names:
18
- if test_name in test_class.__name__.lower() and test_class not in chosen_tests:
19
- chosen_tests.append(test_class)
20
- return chosen_tests
22
+ return filter_by_args(tests_names, TESTS)
23
+
24
+ def filter_actions(actions_names):
25
+ return filter_by_args(actions_names, ACTIONS_STAGES)
21
26
 
22
27
  def main():
23
28
  usage = (
24
29
  "usage: wlt-gw-certificate [-h] -owner OWNER -gw GW\n"
25
30
  f" [-tests {{connection, uplink, downlink, stress}}] [-update] [-pps {STRESS_DEFAULT_PPS}]\n"
26
- " [-agg AGG] [-env {prod, test, dev}]"
31
+ " [-agg AGG] [-env {prod, test, dev}] [-no-reboot]"
27
32
  )
28
33
 
29
34
  parser = ArgumentParser(prog='wlt-gw-certificate',
30
- description=f'Gateway Certificate {GW_CERT_VERSION} - CLI Tool to test Wiliot GWs', usage=usage)
35
+ description=f'Gateway Certificate v{GW_CERT_VERSION} - CLI Tool to test Wiliot GWs', usage=usage)
31
36
 
32
37
  required = parser.add_argument_group('required arguments')
33
38
  required.add_argument('-gw', type=str, help="Gateway ID", required=True)
@@ -35,30 +40,41 @@ def main():
35
40
  optional.add_argument('-owner', type=str, help="Owner ID", required=False, default=REG_CERT_OWNER_ID)
36
41
  optional.add_argument('-suffix', type=str, help="Topic suffix", default='', required=False)
37
42
  optional.add_argument('-tests', type=str, choices=['registration', 'connection', 'uplink', 'downlink', 'actions', 'stress'],
38
- help="Tests to run. Registration omitted by default.", required=False, nargs='+', default=[])
43
+ help="Tests to run. Registration omitted by default.", required=False, nargs='+',
44
+ default=['connection', 'uplink', 'downlink', 'actions', 'stress'])
45
+ optional.add_argument('-actions', type=str, choices=['info', 'reboot', 'bridgeota'],
46
+ help="Action stages to run under ActionsTest", required=False, nargs='+', default=['info', 'reboot', 'ota'])
39
47
  optional.add_argument('-update', action='store_true', help='Update test board firmware', default=False, required=False)
40
48
  optional.add_argument('-pps', type=int, help='Single packets-per-second rate to simulate in the stress test',
41
49
  choices=STRESS_DEFAULT_PPS, default=None, required=False)
42
50
  optional.add_argument('-agg', type=int, help='Aggregation time [seconds] the Uplink stages wait before processing results',
43
51
  default=0, required=False)
44
- optional.add_argument('-env', type=str, help='Environment for the registration test (Internal usage)',
52
+ optional.add_argument('-env', type=str, help='Environment for the RegistrationTest & BridgeOTAStage',
45
53
  choices=['prod', 'test', 'dev'], default='prod', required=False)
46
54
  args = parser.parse_args()
47
55
 
48
- tests = filter_tests(args.tests)
49
56
  topic_suffix = '' if args.suffix == '' else '-'+args.suffix
57
+ tests = filter_tests(args.tests)
58
+ actions = filter_actions(args.actions)
50
59
 
60
+ # Validate args combination before running
51
61
  if args.pps != None and StressTest not in tests:
52
62
  parser.error("Packets per second (-pps) flag can only be used when 'stress' is included in test list (e.g. -tests stress)")
53
- if args.agg != 0 and UplinkTest not in tests:
54
- parser.error("Aggregation time (-agg) flag can only be used when 'uplink' is included in test list (e.g. -tests uplink)")
55
- if args.owner == REG_CERT_OWNER_ID and not all(test == RegistrationTest for test in tests):
56
- print(f"Note: using default owner ID (-owner) - {REG_CERT_OWNER_ID}..")
57
- time.sleep(2)
58
- # parser.error("The -owner flag is required when running any test other than the RegistrationTest.")
63
+ if args.agg != 0 and not any(t in tests for t in (UplinkTest, StressTest)):
64
+ parser.error("Aggregation time (-agg) flag can only be used when 'uplink' or 'stress' are included in test list (e.g. -tests uplink)")
65
+
66
+ if RegistrationTest in tests:
67
+ if not all(test == RegistrationTest for test in tests):
68
+ parser.error("The registration test must be run on it's own, without any others tests.")
69
+ if args.owner != REG_CERT_OWNER_ID:
70
+ parser.error(f"The registration test must be run without the -owner flag (defaults to {REG_CERT_OWNER_ID}).")
71
+ elif args.owner == REG_CERT_OWNER_ID:
72
+ parser.error("When running any test other than registration, the gateway must be registered to an owner which should be provided using the '-owner' flag.")
73
+
59
74
 
60
75
  gwc = GWCertificate(gw_id=args.gw, owner_id=args.owner, topic_suffix=topic_suffix, tests=tests, update_fw=args.update,
61
- stress_pps=args.pps, aggregation_time=args.agg, env=args.env)
76
+ stress_pps=args.pps, aggregation_time=args.agg, env=args.env, actions=actions)
77
+ debug_print(f"All arguments: {vars(args)}")
62
78
  gwc.run_tests()
63
79
  gwc.create_results_html()
64
80
 
Binary file
@@ -57,35 +57,3 @@ class BLESimulator():
57
57
  diff = time.perf_counter() - diff
58
58
  debug_print(f'Desired Delay: {delay/1000} Actual Delay {diff}')
59
59
  packet_to_send = switch_packet(packet_to_send)
60
-
61
- def trigger_by_time_stamp(self, ts):
62
- if ts == None:
63
- return
64
- current_time = datetime.datetime.timestamp(datetime.datetime.now()) * 1000
65
- time_difference = ts-current_time
66
- print(f"The test will start in: {time_difference/1000} secondes")
67
- time.sleep(time_difference/1000)
68
-
69
- def send_brg_network_pkts(self, pkts, duplicates, output_power=DEFAULT_OUTPUT_POWER):
70
- num_brgs = len(pkts)
71
- total_pkts_to_send = num_brgs * 2 * duplicates
72
- for pkt_idx in range(total_pkts_to_send):
73
- brg_idx = pkt_idx % 3
74
- pkt = pkts[brg_idx]
75
- pkt_idx_per_brg = pkt_idx // num_brgs
76
- if not bool(pkt_idx % 2):
77
- packet_to_send = pkt['data_packet']
78
- else:
79
- packet_to_send = pkt['si_packet']
80
- packet_error = pkt['packet_error']
81
- if packet_error[pkt_idx_per_brg]:
82
- debug_print(f'BRG {pkt["bridge_id"]}: Sending Packet {pkt_idx_per_brg}')
83
- self.send_packet(packet_to_send, duplicates=1, output_power=output_power,
84
- channel=SEND_ALL_ADV_CHANNELS, delay=0)
85
- else:
86
- debug_print(f'BRG {pkt["bridge_id"]}: Dropping Packet {pkt_idx_per_brg}')
87
- diff = time.perf_counter()
88
- delay = pkt['time_delay']
89
- time.sleep(delay/1000)
90
- diff = time.perf_counter() - diff
91
- debug_print(f'Desired Delay: {delay/1000} Actual Delay {diff}')
@@ -16,6 +16,7 @@ GAP_TYPE = '16'
16
16
  DEFAULT_ADVA = 'FFFFFFFFFFFF'
17
17
  DEFAULT_DUPLICATES = 3
18
18
  GW_APP_VERSION_HEADER = 'WILIOT_GW_BLE_CHIP_SW_VER'
19
+ GW_MAC_ADDRESS_HEADER = 'WILIOT_GW_BLE_CHIP_MAC_ADDRESS'
19
20
  LOCATION = 'location'
20
21
  DEFAULT_OUTPUT_POWER = 8
21
22
  DEFAULT_DELAY = 20