![]() |
|
TCP/ip connect and maintain connection - 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: TCP/ip connect and maintain connection (/showthread.php?tid=5040) |
TCP/ip connect and maintain connection - Azar - 19.10.2023 I am trying to place a resident script to connect to an ip address, monitor connection and reconnect if connection is lost. I am reading and watching every tutorial i can find and am slowly getting more understanding but need others help with this. I am after some guidance in the implementation of a TCP/ip connection to third party device (Symetrix DSP, control protocol same as control4, amx, crestron, lutron). I have connection working between both the SHAC and the Symetrix DSP, as in I can ping it with a response through the "Network Utilities" I have full control of Symetrix working through PuTTY terminal and now need to implement scripting to send, and manage received data. Can anyone share with me scripting that will build this connection, maintain this connection, reconnect if device goes offline then returns online.. I have found multiple examples of this but am not getting much luck with connection or how to monitor if the connection is alive. Code: local socket = require("socket")
local host, port = "192.168.1.246", 48631
local tcp = assert(socket.tcp())Once i have this connection up and running I need to build scripting to send controls to and receive pushed controls back to update GA's in the SHAC. Control protocol info from Symetrix document shown below. The Control Protocol is a text-based (ASCII string) protocol. Commands are sent with simple character strings with terms separated by spaces and completed with a carriage return character <CR> (ASCII code decimal 13). The general form for commands is: <COMMAND> <PARAMETER1> <PARAMETER2> … <CR> When in PuTTY if i send the command CS 1 65535 <CR> I get Controller Set "CS" to controller number "1" set to maximum "65535" (all as expected) with a response of ACK. Can I send this same data through a LUA script? or does it need to be converted to another format? RE: TCP/ip connect and maintain connection - admin - 19.10.2023 Use this resident script (sleep time = 0) as a starting point: Code: -- socket connected
if connected then
-- send command
sock:send('CS 1 65535\r')
-- read until one line received or error occured
while true do
char, err = sock:receive(1)
-- error while receiving, timeout or closed socket
if err then
-- remote server closed connection, reconnect
if err == 'closed' then
connected = false
alert('[tcp-sock] connection closed')
os.sleep(1)
end
break
-- end of line, parse buffer
elseif char == '\r' then
data = table.concat(buffer)
log(data)
buffer = {}
-- wait some time before next request
os.sleep(1)
break
-- other char, add to buffer
else
buffer[ #buffer + 1 ] = char
end
end
-- first call or previously disconnected
else
-- close previous connection when disconnected
if sock then
sock:close()
sock = nil
end
-- create tcp socket
sock = require('socket').tcp()
sock:settimeout(1)
connected, err = sock:connect('192.168.0.9', 80)
-- connect ok, reset buffer
if connected then
alert('[tcp-sock] connection ok')
buffer = {}
-- error while connecting
else
alert('[tcp-sock] connection failed: %s', err)
os.sleep(5)
end
endRE: TCP/ip connect and maintain connection - Azar - 21.10.2023 Thank you so much, now i know that this will be achievable and I can manage everything from my SHAC. next question can i place a variable parameter into a sock end??as in value = GetCBusLevel(0, 127, 10) --0-255 value * (65535/255) value * 257 example -- send command sock end('CS 34 value*257 \r')this is not working, how would i go about implementing this variable number into the "socket send" RE: TCP/ip connect and maintain connection - Erwin van der Zwart - 21.10.2023 Like this: Code: value = GetCBusLevel(0, 127, 10)
command = 'CS 34 ' .. (value * 257) .. '\r'
sock:send(command)RE: TCP/ip connect and maintain connection - Azar - 21.10.2023 (21.10.2023, 10:56)Erwin van der Zwart Wrote: Like this: I'm getting a error Lua syntax error at line 9: unexpected symbol near '\' How do I get "value x 257" into "command" so that it can be sent RE: TCP/ip connect and maintain connection - CristianAgata - 22.10.2023 (21.10.2023, 22:16)Azar Wrote:Hi,(21.10.2023, 10:56)Erwin van der Zwart Wrote: Like this: There is an error in the char ` use '. Best regards Cristian RE: TCP/ip connect and maintain connection - Azar - 22.10.2023 (22.10.2023, 10:21)CristianAgata Wrote:(21.10.2023, 22:16)Azar Wrote:Hi,(21.10.2023, 10:56)Erwin van der Zwart Wrote: Like this: Hi Cristian, would you kindly explain in more detail? I'm not sure what you mean! Are you pointing to the end of the second line ? Just prior to the backslash? RE: TCP/ip connect and maintain connection - CristianAgata - 22.10.2023 (22.10.2023, 11:45)Azar Wrote:In your code if I m looking good before the /r' there's this char "`" and it is wrong. You must change with this " ' ".(22.10.2023, 10:21)CristianAgata Wrote:(21.10.2023, 22:16)Azar Wrote:Hi,(21.10.2023, 10:56)Erwin van der Zwart Wrote: Like this: Best regards Cristian RE: TCP/ip connect and maintain connection - Erwin van der Zwart - 22.10.2023 Oeps.. responding with iOS on iPhone does that but indeed ‘ must be ' Corrected it in my original post RE: TCP/ip connect and maintain connection - Azar - 28.10.2023 Code: -- socket connected
if connected then
-- Get level of the Volume control group in the Symetrix Control 127 application on the local network
value = GetCBusLevel(0, 127, 10)
-- Convert level to command
--command = 'cs 34' ..(value*257).. cr
command = 'CS 34 '..(value * 257).. '\r'
-- send command
sock:send (command)
-- read until one line received or error occured
while true do
char, err = sock:receive(1)
-- error while receiving, timeout or closed socket
if err then
-- remote server closed connection, reconnect
if err == 'closed' then
connected = false
alert('[tcp-sock] connection closed')
os.sleep(1)
end
break
-- end of line, parse buffer
elseif char == '\r' then
data = table.concat(buffer)
log(data)
buffer = {}
-- wait some time before next request
os.sleep(1)
break
-- other char, add to buffer
else
buffer[ #buffer + 1 ] = char
end
end
-- first call or previously disconnected
else
-- close previous connection when disconnected
if sock then
sock:close()
sock = nil
end
-- create tcp socket
sock = require('socket').tcp()
sock:settimeout(1)
connected, err = sock:connect('192.168.1.246', 48631)
-- connect ok, reset buffer
if connected then
alert('[tcp-sock] connection ok')
buffer = {}
-- error while connecting
else
alert('[tcp-sock] connection failed: %s', err)
os.sleep(5)
end
endThis script continues to send command at every 1 second interval is there any way i can change this so that it only sends socket command apon a new change of cbus level value. similar to an event script that waits for an event before acting? RE: TCP/ip connect and maintain connection - Erwin van der Zwart - 28.10.2023 Just add a if condition like this: Code: if previousvalue ~= value then
-- send command
sock:send (command)
previousvalue == value
endRE: TCP/ip connect and maintain connection - Azar - 28.10.2023 (28.10.2023, 08:25)Erwin van der Zwart Wrote: Just add a if condition like this:I've decided to go to an event script but cant get this to work. Event script by Keyword: Symetrix. all GA's with keyword "Symetrix" also have there control comand number assigned to them by keyword " SYM=### " I'm trying to get the script to insert the control number into the "CS" Command Send line . I'm getting a log of * string: Error: sym=address tag missing Code: local value = event.getvalue()
local dest = event.dst
local grps = GetCBusByKW('Symtrix', 'or')
local k, v, alias, net, app, group
local addr = ''
local buffer = {}
log(grps)
for k, v in pairs(grps) do
alias = table.concat(v.address, '/')
if alias == dest then
local tags = v.keywords
--log(tags)
local t
for _, t in ipairs(tags) do
local tp = string.split(t, '=')
tp[1] = trim(tp[1])
if tp[2] then
tp[2] = trim(tp[2])
if tp[1] == 'sym' then
addr = tp[2] -- Get device address
break
end
end
end
break
end
end
if addr ~= '' then
-- create tcp socket
local sock = require('socket').tcp()
sock:settimeout(1)
local connected, err = sock:connect('192.168.1.246', 48631)
-- connect ok
if connected then
alert('[tcp-sock] connection ok')
-- error while connecting
else
log('[tcp-sock] connection failed: '..err)
sock:close()
do return end
end
local command = 'CS '..addr..' '..(value * 257).. '\r'
-- send command
sock:send (command)
local sent = socket.gettime()
local timeout = 5
while true do
char, err = sock:receive(1)
-- error while receiving, timeout or closed socket
if err then
-- remote server closed connection
log('[tcp-sock] connection closed'..err)
break
-- end of line, parse buffer
elseif char == '\r' then
local data = table.concat(buffer)
log(data)
break
-- other char, add to buffer
else
buffer[ #buffer + 1 ] = char
end
if socket.gettime() - sent > 5 then
log('Timeout receiving data')
break
end
end
sock:close()
else
log('Error: sym=address tag missing')
end
RE: TCP/ip connect and maintain connection - admin - 30.10.2023 Try using this: Code: tags = grp.gettags(event.dst)
for _, tag in ipairs(tags) do
addr = tag:match('SYM=(%d+)')
if addr then
break
end
end
log(addr)
if addr then
-- send TCP message
endNote that tags are case-sensitive. |