This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

MQTT - automatic sync all data with mqtt
#1
Hi, 

Im trying to create a solution to send every object update (sync all knx data) to mqtt using your code. 

Why the value is not updating ? 

MQTT:

campusdst
   out 
       setpoint = 23
       status = 1 >> value not updated automaticaly, why ? 
   in 
       status = 0 >> actual value (update with success every publish) 

Code:
------------------------------------------------------------
------------------- MQTT SUBSCRIVER  ------------------------
------------------------------------------------------------
if not broker then
  -- MQTT settings:
  broker = '192.168.xxx.xxx'
  port = 1883
  username = "xxxxxxx"
  password = "xxxxxxx"
  -- topic to object map
  mqtt_to_object = {
    ['xxx/in/status'] = '32/1/2',
    ['xxx/in/setpoin'] = '32/1/3',
  }
 
  -- object to topic map
  object_to_mqtt = {
    ['32/1/2'] = 'xxx/out/status',
    ['32/1/3'] = 'xxx/out/setpoint',
  }
  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.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
     
      log("change address: " .. addr .." to value :"..payload)
      grp.write(addr, payload)
    end
  end
  mclient.ON_DISCONNECT = function(...)
    log('mqtt disconnect', ...)
    mclientfd = nil
  end
  function mconnect()
    local fd
   
mclient:login_set(username, password)
   
    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
Reply
#2
Who is the other client? What broker do you use and where it is?
------------------------------
Ctrl+F5
Reply
#3
(26.03.2024, 08:31)Daniel Wrote: Who is the other client? What broker do you use and where it is?

Hi, 
Broker: TBMQ (Thingsboard mqtt)
Client "MQTT EXPLORER"

[Image: test.png]
Reply
#4
On line 70 change this code:
Code:
if event.sender == 'mq' or not mclientfd then

To this:
Code:
if not mclientfd then

This will disable loop protection so be careful not to use the same topic names for both in and out.
Reply
#5
(26.03.2024, 12:01)admin Wrote: On line 70 change this code:
Code:
if event.sender == 'mq' or not mclientfd then

To this:
Code:
if not mclientfd then

This will disable loop protection so be careful not to use the same topic names for both in and out.

Fixed!  Smile

Thanks!
Reply


Forum Jump: