0

I have the following code that is based upon the IoT Central C# Samples on GitHub (IoT Central CSharp Examples]1

In a AzureIoTDeviceService class I have the following method:

    public async Task UpdateDeviceAsync(Device device, CancellationToken cancellationToken)
{
    // If the Http Device Client doesnt exist then create it
    if (HttpDeviceClient == null)
    {
        var httpClient = new HttpClient();

        httpClient.DefaultRequestHeaders.Add("Authorization", DeviceParameters.IoTAPIToken);

        HttpDeviceClient = new HttpBasedDeviceService(DeviceParameters.IoTApplicationAPIEndpoint, httpClient);
    }

    // Set the device ID 
    device.Id = DeviceParameters.DeviceId;
    device.InstanceOf = "dtmi:iotDevicesAnywhere:MfrAIUTModelIAA5Level_3o3;1";

    ServiceLogger.LogInformation($"The following Device Information is being updated.\nProperty: Update Device - {device.DisplayName}.");

    // Update the Device        
    var result = await HttpDeviceClient.UpdateDeviceAsync(device, cancellationToken);

    ServiceLogger.LogInformation($"The return device info is Device Name - {result.DisplayName}.");


    string json = JsonConvert.SerializeObject(result, Formatting.Indented);

    ServiceLogger.LogDebug($"The following Device Information was updated.\nProperty: Update Device - {json} is complete.");
}

In a HttpBasedDeviceService class I have the following method:

    public async Task<Device> UpdateDeviceAsync(Device body, CancellationToken cancellationToken)
{
    Guard.Against.Null(body, nameof(body));

    var urlBuilder_ = new StringBuilder();
    urlBuilder_.Append(_baseUrl != null ? _baseUrl.TrimEnd('/') : "").Append("/devices/{device_id}");
    urlBuilder_.Replace("{device_id}", System.Uri.EscapeDataString(ConvertToString(body.Id, System.Globalization.CultureInfo.InvariantCulture)));


    urlBuilder_.Append("?api-version=2022-07-31");

    var client_ = _httpClient;
    try
    {
        using (var request_ = new HttpRequestMessage())
        {
            var content_ = new StringContent(JsonConvert.SerializeObject(body, _settings.Value));

            content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
            request_.Content = content_;
            request_.Method = new System.Net.Http.HttpMethod("PATCH");
            request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));

            var url_ = urlBuilder_.ToString();
            request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);


            HttpResponseMessage? response_ = await client_.SendAsync(request_, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
            try
            {
                var headers_ = Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                if (response_.Content != null && response_.Content.Headers != null)
                {
                    foreach (var item_ in response_.Content.Headers)
                    {
                        headers_[item_.Key] = item_.Value;
                    }
                }

                var status_ = ((int)response_.StatusCode).ToString();
                if (status_ == "200")
                {
                    var objectResponse_ = await ReadObjectResponseAsync<Device>(response_, headers_).ConfigureAwait(false);
                    return objectResponse_.Object;
                }
                else
                if (status_ != "200" && status_ != "204")
                {
                    var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
                    throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                }

                return default(Device);
            }
            finally
            {
                if (response_ != null)
                {
                    response_.Dispose();
                }
            }
        }
    }
    finally
    {
    }
}

From my Razor Page I call the AzureIoTDeviceService.UpdateDevice() method after I register the devices and update some of the device Properties:

                // Set Properties
            foreach (var device in AzureDeviceServices)
            {
                PageLogger.LogInformation(device?.ToString());
                // Get the device properties from the collection

                var currentDeviceProperties = DevicePropertiesCollection.DevicePropertiesEnum.ElementAt(deviceCount);

                // Update Properties
                await UpdateDeviceProperties(currentDeviceProperties, device, cancellationToken);

                // Update device information
                await UpdateDevice(device, currentDeviceProperties, cancellationToken);

                // Now Send Telemetry
                await SendTelemetries(device, numberOfDaysOfTelemetry, currentDeviceProperties, cancellationToken);

                deviceCount++;
            }
        }

Now here are the scenarios:

  1. When I just register one device everything works fine - the Device Display Name is updated appropriately.
  2. When I register 2 devices, everything runs fine (setting the device properties and telemetry) except the first device Display Name is not updated - only the second device's Display Name is updated. If I try to register 3 devices, only the 3rd device's Display Name is updated.

Here is some of the Log Outputs:

Information: Updating Device Info for device name of test-device1-i90 and device sn of dsn1i90 
Information: The following Device Information is being updated.
Property: Update Device - test-device1-i90.
Information: The return device info is Device Name - test-device1-i90.
Information: Report the telemetry values sent. Current Battery Status - 100.
Information: Report the telemetry values sent. Current Tank Level - 100.
Information: Report the telemetry values sent. Current SSRIS - -140.
Information: Report the telemetry values sent. Current Level Read DateTime - 9/1/2022 12:22:20 PM.
Information: Updating properties for device test-device2-i90.
Updating Device Info for device name of test-device2-i90 and device sn of dsn2i90 
Information: The following Device Information is being updated.
Property: Update Device - test-device2-i90.
Information: The return device info is Device Name - test-device2-i90.
Information: Report the telemetry values sent. Current Battery Status - 100.
Information: Report the telemetry values sent. Current Tank Level - 100.
Information: Report the telemetry values sent. Current SSRIS - -140.
Information: Report the telemetry values sent. Current Level Read DateTime - 9/1/2022 12:22:21 PM.

As you can see the "return device info Device Name" is what it should be. What could this be?

Mike Lenart
  • 767
  • 1
  • 5
  • 19

0 Answers0