Управление освещением
    Презентации
    Технические решения на LogicMachine
    Визуализация
      evika.ru    Технические решения на LogicMachine    LogicMachine как TCP сервер для внешних запросов

    LogicMachine как TCP сервер для внешних запросов

    Задача

    При каждом изменении значения объекта ’1/1/1′, посылаем TCP сообщения всем подсоединенным внешним TCP клиентам.

    UDP клиентская функция

    Функция должна быть добавлена в Скрипты –> Общие функции (Scripting -> Common functions).
    Эта функция получает в качестве параметра переменную «текстовая строка» и посылает ее UDP серверу, который в свою очередь рассылает ее всем подсоединенным клиентам по TCP.

    function udpsend(message)	
        require('socket')	
     
        local client = socket.udp()	
        -- upd client ready, send to local port 23456	
        if client then	
            client:sendto(message, '127.0.0.1', 23456)	
            client:close()	
        end	
    end

    Резидентный скрипт – реализация сервера

    Добавим следующий резидентный скрипт с значением параметра Sleep interval, равным «0».
    Далее необходимо описать TCP и UDP сервер. После того, как TCP пошлет сообщение “HELLO”, а TCP сервер/LogicMachine пришлет ответ “HELLO YOU TOO”, соединение будет установлено.

    -- init server handler	
    if not ready then	
        require('copas')
     
        -- list of client sockets	
        clients = {}
     
        -- incoming data handler	
        function datahandler(sock, data)	
            local ip, port
    	ip, port = sock:getpeername()
    	alert('[server] data from %s:%d - %s', ip, port, data)
     
            -- send reply
    	if data == 'HELLO' then
    	    sock:send('HELLO TO YOU\r\n')
    	end
        end
     
        -- connection handler
        function connhandler(sock)
            -- enable keep-alive to check for disconnect events
    	sock:setoption('keepalive', true)
     
            local ip, port, data, err, id
     
            -- get ip and port from socket
    	ip, port = sock:getpeername()
     
            -- client id
    	id = string.format('%s:%d', ip, port)
     
            alert('[server] connection from %s', id)
     
            -- save socket reference
    	clients[ id ] = sock
     
            -- main reader loop
    	while true do
    	    -- wait for single line of data (until \n, \r is ignored)
    	    data, err = copas.receive(sock, '*l')
     
                -- error while receiving
    	    if err then
    	        alert('[server] closed connection from %s:%d', ip, port)
    	        -- remove socket reference
    	        clients[ id ] = nil
    	        return
    	    end
     
    	    -- handle data frame
    	    datahandler(sock, data)
    	end
        end
     
        -- bind to port 12345
        tcpserver = socket.bind('*', 12345)
     
        -- error while binding, try again later
        if not tcpserver then
            os.sleep(5)
    	error('[server] error: cannot bind')
        end
     
        -- set server connection handler
        copas.addserver(tcpserver, connhandler)
     
        -- create local udp server on port 23456
        udpserver = socket.udp()
        udpserver:setsockname('127.0.0.1', 23456)
        udpserver:settimeout(0.1)
     
        ready = true
    end
     
    -- perform server tasks for one second (5 x (0.1 + 0.1))
    for i = 1, 5 do
        message = udpserver:receive()
     
        -- got message from udp, send to all active clients
        if message then
            for id, sock in pairs(clients) do
    	    sock:send(message .. '\r\n')
    	end
        end
     
        copas.step(0.1)
    end

    Программа обработки событий

    Событийный скрипт, основанный на событии будет отслеживать объект ’1/1/1′. В случае включения объекта ( лампы) будет послано сообщение “Lamp is ON” всем TCP клиентам, которые в данный момент подключены к TCP серверу LogicMachine. В случае же выключения объекта будет передано сообщение – “Lamp is OFF”.

    value = event.getvalue()
    udpsend('Lamp is ' .. (value and 'ON' or 'OFF'))




    Copyright © Evika.ru 2017
    All Rights Reserved