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

General Programming Question - Door Controller

Question

My apologies in advance for being so bad, basically i want a simple script that when me or a friend are around a door, it opens the door, but when no one is around that is authorized, close the door. I guess I do not know how to manipulate a table correctly in lua. When you run a scan() with an RFID reader in opensecurity, it returns a table with 4 values, name, range, data (password), locked, and UUID of the rfid reader. I do not know how to pin point specifically to the name of the table, such as if scan[name] == savagenoob then open the door, if none exist close the door. As this code sits, it doesnt work, and if the scan does not find anyone it throws an error in pairs table. Some guidance would be appreciated. 

https://pastebin.com/embed_js/rZPbYy4z


door = require("component").os_door
rfid = require("component").os_rfidreader

scan = rfid.scan()


for k, v in pairs(scan[1]) do
  print(tostring(k)..": "..tostring(v))


if k[1] == "savagenoob" then


  print "You are Allowed"
  door.open()
  print "Door Open"
  else
  door.close()
  print "You are not allowed"
end
end

 

Share this post


Link to post
Share on other sites

2 answers to this question

Recommended Posts

  • 0

Let's solve the problem iteratively, one step at a time. The first thing to do is to define the task thoroughly. Our goal is to make a program that checks periodically if there's an authorized person, opens the door if there is one, and closes it otherwise.

Then we should require everything we need — that is, the door and the RFID reader.

local door = require("component").os_door
local rfid = require("component").os_rfidreader

This is almost the same as what you did in your code, but notice that the variables I've defined are local. You may wonder what it means and why I'm doing this. I'm not going to answer the former question here, lest the answer be too long to read without feeling bored. :)Instead, I'll answer the latter question. Making every variable local helps to prevent odd bugs with "ghost" variables (those that possess a value, albeit not being set anywhere in the program), complicating program development needlessly, and serves to urge the programmer to pass data between functions explicitly instead of relying on global variables. Though, if I am to be honest, it won't make a difference in this program.

Let's move on. The program needs to know the nick of the authorized user.

local authorized = "johnsmith"

Now we'll need the program to repeat some actions (checking surroundings, managing the door) indefinitely. For that we use a loop — specifically, an infinite loop.

while true do
  ...
end

The ellipsis is a placeholder for the loop body, which will be repeated. Let's replace it with actual code.

First, perform a scan.

local scan = rfid.scan()

scan is now a table of tables. Each subtable contains information about one player. Because we don't know which subtable corresponds to the authorized person, we have to check every entry of scan. We'll use a for loop.

local shouldOpen = false

for _, player in ipairs(scan) do
  ...
end

player is a table. The nick of each player is stored in the field name. We can access its value with player.name. If it's equal to authorized, we'll set the shouldOpen variable to true. Otherwise, we look further. If that person is not detected by the scanner, shouldOpen will remain false.

for _, player in ipairs(scan) do
  if player.name == authorized then
    shouldOpen = true
    break
  end
end

If we find the user, the break statement stops the for loop prematurely. Also note that we don't need to put local before shouldOpen = true: local defines a new variable, whereas we just want to reassign an existing one.

Now that we know if there's a trusted user nearby, we can control the door.

if shouldOpen then
  door.open()
else
  door.close()
end

If the door is already open, door.open() does nothing (likewise if we .close() a closed door), which is what we want.

Finally, we add an os.sleep to wait a second before checking again.

os.sleep(1)

Gathering the snippets together, we get the finished program.

local door = require("component").os_door
local rfid = require("component").os_rfidreader

local authorized = "johnsmith"

while true do
  local scan = rfid.scan()
  local shouldOpen = false

  for _, player in ipairs(scan) do
    if player.name == authorized then
      shouldOpen = true
      break
    end
  end

  if shouldOpen then
    door.open()
  else
    door.close()
  end

  os.sleep(1)
end

Share this post


Link to post
Share on other sites
  • 0

He said if he or his friends are around. Your code needs some changes for that.

local door = require("component").os_door
local rfid = require("component").os_rfidreader

local authorized = {
	"johnsmith" = true,
	"johnsmith_friend_1" = true,
	"johnsmith_friend_2" = true
}

while true do
  local scan = rfid.scan()
  local shouldOpen = false

  for _, player in ipairs(scan) do
    if authorized[player.name] then
      shouldOpen = true
      break
    end
  end

  if shouldOpen then
    door.open()
  else
    door.close()
  end

  os.sleep(1)
end

 

Share this post


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.