7 posts
Posted 13 October 2014 - 02:22 AM
So this is for a locked door which reads the first line of the program on the disk with the name "passcode" and then sends the code to a central computer. The central computer then broadcasts a reply if that code is applicable to that door.
Anyway, this is the code from the client computer at one of the doors. It works great until someone puts a disk in that doesn't have the "passcode" program on it. I need to add in somehow to make the computer either ignore the disk or print an error or something. Right now it just says "assertion failed" when it can't find that program on the disk.
rednet.open("bottom")
function sendPass()
while true do
event = os.pullEvent("disk")
sFile = "disk/passcode"
hRead = assert(fs.open(sFile, "r"))
sPass = hRead.readLine()
hRead.close()
rednet.broadcast(sPass)
end
end
function open()
while true do
local senderID,message,distance = rednet.receive()
if message == "1" then redstone.setOutput("left", true) disk.eject("top") sleep(3) redstone.setOutput("left", false) end
end
end
while true do
parallel.waitForAny(sendPass, open)
end
rednet.close("bottom")
756 posts
Posted 13 October 2014 - 04:03 AM
Use fs.exists instead of assert.
Btw this can be done without the use of the parallel api, using os.pullEvent more efficiently.
local sFile = "/disk/passcode"
rednet.open("bottom")
while true do
local event, sender, message ,distance = os.pullEvent() --// Use pullEventRaw here to prevent termination
if event == "rednet_message" then
if message == "1" then
redstone.setOutput("left", true)
disk.eject("top")
sleep(3)
redstone.setOutput("left", false)
end
elseif event == "disk" then
if fs.exists(sFile) then
local hRead = fs.open(sFile,"r")
local sPass = hRead.readLine()
hRead.close()
rednet.broadcast(sPass)
else printError("Passcode is absent from the disk")
end
end
end
Edited on 13 October 2014 - 02:10 AM
7 posts
Posted 13 October 2014 - 08:24 PM
Use fs.exists instead of assert.
Btw this can be done without the use of the parallel api, using os.pullEvent more efficiently.
local sFile = "/disk/passcode"
rednet.open("bottom")
while true do
local event, sender, message ,distance = os.pullEvent() --// Use pullEventRaw here to prevent termination
if event == "rednet_message" then
if message == "1" then
redstone.setOutput("left", true)
disk.eject("top")
sleep(3)
redstone.setOutput("left", false)
end
elseif event == "disk" then
if fs.exists(sFile) then
local hRead = fs.open(sFile,"r")
local sPass = hRead.readLine()
hRead.close()
rednet.broadcast(sPass)
else printError("Passcode is absent from the disk")
end
end
end
That's great! Thanks!
7 posts
Posted 13 October 2014 - 09:14 PM
Another question, how would I go about making it check to see if a value exists in a table?
local users = {"2349", "8888", "1234"}
rednet.open("left")
while true do
local senderID,message,distance = rednet.receive()
if message == users then rednet.send(senderID, "1") end
if message ~= users then rednet.send(senderID, "0") end
end
rednet.close("left")
This is the code from the host computer for the door system. I want it so that it will check if the received passcode is in the table, before it replies with a "1", and if the passcode isn't in the table it will just reply with a "0".
Edited on 13 October 2014 - 07:18 PM
1080 posts
Location
In the Matrix
Posted 13 October 2014 - 09:27 PM
Very simply put, you would need a loop to look through the table, the simplest for this is of course a for loop with pairs()
local function confirm(message,tbl)
for key,value in pairs(tbl) do
if value == message then
return true
end
end
return false --#If it looks through the entire table and it wasn't there, then we return false
end
I make most of what i do into functions just so i can plug and use.
Inside your while loop at the bottom you can easily do this.
while true do
local senderID,message,distance = rednet.receive()
local con = confirm(message,users)
if con then rednet.send(senderID,"1")
elseif not con then rednet.send(senderID,"1") end
end
Edited on 13 October 2014 - 07:27 PM
7083 posts
Location
Tasmania (AU)
Posted 14 October 2014 - 12:46 AM
Bear in mind you can have the function return things other than true/false. Usually I'd make it return the key if the value is found; in this case it'd be easier to have it return "1" or "0".
There's also the option of making the values in your table the keys. This makes for shorter and faster running code:
local users = {["2349"] = "1", ["8888"] = "1", ["1234"] = "1"}
rednet.open("left")
while true do
local senderID,message,distance = rednet.receive()
rednet.send(senderID, users[message] or "0")
end
rednet.close("left")
7 posts
Posted 14 October 2014 - 07:31 PM
So I pulled from a few of the replies and I am here.
local users = {"2349", "8888", "1234"}
local clients = {"32", "37"}
rednet.open("left")
while true do
local senderID,message,distance = rednet.receive()
if senderID (is included in the table) clients and message (is included in the table) users then rednet.send(senderID, "1") end
end
rednet.close("left")
I would like it to just check the tables if the senderID is in the clients table and the recieved message is in the users table before it sends the "1" as a reply.
7083 posts
Location
Tasmania (AU)
Posted 15 October 2014 - 12:16 AM
Well, let's take the code Dragon gave you and use it like he showed you:
local function confirm(message,tbl)
for key,value in pairs(tbl) do
if value == message then
return true
end
end
return false --#If it looks through the entire table and it wasn't there, then we return false
end
local users = {"2349", "8888", "1234"}
local clients = {32, 37} -- senderIDs are received as numbers, not as strings.
rednet.open("left")
while true do
local senderID,message,distance = rednet.receive()
if confirm(senderID, clients) and confirm(message, users) then rednet.send(senderID, "1") end
end
rednet.close("left")