RPI-Pico-Arduino-AzSDK: Direct Methods
ardpico arduino pi pico iot-hub c sdk-for-c-arduino
Azure SDK for C Arduino ESP2866 sample comes with Telemetry and Cloud to Device Me3ssaging. It does not include Direct Methods so lets implement that making deeper use of the SDK.
Scenario
- Hub sends Direct Method with or without payload
- If recognised by device and has any required parameters in payload
- Action the method
- Postive acknowledgement
- Else Negative acknowledgement
- If recognised by device and has any required parameters in payload
Device Setup
- After the WiFi is setup, the WiFi Client is setup followed by MQTT:
mqtt_client.setServer(host, port); mqtt_client.setCallback(receivedCallback);
- Note the setting of the Callback
- After MQTT is initialised, it needs to subscribe to ““$iothub/methods/POST/#””
mqtt_client.subscribe(AZ_IOT_HUB_CLIENT_METHODS_SUBSCRIBE_TOPIC);
- The Callback gets called whenever a subscribed topic is received by the device from the hub
- This gets a topic and payload as string parameters as well as a length of the payload.
void receivedCallback(char* topic, byte* payload, unsigned int length);
- This gets a topic and payload as string parameters as well as a length of the payload.
- This one method handles all corresponce from the hub
- For Direct Methods, the topic starts with
"$iothub/methods/"
which can be used to differentiate Direct Methods from CD Messages and Twinning.
Sample Direct Method no Parameter
Direct Method called from VS Code (Azure IoT Hub extension) : “stop”, blank payload
[C2DMessage] Sending message to [PicoDev2023] ...
[C2DMessage] [Success] Message sent to [PicoDev2023]
[DirectMethod] Invoking Direct Method [stop] to [PicoDev2023] ...
[DirectMethod] Response from [PicoDev2023]:
{
"status": 200,
"payload": {
"request_id": 1,
"method": "stop",
"parameter": "\"\""
}
}
The log in VS Code
========================================
Got IoT Hub Doc-Message-Method-Response
=========================================
Got Topic: $iothub/methods/POST/stop
Got Payload
\\\\\\\\\\\\\\\\\\\\\\\
Direct Method: stop
Telemtry was stopped.
\\\\\\\\\\\\\\\\\\\\\\\
{
"IsRunning": false,
"TelemetryFrequencyMilliseconds": 10000,
} - END Callback
========================================
Arduino IDE Serial Terminal Log of a Direct Method call as on Device
The topic metainformation
The complete topic in this case is:
Topic: $iothub/methods/POST/stop/?$rid=1
Interpretting the metainformation:
The method to call is embedded within the topic. The id increments with every method sent.
The Payload
Payload is actually a string of two double quote characters, so it is interpretted as blank..
Sample Direct Method with Parameter
Direct Method called from VS Code (Azure IoT Hub extension) : “frequency”, payload: “5”
[DirectMethod] Invoking Direct Method [frequency] to [PicoDev2023] ...
[DirectMethod] Response from [PicoDev2023]:
{
"status": 200,
"payload": {
"request_id": 3,
"method": "frequency",
"parameter": "5"
}
}
Log in VS Code
========================================
Got IoT Hub Doc-Message-Method-Response
========================================
Topic: $iothub/methods/POST/frequency/?$rid=3
Got Topic: $iothub/methods/POST/frequency
Got Payload
\\\\\\\\\\\\\\\\\\\\\\\
Direct Method: frequency
Telemetry Period is now: 5 sec.
Telemtry is running.
\\\\\\\\\\\\\\\\\\\\\\\
{
"IsRunning": true,
"TelemetryFrequencyMilliseconds": 5000
} - END Callback
========================================
Log in serial terminal, from device perspective
Implemented Methods on the device.
Note case sensitive; would be easy to make it case insensitive. Also only first 4 characters required.
- start
- No Payload
- stop
- No payload
- frequency
- Requires a payload.
- (In VS Code) After first return enter a period (in seconds) then press enter.
- Toggle
- Toggles the builtIn LED
- Note that this also toggles with MQTT telemetry sends.
- This could esily be a Cloud activated relay or other actuator.
Also: Added (simplistic) reset direct method that unsubscribes mqtt subscriptions, turns off/disconnects serial, wifi, mqtt etc and recalls setup().
Direct Methods from Azure Iot Explorer
THe Explorer approach allows for the setting of a timeout.
Console InvokeDirectMethodFrequency App
There are 4 console apps in the repository; one for Direct Methods InvokeDirectMethodFrequency. This sets the period (need to change frequency to period!) between Telemetry sends.
// s_connectionString is the IOT Hub Connectioon string
s_serviceClient = ServiceClient.CreateFromConnectionString(s_connectionString);
// Invoke the direct method on the device, passing the payload
private static async Task InvokeMethod(int period)
{
var methodInvocation = new CloudToDeviceMethod("frequency") { ResponseTimeout = TimeSpan.FromSeconds(30) };
methodInvocation.SetPayloadJson(period.ToString());
// Invoke the direct method asynchronously and get the response from the simulated device.
var response = await s_serviceClient.InvokeDeviceMethodAsync(s_DeviceName, methodInvocation);
Console.WriteLine("Response status: {0}, payload:", response.Status);
Console.WriteLine(response.GetPayloadAsJson());
}
Typical output is:
IoT Hub Direct Method - Back-end application.
Using Env Var IOTHUB_CONN_STRING_CSHARP = HostName=PicoHub2023.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=LKoTY/upWavEIoDYa1hSIH9cKGIVSo6WtyF1GbEYW/U=
Using Env Var DEVICE_NAME (N.b.Same as DEVICE_ID) = PicoDev2023
Press Enter to continue when the device is sending messages.
2/4 Press Enter to change period again(15s)
15
Response status: 200, payload:
{"request_id":3,"method":"frequency","parameter":"15"}
3/4 Press Enter to change period again (5s)
5
Response status: 200, payload:
{"request_id":4,"method":"frequency","parameter":"5"}
4/4 Press Enter to change period again (2s)
Output of Console app that sends Direct Method request, with parameter
Topic | Subtopic | |
This Category Links | ||
Category: | Pico W AzSDK Index: | Pico W AzSDK |
Next: > | RPI-Pico-Arduino-AzSDK | GET Device Twin Doc |
< Prev: | RPI-Pico-Arduino-AzSDK | CD Mesages |