![]() |
Data buffering - Printable Version +- Logic Machine 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: Data buffering (/showthread.php?tid=399) |
Data buffering - buuuudzik - 22.09.2016 Hello, maybe you know how do the data buffering in Lua and the LM. Maybe you have better solution than my. Task is: I must send a commands 1 after 1(not all in the same time) because device which accepts this commands is slow and there is no feedback. E.g. 1. Pushbutton "Blind up" -> 2. GA script -> 3. Command(RS-485) -> 4. Command(Somfy RTS) Command in Somfy RTS is very slow, normally 0,7s. So if someone want change slat angle this can produce 3 or more commands in 1 second. I want prepare the buffer for this commands because if I won't prepare the buffer a lot of commands will be not executed. This is what I've prepared at this moment: GA script (pushbutton up/down), it sends command to the buffer: Code: value = event.getvalue() This is Somfy.buffer function (reads the buffer from the table 'bufor' from the storage, sends command and delete this command): Code: buffer = function(command) I have also Resident script for sending commands over RS485. Perfectly would be if I could sending the commands with 0.7s break between the commands. But at this moment I can't. I've tried with Resident with time=0s but there was a big CPU usage or strange operation(sometimes it sends the commands from the buffer, sometimes not). At this moment it works but with Resident with time=1s and this code(and unfortunately this is not 100% reliable because when I send 10 commands this mechanism send only 7 or 8): Code: main = function() And this is the Somfy.send function which I use for sending commands via RS485: Code: send = function (command) I must improve this solution, because I want have reliable(100%) solution and I want prepare faster solution (at this moment this is 1 command per second, and it will be good if this would be e.g. 0,7s). Maybe you can give me some advice how improve this solution? Especially what are the principles of the resident script with time = 0s. Is this script is executed parallel with the other scripts or serial? In my script I am using storage for saving the buffer. Buffer is updated in this way: - read from the storage, add new command to the buffer, save to storage(with event script), - read from the storage, delete executed command, save to storage(with resident script 1s). I think that in this solution there is a possibility that in a resident script I open the buffer table(from storage) and before saving by the resident script the table is changed by the event script but after this resident script save its calculated value and maybe this is the problem. Maybe do you have some better mechanism for such bufferring commands or some advice how improve this scripts? Thanks for all help ![]() I've checked more precisely that the minimum break time between 2 commands can be 0.42 so theoretically in 1 second I could send 2 commands. This would be very comfortable for user. RE: Data buffering - admin - 22.09.2016 Your script is not 100% working because there's race condition while accessing storage items. The easiest approach is to use UDP client (event scripts) and server (resident) - this way you don't have to waste CPU power polling and OS will do the buffering for you while your script is sending data to RS-485. I'll prepare a short example later. RE: Data buffering - admin - 23.09.2016 Resident script with sleep time 0, which send whatever data comes from clients and waits for 0.5 sec after each send. Code: if not server then Functiont to send data from event scripts. Code: function send(cmd) RE: Data buffering - buuuudzik - 23.09.2016 Perfect solution ![]() ![]() Thanks admin RE: Data buffering - buuuudzik - 30.09.2016 Unfortunately there is a problem with this solution because probably via this Resident script whole ethernet is blocked still. When I switch on this script I can't use other functions of sending data e.g. sending data via TCP. When this UDP script is switched on and I try to send something via TCP I have always information "connection refused". I tried a few things and it seems that when I try prepare some other TCP connection via resident script it is not working but when I try send some data via TCP in the event script there is no collision. RE: Data buffering - admin - 30.09.2016 Connection refused means that other socket end does not accept the connection. Single local UDP socket should not block anything, check your other scripts. If you are using send() in resident script, you can change the code to close the socket after each send (this is done automatically when script ends, so it will work properly for event scripts with older code). Otherwise it might lead to "No file descriptors available" error when too many sockets are open (>1024). Code: function send(cmd) RE: Data buffering - buuuudzik - 30.09.2016 I checked this and the problem is not in UDP client-server. It works great but when I try send the command via TCP my connection is refused. I try to send cmd to the RS485 server. This is the script: Code: if not server then This is the network configuration of the serial server. RE: Data buffering - admin - 30.09.2016 Try adding client:close() after client:send(cmd). But it all depends on how TCP server is created, it might still refuse connections for some time even when close is called. You might want to have and always-open TCP connection and do reconnect if send fails because remote TCP server might disconnect clients on timeout. This is all in theory and should be tested :) If close does not solve this issue I'll provide an example with automatic retry. RE: Data buffering - buuuudzik - 30.09.2016 Unfortunately it not help. The problem is 1-step before. I've checked and when I take the log from: Code: log(client:connect(host, port)) the result from Logs is Code: * arg: 1 RE: Data buffering - admin - 30.09.2016 Try rebooting that serial device and setting Inactivity time to 1. RE: Data buffering - buuuudzik - 30.09.2016 (30.09.2016, 12:12)admin Wrote: Try rebooting that serial device and setting Inactivity time to 1. Unfortunately it not working ![]() |