Горячая линия Embedded System Rus:8-800-775-06-34 (звонок по России бесплатный)

LM5_N
LM-Wall_N
DALI_N
Vita_N

Чтение данных из счетчика 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