| 
		
	
	
	
		
	Posts: 139 
	Threads: 44 
	Joined: Dec 2017
	
 Reputation: 
4 
	
	
		Hi,  
i want to know if it is possible to create an event loop, like https://forum.logicmachine.net/showthread.php?tid=2670 
to include a tcp connection to have callback function on server:read from tcp port etc 
 
I already have a working tcp script in resident script but i want to make it more economical on cpu etc, 
i am communicating to alarm panel so i want to receive pir triggered events etc 
 
Many Thanks.
	
		
	 
	
	
	
		
	Posts: 8413 
	Threads: 45 
	Joined: Jun 2015
	
 Reputation: 
481 
	
	
		Do you have some extra communication in the script? You won't get any improvements on CPU usage if you're only reading from TCP and updating object values.
	 
		
	 
	
	
	
		
	Posts: 139 
	Threads: 44 
	Joined: Dec 2017
	
 Reputation: 
4 
	
		
		
		22.09.2020, 05:27 
(This post was last modified: 22.09.2020, 20:25 by benanderson_475.)
		
	 
		 (21.09.2020, 07:24)admin Wrote:  Do you have some extra communication in the script? You won't get any improvements on CPU usage if you're only reading from TCP and updating object values. 
What is the best way to achieve what i need?
Below is what i currently have in resident script, i need to log out and log in every 15 min to maintain connectivity, and also have object event script sending to udp server in this script to send the client:write() to alarm to activate outputs, i was thinking as i currently use mqtt with https://forum.logicmachine.net/showthread.php?tid=2670
i can utilize the local bus in the event loop without the need to have an additional event script as well as having the on_timer function in the above link running the login/out function every 900 sec.
is it advisable to use the event loop? Code: --log in--function log_in()
 ip, port = "192.168.1.61", 1918
 
 client = assert(require('socket').tcp())
 client:connect(ip, port);
 client:settimeout(0.5);
 log("Connecting to Alarm at ip:" .. ip .. ' port: '.. tostring(port)..' at '.. os.date("%H:%M:%S"));
 
 -- log("logging Out of alarm")
 client:send(string.char(0x49,0x43,0x08,0x00,0x00,0x00,0x00,0x03))
 -- log("logging In")
 client:send(string.char(0x49,0x43,0x0D,0x00,0x00,0x00,0x00,0x02,0x01,0x02,0x03,0x04,0xFF))
 -- log("Setting alarm timeout")
 client:send(string.char(0x49,0x43,0x0A,0x00,0x00,0x00,0x00,0x04,0x70,0x17))
 --  log("Turning alarm events on")
 client:send(string.char(0x49,0x43,0x0A,0x00,0x00,0x00,0x00,0x06,0x01,0x01))
 end
 
 log_in_time = os.time() + 900
 log_in()
 
 while true do
 
 --re log out/in after 15min --
 if os.time() > log_in_time then
 client:close()
 log_in()
 log_in_time = os.time() + 900
 end
 
 --udp server for recieving commands from event script
 if not server then
 server = require('socket').udp()
 server:settimeout(1)
 server:setsockname('127.0.0.1', 5432)
 log("Udp Server:5432 Recived message")
 end
 
 cmd = server:receive()
 if cmd then
 if cmd == "Gate_Lock" then
 client:send(string.char(0x49,0x43,0x0C,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x0A))
 end
 if cmd == "Gate_UnLock" then
 client:send(string.char(0x49,0x43,0x0C,0x00,0x00,0x00,0x01,0x02,0x01,0x00,0x00,0x00,0x0A))
 end
 end
 
 --recieving data--
 rx = client:receive()
 
 function to_bool(state)
 if state == 'Opened' then
 return true, state
 end
 
 if state == 'Closed' then
 return false, state
 end
 end
 
 
 if rx then
 rx = string.gsub(rx, ".", function(value) return  string.format('%02X', string.byte(value))end)
 msg = string.sub(rx, 19)
 data_type = string.sub(rx, 13,16)
 -- loghex(msg)
 msg = string.gsub(msg, '%x%x', function(value) return string.char(tonumber(value, 16)) end)
 log(msg)
 t =  string.split(msg, ' ')
 
 -- Zone name is always in t[2]
 if t[2] == 'Zone_1' then
 -- Zone state is always in t[4]
 state = to_bool(t[4])
 grp.write('1/1/1', state)
 end
 
 end
 end
 
		
	 
	
	
	
		
	Posts: 139 
	Threads: 44 
	Joined: Dec 2017
	
 Reputation: 
4 
	
	
		@admin any suggestion as above, what do you recommend?Many Thanks
 
		
	 
	
	
	
		
	Posts: 8413 
	Threads: 45 
	Joined: Jun 2015
	
 Reputation: 
481 
	
	
		You can use selectfds to check if there's data in udp/tcp socket or when tcp socket is closed. Code: --log in--function log_in()
 local ip, port = "192.168.1.61", 1918
 
 client = assert(require('socket').tcp())
 client:connect(ip, port)
 client:settimeout(0.5)
 log("Connecting to Alarm at ip:" .. ip .. ' port: '.. tostring(port)..' at '.. os.date("%H:%M:%S"))
 
 -- log("logging Out of alarm")
 client:send(string.char(0x49,0x43,0x08,0x00,0x00,0x00,0x00,0x03))
 -- log("logging In")
 client:send(string.char(0x49,0x43,0x0D,0x00,0x00,0x00,0x00,0x02,0x01,0x02,0x03,0x04,0xFF))
 -- log("Setting alarm timeout")
 client:send(string.char(0x49,0x43,0x0A,0x00,0x00,0x00,0x00,0x04,0x70,0x17))
 --  log("Turning alarm events on")
 client:send(string.char(0x49,0x43,0x0A,0x00,0x00,0x00,0x00,0x06,0x01,0x01))
 end
 
 log_in_time = os.time() + 900
 log_in()
 
 --udp server for recieving commands from event script
 if not server then
 server = require('socket').udp()
 server:setsockname('127.0.0.1', 5432)
 end
 
 sfd = socket.fdmaskset(server:getfd(), 'r')
 cfd = socket.fdmaskset(client:getfd(), 'r')
 
 while true do
 res, sstat, cstat = socket.selectfds(10, sfd, cfd)
 
 if res then
 if sstat then
 cmd = server:receive()
 if cmd then
 log("udp server message", cmd)
 end
 end
 
 if cstat then
 rx, err = client:receive()
 
 if rx then
 log("tcp client message", rx)
 else
 log_in_time = 0
 log("tcp client error", err)
 end
 end
 end
 
 if os.time() > log_in_time then
 client:close()
 log_in()
 log_in_time = os.time() + 900
 end
 end
		
	 
	
	
	
		
	Posts: 139 
	Threads: 44 
	Joined: Dec 2017
	
 Reputation: 
4 
	
	
		Thanks for this, this is what i am after although after a short amount of time it stops reading, i don't get any error in the log, so i insert  
log( _, sstat, cstat)  after _, sstat, cstat = socket.selectfds(10, sfd, cfd) 
 
when arg 1 is nill, after this i don't receive any command from the client:receive() until i stop and start the script etc 
see attached log screenshot
  
		
	 
	
	
	
		
	Posts: 8413 
	Threads: 45 
	Joined: Jun 2015
	
 Reputation: 
481 
	
	
		I've modified the example to check select result before checking if any fds are ready.
	 
		
	 
	
	
	
		
	Posts: 139 
	Threads: 44 
	Joined: Dec 2017
	
 Reputation: 
4 
	
	
		All is well now, Thanks admin
	 
		
	 |