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 :
- Add a new device and choose a type (e.g. “D_BinaryLight1.xml” or “D_TemperatureSensor1.xml”).
- Reload LUUP engine.
- Change the attribut “id_parent” with the id of the MQTT plugin device.
- Reload LUUP engine and refresh your browser.
- You should see variables “mqttTarget” and “mqttTopic” in your newly created device.
- Set the topic you want to subcribe to and the target (format: service,variable=(formula in LUA)).
- 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 )
end
return
end
local subTopic = table.remove( subTopics, 1 )
if ( subTopic == "" ) then
return
end
if ( subIndex[ subTopic ] == nil ) then
subIndex[ subTopic ] = { ["*"] = {} }
end
if ( ( subTopic == "#" ) or ( #subTopics == 0 ) ) then
table.insert( subIndex[ subTopic ]["*"], subscription )
else
Subscriptions.addToIndex_( subscription, subIndex[ subTopic ], subTopics )
end
end,
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 = subscription.target:match( "^(.*),([^=]*)=?(.*)$" )
if ( subscription.service == "" ) then
subscription.service = nil
end
if ( subscription.variable == "" ) then
subscription.variable = nil
end
if ( subscription.formula == "" ) then
subscription.formula = nil
end
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 ) )
else
-- Put the LUA code in a sandbox
subscription.jail = { tonumber = tonumber, tostring = tostring }
setfenv( subscription.luaFormula, subscription.jail )
end
end
table.insert( mqttSubscriptions, subscription )
if ( subscription.topic ~= "" ) then
table.insert( topics, subscription.topic )
end
-- Add to index
Subscriptions.addToIndex_( subscription, mqttIndexTopics, string_split( subscription.topic or "", "/" ) )
end
end
subscribeMqttTopics( topics )
end,
getFromIndex_ = function( subIndex, subTopics )
if ( #subTopics == 0 ) then
return subIndex["*"] or {}
end
local subTopic = table.remove( subTopics, 1 )
local subscriptions = {}
if subIndex["#"] then
table_append( subscriptions, subIndex["#"]["*"] )
end
if subIndex["+"] then
table_append( subscriptions, Subscriptions.getFromIndex_( subIndex["+"], subTopics ) )
end
if subIndex[ subTopic ] then
table_append( subscriptions, Subscriptions.getFromIndex_( subIndex[ subTopic ], subTopics ) )
end
return subscriptions
end,
get = function( topic )
return Subscriptions.getFromIndex_( mqttIndexTopics, string_split( topic or "", "/" ) )
end
}
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.