local bridge = 'ip of the bridge'
local usr = 'same user as api v1'
-- bridge communication base
function hueExec(iMethod, iCommand, iBody)
resp = {}
body = json.encode(iBody)
res, code, headers = https.request({
url = 'https://'..bridge..'/clip/v2/resource'..iCommand,
method = iMethod,
source = ltn12.source.string(body),
sink = ltn12.sink.table(resp),
headers = { ['hue-application-key'] = usr,
['Content-Type'] = 'application/json',
['Accept'] = 'application/json',
['Content-Length'] = #body
}
})
-- handle feedback
if not res or code ~= 200 then
return
else
resp = table.concat(resp)
resp = json.pdecode(resp)
return resp
end
end
-- get all lights
function getLights()
return hueExec('GET', '/light')
end
--log(getLights())
-- get light
function getLight(iLight)
return hueExec('GET', '/light/'..iLight)
end
--log(getLight('e4a834c9-9ca3-4f2d-98be-669c55a90b5d'))
-- activate scene (active or dynamic_palette)
function runScene(iScene, iAction)
vAction = iAction or 'active'
hueExec('PUT', '/scene/'..iScene, {recall = {action = vAction}})
end
--runScene('185d4226-213e-4f01-913b-91c22d85bfac') -- living soho scene
--runScene('185d4226-213e-4f01-913b-91c22d85bfac', 'dynamic_palette') -- living soho dynamic
Events have an id, timestamp, type (‘update’, ‘add’, ‘delete’, ‘error’), and data field which contains the changed properties of the resource in the same format as a GET response on the same resource type. The following is an example event stream that would result from turning a light on and off:
On HTTP1.1, you will need a separate connection for the SSE request and regular requests, but we recommend using HTTP2 to multiplex them over a single connection which is more resource efficient.
Currently there is a 1 second rate limit on the amount of event containers the Bridge will send. If the same property has changed twice within that timeframe, you only get the last state. If multiple resources have changed within that timeframe, you will get multiple events grouped in a single container.
(02.02.2022, 15:53)admin Wrote: You can adapt this code for your use case: https://forum.logicmachine.net/showthrea...1#pid15941
Add headers to initial request lines and change APPKEY to the actual application key:
yep, curl for windows code works:
curl --insecure -N -H "hue-application-key: sameapiuserasbefore" -H "Accept: text/event-stream" https://myipaddress/eventstream/clip/v2
and thx, the raw socket example works also.
working code for evenstream
Code:
if not sock then
host = 'fillyourip'
port = 443
proto = 'tlsv12'
path = '/eventstream/clip/v2'
appkey = 'fillyouruser'
require('ssl')
sock = require('socket').tcp()
sock:settimeout(10)
res, err = sock:connect(host, port)
if res then
sock = ssl.wrap(sock, proto)
res, err = sock:dohandshake()
if res then
sock:send(
'GET ' .. path .. ' HTTP/1.1\r\n' ..
'Host: ' .. host .. '\r\n' ..
'Accept: text/event-stream\r\n' ..
'hue-application-key: ' .. appkey .. '\r\n' ..
'\r\n'
)
else
log('handshake failed: ' .. tostring(err))
end
else
log('connect failed: ' .. tostring(err))
sock:close()
end
end
line, err = sock:receive()
if line then
--log('line: ' .. line)
if line:find(': hi') then
log('connection ok: ', line)
elseif line:find('data:') then
--status = line:split(':')[2]
log('data', line)
end
else
log('receive failed: ' .. tostring(err))
sock:close()
sock = nil
end
line output: data: [{"creationtime":"2022-02-03T13:35:32Z","data":[{"id":"f2ef58b3-818e-45ea-a291-325e8eeb97bc","id_v1":"/lights/10","on":{"on":false},"owner":{"rid":"0120cec8-b58e-4206-a409-2bd99055af55","rtype":"device"},"type":"light"}],"id":"49142b93-3da7-49dc-9ad6-10809df8fe9d","type":"update"}]
Code:
line = string.sub(line,8,-2) -- remove "data: [" and the last ] character
line = json.pdecode(line)
This works
But the second output combines more lines, how to decode this line?
line output:
data: [{"creationtime":"2022-02-03T13:35:32Z","data":[{"id":"728be63c-dc61-42b1-9a84-54daeff76046","id_v1":"/groups/0","on":{"on":false},"type":"grouped_light"}],"id":"b201d09a-0ab2-4a60-b72f-3a099841ebbc","type":"update"},{"creationtime":"2022-02-03T13:35:32Z","data":[{"id":"33b4f136-c59e-4270-83af-814c4f5ba856","id_v1":"/groups/18","on":{"on":false},"type":"grouped_light"}],"id":"e2860e1b-ebd0-40b0-81ed-f1c0b27163a3","type":"update"},{"creationtime":"2022-02-03T13:35:32Z","data":[{"id":"7a8f900c-c312-403a-bf73-9d2fcb005489","id_v1":"/groups/19","on":{"on":false},"type":"grouped_light"}],"id":"1cc814e9-9210-4e75-92c0-29a543c32dcb","type":"update"}]
10.01.2023, 09:16 (This post was last modified: 10.01.2023, 09:21 by Joep.)
I would like to contribute on this and started with the Hue discovey by changing the script i found from https://forum.logicmachine.net/showthrea...4#pid24214
Below the modified version that gives all the Hue Bridge information with most important the IP address.
if not sock then
host = 'x.x.x.x'
port = 443
proto = 'tlsv12'
path = '/eventstream/clip/v2'
appkey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
require('ssl')
sock = require('socket').tcp()
sock:settimeout(10)
res, err = sock:connect(host, port)
if res then
sock = ssl.wrap(sock, proto)
res, err = sock:dohandshake()
if res then
sock:send(
'GET ' .. path .. ' HTTP/1.1\r\n' ..
'Host: ' .. host .. '\r\n' ..
'Accept: text/event-stream\r\n' ..
'hue-application-key: ' .. appkey .. '\r\n' ..
'\r\n'
)
else
log('handshake failed: ' .. tostring(err))
end
else
log('connect failed: ' .. tostring(err))
sock:close()
end
end
line, err = sock:receive()
if line then
log('line: ' .. line)
if line:find(': hi') then
log('connection ok: ', line)
elseif line:find('data:') then
line = '{"data": '..string.sub(line,7)..'}'
log('textline',line)
line = json.pdecode(line)
log(line.data)
for _l,l_items in pairs(line.data) do
log(l_items)
log(l_items.type, l_items.data[1].id_v1, l_items.data[1].on.on)
end
end
else
log('receive failed: ' .. tostring(err))
sock:close()
sock = nil
end