Logic Machine Forum
Local bus and sending to MQtt - Printable Version

+- Logic Machine 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: Local bus and sending to MQtt (/showthread.php?tid=5182)



Local bus and sending to MQtt - benanderson_475 - 03.01.2024

im running the below in script to port all obj wit tag with prefix 'MQ' to mqtt it runs everytime local bus has a message, 
is there a simple way to make it more efficent? is there a better way to do this?  at the moment i have one resident script with a loop which manages local bus and mqtt in one place.

Code:
function localbus_onmessage(event)

event_get_tags = grp.gettags(event.dst)
  -- check if tag has MQ prefix
    for _, tag in ipairs(event_get_tags) do
    tag_is_MQ = tag:match('MQ (.*)')
 
  if tag_is_MQ then
      -- get data type for knx obj
      event_get_obj = grp.find(event.dst)
    --decode data
     tx_payload = busdatatype.decode(event.datahex, event_get_obj.datatype, event.dstraw)
  --  log(event.dst, tx_payload)
 
    if type(tx_payload) == 'boolean' then   
        tx_payload = tx_payload and 1 or 0
     end
      -- extract control type from obj name
      cntrl_typ = string.split(event_get_obj.name, ' ')
     
--log(tx_payload)
   mqtt_send:publish('from_knx_tag/'..  tag_is_MQ, cntrl_typ[1] ..' '.. tx_payload)
     
    break
  end
end       



RE: Local bus and sending to MQtt - admin - 03.01.2024

Calling grp.gettags/grp.find for each value change is very inefficient. You should cache all tagged objects and respective names, datatypes etc when the script starts. The cache is a table where each key is object group address and value is a table with required properties.

Then the callback can be similar to this:
Code:
function localbus_onmessage(event)
  -- find cached object
  local obj = objects[ event.dst ]

  if not obj then
    return
  end

  local value = busdatatype.decode(event.datahex, obj.datatype, event.dstraw)
  
  if type(value) == 'boolean' then    
    value = value and 1 or 0
  end

  mqtt_send:publish('from_knx_tag/'..  obj.topic, obj.prefix ..' '.. value)
end



RE: Local bus and sending to MQtt - benanderson_475 - 03.01.2024

Thanks, this is making sense,  i will run a function when the script starts to cache the objects in a table as described how am i best to achieve this?
my first thoughts,
call group.all() then loop through tagcache and validate the tag with prefix 'MQ' is there, then extract all elements as reqired and insert into cached obj table 
or  maybe i can use  myobjects = grp.tag({'tag name 1', 'tag name 2'}, 'any')  problem is for this one i dont want to list all the avalible tagsas i may have many different ones the only consistant thing in the tag is the 'MQ' prefix

whats the simplist way to recieve all tags with  the 'MQ' prefix or perhaps i should change my naming method to better.

this is wher i am at so far, thoughts?  then i can look up the table with th eabove function.
Code:
local cached_objects = {}

all_obj = grp.all()

for _, obj in pairs(all_obj) do
    local tag_is_MQ

    if obj.tagcache then
        tag_is_MQ = obj.tagcache:match('(MQ%s+[^,]+)')                    
    end
 
    if tag_is_MQ then

      cached_objects[obj.address] = {['address'] =obj.address, ['name'] = obj.name, ['data type'] = obj.datatype, ['tag'] = tag_is_MQ, ['updatetime'] = obj.updatetime}

    end
end

log(cached_objects)



RE: Local bus and sending to MQtt - admin - 03.01.2024

One solution is to use a single common tag for all required objects and then use comment field to store the topic name.


RE: Local bus and sending to MQtt - benanderson_475 - 03.01.2024

(03.01.2024, 10:57)admin Wrote: One solution is to use a single common tag for all required objects and then use comment field to store the topic name.

this sounds eaiser, lets say i use the key word 'MQ' for all obj i want to send to MQTT, how can i filter this and extract the comment field in the local bus function so that only tagged obj with 'MQ' get published etc


RE: Local bus and sending to MQtt - admin - 03.01.2024

Call grp.tag('MQ') and you will get the "comment" field in each object table.


RE: Local bus and sending to MQtt - benanderson_475 - 03.01.2024

Many thanks, have it sorted now with a single common tag