Kamis, 10 November 2016

Tutorial NodeMCU: Membuat telnet server (ESP8266, WeMos, Lua)

Tulisan ini saya buat setelah berpikir bagaimana dapat mengendalikan board WeMos melalui telnet via jaringan, berdasarkan hasil browsing kita dapat melakukannya melalui interface web dengan membuat HTTP Server, pendekatan lainnya adalah membuat telnet server.

Suatu telnet server adalah menerima koneksi melalui port 23. Software client yang dapat digunakan adalah Putty. Interfacing antara server dengan client adalah menggunakan event on receive yang akan menerima payload dari client. payload akan dikirim ke interpreter Lua untuk diproses dengan menggunakan perintah node.input(payload), hasil dari interpreter akan dikirim kembali ke klien dengan melakukan redirect output ke suatu fungsi yang sudah disiapkan. Untuk jelasnya dapat dilihat pada source code berikut ini:

credentials.lua
Dapat dilihat pada tulisan sebelumnya
init.lua
Dapat dilihat pada tulisan sebelumnya
app.lua
-- a simple telnet server
-- diadaptasi dari internet oleh Hendra Soewarno (19067305)


telnet_srv = net.createServer(net.TCP, 180)
telnet_srv:listen(23, function(socket)
    local fifo = {}
    local fifo_drained = true

    local function sender(c)
        if #fifo > 0 then
            c:send("\r" .. table.remove(fifo, 1))
        else
            fifo_drained = true
        end
    end

    local function s_output(str)
        table.insert(fifo, str)
        if socket ~= nil and fifo_drained then
            fifo_drained = false
            sender(socket)
        end
    end

    node.output(s_output, 0)   -- mengarahkan output ke function s_ouput.

    socket:on("receive", function(c, l)
        if string.byte(l) == 255 then
        elseif string.byte(l) == 26 then
            c:close()         -- ctrl-z to exit
        else
            node.input(l)  -- works like pcall(loadstring(l)) but support multiple separate line
        end    
    end)
    socket:on("disconnection", function(c)
        node.output(nil)  -- un-regist the redirect output function, output goes to serial
    end)
    socket:on("sent", sender)

    print("Welcome to NodeMCU world.\r\nPress Enter to continue or Ctrl-Z to close.")
end)

 Gambar 1. Memulai untuk telnet ke server

Gambar 2. Sesi telnet untuk menghidupkan Led Builtin pada board

Tekan Ctrl-Z untuk mengakhiri sesi telnet

Contoh telnet server yang dilengkapi dengan perintah ls, sntp, dan time.

-- a simple telnet server
-- diadaptasi dari internet oleh Hendra Soewarno (19067305)

telnet_srv = net.createServer(net.TCP, 180)
telnet_srv:listen(23, function(socket)
    local fifo = {}
    local fifo_drained = true

    local function sender(c)
        if #fifo > 0 then
            c:send("\r" .. table.remove(fifo, 1))
        else
            fifo_drained = true
        end
    end

    local function s_output(str)
        table.insert(fifo, str)
        if socket ~= nil and fifo_drained then
            fifo_drained = false
            sender(socket)
        end
    end

    node.output(s_output, 0)   -- mengarahkan output ke function s_ouput.

    local function ls()
        l = file.list();
        for k,v in pairs(l) do
            print(k.."("..v .. ")")
        end
    end

    local function time()
        utc = rtctime.epoch2cal(rtctime.get())
        print("UTC:" .. string.format("%04d/%02d/%02d %02d:%02d:%02d", utc["year"], utc["mon"], utc["day"], utc["hour"], utc["min"], utc["sec"]))
    end   

    local function _sntp()

        sntp.sync("1.id.pool.ntp.org",

        function(sec,usec,server)
            print("setting time from: " .. server)
            rtctime.set(sec, usec)
            time()
        end,

        function()
            print('failed!')
        end)
    end
   
    socket:on("receive", function(c, l)
        if string.byte(l) == 255 then
        elseif string.byte(l) == 26 then
            c:close()         -- ctrl-z to exit
        elseif string.sub(l,1,2) == "ls" then
            ls()
        elseif string.sub(l,1,4) == "time" then
            time()
        elseif string.sub(l,1,4) == "sntp" then
            _sntp()                       
        else
            node.input(l)  -- works like pcall(loadstring(l)) but support multiple separate line
        end   
    end)
    socket:on("disconnection", function(c)
        node.output(nil)  -- un-regist the redirect output function, output goes to serial
    end)
    socket:on("sent", sender)

    print("Welcome to NodeMCU world.\r\nPress Enter to continue or Ctrl-Z to close.")
end)

Tidak ada komentar:

Posting Komentar