public override async Task InitializeAsync() { TestLogger.LogDate = true; await base.InitializeAsync(); if (!string.IsNullOrEmpty(this.Configuration.LeafDeviceSerialPort)) { this.arduinoDevice = LoRaArduinoSerial.CreateFromPort(this.Configuration.LeafDeviceSerialPort); } else { TestLogger.Log("[WARN] Not serial port defined for test"); } LoRaAPIHelper.Initialize(this.Configuration.FunctionAppCode, this.Configuration.FunctionAppBaseUrl); }
// Verifies that ABP confirmed and unconfirmed messages are working // Uses Device5_ABP private async Task Test_ABP_Confirmed_And_Unconfirmed_Message_With_ADR(string devicePropertyName) { var device = this.TestFixtureCi.GetDeviceByPropertyName(devicePropertyName); if (device.IsMultiGw) { Assert.True(await LoRaAPIHelper.ResetADRCache(device.DeviceID)); } await this.ArduinoDevice.setDeviceDefaultAsync(); const int MESSAGES_COUNT = 10; this.LogTestStart(device); await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWABP); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, null); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, null); await this.ArduinoDevice.SetupLora(this.TestFixtureCi.Configuration.LoraRegion, LoRaArduinoSerial._data_rate_t.DR3, 4, true); // for a reason I need to set DR twice otherwise it reverts to DR 0 // await this.ArduinoDevice.setDataRateAsync(LoRaArduinoSerial._data_rate_t.DR3, LoRaArduinoSerial._physical_type_t.EU868); // Sends 5x unconfirmed messages for (var i = 0; i < MESSAGES_COUNT / 2; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i + 1}/{MESSAGES_COUNT}"); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); // After transferPacket: Expectation from serial // +MSG: Done await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // 0000000000000005: valid frame counter, msg: 1 server: 0 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: valid frame counter, msg:"); // 0000000000000005: decoding with: DecoderValueSensor port: 8 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: decoding with: {device.SensorDecoder} port:"); // 0000000000000005: message '{"value": 51}' sent to hub await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: message '{{\"value\":{msg}}}' sent to hub"); this.TestFixtureCi.ClearLogs(); } // Sends 5x confirmed messages for (var i = 0; i < MESSAGES_COUNT / 2; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending confirmed '{msg}' {i + 1}/{MESSAGES_COUNT / 2}"); await this.ArduinoDevice.transferPacketWithConfirmedAsync(msg, 10); await Task.Delay(2 *Constants.DELAY_BETWEEN_MESSAGES); // After transferPacketWithConfirmed: Expectation from serial // +CMSG: ACK Received await AssertUtils.ContainsWithRetriesAsync("+CMSG: ACK Received", this.ArduinoDevice.SerialLogs); // 0000000000000005: valid frame counter, msg: 1 server: 0 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: valid frame counter, msg:"); // 0000000000000005: decoding with: DecoderValueSensor port: 8 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: decoding with: {device.SensorDecoder} port:"); // 0000000000000005: message '{"value": 51}' sent to hub await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: message '{{\"value\":{msg}}}' sent to hub"); if (device.IsMultiGw) { var searchTokenSending = $"{device.DeviceID}: sending a downstream message"; var sending = await this.TestFixtureCi.SearchNetworkServerModuleAsync((log) => log.StartsWith(searchTokenSending, StringComparison.OrdinalIgnoreCase)); Assert.NotNull(sending.MatchedEvent); var searchTokenAlreadySent = $"{device.DeviceID}: another gateway has already sent ack or downlink msg"; var ignored = await this.TestFixtureCi.SearchNetworkServerModuleAsync((log) => log.StartsWith(searchTokenAlreadySent, StringComparison.OrdinalIgnoreCase)); Assert.NotNull(ignored.MatchedEvent); Assert.NotEqual(sending.MatchedEvent.SourceId, ignored.MatchedEvent.SourceId); } this.TestFixtureCi.ClearLogs(); } // Sends 10x unconfirmed messages for (var i = 0; i < MESSAGES_COUNT; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i + 1}/{MESSAGES_COUNT / 2}"); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); // After transferPacket: Expectation from serial // +MSG: Done await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // 0000000000000005: valid frame counter, msg: 1 server: 0 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: valid frame counter, msg:"); // 0000000000000005: decoding with: DecoderValueSensor port: 8 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: decoding with: {device.SensorDecoder} port:"); // 0000000000000005: message '{"value": 51}' sent to hub await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: message '{{\"value\":{msg}}}' sent to hub"); this.TestFixtureCi.ClearLogs(); } // Starting ADR test protocol this.Log($"{device.DeviceID}: Starting ADR protocol"); for (var i = 0; i < 56; ++i) { var message = PayloadGenerator.Next().ToString(); await this.ArduinoDevice.transferPacketAsync(message, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); } await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: ADR ack request received"); var searchTokenADRRateAdaptation = $"{device.DeviceID}: performing a rate adaptation: DR"; var received = await this.TestFixtureCi.SearchNetworkServerModuleAsync((log) => log.StartsWith(searchTokenADRRateAdaptation, StringComparison.OrdinalIgnoreCase)); Assert.NotNull(received.MatchedEvent); if (device.IsMultiGw) { var searchTokenADRAlreadySent = $"{device.DeviceID}: another gateway has already sent ack or downlink msg"; var ignored = await this.TestFixtureCi.SearchNetworkServerModuleAsync((log) => log.StartsWith(searchTokenADRAlreadySent, StringComparison.OrdinalIgnoreCase)); Assert.NotNull(ignored.MatchedEvent); Assert.NotEqual(received.MatchedEvent.SourceId, ignored.MatchedEvent.SourceId); } // Check the messages are now sent on DR5 for (var i = 0; i < 2; ++i) { var message = PayloadGenerator.Next().ToString(); await this.ArduinoDevice.transferPacketAsync(message, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DevAddr}: LinkADRCmd mac command detected in upstream payload: Type: LinkADRCmd Answer, power: changed, data rate: changed,", $"{device.DevAddr}: LinkADRCmd mac command detected in upstream payload: Type: LinkADRCmd Answer, power: not changed, data rate: changed,"); } }