Here is the classic testing gap: your QuickApp reacts to other devices — a scene fires on motion, a climate QA follows a temperature sensor, an alarm panel arms on a door sensor. To test that logic you need the devices around your QA. Until now you stubbed them by hand. Not anymore: flua ships simulated devices — 30 device types, bundled in the package (a pip install is enough), loaded with one call.
local temp = _FLUA.loadSimDevice("temperatureSensor") -- returns the device id
fibaro.call(temp, "setValue", 21.5, "C") -- the house warms up
The whole contract fits in one QA:
--%%name:HouseCheck
--%%type:com.fibaro.genericDevice
function QuickApp:onInit()
-- the house: two devices, loaded by name — bundled with flua
local temp = _FLUA.loadSimDevice("temperatureSensor")
local motion = _FLUA.loadSimDevice("motionSensor")
self:debug("sim devices:", temp, motion)
-- a reacting QA: it watches the house like a real scene would
local events = RefreshStateSubscriber()
events:subscribe(
function(event) return event.type == "DevicePropertyUpdatedEvent" end,
function(event)
self:debug("change:", json.encode(event.data))
end)
events:run()
-- drive the devices — exactly like the HC3 UI or a scene would
fibaro.call(temp, "setValue", 21.5, "C")
fibaro.call(motion, "breach")
fibaro.call(motion, "clearBreach")
setTimeout(function()
local dev = api.get("/devices/"..temp)
self:debug("temp is now", dev.properties.value, dev.properties.unit)
_FLUA.exit(0) -- the sim devices stay up; end the run ourselves
end, 300)
end
Run it and watch the subscriber follow every change — three
DevicePropertyUpdatedEvents, exactly as a real device would
post them. Your scenes and reacting QAs get the genuine event flow,
offline, on your laptop.
The bundled set mirrors the QuickApp device templates — and every sim
device answers a uniform, fibaro.call-able API:
setValue(value, unit?) and
setUnit(unit).setValue(bool), breach(),
clearBreach(). The sensor's value is the
breach state — the HC3 contract, no extra property.turnOn/turnOff/
setValue, plus their stock actions —
arm/disarm/setArmed for the alarm
partition, setThermostatMode/setHeatingThermostatSetpoint
for the HVAC trio, setColor for the color controller,
play/pause/setVolume for the player,
emitCentralSceneEvent for the remote.Unknown name? loadSimDevice throws an error that lists
every bundled device — discoverability built in. And because the devices
live inside flua, there is nothing to download, unpack, or configure.
Start any run with --ui and the sim devices appear as
normal panels: ARMED/DISARMED on the alarm partition, colored TRUE/FALSE
on breach sensors, live readings with their units on value sensors, the
transport state on the player, the condition on the weather device. The
types that have controls (switches, player, climate, color) can be driven
straight from the panel while your QA reacts.
Want the house weather instead of one device? The weather
simulator QA (weatherMgr) drives the
simulated /weather endpoint — condition, temperature,
humidity, wind — and every change posts a
WeatherChangedEvent on the refreshStates feed. Combine it
with the climate QA you are testing and you have a whole season on
demand.
Sim devices keep the run alive for as long as they exist (no more
setInterval(function() end, 3600000) hacks — that is
_FLUA.keepAlive() now, and they call it themselves), so a
test run ends with _FLUA.exit(0) when you say so.
Next up: the house gets a custom REST surface — registered endpoints your QAs (and your tools) can call.