Posts: 87
Threads: 29
Joined: Feb 2022
Reputation:
0
Hi !
I appreciate if you could give me any idea because I cannnot come up with a good one.
I use LM RS485 port to communicate with the slave and the following is what I do:
- [event script] send the request to the slave to open/close the water valve
- [event script] send the request to the slave to open/close the drain valve
- [resident script] send a read request to the slave to get the slave's current status every 1 minute
The complicated thing is that I need to leave 0.5sec in between each every command.
Is there a way to wait 0.5 sec between each event script and the resident script?
Thank you for your help in advance!
Posts: 4572
Threads: 23
Joined: Aug 2017
Reputation:
206
Everything should work in single resident script. You can have only one open connection at the time.
------------------------------
Ctrl+F5
Posts: 87
Threads: 29
Joined: Feb 2022
Reputation:
0
Thank you Daniel!
I am wondering how to open/close whenever I want in a single resident script... does that mean I call a resident script from a event script ?
(In my case, the group address 14/2/0 is for opening/closing the water valve, 14/2/1 for opening/closing the drain valve)
Posts: 4572
Threads: 23
Joined: Aug 2017
Reputation:
206
You can set this script to run with 0 interval only make sure everything is on change of values. No need for event script.
------------------------------
Ctrl+F5
Posts: 87
Threads: 29
Joined: Feb 2022
Reputation:
0
Oh I get it !
So I create a resident script with 0 interval and listen to the group address event for 14/2/0 , 14/2/1
I will try this way, thank you Daniel (: !
Posts: 87
Threads: 29
Joined: Feb 2022
Reputation:
0
03.12.2022, 10:57
(This post was last modified: 03.12.2022, 10:58 by Hadeel.)
Dear Daniel
I tried this in a resident script with 0 interval like this but it seems this script does not get executed every second...
When I remove the last line "res, err = port:read(17)" it gets executed every second.
Could you tell me if I am doing anything wrong?
Code: if not port then
require('serial')
port = serial.open('/dev/RS485-1', {
baudrate = 19200,
databits = 8,
stopbits = 1,
parity = 'none',
duplex = 'half'
})
end
log('executed')
if storage.get('coldBathAutoStartCommand') ~= nil then
port:write(storage.get('coldBathAutoStartCommand'))
os.sleep(1)
port:write(':RR\r\n')
storage.set('coldBathAutoStartCommand', nil)
end
port:flush()
res, err = port:read(17)
Posts: 7720
Threads: 42
Joined: Jun 2015
Reputation:
446
port:read(17) is a blocking read. It won't return until 17 bytes are read.
For one-way communication you can use UDP for data transport between scripts:
Code: if not server then
require('socket')
server = socket.udp()
server:setsockname('127.0.0.1', 5485)
server:settimeout(60)
end
if not port then
require('serial')
port = serial.open('/dev/RS485-1', {
baudrate = 19200,
databits = 8,
stopbits = 1,
parity = 'none',
duplex = 'half'
})
end
data = server:receive()
if data then
port:write(data)
os.sleep(1)
port:write(':RR\r\n')
end
Send commands like this:
Code: data = '123456'
sock = require('socket').udp()
sock:sendto(data, '127.0.0.1', 5485)
sock:close()
Posts: 87
Threads: 29
Joined: Feb 2022
Reputation:
0
05.12.2022, 18:58
(This post was last modified: 05.12.2022, 18:58 by Hadeel.)
Thank you Admin!
So I write sock : sendto(data, '127.0.0.1', 5485) in the event script and receive them in resident script.
port:write(':RR\r\n') is a command to request the slave to give LM the status so it is not one-way communication....can I include "port:read(17)" in the same resident script?
Posts: 7720
Threads: 42
Joined: Jun 2015
Reputation:
446
Then you will need something like this. It will request the status after each write or socket read timeout so it can happen faster than once every 60 seconds. But I don't think that it will be an issue.
Code: if not server then
require('socket')
server = socket.udp()
server:setsockname('127.0.0.1', 5485)
server:settimeout(60)
end
if not port then
require('serial')
port = serial.open('/dev/RS485-1', {
baudrate = 19200,
databits = 8,
stopbits = 1,
parity = 'none',
duplex = 'half'
})
end
data = server:receive()
if data then
port:write(data)
os.sleep(0.5)
end
port:write(':RR\r\n')
data = port:read(17, 1) -- read 17 bytes for up to 1 second
if data and #data == 17 then
-- parse data response here
end
Posts: 87
Threads: 29
Joined: Feb 2022
Reputation:
0
Dear admin
I really appreciate your solution !
This looks so beautiful
I will try this in the site
Posts: 87
Threads: 29
Joined: Feb 2022
Reputation:
0
23.03.2023, 02:31
(This post was last modified: 23.03.2023, 03:12 by Hadeel.)
Dear admin,
I am running the code in the site, and I want to add 2 features....could you tell me how I do these?
1. Is there a way to execute port:write(':RR\r\n') every 60 sec even if port:read(17) does not return anything? As you said before, port:read(17) is blocking the script. If there's no response from the slave, the script is not going to be executed anymore
2. I want to alart the system admin if there's no response from the slave(port:read(17)) for 5 min....can I do that in this script?
Code: if not server then
require('socket')
server = socket.udp()
server:setsockname('127.0.0.1', 5485)
server:settimeout(60)
end
if not port then
require('serial')
port = serial.open('/dev/RS485-1', {
baudrate = 19200,
databits = 8,
stopbits = 1,
parity = 'none',
duplex = 'half'
})
end
data = server:receive()
if data then
port:write(data)
os.sleep(0.5)
end
port:flush()
port:write(':RR\r\n')
data, err = port:read(17, 1) -- read 17 bytes for up to 1 second
if data and #data == 17 then
-- parse data response here
end
Posts: 7720
Threads: 42
Joined: Jun 2015
Reputation:
446
Do you have a description of the protocol? Is the response fixed to 17 chars or can it be different? Apart from the status request does the device send something back when a command is written to it?
Posts: 87
Threads: 29
Joined: Feb 2022
Reputation:
0
23.03.2023, 07:48
(This post was last modified: 23.03.2023, 07:50 by Hadeel.)
Dear admin,
Thank you for your response!
It's a special protocol that we(the bath system builder and we) made to meet the control requirement for this project.
Response lengh is fixed to 17 ASCII chars for sure, and apart from the status request the device does not send anything back to LM.
Posts: 7720
Threads: 42
Joined: Jun 2015
Reputation:
446
Ok then the script is already more or less correct. Use this to add an alert if 5 timeouts in a row happen.
Code: if not server then
require('socket')
server = socket.udp()
server:setsockname('127.0.0.1', 5485)
server:settimeout(60)
end
if not port then
require('serial')
port = serial.open('/dev/RS485-1', {
baudrate = 19200,
databits = 8,
stopbits = 1,
parity = 'none',
duplex = 'half'
})
timeouts = 0
end
data = server:receive()
if data then
port:write(data)
os.sleep(0.5)
end
port:flush()
port:write(':RR\r\n')
data, err = port:read(17, 1) -- read 17 bytes for up to 1 second
if data and #data == 17 then
timeouts = 0
-- parse data response here
else
timeouts = timeouts + 1
if timeouts == 5 then
-- send alert
end
end
Posts: 87
Threads: 29
Joined: Feb 2022
Reputation:
0
28.03.2023, 08:35
(This post was last modified: 28.03.2023, 08:39 by Hadeel.)
Dear admin,
Thank you for providing the code, it's working on the site!
However there was one problem we could not solve on the site.
Even though this script intend to wait at least for 0.5 sec between each command,
when the bath system builder checked their command reception log on the slave side,
it seems that sometimes LM sends commmand with 0 sec in between (between the actual command port:write(data) and the status read port:write(':RR\r\n')).
It does not happen every time, it happened just 3 times in a day.
I just changed the timeout to 20 from 1 but everything else is same with your last script.
Code: data, err = port:read(17, 20) -- read 17 bytes for up to 20 second
Could you think of any reason why this happen ?
Thank you !
Posts: 7720
Threads: 42
Joined: Jun 2015
Reputation:
446
Try increasing the sleep time after writing a command from 0.5 seconds to a larger value. You can also add a short sleep after a successful status read.
Posts: 87
Threads: 29
Joined: Feb 2022
Reputation:
0
Thank you admin! We will try both of your suggestion
|