wiliot-certificate 4.4.2__py3-none-any.whl → 4.5.0__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.
- {brg_certificate → certificate}/ag/wlt_cmd_if.html +10 -4
- {brg_certificate → certificate}/ag/wlt_types_ag.py +1878 -519
- certificate/cert_common.py +1488 -0
- certificate/cert_config.py +480 -0
- {brg_certificate → certificate}/cert_data_sim.py +134 -46
- {brg_certificate → certificate}/cert_defines.py +129 -128
- {brg_certificate → certificate}/cert_gw_sim.py +183 -53
- {brg_certificate → certificate}/cert_mqtt.py +179 -64
- {brg_certificate → certificate}/cert_prints.py +35 -33
- {brg_certificate → certificate}/cert_protobuf.py +15 -6
- {brg_certificate → certificate}/cert_results.py +240 -64
- certificate/cert_utils.py +634 -0
- certificate/certificate.py +205 -0
- certificate/certificate_cli.py +76 -0
- certificate/certificate_eth_test_list.txt +76 -0
- certificate/certificate_sanity_test_list.txt +66 -0
- certificate/certificate_test_list.txt +76 -0
- {brg_certificate → certificate}/tests/calibration/interval_test/interval_test.json +3 -2
- {brg_certificate → certificate}/tests/calibration/interval_test/interval_test.py +7 -6
- certificate/tests/calibration/output_power_test/output_power_test.json +23 -0
- certificate/tests/calibration/output_power_test/output_power_test.py +39 -0
- {brg_certificate → certificate}/tests/calibration/pattern_test/pattern_test.json +2 -1
- {brg_certificate → certificate}/tests/calibration/pattern_test/pattern_test.py +20 -15
- certificate/tests/cloud_connectivity/acl_ext_adv_test/acl_ext_adv_test.json +15 -0
- certificate/tests/cloud_connectivity/acl_ext_adv_test/acl_ext_adv_test.py +140 -0
- certificate/tests/cloud_connectivity/acl_test/acl_test.json +15 -0
- certificate/tests/cloud_connectivity/acl_test/acl_test.py +96 -0
- certificate/tests/cloud_connectivity/brg_ota_test/brg_ota_test.json +19 -0
- certificate/tests/cloud_connectivity/brg_ota_test/brg_ota_test.py +41 -0
- certificate/tests/cloud_connectivity/channel_scan_behaviour_test/channel_scan_behaviour_test.json +19 -0
- certificate/tests/cloud_connectivity/channel_scan_behaviour_test/channel_scan_behaviour_test.py +215 -0
- certificate/tests/cloud_connectivity/connection_test/connection_test.json +18 -0
- certificate/tests/cloud_connectivity/connection_test/connection_test.py +67 -0
- certificate/tests/cloud_connectivity/deduplication_test/deduplication_test.json +15 -0
- certificate/tests/cloud_connectivity/deduplication_test/deduplication_test.py +80 -0
- certificate/tests/cloud_connectivity/downlink_test/downlink_test.json +21 -0
- certificate/tests/cloud_connectivity/downlink_test/downlink_test.py +201 -0
- certificate/tests/cloud_connectivity/ext_adv_stress_test/ext_adv_stress_test.json +17 -0
- certificate/tests/cloud_connectivity/ext_adv_stress_test/ext_adv_stress_test.py +104 -0
- certificate/tests/cloud_connectivity/reboot_test/reboot_test.json +18 -0
- certificate/tests/cloud_connectivity/reboot_test/reboot_test.py +59 -0
- certificate/tests/cloud_connectivity/registration_test/registration_test.json +20 -0
- certificate/tests/cloud_connectivity/registration_test/registration_test.py +384 -0
- certificate/tests/cloud_connectivity/registration_test/registration_test_cli.py +90 -0
- certificate/tests/cloud_connectivity/stress_test/stress_test.json +17 -0
- certificate/tests/cloud_connectivity/stress_test/stress_test.py +101 -0
- certificate/tests/cloud_connectivity/uplink_ext_adv_test/uplink_ext_adv_test.json +25 -0
- certificate/tests/cloud_connectivity/uplink_ext_adv_test/uplink_ext_adv_test.py +92 -0
- certificate/tests/cloud_connectivity/uplink_test/uplink_test.json +20 -0
- certificate/tests/cloud_connectivity/uplink_test/uplink_test.py +169 -0
- {brg_certificate → certificate}/tests/datapath/aging_test/aging_test.json +2 -1
- certificate/tests/datapath/aging_test/aging_test.py +142 -0
- certificate/tests/datapath/event_ble5_test/event_ble5_test.json +17 -0
- certificate/tests/datapath/event_ble5_test/event_ble5_test.py +89 -0
- certificate/tests/datapath/event_test/event_test.json +17 -0
- certificate/tests/datapath/event_test/event_test.py +80 -0
- {brg_certificate → certificate}/tests/datapath/num_of_tags_test/num_of_tags_test.json +4 -3
- {brg_certificate → certificate}/tests/datapath/num_of_tags_test/num_of_tags_test.py +19 -13
- certificate/tests/datapath/output_power_test/output_power_test.json +23 -0
- {brg_certificate → certificate}/tests/datapath/output_power_test/output_power_test.py +17 -6
- {brg_certificate → certificate}/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.json +2 -1
- {brg_certificate → certificate}/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.py +13 -11
- {brg_certificate → certificate}/tests/datapath/pacer_interval_test/pacer_interval_test.json +2 -1
- {brg_certificate → certificate}/tests/datapath/pacer_interval_test/pacer_interval_test.py +9 -7
- {brg_certificate → certificate}/tests/datapath/pattern_test/pattern_test.json +3 -2
- {brg_certificate → certificate}/tests/datapath/pattern_test/pattern_test.py +18 -6
- certificate/tests/datapath/pkt_filter_ble5_chl21_test/pkt_filter_ble5_chl21_test.json +20 -0
- certificate/tests/datapath/pkt_filter_ble5_chl21_test/pkt_filter_ble5_chl21_test.py +61 -0
- {brg_certificate → certificate}/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.json +2 -1
- {brg_certificate → certificate}/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.py +15 -14
- certificate/tests/datapath/pkt_filter_brg2gw_ext_adv_test/pkt_filter_brg2gw_ext_adv_test.json +19 -0
- certificate/tests/datapath/pkt_filter_brg2gw_ext_adv_test/pkt_filter_brg2gw_ext_adv_test.py +85 -0
- {brg_certificate → certificate}/tests/datapath/pkt_filter_gen3_test/pkt_filter_gen3_test.json +2 -1
- {brg_certificate → certificate}/tests/datapath/pkt_filter_gen3_test/pkt_filter_gen3_test.py +10 -9
- {brg_certificate → certificate}/tests/datapath/pkt_filter_test/pkt_filter_test.json +2 -1
- {brg_certificate → certificate}/tests/datapath/pkt_filter_test/pkt_filter_test.py +10 -9
- {brg_certificate → certificate}/tests/datapath/rssi_threshold_test/rssi_threshold_test.json +3 -2
- {brg_certificate → certificate}/tests/datapath/rssi_threshold_test/rssi_threshold_test.py +9 -8
- brg_certificate/tests/datapath/output_power_test/output_power_test.json → certificate/tests/datapath/rx_channel_hopping_test/rx_channel_hopping_test.json +6 -4
- certificate/tests/datapath/rx_channel_hopping_test/rx_channel_hopping_test.py +77 -0
- {brg_certificate → certificate}/tests/datapath/rx_channel_test/rx_channel_test.json +3 -2
- {brg_certificate → certificate}/tests/datapath/rx_channel_test/rx_channel_test.py +7 -6
- {brg_certificate → certificate}/tests/datapath/rx_rate_gen2_test/rx_rate_gen2_test.json +8 -7
- {brg_certificate → certificate}/tests/datapath/rx_rate_gen2_test/rx_rate_gen2_test.py +113 -73
- {brg_certificate → certificate}/tests/datapath/rx_rate_gen3_test/rx_rate_gen3_test.json +8 -7
- {brg_certificate → certificate}/tests/datapath/rx_rate_gen3_test/rx_rate_gen3_test.py +112 -72
- {brg_certificate → certificate}/tests/datapath/stress_gen3_test/stress_gen3_test.json +4 -3
- {brg_certificate → certificate}/tests/datapath/stress_gen3_test/stress_gen3_test.py +15 -11
- {brg_certificate → certificate}/tests/datapath/stress_test/stress_test.json +4 -3
- {brg_certificate → certificate}/tests/datapath/stress_test/stress_test.py +15 -11
- {brg_certificate → certificate}/tests/datapath/tx_repetition_test/tx_repetition_test.json +3 -1
- {brg_certificate → certificate}/tests/datapath/tx_repetition_test/tx_repetition_test.py +14 -13
- certificate/tests/edge_mgmt/action_blink_test/action_blink_test.json +15 -0
- certificate/tests/edge_mgmt/action_blink_test/action_blink_test.py +24 -0
- certificate/tests/edge_mgmt/action_get_battery_sensor_test/action_get_battery_sensor_test.json +15 -0
- certificate/tests/edge_mgmt/action_get_battery_sensor_test/action_get_battery_sensor_test.py +43 -0
- certificate/tests/edge_mgmt/action_get_module_test/action_get_module_test.json +15 -0
- certificate/tests/edge_mgmt/action_get_module_test/action_get_module_test.py +42 -0
- certificate/tests/edge_mgmt/action_get_pof_data_test/action_get_pof_data_test.json +15 -0
- certificate/tests/edge_mgmt/action_get_pof_data_test/action_get_pof_data_test.py +44 -0
- certificate/tests/edge_mgmt/action_gw_hb_test/action_gw_hb_test.json +16 -0
- certificate/tests/edge_mgmt/action_gw_hb_test/action_gw_hb_test.py +42 -0
- certificate/tests/edge_mgmt/action_reboot_test/action_reboot_test.json +15 -0
- certificate/tests/edge_mgmt/action_reboot_test/action_reboot_test.py +49 -0
- certificate/tests/edge_mgmt/action_restore_defaults_test/action_restore_defaults_test.json +15 -0
- certificate/tests/edge_mgmt/action_restore_defaults_test/action_restore_defaults_test.py +102 -0
- certificate/tests/edge_mgmt/action_send_hb_test/action_send_hb_test.json +15 -0
- certificate/tests/edge_mgmt/action_send_hb_test/action_send_hb_test.py +45 -0
- {brg_certificate → certificate}/tests/edge_mgmt/periodic_msgs_test/periodic_msgs_test.json +3 -2
- {brg_certificate → certificate}/tests/edge_mgmt/periodic_msgs_test/periodic_msgs_test.py +22 -11
- {brg_certificate → certificate}/tests/energy2400/duty_cycle_test/duty_cycle_test.json +2 -1
- {brg_certificate → certificate}/tests/energy2400/duty_cycle_test/duty_cycle_test.py +7 -6
- certificate/tests/energy2400/output_power_test/output_power_test.json +23 -0
- {brg_certificate → certificate}/tests/energy2400/output_power_test/output_power_test.py +17 -6
- {brg_certificate → certificate}/tests/energy2400/pattern_test/pattern_test.json +2 -1
- {brg_certificate → certificate}/tests/energy2400/pattern_test/pattern_test.py +7 -6
- certificate/tests/energy2400/signal_indicator_ble5_test/signal_indicator_ble5_test.json +26 -0
- certificate/tests/energy2400/signal_indicator_ble5_test/signal_indicator_ble5_test.py +379 -0
- certificate/tests/energy2400/signal_indicator_ext_adv_test/signal_indicator_ext_adv_test.json +20 -0
- certificate/tests/energy2400/signal_indicator_ext_adv_test/signal_indicator_ext_adv_test.py +173 -0
- certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.json +24 -0
- certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.py +350 -0
- {brg_certificate → certificate}/tests/energy_sub1g/duty_cycle_test/duty_cycle_test.json +2 -1
- {brg_certificate → certificate}/tests/energy_sub1g/duty_cycle_test/duty_cycle_test.py +7 -6
- {brg_certificate → certificate}/tests/energy_sub1g/pattern_test/pattern_test.json +2 -1
- {brg_certificate → certificate}/tests/energy_sub1g/pattern_test/pattern_test.py +7 -6
- {brg_certificate → certificate}/tests/pwr_mgmt/pwr_mgmt_test/pwr_mgmt_test.json +2 -1
- {brg_certificate → certificate}/tests/pwr_mgmt/pwr_mgmt_test/pwr_mgmt_test.py +10 -10
- {brg_certificate → certificate}/tests/sensors/ext_sensor_test/ext_sensor_test.json +5 -4
- certificate/tests/sensors/ext_sensor_test/ext_sensor_test.py +450 -0
- certificate/wlt_types.py +122 -0
- {gw_certificate → common}/api_if/202/status.json +6 -0
- {gw_certificate → common}/api_if/203/status.json +6 -0
- {gw_certificate → common}/api_if/204/status.json +6 -0
- common/api_if/206/data.json +85 -0
- common/api_if/206/status.json +69 -0
- common/api_if/api_validation.py +91 -0
- common/web/templates/generator.html +210 -0
- common/web/templates/index.html +20 -0
- common/web/templates/menu.html +54 -0
- common/web/templates/parser.html +53 -0
- {brg_certificate/ag → common/web/templates}/wlt_types.html +1216 -191
- common/web/web_utils.py +399 -0
- {brg_certificate → common}/wltPb_pb2.py +14 -12
- {gw_certificate/common → common}/wltPb_pb2.pyi +16 -2
- gui_certificate/gui_certificate_cli.py +14 -0
- gui_certificate/server.py +1267 -0
- gui_certificate/templates/cert_run.html +1273 -0
- wiliot_certificate-4.5.0.dist-info/METADATA +99 -0
- wiliot_certificate-4.5.0.dist-info/RECORD +168 -0
- {wiliot_certificate-4.4.2.dist-info → wiliot_certificate-4.5.0.dist-info}/WHEEL +1 -1
- wiliot_certificate-4.5.0.dist-info/entry_points.txt +5 -0
- wiliot_certificate-4.5.0.dist-info/top_level.txt +3 -0
- brg_certificate/ag/energous_v0_defines.py +0 -925
- brg_certificate/ag/energous_v1_defines.py +0 -931
- brg_certificate/ag/energous_v2_defines.py +0 -925
- brg_certificate/ag/energous_v3_defines.py +0 -925
- brg_certificate/ag/energous_v4_defines.py +0 -925
- brg_certificate/ag/fanstel_lan_v0_defines.py +0 -925
- brg_certificate/ag/fanstel_lte_v0_defines.py +0 -925
- brg_certificate/ag/fanstel_wifi_v0_defines.py +0 -925
- brg_certificate/ag/minew_lte_v0_defines.py +0 -925
- brg_certificate/ag/wlt_types_ag_jsons/brg2brg_ota.json +0 -142
- brg_certificate/ag/wlt_types_ag_jsons/brg2gw_hb.json +0 -785
- brg_certificate/ag/wlt_types_ag_jsons/brg2gw_hb_sleep.json +0 -139
- brg_certificate/ag/wlt_types_ag_jsons/calibration.json +0 -394
- brg_certificate/ag/wlt_types_ag_jsons/custom.json +0 -515
- brg_certificate/ag/wlt_types_ag_jsons/datapath.json +0 -672
- brg_certificate/ag/wlt_types_ag_jsons/energy2400.json +0 -550
- brg_certificate/ag/wlt_types_ag_jsons/energySub1g.json +0 -595
- brg_certificate/ag/wlt_types_ag_jsons/externalSensor.json +0 -598
- brg_certificate/ag/wlt_types_ag_jsons/interface.json +0 -938
- brg_certificate/ag/wlt_types_ag_jsons/powerManagement.json +0 -1234
- brg_certificate/ag/wlt_types_ag_jsons/side_info_sensor.json +0 -105
- brg_certificate/ag/wlt_types_ag_jsons/signal_indicator_data.json +0 -77
- brg_certificate/ag/wlt_types_ag_jsons/unified_echo_ext_pkt.json +0 -61
- brg_certificate/ag/wlt_types_ag_jsons/unified_echo_pkt.json +0 -110
- brg_certificate/brg_certificate.py +0 -225
- brg_certificate/brg_certificate_cli.py +0 -63
- brg_certificate/cert_common.py +0 -923
- brg_certificate/cert_config.py +0 -402
- brg_certificate/cert_utils.py +0 -362
- brg_certificate/certificate_bcc_sanity_test_list.txt +0 -40
- brg_certificate/certificate_bcc_test_list.txt +0 -48
- brg_certificate/certificate_sanity_test_list.txt +0 -43
- brg_certificate/certificate_test_list.txt +0 -53
- brg_certificate/config/eclipse.json +0 -10
- brg_certificate/config/hivemq.json +0 -10
- brg_certificate/config/mosquitto.json +0 -10
- brg_certificate/config/mosquitto.md +0 -95
- brg_certificate/config/wiliot-dev.json +0 -10
- brg_certificate/restore_brg.py +0 -61
- brg_certificate/tests/calibration/output_power_test/output_power_test.json +0 -16
- brg_certificate/tests/calibration/output_power_test/output_power_test.py +0 -28
- brg_certificate/tests/datapath/aging_test/aging_test.py +0 -143
- brg_certificate/tests/datapath/pacer_interval_tags_count_test/pacer_interval_tags_count_test.json +0 -16
- brg_certificate/tests/datapath/pacer_interval_tags_count_test/pacer_interval_tags_count_test.py +0 -73
- brg_certificate/tests/datapath/tx_repetition_algo_test/tx_repetition_algo_test.json +0 -17
- brg_certificate/tests/datapath/tx_repetition_algo_test/tx_repetition_algo_test.py +0 -118
- brg_certificate/tests/edge_mgmt/actions_test/actions_test.json +0 -14
- brg_certificate/tests/edge_mgmt/actions_test/actions_test.py +0 -396
- brg_certificate/tests/edge_mgmt/brg2brg_ota_ble5_test/brg2brg_ota_ble5_test.json +0 -20
- brg_certificate/tests/edge_mgmt/brg2brg_ota_ble5_test/brg2brg_ota_ble5_test.py +0 -94
- brg_certificate/tests/edge_mgmt/brg2brg_ota_test/brg2brg_ota_test.json +0 -19
- brg_certificate/tests/edge_mgmt/brg2brg_ota_test/brg2brg_ota_test.py +0 -87
- brg_certificate/tests/edge_mgmt/leds_test/leds_test.json +0 -17
- brg_certificate/tests/edge_mgmt/leds_test/leds_test.py +0 -223
- brg_certificate/tests/edge_mgmt/ota_test/ota_test.json +0 -17
- brg_certificate/tests/edge_mgmt/ota_test/ota_test.py +0 -128
- brg_certificate/tests/energy2400/output_power_test/output_power_test.json +0 -16
- brg_certificate/tests/energy2400/signal_indicator_ble5_10_250k_test/signal_indicator_ble5_10_250k_test.json +0 -20
- brg_certificate/tests/energy2400/signal_indicator_ble5_10_250k_test/signal_indicator_ble5_10_250k_test.py +0 -321
- brg_certificate/tests/energy2400/signal_indicator_ble5_10_500k_test/signal_indicator_ble5_10_500k_test.json +0 -20
- brg_certificate/tests/energy2400/signal_indicator_ble5_10_500k_test/signal_indicator_ble5_10_500k_test.py +0 -321
- brg_certificate/tests/energy2400/signal_indicator_sub1g_2_4_test/signal_indicator_sub1g_2_4_test.json +0 -20
- brg_certificate/tests/energy2400/signal_indicator_sub1g_2_4_test/signal_indicator_sub1g_2_4_test.py +0 -141
- brg_certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.json +0 -20
- brg_certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.py +0 -276
- brg_certificate/tests/energy_sub1g/signal_indicator_functionality_test/signal_indicator_functionality_test.json +0 -20
- brg_certificate/tests/energy_sub1g/signal_indicator_functionality_test/signal_indicator_functionality_test.py +0 -390
- brg_certificate/tests/energy_sub1g/signal_indicator_test/signal_indicator_test.json +0 -16
- brg_certificate/tests/energy_sub1g/signal_indicator_test/signal_indicator_test.py +0 -28
- brg_certificate/tests/sensors/ext_sensor_test/ext_sensor_test.py +0 -305
- brg_certificate/wltPb_pb2.pyi +0 -234
- brg_certificate/wlt_types.py +0 -113
- gw_certificate/ag/ut_defines.py +0 -364
- gw_certificate/ag/wlt_types.py +0 -85
- gw_certificate/ag/wlt_types_ag.py +0 -5310
- gw_certificate/ag/wlt_types_data.py +0 -64
- gw_certificate/api/extended_api.py +0 -23
- gw_certificate/api_if/200/data.json +0 -106
- gw_certificate/api_if/200/status.json +0 -47
- gw_certificate/api_if/201/data.json +0 -98
- gw_certificate/api_if/201/status.json +0 -53
- gw_certificate/api_if/205/logs.json +0 -12
- gw_certificate/api_if/api_validation.py +0 -38
- gw_certificate/api_if/gw_capabilities.py +0 -54
- gw_certificate/cert_results.py +0 -145
- gw_certificate/common/analysis_data_bricks.py +0 -60
- gw_certificate/common/debug.py +0 -42
- gw_certificate/common/serialization_formatter.py +0 -93
- gw_certificate/common/utils.py +0 -8
- gw_certificate/common/utils_defines.py +0 -15
- gw_certificate/common/wltPb_pb2.py +0 -84
- gw_certificate/gw_certificate.py +0 -154
- gw_certificate/gw_certificate_cli.py +0 -87
- gw_certificate/interface/4.4.91_app.zip +0 -0
- gw_certificate/interface/4.4.91_sd_bl_app.zip +0 -0
- gw_certificate/interface/ble_simulator.py +0 -61
- gw_certificate/interface/ble_sniffer.py +0 -189
- gw_certificate/interface/flash_fw.py +0 -90
- gw_certificate/interface/if_defines.py +0 -36
- gw_certificate/interface/mqtt.py +0 -563
- gw_certificate/interface/nrfutil-linux +0 -0
- gw_certificate/interface/nrfutil-mac +0 -0
- gw_certificate/interface/nrfutil.exe +0 -0
- gw_certificate/interface/pkt_generator.py +0 -594
- gw_certificate/interface/uart_if.py +0 -236
- gw_certificate/interface/uart_ports.py +0 -20
- gw_certificate/templates/results.html +0 -241
- gw_certificate/templates/stage.html +0 -22
- gw_certificate/templates/table.html +0 -6
- gw_certificate/templates/test.html +0 -38
- gw_certificate/tests/__init__.py +0 -10
- gw_certificate/tests/actions.py +0 -289
- gw_certificate/tests/bad_crc_to_PER_quantization.csv +0 -51
- gw_certificate/tests/connection.py +0 -188
- gw_certificate/tests/downlink.py +0 -172
- gw_certificate/tests/generic.py +0 -238
- gw_certificate/tests/registration.py +0 -340
- gw_certificate/tests/static/__init__.py +0 -0
- gw_certificate/tests/static/connection_defines.py +0 -9
- gw_certificate/tests/static/downlink_defines.py +0 -9
- gw_certificate/tests/static/generated_packet_table.py +0 -195
- gw_certificate/tests/static/packet_table.csv +0 -10067
- gw_certificate/tests/static/references.py +0 -5
- gw_certificate/tests/static/uplink_defines.py +0 -14
- gw_certificate/tests/throughput.py +0 -240
- gw_certificate/tests/uplink.py +0 -853
- wiliot_certificate-4.4.2.dist-info/METADATA +0 -211
- wiliot_certificate-4.4.2.dist-info/RECORD +0 -210
- wiliot_certificate-4.4.2.dist-info/entry_points.txt +0 -3
- wiliot_certificate-4.4.2.dist-info/top_level.txt +0 -3
- {brg_certificate → certificate}/__init__.py +0 -0
- {gw_certificate → common}/api_if/202/data.json +0 -0
- {gw_certificate/api_if/200 → common/api_if/202}/logs.json +0 -0
- {gw_certificate → common}/api_if/203/data.json +0 -0
- {gw_certificate/api_if/201 → common/api_if/203}/logs.json +0 -0
- {gw_certificate → common}/api_if/204/data.json +0 -0
- {gw_certificate/api_if/202 → common/api_if/204}/logs.json +0 -0
- {gw_certificate → common}/api_if/205/data.json +0 -0
- {gw_certificate/api_if/203 → common/api_if/205}/logs.json +0 -0
- {gw_certificate → common}/api_if/205/status.json +0 -0
- {gw_certificate/api_if/204 → common/api_if/206}/logs.json +0 -0
- {gw_certificate → common/api_if}/__init__.py +0 -0
- {gw_certificate/api_if → gui_certificate}/__init__.py +0 -0
- {wiliot_certificate-4.4.2.dist-info → wiliot_certificate-4.5.0.dist-info}/licenses/LICENSE +0 -0
gw_certificate/interface/mqtt.py
DELETED
|
@@ -1,563 +0,0 @@
|
|
|
1
|
-
import copy
|
|
2
|
-
import datetime
|
|
3
|
-
from enum import Enum
|
|
4
|
-
import json
|
|
5
|
-
import logging
|
|
6
|
-
import time
|
|
7
|
-
from typing import Literal, Union
|
|
8
|
-
import uuid
|
|
9
|
-
import paho.mqtt.client as mqtt
|
|
10
|
-
import ssl
|
|
11
|
-
import base64
|
|
12
|
-
from google.protobuf.message import DecodeError
|
|
13
|
-
from google.protobuf.json_format import MessageToDict, Parse, ParseError, ParseDict
|
|
14
|
-
import random
|
|
15
|
-
import re
|
|
16
|
-
|
|
17
|
-
from gw_certificate.ag.ut_defines import PACKETS, PAYLOAD, MGMT_PKT, SIDE_INFO_PKT, GW_ID, NFPKT, GW_LOGS, UNIFIED_PKT, STATUS_CODE_STR
|
|
18
|
-
from gw_certificate.ag.wlt_types_ag import GROUP_ID_BRG2GW, GROUP_ID_SIDE_INFO, GROUP_ID_UNIFIED_PKT
|
|
19
|
-
from gw_certificate.ag.wlt_types_data import DATA_DEFAULT_GROUP_ID, DataPacket
|
|
20
|
-
from gw_certificate.common.debug import debug_print
|
|
21
|
-
from gw_certificate.common import wltPb_pb2
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
DATA_PKT = 'data_pkt'
|
|
25
|
-
ACTIONSTATUS = 'actionStatus'
|
|
26
|
-
GATEWAYSTATUS = 'gatewayStatus'
|
|
27
|
-
|
|
28
|
-
TOPIC_SUFFIX_PB = '-v2'
|
|
29
|
-
|
|
30
|
-
class CustomBrokers(Enum):
|
|
31
|
-
HIVE = 'broker.hivemq.com'
|
|
32
|
-
EMQX = 'broker.emqx.io'
|
|
33
|
-
ECLIPSE = 'mqtt.eclipseprojects.io'
|
|
34
|
-
|
|
35
|
-
def get_broker_url(broker):
|
|
36
|
-
try:
|
|
37
|
-
broker_url = CustomBrokers[broker.upper()].value
|
|
38
|
-
debug_print(f"Broker URL: {broker_url}")
|
|
39
|
-
return broker_url
|
|
40
|
-
except KeyError:
|
|
41
|
-
raise KeyError(f"Broker '{broker}' not found in CustomBrokers.")
|
|
42
|
-
|
|
43
|
-
class Serialization(Enum):
|
|
44
|
-
UNKNOWN = "unknown"
|
|
45
|
-
JSON = "JSON"
|
|
46
|
-
PB = "Protobuf"
|
|
47
|
-
|
|
48
|
-
class GwAction(Enum):
|
|
49
|
-
DISABLE_DEV_MODE = "DevModeDisable"
|
|
50
|
-
REBOOT_GW ="rebootGw"
|
|
51
|
-
GET_GW_INFO ="getGwInfo"
|
|
52
|
-
|
|
53
|
-
class WltMqttMessage:
|
|
54
|
-
def __init__(self, body, topic):
|
|
55
|
-
self.body = body
|
|
56
|
-
self.mqtt_topic = topic
|
|
57
|
-
self.mqtt_timestamp = datetime.datetime.now()
|
|
58
|
-
self.body_ex = copy.deepcopy(body)
|
|
59
|
-
self.is_unified = False
|
|
60
|
-
if "data" in self.mqtt_topic and PACKETS in self.body_ex.keys():
|
|
61
|
-
for pkt in self.body_ex[PACKETS]:
|
|
62
|
-
data_pkt = DataPacket()
|
|
63
|
-
data_pkt.set(pkt[PAYLOAD])
|
|
64
|
-
if data_pkt.pkt != None:
|
|
65
|
-
if data_pkt.hdr.group_id == GROUP_ID_BRG2GW:
|
|
66
|
-
pkt[MGMT_PKT] = copy.deepcopy(data_pkt)
|
|
67
|
-
if data_pkt.hdr.group_id == GROUP_ID_SIDE_INFO:
|
|
68
|
-
pkt[SIDE_INFO_PKT] = copy.deepcopy(data_pkt)
|
|
69
|
-
if data_pkt.hdr.group_id == DATA_DEFAULT_GROUP_ID:
|
|
70
|
-
pkt[DATA_PKT] = copy.deepcopy(data_pkt)
|
|
71
|
-
if data_pkt.hdr.group_id == GROUP_ID_UNIFIED_PKT:
|
|
72
|
-
pkt[UNIFIED_PKT] = copy.deepcopy(data_pkt)
|
|
73
|
-
self.is_unified = True
|
|
74
|
-
|
|
75
|
-
def __repr__(self) -> str:
|
|
76
|
-
if self.body_ex != {}:
|
|
77
|
-
return str(self.body_ex)
|
|
78
|
-
return str(self.body)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
class WltMqttMessages:
|
|
82
|
-
def __init__(self):
|
|
83
|
-
self.data = []
|
|
84
|
-
self.status = []
|
|
85
|
-
self.update = []
|
|
86
|
-
self.all = []
|
|
87
|
-
|
|
88
|
-
def insert(self, pkt):
|
|
89
|
-
self.all.append(pkt)
|
|
90
|
-
if "data" in pkt.mqtt_topic:
|
|
91
|
-
self.data.append(pkt)
|
|
92
|
-
elif "status" in pkt.mqtt_topic:
|
|
93
|
-
self.status.append(pkt)
|
|
94
|
-
elif "update" in pkt.mqtt_topic:
|
|
95
|
-
self.update.append(pkt)
|
|
96
|
-
|
|
97
|
-
def __repr__(self) -> str:
|
|
98
|
-
return f'Data {self.data} \n Status {self.status} \n Update {self.update}'
|
|
99
|
-
|
|
100
|
-
class MqttClient:
|
|
101
|
-
|
|
102
|
-
def __init__(self, gw_id, owner_id, logger_filepath=None, topic_suffix='', serialization=Serialization.UNKNOWN, broker='hive'):
|
|
103
|
-
# Set variables
|
|
104
|
-
self.gw_id = gw_id
|
|
105
|
-
self.owner_id = owner_id
|
|
106
|
-
self.broker_url = get_broker_url(broker)
|
|
107
|
-
|
|
108
|
-
# Configure logger
|
|
109
|
-
logger = logging.getLogger('mqtt')
|
|
110
|
-
logger.setLevel(logging.DEBUG)
|
|
111
|
-
if logger_filepath is not None:
|
|
112
|
-
# create file handler which logs even debug messages
|
|
113
|
-
fh = logging.FileHandler(logger_filepath)
|
|
114
|
-
fh.setLevel(logging.DEBUG)
|
|
115
|
-
formatter = logging.Formatter('%(asctime)s | %(message)s')
|
|
116
|
-
fh.setFormatter(formatter)
|
|
117
|
-
logger.addHandler(fh)
|
|
118
|
-
logger.propagate = False # Do not send logs to 'root' logger
|
|
119
|
-
debug_print(f'MQTT Logger initialized at {logger_filepath}')
|
|
120
|
-
self.logger = logger
|
|
121
|
-
|
|
122
|
-
# Configure Paho MQTT Client
|
|
123
|
-
client_id = f'GW_Certificate_{uuid.uuid4()}'
|
|
124
|
-
self.userdata = {'messages': WltMqttMessages(), 'gw_seen': False , 'logger': self.logger, 'serialization': serialization, 'published': []}
|
|
125
|
-
# Try-except is temporary until old users are up to date
|
|
126
|
-
try:
|
|
127
|
-
self.client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id, userdata=self.userdata)
|
|
128
|
-
except AttributeError:
|
|
129
|
-
print("\nGW Certificate now runs with latest paho-mqtt!\nPlease upgrade yours to version 2.0.0 (pip install --upgrade paho-mqtt)\n")
|
|
130
|
-
raise
|
|
131
|
-
self.client.enable_logger(logger=self.logger)
|
|
132
|
-
self.client.on_message = on_message
|
|
133
|
-
self.client.on_connect = on_connect
|
|
134
|
-
self.client.on_disconnect = on_disconnect
|
|
135
|
-
self.client.on_subscribe = on_subscribe
|
|
136
|
-
self.client.on_unsubscribe = on_unsubscribe
|
|
137
|
-
self.client.on_publish = on_publish
|
|
138
|
-
self.client.on_log = on_log
|
|
139
|
-
self.client.tls_set(tls_version=ssl.PROTOCOL_TLSv1_2)
|
|
140
|
-
debug_print(f'Connecting to MQTT broker: tls://{self.broker_url}:8883, Keepalive=60')
|
|
141
|
-
self.client.connect(self.broker_url, port=8883, keepalive=60)
|
|
142
|
-
# Set Topics
|
|
143
|
-
self.update_topic = f"update{topic_suffix}/{owner_id}/{gw_id}"
|
|
144
|
-
debug_print(f'Subscribe to {self.update_topic}...')
|
|
145
|
-
self.client.subscribe(self.update_topic)
|
|
146
|
-
self.data_topic = f"data{topic_suffix}/{owner_id}/{gw_id}"
|
|
147
|
-
debug_print(f'Subscribe to {self.data_topic}...')
|
|
148
|
-
self.client.subscribe(self.data_topic)
|
|
149
|
-
self.status_topic = f"status{topic_suffix}/{owner_id}/{gw_id}"
|
|
150
|
-
debug_print(f'Subscribe to {self.status_topic}...')
|
|
151
|
-
self.client.subscribe(self.status_topic)
|
|
152
|
-
|
|
153
|
-
self.data_topic_pb = f"data{TOPIC_SUFFIX_PB}{topic_suffix}/{owner_id}/{gw_id}"
|
|
154
|
-
debug_print(f'Subscribe to {self.data_topic_pb}...')
|
|
155
|
-
self.client.subscribe(self.data_topic_pb)
|
|
156
|
-
self.status_topic_pb = f"status{TOPIC_SUFFIX_PB}{topic_suffix}/{owner_id}/{gw_id}"
|
|
157
|
-
debug_print(f'Subscribe to {self.status_topic_pb}...')
|
|
158
|
-
self.client.subscribe(self.status_topic_pb)
|
|
159
|
-
|
|
160
|
-
self.client.loop_start()
|
|
161
|
-
while(not self.client.is_connected()):
|
|
162
|
-
debug_print(f'Waiting for MQTT connection...')
|
|
163
|
-
time.sleep(1)
|
|
164
|
-
debug_print('Connected to MQTT.')
|
|
165
|
-
|
|
166
|
-
def get_serialization(self):
|
|
167
|
-
"""
|
|
168
|
-
return serialization type
|
|
169
|
-
"""
|
|
170
|
-
return self.userdata['serialization']
|
|
171
|
-
|
|
172
|
-
# Downstream Interface
|
|
173
|
-
def send_action(self, action:GwAction):
|
|
174
|
-
"""
|
|
175
|
-
Send an action to the gateway
|
|
176
|
-
:param action: GwAction - Required
|
|
177
|
-
"""
|
|
178
|
-
assert isinstance(action, GwAction), 'Action Must be a GWAction!'
|
|
179
|
-
# JSON
|
|
180
|
-
if self.get_serialization() in {Serialization.UNKNOWN, Serialization.JSON}:
|
|
181
|
-
raw_payload = json.dumps({"action": action.value})
|
|
182
|
-
self.userdata['published'].append(raw_payload.encode('utf-8'))
|
|
183
|
-
message_info = self.client.publish(self.update_topic, payload=raw_payload)
|
|
184
|
-
# PB
|
|
185
|
-
if self.get_serialization() in {Serialization.UNKNOWN, Serialization.PB}:
|
|
186
|
-
payload = wltPb_pb2.DownlinkMessage()
|
|
187
|
-
payload.gatewayAction.action = action.value
|
|
188
|
-
raw_payload = payload.SerializeToString()
|
|
189
|
-
self.userdata['published'].append(raw_payload)
|
|
190
|
-
message_info = self.client.publish(self.update_topic, payload=raw_payload)
|
|
191
|
-
message_info.wait_for_publish()
|
|
192
|
-
return message_info
|
|
193
|
-
|
|
194
|
-
def send_bridge_ota_action(self, target_bridge, version, tx_max_duration, upgrade_bl_sd,
|
|
195
|
-
gw_id, cloud="aws", env='prod'):
|
|
196
|
-
"""
|
|
197
|
-
VersionUUID generated here - Consistent per (version + upgrade_bl_sd) combination.
|
|
198
|
-
ImageDirUrl generated here - Consistent per (cloud + env + version) combination. Bridge type remain the same.
|
|
199
|
-
RebootPacket generated here - using given targer_bridge and random seq_id.
|
|
200
|
-
"""
|
|
201
|
-
CLOUD_MAP = {"aws": f"https://api.us-east-2.{env}.wiliot.cloud",
|
|
202
|
-
"gcp": f"https://api.us-central1.{env}.gcp.wiliot.cloud"}
|
|
203
|
-
GW_TYPE_UNKNOWN = 254
|
|
204
|
-
|
|
205
|
-
image_dir_url = f"{CLOUD_MAP[cloud]}/v1/bridge/type/{GW_TYPE_UNKNOWN}/version/{version}/binary/"
|
|
206
|
-
version_uuid = f"{version}1337{upgrade_bl_sd}"
|
|
207
|
-
seq_id = f"{random.randint(0, 255):02X}"
|
|
208
|
-
debug_print(f"Bridge file URL: {image_dir_url}")
|
|
209
|
-
|
|
210
|
-
reboot_packet = f"1E16C6FC0000ED070C{seq_id}{target_bridge}01"
|
|
211
|
-
reboot_packet = reboot_packet.ljust(62, '0')
|
|
212
|
-
|
|
213
|
-
if self.get_serialization() in {Serialization.UNKNOWN, Serialization.JSON}:
|
|
214
|
-
message = {
|
|
215
|
-
"action": 1,
|
|
216
|
-
"gatewayId": gw_id,
|
|
217
|
-
"imageDirUrl": image_dir_url,
|
|
218
|
-
"versionUUID": version_uuid,
|
|
219
|
-
"upgradeBlSd": upgrade_bl_sd,
|
|
220
|
-
"txPacket": reboot_packet,
|
|
221
|
-
"txMaxRetries": tx_max_duration // 100,
|
|
222
|
-
"txMaxDurationMs": tx_max_duration,
|
|
223
|
-
"bridgeId": target_bridge
|
|
224
|
-
}
|
|
225
|
-
self.send_payload(message, topic='update')
|
|
226
|
-
if self.get_serialization() in {Serialization.UNKNOWN, Serialization.PB}:
|
|
227
|
-
message = wltPb_pb2.DownlinkMessage()
|
|
228
|
-
message.bridgeUpgrade.rebootPacket = bytes.fromhex(reboot_packet)
|
|
229
|
-
message.bridgeUpgrade.txMaxDurationMs = tx_max_duration
|
|
230
|
-
message.bridgeUpgrade.txMaxRetries = tx_max_duration // 100
|
|
231
|
-
message.bridgeUpgrade.bridgeId = target_bridge
|
|
232
|
-
message.bridgeUpgrade.versionUuid = version_uuid
|
|
233
|
-
message.bridgeUpgrade.upgradeBlSd = upgrade_bl_sd
|
|
234
|
-
message.bridgeUpgrade.imageDirUrl = image_dir_url
|
|
235
|
-
self.send_payload(message, topic='update')
|
|
236
|
-
|
|
237
|
-
def send_payload(self, payload, topic:Literal['update', 'data', 'status']='update'):
|
|
238
|
-
"""
|
|
239
|
-
Send a payload to the gateway
|
|
240
|
-
:type payload: dict [JSON] / str [PB]
|
|
241
|
-
:param payload: payload to send
|
|
242
|
-
:type topic: Literal['update', 'data', 'status']
|
|
243
|
-
:param topic: defualts to update
|
|
244
|
-
"""
|
|
245
|
-
def cast_to_proto(payload: Union[str, dict, wltPb_pb2.DownlinkMessage]):
|
|
246
|
-
if isinstance(payload, wltPb_pb2.DownlinkMessage):
|
|
247
|
-
return payload
|
|
248
|
-
|
|
249
|
-
if isinstance(payload, str):
|
|
250
|
-
payload = json.loads(payload)
|
|
251
|
-
# payload is now a dictionary
|
|
252
|
-
|
|
253
|
-
def add_proto_field_type(d):
|
|
254
|
-
for key, value in list(d.items()):
|
|
255
|
-
if isinstance(value, int):
|
|
256
|
-
d[key] = {"integerValue": value}
|
|
257
|
-
elif isinstance(value, float):
|
|
258
|
-
d[key] = {"numberValue": value}
|
|
259
|
-
elif isinstance(value, str):
|
|
260
|
-
d[key] = {"stringValue": value}
|
|
261
|
-
elif isinstance(value, bool):
|
|
262
|
-
d[key] = {"boolValue": value}
|
|
263
|
-
elif isinstance(value, dict):
|
|
264
|
-
add_proto_field_type(value) # Recursively handle nested dictionaries
|
|
265
|
-
|
|
266
|
-
if 'gatewayConfig' in payload:
|
|
267
|
-
config = payload['gatewayConfig'].get('config', {})
|
|
268
|
-
add_proto_field_type(config)
|
|
269
|
-
|
|
270
|
-
pb_message = wltPb_pb2.DownlinkMessage()
|
|
271
|
-
ParseDict(payload, pb_message, ignore_unknown_fields=True)
|
|
272
|
-
|
|
273
|
-
return pb_message
|
|
274
|
-
|
|
275
|
-
topic = {'update': self.update_topic,
|
|
276
|
-
'data': self.data_topic,
|
|
277
|
-
'status': self.status_topic}[topic]
|
|
278
|
-
# JSON
|
|
279
|
-
if self.get_serialization() in {Serialization.UNKNOWN, Serialization.JSON}:
|
|
280
|
-
try:
|
|
281
|
-
raw_payload = json.dumps(payload)
|
|
282
|
-
# Add published payload to published list
|
|
283
|
-
self.userdata['published'].append(raw_payload.encode('utf-8'))
|
|
284
|
-
message_info = self.client.publish(topic, raw_payload)
|
|
285
|
-
except TypeError as e:
|
|
286
|
-
if self.get_serialization() != Serialization.UNKNOWN:
|
|
287
|
-
debug_print(f'Cannot pack payload as JSON!: {payload}')
|
|
288
|
-
raise e
|
|
289
|
-
# PB
|
|
290
|
-
if self.get_serialization() in {Serialization.UNKNOWN, Serialization.PB}:
|
|
291
|
-
try:
|
|
292
|
-
pb_message = cast_to_proto(payload)
|
|
293
|
-
raw_payload = pb_message.SerializeToString()
|
|
294
|
-
# Add published payload to published list
|
|
295
|
-
self.userdata['published'].append(raw_payload)
|
|
296
|
-
message_info = self.client.publish(topic, raw_payload)
|
|
297
|
-
except ParseError as e:
|
|
298
|
-
if self.get_serialization() != Serialization.UNKNOWN:
|
|
299
|
-
debug_print(f'Cannot parse payload as PB message!: {payload}')
|
|
300
|
-
raise e
|
|
301
|
-
message_info.wait_for_publish()
|
|
302
|
-
return message_info
|
|
303
|
-
|
|
304
|
-
def advertise_packet(self, raw_packet, tx_max_duration=800, use_retries=False):
|
|
305
|
-
if len(raw_packet) < 62:
|
|
306
|
-
if len(raw_packet) == 54:
|
|
307
|
-
raw_packet = 'C6FC' + raw_packet
|
|
308
|
-
if len(raw_packet) == 58:
|
|
309
|
-
raw_packet = '1E16' + raw_packet
|
|
310
|
-
if len(raw_packet) > 62:
|
|
311
|
-
raw_packet = raw_packet[-62:]
|
|
312
|
-
|
|
313
|
-
assert len(raw_packet) == 62, 'Raw Packet must be 62 chars long!'
|
|
314
|
-
|
|
315
|
-
if self.get_serialization() == Serialization.PB: # PB Serialization
|
|
316
|
-
payload = wltPb_pb2.DownlinkMessage()
|
|
317
|
-
payload.txPacket.payload = bytes.fromhex(raw_packet)
|
|
318
|
-
payload.txPacket.maxRetries = int(tx_max_duration / 100)
|
|
319
|
-
payload.txPacket.maxDurationMs = tx_max_duration
|
|
320
|
-
|
|
321
|
-
else: # JSON Serialization
|
|
322
|
-
if use_retries:
|
|
323
|
-
payload = {
|
|
324
|
-
'action': 0, # Advertise BLE Packet
|
|
325
|
-
'txPacket': raw_packet, # Raw Packet
|
|
326
|
-
'txMaxRetries': tx_max_duration / 100, # Tx Max Retries
|
|
327
|
-
}
|
|
328
|
-
else:
|
|
329
|
-
payload = {
|
|
330
|
-
'txPacket': raw_packet, # Raw Packet
|
|
331
|
-
'txMaxDurationMs': tx_max_duration, # Tx Max Duration
|
|
332
|
-
'action': 0 # Advertise BLE Packet
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
self.send_payload(payload, topic='update')
|
|
336
|
-
return payload
|
|
337
|
-
|
|
338
|
-
def check_gw_seen(self):
|
|
339
|
-
return self.userdata['gw_seen']
|
|
340
|
-
|
|
341
|
-
def get_gw_info_message(self):
|
|
342
|
-
messages = self.get_all_messages_from_topic('status')
|
|
343
|
-
for message in messages:
|
|
344
|
-
if GW_LOGS not in message.body_ex.keys():
|
|
345
|
-
if 'gatewayInfo' in message.body_ex.keys():
|
|
346
|
-
return message.body_ex
|
|
347
|
-
return None
|
|
348
|
-
|
|
349
|
-
def get_gw_configuration_reboot(self):
|
|
350
|
-
self.flush_messages()
|
|
351
|
-
self.send_action(GwAction.REBOOT_GW)
|
|
352
|
-
debug_print('---GW CONFIG---')
|
|
353
|
-
try:
|
|
354
|
-
debug_print(self.userdata['messages'].status)
|
|
355
|
-
return True
|
|
356
|
-
except KeyError:
|
|
357
|
-
return False
|
|
358
|
-
|
|
359
|
-
def exit_custom_mqtt(self, mqtt_mode:Literal['automatic', 'manual' ,'legacy']):
|
|
360
|
-
if mqtt_mode == 'legacy':
|
|
361
|
-
return self.send_action(GwAction.DISABLE_DEV_MODE)
|
|
362
|
-
elif mqtt_mode == 'automatic':
|
|
363
|
-
if self.get_serialization() in {Serialization.UNKNOWN, Serialization.JSON}:
|
|
364
|
-
custom_mqtt = {
|
|
365
|
-
"customBroker": False,
|
|
366
|
-
"brokerUrl": "",
|
|
367
|
-
"port": 8883,
|
|
368
|
-
"username": "",
|
|
369
|
-
"password": "",
|
|
370
|
-
"updateTopic": f"update/{self.owner_id}/{self.gw_id}",
|
|
371
|
-
"statusTopic": f"status/{self.owner_id}/{self.gw_id}",
|
|
372
|
-
"dataTopic": f"data/{self.owner_id}/{self.gw_id}"
|
|
373
|
-
}
|
|
374
|
-
self.send_payload(custom_mqtt)
|
|
375
|
-
if self.get_serialization() in {Serialization.UNKNOWN, Serialization.PB}:
|
|
376
|
-
custom_mqtt = wltPb_pb2.DownlinkMessage()
|
|
377
|
-
custom_mqtt.customMessage.entries['customBroker'].CopyFrom(wltPb_pb2.Value(boolValue=False))
|
|
378
|
-
custom_mqtt.customMessage.entries['brokerUrl'].CopyFrom(wltPb_pb2.Value(stringValue=""))
|
|
379
|
-
custom_mqtt.customMessage.entries['port'].CopyFrom(wltPb_pb2.Value(integerValue=8883))
|
|
380
|
-
custom_mqtt.customMessage.entries['username'].CopyFrom(wltPb_pb2.Value(stringValue=""))
|
|
381
|
-
custom_mqtt.customMessage.entries['password'].CopyFrom(wltPb_pb2.Value(stringValue=""))
|
|
382
|
-
custom_mqtt.customMessage.entries['updateTopic'].CopyFrom(wltPb_pb2.Value(stringValue=f"update/{self.owner_id}/{self.gw_id}"))
|
|
383
|
-
custom_mqtt.customMessage.entries['statusTopic'].CopyFrom(wltPb_pb2.Value(stringValue=f"status/{self.owner_id}/{self.gw_id}"))
|
|
384
|
-
custom_mqtt.customMessage.entries['dataTopic'].CopyFrom(wltPb_pb2.Value(stringValue=f"data/{self.owner_id}/{self.gw_id}"))
|
|
385
|
-
self.send_payload(custom_mqtt)
|
|
386
|
-
elif mqtt_mode == 'manual':
|
|
387
|
-
debug_print(f"Make sure GW {self.gw_id} is set to Wiliot MQTT broker")
|
|
388
|
-
return True
|
|
389
|
-
|
|
390
|
-
# Packet Handling
|
|
391
|
-
def flush_messages(self):
|
|
392
|
-
self.userdata = {'messages': WltMqttMessages(), 'gw_seen': False , 'logger': self.logger, 'serialization':self.get_serialization(), 'published':[]}
|
|
393
|
-
self.client.user_data_set(self.userdata)
|
|
394
|
-
|
|
395
|
-
def flush_messages_topic(self, topic:Literal['status', 'data', 'update']):
|
|
396
|
-
if topic == 'data':
|
|
397
|
-
self.userdata['messages'].data = []
|
|
398
|
-
elif topic == 'status':
|
|
399
|
-
self.userdata['messages'].status = []
|
|
400
|
-
elif topic == 'update':
|
|
401
|
-
self.userdata['messages'].update = []
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
def get_all_messages_from_topic(self, topic:Literal['status', 'data', 'update']):
|
|
405
|
-
return getattr(self.userdata['messages'], topic)
|
|
406
|
-
|
|
407
|
-
def get_all_pkts_from_topic(self, topic:Literal['status', 'data', 'update']):
|
|
408
|
-
pkts = []
|
|
409
|
-
if topic == 'data':
|
|
410
|
-
for p in eval(f'self.userdata["messages"].{topic}'):
|
|
411
|
-
gw_id = p.body_ex[GW_ID] if GW_ID in p.body_ex else ""
|
|
412
|
-
if PACKETS in p.body_ex:
|
|
413
|
-
for pkt in p.body_ex[PACKETS]:
|
|
414
|
-
pkt[GW_ID] = gw_id
|
|
415
|
-
pkts += [pkt]
|
|
416
|
-
return pkts
|
|
417
|
-
|
|
418
|
-
def get_status_message(self):
|
|
419
|
-
messages = self.get_all_messages_from_topic('status')
|
|
420
|
-
for message in messages:
|
|
421
|
-
if GW_LOGS not in message.body_ex.keys():
|
|
422
|
-
if 'gatewayConf' in message.body_ex.keys():
|
|
423
|
-
return message.body_ex
|
|
424
|
-
elif GATEWAYSTATUS in message.body_ex.keys():
|
|
425
|
-
return message.body_ex[GATEWAYSTATUS]
|
|
426
|
-
return None
|
|
427
|
-
|
|
428
|
-
def get_action_status_message(self):
|
|
429
|
-
# Implemented with a list since we can't expect when the GW will publish a msg. To avoid flushing it.
|
|
430
|
-
messages = self.get_all_messages_from_topic('status')
|
|
431
|
-
action_status_msgs = []
|
|
432
|
-
for message in messages:
|
|
433
|
-
if GW_LOGS not in message.body_ex.keys():
|
|
434
|
-
if STATUS_CODE_STR in message.body_ex.keys():
|
|
435
|
-
action_status_msgs.append(message.body_ex)
|
|
436
|
-
elif ACTIONSTATUS in message.body_ex.keys():
|
|
437
|
-
message.body_ex[ACTIONSTATUS].setdefault('status', 0)
|
|
438
|
-
action_status_msgs.append(message.body_ex[ACTIONSTATUS])
|
|
439
|
-
if len(action_status_msgs) == 0:
|
|
440
|
-
return None
|
|
441
|
-
return action_status_msgs[-1]
|
|
442
|
-
|
|
443
|
-
def get_coupled_tags_pkts(self):
|
|
444
|
-
return [p for p in self.get_all_pkts_from_topic('data') if NFPKT in p]
|
|
445
|
-
|
|
446
|
-
def get_uncoupled_tags_pkts(self):
|
|
447
|
-
return [p for p in self.get_all_pkts_from_topic('data') if NFPKT not in p]
|
|
448
|
-
|
|
449
|
-
def get_all_tags_pkts(self):
|
|
450
|
-
return [p for p in self.get_all_pkts_from_topic('data')]
|
|
451
|
-
|
|
452
|
-
# Validate topic
|
|
453
|
-
def validate_serialization_topic(self, topic:Literal['status', 'data', 'update']):
|
|
454
|
-
messages = self.get_all_messages_from_topic(topic)
|
|
455
|
-
|
|
456
|
-
if self.get_serialization() == Serialization.JSON:
|
|
457
|
-
for message in messages:
|
|
458
|
-
if TOPIC_SUFFIX_PB in message.mqtt_topic:
|
|
459
|
-
return (False, message.body_ex, message.mqtt_topic)
|
|
460
|
-
elif self.get_serialization() == Serialization.PB:
|
|
461
|
-
for message in messages:
|
|
462
|
-
if TOPIC_SUFFIX_PB not in message.mqtt_topic:
|
|
463
|
-
return (False, message.body_ex, message.mqtt_topic)
|
|
464
|
-
return (True, None, None)
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
# MQTT Client callbacks
|
|
468
|
-
|
|
469
|
-
def on_connect(mqttc, userdata, flags, reason_code, properties):
|
|
470
|
-
message = f'MQTT: Connection, RC {reason_code}'
|
|
471
|
-
userdata['logger'].info(message)
|
|
472
|
-
# Properties and Flags
|
|
473
|
-
userdata['logger'].info(flags)
|
|
474
|
-
userdata['logger'].info(properties)
|
|
475
|
-
|
|
476
|
-
def on_disconnect(mqttc, userdata, flags, reason_code, properties):
|
|
477
|
-
if reason_code != 0:
|
|
478
|
-
userdata['logger'].info(f"MQTT: Unexpected disconnection. {reason_code}")
|
|
479
|
-
else:
|
|
480
|
-
userdata['logger'].info('MQTT: Disconnect')
|
|
481
|
-
userdata['logger'].info(flags)
|
|
482
|
-
userdata['logger'].info(properties)
|
|
483
|
-
|
|
484
|
-
def on_subscribe(mqttc, userdata, mid, reason_codes, properties):
|
|
485
|
-
userdata['logger'].info(f"MQTT: Subscribe, MessageID {mid}")
|
|
486
|
-
for sub_result, idx in enumerate(reason_codes):
|
|
487
|
-
userdata['logger'].info(f"[{idx}]: RC {sub_result}")
|
|
488
|
-
userdata['logger'].info(properties)
|
|
489
|
-
|
|
490
|
-
def on_unsubscribe(mqttc, userdata, mid, reason_codes, properties):
|
|
491
|
-
userdata['logger'].info(f"MQTT: Unsubscribe, MessageID {mid}")
|
|
492
|
-
for sub_result, idx in enumerate(reason_codes):
|
|
493
|
-
userdata['logger'].info(f"[{idx}]: RC {sub_result}")
|
|
494
|
-
userdata['logger'].info(properties)
|
|
495
|
-
|
|
496
|
-
def on_message(mqttc, userdata, message):
|
|
497
|
-
# Ignore messages published by MQTT Client
|
|
498
|
-
if message.payload in userdata['published']:
|
|
499
|
-
userdata['logger'].info(f'Received self-published payload - {message.topic}: {message.payload}')
|
|
500
|
-
return
|
|
501
|
-
# Try to parse message as JSON and determine if GW is working in JSON / PB mode
|
|
502
|
-
if userdata['serialization'] == Serialization.UNKNOWN:
|
|
503
|
-
try:
|
|
504
|
-
payload = message.payload.decode("utf-8")
|
|
505
|
-
userdata['logger'].info("Received JSON-Serialized packet - setting serialization to JSON")
|
|
506
|
-
debug_print("##### Received JSON-Serialized packet - setting serialization to JSON #####")
|
|
507
|
-
userdata['serialization'] = Serialization.JSON
|
|
508
|
-
except (json.JSONDecodeError, UnicodeDecodeError):
|
|
509
|
-
userdata['logger'].info("Received non-JSON-Serialized packet - setting serialization to PB")
|
|
510
|
-
debug_print("##### Received non-JSON-Serialized packet - setting serialization to PB #####")
|
|
511
|
-
userdata['serialization'] = Serialization.PB
|
|
512
|
-
if userdata['serialization'] == Serialization.JSON:
|
|
513
|
-
on_message_json(mqttc, userdata, message)
|
|
514
|
-
if userdata['serialization'] == Serialization.PB:
|
|
515
|
-
on_message_protobuf(mqttc, userdata, message)
|
|
516
|
-
|
|
517
|
-
def on_message_json(mqttc, userdata, message):
|
|
518
|
-
payload = message.payload.decode("utf-8")
|
|
519
|
-
data = json.loads(payload)
|
|
520
|
-
userdata['messages'].insert(WltMqttMessage(data, message.topic))
|
|
521
|
-
userdata['logger'].debug(f'{message.topic}: {payload}')
|
|
522
|
-
if(userdata['gw_seen'] is False):
|
|
523
|
-
userdata['gw_seen'] = True
|
|
524
|
-
|
|
525
|
-
def on_message_protobuf(mqttc, userdata, message):
|
|
526
|
-
pb_message = None
|
|
527
|
-
if 'status' in message.topic:
|
|
528
|
-
# Try to decode UplinkMessage
|
|
529
|
-
try:
|
|
530
|
-
pb_message = wltPb_pb2.UplinkMessage()
|
|
531
|
-
pb_message.ParseFromString(message.payload)
|
|
532
|
-
except DecodeError as e:
|
|
533
|
-
userdata['logger'].debug(f'{message.topic}: An exception occured:\n{e}\n(could be a JSON msg or pb msg that is not UplinkMessage)###########')
|
|
534
|
-
userdata['logger'].debug(f'Raw Payload: {message.payload}')
|
|
535
|
-
elif 'data' in message.topic:
|
|
536
|
-
# Try to decode GatewayData
|
|
537
|
-
try:
|
|
538
|
-
pb_message = wltPb_pb2.GatewayData()
|
|
539
|
-
pb_message.ParseFromString(message.payload)
|
|
540
|
-
except DecodeError as e:
|
|
541
|
-
userdata['logger'].debug(f'{message.topic}: An exception occured:\n{e}\n(could be a JSON msg or pb msg that is not UplinkMessage)###########')
|
|
542
|
-
userdata['logger'].debug(f'Raw Payload: {message.payload}')
|
|
543
|
-
else:
|
|
544
|
-
userdata['logger'].debug(f'Message from update topic, not decoding')
|
|
545
|
-
userdata['logger'].debug(f'{message.topic}: {message.payload}')
|
|
546
|
-
if pb_message is not None:
|
|
547
|
-
pb_message_dict = MessageToDict(pb_message)
|
|
548
|
-
if 'data' in message.topic and 'packets' in pb_message_dict.keys():
|
|
549
|
-
for idx, packet in enumerate(pb_message_dict['packets']):
|
|
550
|
-
pb_message_dict['packets'][idx]['payload'] = base64.b64decode(packet['payload']).hex().upper()
|
|
551
|
-
userdata['messages'].insert(WltMqttMessage(pb_message_dict, message.topic))
|
|
552
|
-
userdata['logger'].debug(f'{message.topic}: {pb_message.__class__.__name__}')
|
|
553
|
-
userdata['logger'].debug(f'{pb_message_dict}')
|
|
554
|
-
if(userdata['gw_seen'] is False):
|
|
555
|
-
userdata['gw_seen'] = True
|
|
556
|
-
|
|
557
|
-
def on_publish(mqttc, userdata, mid, reason_code, properties):
|
|
558
|
-
userdata['logger'].info(f"MQTT: Publish, MessageID {mid}, RC {reason_code}")
|
|
559
|
-
userdata['logger'].info(properties)
|
|
560
|
-
|
|
561
|
-
def on_log(mqttc, userdata, level, buf):
|
|
562
|
-
if (level < mqtt.MQTT_LOG_DEBUG):
|
|
563
|
-
userdata['logger'].info(f"MQTT: Log level={level}, Msg={buf}")
|
|
Binary file
|
|
Binary file
|
|
Binary file
|