问题
I have registered the devices in IoT and the client application (device) can read/update reported twin properties.
The properties are the wollowing :
"EbbyVersion": {
"Major": 2,
"Minor": 1,
"Revision": 0
},
"Telemetry": {
"CachingInterval": 60,
"SendingInterval": 480,
"UploadTimeout": 10
},
"Power": {
"MaximumAvailable": 3500,
"Thresholds": {
"Low": 2500,
"Medium": 3000,
"High": 3500
}
},
"Lighting": {
"R": 32,
"G": 64,
"B": 128,
"W": 255
},
I write the following code to connect to IoT Device Twin :
var registryManager = RegistryManager.CreateFromConnectionString(AppSettings.KeyIoT);
var twin = await registryManager.GetTwinAsync(dto.DeviceIdorId);
Now, I have to read/update desired twin properties from back end application (in C#). Need help.
回答1:
Hopefully TwinCollection class would help. Please refer to this discussion C# How to update desired twin property of an Azure IoT Hub device
回答2:
You might have already figured it out, but i guess it's worthy to have it written down.
We have, at least, two ways to accomplish this:
Using Azure IoT Service SDK:
- Read: with RegistryManager.GetTwinAsync Method
- Write: with RegistryManager.UpdateTwinAsync Method
Using Azure IoT API:
- Read: using Get Twin
- Write: using Update Twin
1 - Reading Twin using Azure IoT SDK
using Microsoft.Azure.Devices;
...
static RegistryManager registryManager;
static string connectionString = "<Enter the IoT Hub Connection String>";
...
string deviceid = "<deviceid>";
registryManager = RegistryManager.CreateFromConnectionString(connectionString);
var twin = await registryManager.GetTwinAsync(deviceid);
Console.WriteLine(twin.ToJson())
Note: You could retrieve the twin on an instance of the Twin Class as well. You would only need to add
using Microsoft.Azure.Devices.Shared;
...
Twin twin = await registryManager.GetTwinAsync(deviceid);
1 - Reading Twin using Azure IoT API
Just like you would do with a HTTP Client (like Postman), you would need to make a GET request to:
https://YOUR_IOT_HUB_NAME.azure-devices.net/twins/{deviceid}?api-version=2020-05-31-preview
At the moment of writing, Microsoft Official Docs states that the latest API Version for the service IoT Hub is: "2020-05-31-preview", so this will vary over time.
You would also need to provide the Authorization header, with a valid SAS Token value.
An example of all of this, using HttpWebRequest would look like this:
string deviceid = "<deviceid>";
string URL = $"https://YOUR_IOT_HUB_NAME.azure-devices.net/twins/{deviceid}?api-version=2020-05-31-preview"
string SAS_TOKEN = "<IOT_SAS_TOKEN>";
...
try
{
string resultStr = string.Empty;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.AutomaticDecompression = DecompressionMethods.GZip;
request.Headers.Add("Authorization", SAS_TOKEN);
request.ContentType = "application/json";
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
resultStr = reader.ReadToEnd();
}
Console.WriteLine(resultStr);
}
catch (Exception e)
{
throw e;
}
2 - Updating Twin using Azure IoT SDK
using Microsoft.Azure.Devices;
...
static RegistryManager registryManager;
static string connectionString = "<Enter the IoT Hub Connection String>";
...
registryManager = RegistryManager.CreateFromConnectionString(connectionString);
string deviceid = "<deviceid>";
string etag = "<twinETag>"; // You could also get this value from the twin if you previously read it, by doing twin.ETag
// This is the piece of the twin tags we want to update
var patch = @"{
tags: {
info: {
origin: 'Argentina',
version: '14.01'
}
}
}";
await registryManager.UpdateTwinAsync(deviceid, patch, twinETag);
2 - Updating Twin using Azure IoT API
Exactly as in step "1 - Reading Twin using Azure IoT API", you need to use use the same URL
https://YOUR_IOT_HUB_NAME.azure-devices.net/twins/{deviceid}?api-version=2020-05-31-preview
And adding the Authorization header with the IoT SAS Token value, you need to use a PATCH method now. This means that in the body, you need to send the piece you want to update.
IMPORTANT: DO NOT USE A POST method unintentionally, because this will replace your entirely twin with what you send. You should use the POST method only if you send entire new twin as the body. We're not doing that now.
Again, an example of all of this, using HttpWebRequest would look like this:
string deviceid = "<deviceid>";
string URL = $"https://YOUR_IOT_HUB_NAME.azure-devices.net/twins/{deviceid}?api-version=2020-05-31-preview"
string SAS_TOKEN = "<IOT_SAS_TOKEN>";
...
var patch = @"{
tags: {
info: {
origin: 'Argentina',
version: '14.01'
}
}
}";
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(GetDeviceTwinURL(deviceid));
req.Method = "PATCH";
req.Headers.Add("Authorization", SAS_TOKEN);
req.ContentType = "application/json";
Stream stream = req.GetRequestStream();
byte[] buffer = Encoding.UTF8.GetBytes(patch);
stream.Write(buffer, 0, buffer.Length);
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
}
catch (Exception e)
{
throw e;
}
Note whenever i used 'string URL = $"...{deviceid}..."' i'm replacing deviceid variable with the deviceid i previously defined using string interpolation.
You can find another great examples here.
回答3:
One way is to:
- Deserialise the Desired or Reported json to a class
- Modify the object as needed
- Serialise back to json (making sure that nulls are included)
- Update twin with the new json.
来源:https://stackoverflow.com/questions/59006080/device-twin-how-to-read-write-properties-in-c-sharp