Jump to content




read("*")/rednet.open() Help.



  • You cannot reply to this topic
51 replies to this topic

#1 applesauce10189

  • Members
  • 162 posts

Posted 28 January 2014 - 09:53 AM

I'm making a password program and I also have a house control program, I plan on having both a password and using a wireless modem to open it when I want to. Password for people allowed in 24/7 and wireless modem for when I'm okay with visitors.

Here's what I have so far.
rednet.open("back")
term.clear()
term.setCursorPos(1,1)
term.setTextColor(colors.purple)
print("AppleOS v0.1")
term.setTextColor(colors.white)
while true do
  if read("*") or rednet.recieve(1) == "open door" then
	rs.setOutput("left", true)
	sleep(2)
	rs.setOutput("left", false)
  end
end

Edited by applesauce10189, 28 January 2014 - 09:54 AM.


#2 CometWolf

  • Members
  • 1,283 posts

Posted 28 January 2014 - 09:56 AM

if read("*") or rednet.recieve(1) == "open door" then
lol, this won't work as these both block until they are finished, as in take all events. rednet.receive won't be ran until you hit enter on the read funciton.
You'll either have to make your own read function or use the parallel api.

#3 applesauce10189

  • Members
  • 162 posts

Posted 28 January 2014 - 10:15 AM

Okay, took your advice and used the parallel API, I know almost nothing of it so I may have used it wrong.
rednet.open("back")
term.clear()
term.setCursorPos(1,1)
term.setTextColor(colors.purple)
print("AppleOS v0.1")
while true do
  parallel.waitForAny(local x = read("*"), local password = rednet.receive()) --Unexpected symbol.
  if x or password == "open door" then
    rs.setOutput("left", true)
    sleep(2)
    rs.setOutput("left", false)
  end
end


#4 CometWolf

  • Members
  • 1,283 posts

Posted 28 January 2014 - 10:29 AM

You can't pass arguments to the functions called with the parallel api. You'll either have to define them as their own functions with the arguments already passed then pass those functions to the parallel api, or define them as anonymous functions passed to the parallel api.
local password = "derp"
while true do
  local acess = false
  parallel.waitForAny(
    function()
	  if read("*") ==password then
	    acess = true
	  end
    end,
    function()
	  if rednet.receive() == password then
	    acess = true
	  end
    end
  )
  if acess then
    rs.setOutput("left", true)
    sleep(2)
    rs.setOutput("left", false)
  end
end


#5 applesauce10189

  • Members
  • 162 posts

Posted 28 January 2014 - 10:40 AM

View PostCometWolf, on 28 January 2014 - 10:29 AM, said:

You can't pass arguments to the functions called with the parallel api. You'll either have to define them as their own functions with the arguments already passed then pass those functions to the parallel api, or define them as anonymous functions passed to the parallel api.
local password = "derp"
while true do
  local acess = false
  parallel.waitForAny(
	function()
	  if read("*") ==password then
		acess = true
	  end
	end,
	function()
	  if rednet.receive() == password then
		acess = true
	  end
	end
  )
  if acess then
	rs.setOutput("left", true)
	sleep(2)
	rs.setOutput("left", false)
  end
end
I always forget you can start a parenthesis on one line and end it on another. Just doesn't feel natural to me.

#6 surferpup

  • Members
  • 286 posts
  • LocationUnited States

Posted 28 January 2014 - 10:44 AM

Change:

parallel.waitForAny(local x = read("*"), local password = rednet.receive()) --Unexpected symbol.

To:

local x,password  
parallel.waitForAny(function() x = read("*") end, function() _,password = rednet.receive() end)

The parallel.waitForAny is expecting functions as arguments. I replaced your assignments with two inline functions. Also, the first return value for rednet.receive() is the senderID, the second is the message. You want the message. I ignored the first return value of rednet.receive() so I could get the message ( _,password = rednet.receive() ). You will have trouble if you don't do that.

Edit: CometWolf was answering this at the same time I was testing my answer. His answer is better developed, although he did not address the problem with your call to rednet.receive()​. I edited mine to emphasize the change I made to your code here.

Edited by surferpup, 28 January 2014 - 10:53 AM.


#7 CometWolf

  • Members
  • 1,283 posts

Posted 28 January 2014 - 10:50 AM

I didn't test mine, but looking at yours now i realized the rednet on mine would fail as it's checking the ID for the password :P

Edited by CometWolf, 28 January 2014 - 10:54 AM.


#8 applesauce10189

  • Members
  • 162 posts

Posted 28 January 2014 - 10:57 AM

Okay, I did as you said and now it says I need a ( to close the ) on line 11.

rednet.open("back")
term.clear()
term.setCursorPos(1,1)
term.setTextColor(colors.purple)
print("AppleOS v0.1")

local password = "open door"
access = false

while true do
  parallel.waitForAny(

  function()
	local x = read("*")
	if x == password then
	  access = true
	end
  end

  function()
	local signal = rednet.receive()
	if id,message == password then
	  access = true
	end
  end
  )
end
EDIT: Didn't see the 2 posts above this. Editting code then going to post it again.
ANOTHER EDIT: All I did was add/change one word. Just going to edit this code to avoid useless posts.

Edited by applesauce10189, 28 January 2014 - 11:01 AM.


#9 surferpup

  • Members
  • 286 posts
  • LocationUnited States

Posted 28 January 2014 - 10:59 AM

I test mine or I will be taken to the woodshed. Besides, I wanted to check out the use of:

if x or password == "open door" then

I thought this would evaluate to if true == "open door" then... but it turns out it works fine. Not sure exactly why this works, but it does. Learn something new all the time.


This is incorrect. It does not work. You need to change it to:

[if x=="open door" or password == open door" then[/color]


I will correct my other posts as well. This was an error in my test routine when I was checking this. Sorry.

Edited by surferpup, 28 January 2014 - 11:34 AM.


#10 CometWolf

  • Members
  • 1,283 posts

Posted 28 January 2014 - 10:59 AM

You forgot the "," to seperate the arguments. Put one at the end closing the first function you're passing to the parallel api.

#11 surferpup

  • Members
  • 286 posts
  • LocationUnited States

Posted 28 January 2014 - 11:00 AM

View Postapplesauce10189, on 28 January 2014 - 10:57 AM, said:

Okay, I did as you said and now it says I need a ( to close the ) on line 11.

You are missing a ,

end
,
function()

I'm signing off this thread -- CometWolf, you got this.

Edited by surferpup, 28 January 2014 - 11:01 AM.


#12 CometWolf

  • Members
  • 1,283 posts

Posted 28 January 2014 - 11:03 AM

lol, imma ninja!

View Postsurferpup, on 28 January 2014 - 10:59 AM, said:

if x or password == "open door" then
I thought this would evaluate to if true == "open door" then... but it turns out it works fine. Not sure exactly why this works, but it does. Learn something new all the time.
if you'd have done (x or password) then it would use x to compare, if it was not nil or false, and otherwise use password. However what it's doing without the parenthese is this
if x == true
or password == "open door" then


#13 surferpup

  • Members
  • 286 posts
  • LocationUnited States

Posted 28 January 2014 - 11:11 AM

View PostCometWolf, on 28 January 2014 - 11:03 AM, said:

However what it's doing without the parenthese is this
if x == true
or password == "open door" then

I tested that. What I found was that it essentially converted it to this:
if (x=="open door") or (password =="open door") then


What you are suggesting is that it is doing a nil check on x (it is not nil) and a value comparison on password. I am actually pretty impressed that these two logical statements are equivalent:
x or password == "open door"

x == "open door" or password == "open door"


Edit: This post is incorrect. These are not equivalent. The second one is what should be used.

x or password == "open door"  < -- this will not evaluate correctly

x == "open door" or password == "open door"  <-- this will evaluate correctly

Edited by surferpup, 28 January 2014 - 11:46 AM.


#14 applesauce10189

  • Members
  • 162 posts

Posted 28 January 2014 - 11:13 AM

Okay here's the final version of my code. It works but one question I have that's some-what unrelated, when I terminate the program I get "Parallel: 22 Terminated" or something like that I don't remember word for word, quick edit. I assume the "Parallel" means the problem occured in the parallel API.

rednet.open("back")
term.clear()
term.setCursorPos(1,1)
term.setTextColor(colors.purple)
print("AppleOS v0.1")

local password = "open door"
access = false

while true do
  parallel.waitForAny(

  function()
	local x = read("*")
	if x == password then
	  access = true
	end
  end

  ,

  function()
	local id,message = rednet.receive()
	if message == password then
	  access = true
	end
  end
  )

  if access then
	rs.setOutput("left", true)
	sleep(2)
	rs.setOutput("left", false)
  end
end
EDIT: Not sure if anybody saw that but I accidentally posted it without the code. Sorry. Lol.

Edited by applesauce10189, 28 January 2014 - 11:16 AM.


#15 surferpup

  • Members
  • 286 posts
  • LocationUnited States

Posted 28 January 2014 - 11:21 AM

It is because you did not gracefully exit. The code is waiting for a parallel event when you pressed ctrl-T Note you will get some kind of terminated message any time you ctrl-t a program. You have not given any kind of graceful exit condition. Here is one which will exit when the user types exit or when the rednet message is exit:

while true do
  local x,password  
  parallel.waitForAny(function() x = read("*") end, function() _,password = rednet.receive() end)
  if x == "open door" or password == "open door" then
	--what you already do
  elseif x == "exit" or password == "exit" then
	break;
  end
end
rednet.close("back")

Edit -- corrected logical comparison in if statements.

Edited by surferpup, 28 January 2014 - 11:36 AM.


#16 TechMasterGeneral

  • Members
  • 149 posts
  • LocationUnited States

Posted 28 January 2014 - 11:31 AM

Try this...

rednet.open("back")
term.clear()
term.setCursorPos(1,1)
term.setTextColor(colors.purple)
print("AppleOS v0.1")
term.setTextColor(colors.white)
while true do
local cmd = read("*")
local evt, p1, p2, p3 = os.pullEvent("rednet_message")
  if cmd == "open door" or  p2 == "open door" then
		rs.setOutput("left", true)
		sleep(2)
		rs.setOutput("left", false)
  end
end


Ignore this.. I'm night quite sure why it won't work

Edited by LuaCrawler, 28 January 2014 - 12:16 PM.


#17 CometWolf

  • Members
  • 1,283 posts

Posted 28 January 2014 - 11:34 AM

View PostLuaCrawler, on 28 January 2014 - 11:31 AM, said:

Try this...

rednet.open("back")
term.clear()
term.setCursorPos(1,1)
term.setTextColor(colors.purple)
print("AppleOS v0.1")
term.setTextColor(colors.white)
while true do
local cmd = read("*")
local evt, p1, p2, p3 = os.pullEvent("rednet_message")
  if cmd == "open door" or if p1 == 1 and p2 == "open door" then
		rs.setOutput("left", true)
		sleep(2)
		rs.setOutput("left", false)
  end
end
Why this won't work has already been explained...

Lol surf, i was about to ask you about that, but when i qouted the post it was crossed out.

#18 surferpup

  • Members
  • 286 posts
  • LocationUnited States

Posted 28 January 2014 - 11:45 AM

I was

View PostCometWolf, on 28 January 2014 - 11:34 AM, said:

Lol surf, i was about to ask you about that, but when i qouted the post it was crossed out.

I was busy making sure I flagged my error to correct the info. The original logical test used in this code as posted by applesauce10189 will fail. I think I show that now. I really dislike it when I post inaccurate info, I don't want to mislead others.

A for my solution for the graceful exit, that will work fine with the edit I made.

And -- yes, you are a ninja.

#19 TechMasterGeneral

  • Members
  • 149 posts
  • LocationUnited States

Posted 28 January 2014 - 12:18 PM

View PostCometWolf, on 28 January 2014 - 11:34 AM, said:

View PostLuaCrawler, on 28 January 2014 - 11:31 AM, said:

Try this...

rednet.open("back")
term.clear()
term.setCursorPos(1,1)
term.setTextColor(colors.purple)
print("AppleOS v0.1")
term.setTextColor(colors.white)
while true do
local cmd = read("*")
local evt, p1, p2, p3 = os.pullEvent("rednet_message")
  if cmd == "open door" or if p1 == 1 and p2 == "open door" then
		rs.setOutput("left", true)
		sleep(2)
		rs.setOutput("left", false)
  end
end
Why this won't work has already been explained...

Lol surf, i was about to ask you about that, but when i qouted the post it was crossed out.

Why won't it work...
cus i've done stuff similar to that... i'm not sure... oh well then

#20 surferpup

  • Members
  • 286 posts
  • LocationUnited States

Posted 28 January 2014 - 12:44 PM

View PostLuaCrawler, on 28 January 2014 - 12:18 PM, said:

Why won't it work...
cus i've done stuff similar to that... i'm not sure... oh well then

Take a careful look at what it is doing in the while loop:
  • wait for user input AND THEN
  • wait for rednet message AND THEN
  • do stuff AND THEN
  • go back to while
These are serially performed tasks. What you want to do is wait for EITHER user inout OR a rednet message and then do stuff.
The parallel.waitForAny function does is precisely that. It will wait for any of the functions to yield and then continue. Do you see the difference?





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users