Jump to content
  • Sky
  • Blueberry
  • Slate
  • Blackcurrant
  • Watermelon
  • Strawberry
  • Orange
  • Banana
  • Apple
  • Emerald
  • Chocolate
  • Charcoal
  • 0
meigrafd

Verify modem_message arrive

Question

Is there a way to verify that a modem_message was received?

As i know a send() doesnt means that the message will 100% arrive - even like UDP.

I want to send Commands over Wireless Network but need to be sure that it really arrive and if not to repeat sending it... like a command-queue or so..

An example code whould be helpful ;)

Thanks!

Link to post
Share on other sites

6 answers to this question

Recommended Posts

  • 0

If you store the sender of the message into a variable when the message is received, you can write a method to send a small message back in reply, that triggers right before you evaluate the message on the receiver side. The sender then takes note of whether it got that reply message or not, and if no reply comes after, say, 5 seconds, then keep looping to send the message over and over again, until it gets a confirmation reply, upon which it exits the loop and continues doing what it was going to do. You could even make it make a sound when it gets a reply back with computer.beep().

 

As for example code, I’ll write some pseudocode, just to give you an idea.

--In the sender:
replied = false

while not replied do
    modem.send(<destination>,<port>,"Message")
    _,_,_,_,message = event.pull(5,"modem")
    if message ~= nil then --if the message contains something, thus was a successful reply
       replied = true
    end
end

--in the receiver:

_,sender,_,_,message = event.pull("modem")
modem.send(sender,<port>,"Got it!") --send confirm reply
--evaluate message and all that jazz

  That should be what you need to do. Let me know if you need any more help.

Link to post
Share on other sites
  • 0

Hm. The Problem is that i want to send Commands which the 'receiver' execute. It would be bad if the 'receiver' execute that Command more than one time only coz the 'sender' didnt know that his command got arrived...

As example:

I have a Computer with touch-screen. Now i click on a "OFF" button to tell Robot#1 to turn reactor off. The problem now is that this command not always arrives and i need to click it again...

My idea now was to code something like a queue - a table with 'destinationAddress' and 'command'

local commandQueue = {}
remoteAddress = 'abcde-fghi...'
commandQueue.remoteAddress = 'POWER:OFF'
And having a function which repeat processes this queue..

local proceedCommandQueue = function()
    if (tableLength(commandQueue) > 0) then
        for remoteAddress,command in pairs(commandQueue) do
            wlan.send(remoteAddress, wlanPort, command)
        end
    end
end
event.timer(0.5, proceedCommandQueue)
But now i have brain-lagg and dont know how to verify this on client-side (receiver) or even how i must handle it by the computer (sender) to be sure that command was executed and can get delete from commandQueue
Link to post
Share on other sites
  • 0

If you're sending messages wirelessly, and sometimes they fail to arrive, could it be that your wireless signal strength on the sender is too low?

 

I'm just not sure if making a command queue is necessary. If all you're sending is a command to turn off a reactor, then it shouldn't matter if that gets executed multiple times, since you can't turn off an already off thing. The extra "off" signals would just be ignored.

 

Ooh, I just thought of something. What if you sent a random number as another parameter with the message,(i.e, modem.send(<address>,<port>,"Message",<random #>)) generated every time you click the button to start the command-sending loop? Then, the receiver could store that random number, and if the next command contains the same number, it's a duplicate, and can ignore it. That should work. I believe there's a library called math that has a random number generator.

 

PS. Making conversation, I noticed that you're in Germany. Where are you from in Germany? I'm personally from Texas in the US.

Link to post
Share on other sites
  • 0

If you're sending messages wirelessly, and sometimes they fail to arrive, could it be that your wireless signal strength on the sender is too low?

It was set to default and its max: 400

actually i have set it to 200 but on default the problem was there too..

 

I'm just not sure if making a command queue is necessary. If all you're sending is a command to turn off a reactor, then it shouldn't matter if that gets executed multiple times, since you can't turn off an already off thing. The extra "off" signals would just be ignored.

That was just an example - i have more commands as only "off" :)

 

Another example is, that the computer always sends a "ping" via broadcast and if a new client (robot) is in network it should get added to a GUI on computer.. but also this "pong" doesnt arrive allways but the robot doesnt repeats again...

Maybe it get clear if you have a look to the code:

Computer: http://pastebin.com/hfjT7e8s ...importend code for this begins @line 199

Robot: http://pastebin.com/FT4UuWdX ...importend code for this begins @line 543

 

Ooh, I just thought of something. What if you sent a random number as another parameter with the message,(i.e, modem.send(<address>,<port>,"Message",<random #>)) generated every time you click the button to start the command-sending loop? Then, the receiver could store that random number, and if the next command contains the same number, it's a duplicate, and can ignore it. That should work. I believe there's a library called math that has a random number generator.

Mh. You mean that the Client saves the last "random-key" and rechecks it on next received command? Oke... But what is with commands where the Computer requests stuff from Client, but that will not arrive? :P

 

PS. Making conversation, I noticed that you're in Germany. Where are you from in Germany? I'm personally from Texas in the US.

'Niedersachsen' ;)
Link to post
Share on other sites
  • 0

This may be an overkill for your problem and beta but you are free to try it:

I programmed a request-handler and a modem-hanlder (actually used together). you add a task to send the commands, it then sends those commands and waits for a response and returns the response. the function that is called on the remote client can be programmed like any normal internal function like:

function turnOff() reactor.off() return true end

Then you will get a "true" in your host function that looks like this:

ret=f.remoteRequest(reactor-address,command,data,nil,timeout) --> will be executed on the client as command(data)

ret gets the return of the client function turnOff().

If the host does not get an answer within the timeout it will send it a second time. of course you can let it send a third time if ret is still nil.

Basically it also does what Gangsir said, sending and storing message-ids to take care of duplicate message, so one request can't get executed 10 times if the message arrives this often.

 

if you are still interested, this is how to work with that (adapted to your situation):

local f=require"req_handler"
f.initialize()

local reactor=address
local reactor2=address

local function turnOff(reactor) 
  local ret
  try=1
 while not ret and try<5 do
   ret=f.remoteRequest(reactor,turnOff,nil,nil,2)
   try=try+1
 end
print(ret)
end

local function toggle(...)
  --doStuff
  f.addTask(turnOff,reactor)
end

event.listen("touch",toggle)

while true do f.execute() end

the request_handler (f) is like a process manager, you add a task and it will get executed when calling f.execute(). This makes sure that ids will be generated and the remote answer will get back to the correct function (this is not used in this example, there are more complex situations where you have to wait 20 seconds for an answer but don't want your host to get stuck that long. especially for this cases i use the request handler. pausing the execution of one task until an answer arrives and continue it when the answer is received. at the moment not with coroutines sadly, but i will add this one day).

 

 

On your client the code could look like this:

local f=require"req_handler"
f.initialize()

local function turnOffReactor()
--doStuff
  return true
end

f.registerFunction(turnOffReactor,"turnOff") --makes this function available for external calls: host calling this function on client

while true do f.execute() end

So this is basically how you could use this. (you shouldn't change the port 801 though, i did not test that). It automatically uses wireless with strength 400 if available.

you can get it from my github:

https://github.com/kevinkk525/OC-tools/blob/master/modem-handler.lua

https://github.com/kevinkk525/OC-tools/blob/master/request-handler.lua

 

Use this code to get it to your OC-PC with an internet card:

local component=require"component"

if not component.isAvailable("internet") then
    print("You need a internet card, quit with any key")
    local inp=io.read()
    os.exit()
end
if not component.internet.isHttpEnabled() then
    print("Http is not enabled, please ask your admin! quit with any key")
    local inp=io.read()
    os.exit()
end
print("\ndownloading request-handler and modem-handler")
os.execute("wget -f https://github.com/kevinkk525/OC-tools/raw/master/modem-handler.lua /lib/modem_handler.lua")
os.execute("wget -f https://github.com/kevinkk525/OC-tools/raw/master/request-handler.lua /lib/req_handler.lua")

if it is too complicated or not what you want to add just ignore this :D I'm building all my networks with it.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use and Privacy Policy.