public async Task OTAA_Join_With_Valid_Device_Updates_DeviceTwin() { var device = TestFixtureCi.Device1_OTAA; LogTestStart(device); var twinBeforeJoin = await TestFixtureCi.GetTwinAsync(device.DeviceID); await ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWOTAA); await ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, device.AppEui); await ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey); await ArduinoDevice.SetupLora(TestFixtureCi.Configuration); var joinSucceeded = await ArduinoDevice.setOTAAJoinAsyncWithRetry(LoRaArduinoSerial._otaa_join_cmd_t.JOIN, 20000, 5); Assert.True(joinSucceeded, "Join failed"); await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_JOIN); // After join: Expectation on serial // +JOIN: Network joined // +JOIN: NetID 010000 DevAddr 02:9B:0D:3E // Assert.Contains("+JOIN: Network joined", this.lora.SerialLogs); await AssertUtils.ContainsWithRetriesAsync( (s) => s.StartsWith("+JOIN: NetID", StringComparison.Ordinal), ArduinoDevice.SerialLogs); // verify status in device twin await Task.Delay(TimeSpan.FromSeconds(60)); var twinAfterJoin = await TestFixtureCi.GetTwinAsync(device.DeviceID); Assert.NotNull(twinAfterJoin); Assert.NotNull(twinAfterJoin.Properties.Reported); try { Assert.True(twinAfterJoin.Properties.Reported.Contains("FCntUp"), "Property FCntUp does not exist"); Assert.True(twinAfterJoin.Properties.Reported.Contains("FCntDown"), "Property FCntDown does not exist"); Assert.True(twinAfterJoin.Properties.Reported.Contains("NetId"), "Property NetId does not exist"); Assert.True(twinAfterJoin.Properties.Reported.Contains("DevAddr"), "Property DevAddr does not exist"); Assert.True(twinAfterJoin.Properties.Reported.Contains("DevNonce"), "Property DevNonce does not exist"); Assert.True(twinAfterJoin.Properties.Reported.Contains("NwkSKey"), "Property NwkSKey does not exist"); Assert.True(twinAfterJoin.Properties.Reported.Contains("AppSKey"), "Property AppSKey does not exist"); Assert.True(twinAfterJoin.Properties.Reported.Contains("DevEUI"), "Property DevEUI does not exist"); var devAddrBefore = (string)twinBeforeJoin.Properties.Reported["DevAddr"]; var devAddrAfter = (string)twinAfterJoin.Properties.Reported["DevAddr"]; var actualReportedDevEUI = (string)twinAfterJoin.Properties.Reported["DevEUI"]; Assert.NotEqual(devAddrAfter, devAddrBefore); Assert.Equal(device.DeviceID, actualReportedDevEUI); Assert.True(twinBeforeJoin.Properties.Reported.Version < twinAfterJoin.Properties.Reported.Version, "Twin was not updated after join"); Log($"[INFO] Twin was updated successfully. Version changed from {twinBeforeJoin.Properties.Reported.Version} to {twinAfterJoin.Properties.Reported.Version}"); } catch (XunitException xunitException) { if (TestFixtureCi.Configuration.IoTHubAssertLevel == LogValidationAssertLevel.Warning) { Log($"[WARN] {nameof(OTAA_Join_With_Valid_Device_Updates_DeviceTwin)} failed. {xunitException}"); } else if (TestFixtureCi.Configuration.IoTHubAssertLevel == LogValidationAssertLevel.Error) { throw; } } }