LogicMachine Forum
mqtt with logic machine - Printable Version

+- LogicMachine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8)
+--- Thread: mqtt with logic machine (/showthread.php?tid=5400)

Pages: 1 2


RE: mqtt with logic machine - abby - 05.06.2024

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


RE: mqtt with logic machine - admin - 05.06.2024

Post your whole script code listing. It must be a resident script with 0 sleep time.


RE: mqtt with logic machine - abby - 05.06.2024

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



RE: mqtt with logic machine - admin - 05.06.2024

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.


RE: mqtt with logic machine - abby - 05.06.2024

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


RE: mqtt with logic machine - admin - 05.06.2024

You can add new entries to this table.


RE: mqtt with logic machine - abby - 17.06.2024

Thanks sir for your help . it means a lot to me Smile