MQTT Client Plugin

In the early part of /usr/share/lua/5.1/mqtt_library.lua I’ll bet you find this:

if (not isPsp()) then

Some versions of Lua will define a global with the name of the loaded module when using require, and some do not. Lua on my Veras does, but on my Ubuntu VM that I regularly use for development (and openLuup) it does not. To fix:

if (not isPsp()) then
  socket = require("socket")
  io = require("io")
  ltn12 = require("ltn12")
--ssl = require("ssl")

(I put the fix in the comment even though it won’t be used, just for consistency)

Yes, and thanks for that. After banging on this for a few more hours I had concluded similarly that the “if not Psp” block wasn’t setting a global collection, therefore there was no global. What is Psp anyway?

But that’s interesting that some luas will push require to a global and some not.

I got socket and therefore the connection to work, but after a bit there is a new error. So onto the next puzzle I guess.

ERROR: files/L_SensorMqtt1.lua:331: attempt to index upvalue ‘alias’ (a boolean value)

2019-10-01 19:26:28.248   luup_log:33: SensorMqtt: Watch event - device: 10320 variable: ArmedTripped value 0 => 1
2019-10-01 19:26:28.248   openLuup.context_switch::  ERROR: files/L_SensorMqtt1.lua:331: attempt to index upvalue 'alias' (a boolean value)
2019-10-01 19:26:28.248   openLuup.scheduler:: 10320.urn:micasaverde-com:serviceId:SecuritySensor1.ArmedTripped ERROR files/L_SensorMqtt1.lua:331: attempt to index upvalue 'alias' (a boolean value) function: 0x882820
2019-10-01 19:26:32.900   luup_log:33: SensorMqtt: Connection down: socket_client:receive(): closed
2019-10-01 19:26:32.901   luup_log:33: SensorMqtt: MQTT connection status changed from "Connected" to "Disconnected"
2019-10-01 19:26:32.901   luup.variable_set:: 33.urn:upnp-sensor-mqtt-se:serviceId:SensorMqtt1.mqttServerStatus was: Connected now: Disconnected #hooks:0
2019-10-01 19:26:32.901   luup.variable_set:: 33.urn:upnp-sensor-mqtt-se:serviceId:SensorMqtt1.mqttServerConnected was: 1 now: 0 #hooks:0
2019-10-01 19:26:38.071   luup_log:33: SensorMqtt: Connection down: /usr/share/lua/5.1/mqtt_library.lua:382: MQTT.client:handler(): Not connected
2019-10-01 19:26:43.109   luup_log:33: SensorMqtt: Connection down: /usr/share/lua/5.1/mqtt_library.lua:382: MQTT.client:handler(): Not connected

Everything working great now.

Hmm The subscribe functionality of this plugin could be used to get data from Zwave2MQTT as it is still work in progress, I am considering to create a device bridge from openLuup to an instance of Zwave2Mqtt so as to replace the vera with a much more open and reliable alternative with that project turns out to work well and indeed better than where the vera is currently going.

I did make a small change to L_SensorMqtt1.lua to re-subscribe to subscribed topics after reconnecting to the broker if the connection was lost for any reason. I was having a problem with my broker disconnecting me. I ditched the broker and built my own instead but I still think this is a useful change. 3 lines added after the “connectToMqtt()”

– Publish an MQTT message

function publishMessage(topic, payload)

    log_debug("Publish topic: " .. topic .. " message:" .. payload)

    -- If we aren't connected for some reason, then connect first
    if not connectedToBroker() then
            if connectedToBroker() then

    -- Try to publish.  Mqtt standard is fire and forget on publishing.
    local ok, result = pcall(mqttClient.publish, mqttClient, topic, payload)
    if ( not ok ) then
            log_warn("Unable to publish, connection down.  Discarding message: " .. payload)


I also created a simple Reactor group that watches the connected status and initiates the equivalent of a sensor trip once per minute until the connection is restored. Since the sensor trips are published a reconnect will be attempted each time. This helps minimize any ‘outage’.

1 Like

I have the plugin running on openLuup without any error messages. I have created 4 virtual switches, each with the MQTT device as the parent device. Each switch subscribes to a different topic (all topics are individual tasmota switch statuses) on my MQTT broker, Mosquito. I can see in the log that there is a recognized payload: the payload for each switch is simply “ON” or “OFF”.

However, I cannot get the virtual switch (which represents the tasmota switch), to toggle on or off when a payload arrives.

The bit of example code included in the plugin readme, that represents a “lua formula”, has me completely baffled:

urn:upnp-org:serviceId:SwitchPower1,Status=payload.value and ((payload.value=="alarm") and "1" else "0")

I have tried:

urn:upnp-org:serviceId:SwitchPower1,Status=payload.value and ((payload.value=="ON") and "1" else "0")
urn:upnp-org:serviceId:SwitchPower1,Status= if (payload.value=="ON") then "1" else "0" end

or changing the variable type… then 1 else 0 end etc. Nothing seems to work, and I don’t understand the syntax of the formula in the context of what the readme says the formula is supposed to do: ie turn the virtual switch on or off.

Can anyone help here.

The fragment you have provided is not valid Lua, so I’m presuming that these are parameters to a function call?

This bit:

payload.value and ((payload.value=="alarm")

…is simply a conditional which is true if the value of the payload is “alarm”, but this will never be so since your payload value is “ON” or “OFF”.

Can we see a bit more of the code to fully understand what you need to do here?


Hey AK,

Yes, these are parameters to a function call. However, it’s not clear what the function does, the function’s syntax, and any formatting that is required. The function is described in the readme as follows:

You can subscribe to a topic by creating a child device :

  1. Add a new device and choose a type (e.g. “D_BinaryLight1.xml” or “D_TemperatureSensor1.xml”).
  2. Reload LUUP engine.
  3. Change the attribut “id_parent” with the id of the MQTT plugin device.
  4. Reload LUUP engine and refresh your browser.
  5. You should see variables “mqttTarget” and “mqttTopic” in your newly created device.
  6. Set the topic you want to subcribe to and the target (format: service,variable=(formula in LUA)).
  7. Reload LUUP engine.

If the payload of the received message is in JSON, the plugin will try to decode it and put it in the variable “payload” in the context of the LUA formula.

Examples :

Topic  : Test/#
Target: urn:upnp-org:serviceId:SwitchPower1,Status=payload.value and ((payload.value=="alarm") and "1" or "0")

On a message from topic ‘Test/Something’ with payload ‘{“value”:“alarm”}’, the switch will be powered on.

Topic  : Test/+/Sensor
Target: urn:upnp-org:serviceId:TemperatureSensor1,CurrentTemperature=payload.temperature and (tonumber(payload.temperature) or "0")

On a message from topic ‘Test/Something/Sensor’ with payload "{"temperature “:“15.2”, “hygrometry”:“80”}”, the temperature will be set to 15,2.

The function seems to be stored in a table called subscriptions in the “L_SensorMqtt1.lua” file at around line 460:

 Subscriptions = {

	addToIndex_ = function( subscription, subIndex, subTopics )
		if ( #subTopics == 0 ) then
			if subIndex["*"] then
				table.insert( subIndex["*"], subscription )
		local subTopic = table.remove( subTopics, 1 )
		if ( subTopic == "" ) then
		if ( subIndex[ subTopic ] == nil ) then
			subIndex[ subTopic ] = { ["*"] = {} }
		if ( ( subTopic == "#" ) or ( #subTopics == 0 ) ) then
			table.insert( subIndex[ subTopic ]["*"], subscription )
			Subscriptions.addToIndex_( subscription, subIndex[ subTopic ], subTopics )

	retrieve = function()

		log_debug("************************************************ Subscriptions Settings ***************************************")

		mqttSubscriptions = {}
		mqttIndexTopics = {}
		local topics = {}
		local strError
		for deviceId, device in pairs( luup.devices ) do
			if ( device.device_num_parent == DEVICE_ID ) then
				local subscription = {
					deviceId = deviceId,
					topic    = getVariableOrInit( deviceId, SERVICE_ID, "mqttTopic", "" ),
					target   = getVariableOrInit( deviceId, SERVICE_ID, "mqttTarget", "" )
				-- service,variable=formula
				-- eg for topic /test/, payload {"value":"alarm"}
				-- urn:upnp-org:serviceId:SwitchPower1,Status=payload.value and ((payload.value=="alarm") and "1" or "0")
				subscription.service, subscription.variable, subscription.formula = "^(.*),([^=]*)=?(.*)$" )
				if ( subscription.service == "" ) then
					subscription.service = nil
				if ( subscription.variable == "" ) then
					subscription.variable = nil
				if ( subscription.formula == "" ) then
					subscription.formula = nil
				log_debug( "Device #" .. tostring( subscription.deviceId ) .. ", topic=" .. subscription.topic .. ", service=" .. tostring(subscription.service) .. ", variable=" .. tostring(subscription.variable) .. ", formula=(" .. tostring(subscription.formula) .. ")" )
				if ( subscription.formula ) then
					-- Try to prepare the LUA code of the formula
					subscription.luaFormula, strError = loadstring( "return " .. subscription.formula )
					if ( subscription.luaFormula == nil ) then
						log_error( "Error in target LUA formula: " .. tostring( strError ) )
						-- Put the LUA code in a sandbox
						subscription.jail = { tonumber = tonumber, tostring = tostring }
						setfenv( subscription.luaFormula, subscription.jail )
				table.insert( mqttSubscriptions, subscription )
				if ( subscription.topic ~= "" ) then
					table.insert( topics, subscription.topic )
				-- Add to index
				Subscriptions.addToIndex_( subscription, mqttIndexTopics, string_split( subscription.topic or "", "/" ) )
		subscribeMqttTopics( topics )

	getFromIndex_ = function( subIndex, subTopics )
		if ( #subTopics == 0 ) then
			return subIndex["*"] or {}
		local subTopic = table.remove( subTopics, 1 )
		local subscriptions = {}
		if subIndex["#"] then
			table_append( subscriptions, subIndex["#"]["*"] )
		if subIndex["+"] then
			table_append( subscriptions, Subscriptions.getFromIndex_( subIndex["+"], subTopics ) )
		if subIndex[ subTopic ] then
			table_append( subscriptions, Subscriptions.getFromIndex_( subIndex[ subTopic ], subTopics ) )
		return subscriptions

	get = function( topic )
		return Subscriptions.getFromIndex_( mqttIndexTopics, string_split( topic or "", "/" ) )

What I cannot see is how to structure the function syntax to turn its host object (virtual switch) off and on. I suppose I could just create my own variable with the function, and then use that variable in a reactor sensor to do the on/off work with a set target action, but this seems clumsy. It’s a nice plugin, with even greater potential, but as is often the case with plugins, specifics are learned the hard way.

Any help is appreciated.

This is what I use to control a virtual switch. This is what is in the mqttTarget variable of the virtual switch


I have a Mqtt client app on my phone that will send a message of either {“value”:“1”} or {“value”:“0”} depending on the state of a button on the app. This is about the simplest use case.

To make use of the state of the virtual switch I can use a variable watch in a scene or a reactor group that does the same thing. Using a trigger in a scene will not work.

If the Mqtt message uses (for example) “ON” and “OFF” instead of “1” and “0”, the function in mqttTarget gets a little more complex.

urn:upnp-org:serviceId:SwitchPower1,Status=((payload.value=="ON") and "1") or ((payload.value=="OFF") and "0") or "0"

For the virtual switch the function must result in a “1” or a “0”. Note these are strings and not numbers. Numbers won’t work. I learned that the hard way.

You mentioned that your payload is either ON or OFF. Does that mean that your actual Mqtt message is {“value”:“ON”} or {“value”:“OFF”}? Or maybe just {“ON”} or {“OFF”}? Or maybe just “ON” or “OFF”?

The plugin examples all follow the first pattern, which is a representation of a JSON object. I have not tried the second or third patterns, though I may give it a try to see what happens.

I have a few other Mqtt fed virtual sensors or devices also and I can show working examples if you’re interested. A few of these required some scene lua also.

mqtt virtual switch (of course)
mqtt virtual temperature sensor
mqtt virtual humidity sensor
mqtt multi-string container
mqtt multiswitch

Hope this helps you out! --D

Hey, thanks, that definitely helps.

Here’s the log entry for the payload:

2019-11-12 12:37:34.710 luup.variable_set:: 227.urn:upnp-sensor-mqtt-se:serviceId:SensorMqtt1.mqttLastReceivedPayload was: ON now: ON #hooks:0

2019-11-12 12:37:34.710 luup_log:227: SensorMqtt: Receive topic: stat/power_main_vera/POWER payload:ON

When I look at the payload in MQTT.fx (an MQTT inspector), there are no field names associated with the payload value, so I believe that the value of “ON” or “OFF” is all that is being sent by Mosquitto.

I tried your revised conditional formula, but it does not seem to pick up on the payload as the “Status” variable remains unchanged at “0”.


I am using the MQTT plugin for some time and there was absolutely no issues with the plugin. However I have faced one issue yesterday. I am not able to find out how to change it.

Situation in general:

I am using the “watchdog variables” from Vera plugin (monitoring the hard disk space, free, used, total) in order to sent data to broker and later on input it to Influx for Grafana purposes. So far so good.
However if there is no any changes in the values, nothing is sent towards broker. Normally I am OK with this, but it is crashing all the graphs in Grafana. No new input, no lines in graph. There is only 1 point on the graph and no second point to create the graph.

Is it possible to configure that periodically (for example - 1 time per some 12h) update will be sent, even if there is no update.

Thanks for any hints and solutions.

A simple general solution to this problem, which should work for any plugin with this issue, is to set up a scheduled scene which reads the variables in question, and modifies them (without changing their numerical value.)

However, this does depend on how the plugin determines that the value has not changed.

How to change the variable without changing its value? Since all device variables are, in fact, strings, then you can just add a blank space to the tail of the variable. Try this out manually, first, and see if it triggers an MQTT update.

So @Buxton, it appears the message from your Mqtt client is a simple string and not a string representation of a JSON object. That’s fine. I tested the following and it works with my virtual switch

urn:upnp-org:serviceId:SwitchPower1,Status=((payload=="ON") and "1") or ((payload=="OFF") and "0") or "0"

The way this works is; the first condition is evaluated and if the payload string is ON, the and “1” is evaluated resulting in “1”. Since the first and condition is satisfied the remaining or expressions are not evaluated and “1” is returned from the expression. If payload string is OFF the first and expression fails and the next and expression after the first or is evaluated. Since the payload is OFF, the and “0” is evaluated resulting in “0”. Since this and condition is satisfied the remaining or expression is not evaluated and “0” is returned from the expression. If payload is neither ON or OFF the final or expression results in “0” getting returned from the expression.

In reality, since the switch is either ON, or it isn’t, the logic can be greatly simplified as follows:

urn:upnp-org:serviceId:SwitchPower1,Status=payload=="ON" and "1" or "0"

Hope this helps! --D

Awesome, both expressions work. So the problem was that I was referencing a field named “.value” — that didn’t exist because the payload variable had only a simple text string.

And thanks for clarifying how the function evaluates the input side. I’m hoping that the plugin author can provide some guidance on do’s and dont’s as regards the syntax in the function call as I can foresee quite a large range of MQTT subscriptions that could be used with this plugin…

I appreciate the second look you took here.

Now if the publish side of the MQTT exchange could be contained in the child device, that would close the loop on using the virtual device for MQTT actions… though this can be done with a reactor sensor acting on the vswitch state.

As well, I hope to see QOS level 1 implemented in the underlying MQTT lua module. It seems like this could be done with simple callbacks and delays to ensure accurate message transfer.

Thanks again.

Hi akbooer,

Great idea, so simple… ::slight_smile:

Introducing “nil” solve this issue :slight_smile:

Grafana is ignoring “nil”, so all good.


1 Like

I’ve just updated my Vera Plus to the latest firmware and now the plugin seems not to work anymore. Strange thing I’m not anymore able to see it in the list of installed apps and not in the apps we can install!
Does someone had the same problem ?
Thanks in advance

I reply myself to my post. Seems that the firmware upgrade has erased the dependencies added in /usr/lib/lua
Copied again the dependencies and rebooted the vera and the MQTT messages are back

I had the same issue and can confirm that the dependencies were missing after the FW upgrade. Reinstalled the files and the plugin is working again.

I’m glad I found this plug-in which is successfully running on a VeraEdge and meant to be used for integration with my Home Assistant Mosquitto broker. Using MQTT explorer I get the following result:

“ServiceId”: “urn:upnp-org:serviceId:TemperatureSensor1”,
“CurrentTemperature”: 0.5,
“DeviceId”: 129,
“DeviceName”: “dT-FloorHeating”,
“Time”: 1584366108,
“RoomName”: “Central Heating”,
“OldCurrentTemperature”: 0.3,
“Variable”: “CurrentTemperature”,
“RoomId”: 9,
“DeviceType”: “urn:schemas-micasaverde-com:device:TemperatureSensor:1”

The thing I’m struckling with is how to get the variable CurrentTemperature displayed as an entity within Home Assistant. I have tried the following to no avail:

  • platform: mqtt
    name: “CurrentTemperature”
    state_topic: “Vera/Events/191”
    value_template: ‘{{ value_json.CurrentTemperature[0].value }}’

Any guidance would be highly appreciated.

I have a similar issue to what has been described here. When I start up Home Assistant broker, all values from VERA are initially UNKNOWN. Only after some time are values being reported. Should I assume that the mqtt client only reports by exception, i.e. at change of current value? If this is the case I can assume all is working fine, otherwise I have to dig deeper and identify why! Any feedback would be appreciated.

Best Home Automation shopping experience. Shop at getvera!

© 2020 Vera Control Ltd., All Rights Reserved. Terms of Use | Privacy Policy | Forum Rules