Post your best Lua script examples here

User avatar
By Asterion
#50121
WEMOS D1 R2 (http://www.wemos.cc/Products/d1_r2.html) running:
    NodeMCU custom build by frightanic.com
    branch: master
    commit: c8037568571edb5c568c2f8231e4f8ce0683b883
    SSL: true
    modules: adc,bit,bmp085,cjson,coap,crypto,dht,enduser_setup,file,gpio,hx711,i2c,mqtt,net,node,ow,pwm,rc,rtcfifo,rtcmem,rtctime,sntp,spi,tmr,u8g,uart,wifi
    build built on: 2016-02-25 14:44
    powered by Lua 5.1.4 on SDK 1.4.0

I connect to my home wifi with:

    wifi.setmode(wifi.STATION)
    wifi.sta.config("SSID","password") # yes with my SSID and password
    print(wifi.sta.getip())

The print function above (of course) will return the IP address of the WEMOS board so I am happy the board is connecting with the wifi.

So, having checked the board is connected to wifi I then use a cutdown of the mqtt example from wikipedia being:

    m = mqtt.Client("clientid", 120, null, null)
    m:lwt("/lwt", "offline", 0, 0)
    m:on("connect", function(con) print ("connected") end)
    m:on("offline", function(con) print ("offline") end)
    m:connect("192.168.0.48", 1883, 0)
    m:publish("hello","there",0,0)
    m:close();



The error I get is:
    dofile("script2.lua")
    script2.lua:21: not connected
    stack traceback:
    [C]: in function 'publish'
    script2.lua:21: in main chunk
    [C]: in function 'dofile'
    stdin:1: in main chunk

I am running emqtt console and don't see a connection from the WEMOS. I am running both a node-red and paho python subscribe clients and I can subscrive with a node-red publisher. I see activity on the node-red and the paho-python client so I know that is all set up correctly.

But there is a quirk with the nodemcu I am not quite getting. Any hints please?

Cheers,
A
User avatar
By marcelstoer
#50136 I guess you need to get accustomed to the asynchronous nature of NodeMCU/Lua. Most function calls are non-blocking which means you need to work with the provided callback hooks. More specifically you can only publish a message once your client has successfully connected to the broker.

So, either you connect first whenever you need to publish a message thereby publishing in the callback of mqtt.client:connect. Or you somehow ensure you're always connected and keep a "MQTT connection state" flag somewhere. That can be accomplished with something like this

Code: Select alllocal mqttConnected = 0
local mq = mqtt.Client(MQTT_CLIENT, 300, MQTT_USER, MQTT_PASS)
function configureMqtt()
  tmr.alarm(MQTT_ALARM_ID, 1111, 1, connectToBroker)

  mq:on("offline", function(connection)
    print("MQTT: offline")
    mqttConnected = 0
  end)
  mq:on("connect", function(connection)
    print("MQTT: 'on connect' received")
  end)
end

function connectToBroker()
  if wifiReady == 1 and mqttConnected ~= 1 then
    turnMqttLedOnOff()
    mq:connect(MQTT_HOST, MQTT_PORT, 0, function(connection)
      print("MQTT: connected to " .. MQTT_HOST .. ":" .. MQTT_PORT .. " as '" .. MQTT_CLIENT .. "'")
      mqttConnected = 1
      turnMqttLedOn()
    end)
  end
end

function publishToBroker(state)
  if mqttConnected == 1 then
    print("MQTT: publishing '" .. state .. "'")
    mq:publish(MQTT_TOPIC, state, 0, 0, function(conn)
      print("MQTT: ...done")
    end)
  else
    connectToBroker()
    publishToBroker(state)
  end
end