Posts: 53
Threads: 9
Joined: Oct 2023
Reputation:
0
05.06.2024, 12:41
(This post was last modified: 05.06.2024, 12:43 by abby .)
I have done it sir it worked but the data is coming when i trigger from the group address it is directly not coming from the device
Attached Files
Thumbnail(s)
Posts: 7773
Threads: 42
Joined: Jun 2015
Reputation:
447
Post your whole script code listing. It must be a resident script with 0 sleep time.
Posts: 53
Threads: 9
Joined: Oct 2023
Reputation:
0
Code:
if not broker then
broker = 'mqtt.intingy.com'
function multiply(mult)
return function(value)
local num = tonumber(value)
if num then
return num * mult
else
return value
end
end
end
-- topic to object map
mqtt_to_object = {
['people'] = '32/1/1',
['temp'] = '32/1/2',
['co2'] = '32/1/3',
['multi-sensor'] = '32/1/4',
['entelechy'] = '32/1/5'
}
-- optional topic value conversion function
mqtt_to_object_conv = {
['in/topic1'] = multiply(100),
['in/topic2'] = multiply(0.01),
}
-- object to topic map
object_to_mqtt = {
['1/1/1'] = 'out/topic1',
['1/1/2'] = 'out/topic2',
}
datatypes = {}
grp.sender = 'mq'
require('socket')
for addr, _ in pairs(object_to_mqtt) do
local obj = grp.find(addr)
if obj then
datatypes[ addr ] = obj.datatype
end
end
mclient = require('mosquitto').new()
mclient:login_set('entelechy_client', 'nNu6Unh0E/4')
mclient.ON_CONNECT = function(res, ...)
log('mqtt connect status', res, ...)
if res then
for topic, _ in pairs(mqtt_to_object) do
mclient:subscribe(topic)
end
else
mclient:disconnect()
end
end
mclient.ON_MESSAGE = function(mid, topic, payload)
local addr = mqtt_to_object[ topic ]
if addr then
local fn = mqtt_to_object_conv[ topic ]
if fn then
payload = fn(payload)
end
grp.write(addr, payload)
end
end
mclient.ON_DISCONNECT = function(...)
log('mqtt disconnect', ...)
mclientfd = nil
end
function mconnect()
local fd
mclient:connect(broker)
fd = mclient:socket()
-- fd ref is valid
if fd then
mclientfd = fd
end
end
mconnect()
function publishvalue(event)
-- message from us or client is not connected
if event.sender == 'mq' or not mclientfd then
return
end
local addr = event.dst
local dpt = datatypes[ addr ]
local topic = object_to_mqtt[ addr ]
-- unknown object
if not dpt or not topic then
return
end
local value = busdatatype.decode(event.datahex, dpt)
if value ~= nil then
if type(value) == 'boolean' then
value = value and 1 or 0
end
mclient:publish(topic, tostring(value))
end
end
lbclient = require('localbus').new(1)
lbclient:sethandler('groupwrite', publishvalue)
lbclientfd = socket.fdmaskset(lbclient:getfd(), 'r')
-- run timer every 5 seconds
timer = require('timerfd').new(5)
timerfd = socket.fdmaskset(timer:getfd(), 'r')
end
-- mqtt connected
if mclientfd then
mclientfdset = socket.fdmaskset(mclientfd, mclient:want_write() and 'rw' or 'r')
res, lbclientstat, timerstat, mclientstat =
socket.selectfds(10, lbclientfd, timerfd, mclientfdset)
-- mqtt not connected
else
res, lbclientstat, timerstat =
socket.selectfds(10, lbclientfd, timerfd)
end
if mclientfd and mclientstat then
if socket.fdmaskread(mclientstat) then
mclient:loop_read()
end
if socket.fdmaskwrite(mclientstat) then
mclient:loop_write()
end
end
if lbclientstat then
lbclient:step()
end
if timerstat then
-- clear armed timer
timer:read()
if mclientfd then
mclient:loop_misc()
else
mconnect()
end
end
Posts: 7773
Threads: 42
Joined: Jun 2015
Reputation:
447
Your topic names are incorrect. On top of that the data is published in JSON so you cannot write it directly to objects. Here's a working example for the multisensor topic:
Code:
if not broker then
json = require('json')
broker = 'mqtt.intingy.com'
mqtt_to_local = {
['entelechy/multisensor/UNKNOWN-ROOM/E5001000143C'] = function(payload)
local data = json.pdecode(payload)
if type(data) == 'table' then
grp.checkupdate('32/1/2', data['Temperature'])
grp.checkupdate('32/1/3', data['Relative Humidity'])
grp.checkupdate('32/1/4', data['Illumination'])
end
end,
}
-- object to topic map
object_to_mqtt = {}
datatypes = {}
grp.sender = 'mq'
require('socket')
for addr, _ in pairs(object_to_mqtt) do
local obj = grp.find(addr)
if obj then
datatypes[ addr ] = obj.datatype
end
end
mclient = require('mosquitto').new()
mclient:login_set('entelechy_client', 'nNu6Unh0E/4')
mclient.ON_CONNECT = function(res, ...)
log('mqtt connect status', res, ...)
if res then
for topic, _ in pairs(mqtt_to_local) do
mclient:subscribe(topic)
end
else
mclient:disconnect()
end
end
mclient.ON_MESSAGE = function(mid, topic, payload)
local fn = mqtt_to_local[ topic ]
if fn then
fn(payload)
end
end
mclient.ON_DISCONNECT = function(...)
log('mqtt disconnect', ...)
mclientfd = nil
end
function mconnect()
local fd
mclient:connect(broker)
fd = mclient:socket()
-- fd ref is valid
if fd then
mclientfd = fd
end
end
mconnect()
function publishvalue(event)
-- message from us or client is not connected
if event.sender == 'mq' or not mclientfd then
return
end
local addr = event.dst
local dpt = datatypes[ addr ]
local topic = object_to_mqtt[ addr ]
-- unknown object
if not dpt or not topic then
return
end
local value = busdatatype.decode(event.datahex, dpt)
if value ~= nil then
if type(value) == 'boolean' then
value = value and 1 or 0
end
mclient:publish(topic, tostring(value))
end
end
lbclient = require('localbus').new(1)
lbclient:sethandler('groupwrite', publishvalue)
lbclientfd = socket.fdmaskset(lbclient:getfd(), 'r')
-- run timer every 5 seconds
timer = require('timerfd').new(5)
timerfd = socket.fdmaskset(timer:getfd(), 'r')
end
-- mqtt connected
if mclientfd then
mclientfdset = socket.fdmaskset(mclientfd, mclient:want_write() and 'rw' or 'r')
res, lbclientstat, timerstat, mclientstat =
socket.selectfds(10, lbclientfd, timerfd, mclientfdset)
-- mqtt not connected
else
res, lbclientstat, timerstat =
socket.selectfds(10, lbclientfd, timerfd)
end
if mclientfd and mclientstat then
if socket.fdmaskread(mclientstat) then
mclient:loop_read()
end
if socket.fdmaskwrite(mclientstat) then
mclient:loop_write()
end
end
if lbclientstat then
lbclient:step()
end
if timerstat then
-- clear armed timer
timer:read()
if mclientfd then
mclient:loop_misc()
else
mconnect()
end
end
More topic payload conversion functions can be added to the
mqtt_to_local table as needed.
Posts: 53
Threads: 9
Joined: Oct 2023
Reputation:
0
thank you Sir for your support it is working i have one question but for another sensor data i can edit the mqtt_to_local or i have to have to make another resident script
Posts: 7773
Threads: 42
Joined: Jun 2015
Reputation:
447
You can add new entries to this table.
Posts: 53
Threads: 9
Joined: Oct 2023
Reputation:
0
Thanks sir for your help . it means a lot to me