I use Azure Service Bus to communicate IoT Hub with Node.js Functions. On Function side, I need to have access to message body as well as custom properties.
By retrieving messages elsewhere, I have noticed that my message in Service Bus consists of:
Body (the string set on IoT Device side).
Custom properties (include properties set on IoT Device side, IoT Device ID, and some additional metadata).
I have found online that in C# it is possible to access these custom properties using BrokeredMessage object. However, there is no mention on how to make this happen in Node.js. To give some details, I am printing the message as soon as it arrives to Function, using the following code:
module.exports = function(context, message) {
context.log('Message', message, 'of type', (typeof message));
...
}
What I am getting in the log console is:
message { test: true } of type object
Where "{ test: true }" is the content of a message set by IoT Device. No trace of properties though...
Is there some formal way or at least a trick to receive and extract these properties?
Thank you!
Browsing resources mentioned in the link posted by Ling Toh in a comment I got inspired to have a look at the context object.
Apparently, all of the Service Bus custom properties are available in context.bindingData.properties object.
In my case:
properties:
{
type: 'sometype', // <- this is the property I have set manually in IoT Hub message
'iothub-connection-device-id': 'mydeviceid',
'iothub-connection-auth-method': '{"scope":"somescope","type":"sometype","issuer":"external","acceptingIpFilterRule":null}',
'iothub-connection-auth-generation-id': 'someid' // <- These are added by IoT Hub
}
Related
I'm working Azure Function that sends data to few devices via IoT hub. I'm trying to log whole process and I am unsure if my current solution is sufficient.
So far I'm using message feedback(as mentioned in documentation) to log if device received send message.
"The IoT hub doesn't generate a feedback message. If the cloud-to-device message reaches the Completed state, the IoT hub generates a feedback message." As I understand it if I receive said feedback it is confirmation that message was successfully/unsuccessfully received by device.
Is my understanding that this is absolute confirmation that message was or wasn't received by device correct? Or is there another option to get is confirmation?
I recommend reading through the section Receive Cloud to Device Delivery feedback for better understanding on this. The section explains how you can set the Acknowledgment feedback option. The Azure IoT Hub provides feedback in both Positive and Negative scenarios.
If you have set the message Ack to full as indicated in the article using the following code commandMessage.Ack = DeliveryAcknowledgement.Full;, you will receive a message in both Completed as well as Dead lettered scenarios (Positive and Negative outcome).
If you are specifically targeting the success messages, you would need to set the acknowledgement to Positive. The feedback you then receive is a confirmation proving that message was successfully received by device.
Hope this helps!
I followed the below steps to send a message to an IoT device using azure function.
Additional answer wrto #LeelaRajesh_Sayana.
Created a IoT hub and added the device
Add the device name and click on save
Select the device you created and click on send message
Enter the message to send
To create a particular condition, we have code it. I have used C# function time trigger to send message IoT Hub messages and added the below condition .
try
{
log.Loginformation($"Message sent : {message}");
}
catch (Exception ex)
{
log.LogError($"Error sending message :{ex.Message});
}
using System;
using Microsoft.Azure.Devices;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
namespace AzureFunctionIoT
{
public static class SendMessageToIoTDevices
{
[FunctionName("SendMessageToIoTDevices")]
public static void Run([TimerTrigger("0 0 0 * * *")]TimerInfo myTimer, ILogger log)
{
string connectionString = Environment.GetEnvironmentVariable("IoTHubConnectionString");
ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(connectionString);
var message = new Microsoft.Azure.Devices.Message(System.Text.Encoding.ASCII.GetBytes("Hello IoT Devices"));
serviceClient.SendAsync("<DeviceId>", message).GetAwaiter().GetResult();
log.LogInformation("Message sent successfully");
}
}
}
Run the messages with Azure IoT Hub (.NET) Code
I'd like to know how to represent C2D message and External message on IoT Edge module by IoT Plug & Play DTDL definition.
I thought that a Command with a value of "asynchronous" in commandType property is used as C2D message. But when I check the behavior in IoT Central, such a command is handled as a direct method invocation.
Is it possible to represent C2D message by IoT PnP model? If yes, please let me know how to describe that.
regards,
It is a fully managed service which enable secure bidirectional communication between large no of devices and back end.
Simulated Device: connects to your IoThub and receive cloud-to-device messages.
SendCloudToDevice: app Sends a cloud to device message to device app with the help of IOT hub.
To receive cloud-to-device messages from the IoT hub.
Inside visual studio, in the Simulated Device project add given method to Simulated Device class.
private static async void ReceiveC2dAsync()
{
Console.WriteLine("\nReceiving cloud to device messages from service");
while (true)
{
Message receivedMessage = await s_deviceClient.ReceiveAsync();
if (receivedMessage == null) continue;
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Received message: {0}",
Encoding.ASCII.GetString(receivedMessage.GetBytes()));
Console.ResetColor();
await s_deviceClient.CompleteAsync(receivedMessage);
}
}
Add ReceiveC2dAsync() in main method before console.ReadLine().
I am looking for a way to see which device has sent which message in Azure.
Via "IoT-hub" we can get a list of the devices but I cannot seem to find a way to correlate the messages to the devices.
Doe anyone have any idea?
Thanks in advance.
Regards
Have a look at this document for more details about the message format.
The device id is a part of the IoT Hub message system properties such as ConnectionDeviceId.
The following example shows a query of the ASA job. You can see how to get the device id from the telemetry message via the stream pipeline:
WITH subquery as (
SELECT
System.Timestamp as time,
counter,
temperature,
humidity,
EventProcessedUtcTime,
IoTHub.ConnectionDeviceId as deviceId,
IoTHub.MessageId as messageId
FROM iot Timestamp by time
)
SELECT
*
INTO
outBlob
FROM
subquery
another example is for Azure EventHubTrigger Function (AF). The telemetry message from the stream pipeline (events endpoint) is serialized into the EventData object and pushed to the AF:
public static async Task Run(EventData ed, TraceWriter log)
{
log.Info($"Label = {ed.SystemProperties["iothub-message-source"]} -{ed.SystemProperties["iothub-connection-device-id"]}/{ed.SequenceNumber}");
// ...
}
You could try Azure IoT Toolkit extension for VS Code to monitor all the messages sent to Azure IoT Hub. You could see which device has sent what message to Azure IoT Hub.
You could also refer to this blog post for more details about how to use this extension to monitor messages.
When a message arrives in IoT Hub, the hub adds a number of system properties to the message, including the deviceid of the device that sent the message - for more information about message properties, see https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-messages-construct
If you're using C# to read the messages, see the ConnectionDeviceId property of this class: https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.devices.messagesystempropertynames?view=azure-dotnet
I am new to Azure logic apps. I have a service bus and pass a json object message to that service bus then I set up an action in logic apps to listen to my service bus. So everytime a new message come in to that service bus my logic apps will pick it up and send it to http.
My question is how can I grab the property from the message in service bus and pass it to my http action. I tried this
“Id” : “#{json(triggerBody()[‘ContentData’]).id}”
but it's not working
Who and how is sending the message on the queue?
I read a json message property (DestinationPath) in this way:
#{json(base64ToString(triggerBody()?['ContentData'])).DestinationPath}
Here is how my Logic App looks like
and in my case the message is sent from an Azure webjob as a BrokeredMessage:
string jsonMessage = JsonConvert.SerializeObject(myObject);
Stream streamMessage = new MemoryStream(Encoding.UTF8.GetBytes(jsonMessage));
BrokeredMessage msg = new BrokeredMessage(streamMessage);
client.Send(msg);
My precise setup to decrypt the base 64 message using the interface. Easy enough to type into the expression builder.
json(base64ToString(triggerBody()?['ContentData']))
ContentData of Service Bus messages is Base64 encoded, so you need to decode it first, e.g.
“Id” : “#{json(base64ToString(triggerBody()?[‘ContentData’])).id}”
Logic app now has expressions to decode Base 64 encoded value.
My requirement was to decode the encoded ServiceBus message to an Azure Function. I solved this using Logic App Expression, decodeBase64() which can accept a dynamic content of type string, in this case the 'Content'- Content of the message, and returns the decoded json string.
decodeBase64(triggerBody()?['ContentData'])
Find attached the screen shots for reference.
In the place holder for input to the action, include an expression and choose decodeBase64()
Get back to Dynamic Content tab to select 'Content' available from previous step, on hitting OK the expression would get generated
I'm working with Azure Notification Hub, and I want to send a push notification message to all registered device in .NET backend. But I'm not sure this way will send to all devices because I don't have the way to check the number of devices received push message.
So, how to, I can send a push message to all devices or can make sure this way is correct?
public static async Task<bool> SendBroadcast(string msg)
{
try
{
var notificationHubClient = NotificationHubClient.CreateClientFromConnectionString(ConfigurationManager.AppSettings["ServiceBusPushNotificationConnectionString"], ConfigurationManager.AppSettings["ServiceBusPushNotificationName"]);
Dictionary<string, string> param = new Dictionary<string, string>();
param.Add("message", msg);
param.Add("alert", msg);
var template = new TemplateNotification(param);
var result = await notificationHubClient.SendNotificationAsync(template);
Console.WriteLine(JsonConvert.SerializeObject(result));
return true;
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
return false;
}
}
If you don't specify any tag expression, that means it's broadcast. All devices will receive the notification. You can track how many devices are received through using Per Message Telemetry. Please see below links for same.
https://msdn.microsoft.com/en-us/library/azure/mt608135.aspx
https://azure.microsoft.com/en-us/blog/push-notification-hub-telemetry-expiry-update/
You need to use tags as described in Routing and Tag Expressions:
The only way to target specific registrations is to associate them
with a tag, then target that tag. As discussed in Registration
Management, in order to receive push notifications an app has to
register a device handle on a notification hub. Once a registration is
created on a notification hub, the application backend can send push
notifications to it. The application backend can choose the
registrations to target with a specific notification in the following
ways:
Broadcast: all registrations in the notification hub receive the
notification.
Tag: all registrations that contain the specified tag receive the
notification.
Tag expression: all registrations whose set of tags match the
specified expression receive the notification.
Note, there're limitations on broadcast messages that you need to take into account.
Take a look at the Breaking News App Sample on details about how to use broadcast notifications.