PDA

View Full Version : FIBARO control from Girder-passing response value to action script



MarBe
January 11th, 2016, 02:55 PM
Hi,
I try to use Girder to control devices on FIBARO via http get.
It works, but only the respose from get on reading I cannot to pass to action script.
It hang up with function

cb(true, response)

How to pass the response value to action script?
FIBARO:readDevice(83)

Thank you very much.


Error code at Girder console
po led 11 21:50:51 2016 http_callback / .../Program Files/Promixis/Girder 6/lua/FIBARO/init.lua:99: attempt to call upvalue 'cb' (a nil value)
po led 11 21:50:51 2016 stack traceback:
po led 11 21:50:51 2016 .../Program Files/Promixis/Girder 6/lua/FIBARO/init.lua:99: in function 'cb'
po led 11 21:50:51 2016 .../Program Files/Promixis/Girder 6/lua/FIBARO/init.lua:71: in function <.../Program Files/Promixis/Girder 6/lua/FIBARO/init.lua:44>

_______________________
The action script

if not FIBARO then
require('FIBARO')
FIBARO = FIBARO.new("ip", 11111, "user", "pass")
end


local cb
FIBARO:readDevice(83)

FIBARO:setDeviceSwitch(83,"turnOn")
FIBARO:setDeviceDimmer(109,99)
____________________
/girder6/lua/fibaro/init.lua

--[[

FIBARO
Copyright 2014(c) Promixis, LLC
Licensed for use with Promixis software.

Example Use Girder 6

if not FIBARO then
require('fibaro')
K = fibaro.new("[ip adress]", 11111, "user", "pass")
end

FIBARO:readDevice(83)
FIBARO:setDeviceSwitch(83,"turnOn")
FIBARO:setDeviceDimmer(83,99)


--]]

local table = require('table')
local print = print
local class = require('Class')
local network = require('network')
local response = {}

-- [[ GIRDER 6
local json = require('json')
local network = require('network')
module(...)
--]]

--[[ GIRDER 5
local json = require('json.json')
module("kodi")
--]]



class:subclass( _M )

local function worker( self, url, cb )

network.get( url, function( success, status, body )
--print("ASDF", success, status, body)
if not success then
cb(false)
return
end

local response = json.decode(body)

if not response then
print("Could not parse response", data)
cb(false)
return
end
--[[
if request.id and request.id ~= response.id then
print("RequestID and ResponseID do not match", request.id, response.id, data)
cb(false)
return
end
]]--
if response.error then
print("Request Error", response.error.message, response.error.code, j)
cb(false)
return
end

cb(true, response)

end, 1000, self.username, self.password )
end

function readDevice( self, deviceID, cb )

local url = "http://" .. self.ip .. "/api/devices?id=" .. deviceID
worker( self, url, function( success, response )

if not success then
print("Request failed")
if cb then
cb(false)
end
return
end

if not response then

print("No result found")
if cb then
cb(false)
end
return
end
--table.print(response)
cb(true, response)

end )
end

function setDeviceSwitch( self, deviceID, command, cb )

local url = "http://" .. self.ip .. "/api/callAction?deviceID=" .. deviceID .. "&name=" .. command
worker( self, url, function( success, response )

if cb then
cb(success)
end

end )
end

function setDeviceDimmer( self, deviceID, value, cb )

local url = "http://" .. self.ip .. "/api/callAction?deviceID=" .. deviceID .. "&name=setValue&arg1=" .. value
worker( self, url, function( success, response )

if cb then
cb(success)
end

end )

end


function init ( self, ip, port, username, password )

if not port then
port = 80
end

if not ip then
ip = "127.0.0.1"
end

self.ip = ip
self.port = port
self.username = username
self.password = password
end

function deinit()
self.ip = nil
self.port = nil
end

Ron
January 11th, 2016, 03:35 PM
This is an asynchronous request. That means it needs a callback function that you give it. The CB parameter. In this example below I've made an anonymous function where the CB parameter is.



FIBARO:readDevice(83, function( status, response)
print('result = ', status, response)
end)

MarBe
January 11th, 2016, 04:58 PM
Yes, thats it! Thanks

if not FIBARO then
require('FIBARO')
FIBARO = FIBARO.new("192.168.11.81", 11111, "admin", "heslo4admin")
end

FIBARO:readDevice(83, function( status, response)
print('result = ', status)
print(response.properties.value)
end)


FIBARO:setDeviceSwitch(83,"turnOff", function( status )
print('result = ', status)
end)
FIBARO:setDeviceDimmer(109,99, function( status )
print('result = ', status)
end)

MarBe
January 13th, 2016, 02:07 PM
Please, onemore help, how to pass the response value outside the function?
This work not, retur response at function does not return it to the script and last print(response) get nil value.
Thank you

FIBARO:readDevice(83, function(status, response)
print('result = ', status)
print(response.properties.value)
return response
end)

print(response);

Ron
January 13th, 2016, 02:20 PM
The anonymous function (https://en.wikipedia.org/wiki/Anonymous_function) that is passed as a callback is run asynchronously to the rest of the code. That means that the "print(response)" part happens before the "print('result = ', status)" part. Thus response is not set yet.

Whatever you need to do with the response needs to be done inside the anonymous function(status,reponse)...end. (this can include calling other functions again).

edit: the "return response" part does nothing for you here.