Home Center 3 / Yubii Home – Quick Apps
Quick Apps are used to extend the capabilities of the FIBARO System. It enables you to create new integrations in the system that support TCP/IP devices or create specific connected devices.
The entire code written within a given Quick App is running in one environment. It refers to both the main code and the code for controlling the controls. This makes it possible, for example, to create a TCP connection in the main part of the code and use it in the code to operate buttons.
Integration with the system
A device created as a Quick App can be used in the system just like any other device. A device created in this way can be used in scenes, connected devices, etc. To achieve the best level of integration, it is best to choose the appropriate device type, e.g. when integrating a dimmable light bulb, it is best to choose the type of multi-level switch.
Lua
The Lua code written in Quick Apps is slightly different from the code written in scenes. Quick Apps uses an object-oriented programming paradigm that helps to structure the written Lua code.
You can read more about object-oriented programming in Lua here (https://www.lua.org/pil/16.html).
Quick App Class
The QuickApp class is used to represent the created device. It has built-in methods for updating properties, updating device view, downloading variables, etc. To extend the Quick App class we can add methods to it.
|
1 2 3 |
function QuickApp:myMethod() self:debug("Hello from my method") end |
This method can be called by self:myMethod()
self
self is an object that can be used inside the Quick App class. It is a reference to ‘itself’. Similar solutions can be found in programming languages such as python or this in javascript. Please note it is only available inside the class methods.
|
1 2 3 4 5 |
function QuickApp:turnOn() self:debug("binary switch turned on") -- debugging method will work end self:debug("hello world!") -- the debug method will not work because the self object does NOT exist here |
You can add your variables to the self, which can then be used in other methods. This allows us to avoid creating global variables.
|
1 2 3 4 5 6 7 8 |
function QuickApp:hello() self:debug("hello", self.world) end function QuickApp:onInit() self.world = "world!" self:hello() end |
onInit
This is the method that is called when the system starts the Quick App. This happens at the system startup and after each saving of the device. It is a place where you can initialize variables, establish a connection with the device, etc.
Defining this method is not required for the Quick App to work properly.
|
1 2 3 4 5 |
function QuickApp:onInit() self:debug("onInit") self.httpClient = net.HTTPClient() self.baseUrl = "http://".. self:getVariable("ip") end |
View setup – controls support (firmware 5.030)
There are three types of controls:
- label
- button
- slider
The button and slider can handle events. Button emits onReleased event, and slider emits onChanged event to inform about the change. Events are visible in the control’s edit mode. You can enter name of the method from QuickApp class, that should handle the event. When the event occurs on the control, parameter event of table type will be passed to the method, with the following fields:
deviceId– field ofinttype with the identificator of the device that emitted the event,values– field oftabletype with values passed by the control. Used only for slider, its value is passed in first position of the table,eventType– field ofstringtype contains event type,elementName– field ofstringtype contains name of the control that emitted the event.
For example slider configured as below:

method with name onSliderChanged should be implemented. Code example below:
|
1 2 3 4 |
function QuickApp:onSliderChanged(event) local value = event.values[1] self:debug("value", value) end |
For the label control, events cannot be handled. All controls can be updated by the QuickApp:updateView method.
View setup – controls support (firmware 5.021)
There are three types of controls:
- label
- button
- slider
The button and slider can handle events. You can use the self object (as in methods) in the code to handle the controls. This means that all methods and variables assigned to the self object in the main part of the code can also be used here.
When handling a slider change, the new state can be obtained from the value variable.
|
1 2 |
self:debug('New slider value:', value) self:updateProperty('value', value) |
For the label control, events cannot be handled. All controls can be updated by the QuickApp:updateView method.
Methods within the QuickApp class
The following set of methods is available in QuickApp class. As described earlier, they can be called inside the QuickApp class methods by self:<method name>().
QuickApp:debug(message, …)
A method for displaying messages of type DEBUG in the log window (under the code editor). The variables can be of any type, as they will be converted into text using the tostring function and separated by a single space.
|
1 2 3 |
function QuickApp:sum(x,y) self:debug(x, '+', y, '=', x+y) end |
QuickApp:trace(message, …)
A method similar to the QuickApp:debug method. The only difference is that it displays messages of type TRACE instead of DEBUG. Method is available for firmware 5.030 or higher.
QuickApp:warning(message;, …)
A method similar to the QuickApp:debug method. The only difference is that it displays messages of type WARNING instead of DEBUG. Method is available for firmware 5.030 or higher.
QuickApp:error(message, …)
A method similar to the QuickApp:debug method. The only difference is that it displays messages of type ERROR instead of DEBUG. Method is available for firmware 5.030 or higher.
QuickApp:getVariable(variable_name)
The method is used to get the Quick App variables. Variables can be added from the device configuration or the method QuickApp:setVariable.
|
1 2 3 |
function QuickApp:onInit() self.ip = self:getVariable("ip") end |
QuickApp:setVariable(variable_name, value)
The method for setting device variables.
|
1 |
self:setVariable("token", token) |
QuickApp:updateProperty(device_property, value)
The method for updating device properties.
|
1 2 3 4 5 6 |
-- example for the binary switch -- value property represents the state of the device function QuickApp:onValueUpdateSample() self:updateProperty('value', true) -- binary switch on self:updateProperty('value', false) -- binary switch off end |
QuickApp:updateView(component_name, component_attribute, value)
The method for updating the device view.
|
1 2 3 4 5 |
function QuickApp:updateViewSample() self:updateView("label1", "text", "Device on") -- updating the text for 'label1'. self:updateView("button1", "text", "on") -- updating the text for 'button1'. self:updateView("slider1", "value", "99") -- updating the text for 'slider1'. end |
Mapping actions to methods
This mechanism allows you to manage the actions of the device. Each action sent to the device (e.g. from the scene), is mapped to the method in the Quick App. The name of the action is mapped to the name of the method. The arguments of the action are passed as arguments of the method.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
-- example: fibaro.call(44, "turnOn") function QuickApp:turnOn() self:debug("turnOn") end -- example: fibaro.call(44, "setValue", 90) function QuickApp:setValue(value) self:debug("setValue", value) end -- example: fibaro.call(44, "myCustomAction", 10, "test") function QuickApp:myCustomAction(arg1, arg2) self:debug("myCustomAction", arg1, arg2) end |
Looping up the execution
The execution of the QuickApp code is not looped in any way. It is also not necessary for its proper functioning. An example of simple loops is shown below.
|
1 2 3 4 5 6 7 8 9 10 11 |
function QuickApp:loop(text) self:debug("Text from loop:" , text) fibaro.setTimeout(2000, function() self:loop(text) end) end function QuickApp:onInit() self:loop("hello from loop") end |
net.HTTPClient
Class for handling HTTP/HTTPS queries.
net.HTTPClient(options)
HTTPClient class constructor.
Parameters
options– (optional) The argument oftabletype with options for connection. The only option that can be set is atimeoutexpressed in milliseconds.
Example
|
1 2 3 |
function QuickApp:onInit() self.http = net.HTTPClient({timeout=3000}) end |
HTTPClient:request(address, params)
A method to execute HTTP/HTTPS queries.
Parameters
address– the argument of thestringtype with the address to which the query is to be executed. e.g.http://127.0.0.1/api/users,https://google.comparams– (optional) the argument of thetabletype. The argument may contain options for the query and/or feedback functions. The possible parameters are described below
items of the params array
options– an array of query options. Possible options:checkCertificate– Abooleanfield that says whether to verify the certificate (defaulttrue). This field is only used for HTTPS connectionmethod– a field of the typestringwhich contains the name of the http method (e.g.GET)data– a field of typestringthat contains the query bodyheaders– a field of typetable, which contains query headers
success(response)– The function will be triggered if the data is sent correctly. Thedataargument passed on is of thetabletype with the following structure:data– a field of typestringcontaining the response bodystatus– a field of typenumbercontaining a response code e.g. 200, 404 etc.headers– a field of typetablecontaining response headers
error(message)– The function will be triggered in case of an error when sending data, e.g. disconnection. The parametermessage(typestring) returns the error content.
Examples
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
-- An example of a GET inquiry -- self.http must have been previously created by net.HTTPClient function QuickApp:getQuote() local address = "https://quotes.rest/qod" self.http:request(address, { options={ headers = { Accept = "application/json" }, checkCertificate = true, method = 'GET' }, success = function(response) self:debug("response status:", response.status) self:debug("headers:", response.headers["Content-Type"]) local data = json.decode(response.data) if data.contents and data.contents.quotes and data.contents.quotes[1] then local quote = data.contents.quotes[1].quote self:debug(quote) self:updateView("label", "text", quote) end end, error = function(error) self:debug('error: ' .. json.encode(error)) end }) end |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
-- An example of a POST inquiry -- self.http must have been previously created by net.HTTPClient function QuickApp:createBackup(description) local requestBody = { action = "create", params = { type = "local", description = description } } self.http:request("http://127.0.0.1/api/service/backups", { options = { data = json.encode(requestBody), method = "POST", headers = { ["Content-Type"] = "application/json", ["Accept"] = "application/json", ["Authorization"] = "Basic YWRtaW46YWRtaW4=", } }, success = function(response) self:debug(response.status) self:debug(response.data) end, error = function(message) self:debug("error:", message) end }) end |
net.TCPSocket
Class for handling the TCP connection.
net.TCPSocket(options)
TCPSocket class constructor.
Parameters
options– (optional) argument as a table containing options for the connection. The only option that can be set is atimeoutexpressed in milliseconds.
Example
|
1 2 3 |
function QuickApp:onInit() self.sock = net.TCPSocket({timeout = 10000}) end |
TCPSocket:connect(ip, port, callbacks)
The method establishes the TCP connection to the specified IP and port.
Parameters
ip– an argument of thestringtype with the IP address to establish the connectionport– an argument of thenumbertype argument with the port to establish the connectioncallbacks– (optional) an argument of the typetablewith callback actions, which will be executed in case of the relevant events described below
Feedback functions:
success()– the function will be triggered if the connection is correcterror(message)– The function will be triggered in case of an error when trying to connect, e.g. no connection. The parametermessage(typestring) passes the error message
Example
|
1 2 3 4 5 6 7 8 9 10 11 12 |
function QuickApp:onInit() self.sock = net.TCPSocket() self.sock:connect(self.ip, self.port, { success = function() self:debug("connected") end, error = function(message) self:debug("connection error:", message) end, }) end |
TCPSocket:read(callbacks)
A method for reading data from a set socket. For proper operation the connection must be set up correctly.
Parameters
callbacks– (optional) an argument of the typetablewith feedback functions, which will be executed if the relevant events described below occur
Feedback functions:
succes(data)– the function will be triggered if the data package is read correctly. The data is passed by thedataargument, which is ofstringtypeerror(message)– the function will be triggered in case of an error when trying to read data, e.g. disconnection. The parametermessagecarries the error content
Example
|
1 |
function QuickApp:waitForRespons(**optional**) |
TCPSocket:readUntil(delimiter, callbacks)
The method reads the data until the given string (delimiter) appears. The method is useful for handling protocols where there is a fixed character or character string that indicates the end of a data packet. The returned data not will contain the character string given as a delimiter.
For proper operation, the connection must be set up correctly.
Parameters
delimiter– the argument of the typestringwhich is a limit to which data will be readcallbacks– (optional) an argument of the typetablewith feedback functions, which will be executed if the relevant events described below occur
Feedback functions:
success(data)– the function will be called if the data package is read correctly. The data is passed by thedataargument, which is ofstringtypeerror(message)– the function will be called in case of an error when trying to read data, e.g. disconnection. The parametermessagecarries the error content
Example
|
1 2 3 4 5 6 7 8 9 10 11 |
function QuickApp:waitForResponseFunction() self.sock:readUntil("STOP", { success = function(data) self:debug(data) self:waitForResponseFunction() -- looping the data readout end, error = function() self:debug("response error") end }) end |
TCPSocket:send(data, callbacks)
The method for sending data. The connection must be correctly established for proper operation.
Parameters
data–stringargument with data to be sentcallbacks– (optional) an argument of the typetablewith feedback functions, which will be executed if the relevant events described below occur
Feedback functions:
success()– the function will be triggered if the connection is correcterror(message)– the function will be triggered in case of an error when trying to read data, e.g. disconnection. The parametermessagecarries the error content
Example
|
1 2 3 4 5 6 7 8 9 10 |
function QuickApp:send(strToSend) self.sock:write(strToSend, { success = function() self:debug("data sent") end, error = function(err) self:debug("error while sending data") end }) end |
TCPSocket:close()
The method used to close the socket and to disconnect the connection.
TCP example
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
-- Quick App template for handling the TCP device function QuickApp:turnOn() self:debug("binary switch turned on") self:send("Some command for on\n") -- sending data to the device. In a normal implementation it will be a code with an appropriate command. self:updateProperty("value", true) end function QuickApp:turnOff() self:debug("binary switch turned off") self:send("Some command for off\n") -- sending data to the device. In a normal implementation it will be a code with an appropriate command. self:updateProperty("value", false) end -- the method for sending data to the device -- the method can be called from anywhere function QuickApp:send(strToSend) self.sock:write(strToSend, { success = function() -- the function that will be triggered when the data is correctly sent self:debug("data sent") end, error = function(err) -- the function that will be triggered in the event of an error in data transmission self:debug("error while sending data") end }) end -- method for reading data from the socket -- since the method itself has been looped, it should not be called from other locations than QuickApp:connect function QuickApp:waitForResponseFunction() self.sock:read({ -- reading a data package from the socket success = function(data) self:onDataReceived(data) -- handling of received data self:waitForResponseFunction() -- looping of data readout end, error = function() -- a function that will be called in case of an error when trying to receive data, e.g. disconnecting a socket self:debug("response error") self.sock:close() -- socket closed fibaro.setTimeout(5000, function() self:connect() end) -- re-connection attempt (every 5s) end }) end -- a method to open a TCP connection. -- if the connection is successful, the data readout loop will be called QuickApp:waitForResponseFunction() function QuickApp:connect() self.sock:connect(self.ip, self.port, { -- connection to the device with the specified IP and port success = function() -- the function will be triggered if the connection is correct self:debug("connected") self:send("Hello!\n") self:waitForResponseFunction() -- launching a data readout "loop" end, error = function(err) -- a function that will be triggered in case of an incorrect connection, e.g. timeout self.sock:close() -- closing the socket self:debug("connection error") fibaro.setTimeout(5000, function() self:connect() end) -- re-connection attempt (every 5s) end, }) end -- function handling the read data -- normally this is where the data reported by the device will be handled function QuickApp:onDataReceived(data) self:debug("onDataReceived", data) end function QuickApp:onInit() self:debug("onInit") self.ip = self:getVariable("ip") self.port = tonumber(self:getVariable("port")) self.sock = net.TCPSocket() -- creation of a TCPSocket instance self:connect() end |
net.UDPSocket
Class for handling the UDP connection.
UDPSocket class methods
net.UDPSocket(options)
UDPSocket class constructor.
Parameters
options– (optional) argument as a table containing options for the connection. Avaiable parameters:broadcast– (optional) an argument of the typebooleanthat turns on the broadcast optiontimeout– (optional) an argument of the typenumberwith response timeout in milliseconds
Example
|
1 2 3 4 5 6 7 |
function QuickApp:onInit() self.udp = net.UDPSocket({ broadcast = true, timeout = 5000 }) end |
UDPSocket:sendTo(data, ip, port, callbacks)
Method sends datagram to provided ip and port.
Parameters
data– an argument of thestringtype with data to be sentip– an argument of thestringtype with the IP address to establish the connectionport– an argument of thenumbertype argument with the port to establish the connectioncallbacks– (optional) an argument of the typetablewith callback actions, which will be executed in case of the relevant events described below
Feedback functions:
success()– the function will be triggered if the connection is correcterror(message)– The function will be triggered in case of an error when trying to connect, e.g. no connection. The parametermessage(typestring) passes the error message
Example
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
function QuickApp:onInit() self.udp = net.UDPSocket({ broadcast = true, timeout = 1000 }) local payload = string.char(0x46,0x49,0x42,0x41,0x52,0x4f) self.udp:sendTo(payload, '255.255.255.255', 44444, { success = function() self:receiveData() end, error = function(error) print('Error:', error) end }) end |
UDPSocket:receive(callbacks)
A method for reading data from a socket.
Parameters
callbacks– (optional) an argument of the typetablewith callback actions, which will be executed in case of the relevant events described below
Feedback functions:
success(data)– the function will be triggered if the data package is read correctly. The data is passed by thedataargument, which is ofstringtypeerror(message)– The function will be triggered in case of an error when trying to read the data, e.g. timeout. The parametermessage(typestring) passes the error message
|
1 2 3 4 5 6 7 8 9 10 11 |
function QuickApp:receiveData() self.udp:receive({ success = function(data) print(data) self:receiveData() -- will read next datagram end, error = function(error) self:debug("Error:", error) end}) end |
UDPSocket:close()
The method used to close the socket.
WebSocket client
Quick Apps in Home Center 3 support communication with WebSocket standard by creating WebSocket and WebSocket Secure clients. To learn more about WebSocket clients click here.
MQTT client
Quick Apps in Home Center 3 support communication in MQTT standard by creating MQTT clients. To learn more about MQTT clients click here.
Managing child devices
Quick Apps in Home Center 3 support device inheritance to create multiple interconnected devices. To learn more about managing child devices click here.
Sample Quick Apps to download
To upload the sample to your Home Center 3 go to > Devices > > Other Device > Upload file and choose the downloaded file.
TCP connection sample (for devices like Global Caché)
In this example the Quick App will communicate with another device using TCP protocol. IP address and port can be modified using variables. It consists of 3 buttons: ON button will send “ON” message, OFF button will send “OFF” message and wait for response, sampleHex button will send sample hexadecimal message.
Current weather data from OpenWeatherMap
In this example the Quick App will import weather data for provided location from OpenWeatherMap and display condition, temperature, wind and humidity. Created device can be used as the main weather provided (set in General settings) to use in scenes and interfaces. For the Quick App to work properly you must configure following variables:
- locationId – ID of one of the locations set in the FIBARO System (General > Location)
- APIKey – API key for OpenWeatherMap, you can aquire it here: https://openweathermap.org/appid
- Unit – unit system for the data: metric or imperial
Random temperature
In this example the Quick App will simulate temperature sensor, that changes temperature to random values in random intervals. Using variables you can set: maximum and minimum temperature, maximum and minimum time interval and precision (number of decimals).
Backuper
In this example the Quick App will create backup of the system after clicking the button. The user can change type of the backup (remote or local) using backupType variable.