NodeMCU + MQTT + relé vezérlés egy lua-val

 ( Hyperion | 2016. február 25., csütörtök - 9:30 )

Sziasztok!

Bocs a kusza címért.
Hobbiprojektnél ismerkedem a nodeMCU-s lua programozással.
Amit szeretnék:

- DHT22-n kinyert hőmérséklet + páratartalom küldése az MQTT felé(Openhab interfésszel)
- Relé modul vezérlése, az MQTT-től kapott álapottal.

Nem bonyolult, külön-külön szépen működik. Viszont 1 szkriptbe nem bírom összehozni.
Ugyanis, ha bontom a subscribe-et hogy elküldjem a hőmérséklet adatokat, a relé állapotváltozást, értelem szerűen nem fogja ezen id alatt lekövetni.

Tudtok esetleg példaprogramkódot linkelni, vagy javaslatot adni?

Mindenképpen csak NodeMCU-t szeretnék használni, külső eszközt(Raspi, Ardu-t) nem szeretnék bevonni.

Köszönöm!

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

sub
Nálam is tervben van egy ilyen implementáció, de még nem kezdtem neki, csak figyelek.

Félek, hogy marad a 2 eszköz.. Nem nagy összeg, kb 600Ft az ESP8266, de azért jobb lett volna 1-ben. :/

Nem hiszem, hogy ne lehetne megoldani, de tapasztalatom még nincs vele, talán majd a hétvégén. :)

Valószínű hogy meglehet, de kérdés hogy ez mennyire fogja befolyásolni az üzembiztonságot. Azon az állásponton vagyok, hogy inkább sok kis szegmensből álljon a rendszer(LED vezérlő, TV áramellátás, termosztát stb) így, kisebb galibát okoz ha valami gond van..
Pl.: Készítettem egy fél éve egy arduinós, esp-s időjárás-állomást, egyben cirkóvezérléssel.
Netről szedi az előrejelzést + kommunikál a lakás érzékelőivel (DHT22). Tök jól működött kb 2 hétig. Majd gondolt egyet és berántotta a relét, ezzel elindítva a fűtést majd lefagyott..
Mire hazaértünk, volt vagy 28fok a lakásban! :x

Szóval azóta kicsit óvatosabb vagyok :)
(Megjegyzem azóta sem tudom, hogy miért volt ez a bug.:))

Nekem pár éjszakám volt így... elég rossz érzés így ébredni. Bár, esetedben, hogy nem voltál otthon sem jobb...

A probléma az volt, hogy naívan vettem egy analóg frevenciás Sony vezeték nélküli fejhallgatót (azóta már kicseréltem 2,4Ghz-s Pioneer-ra). Amikor áram alatt volt a Sony adó egysége (ha használtam, ha nem), elnyomta a cirkó felé menő Computherm wireless rádiófrekvenciás termosztát "lekapcsolás" üzenetet.
Ezt követően a termosztát úgy tekintette, hogy az üzenet elment (visszaigazolást nem várt) és vígan mérte az emelkedő hőmérsékletet.

Ekkor határoztam el, hogy majd én is inkább saját rendszert építek, ahol a hőmérő a zsinór nélküli és a döntéshozó a kábeles...!
Még nem csináltam meg, de ami késik nem múlik... főleg, hogy a fiam új távirányítós autója is hasonlókat kezd csinálni, így minden nap figyelni kell, hogy ne maradjon bekapcsolva....

A dht már hetek óta stabil, az adc-re kötött fotoellenállás szintén. Pár napja a relé is gond nélkül megy. Nem a nodemcu boarddal csináltam csak egy natúr esp12e van összeforrasztva.


wifi.setmode(wifi.STATION)
wifi.setphymode(wifi.PHYMODE_N)
wifi.sta.config("apname", "appasswd")

relay = gpio.LOW
gpio.mode(8, gpio.OUTPUT)

m = mqtt.Client("mymqttendpoint", 120, "", "")
conn = false

function tick()
if wifi.sta.status() ~= 5 then
conn = false
return
end
if not conn then
m:connect("test.mosquitto.org", 1883)
return
end
s, t, h, td, hd = dht.readxx(4)
if s == dht.OK then
m:publish("mysensor/esp1/temperature", t.."."..td, 0, 0)
m:publish("mysensor/esp1/humidity", h.."."..hd, 0, 0)
end
m:publish("mysensor/esp1/light", adc.read(0)..".0", 0, 0)
end

m:on("connect", function(c)
conn = true
m:subscribe("mysensor/esp1/relay", 0)
tick()
end)

m:on("offline", function(c)
m:close()
conn = false
end)

m:on("message", function(c, topic, data)
if data == "on" then
relay = gpio.HIGH
elseif data == "off" then
relay = gpio.LOW
elseif data == "toggle" then
if relay == gpio.LOW then
relay = gpio.HIGH
else
relay = gpio.LOW
end
end
gpio.write(8, relay)
end)

tmr.alarm(0, 10000, tmr.ALARM_AUTO, tick)

Sub

+1

Tökéletes...
Stabil, gyors.

Köszönöm, kicsit átfaragom és tesztelem huzamosabb ideig!

Későn találtam erre a threadre, de talán lehet érdekes ez a megoldás is. Egy példaprogramot faragtam át, nem értek a LUA-hoz és nem tudom, miért így lett megoldva:

init.lua:

-- file : init.lua
app = require("application")
config = require("config")
setup = require("setup")

setup.start()

config.lua:

-- file : config.lua
local module = {}

module.SSID = {}
module.SSID["***"] = "***"

module.HOST = "172.***"
module.PORT = 1883
module.ID = node.chipid()

module.ENDPOINT = "saabi/sensors/room/"
return module

setup.lua:

-- file: setup.lua
local module = {}

local function wifi_wait_ip()
    if wifi.sta.getip()== nil then
        print("IP unavailable, waiting...")
    else
        tmr.stop(1)
        print("\n====================================")
        print("ESP8266 mode is: " .. wifi.getmode())
        print("MAC address is: " .. wifi.ap.getmac())
        print("IP is : " .. wifi.sta.getip())
        print("====================================")
        app.start()
    end
end

local function wifi_start(list_aps)
    if list_aps then
        for key,value in pairs(list_aps) do
            if config.SSID and config.SSID[key] then
                wifi.setmode(wifi.STATION)
                wifi.sta.config(key,config.SSID[key])
                wifi.sta.connect()
                print("Connecting to " .. key .. " ...")
                -- config.SSD = nil -- can save memory
                tmr.alarm(1, 2500, 1, wifi_wait_ip)
            end
        end
    else
        print("Error getting AP list")
    end
end

function module.start()
    print("Configuring WiFi ...")
    wifi.setmode(wifi.STATION);
    wifi.sta.getap(wifi_start)
end

return module

application.lua:

-- file : application.lua
local module = {}
m = nil
dhtpin = 4
sw1pin = 1
sw2pin = 2

gpio.mode(sw1pin, gpio.INT, gpio.PULLUP)
gpio.mode(sw2pin, gpio.INT, gpio.PULLUP)

function sw1pushed()
    m:publish("saabi/switches/SW1","CLOSED",0,0)
    tmr.delay(50)
    gpio.trig(sw1pin, "up", sw1released)
end

function sw1released()
    m:publish("saabi/switches/SW1","OPEN",0,0)
    tmr.delay(50)
    gpio.trig(sw1pin, "down", sw1pushed)
end

function sw2pushed()
    m:publish("saabi/switches/SW2","CLOSED",0,0)
    tmr.delay(50)
    gpio.trig(sw2pin, "up", sw2released)
end

function sw2released()
    m:publish("saabi/switches/SW2","OPEN",0,0)
    tmr.delay(50)
    gpio.trig(sw2pin, "down", sw2pushed)
end

local function send_temp()
    status, temp, humi, temp_dec, humi_dec = dht.read(dhtpin)
    if status == dht.OK then
        print("Temp: "..temp)
        m:publish(config.ENDPOINT .. "temp",temp,0,0)
        m:publish(config.ENDPOINT .. "humi",humi,0,0)
    end
end

local function register_myself()
    m:subscribe(config.ENDPOINT .. config.ID,0,function(conn)
        print("Successfully subscribed to data endpoint")
    end)
end

local function mqtt_start()
    m = mqtt.Client(config.ID, 120)
    m:connect(config.HOST, config.PORT, 0, 1, function(conn)
        register_myself()
        tmr.stop(6)
        tmr.alarm(6, 200000, tmr.ALARM_AUTO, send_temp)
        gpio.trig(sw1pin, "down", sw1pushed)
        gpio.trig(sw2pin, "down", sw2pushed)
    end)
end

function module.start()
    mqtt_start()
end

return module

Két kapcsoló állapotát is küldi, ezeket használom az előszoba és nappali világításának kapcsolására.

Ave, Saabi.