This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Karaktar's profile picture

little help its repeating and i dont want it to

Started by Karaktar, 10 September 2017 - 10:20 PM
Karaktar #1
Posted 11 September 2017 - 12:20 AM
so im using a great program from thegaminggnome however i needed to change the action it performs in order for it to function they i want so here is the action programing what i want it to do is either run one or the other depending on the input

if (message == phrase) then
rs.setoutput yadyada
sleep(20)
rs.setoutput yadyada
else
setoutput yadyad
sleep(20)
setoutput yadyada
end

yeah i know the commands arnt right those art the problem the problem is its looping on both and i just want to do one or the other once

i guess what im really asking is can i put in extra end for each possible function like can i turn the top into a standalone function that only triggers for said input

ideally i would like to make evrything minus the else work so that it opens my door and then closes it and then sitt until it receives the mesg tp open it again which in my case is sent via a prox sensor over a wirless modem
Edited on 10 September 2017 - 10:28 PM
Exerro #2
Posted 11 September 2017 - 12:45 AM
Well, obviously that's not the code, but if it were (and correctly formatted 'n' all that) it wouldn't loop. Lua's if statements function how you'd expect:

if condition then
    --# this runs once if condition is truthy
else
    --# this runs once if condition is falsey
end

There's gotta be something else in your code causing it to loop.
Dave-ee Jones #3
Posted 11 September 2017 - 01:01 AM
Well, obviously that's not the code, but if it were (and correctly formatted 'n' all that) it wouldn't loop. Lua's if statements function how you'd expect:

if condition then
	--# this runs once if condition is truthy
else
	--# this runs once if condition is falsey
end

There's gotta be something else in your code causing it to loop.


if message == "this is a test" then
  print("Yes, it works, now stop testing me!")
elseif message == "this isn't a test" then
  rs.setOutput("top",true)
  print("ALARM BELLS BE RINGIN'")
end
Edited on 10 September 2017 - 11:01 PM
Karaktar #4
Posted 11 September 2017 - 01:03 AM
ok well heres the whole code

Spoiler
local modem = peripheral.wrap("right")
local answer = ""
local inputting
local checking
local secretphrase = ""
local portNum = ""
--This function listens for the correct phrase on the determined port
--and will open the door if the phrase and port are matching the other program
function door(phrase,portNum)
    port = tonumber(portNum)
    if not (modem.isOpen(port)) then
        modem.open(port)
    end
    local event, modemSide, senderChannel,replyChannel,message,senderDistance = os.pullEvent("modem_message")
    if (message == phrase) then
        rs.setOutput("front",false)
	    sleep(20)
	    rs.setOutput("front",true)
    else
        rs.setOutput("back",false)
	    sleep(20)
	    rs.setOutput("back",true)
    end
    message = nil
end
--This functions checks if there is a file named "proxInfo"
--If there is, it will tell the program to just read from that
--if there is no file it will tell the program we need to make one
function fileCheck(name)
local f = fs.open(name, "r")
    if f~=nil then
    local line = f.readLine()
    --This will read through the file line by line until it comes across "END"
        repeat
            line = f.readLine()
            if tostring(line) == "END" then
                f.close()
                sleep(1)
                return true
            end
        until line == nil
        sleep(1)
        f.close()
        return false
    else
        return false
    end
end
--The main loop of the program on startup
while true do
    modem.closeAll()
    if fileCheck("proxInfo") then
        inputting = false
        answer = "y"
        checking = false
    else
        inputting = true
        checking = true
    end
    --This starts the user prompt
    while inputting == true do
        term.clear()
        term.setCursorPos(1,1)
        term.clear()
        term.setCursorPos(1,1)
        write("Enter the secret phrase\n")
        write("that you entered on the other\n")
        write("computer: ")
        secretPhrase = read()
-----------------------------------
        term.clear()
        term.setCursorPos(1,1)
        write("Enter the port number \n(can't be greater than 65535): ")
        portNum = read()
        --If the port number is higher than it should be, we keep asking
        while (tonumber(portNum) > 65535) do
            term.clear()
            term.setCursorPos(1,1)
            write("Please enter a vaild port number \n(can't be greater than 65535): ")
            portNum = read()
        end
------------------------------------
        term.clear()
        term.setCursorPos(1,1)
        print("Your secret phrase is: "..secretPhrase)
        print("Your port number is: "..portNum)
        sleep(1)
        print("Is this the correct information (y/n)? ")
        answer = read()
        if answer == "y" then
            h = fs.open("proxInfo", "w")
            h.writeLine(secretPhrase)
            h.writeLine(portNum)
            h.writeLine("END")
            h.close()
            checking = false
            inputting = false
        else
            inputting = true
            checking = true
        end
    end
---------------------------------------
    --We keep looping through this once we have a file
    while (checking == false) and (answer == "y") do
        print("Starting the program...")
        h = fs.open("proxInfo", "r")
        secretPhrase = h.readLine()
        portNum = h.readLine()
        h.close()
        sleep(3)
        term.clear()
        term.setCursorPos(1,1)
        print("If you want to change any settings place")
        print("a lever on top of this computer and pull it.")
        print("You will be prompted if you wish to edit")
        print("the settings. Don't forget to remove")
        print("the lever or toggle it again when you are done!")
        while true do
        door(secretPhrase,portNum)
        if rs.getInput("top") == true then
            term.clear()
            term.setCursorPos(1,1)
            print("Would you like to edit the settings (y/n)? ")
            sleep(1)
            local editCheck = read()
            if editCheck == "y" then
                sleep(1)
                fs.delete("proxInfo")
                os.reboot()
            else
                sleep(1)
                term.clear()
                term.setCursorPos(1,1)
                print("If you want to change any settings place")
                print("a lever on top of this computer and pull it.")
                print("You will be prompted if you wish to edit")
                print("the settings. Don't forget to remove")
                print("the lever or toggle it again when you are done!")
                end
            end
            sleep(2)
        end
    end
end
--Code created by ThatGamingGnome
--Check out my youtube channel @ http://www.youtube.com/user/ThatGamingGnome
Edited on 11 September 2017 - 12:02 AM
Bomb Bloke #5
Posted 11 September 2017 - 02:10 AM
ideally i would like to make evrything minus the else work so that it opens my door and then closes it and then sitt until it receives the mesg tp open it again which in my case is sent via a prox sensor over a wirless modem
If you're saying you don't want the code inside the "else" block to run under any circumstances, then you simply need to delete those lines of code that're inside the "else" block.
Karaktar #6
Posted 11 September 2017 - 02:34 AM
ideally i would like to make evrything minus the else work so that it opens my door and then closes it and then sitt until it receives the mesg tp open it again which in my case is sent via a prox sensor over a wirless modem
If you're saying you don't want the code inside the "else" block to run under any circumstances, then you simply need to delete those lines of code that're inside the "else" block.

heres what i want it to do when it recieves the message i want it to toggle one side off for 20 secs and then back on and if no message then toggle the other side off for 20 sec then on so that after wheather its receiving a message or not it does the one action and then returns to both side on the original code was designed to operate a simple door i am trying to use the code to operate a redstone in motion door. right now im using timers that the computer turns on and or off depending on the message of course i now realize that this poses a problem since the code is set to run on a loop which is fine if the loop just repeats what is already set however since i am wanting it to do more then one thing because of the loop it goes back and runs the function again and again and again for which ever state it is receiving so thinking about it more im wondering if i add in a second if function afther the first if to make it sense the sate of said side and then only do something if that state returns false


ahh hell im getting myself confused


its because the entire program loops instead of the get msg function so it just loops and so if the msg returns the same it repeats that outcome
where it would be better if it just looped the check for function and if the check for function returned a differernt answer then the program would change its outcome and if it didnt then it would do nothing and just keep checking for an update am i making sense
Edited on 11 September 2017 - 12:45 AM
Bomb Bloke #7
Posted 11 September 2017 - 03:41 AM
So if I understand correctly, you don't want the script to wait for messages - you just want it to keep toggling the back input over and over, toggling the front input once for every time the correct password happens to be received?
Karaktar #8
Posted 11 September 2017 - 04:30 AM
ok heres how i want it to work

get msg then do
rs.setoutput side off
sleep(20)
rssetoutput side on
sleep(20)
rsetoutput diff side off
sleep(20)
rssetoutput diff side on
else
end

so that when nothing changes it keeps both side on until things change

so that when i approach the door it senses me (already working) and opens the door then waits for some time and closes it and if it doesnt sense me it does nothing and if i stay close after it opens and closes it does nothing i would have to leave and re aproach
Edited on 11 September 2017 - 02:33 AM
Stekeblad #9
Posted 11 September 2017 - 08:18 AM
I can't see any sensor code so I make some up. This is so the door only open once then you get close and not open agaon until you leave and come back

local playerIsHere = false -- did the sensor sense you this scan?
local playerWasHere = false -- did the sensor sense you last scan?
while true do
  playerWasHere = playerIsHere -- remember last scan
  playerIsHere = sensor.isPlayerNearby()
  if(playerIsHere and not playerWasHere) then -- if the sensor found a player then it scaned but not the scan before
    openAndCloseDoor()
  else
    print("player is still here or no player is here, do nothing.")
  end
end
Karaktar #10
Posted 11 September 2017 - 02:07 PM
heres the sensor code


Spoiler
os.unloadAPI("ocs/apis/sensor")
os.loadAPI("ocs/apis/sensor")
local prox = sensor.wrap("top")
local modem = peripheral.wrap("right")
local playerName = ""
local playerNames = {}
local secretPhrase = ""
local portNum = ""
local answer = ""
local inputting
local checking
local heldItemCheck
local item
local heldItem
local b = 0
--This function checks what item the player is holding
function itemCheck(name)
local targets = prox.getTargets()
--Read data from sensor
	for k, v in pairs(targets) do
		if ((v.Name) == "Player") then
			targetsDetail = prox.getTargetDetails(k)
			if not(targetsDetail == nil) then
				if name == targetsDetail.Username then
					heldItem = targetsDetail.HeldItem.Name
					return heldItem
				end
			end
		end
	end
end
--This functions checks our array "playerNames" which contains the players
--we allowed access to this door
--If the for loops finds a match, it will open the door
function arrayCheck(playerNames,playerName,secretPhrase,portNum,item,heldItem)
local port = tonumber(portNum)
	for key, value in pairs(playerNames) do
		if value == playerName and item == nil then
			modem.transmit(port,524,secretPhrase)
		elseif value == playerName and item == heldItem then
			modem.transmit(port,524,secretPhrase)
		end	
	end
	modem.transmit(port,524,"not_player")
end
--This checks the names of the players near the sensor
--and then sends this daya to the "arrayCheck" function
function nameCheck(secretPhrase,playerNames,portNum,item)
local targets = prox.getTargets()
--Read data from sensor
	for k, v in pairs(targets) do
		if ((v.Name) == "Player") then
			targetsDetail = prox.getTargetDetails(k)
			if not(targetsDetail == nil) then
				playerName = targetsDetail.Username
				heldItem = targetsDetail.HeldItem.Name
			end
		end
	end
	arrayCheck(playerNames,playerName,secretPhrase,portNum,item,heldItem)
	targets = nil
	targetsDetail = nil
	playerName = nil
end
--This functions checks if there is a file named "proxInfo"
--If there is, it will tell the program to just read from that
--if there is no file it will tell the program we need to make one
function fileCheck(name)
local f = fs.open(name, "r")
	if f~=nil then
		repeat
			local line = f.readLine()
			if tostring(line) == "END" then
				f.close()
				sleep(1)
				return true
			end
		until line == nil
		f.close()
		sleep(1)
		return false
	else
		return false
	end
end
--The main loop of the program on startup
while true do
	modem.closeAll()
	if fileCheck("proxInfo") then
		inputting = false
		answer = "y"
		checking = false
	else
		inputting = true
		checking = true
	end
	while inputting == true do
		term.clear()
		term.setCursorPos(1,1)
		write("Enter a secret phrase: ")
		secretPhrase = read()
-----------------------------------
		term.clear()
		term.setCursorPos(1,1)
		write("Enter port number \n(can't be greater than 65535): ")
		portNum = read()
		while (tonumber(portNum) > 65535) do
			term.clear()
			term.setCursorPos(1,1)
			write("Please enter a vaild port number \n(can't be greater than 65535): ")
			portNum = read()
		end
-----------------------------------
		term.clear()
		term.setCursorPos(1,1)
		write("Do you want to have the\ndoor open when holding a\nspecific item like a key (y/n)?: ")
		heldItemCheck = read()
		if heldItemCheck == "y" then
			term.clear()
			term.setCursorPos(1,1)
			write("Please enter your name so the\nsensor knows who to look for: ")
			local myName = read()
			term.clear()
			term.setCursorPos(1,1)
			write("Please hold the item you wish\nto be a 'key' for the door\nand then push enter...")
			sleep(1)
			local dummy = read()
			item = itemCheck(myName)
		end
-----------------------------------
		term.clear()
		term.setCursorPos(1,1)
		print("Enter the names seperated by a space\nof the players you want to open this door")
		write("Player Names: ")
		local userInput = read()
		for i in string.gmatch(userInput, "%S+") do
			table.insert(playerNames, i)
		end
		sleep(1)
		term.clear()
		term.setCursorPos(1,1)
		print("Your secret phrase is: "..secretPhrase)
		print("Your port number is: "..portNum)
		if heldItemCheck == "y" then
			print("Your key is: "..item)
		end
		print("The player(s) allowed is/are:")
		for d=1,# playerNames do
			print(playerNames[d])
		end  
		sleep(1)
		print("Is this the correct information (y/n)? ")
		answer = read()
		if answer == "y" then
			h = fs.open("proxInfo", "w")
			h.writeLine(secretPhrase)
			h.writeLine(portNum)
			if heldItemCheck == "y" then
				h.writeLine("ITEM")
				h.writeLine(item)
			else
				h.writeLine("")
			end
			for a=1,# playerNames do
				h.writeLine(playerNames[a])
			end
			h.writeLine("END")
			h.close()
			checking = false
			inputting = false
		else
			for d=1,# playerNames do
				table.remove(playerNames,d)
			end
			inputting = true
			checking = true
		end
	end
-----------------------------------
	--We keep looping through this once we have a file
	while answer == "y" and checking == false do
		print("Starting the program...")
		h = fs.open("proxInfo", "r")
		secretPhrase = h.readLine()
		portNum = h.readLine()
		if h.readLine() == "ITEM" then
			item = h.readLine()
		else
			item = nil
		end
		local x = 0
		repeat
			x = x + 1
			ln = h.readLine()
			playerNames[x] = ln
		until ln == "END"
-----------------------------------
		--print(secretPhrase)
		--print(portNum)
		--print(item)
		--for i=1,# playerNames do
		--	print(playerNames[i])
		--end
-----------------------------------
		h.close()
		sleep(3)
		term.clear()
		term.setCursorPos(1,1)
		print("If you want to change any settings place")
		print("a lever in front of this computer and pull it.")
		print("You will be prompted if you wish to edit")
		print("the settings. Don't forget to remove")
		print("the lever or toggle it again when you are done!")
		while true do
			nameCheck(secretPhrase,playerNames,portNum,item)
			if rs.getInput("front") == true then
				term.clear()
				term.setCursorPos(1,1)
				print("Would you like to edit the settings (y/n)? ")
				sleep(1)
				local editCheck = read()
				if editCheck == "y" then
					sleep(1)
					fs.delete("proxInfo")
					os.reboot()
				else
					sleep(1)
					term.clear()
					term.setCursorPos(1,1)
					print("If you want to change any settings place")
					print("a lever in front of this computer and pull it.")
					print("You will be prompted if you wish to edit")
					print("the settings. Don't forget to remove")
					print("the lever or toggle it again when you are done!")
				end
			end
			sleep(2)
		end
	end
end
--Code created by ThatGamingGnome
--Check out my youtube channel @ http://www.youtube.com/user/ThatGamingGnome


cant remember how to set it has code
Edited on 12 September 2017 - 02:59 PM
Stekeblad #11
Posted 12 September 2017 - 10:01 AM
To make it format code you write "code" inside [] in the beginning and "/code" inside [] at the end

So, to make the door open once and only for allowed players I am thinking like this.
1. Get a list of players in the sensors range
2. Filter out everyone that is not allowed (playerNames = {} ??)
3. Check if they was here when we scanned for players last time
4. Deside if we should open the door or not

Using this as help I hope you can figure out how to make it work with what you have

Spoiler

local playerNames = {"Stekeblad", "Karaktar"}
local playersThisScan = {}
local playersLastScan = {}

local function getPlayersInRange()
  local playersFound = {}
  local targets = prox.getTargets()
  for k, v in pairs(targets) do
	if((v.Name) == "Player") then
	  targetsDetail = prox.getTargetsDetail()
	  if not(targetsDetail == nil) then
		playerName = targetsDetail.Username
		playersFound[playerName] = true
	  end
	end
  end
  return playersFound
end

local function filterOnWhitelistedPlayers(whitelist, tableToFilter)
  for k, v in pairs(tableToFilter) do
	if not whitelist[v] then
	  tableToFilter[k] = nil --remove player that is not allowed
	end
  end
  return tableToFilter
end

local function shouldDoorOpen()
  for k, v in pairs(playersThisScan) do
	if not (playersLastScan[k] then -- if player( that is whitelisted) is in range of the scanner and was not in range last scan
	  return true
	end
  end
  return false
end

while true do
  -- save last scan
  playersLastScan = {}
  for k, v in pairs(playersThisScan)
	playersLastScan[k] = v
  end

  playersThisScan = getPlayersInRange()
  playersThisScan = filterOnWhitelistedPlayers(playerNames, playersThisScan)
  if (shouldDoorOpen())
   -- tell the door to open, redstone, modem message, whatever
  end
  sleep(20)
end
Edited on 12 September 2017 - 12:38 PM
Exerro #12
Posted 12 September 2017 - 03:00 PM
To make it format code you write "code" inside [] in the beginning and "/code" inside [] at the end

So, to make the door open once and only for allowed players I am thinking like this.
1. Get a list of players in the sensors range
2. Filter out everyone that is not allowed (playerNames = {} ??)
3. Check if they was here when we scanned for players last time
4. Deside if we should open the door or not

Using this as help I hope you can figure out how to make it work with what you have

Spoiler

local playerNames = {"Stekeblad", "Karaktar"}
local playersThisScan = {}
local playersLastScan = {}

local function getPlayersInRange()
  local playersFound = {}
  local targets = prox.getTargets()
  for k, v in pairs(targets) do
	if((v.Name) == "Player") then
	  targetsDetail = prox.getTargetsDetail()
	  if not(targetsDetail == nil) then
		playerName = targetsDetail.Username
		playersFound[playerName] = true
	  end
	end
  end
  return playersFound
end

local function filterOnWhitelistedPlayers(whitelist, tableToFilter)
  for k, v in pairs(tableToFilter) do
	if not whitelist[v] then
	  tableToFilter[k] = nil --remove player that is not allowed
	end
  end
  return tableToFilter
end

local function shouldDoorOpen()
  for k, v in pairs(playersThisScan) do
	if not (playersLastScan[k] then -- if player( that is whitelisted) is in range of the scanner and was not in range last scan
	  return true
	end
  end
  return false
end

while true do
  -- save last scan
  playersLastScan = {}
  for k, v in pairs(playersThisScan)
	playersLastScan[k] = v
  end

  playersThisScan = getPlayersInRange()
  playersThisScan = filterOnWhitelistedPlayers(playerNames, playersThisScan)
  if (shouldDoorOpen())
   -- tell the door to open, redstone, modem message, whatever
  end
  sleep(20)
end

There are a few issues here. The function `pairs()` doesn't like it when you change the table being iterated through while it's iterating, so this code would work better:

local function filterOnWhitelistedPlayers(whitelist, tableToFilter)
  local whitelisted = {}
  for k, v in pairs(tableToFilter) do
        if whitelist[k] then
          whitelisted[k] = v --remove player that is not allowed
        end
  end
  return whitelisted
end

There's a closing bracket missing in the shouldDoorOpen:

if not (playersLastScan[k] then

And the code at the end can be simplified a bit:

while true do
  playersLastScan = playersThisScan
  playersThisScan = filterOnWhitelistedPlayers(playerNames, getPlayersInRange())
  if (shouldDoorOpen())
   -- tell the door to open, redstone, modem message, whatever
  end
  sleep(20)
end
Karaktar #13
Posted 12 September 2017 - 11:56 PM
ok gonna be honest here im lost as this wasnt my code to begin with and is far beyond what my current lua knowledge is would anyone like to take a crake at changing the original sensor code to act in the way i want and notate it so i can learn or at least attempt to learn
Stekeblad #14
Posted 13 September 2017 - 11:28 AM
Thanks Exerro for pointing out some problems in my code.


ok gonna be honest here im lost as this wasnt my code to begin with and is far beyond what my current lua knowledge is would anyone like to take a crake at changing the original sensor code to act in the way i want and notate it so i can learn or at least attempt to learn
What of the features of the original code are you interested in? Do you just want a simple script that opens a door if you (and maybe some friends) are close and not anyone else, or also the parts with the lever on top and held item?
Karaktar #15
Posted 14 September 2017 - 03:15 PM
Thanks Exerro for pointing out some problems in my code.


ok gonna be honest here im lost as this wasnt my code to begin with and is far beyond what my current lua knowledge is would anyone like to take a crake at changing the original sensor code to act in the way i want and notate it so i can learn or at least attempt to learn
What of the features of the original code are you interested in? Do you just want a simple script that opens a door if you (and maybe some friends) are close and not anyone else, or also the parts with the lever on top and held item?


well the original code is great in that its flexible and allows for changing settings without needing to break the computer so the levers need to stay aside from that all it needs to do is send the open msg once when it senses a whitelisted play and then do nothing until that condition changes either with the addition of another whitlisted player so that the combined actions of both the sensor unit and the open door unit would act like this

1 sense player that is white listed
2 send msg to open door
3 door unit opens door waits a specified amount of time and closes door
4 return back to default state ie wait for conditions to change

in truth this could be combined at least for my purposes into one computer since my door functions differently then the door this code was originally made to operate however i think for versatility sake keeping it separate would allow for ppl wanting its use for other doors

also the key idea was good but it throws an error on line 56 if you choose not to use the key i just deleted the line however im sure it could be corrected
im thinking instead of adding a key function to the whitelisted players make it choose between either using a key or using a whitelist or both in this way ppl who want to have it just use a key that they give out (i think metadata is important here) can simply do that and for other stuff having a whitelist would allow for sensor range increase without the door opening for no reason and would allow for opening the door if running from something and the door wold be open when you get there ( because my door is using remain in motion its doesnt open very fast)
Stekeblad #16
Posted 14 September 2017 - 09:45 PM
Good, what I wrote earlier is one of the simpler solution but need a few changes and comments

Spoiler

os.unloadAPI("/ocs/apis/sensor") -- taken from original code, probably a reson to try and remove the api and add it again
os.loadAPI("/ocs/apis/sensor") -- makes it possible to use the sensor api in the program

local prox = sensor.wrap("top") -- make something on the top of the computer usable under the name prox
local whitelist = {"Stekeblad", "Karaktar"} -- names of all the player we want to allow
local playersThisScan = {}
local playersLastScan = {}

local function getPlayersInRange() -- returns a table containing the names of all players in range
  local playersFound = {}
  local targets = prox.getTargets() -- scan for stuff
  for k, v in pairs(targets) do -- check everything found one at the time
	if((v.Name) == "Player") then -- make sure it is a player, can the sensor find items?
	  targetsDetail = prox.getTargetsDetail() -- get more info about the player
	  if not(targetsDetail == nil) then
		playerName = targetsDetail.Username -- get the players name
		playersFound[playerName] = true
	  end
	end
  end
  return playersFound
end

local function filterOnWhitelistedPlayers(whitelist, tableToFilter) -- takes two tables with names, returns all names that is in both tables (everyone that is whitelisted)
  local filteredTable = {}
  for k, v in pairs(tableToFilter) do -- for all found players
	if whitelist[k] then
	  filteredTable[k] = v -- save all players that is in in the whitelist
	end
  end
  return filteredTable
end

local function shouldDoorOpen() -- do the check if the door should open here
  for k, v in pairs(playersThisScan) do
	if not (playersLastScan[k]) then -- if player( that is whitelisted) is in range of the scanner and was not in range last scan
	  return true -- allow the door to be opened
	end
  end
  return false -- do not open the door
end

while true do
  playersLastScan = playersThisScan -- remember all whitelisted players that was in range
  playersThisScan = getPlayersInRange() -- scan for players
  playersThisScan = filterOnWhitelistedPlayers(whitelist, playersThisScan) -- filter on whitelist
  if (shouldDoorOpen()) -- door check
   -- tell the door to open, redstone, modem message, whatever
	rs.setOutput("back", true)
	sleep(20) -- seconds to give the door to open and the player to pass before starting to close
	rs.setOutput("back", false")
  end
  sleep(20) -- seconds to wait before checking for players again
end

Then checking for held item you said the nbt can be important so you need to check what information is available from the sensor, look at targetsDetail.HeldItem table and see what information more than the name that can be used.
Easiest place to have this code is in getPlayersInRange() there most of the information already is available. If it is placed between

playerName = targetsDetail.Username
and

playersFound[playerName] = true
you can make it only sets the value to true if the player have the correct item

I am not able to test this so it will probably not work directly.