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:
- When I just register one device everything works fine - the Device Display Name is updated appropriately.
- 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?