0

我目前有一个 esp8266 使用此处找到的示例代码向 Azure 发送消息。下面的代码是我尝试使用 java 库在 arduino 上调用直接方法。我创建了一个对象,它与simplesample_mqtt.c. 然后我调用MethodResult.invoke(deviceId, methodName, responseTimeout, connectTimeout, device);并传入设备对象、deviceId 和我想调用的方法,但我遇到了超时异常。

后端应用程序.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="

对 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 

抛出异常

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!
4

1 回答 1

0

有关如何运行 ac simple device 方法,请参阅此示例。在此示例中,它使用IoTHubClient_LL_SetDeviceMethodCallback来设置回调到后端的直接方法。您提到的示例仅用于操作。

[更新]:

实际上,Azure-iot-sdk-c 序列化程序中的 WITH_METHOD 和 WITH_ACTION 是有区别的。ACTION 可以通过后端的云到设备消息调用,而 METHOD 需要在 DeviceMethodCallback 中处理。

直接方法是同步的,并且在超时期限后成功或失败(默认值:30 秒,可设置为 3600 秒)。作为该方法的结果,设备可能会返回一些消息正文,但该方法不需要这样做。无法保证方法调用的顺序或任何并发语义。直接方法遵循请求-响应模式,适用于需要立即确认其结果的通信。

如果您想使用 METHOD 而不是 ACTION,您需要使用 WITH_METHOD 宏在模型中声明函数,并且需要通过IoTHubClient_LL_SetDeviceMethodCallback实现设备方法回调处理。

于 2018-06-04T08:29:53.250 回答