Управление освещением
    Презентации
    Технические решения на LogicMachine
    Визуализация
      evika.ru    Технические решения на LogicMachine    Чтение данных из счетчика Plugwise Smile P1 с помощью HTTP запросов (пример разбора xml)

    Чтение данных из счетчика Plugwise Smile P1 с помощью HTTP запросов (пример разбора xml)

    Пример: Чтение данных из счетчика Plugwise Smile P1 с помощью HTTP запросов из LogicMachine

    Plugwise Smile P1

    Счетчик Plugwise Smile P1 дает возможность получать данные в реальном времени о потреблении газа и электричества прямо на телефоне или планшете.

    Создадим резидентный скрипт или скрипт по расписанию. Скопируем в него следующий код, который будет при каждом вызове получать данные о потребление газа и электричества, текущие значение и максимальные.

    require('socket.http')
     
    socket.http.TIMEOUT = 5
    smiledata = socket.http.request('http://192.168.178.49/smartmeter/modules')
    smiletabel=collect(smiledata)
     
    if not smiledata then
    	alert('Smile: cannot fetch data')
    end
     
    -- data parser
    peak=tonumber(smiletabel[2][2][3][1][4][1][1])
    offpeak=tonumber(smiletabel[2][2][3][2][4][1][1])
    gas=tonumber(smiletabel[2][1][1][1][4][1][1])
    electranow=tonumber(smiletabel[2][2][4][1][4][1][1])
     
    storage.set('offpeak',offpeak)
    storage.set('peak',peak)
    storage.set('gas',gas)
    storage.set('electranow',electranow)
     
    totalmeter=(peak+offpeak)
    storage.set('totalmeter',totalmeter)
    totalgas=(gas)
    storage.set('totalgas',totalgas)
     
    if electranowoud~=electranow then
    	grp.write('7/0/50',electranow)
    end
     
    os.sleep(1)
     
    if totalmeteroud~=totalmeter then
    	grp.write('7/0/51',totalmeter)
    end
     
    os.sleep(1)
     
    if peakoud~=peak then
    	grp.write('7/0/53',peak)
    end
     
    os.sleep(1)
     
    if offpeakoud~=offpeak then
    	grp.write('7/0/54',offpeak)
    end
     
    os.sleep(1)
     
    if gasoud~=gas then
    	grp.write('7/0/55',gas)
    end
     
    --counters
    if not totalmeterlast then
    	totalmeterlast=totalmeter
    end
     
    if not totalmeter then
    	totalmeter=0
    end
     
    if not kwhteller then
    	kwhteller=0
    end
     
    kwhdelta=(totalmeter-totalmeterlast)
    kwhteller=storage.get('kwhteller',0)+kwhdelta
    grp.write('7/0/52',kwhteller)
    totalmeterlast=totalmeter
    storage.set('kwhteller',kwhteller)
     
    if not totalgaslast then
    	totalgaslast=totalgas
    end
     
    if not totalgas then
    	totalgas=2
    end
     
    if not gasteller then
    	gasteller=3
    end
     
    gasdelta=(totalgas-totalgaslast)
    gasteller=storage.get('gasteller',4)+gasdelta
    grp.write('7/0/56',gasteller)
    totalgaslast=totalgas
    storage.set('gasteller',gasteller)
     
    electranowoud=electranow
    totalmeteroud=totalmeter
    peakoud=peak
    offpeakoud=offpeak
    gasoud=gas

    XML parser

    Добавьте функцию разбора xml строки в Common functions

    ---xml parser
    function parseargs(s)
      local arg = {}
      string.gsub(s, "(%w+)=([\"'])(.-)%2", function (w, _, a)
        arg[w] = a
      end)
      return arg
    end
     
    function collect(s)
      local stack = {}
      local top = {}
      table.insert(stack, top)
      local ni,c,label,xarg, empty
      local i, j = 1, 1
      while true do
        ni,j,c,label,xarg, empty = string.find(s, "", i)
        if not ni then break end
        local text = string.sub(s, i, ni-1)
        if not string.find(text, "^%s*$") then
          table.insert(top, text)
        end
        if empty == "/" then  -- empty element tag
          table.insert(top, {label=label, xarg=parseargs(xarg), empty=1})
        elseif c == "" then   -- start tag
          top = {label=label, xarg=parseargs(xarg)}
          table.insert(stack, top)   -- new level
        else  -- end tag
          local toclose = table.remove(stack)  -- remove top
          top = stack[#stack]
          if #stack < 1 then
            error("nothing to close with "..label)
          end
          if toclose.label ~= label then
            error("trying to close "..toclose.label.." with "..label)
          end
          table.insert(top, toclose)
        end
        i = j+1
      end
      local text = string.sub(s, i)
      if not string.find(text, "^%s*$") then
        table.insert(stack[#stack], text)
      end
      if #stack > 1 then
        error("unclosed "..stack[#stack].label)
      end
      return stack[1]
    end

     




    Copyright
    © Embedded Systems Rus
    2017. All Rights Reserved