MQTT / ESP8266 / NodeMCU / Lua代码不发布

我在ESP8266上有以下Lua代码的问题......

function sendData(humidity,temperature)
    -- 设置MQTT客户端和事件
    print("进入sendData()函数")
    print("设置mqtt.Client...")
    m = mqtt.Client(mqtt_client_id, 120, username, password)
    print("尝试连接客户端...")
    m:connect(mqtt_broker_ip , mqtt_broker_port, 0, function(conn)
        print("连接到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("将进入深度睡眠 " .. (DSLEEPTIME/1000) .. " 秒")
            node.dsleep(DSLEEPTIME*1000,4)
        end)
    end)
end

代码已经成功地被以下代码调用...

-- 连接网络
wifi.setmode(wifi.STATION)
wifi.setphymode(wifi_signal_mode)
wifi.sta.config(wifi_SSID, wifi_password)
wifi.sta.connect()

print("尝试连接...")
ip = wifi.sta.getip()
if ip ~= nil then
    print("成功获取IP地址: " .. ip)
    print("即将启动sendData()...")
    sendData(humidity, temperature)
    print("从sendData()返回...")
end

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

尝试连接...
尝试连接...
尝试连接...
尝试连接...
尝试连接...
尝试连接...
成功获取IP地址: 192.168.0.39
即将启动sendData()...
进入sendData()函数
设置mqtt.Client...
尝试连接客户端...
从sendData()返回...

所以它基本上进入了sendData(...),我看到print("尝试连接客户端...")这一行的输出......

print("尝试连接客户端...")

...但我从未看到m:connect(...)块中的日志,比如...

print("连接到MQTT")

...它似乎立即返回。

MQTT代理是运行Mosquitto的Raspberry Pi,我已经在我的Android手机和平板电脑上测试过它。我在两个方向上的手机和平板电脑之间获得了成功的发布/订阅。

我是一个Lua新手,只理解MQTT的基础知识,对于m:connect(...)块出了什么问题,如果有人能帮忙,将不胜感激。

更新:问题已解决 - 很抱歉没能及时回复此线程。问题简单地归结为我在RPi上运行的Mosquitto版本(兼容MQTT v3.1)。NodeMCU MQTT库支持MQTT v3.1.1,不向后兼容。实质上,我的代码没有太大问题,尽管我做了一些更改——MQTT版本不兼容。

点赞
用户2858170
用户2858170

你的代码看起来很好。如果 m:connect 失败了,由于你没有为连接失败尝试提供回调函数,什么都不会发生。

此外,你没有检查 m:connect 的返回值是否成功。

请参阅 http://nodemcu.readthedocs.org/en/dev/en/modules/mqtt/#mqttclientconnect 并检查你的连接尝试是否失败。

2016-04-16 17:25:23
用户131929
用户131929

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

我总是帮助去掉失败的函数并利用所有可用的回调函数。我可以确认以下工作在‘dev’分支上的一个近2个月的固件发送数据到 cloudmqtt.com:

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 明确地定义了安全性和自动重新连接标志。如果只设置所有可选参数的子集,它总是让我感到困惑。在 m:connect 中的 0 是否被解释为 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),然后在该函数内部再次使用 m:publish(..,function(conn)。您的代码中不与 conn 对象交互,因此没有问题。但是,在其他项目中可能会伤及大局。
2016-04-17 08:36:58