So far the series lived in the sim: timers, UI, the house, mock
services. Today the QuickApp reaches out of the laptop — flua's
net.HTTPClient and mqtt clients make real
network calls, with the same API the QA uses on the HC3. Write it once,
test it offline against the real service, and the same file runs on the
controller.
Requests are asynchronous with a success/error callback pair — no
fibaro.sleep, no busy waits. Timeouts, headers, bodies, the
lot:
--%%name:http-demo
-- --------------- EOH ---------------
setTimeout(function()
local client = net.HTTPClient()
-- GET with a success/error pair
client:request("https://httpbin.org/get?hello=world", {
options = { timeout = 5 },
success = function(resp)
print("get:", resp.status, resp.headers["Content-Type"])
print("get data:", resp.data:sub(1, 80))
end,
error = function(err) print("get error:", err) end,
})
-- POST with headers and a body
client:request("https://httpbin.org/post", {
options = {
method = "POST",
headers = { ["Content-Type"] = "application/json" },
data = '{"value": 42}',
timeout = 5,
},
success = function(resp) print("post:", resp.status) end,
error = function(err) print("post error:", err) end,
})
end, 100)
Run it — httpbin echoes whatever you send, so you see your own query string and body come back:
[http-demo5000]: get: 200 application/json
[http-demo5000]: get data: {
"args": {
"hello": "world"
}, ...
[http-demo5000]: post: 200
Errors never crash the QA: a refused connection, a DNS failure, a
timeout — all land in the error callback (the full
examples/http.lua has a request to a dead port to prove it).
Credentials for real APIs belong in a --%%var reading the
config file, as in the previous post.
The HC3's MQTT client (firmware 5.030+ API) is fully emulated.
examples/mqtt.lua connects to the public broker at
broker.hivemq.com, subscribes, publishes, and prints its own echo:
local broker = os.getenv("MQTT_URL") or "mqtt://broker.hivemq.com:1883"
setTimeout(function()
local client = mqtt.Client.connect(broker, {
clientId = "flua-demo-" .. tostring(os.time()),
cleanSession = true,
callback = function(errorCode)
print("connect result:", errorCode == 0 and "ok" or "failed " .. tostring(errorCode))
end,
})
client:addEventListener("connected", function()
print("connected:", client:isConnected())
client:subscribe("flua/demo", { qos = mqtt.QoS.AT_LEAST_ONCE })
end)
client:addEventListener("subscribed", function(event)
client:publish("flua/demo", "hello from flua", {
qos = mqtt.QoS.AT_LEAST_ONCE,
retain = false,
})
end)
client:addEventListener("message", function(event)
print("mqtt echo:", event.topic, event.payload, "qos=" .. tostring(event.qos))
client:disconnect()
end)
client:addEventListener("closed", function() print("closed") end)
client:addEventListener("error", function(event) print("mqtt error:", event.code) end)
end, 100)
[mqtt-demo5000]: connected: true [mqtt-demo5000]: connect result: ok [mqtt-demo5000]: mqtt echo: flua/demo hello from flua qos=1
The echo takes a while — it is a real broker across the internet, and
public brokers throttle rapid reconnects; if it is down or unhappy, the
error path prints cleanly instead of crashing. Point the
broker at your own (or a local mock) with
MQTT_URL=mqtt://127.0.0.1:1883 — and that is exactly where
post 14's .env comes in for real broker credentials.
Secure brokers work too: mqtts:// or
options.tls enables TLS, with SNI on by default like the HC3
(since 5.191) — tls = { useSNI = false } switches it off when
a broker trips over it. Also available: allowUnauthorized,
certificateAuthority, clientCertificate.
The loop from post 8 fits here perfectly: while you build the
integration logic, run against a mock server in Lua
(net.HTTPServer / net.TCPServer), then flip the
URL to the real service and run the same QA. The service contract is
tested offline; the only thing that changes is the endpoint.
Next time: proxy mode — flua mirrors a QA onto your real HC3, so it runs offline but behaves as a device on the controller. The deepest offline-online blend yet.
net + mqtt: USAGE.md ("Network") · examples/http.lua, examples/mqtt.lua · flua: https://github.com/jangabrielsson/flua