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.

TCP Socket Connection for Legrand
#21
Thank you very much, now it looks much more hopeful. But is there still a problem?

Reply
#22
Increase socket timeout by changing sock:settimeout(1) to sock:settimeout(5)
Reply
#23
Thank you administrator!

So already in the alarms the connection is ok.

How do I see the messages from the bus in LM? Because at the moment I only have * # * 1 ##, but not what's going on online. My goal is to transfer all lamps and thermostats to LM for easier and more beautiful operation. That is, I need to be able to read and change their condition.

I apologize for the stupid questions, but I'm still new to writing scripts.
Reply
#24
After the connection is open you need to call read and parse the incoming data. For sending commands a separate script might be needed because there are two session types - command (*99*0##) and event (*99*1##). Unfortunately it's quite hard to make a full example without being able to test it on a real device.
Reply
#25
Okay, I get it.

I used the sample TCP code:
Code:
function read(sock)
  local buf = {}

  while true do
    local ch, err = sock:receive(1)

    if ch then
      local pr = buf[ #buf ]

      buf[ #buf + 1 ] = ch

      if ch == '#' and pr == '#' then
        break
      end

    else
      return nil, err
    end
  end

  local ret = table.concat(buf)
  log(ret)
  return ret
end




-- init socket
if not sock then
  require('socket')

  sock, err = socket.connect('192.168.1.247', 20000)

  -- set timeout to 1 second
  if sock then
    sock:settimeout(1)
  -- error opening connection, log error and wait before reconnecting 
  else
    error(err)
    sleep(5)
  end
end

-- socket handler
if sock then   

sock:send('*99*1##')
 
 
 
--data = sock:receive(14)
   res, err = read(sock)
 
 
 
--sock:send('*#1*12##')
-- log('check')
-- sock:send('*1*1*12##')
  -- got data, log it
  if data then
    log(data)
  end
end

 and I'm currently getting this:
* # 4 * 1 * 0 * 0229 ## in log.
Which means that the temperature of thermostat 1 is 22.9 degrees. How to separate the digit with the code 1 to be address 32/1/1 and write the value 22.9 in it? How do I separate receiving and sending commands so that it works properly?
Reply
#26
Hi, I made several attempts to control the MX200 with a script, but unfortunately failed. I have the following commands on the line:

Code:
MH200
26.04.2022 19:53:58    
* string: *1*9*11##    90%
    
    
MH200
26.04.2022 19:54:15    
* string: *1*1000#0*11##    OK
    
    
MH200
26.04.2022 19:54:15    
* string: *1*0*11##    OFF

could you help me to bind them in a script so that I can recognize them on arrival and bind them to the respective objects and accordingly if the value of the object changes I send the command back to the gateway?
This is the code I use to get them in the log:
Code:
function read(sock)
  local buf = {}

  while true do
    local ch, err = sock:receive(1)

    if ch then
      local pr = buf[ #buf ]

      buf[ #buf + 1 ] = ch

      if ch == '#' and pr == '#' then
        break
      end

    else
      return nil, err
    end
  end

  local ret = table.concat(buf)
  log(ret)
  return ret
end




-- init socket
if not sock then
  require('socket')

  sock, err = socket.connect('192.168.1.247', 20000)

  -- set timeout to 1 second
  if sock then
    sock:settimeout(1)
  -- error opening connection, log error and wait before reconnecting 
  else
    error(err)
    sleep(5)
  end
end

-- socket handler
if sock then   

sock:send('*99*1##')

   res, err = read(sock)
 

  if data then
    log(data)
  end
end
Reply
#27
Use this. Changing mapping will require full script restart via disable/enable.
Code:
if not sock then
  mapping = {
    ['11'] = '1/1/11',
  }

  function parselighting(what, where)
    local addr = mapping[ where ]
    what = tonumber(what) or -1

    if addr and 0 <= what and what <= 10 then
      grp.checkwrite(addr, what * 10)
    end
  end

  function parse(msg)
    local who, what, where = unpack(msg:split('*'))
    who = tonumber(who)

    -- lighting
    if who == 1 then
      parselighting(what, where)
    end
  end

  function read(sock)
    local buf = {}

    while true do
      local ch, err = sock:receive(1)

      if ch then
        local pr = buf[ #buf ]

        buf[ #buf + 1 ] = ch

        if ch == '#' and pr == '#' then
          break
        end

      else
        return nil, err
      end
    end

    if #buf > 0 and buf[ 1 ] == '*' then
      return table.concat(buf, '', 2, #buf - 2)
    end
  end

  sock = require('socket').tcp()
  sock:settimeout(1)

  res, err = sock:connect('192.168.1.247', 20000)

  if res then
    sock:send('*99*1##')
  else
    log('connect failed', err)

    sock:close()
    sock = nil
    os.sleep(1)
  end
end

-- socket handler
if sock then    
  res, err = read(sock)

  if res then
    parse(res)
  elseif err == 'closed' then
    sock:close()
    sock = nil
  end
end

This example partially implements parsing of lighting type messages (off and dimming).
Docs for all types: https://developer.legrand.com/documentat...or-myhome/
Reply
#28
Thank you so much!

 It works perfectly, but now how can I send commands to the gateway when changing the object in a logic machine?
Reply


Forum Jump: