20.04.2022, 07:06
TCP Socket Connection for Legrand
|
20.04.2022, 07:11
Increase socket timeout by changing sock:settimeout(1) to sock:settimeout(5)
21.04.2022, 06:10
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.
22.04.2022, 10:45
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.
Okay, I get it.
I used the sample TCP code: Code: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 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
endand 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?
14.06.2022, 06:45
Hi, I made several attempts to control the MX200 with a script, but unfortunately failed. I have the following commands on the line:
Code: 12345678910111213 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## OFFcould 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: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 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
15.06.2022, 09:55
Use this. Changing mapping will require full script restart via disable/enable.
Code: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 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
endThis example partially implements parsing of lighting type messages (off and dimming). Docs for all types: https://developer.legrand.com/documentat...or-myhome/
23.06.2022, 05:56
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?
27.06.2022, 12:15
You need a separate socket connection for commands. You also need to send another init sequence: *99*0##.
This example should control light point 11 by converting 0..100% value to 0..10. There's some extra logging to check if the message flow is correct. Remove it when the script is working properly. Code: 1234567891011121314151617181920212223242526 value = event.getvalue()
value = math.ceil(value / 10)
cmd = '*1*' .. value .. '*11##'
sock = require('socket').tcp()
sock:settimeout(1)
res, err = sock:connect('192.168.1.247', 20000)
if res then
sock:send('*99*0##')
res, err = sock:receive(6) -- receive ACK
log('receive 1', res, err)
res, err = sock:send(cmd)
log('send', res, err)
res, err = sock:receive(6) -- receive result ACK/NACK
log('receive 2', res, err)
else
log('connect failed', err)
end
sock:close()
28.06.2022, 07:44
(27.06.2022, 12:15)admin Wrote: You need a separate socket connection for commands. You also need to send another init sequence: *99*0##. Works perfectly! Thank you very much for the help!
Hello Admin,
Would you help me to refactor the code so that it can use all the features of Open web net ? I tried to redo it myself for the temperature, but I'm sure it's not the right way since the string is different there. Code: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 if not sock then
mappingtemp = {
['1'] = '1/1/1',
['2'] = '1/1/2',
}
mapping = {
['3'] = '1/1/3',
['4'] = '1/1/4',
['5'] = '1/1/5',
['6'] = '1/1/6',
['7'] = '1/1/7',
['8'] = '1/1/8',
['9'] = '1/1/9',
['10'] = '1/1/10',
['11'] = '1/1/11',
['12'] = '1/1/12',
['13'] = '1/1/13',
['14'] = '1/1/14',
['15'] = '1/1/15',
['16'] = '1/1/16',
['17'] = '1/1/17',
['22'] = '1/1/22',
['23'] = '1/1/23',
['51'] = '1/1/51',
['0215'] = '1/1/52',
}
function parselighting(what, where)
log("Ok")
local addr = mapping[ where ]
what = tonumber(what) or -1
if addr and 0 <= what and what <= 10 then
grp.checkwrite(addr, what)
end
end
function parsetemperature(where, value)
local addr = mappingtemp[ where ]
log(where)
value = tonumber(value) or -1
if addr and 0 <= value and value <= 4050 then
value = value * 0.1
grp.checkwrite(addr, value)
log("done",value)
end
end
function parse(msg)
log (msg)
length = string.len(msg)
if length == 11 then
log("length",length)
local who, where, dimension, value = unpack(msg:split('*'))
if who == "#4" then
who = string.sub(who,2,2)
who = tonumber(who)
parsetemperature(where, value)
end
end
if length == 6 then
log("length",length)
local who, what, where = unpack(msg:split('*'))
who = tonumber(who)
-- lighting
if who == 1 then
parselighting(what, where)
log(what)
log(where)
end
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.195', 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
log(res)
parse(res)
elseif err == 'closed' then
sock:close()
sock = nil
end
end
31.08.2022, 12:38
Try replacing the parse function with this:
Code: 123456789101112 function parse(msg)
local chunks = msg:split('*')
local who = table.remove(chunks, 1)
if who == '#1' then
local what, where = unpack(chunks)
parselighting(what, where)
elseif who == '#4' then
local where, dimension, value = unpack(chunks)
parsetemperature(where, value)
end
end
01.09.2022, 12:53
Thanks Admin!
With a slight modification it works perfectly. But I have another problem - the system runs fast for about a day and then starts responding after about 10 seconds (turning on the lights with the first code). I try with OpenWebNet_Client from my PC and it works fast. When I changed the IP on the MH200N it worked quickly again for about a day. Restarting LM or anything else makes no difference. The only difference is that through OpenWebNet_Client I log in with a password, and LM is on a password-free IP. Could there be some communication left open that would initiate the delay? Do you have any other idea? I know it's hard when you don't have access to a working installation, but at least if you could give me some pointers on how and where to look for it.
07.10.2022, 06:29
Hi Admin,
I still have no progress on the case. Can you help me refactor the code so that I can log in with a username and password?
07.10.2022, 06:40
Try this code again: https://forum.logicmachine.net/showthrea...2#pid25762
Make sure that the password contains only numbers otherwise the script will fail.
11.10.2022, 08:55
(07.10.2022, 06:40)admin Wrote: Try this code again: https://forum.logicmachine.net/showthrea...2#pid25762 Hello, The code works! It manages to log in, now I have to combine it with the other one so that it can also control the lighting. |
« Next Oldest | Next Newest »
|