【问题标题】:How to build a system to handle MQTT broker and Django如何构建一个系统来处理 MQTT 代理和 Django
【发布时间】:2017-09-15 09:05:07
【问题描述】:

我正计划构建一个家庭自动化系统,物联网设备与 MQTT 代理进行通信。该系统还涉及一个 Django Web 服务器,它为 ios/android 设备提供 API。我将描述一个我想要实现的示例。

从移动应用程序向 Django 服务器进行 API 调用以打开设备。当向 Django 发出此类 API 请求时,它应该通过 MQTT 协议将“开启”数据推送到 IoT 设备。

此外,物联网设备会向 MQTT 代理发送一些实时数据。收到此类数据后,我想通过 apns/fcm 向移动应用发送推送通知。

我该如何实现呢? Django 通道是否可以达到目的,或者我应该将我的 Django 服务器编码为 MQTT 客户端并与 MQTT 代理通信?或者有没有其他方法可以实现。

【问题讨论】:

    标签: python django mqtt paho django-channels


    【解决方案1】:

    好吧,我在 paho-MQTT 上做了一个小项目,这是使用 google chrome 扩展程序 MQTTLens 的一次不错的体验。(如果你不使用这个,你应该试试这个已经)

    在你的情况下,我认为你可以使用 Django 的 rest-framework 来构建 API,在前端,你可以使用crispy-form 来发出 ON-OFF 信号,这将直接与 Django 的视图通信,您可以在其中编写客户端和订阅者的详细信息。

    让我们专注于从移动应用程序到 Django 服务器的 API 调用以打开设备。当向 Django 发出此类 API 请求时,它应该通过 MQTT 协议将“打开”数据推送到 IoT 设备。

    • 您可以查看对 API 调用的响应来自任何设备,您可以查看django-rest-framework 这是我们拥有的最佳选择。

    现在物联网设备向 MQTT 代理发送一些实时数据

    • 对此,您可以查看Google's this artical。 MQTT 代理可以轻松地处理 Django 视图,如果您使用模块化结构和 Django 的 DRY concpet,此过程不会很复杂。

    另一方面,您也可以为客户或经纪人制作不同的视图,这取决于您,但我认为这种方法需要很长时间来开发这样的应用程序,我不了解移动开发,所以我可以'帮不了你:(.

    【讨论】:

    • 目前,我已经构建了一个系统,物联网设备和移动应用程序通过 API 与 Django 服务器通信。但是 HTTP 协议对于我的物联网设备来说有点重,所以我决定切换到轻量级 -用于 IoT 的权重 MQTT 协议 - 服务器通信和移动应用程序服务器通信的 API。但我不知道如何实现系统来处理我在示例中提到的内容。
    • 我在答案中添加了您现在可以查看的内容
    • 如果这个答案有用,那么你可以接受这个答案
    • DRF 是基于拉取的,这意味着物联网设备必须调用 API 才能了解其状态。 AFAIK,DRF 无法将数据“推送”到物联网设备。
    【解决方案2】:

    您可以使用 JavaScript 处理任务。我有使用 JavaScript 在 Django 和 Django-REST 项目中实现 MQTT 协议的经验。你应该在你的前端文件(在我的例子中是 HTML)中嵌入一个 JavaScript 代码块。首先,您应该在文件中调用 Paho-MQTT jQuery 包。

    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.2/mqttws31.min.js"></script>
    

    然后添加这段代码。

    #parameters
    var hostname = "mqtt.eclipse.org"; #There are different brokers. You should enter the broker's hostname.
    var port = 80; #The port number can be different based on a TLS or non-TLS connection.
    var ClientID = "ClientID_" + parseInt(Math.random()*100);
    
    #Create a client instance
    var client = new Paho.MQTT.Client(hostname, Number(port), ClientID);
    
    #Set callback handlers
    client.onConnectionLost = onConnectionLost;
    client.onMessageArrived = onMessageArrived;
    
    #Connect the client
    client.connect(
      {onSuccess: onConnect}
    );
    
    #Called when client connects
    function onConnect() {
      #Once a connection has been established, make a subscription and send a message
      console.log("onConnect");
      client.subscribe("subTopic");
      alert("Connected.");
    }
    
    #Called when the client loses its connection
    function onConnectionLost(responseObject){
      if(responseObject.errorCode != 0){
        console.log("onConnectionLost:" + responseObject.errorMessage);
      }
    }
    
    #Called when a message arrives
    function onMessageArrived(message) {
      console.log("Message arrived: topic=" + message.destinationName + ", message=" + message.payloadString);
      if (message.destinationName == "subTopic") {
        #Do something
      }
    

    通过使用代码,您的应用程序将连接到代理并收听一个或多个主题。这意味着您可以实时获取传感器的数据。这需要在您的硬件设备上发布传感器数据,例如 ESP 模块或 Raspberry PI。 您很可能希望从应用程序向执行器发送命令以打开或关闭它们。为此,您需要从您的应用程序中发布一些您的硬件将收听的消息。 假设您有一个切换开关,您想通过切换它来发布消息。

    <label id="switch{{ device.unique_id }}" class="switch">
      <input id="state{{ device.unique_id }}" type="checkbox" onclick="publish('{{ device.unique_id }}')">
      <span class="slider round"></span>
    </label>
    

    上面的 HTML 块应该驻留在 django for 块中。然后你应该编写publish onclick 函数来在切换开关时调用它。您可以在下面看到此类函数的示例。

    function publish(x) {
      if(!client){
        return;
      }
      var status = document.getElementById(x);
      if (status.innerHTML == 'ON'){
        status.innerHTML = 'OFF';
        var message = new Paho.MQTT.Message("TurnOFF");
        message.destinationName = "pubTopic";
        client.send(message);
      } else {
        status.innerHTML = 'ON';
        var message = new Paho.MQTT.Message("TurnON");
        message.destinationName = "pubTopic";
        client.send(message);
      }
    }
    

    x 在发布函数中是嵌入在 HTML 文件中的 id。要接收您发布的消息,您应该在硬件设备上收听特定主题。

    【讨论】:

      猜你喜欢
      • 2021-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多