element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Azure Sphere Starter Kit
  • Products
  • Dev Tools
  • Avnet Boards Community
  • Azure Sphere Starter Kit
  • More
  • Cancel
Azure Sphere Starter Kit
Blog Implementing Direct Methods in Azure Sphere
  • Blog
  • Forum
  • Documents
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Azure Sphere Starter Kit requires membership for participation - click to join
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: bwilless
  • Date Created: 12 Sep 2019 1:37 PM Date Created
  • Views 2146 views
  • Likes 6 likes
  • Comments 5 comments
  • azure sphere
  • avnet
  • azure sphere starter kit
  • mt3620
Related
Recommended

Implementing Direct Methods in Azure Sphere

bwilless
bwilless
12 Sep 2019

Introduction

 

One of the really nice things about developing your secure IoT product with Azure Sphere is that Microsoft has implemented all the hooks and OS Services for your Azure Sphere application to leverage Azure IoT Hub features for Cloud to Device (C2D) communication/control.  Three common D2C tools available from Azure IoT Hubs are Device Twins, Remote Messages, and Direct Method calls.  This blog will introduce the reader to Direct Method calls.

 

What is a Direct Method?

 

From the Microsoft documentation:  " . . .  Direct methods represent a request-reply interaction with a device similar to an HTTP call in that they succeed or fail immediately (after a user-specified timeout). This approach is useful for scenarios where the course of immediate action is different depending on whether the device was able to respond."

 

You can think of a Direct Method as a method implemented in your Azure Sphere application that can be invoked from the Cloud.  Direct Methods accept a JSON object argument to pass any arguments that your Direct Method needs to accomplish its purpose in life.  Additionally, your Direct Method can return a JSON object.  The JSON argument and response objects can be up to 128 KB in size, so you have lots of flexibility in both directions. 

 

When should you use a Direct Method?

 

When deciding if you should use a Direct Method, you should ask yourself one question.  Does my device have to be on-line and connected to my Azure IoT Hub when I invoke the Direct Method?  If your answer is yes, then you should consider using a Direct Method.

 

Examples of when you may want to use a Direct Method:

 

  • I have an IoT device that should respond to a user request in almost real-time
    • Connected garage door opener: Open Door, Close Door
    • Connected light bulb: Turn on, Turn off
    • Connected Car: Unlock door

 

Examples where you may not want to use a Direct Method:

 

In these cases you should consider the scenario where the device may not be connected to your Azure IoT Hub, but you want to push a change down to the device; you don't care when the change takes place as long as it happens eventually.  Using a Device Twin desired property would be a better choice.

 

  • I have a device that may not be connected and I don't need the change to happen in near real-time
    • I want to change the telemetry reporting cadence
    • I want to change a static message on a display
    • I want to enable a new feature on a device

 

Direct Method Specifics

 

There are a few things you should know about using Direct Methods

 

  • Support for Direct Methods is only available on Azure IoT Hubs using the standard tier pricing or higher
  • Direct Method calls from Azure target a single device
    • Azure does provide a way to schedule jobs for multiple devices
  • Direct Methods follow a request-response pattern
  • Direct Method argument/response JSON objects can be up to 128 KB in size
  • If a Direct Method call fails, the call will not retry, that is, it will NOT be sent when the device reconnects to the IoT Hub

 

How to implement a Direct Method

 

I've seen some example applications where Direct Methods were used, but I wanted to get a better grasp on how to use them.  I decided to add two Direct Methods to the Avnet Azure Sphere Out-of-Box application.  This would require me to learn about the feature, give me some hands on experience, and document how to implement them for this blog.

 

What are the things I need to do to implement a Direct Method?

 

Implementing the Direct Method is a simple process.  Below I've listed the minimum things your application needs to do/implement to enable Direct Methods in your application.

 

  1. Define your new Direct Method
    1. Define the name of your Direct Method
    2. Define the argument JSON Object and data items inside the object
    3. Define the response JSON Object to return to Azure
  2. Inform the OS Services that I have a callback method for any Direct Method messages from the Azure IoT Hub
  3. Implement the callback method
    1. Identify which Direct Method was called
    2. Parse the JSON argument
    3. Do something meaningful for the Direct Method Call
    4. Construct and send a JSON object response back to my IoT Hub

 

My Direct Method Implementation

 

I decided to implement two different Direct Methods.

 

(1) Define your new Direct Method

 

Below are the high level details for my two Direct Methods:

 

Direct Method name: haltApplication

Direct Method Purpose:  This Direct Method will cause the application to exit by setting the global terminationRequired flag to true

Direct Method Arguments: This Direct Method does not require any arguments.  Note that the user can pass any arguments into this Direct Method, however all arguments are ignored.

Direct Method Response: The Direct Method has one response:

  • { "success" : true, "message" : "Halting Application" }

 

Direct Method name: setSensorPollTime

Direct Method Purpose:  This Direct Method will dynamically change the time period between polling the on-board ST-Micro sensors.  Note the default period is 1 second.  The Direct Method change will not be persistent.  That is, if the application is restarted the default poll time of 1 second will be used.  This function could be improved by writing the new setting to persistent memory and reading the persistent memory on startup.

Direct Method Arguments: This Direct Method requires a JSON object { "pollTime" : <time in seconds greater than 0> }

Direct Method Responses: The Direct Method implements two different responses.  One for success and one when the argument does not meet the specifications.

  • { "success" : true, "message" : "New Sensor Poll Time <new poll time> seconds" }
  • { "success" : false, "message" : "request does not contain an identifiable payload" }

 

(2) Inform the OS Services that I have a callback method for any Direct Method messages from IoT Hub

 

We use the void AzureIoT_SetDirectMethodCallback(DirectMethodCallFnType callback) routine to inform the OS services about our callback function.  In my application I call this method in the InitPeripheralsAndHandlers(void) routine that gets called when the application starts up.

 

image

 

(3) Implement the callback method

 

The callback method must use a specific function signature shown below:

 

static int <Your_Callback_Method_Name> (const char *methodName, const char *payload, size_t payloadSize, char **responsePayload, size_t *responsePayloadSize)

Annotated Code Example

 

The graphic below calls out each of the pieces needed to implement the Direct Method.  You can click on the graphic to see a larger version of the picture.

 

image

 

How to invoke a Direct Method

 

My experience with Direct Methods has been to open a Direct Method interface and type in the Direct Method name and the JSON object specifying the arguments.  I'm sure there are ways the Direct Methods can be called programmatically from Azure or from applications that have access to the IoT Hub.  I'll leave that exercise for a later date.  For now, let me show you how to call each of my Direct Methods using the manual method.

 

There are at least three different interfaces I've used to send Direct Method calls.  Using the Azure Portal, Visual Studio Cloud Explorer, and using the Device Explorer utility.  I'll review how to use the Azure Portal method since it's a clean interface and if you have access to your IoT Hub and your specific IoT device you're good to go.

 

Using the Azure Portal to call Direct Methods

 

  1. Open the Azure Portal and sign in
  2. Find your IoT Hub, open the IoT Hub resource
  3. From the IoT Hub instance find the "IoT devices" blade, then your IoT device
    1. image
  4. Once you're inside the page for your IoT Device look along the top of the window.  Here you'll see some of the things you can do with your IoT device.  Note that the three ways we identified to send C2D message are all represented in this interface.  Since this blog is all about Direct Methods, click on the Direct Method link.
    1. image
  5. This will open the Direct Method interface. Below I'll describe each item in this interface:
    1. Invoke Method:  This is the GO button.  After you enter the Method Name and any Payload details, click on the "Invoke Method" link to send the Direct Method call to your device.
    2. Method Name: This is where, you guessed it, you type in the name of the Direct Method you want to call in your application.  Note that this name is case sensitive.
    3. Payload: This is where you type in the JSON structure with the arguments for your Direct Method.
    4. Result: This is where the JSON return object will be displayed.
    1. image

Let's see it in action:

 

In the graphic below I'm calling the setSensorPollTime Direct Method and I'm setting the new poll time to 5 seconds.

 

image

 

Next I click on the "Invoke Method" link:

  1. Azure IoT Hub sends the Direct Method Call to my device
  2. The Azure Sphere OS Services catch the message and invoke my directMethodCall() routine and include all the required arguments
  3. The routine determines that the setSensorPollTime Direct Method was called
  4. The setSensorPollTime code parses the argument JSON object and validates that the data is good
  5. The setSensorPollTime code changes the poll timer
  6. The setSensorPollTime code constructs the return JSON object and sends it back to the Azure IoT Hub

 

You can see that the return JSON object is displayed in the Azure Portal inside the Result window!  Like magic!

image

 

Hands on Exercise

Now lets load some code onto our Avnet Azure Sphere Starter Kit and try out the new Direct Methods.  The prerequisites for this exercise are to complete the first two Out of Box Blogs from the links below.  Once you have loaded the OOB example application and connected it to your IoT Hub, come back to this blog for further instructions.

 

Note: If you've previously worked through the OOB blogs (before 9/12/19), you'll need to pull the latest code from GitHub.

 

  1. Complete the OOB blog 1 of 3 (Pull and load the GitHub project)
  2. Complete the OOB blog 2 of 3 (Create an IoT Hub, IoT device and connect your application to the IoT Hub)
  3. Make sure the example application is running on your Starter Kit
  4. Make sure the example application is connected to the Azure IoT Hub
  5. Open the Azure Portal and login to your Azure account
  6. Find your IoT Hub
  7. Find the "IoT devices" blade
  8. Find your IoT device
  9. Open the "Direct Method" interface
  10. Enter the following information:
    1. Method Name: setSensorPollTime
    2. Payload: { "pollTime" : 10 }
    3. Watch the debug output in Visual Studio.  Note that the sensors are read every 1 second
    4. Back in the Azure Portal click on the "Invoke Method" link
    5. Watch the debug output in Visual Studio.  You should see debug output stating that the poll time was changed and you should see the time between sensor reads go from 1 second to 10 seconds.
    6. Review the result window in the Azure Portal and note the return JSON object
  1. Now go back to the Azure Portal Direct Method interface; lets call the second Direct Method
    1. Method Name: haltApplication
    2. Payload: { }
    3. Click on the "Invoke Method" link
    4. Go back to your Visual Studio application and note that the application has halted
    5. Review the result window in the Azure Portal, note the return JSON object

 

Conclusion

 

Direct Methods allow users to invoke code on a remote connected device.  Because you can pass large JSON arguments to the Direct Method, your imagination is the only limitation to how you could use this powerful Cloud-to-Device mechanism.

 

If you have used Direct Methods to implement features or functionalities in your own IoT deployment, please add a comment with a high level overview of what you did.  This will help other developers generate ideas.

 

Thanks for reading,

 

Brian

  • Sign in to reply

Top Comments

  • Fred27
    Fred27 over 5 years ago +2
    Agreed - another very nice article. I'm already using Direct Methods in my project so had to work all this out myself. If you have used Direct Methods to implement features or functionalities in your own…
  • juli15
    juli15 over 5 years ago +1
    Hi! This article is incredible, it's giving me a lot of hints to achieve a little bit more of level with C and IoT! I've implemented your code typed by hand (I say it because I'm afraid this could be the…
  • bwilless
    bwilless over 5 years ago in reply to juli15

    Hmm . . .

     

    Did you start your project with a working example, or did you start from scratch?  I've always started with a working example that included all the basic functionality that I needed, for example a UART or I2C example.

     

    If you installed the Azure Sphere SDK then the azure_iot_utilities.* files should be on your development PC.  I'm not a Visual Studio expert, but I would look at your project properties (in the solution explorer, right click on your project name, then select properties.  Once the properties dialog is open, go to the Linker section, then input.  Make sure that "azureiot" is listed under your Library Dependencies.

     

    I hope that helps,

     

    Brian

     

    image

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • juli15
    juli15 over 5 years ago in reply to Fred27

    Hi Brian!

     

    That's what I've found after searching almost everywhere, but I get an error saying that this library does not exist..

    I've tried to add it manually (copying the ".h" file from github) but didn't work..

     

    There's something that I didn't do? Sorry if I'm being so silly with this..

     

    Thanks again!

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • bwilless
    bwilless over 5 years ago in reply to juli15

    Hi Juli,

     

    Thanks for the kind words.  The AzureIoT_SetDirectMethodCallback() method is declared in the azure_iot_utilities.h header file.  If you add . . .

     

    #include "azure_iot_utilities.h"

     

    at the top of your main.c function then your error should clear.

     

    Brian

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Fred27
    Fred27 over 5 years ago

    Agreed - another very nice article. I'm already using Direct Methods in my project so had to work all this out myself.

     

    If you have used Direct Methods to implement features or functionalities in your own IoT deployment, please add a comment with a high level overview of what you did.  This will help other developers generate ideas.

    My project is based around Azure AD B2C for user authentication. This then calls through an Azure Function and Azure IoT Hub (using a direct method) to get extra security information from the Azure Sphere device.

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • juli15
    juli15 over 5 years ago

    Hi! This article is incredible, it's giving me a lot of hints to achieve a little bit more of level with C and IoT! I've implemented your code typed by hand (I say it because I'm afraid this could be the error..). But when I try to compile the code, it's giving me an error which says

     

    " Error implicit declaration of function 'AzureIoT_SetDirectMethodCallback'; did you mean 'DirectMethodCall'? [-Werror=implicit-function-declaration]

      AzureIoT_SetDirectMethodCallback(&DirectMethodCall);"

     

     

    As I've been reading through other websites, it has something to do with being executing functions before declarating them, but in this case, 'AzureIoT_SetDirectMethodCallback' is where we are declaring the function, right? I don't clearly understand what VS is trying to tell... I'm declaring it as you said, in InitPeripheralsAndHandlers

     

     

    Thank you for all your good work!

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube