publish data under specific MQTT topic  [Solved]

Easy to use, 100% Lua-based event scripting framework.

Moderator: leecollings

Post Reply
fireport
Posts: 27
Joined: Friday 03 January 2020 21:14
Target OS: Linux
Domoticz version:
Contact:

publish data under specific MQTT topic

Post 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"
                        }, 
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: publish data under specific MQTT topic

Post 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
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
fireport
Posts: 27
Joined: Friday 03 January 2020 21:14
Target OS: Linux
Domoticz version:
Contact:

Re: publish data under specific MQTT topic

Post 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
}
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: publish data under specific MQTT topic

Post 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
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
fireport
Posts: 27
Joined: Friday 03 January 2020 21:14
Target OS: Linux
Domoticz version:
Contact:

Re: publish data under specific MQTT topic  [Solved]

Post 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
User avatar
jacobsentertainment
Posts: 223
Joined: Thursday 01 October 2020 1:47
Target OS: Raspberry Pi / ODroid
Domoticz version: 2021-1
Location: Not @ home
Contact:

Re: publish data under specific MQTT topic

Post 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?
User avatar
FireWizard
Posts: 1905
Joined: Tuesday 25 December 2018 12:11
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Voorthuizen (NL)
Contact:

Re: publish data under specific MQTT topic

Post by FireWizard »

Hi, @jacobsentertainment

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

Regards
User avatar
jacobsentertainment
Posts: 223
Joined: Thursday 01 October 2020 1:47
Target OS: Raspberry Pi / ODroid
Domoticz version: 2021-1
Location: Not @ home
Contact:

Re: publish data under specific MQTT topic

Post 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.
juergen852
Posts: 2
Joined: Saturday 20 August 2022 17:27
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: publish data under specific MQTT topic

Post 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
juergen852
Posts: 2
Joined: Saturday 20 August 2022 17:27
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: publish data under specific MQTT topic

Post 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
}
Hencor
Posts: 48
Joined: Sunday 01 September 2019 18:59
Target OS: Raspberry Pi / ODroid
Domoticz version: 2021.1
Location: DE
Contact:

Re: publish data under specific MQTT topic

Post 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?
User avatar
waltervl
Posts: 5900
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2024.7
Location: NL
Contact:

Re: publish data under specific MQTT topic

Post 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
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
FlyingDomotic
Posts: 389
Joined: Saturday 27 February 2016 0:30
Target OS: Raspberry Pi / ODroid
Domoticz version: 2020.2
Contact:

Re: publish data under specific MQTT topic

Post 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.
Hencor
Posts: 48
Joined: Sunday 01 September 2019 18:59
Target OS: Raspberry Pi / ODroid
Domoticz version: 2021.1
Location: DE
Contact:

Re: publish data under specific MQTT topic

Post 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:
FlyingDomotic
Posts: 389
Joined: Saturday 27 February 2016 0:30
Target OS: Raspberry Pi / ODroid
Domoticz version: 2020.2
Contact:

Re: publish data under specific MQTT topic

Post 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 ;-)
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest