| name | quickapp-api |
| description | Full HC3 QuickApp Lua API reference: fibaro.* functions, QuickApp methods (self:updateProperty, self:updateView, self:getVariable, etc.), plugin.* API, api.* REST calls, net.HTTPClient/TCPSocket, timers (setTimeout/setInterval), JSON, and standard Lua libraries available in QA context. USE FOR: writing QuickApp code, looking up specific method signatures, understanding what functions are available, fixing "attempt to call nil" errors on QA methods. |
QuickApp Lua API Reference
Complete reference for the Fibaro HC3 QuickApp Lua programming environment. Use this skill when writing QuickApp code with plua.
QuickApp Lifecycle
Every QuickApp starts with onInit(). The global quickApp variable is set only after onInit() returns.
function QuickApp:onInit()
self:debug("Started, id =", self.id, "name =", self.name)
end
QuickApp Methods (self:...)
Logging
self:debug(...)
self:trace(...)
self:warning(...)
self:error(...)
All logging methods accept multiple arguments separated by commas; they are concatenated with spaces.
Device Properties
self:updateProperty("value", true)
self:updateProperty("log", "status msg")
Common property names: value, dead, log, userDescription.
QuickApp Variables
local v = self:getVariable("myKey")
self:setVariable("myKey", "myValue")
UI Updates
self:updateView("labelId", "text", "Hello world")
self:updateView("sliderId", "value", "75")
self:updateView("btnId", "text", "Click me")
self:updateView("switchId", "value", "true")
Children
local child = self:createChildDevice({
name = "My Child",
type = "com.fibaro.binarySwitch",
initialProperties = { value = false }
}, ChildClass)
self:initChildDevices({ ["com.fibaro.binarySwitch"] = ChildClass })
self:removeChildDevice(childId)
Actions and Interfaces
self:callAction("myMethod", arg1, arg2)
self:addInterfaces({"energy", "battery"})
self:hasInterface("energy")
Properties on self
| Property | Type | Description |
|---|
self.id | number | Device ID |
self.name | string | Device name |
self.type | string | Device type string |
self.properties | table | Full properties (read-only reference) |
fibaro.* Global API
Device Control
fibaro.call(deviceId, "turnOn")
fibaro.call(deviceId, "setValue", 75)
fibaro.getValue(deviceId, "value")
fibaro.get(deviceId, "value")
fibaro.getDevicesID(filter)
Since fw ≥ 5.031.33, fibaro.call is async by default. For self-calls use self:method().
Control with fibaro.useAsyncHandler(true/false).
Device Metadata
fibaro.getName(deviceId)
fibaro.getType(deviceId)
fibaro.getRoomID(deviceId)
fibaro.getRoomName(roomId)
fibaro.getRoomNameByDeviceID(deviceId)
fibaro.getSectionID(deviceId)
Global Variables
fibaro.getGlobalVariable("myVar")
fibaro.setGlobalVariable("myVar", "val")
Scenes & Profiles
fibaro.scene("execute", sceneId)
fibaro.scene("kill", sceneId)
fibaro.profile(profileId, "activateProfile")
Alarms & Notifications
fibaro.alarm(partitionId, "arm")
fibaro.alert("email", {userId}, "msg")
fibaro.alert("push", {userId}, "msg")
fibaro.emitCustomEvent("myEventName")
Logging (global)
fibaro.debug(tag, message)
fibaro.trace(tag, message)
fibaro.warning(tag, message)
fibaro.error(tag, message)
plugin.* API
Lower-level API — prefer self: QuickApp methods where available.
plugin.mainDeviceId
plugin.createChildDevice(props)
plugin.deleteDevice(deviceId)
plugin.getChildDevices(deviceId)
plugin.getDevice(deviceId)
plugin.getProperty(deviceId, prop)
plugin.restart(deviceId)
api.* — Direct REST Calls to HC3
local device = api.get("/devices/25")
local devices = api.get("/devices?interface=zwave")
local result = api.post("/customEvents/myEvent", {})
api.put("/devices/25", { name = "New Name" })
api.delete("/globalVariables/oldVar")
api.* returns the parsed JSON response (Lua table), or nil on error.
Timers and Scheduling
local ref = setTimeout(function()
self:debug("fired!")
end, 5000)
clearTimeout(ref)
local ref2 = setInterval(function()
self:debug("tick")
end, 10000)
clearInterval(ref2)
setTimeout(function() self:doSomething() end, 0)
Avoid fibaro.sleep(ms) — it blocks all event handling, HTTP callbacks, and timers while sleeping. Always use setTimeout/setInterval patterns instead.
net.* — Networking in QuickApps
HTTP Client
local http = net.HTTPClient()
http:request("https://api.example.com/data", {
options = {
method = "GET",
headers = { ["Authorization"] = "Bearer " .. token }
},
success = function(response)
local data = json.decode(response.data)
self:debug("status:", response.status)
end,
error = function(err)
self:error("HTTP error:", err)
end
})
TCP Socket
local tcp = net.TCPSocket()
tcp:connect("192.168.1.100", 8080, {
success = function()
tcp:write("HELLO\n", {
success = function() self:debug("sent") end
})
end,
error = function(err) self:error("connect error:", err) end
})
tcp:read({ success = function(data) self:debug("received:", data) end })
tcp:close()
UDP Socket
local udp = net.UDPSocket()
udp:sendTo("data", "192.168.1.100", 9999)
JSON
local t = json.decode('{"key": "value", "num": 42}')
local s = json.encode({ key = "value", num = 42 })
Availability: plua vs HC3
| Function | plua | HC3 |
|---|
json.encode(t) | ✓ | ✓ |
json.decode(s) | ✓ | ✓ |
json.encodeFormated(t) | ✓ | ✗ — plua only |
json.util.InitArray(t) | ✓ | ✓ |
json.encodeFormated produces pretty-printed JSON but is only available in plua. Do not use it in code intended to run on a real HC3 — it will throw a nil-call error. If you need formatted output on the HC3, provide your own implementation.
Marking tables as arrays: json.util.InitArray
By default, an empty or mixed Lua table may encode as {} (object) rather than [] (array). Use json.util.InitArray to force array encoding — this is available on both plua and real HC3 and is essential when posting to REST APIs that require a JSON array:
local arr = json.util.InitArray({})
local items = json.util.InitArray({"a","b"})
api.post("/foo", { ids = json.util.InitArray({}) })
Standard Lua Available in QAs
os.time(), os.date(), os.clock(), os.difftime()
string.format(), string.find(), string.gmatch(), string.gsub(), string.sub(), string.split() (Fibaro extension), string.starts() (Fibaro extension)
table.insert(), table.remove(), table.sort(), table.concat()
math.floor(), math.ceil(), math.abs(), math.max(), math.min(), math.random(), math.huge
pcall(f, ...) — protected call; returns (true, result) or (false, errmsg)
tostring(), tonumber(), type(), pairs(), ipairs()
Key Caveats
self:getVariable(name) returns "" when missing, not nil
self:updateView(...) values must be strings — use tostring(n)
self.properties.* writes are transient — use self:updateProperty() to persist
- All QuickApp methods are publicly callable via
fibaro.call(id, "method") — keep private helpers as local functions outside the class
self.parent is not available during Child:__init() — use child's onInit() instead
quickApp global is only set after onInit() returns