# The complete code

function findFunction(id)
	for i, fun in ipairs(functions) do
		if fun.id == id then
			return functions[i]
		end
	end
end

function handleTrigger(topic, payload, retained)
	local data = json:decode(payload)

	-- Verify that the door was opened
	if data.value == openState then
		-- Turn on
		local payload = json:encode({ value = onValue })
		mq:pub(controlTopic, payload, false, 0)

		-- Start timer for off..
		timer:after(cfg.timeout, function()
			local payload = json:encode({ value = offValue })
			mq:pub(controlTopic, payload, false, 0)
		end)
	end
end

function onStart()
	-- Get all values for the trigger
	local triggerFunction = findFunction(cfg.triggerFunction)
	triggerTopic = triggerFunction.meta.topic_read

	-- Manually call the updated function to set the initial state of the variables
	onFunctionsUpdated()

	mq:sub(triggerTopic, 0)
	mq:bind(triggerTopic, handleTrigger)
end

function onFunctionsUpdated()
	-- Get all values for the trigger
	local triggerFunction = findFunction(cfg.triggerFunction)
	openState = tonumber(triggerFunction.meta.state_open)
	closedState = tonumber(triggerFunction.meta.state_closed)

	-- Get all values for the control function
	local controlFunction = findFunction(cfg.actuatorFunction)
	controlTopic = controlFunction.meta.topic_write
	onValue = tonumber(controlFunction.meta.state_on)
	offValue = tonumber(controlFunction.meta.state_off)
end