自定义分配支持设置初始设备对以及IoT中心。孪生设备未设置。
我已在Azure中配置设备供应服务以使用自定义Azure功能。在Azure功能中,通过自定义API,我们运行逻辑以确定设备的最佳IoT中心位置。除了分配IoT Hub之外,该代码还提供了初始设备孪生数据,但它不起作用。
我正在跟踪此博客中描述的代码示例: https://sandervandevelde.wordpress.com/2018/12/29/custom-iot-hub-assignment-in-device-provisioning-service/
我已经研究了几个相关的自定义分配问题,但没有发现有人使用如上所述的自定义azure函数方法。
这是上面博客文章中的相关代码的片段。
var response = new Response(savefileresponse.AssignedHub);
//loading an instance of the initiTwin didn't work, try typing device twin values in manually
//response.initialTwin = savefileresponse.initialTwin;
response.initialTwin.properties.desired = new JObject();
response.initialTwin.properties.desired.PropOne = "2345";
response.initialTwin.properties.desired.PropTwo = "6789";
下面是来自Blog文章的类定义。请注意将动态类型用于所需的属性。有人可以确认这是对DPS的正确消息响应类型吗?
public class AssignDeviceResponse
{
public AssignDeviceResponse()
{
this.initialTwin = new ResponseTwin();
}
public ProvisioningRegistrationStatusType Status { get; set; }
public string DeviceId { get; set; }
public string AssignedHub { get; set; }
public ResponseTwin initialTwin { get; set; }
}
#endregion
#region Microsoft DPS response contracts
public class Response
{
public Response(string hostName)
{
iotHubHostName = hostName;
initialTwin = new ResponseTwin();
}
public string iotHubHostName { get; set; }
public ResponseTwin initialTwin { get; set; }
}
public class ResponseTwin
{
public ResponseTwin()
{
properties = new ResponseProperties();
}
public dynamic tags { get; set; }
public ResponseProperties properties { get; set; } // contains desired properties
}
public class ResponseProperties
{
public dynamic desired { get; set; }
}
#endregion
设置后,IoT中心值将正确返回到设备。然后,我进入了Azure门户IoT Hub,并展示了设备的双重价值。我添加的所有自定义属性均未显示。下面的孪生兄弟显然是IoT中心的默认设置,因为它也不符合DPS服务中的孪生兄弟。
{
"deviceId": "cde5d316-9c01-3961-b850-8f5c17cea937",
"etag": "AAAAAAAAAAE=",
"deviceEtag": "NzA1OTc5MzE1",
"status": "enabled",
"statusUpdateTime": "0001-01-01T00:00:00",
"connectionState": "Disconnected",
"lastActivityTime": "2019-04-26T16:41:11.6618195",
"cloudToDeviceMessageCount": 0,
"authenticationType": "selfSigned",
"x509Thumbprint": {
"primaryThumbprint":
"xxx",
"secondaryThumbprint":
"xxx"
},
"version": 2,
"properties": {
"desired": {
"$metadata": {
"$lastUpdated": "2019-04-26T16:41:09.4381992Z"
},
"$version": 1
},
"reported": {
"$metadata": {
"$lastUpdated": "2019-04-26T16:41:09.4381992Z"
},
"$version": 1
}
},
"capabilities": {
"iotEdge": false
}
}
如何通过自定义分配设置设备孪生默认值?
编辑:在我的函数上尝试了不同的响应类型之后,我认为我还将发布对我有用的代码,以读取参数以及形成通过DPS正确序列化的响应。问题仍然在于如何设置所需的initialTwin值。这是天蓝色的功能代码,可序列化回DPS。
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
HttpRequestMessage req, TraceWriter log)
{
string requestBody = await req.Content.ReadAsStringAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
//Read out key information
string deviceId = data.deviceRuntimeContext.registrationId;
string certificate = data.deviceRuntimeContext.x509.clientCertificate;
var response = new Response(data.linkedHubs?[0]);
//Can't get initialTwin data back to DPS
//response.initialTwin = new ResponseTwin() { }
return req.CreateResponse<Response>(HttpStatusCode.OK, response);
}
答案 0 :(得分:0)
以下代码段是单个注册中的 bypass 自定义功能的示例:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
//log.LogInformation($"\nHeaders:\n\t{string.Join("\n\t", req.Headers.Select(i => $"{i.Key}={i.Value.First()}"))}");
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
string iotHub = data?.individualEnrollment?.iotHubs?[0];
dynamic result = new { iotHubHostName = $"{iotHub}" };
return (ActionResult)new OkObjectResult(result);
}
在初始化设备双胞胎的情况下,我们需要添加一个 initialTwin 属性对象,如以下示例所示:
dynamic result = new {
iotHubHostName = $"{iotHub}",
initialTwin = new {
tags = new { abcd = 12345},
properties = new {
desired = new {
PropOne = "2345",
PropTwo = "6789"
}
}
}
};
答案 1 :(得分:0)
根据该陈述,在您的问题中“我添加的所有自定义属性均未显示”,我认为该设备已被供应,并且您正在重新供应该设备。在这种情况下,DPS假定客户的解决方案已经具有配置状态,我们不想覆盖它。根据情况,您可以采取措施来满足您的需求。如果这是测试,并且您不担心与该设备相关的现有数据,则可以从集线器中删除该设备并进行重新配置。现在,新的双胞胎数据将从DPS中显示。
答案 2 :(得分:0)
我怀疑这会帮助其他人,下面的代码可以正常工作,但几乎没有。我一直无法修改动态结果而没有得到序列化错误,但至少此Azure Function代码(而非脚本)可以正常工作。关键是响应中的演员。
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
HttpRequestMessage req, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
//log.LogInformation($"\nHeaders:\n\t{string.Join("\n\t", req.Headers.Select(i => $"{i.Key}={i.Value.First()}"))}");
string requestBody = await req.Content.ReadAsStringAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
string iotHub = data.linkedHubs[0];
dynamic result = new
{
iotHubHostName = $"{iotHub}",
initialTwin = new
{
tags = new { abcd = 12345 },
properties = new
{
desired = new
{
PropOne = "2345",
PropTwo = "6789"
}
}
}
};
log.Info($"Sending back result: {Convert.ToString(result)}");
return req.CreateResponse<dynamic>(HttpStatusCode.OK, (Object)result);
}
答案 3 :(得分:0)
好吧,在Microsoft的帮助下解决此问题之后,这里是问题的答案。
1。)在Azure Functions的V2实例中实现Azure Function
2。)添加对Microsoft.Azure.Devices.Shared的引用
DPS代码需要一个TwinState实例,如下所示
public class ResponseObj
{
public string iotHubHostName { get; set; }
public TwinState initialTwin { get; set; }
}
然后通过此返回类型处理序列化
return (ActionResult)new OkObjectResult(response);