Page 1 of 1

publish data under specific MQTT topic

Posted: Thursday 21 May 2020 9:15
by fireport
Hi to everyone,
I have a magicmirror module that subscribes to tasmota MQTT topic and, using json pointer, displays data on my monitor.
Now I need to subscribe to information available only in domoticz (like a custom monthly power consumption)
I tried to use it subscribing to domoticz/out but I didn't find a suitable JSON pointer.
So, now, I'm looking for a script that can publish to a specific topic in the MQTT broker.
Can someone help me?

To give you an example, this is a snap of my current module configuration

Code: Select all

 {
            module: "MMM-MQTT",
            position: "top_center",
            header: "Temperatura",
            config: {
                logging: false,
                useWildcards: false,
                mqttServers: [{
                    address: "xxxxxx",
                    port: "1883",
                    user: "xxxxx",
                    password: "xxxxxx",
                    subscriptions: [{
                            topic: "sensore_salone/tele/SENSOR",
                            label: "Salone:",
                            suffix: "°C",
                            decimals: 1,
                            sortOrder: 10,
                            maxAgeSeconds: 600,
                            jsonpointer: "/AM2301/Temperature"
                        }, 

Re: publish data under specific MQTT topic

Posted: Thursday 21 May 2020 10:37
by waaren
fireport wrote: Thursday 21 May 2020 9:15 So, now, I'm looking for a script that can publish to a specific topic in the MQTT broker.
Below dzVents script can be used for that. You need an installed mosquitto on your system.

When not yet familiar with dzVents please start with reading Get started Before implementing (~ 5 minutes). Special attention please for "In Domoticz go to Setup > Settings > Other and in the section EventSystem make sure the checkbox 'dzVents enabled' is checked. Also make sure that in the Security section in the settings you allow 127.0.0.1 to not need a password. dzVents uses that port to send certain commands to Domoticz. Finally make sure you have set your current location in Setup > Settings > System > Location, otherwise there is no way to determine nighttime/daytime state."

Code: Select all

local myDevicename = 'MQTT trigger' -- change to the name of the device that will trigger this script

return
{
    on =
    {
        devices =
        {
            myDevicename,
        },
    },

    logging =
    {
        level = domoticz.LOG_DEBUG,  -- change to LOG_ERROR when ok
    },

    execute = function(dz)

        local myMessage = 'enter your message here'
        local myTopic = 'whatever/topic/you/need'

        local function osCommand(cmd)
            dz.log('Executing Command: ' .. cmd,dz.LOG_DEBUG)

            local fileHandle = assert(io.popen(cmd .. ' 2>&1 || echo ::ERROR::', 'r'))
            local commandOutput = assert(fileHandle:read('*a'))
            local returnTable = {fileHandle:close()}

            if commandOutput:find '::ERROR::' then     -- something went wrong
                dz.log('Error ==>> ' .. tostring(commandOutput:match('^(.*)%s+::ERROR::') or ' ... but no error message ' ) ,dz.LOG_DEBUG)
            else -- all is fine!!
                dz.log('ReturnCode: ' .. returnTable[3] .. '\ncommandOutput:\n' .. commandOutput, dz.LOG_DEBUG)
            end

            return commandOutput,returnTable[3] -- rc[3] contains returnCode
        end

        local function sendMQTT(message, topic)
            local MQTTTopic = topic or 'domoticz/out'
            osCommand ( 'mosquitto_pub' ..  ' -t '  .. MQTTTopic .. " -m '" .. message .. "'")
        end

        sendMQTT(myMessage, myTopic)

    end
}

Re: publish data under specific MQTT topic

Posted: Thursday 21 May 2020 16:50
by fireport
Thank you @wareen !!
I slightly modify your code to publish three devices via MQTT.
Because I'm a novice of dzVents, any suggestion about the code will be very appreciated.

Code: Select all

--local myDevicename = 148 -- change to the name of the device that will trigger this script
local MyDevices             = {146,149}
return
{
    on =
    {
        timer = 
        { 
            'every minute',
        },
    },

    logging =
    {
        level = domoticz.LOG_DEBUG,  -- change to LOG_ERROR when ok
    },

    execute = function(dz)

       
        
        local function osCommand(cmd)
            dz.log('Executing Command: ' .. cmd,dz.LOG_DEBUG)

            local fileHandle = assert(io.popen(cmd .. ' 2>&1 || echo ::ERROR::', 'r'))
            local commandOutput = assert(fileHandle:read('*a'))
            local returnTable = {fileHandle:close()}

            if commandOutput:find '::ERROR::' then     -- something went wrong
                dz.log('Error ==>> ' .. tostring(commandOutput:match('^(.*)%s+::ERROR::') or ' ... but no error message ' ) ,dz.LOG_DEBUG)
            else -- all is fine!!
                dz.log('ReturnCode: ' .. returnTable[3] .. '\ncommandOutput:\n' .. commandOutput, dz.LOG_DEBUG)
            end

            return commandOutput,returnTable[3] -- rc[3] contains returnCode
        end

        local function sendMQTT(message, topic)
            local MQTTTopic = topic or 'domoticz/out'
            osCommand ( 'mosquitto_pub  -u user -P fireport68 ' ..  ' -t '  .. MQTTTopic .. " -m '" .. message .. "'")
        end

        for i,device in ipairs(MyDevices) do
            local myMessage = tostring(dz.devices(device).counter)
            --local myMessage = dz.devices(device).name .. '\\' .. tostring(dz.devices(device).counter)
            dz.log('myMessage: '  .. myMessage,dz.LOG_FORCE)
            local myTopic = 'domoticz/custom/' .. dz.devices(device).idx
            sendMQTT(myMessage, myTopic)
        end
        
       
       -- sendMQTT(myMessage, myTopic)

    end
}

Re: publish data under specific MQTT topic

Posted: Thursday 21 May 2020 18:18
by waaren
fireport wrote: Thursday 21 May 2020 16:50 Because I'm a novice of dzVents, any suggestion about the code will be very appreciated.
Looks good !

One thing to consider is if you really need to send the value every minute or only when the device is updated.
In the latter case you could do something like..

Code: Select all

        for _, device in ipairs(MyDevices) do
            myDevice = dz.devices(device)
            if myDevice.lastUpdate.minutesAgo < 2 then
                local myMessage = tostring(myDevice.counter)
                dz.log('myMessage: '  .. myMessage,dz.LOG_FORCE)
                local myTopic = 'domoticz/custom/' .. myDevice.idx
                sendMQTT(myMessage, myTopic)
            end
        end

Re: publish data under specific MQTT topic  [Solved]

Posted: Friday 22 May 2020 7:28
by fireport
Thank you waaren
I used one minute delay only for testing purposes. My devices are updated every 15 minutes.
Your code taught me new tricks about dzVents :D

Re: publish data under specific MQTT topic

Posted: Friday 08 October 2021 20:09
by jacobsentertainment
With some help found this topic, nice one!

How can one part in the topic be the value of an domoticz device? I'm planning on publishing a message to the mqtt so my zigbee bridge will send an message to a thermostat device.
The full topic/message that my zigbee needs to send =

Code: Select all

ZbSend {"Device":"0x8A30", "Write":{"OccupiedHeatingSetpoint": 22}}
Where "22" needs to be the value of a domoticz device (setpoint)

I tried the script above but getting

Code: Select all

Status: dzVents: Debug: Error ==>> sh: 1: mosquitto_pub: not found
What am I doing wrong here?

Re: publish data under specific MQTT topic

Posted: Friday 08 October 2021 20:43
by FireWizard
Hi, @jacobsentertainment

This indicates that probably mosquitto-clients has not been installed.

Regards

Re: publish data under specific MQTT topic

Posted: Friday 08 October 2021 22:42
by jacobsentertainment
FireWizard wrote: Friday 08 October 2021 20:43 Hi, @jacobsentertainment

This indicates that probably mosquitto-clients has not been installed.

Regards
I had a 5 minute brainfart and figured out that neededto be domoticz/out :lol:

Cheers. I got my issue solved thanks.

Re: publish data under specific MQTT topic

Posted: Saturday 20 August 2022 17:37
by juergen852
I would like to forward temperatures, pressure, on/off etc. to mosquitto, but I do not manage to send the values.
Tried different aproaches, but alwasy get errors when creating "myMessage".
Only the one which is commented out works, but it only sends sensorname\nil.

for i,device in ipairs(MyDevices) do
local myMessage = tostring(dz.devices(device).counter)
--local myMessage = dz.devices(device).name .. '\\' .. tostring(dz.devices(device).sensorValue) .. '\\' ..tostring(dz.devices(device).sensorValue)
local myMessage = dz.devices(device).name .. '\\' .. tostring(dz.devices(device).counter)
-- local myMessage = dz.devices(device).name .. '\\' .. dz.devices(device).idx .. '\\' .. tostring(dz.devices(device).sensorValue)
dz.log('myMessage: ' .. myMessage,dz.LOG_FORCE)
local myTopic = 'zypern2/' .. dz.devices(device).idx
sendMQTT(myMessage, myTopic)
end

Re: publish data under specific MQTT topic

Posted: Saturday 20 August 2022 17:47
by juergen852
Maybe I should publish the whole script.

--local myDevicename = 148 -- change to the name of the device that will trigger this script
local MyDevices = {1,2,7,8,9,10,11,12}
return
{
on =
{
timer =
{
'every minute',
},
},

logging =
{
level = domoticz.LOG_DEBUG, -- change to LOG_ERROR when ok
},

execute = function(dz)

local function osCommand(cmd)
dz.log('Executing Command: ' .. cmd,dz.LOG_DEBUG)

local fileHandle = assert(io.popen(cmd .. ' 2>&1 || echo ::ERROR::', 'r'))
local commandOutput = assert(fileHandle:read('*a'))
local returnTable = {fileHandle:close()}

if commandOutput:find '::ERROR::' then -- something went wrong
dz.log('Error ==>> ' .. tostring(commandOutput:match('^(.*)%s+::ERROR::') or ' ... but no error message ' ) ,dz.LOG_DEBUG)
else -- all is fine!!
dz.log('ReturnCode: ' .. returnTable[3] .. '\ncommandOutput:\n' .. commandOutput, dz.LOG_DEBUG)
end

return commandOutput,returnTable[3] -- rc[3] contains returnCode
end

local function sendMQTT(message, topic)
local MQTTTopic = topic
osCommand ( 'mosquitto_pub -h someserver.de -u someuser -P somepwd' .. ' -t ' .. MQTTTopic .. " -m '" .. message .. "'")
end

for i,device in ipairs(MyDevices) do
local myMessage = tostring(dz.devices(device).counter)
--local myMessage = dz.devices(device).name .. '\\' .. tostring(dz.devices(device).sensorValue) .. '\\' ..tostring(dz.devices(device).sensorValue)
local myMessage = dz.devices(device).name .. '\\' .. tostring(dz.devices(device).counter)
-- local myMessage = dz.devices(device).name .. '\\' .. dz.devices(device).idx .. '\\' .. tostring(dz.devices(device).sensorValue)
dz.log('myMessage: ' .. myMessage,dz.LOG_FORCE)
local myTopic = 'zypern2/' .. dz.devices(device).idx
sendMQTT(myMessage, myTopic)
end


-- sendMQTT(myMessage, myTopic)

end
}

Re: publish data under specific MQTT topic

Posted: Monday 08 July 2024 10:46
by Hencor
I'm also trying to publish data a bit more customized, so not under domoticz/out.
I'm running domoticz with docker, so I have not easy access to mosquitto_pub, if I'm not wrong!? Is there another solution with dzvents?

In my case I try to move my danfoss ally thermostats from deconz to zigbee2mqtt. To make use of the external temperature sensor feature I need to publish to a specific zigbee2mqtt topic.

I also asked for another option right here:
https://www.domoticz.com/forum/viewtopic.php?t=40342
Hencor wrote: Friday 05 July 2024 11:54 I have a small additional question regarding this topic.
Is there a possibility to change the values inside this setup section with dzvents or something?

Re: publish data under specific MQTT topic

Posted: Monday 08 July 2024 11:26
by waltervl
You can send MQTT payloads when you install mosquitto clients and use mosquitto_pub. There are dzvents examples on this forum how to send MQTT payloads with mosquitto_pub (search on this forum)

To install mosquitto_pub use

Code: Select all

apt-get -y install mosquitto-clients
Docker: To install mosquitto_pub in the Domoticz Docker container use the customstart.sh script, see
https://www.domoticz.com/wiki/Docker#cu ... _container
The example includes mosquitto-clients install

Re: publish data under specific MQTT topic

Posted: Monday 08 July 2024 12:22
by FlyingDomotic
If there's a direct link between MQTT topic and Domoticz device, you may also use MqttMapper plugin, which links in both ways topic and device. To write into a topic, just write into Domoticz device associated to it, MqttMapper will do the job.

Re: publish data under specific MQTT topic

Posted: Monday 08 July 2024 21:25
by Hencor
Thanks @waltervl. That did the trick! I have now a nice script that just sends out the external measured temperature to the right topic. Works like a charm.

@FlyingDomotic: Yes I know your nice plugin.
For now it seems the easier solution to me, to just write a dzvents script that send out the data. But perhaps I give it a try later. I'm a little bit fearful of creating the config.json :lol:

Re: publish data under specific MQTT topic

Posted: Monday 08 July 2024 23:22
by FlyingDomotic
The easiest way is the preferred one, and the best.

For json file, if you want to write it one day or the other, there are lot of examples in documentation, copy and past them to start ;-)