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