通过IoTHub / Xamarin App / ESP8266进行双向通信

时间:2017-01-04 15:57:43

标签: xamarin.forms azure-iot-hub

在工作中使用ESP8266,Xamarin应用程序和Azure IoTHub处理新产品,以便为客户的设备启用双向通信。

我们已经在应用程序和ESP上正常运行C2D(云2设备)和D2C(设备2云)通信,但是我们没有找到有关设置IoTHub以解释传入的遥测消息的任何信息,处理他们各自的" To:"字段并将它们放回C2D主题,这应该允许我们的目标设备接收它。

我们尝试了什么:

  1. 逻辑应用。能够触发传入队列的消息,但不确定要将其转发回C2D事件中心的HTTP请求。
  2. 我们已成功将每封邮件转发到队列中,但Xamarin的PCL库无法连接到Azure Service Bus Queues(无赖)。
  3. 我找到了一个微软实习生的参考资料,开发了一个车库门开启器的直接设备到设备通信,但她使用的库只适用于UWP应用程序,当我们确实这样做时,这并不是很方便。想要定位iOS,Android和UWP(首先选择Xamarin的原因)。

    https://blogs.windows.com/buildingapps/2016/09/08/device-to-device-communication-with-azure-iot-hub/#ykPJrVE734GpSEzV.97

    是否有人能够使用Azure门户触发C2D条件事件?

1 个答案:

答案 0 :(得分:3)

通过与Microsoft Azure团队的一些对话,我们确定webjob与队列路由相结合是我们的最佳解决方案。

所有消息都路由到队列,当它们到达队列时,webjob处理消息并使用ServiceBus Messaging对象发送消息,以将云发送到设备响应消息。

以下是任何想要使用它的人的代码。

只要邮件的原始发件人指定" To"在代理消息中的属性,它将被传递到注册表中的该设备。您将需要Service Bus和Azure.Messaging NuGet包才能使用它。此代码将复制整个邮件并将整个邮件发送到所需的注册表设备。

private const string queueName = "<queue_name>";
    private const string IoTHubConnectionString = "HostName=<your_host>;SharedAccessKeyName=<your_service_user>;SharedAccessKey=<your sas>";
    // This function will get triggered/executed when a new message is written 
    // on an Azure Queue called <queue_name>.
    public static void ReceiveQueueMessages(
        [ServiceBusTrigger(queueName)] BrokeredMessage message,
        TextWriter log)
    {
        if (message.To == null)
        {
            //message = null
            return;
        }
        else
        {
            //Retrieve the message body regardless of the content as a stream
            Stream stream = message.GetBody<Stream>();
            StreamReader reader;

            if (stream != null)
                reader = new StreamReader(stream);
            else
                reader = null;

            string s;
            Message serviceMessage;

            if ( reader != null )
            {
                s = reader.ReadToEnd();
                serviceMessage = new Microsoft.Azure.Devices.Message(Encoding.ASCII.GetBytes(s));
            }
            else
            {
                serviceMessage = new Microsoft.Azure.Devices.Message();
            }

            foreach (KeyValuePair<string, object> property in message.Properties)
            {
                serviceMessage.Properties.Add(property.Key, property.Value.ToString());
            }
            SendToIoTHub(message.To.ToString(), serviceMessage);
        }
    }

    static async void SendToIoTHub(string target, Microsoft.Azure.Devices.Message message)
    {
        // Write it back out to the target device

        ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(IoTHubConnectionString);

        var serviceMessage = message;
        serviceMessage.Ack = DeliveryAcknowledgement.Full;
        serviceMessage.MessageId = Guid.NewGuid().ToString();

        try
        {
            await serviceClient.SendAsync(target, serviceMessage);
        }
        catch
        {
            await serviceClient.CloseAsync();
            return;
        }

        await serviceClient.CloseAsync();
    }