I have defined an Azure IoT DPS, with an enrollment group, that calls a Custom allocation policy function, this function should set initialDeviceTwin tags, I have tried to implement this function as described in https://learn.microsoft.com/en-us/azure/iot-dps/tutorial-custom-allocation-policies
With TwinCollection as the type for the tags – that did not work i.e no DeviceTwin tags was set, then I changed the implementation to:
[Function("DeviceIoTHubAllocationFunc")]
public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous,"post")] HttpRequest req)
{
_logger.LogInformation("C# HTTP trigger function processed a request.");
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
// Get registration ID of the device
string regId = data?.deviceRuntimeContext?.registrationId;
string message = "Uncaught error";
bool fail = false;
_logger.LogInformation("Request.Body:...");
_logger.LogInformation(requestBody);
ResponseObj obj = new ResponseObj();
Response response = null;
//ProvisioningServiceResponse response = null;
if (regId == null)
{
message = "Registration ID not provided for the device.";
_logger.LogInformation("Registration ID : NULL");
fail = true;
}
else
{
_logger.LogInformation("RegID");
_logger.LogInformation(regId);
string[] hubs = data?.linkedHubs?.ToObject<string[]>();
// Must have hubs selected on the enrollment
if (hubs == null)
{
message = "No hub group defined for the enrollment.";
_logger.LogInformation("linkedHubs : NULL");
fail = true;
}
_logger.LogInformation("Before get IoTHubModel");
_logger.LogInformation(regId);
var model = _repository.GetBySerialNumber(regId);
_logger.LogInformation("After get IoTHubModel");
_logger.LogInformation(model.HubHostName);
if (model is not null && hubs.Any(h => h.Equals(model.HubHostName)))
{
response = new Response(model.HubHostName);
response.initialTwin.tags = new JObject
{
["enrolled"] = model.Enrolled,
["regional"] = "eus2",
};
}
else
{
message = "Unknown hubhost";
_logger.LogInformation($"Expected Hub host name : {model?.HubHostName ?? "NULL"}");
fail = true;
}
}
_logger.LogInformation("nResponse");
_logger.LogInformation((response.iotHubHostName != null) ? JsonConvert.SerializeObject(response) : message);
return (fail)
? new BadRequestObjectResult(message)
: (ActionResult)new OkObjectResult(response);
}
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; }
}
The log output from the function was:
Request: “……….., initialTwin”:{“tags”:{},”properties”:{“desired”:{}}}
Response: {“iotHubHostName”:”MYHUB.azure-devices.net”,”initialTwin”:{“tags”:{“enrolled”:true,”region”:”eus2″},”properties”:{“desired”:null}}}
When I inspect the device twin the following tags are set:
"tags": {
"enrolled": [],
"region": []
},
What am I doing wrong – and any guesses why the Microsoft.Azure.Devices.Shared.TwinState and TwinCollection doesn’t work
Thanks
Described in the sections above
Uffe Hansen is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.