fibaro-flua 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fibaro_flua-0.1.1/LICENSE +21 -0
- fibaro_flua-0.1.1/PKG-INFO +306 -0
- fibaro_flua-0.1.1/README.md +444 -0
- fibaro_flua-0.1.1/USAGE.md +259 -0
- fibaro_flua-0.1.1/pyproject.toml +57 -0
- fibaro_flua-0.1.1/setup.cfg +4 -0
- fibaro_flua-0.1.1/src/fibaro_flua.egg-info/PKG-INFO +306 -0
- fibaro_flua-0.1.1/src/fibaro_flua.egg-info/SOURCES.txt +63 -0
- fibaro_flua-0.1.1/src/fibaro_flua.egg-info/dependency_links.txt +1 -0
- fibaro_flua-0.1.1/src/fibaro_flua.egg-info/entry_points.txt +2 -0
- fibaro_flua-0.1.1/src/fibaro_flua.egg-info/requires.txt +6 -0
- fibaro_flua-0.1.1/src/fibaro_flua.egg-info/top_level.txt +1 -0
- fibaro_flua-0.1.1/src/flua/__init__.py +3 -0
- fibaro_flua-0.1.1/src/flua/__main__.py +7 -0
- fibaro_flua-0.1.1/src/flua/api/__init__.py +211 -0
- fibaro_flua-0.1.1/src/flua/api/request.py +44 -0
- fibaro_flua-0.1.1/src/flua/api/routes/__init__.py +117 -0
- fibaro_flua-0.1.1/src/flua/api/routes/alarms.py +62 -0
- fibaro_flua-0.1.1/src/flua/api/routes/devices.py +104 -0
- fibaro_flua-0.1.1/src/flua/api/routes/plugins.py +174 -0
- fibaro_flua-0.1.1/src/flua/api/routes/scenes.py +49 -0
- fibaro_flua-0.1.1/src/flua/api/routes/system.py +75 -0
- fibaro_flua-0.1.1/src/flua/api/state.py +222 -0
- fibaro_flua-0.1.1/src/flua/bindings.py +208 -0
- fibaro_flua-0.1.1/src/flua/check.py +48 -0
- fibaro_flua-0.1.1/src/flua/cli.py +492 -0
- fibaro_flua-0.1.1/src/flua/clock.py +85 -0
- fibaro_flua-0.1.1/src/flua/config.py +156 -0
- fibaro_flua-0.1.1/src/flua/devices/__init__.py +83 -0
- fibaro_flua-0.1.1/src/flua/devices/devices.json +1 -0
- fibaro_flua-0.1.1/src/flua/engine.py +1064 -0
- fibaro_flua-0.1.1/src/flua/http.py +45 -0
- fibaro_flua-0.1.1/src/flua/lua/fibaro.lua +527 -0
- fibaro_flua-0.1.1/src/flua/lua/init.lua +675 -0
- fibaro_flua-0.1.1/src/flua/lua/json.lua +22 -0
- fibaro_flua-0.1.1/src/flua/lua/mobdebug.lua +2769 -0
- fibaro_flua-0.1.1/src/flua/lua/mqtt.lua +209 -0
- fibaro_flua-0.1.1/src/flua/lua/net.lua +300 -0
- fibaro_flua-0.1.1/src/flua/lua/quickapp.lua +483 -0
- fibaro_flua-0.1.1/src/flua/lua/socket.lua +113 -0
- fibaro_flua-0.1.1/src/flua/messages.py +196 -0
- fibaro_flua-0.1.1/src/flua/mqtt.py +500 -0
- fibaro_flua-0.1.1/src/flua/sync_socket.py +313 -0
- fibaro_flua-0.1.1/src/flua/timers.py +99 -0
- fibaro_flua-0.1.1/src/flua/websocket.py +357 -0
- fibaro_flua-0.1.1/tests/test_annotations.py +89 -0
- fibaro_flua-0.1.1/tests/test_api.py +463 -0
- fibaro_flua-0.1.1/tests/test_clock.py +97 -0
- fibaro_flua-0.1.1/tests/test_config.py +108 -0
- fibaro_flua-0.1.1/tests/test_devices.py +148 -0
- fibaro_flua-0.1.1/tests/test_dx.py +218 -0
- fibaro_flua-0.1.1/tests/test_engine.py +133 -0
- fibaro_flua-0.1.1/tests/test_http.py +168 -0
- fibaro_flua-0.1.1/tests/test_json.py +48 -0
- fibaro_flua-0.1.1/tests/test_lua.py +55 -0
- fibaro_flua-0.1.1/tests/test_mqtt.py +276 -0
- fibaro_flua-0.1.1/tests/test_qa.py +453 -0
- fibaro_flua-0.1.1/tests/test_quickapp.py +501 -0
- fibaro_flua-0.1.1/tests/test_socket.py +528 -0
- fibaro_flua-0.1.1/tests/test_sync_socket.py +112 -0
- fibaro_flua-0.1.1/tests/test_tcp.py +170 -0
- fibaro_flua-0.1.1/tests/test_timers.py +105 -0
- fibaro_flua-0.1.1/tests/test_udp.py +110 -0
- fibaro_flua-0.1.1/tests/test_virtual_time.py +85 -0
- fibaro_flua-0.1.1/tests/test_websocket.py +202 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jan Gabrielsson
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fibaro-flua
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Develop Fibaro Home Center 3 QuickApps offline: the HC3 Lua runtime (QuickApp, fibaro, api, net, mqtt) with a simulated HC3, virtual time, and a real debugger
|
|
5
|
+
Author-email: Jan Gabrielsson <jan@gabrielsson.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Jan Gabrielsson
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Keywords: fibaro,hc3,home center,quickapp,lua,smart home,automation
|
|
29
|
+
Classifier: Development Status :: 3 - Alpha
|
|
30
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
31
|
+
Classifier: Operating System :: OS Independent
|
|
32
|
+
Classifier: Programming Language :: Python :: 3
|
|
33
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
36
|
+
Classifier: Topic :: Home Automation
|
|
37
|
+
Classifier: Topic :: Software Development :: Interpreters
|
|
38
|
+
Requires-Python: >=3.11
|
|
39
|
+
Description-Content-Type: text/markdown
|
|
40
|
+
License-File: LICENSE
|
|
41
|
+
Requires-Dist: lupa>=2.4
|
|
42
|
+
Provides-Extra: dev
|
|
43
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
44
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
|
|
45
|
+
Requires-Dist: ruff>=0.6.0; extra == "dev"
|
|
46
|
+
Dynamic: license-file
|
|
47
|
+
|
|
48
|
+
# flua — user guide for QA developers
|
|
49
|
+
|
|
50
|
+
flua runs Fibaro QuickApps **offline** on your Mac or PC. You write the same
|
|
51
|
+
Lua you'd write on the HC3 — `QuickApp`, `fibaro`, `api`, `net`, `mqtt` — and
|
|
52
|
+
flua provides the rest of the world: a simulated HC3, real network access, a
|
|
53
|
+
virtual clock, a proper debugger with breakpoints, and a one-command path back
|
|
54
|
+
to the HC3 as a `.fqa` file.
|
|
55
|
+
|
|
56
|
+
The HC3 editor is tiny and debugging there means `print()` statements. flua
|
|
57
|
+
exists so you can develop in your real editor, with real tooling, and upload
|
|
58
|
+
when it works.
|
|
59
|
+
|
|
60
|
+
- [Install](#install)
|
|
61
|
+
- [Your first QuickApp](#your-first-quickapp)
|
|
62
|
+
- [Running QAs](#running-qas)
|
|
63
|
+
- [VS Code setup](#vs-code-setup)
|
|
64
|
+
- [QA directives (`--%%`)](#qa-directives--)
|
|
65
|
+
- [Multi-file QAs](#multi-file-qas)
|
|
66
|
+
- [The offline HC3](#the-offline-hc3)
|
|
67
|
+
- [Loading QAs at runtime](#loading-qas-at-runtime)
|
|
68
|
+
- [Network clients](#network-clients)
|
|
69
|
+
- [Deploying to the HC3](#deploying-to-the-hc3)
|
|
70
|
+
- [Bringing an HC3 QA home](#bringing-an-hc3-qa-home)
|
|
71
|
+
- [Static checks](#static-checks)
|
|
72
|
+
- [flua extensions (`_FLUA`)](#flua-extensions-_flua)
|
|
73
|
+
|
|
74
|
+
## Install
|
|
75
|
+
|
|
76
|
+
Python 3.11+. lupa (which bundles Lua) is the only runtime dependency.
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
pip install fibaro-flua # from PyPI — installs the flua command
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
From a checkout (development):
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
cd flua
|
|
86
|
+
python3 -m venv .venv
|
|
87
|
+
.venv/bin/pip install -e ".[dev]"
|
|
88
|
+
flua --version
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Your first QuickApp
|
|
92
|
+
|
|
93
|
+
A QuickApp is an ordinary Lua file. `QuickApp:onInit` runs exactly like on
|
|
94
|
+
the HC3, and `self:debug` prints immediately (unlike the HC3, where you'd
|
|
95
|
+
only see it in the debug window):
|
|
96
|
+
|
|
97
|
+
```lua
|
|
98
|
+
--%%name:hello
|
|
99
|
+
-- --------------- EOH ---------------
|
|
100
|
+
function QuickApp:onInit()
|
|
101
|
+
self:debug("I started")
|
|
102
|
+
setTimeout(function() self:debug("one second later") end, 1000)
|
|
103
|
+
end
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Save it as `hello.lua` and run it:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
.venv/bin/flua hello.lua
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Every `.lua` file you pass is a QuickApp — it gets `QuickApp`, `fibaro`,
|
|
113
|
+
`api`, `net`, `mqtt`, timers, and runs `onInit` exactly like on the HC3.
|
|
114
|
+
Anything that has nothing left to do (no timers, no network connections)
|
|
115
|
+
makes flua exit; QAs with timers or open connections keep running.
|
|
116
|
+
|
|
117
|
+
## Running QAs
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
.venv/bin/flua script.lua # one QA
|
|
121
|
+
.venv/bin/flua qa1.lua qa2.lua # several QAs, isolated, can talk to each other
|
|
122
|
+
.venv/bin/flua -e 'setTimeout(function() print("hi") end, 100)'
|
|
123
|
+
.venv/bin/flua --run-for 5 script.lua # at least 5 s, then exit when idle
|
|
124
|
+
.venv/bin/flua --run-for -3 script.lua # exactly 3 s
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Virtual time — great for testing long-running logic:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
.venv/bin/flua --speed 60 script.lua # 60x faster
|
|
131
|
+
.venv/bin/flua --instant script.lua # timers fire now, os.time() jumps ahead
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## VS Code setup
|
|
135
|
+
|
|
136
|
+
The repo ships `.vscode/launch.json` with three configurations:
|
|
137
|
+
|
|
138
|
+
- **Flua: Run Current File** — runs the file in the panel.
|
|
139
|
+
- **Flua: Run Current File (Terminal)** — runs it in the integrated terminal
|
|
140
|
+
(pick this one for `self:debug` output you can scroll).
|
|
141
|
+
- **Flua: Debug Current File (mobdebug)** — real debugging: breakpoints,
|
|
142
|
+
stepping, variable inspection. Install the VS Code extension
|
|
143
|
+
**Lua MobDebug** (`alexeymelnichuk.lua-mobdebug`), open your QA, press F5
|
|
144
|
+
with the mobdebug configuration selected. flua waits for the debugger
|
|
145
|
+
before running your code.
|
|
146
|
+
|
|
147
|
+
While you step through code, `print`/`self:debug` output appears **immediately**
|
|
148
|
+
— logs never queue behind a paused program.
|
|
149
|
+
|
|
150
|
+
The fastest loop for tinkering:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
.venv/bin/flua --watch script.lua
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
flua restarts the QA whenever you save the file (or any `--%%file` file).
|
|
157
|
+
Ctrl-C stops it. Works on top of the debugger too.
|
|
158
|
+
|
|
159
|
+
## QA directives (`--%%`)
|
|
160
|
+
|
|
161
|
+
Directives are ordinary Lua comments at the top of the file. flua parses them
|
|
162
|
+
before running; the HC3 ignores them — the same file runs in both places.
|
|
163
|
+
Parsing stops at the end-of-header marker:
|
|
164
|
+
|
|
165
|
+
```lua
|
|
166
|
+
--%%name:my-qa
|
|
167
|
+
-- --------------- EOH ---------------
|
|
168
|
+
-- nothing below this line is parsed as a directive
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
| Directive | Meaning |
|
|
172
|
+
|---|---|
|
|
173
|
+
| `--%%name:x` | the device/QA name (`_FLUA.config.name`) |
|
|
174
|
+
| `--%%type:com.fibaro.binarySwitch` | device type (defaults to binarySwitch; unknown types are an error) |
|
|
175
|
+
| `--%%properties:value=false` | default device properties (plural form) |
|
|
176
|
+
| `--%%property:value=true` | raw property, scalar values; repeatable, merges |
|
|
177
|
+
| `--%%var:name=value` | initializes a **QuickApp variable** (string values; `self:getVariable(name)`) |
|
|
178
|
+
| `--%%uid:...` | sets `quickAppUuid` |
|
|
179
|
+
| `--%%description:...` | sets `userDescription` |
|
|
180
|
+
| `--%%model:...` | sets `model` |
|
|
181
|
+
| `--%%build:7` | sets `buildNumber` (a number) |
|
|
182
|
+
| `--%%manufacturer:...` | sets `manufacturer` |
|
|
183
|
+
| `--%%file:lib.lua,lib` | extra QA file, loads before main (see below) |
|
|
184
|
+
| `--%%speed:60` | virtual time speed (global) |
|
|
185
|
+
| `--%%instant:true` | instant mode (global) |
|
|
186
|
+
| `--%%maxhours:48` | stop after 48 virtual hours (global) |
|
|
187
|
+
| `--%%time:speed=2,instant=true,hours=48,start=2027/10/6 12:00:20` | combined runtime settings (global) |
|
|
188
|
+
| `--%%time:2027/10/6 12:00:20` | bare form: set the virtual start time |
|
|
189
|
+
|
|
190
|
+
Names follow plua: `--%%name:value` for scalars,
|
|
191
|
+
`--%%name:sub1=val1,sub2=val2` for subparameters. A typo'd directive is
|
|
192
|
+
silently ignored at runtime — run `flua --check` to catch those.
|
|
193
|
+
|
|
194
|
+
The virtual clock starts **now** unless you set a start time — handy for
|
|
195
|
+
testing dates: leap years, DST switches, New Year logic. Combine with
|
|
196
|
+
`--instant` to fast-forward through the interesting moments:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
.venv/bin/flua --start "2027/12/31 23:59:50" script.lua
|
|
200
|
+
# or in the file: --%%time:start=2027/12/31 23:59:50,instant=true
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Multi-file QAs
|
|
204
|
+
|
|
205
|
+
On the HC3 a QA is a set of named Lua files — one is `main`. flua keeps your
|
|
206
|
+
files on disk and declares the extras in the main file:
|
|
207
|
+
|
|
208
|
+
```lua
|
|
209
|
+
--%%file:lib.lua,lib
|
|
210
|
+
--%%file:util.lua,util
|
|
211
|
+
-- --------------- EOH ---------------
|
|
212
|
+
print(helper())
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Files load in declaration order, **main loads last**. Paths resolve relative
|
|
216
|
+
to the main file's directory. See `examples/multifile.lua`. The HC3's file
|
|
217
|
+
API works offline too (`api.get('/quickApp/' .. _FLUA.qaId .. '/files')` etc.).
|
|
218
|
+
|
|
219
|
+
## The offline HC3
|
|
220
|
+
|
|
221
|
+
`--seed` loads a simulated house (see `examples/house.json`):
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
.venv/bin/flua --seed examples/house.json script.lua
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Your QAs become devices (ids from 5000) in the same simulated HC3, so
|
|
228
|
+
everything works between them:
|
|
229
|
+
|
|
230
|
+
- `api.get/post/put/delete` — the real HC3 REST surface (devices, plugins,
|
|
231
|
+
variables, globals, scenes, alarms, profiles, refreshStates, …)
|
|
232
|
+
- `fibaro.call(id, 'turnOn')` — calls another QA's QuickApp method
|
|
233
|
+
- `fibaro.emitCustomEvent(name)` → `QuickApp:onCustomEvent(name)` handlers
|
|
234
|
+
- `self:setVariable/getVariable` — persistent, survives restarts
|
|
235
|
+
- `GET /refreshStates?last=N` — the HC3's polling change feed
|
|
236
|
+
|
|
237
|
+
QAs find each other by name with `fibaro.getIds({type = "quickApp"})` — see
|
|
238
|
+
`examples/qa3.lua` and `examples/qa4.lua` calling each other.
|
|
239
|
+
|
|
240
|
+
## Loading QAs at runtime
|
|
241
|
+
|
|
242
|
+
From VS Code you often run one QA — let it bring up the QAs it needs:
|
|
243
|
+
|
|
244
|
+
```lua
|
|
245
|
+
local id = _FLUA.loadQAfromFile("examples/qa3.lua") -- annotations parsed
|
|
246
|
+
local id2 = _FLUA.loadQAfromString([[ ...inline QA... ]])
|
|
247
|
+
fibaro.call(id, "turnOn") -- immediately reachable
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Both return the new QA id (or `nil, error`). `examples/dynamic.lua` demos it.
|
|
251
|
+
|
|
252
|
+
## Network clients
|
|
253
|
+
|
|
254
|
+
Real network, HC3-style APIs, all asynchronous through the pump (callbacks
|
|
255
|
+
run in your QA, timers keep running while requests are in flight):
|
|
256
|
+
|
|
257
|
+
- `net.HTTPClient()` → `request(url, {options, success, error})` — `examples/http.lua`
|
|
258
|
+
- `net.TCPSocket({timeout=ms})` → `connect/send/read/readUntil/close` — `examples/tcp.lua`
|
|
259
|
+
- `net.UDPSocket({broadcast, timeout})` → `sendTo/receive` — `examples/udp.lua`
|
|
260
|
+
- `net.WebSocketClient()/WebSocketClientTls()` → `addEventListener`, `connect`, `send` — `examples/websocket.lua`
|
|
261
|
+
- `mqtt.Client.connect(uri, options)` → `subscribe/publish/unsubscribe/disconnect`, `mqtt.QoS` — `examples/mqtt.lua`
|
|
262
|
+
|
|
263
|
+
## Deploying to the HC3
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
.venv/bin/flua export script.lua -o myqa.fqa
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Upload `myqa.fqa` through the HC3 web UI (Create QuickApp → import). The
|
|
270
|
+
package follows the HC3's schema — only the properties the HC3 accepts
|
|
271
|
+
travel; dynamic properties are left out.
|
|
272
|
+
|
|
273
|
+
## Bringing an HC3 QA home
|
|
274
|
+
|
|
275
|
+
Export the QA from the HC3 UI (`.fqa`), then:
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
.venv/bin/flua unpack myqa.fqa -d myqa-project/
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
You get a runnable flua project: `main.lua` with generated `--%%` directives
|
|
282
|
+
and one file per QA file, ready for editing and debugging.
|
|
283
|
+
|
|
284
|
+
## Static checks
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
.venv/bin/flua --check script.lua
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
Checks syntax, unknown `--%%` directives (typos), and deprecated API calls.
|
|
291
|
+
Warnings don't fail the run; syntax errors exit 1. Good in CI.
|
|
292
|
+
|
|
293
|
+
## flua extensions (`_FLUA`)
|
|
294
|
+
|
|
295
|
+
Everything HC3-compatible is a plain global (`QuickApp`, `fibaro`, `api`,
|
|
296
|
+
`net`, `mqtt`, `json`, …). flua-specific helpers live on `_FLUA` so your code
|
|
297
|
+
stays portable:
|
|
298
|
+
|
|
299
|
+
- `_FLUA.qaId` — this QA's id; `_FLUA.config` — this QA's config table
|
|
300
|
+
- `_FLUA.arg` — the file path / `-e` marker
|
|
301
|
+
- `_FLUA.exit(code)` — stop the engine (vs `exit(code)` which stops only this QA)
|
|
302
|
+
- `_FLUA.qa(id)` — another QA's QuickApp instance (lupa proxy)
|
|
303
|
+
- `_FLUA.loadQAfromFile(path)` / `_FLUA.loadQAfromString(code)` — dynamic QA loading
|
|
304
|
+
- `_FLUA.async.run(fn)` / `_FLUA.async.await(worker)` / `_FLUA.async.wait(ms)` — coroutine awaits
|
|
305
|
+
- `_FLUA.setTimeout(fn, ms, qaId)` — timer with explicit QA attribution
|
|
306
|
+
- `if _FLUA then` — detect flua at runtime
|