简体   繁体   中英

Sending cloud to device message Azure IoT

I currently have an esp8266 sending messages to Azure using the example code found here . The code bellow is my attempt to call the direct method on the arduino using the java libraries. I created an object that has the same attributes as the model defined in the simplesample_mqtt.c . Then I call MethodResult.invoke(deviceId, methodName, responseTimeout, connectTimeout, device); and pass in the device object, the deviceId and the method I would like to invoke but I'm getting a time out exception.

BackEndApplication.java

package com.microsoft.docs.iothub.samples;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceMethod;
import com.microsoft.azure.sdk.iot.service.devicetwin.MethodResult;
import com.microsoft.azure.sdk.iot.service.exceptions.IotHubException;

public class BackEndApplication {

    // Connection string for your IoT Hub
    // az iot hub show-connection-string --hub-name {your iot hub name}
    public static final String iotHubConnectionString = "HostName=Something.azure-devices.net;SharedAccessKeyName=Owner;SharedAccessKey=jdjdjdjdjdjdjdjdjdjd";

    // Device to call direct method on.
    public static final String deviceId = "DeviceIdUsedByArduino";

    // Name of direct method and payload.
    public static final String methodName = "TurnFanOn";

    public static final Long responseTimeout = TimeUnit.SECONDS.toSeconds(30);
    public static final Long connectTimeout = TimeUnit.SECONDS.toSeconds(5);

    public static void main(String[] args) {
        try {
            System.out.println("Calling direct method...");
            ContosoAnemometer device = new ContosoAnemometer();
            device.DeviceId = deviceId;
            device.WindSpeed = 1;
            device.Temperature = 1;
            device.Humidity = 1;

            // Create a DeviceMethod instance to call a direct method.
            DeviceMethod methodClient = DeviceMethod.createFromConnectionString(iotHubConnectionString);

            // Call the direct method.
            MethodResult result = methodClient.invoke(deviceId, methodName, responseTimeout, connectTimeout, device);

            if (result == null) {
                throw new IOException("Direct method invoke returns null");
            }

            // Show the acknowledgement from the device.
            System.out.println("Status: " + result.getStatus());
            System.out.println("Response: " + result.getPayload());
        } catch (IotHubException e) {
            System.out.println("IotHubException calling direct method:");
            System.out.println(e.getMessage());
        } catch (IOException e) {
            System.out.println("IOException calling direct method:");
            System.out.println(e.getMessage());
        }
        System.out.println("Done!");
    }
}

iot_configs.h

#define IOT_CONFIG_CONNECTION_STRING    "HostName=Something.azure-devices.net;DeviceId=DeviceIdUsedByArduino;SharedAccessKey=somthing="

Response on Arduino

Connected to wifi
Fetching NTP epoch time failed! Waiting 2 seconds to retry.
Fetched NTP epoch time is: 1527899856
IoT Hub SDK for C, version 1.1.29
IoTHubClient accepted the message for delivery
Message Id: 0 Received.
Result Call Back Called! Result is: IOTHUB_CLIENT_CONFIRMATION_OK 

Exception Thrown

Calling direct method...
IotHubException calling direct method:
IoT Hub not found! {"errorCode":404103,"trackingId":"09128374091283749028h-G:5-TimeStamp:06/02/2018 00:39:09","message":"Timed out waiting for device to subscribe.","timestampUtc":"2018-06-02T00:39:09.7655165Z"} 
Done!

Please refer to this sample about how to run ac simple device Method. In this sample, it uses IoTHubClient_LL_SetDeviceMethodCallback to set the direct method for call back to back end. The sample you mentioned is just for action.

[Update]:

Actually,there are differences between WITH_METHOD and WITH_ACTION in Azure-iot-sdk-c serializer. ACTION can be called via cloud-to-device message from back-end,while METHOD need to be handled in DeviceMethodCallback.

Direct methods are synchronous and either succeed or fail after the timeout period (default: 30 seconds, settable up to 3600 seconds). The device may return some message body as a result of the method, but it isn't required for the method to do so. There is no guarantee on ordering or any concurrency semantics on method calls.Direct methods follow a request-response pattern and are meant for communications that require immediate confirmation of their result.

If you want to use METHOD instead of ACTION you need to declare the function in the model using WITH_METHOD macro and need to implement the device method callback handling via IoTHubClient_LL_SetDeviceMethodCallback .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM