Hello Guest it is April 19, 2024, 10:51:04 PM

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - SebDE

Pages: 1
1
Mach4 General Discussion / Re: Mach4 MQTT Client
« on: March 15, 2018, 10:30:42 AM »
 ??? - okay I just find these Plugin for Mach3 - can you give me a direction where I can find this? You're totally right that this way will be much easier ....


2
Mach4 General Discussion / Re: Mach4 MQTT Client
« on: March 15, 2018, 09:53:50 AM »
Thanks for the answer - that are good news. So I will try to implement a Mach4 > MQTT > Arduino > Modbus Bridge to control my VFD via ethernet. Than i have a good practical test case to see if eversthing works fine.

3
Mach4 General Discussion / Mach4 MQTT Client
« on: March 15, 2018, 03:07:07 AM »
Hello,

the last days I spent my time to implement a MQTT Client in Lua to work with Mach4. Actually I can connect to a MQTT Broker, publish Messages via functions und subscribe topics. But I'm not sure if I place all MQTT functions at the right place. I've made the main MQTT Connection in the Screen Load Script with the following code:

Code: [Select]
---------------------------------------------------------------
-- Load modules
....
--MQTT module
package.loaded.MqttModul = nil
mqtt = require "mqtt_library"
....
---------------------------------------------------------------
....
....
function mqttCallback(
  topic,    -- string
  message)  -- string
  mc.mcCntlSetLastError(inst,"Topic: " .. topic .. ", message: '" .. message .. "'")
end

function SendMessage(msg)
    mc.mcCntlSetLastError(inst, msg);
    mqtt_client:publish("mach4",msg)
end

function MQTT_Connect()
    mqtt_client = mqtt.client.create("192.168.0.55", nil, mqttCallback)
    mqtt_client:connect("mach4")
    mqtt_client:publish("mach4", "online")
    mqtt_client:subscribe({"mach4/set"})
end

MQTT_Connect()

To maintain the MQTT Connection and to recieve messages it is important to call a handle function et least every few seconds. So I put this handler in the PLC Script:

Code: [Select]
local inst = mc.mcGetInstance()
local rc = 0;
testcount = testcount + 1
machState, rc = mc.mcCntlGetState(inst);
local inCycle = mc.mcCntlIsInCycle(inst);

mqtt_client:handler()
......

At the moment everything works fine but I have the following question: Is it a Problem that I call the mqtt_client:handler() in the PLC Script? Will I get problems like a delay if the handle function block for a moment? The code for the mqtt_client:handler() is:

Code: [Select]
function MQTT.client:handler()                                    -- Public API
  if (self.connected == false) then
    error("MQTT.client:handler(): Not connected")
  end

  MQTT.Utility.debug("MQTT.client:handler()")

-- Transmit MQTT PING message
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~
-- MQTT 3.1 Specification: Section 3.13: PING request
--
-- bytes 1,2: Fixed message header, see MQTT.client:message_write()

  local activity_timeout = self.last_activity + MQTT.client.KEEP_ALIVE_TIME

  if (MQTT.Utility.get_time() > activity_timeout) then
    MQTT.Utility.debug("MQTT.client:handler(): PINGREQ")

    self:message_write(MQTT.message.TYPE_PINGREQ, nil)
  end

-- Check for available client socket data
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  local ready = MQTT.Utility.socket_ready(self.socket_client)

  if (ready) then
    local error_message, buffer =
      MQTT.Utility.socket_receive(self.socket_client)

    if (error_message ~= nil) then
      self:destroy()
      error_message = "socket_client:receive(): " .. error_message
      MQTT.Utility.debug(error_message)
      return(error_message)
    end

    if (buffer ~= nil and #buffer > 0) then
      local index = 1

      -- Parse individual messages (each must be at least 2 bytes long)
      -- Decode "remaining length" (MQTT v3.1 specification pages 6 and 7)

      while (index < #buffer) do
        local message_type_flags = string.byte(buffer, index)
        local multiplier = 1
        local remaining_length = 0

        repeat
          index = index + 1
          local digit = string.byte(buffer, index)
          remaining_length = remaining_length + ((digit % 128) * multiplier)
          multiplier = multiplier * 128
        until digit < 128                              -- check continuation bit

        local message = string.sub(buffer, index + 1, index + remaining_length)

        if (#message == remaining_length) then
          self:parse_message(message_type_flags, remaining_length, message)
        else
          MQTT.Utility.debug(
            "MQTT.client:handler(): Incorrect remaining length: " ..
            remaining_length .. " ~= message length: " .. #message
          )
        end

        index = index + remaining_length + 1
      end

      -- Check for any left over bytes, i.e. partial message received

      if (index ~= (#buffer + 1)) then
        local error_message =
          "MQTT.client:handler(): Partial message received" ..
          index .. " ~= " .. (#buffer + 1)

        if (MQTT.ERROR_TERMINATE) then         -- TODO: Refactor duplicate code
          self:destroy()
          error(error_message)
        else
          MQTT.Utility.debug(error_message)
        end
      end
    end
  end

  return(nil)
end

The MQTT Client library is from https://github.com/geekscape/mqtt_lua

If someone is interested in the modified code and an installation instruction please let me know.

Thanks for help

Pages: 1