1

我对 ESP8266 上的以下 Lua 代码有疑问...

function sendData(humidity,temperature)
    -- Setup MQTT client and events
    print("sendData() entered")
    print("Setting up mqtt.Client...")
    m = mqtt.Client(mqtt_client_id, 120, username, password)
    print("Attempting client connect...")
    m:connect(mqtt_broker_ip , mqtt_broker_port, 0, function(conn)
        print("Connected to MQTT")
        print("  IP: " .. mqtt_broker_ip)
        print("  Port: " .. mqtt_broker_port)
        print("  Client ID: " .. mqtt_client_id)
        print("  Username: " .. mqtt_username)

        payload = "Temp: " .. temperature .. " Hmdy: " .. humidity
        m:publish("pt/env",payload, 0, 0, function(conn)
            print("Going to deep sleep for " .. (DSLEEPTIME/1000) .. " seconds")
            node.dsleep(DSLEEPTIME*1000,4)             
        end)
    end)
end

使用以下代码成功调用了代码...

-- Connect to network
wifi.setmode(wifi.STATION)
wifi.setphymode(wifi_signal_mode)
wifi.sta.config(wifi_SSID, wifi_password) 
wifi.sta.connect()

print("Attempting to connect...")
ip = wifi.sta.getip()
if ip ~= nil then
    print("Got IP: " .. ip)
    print("About to call sendData()...")
    sendData(humidity, temperature)
    print("Returned from sendData()...")
end

使用 ESPlorer 我看到以下内容...

Attempting to connect...
Attempting to connect...
Attempting to connect...
Attempting to connect...
Attempting to connect...
Attempting to connect...
Got IP: 192.168.0.39
About to call sendData()...
sendData() entered
Setting up mqtt.Client...
Attempting client connect...
Returned from sendData()...

所以它基本上进入sendData(...)了,我看到了线路的输出......

print("Attempting client connect...")

...但我从来没有看到m:connect(...)块中的日志记录,例如...

print("Connected to MQTT")

...似乎它只是立即返回。

MQTT 代理是一个运行 Mosquitto 的 Raspberry Pi,我已经在我的 Android 手机和平板电脑上使用应用程序对其进行了测试。我在手机和平​​板电脑之间双向成功发布/订阅。

我是 Lua 新手,只了解 MQTT 的基础知识,m:connect(...)如果有人可以提供帮助,我不知道该块有什么问题。

更新:问题已解决- 很抱歉没有尽快回到这个线程。问题只是因为我在我的 RPi 上运行的 Mosquitto 版本(它符合 MQTT v3.1)。NodeMCU MQTT 库支持 MQTT v3.1.1 并且不向后兼容。从本质上讲,我的代码并没有太大的问题,尽管我确实做了一些更改——这只是因为 MQTT 版本不兼容。

4

2 回答 2

1

您没有告诉我们您使用的 NodeMCU 版本。警告:不要使用https://github.com/nodemcu/nodemcu-firmware/releases上提供的任何预构建的 0.9.x 二进制文件。根据http://nodemcu.readthedocs.io/en/dev/en/build/构建您自己的固件。

我总是帮助剥离失败的函数并利用所有可用的回调函数。dev我可以确认从分支向 cloudmqtt.com 发送数据的近 2 个月前固件上的以下工作:

function sendData(humidity, temperature)
    print("Setting up mqtt.Client...")
    m = mqtt.Client("SO-36667049", 120, "user", "password")
    print("Attempting client connect...")
    m:connect("m20.cloudmqtt.com", 12703, 0, 0,
        function(conn)
            print("Connected to MQTT")
            payload = "Temp: " .. temperature .. " Hmdy: " .. humidity
            m:publish("topic", payload, 0, 0, 
                function(client) 
                    print("Message sent") 
                end)
        end,
        function(client, reason)
            print("Connection failed, reason: " .. reason)
        end)
end

差异:

  • m:connect明确定义安全 y/n 和自动重新连接 y/n。如果只设置了所有可选参数的一个子集,它总是让我感到困惑。你的0inm:connect被解释为secure还是autoreconnect?我不太了解 Lua,无法说明我为什么要明确编码。
  • 对失败的连接尝试使用额外的回调函数。有关失败原因代码,请参阅http://nodemcu.readthedocs.org/en/dev/en/modules/mqtt/#connection-failure-callback-reason-codes 。
  • 不要在回调函数中使用与“父”函数中相同的变量名称。注意你是如何使用m:connect(..., function(conn)的,然后在你m:publish(..., function(conn)再次使用的那个函数中。您不会与conn代码中的对象进行交互,因此不会造成任何伤害。但是,这可能会在其他项目中咬你。
于 2016-04-17T08:36:58.167 回答
0

您的代码看起来不错。如果 m:connect 失败,则不会发生任何事情,因为您没有为失败的连接尝试提供回调函数。

您也不会检查 m:connect 的返回值是否成功。

参考 http://nodemcu.readthedocs.org/en/dev/en/modules/mqtt/#mqttclientconnect

并检查您的连接尝试是否失败。

于 2016-04-16T17:25:23.740 回答