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

[LUA] Time check

Started by 1337patchy, 06 July 2012 - 08:57 PM
1337patchy #1
Posted 06 July 2012 - 10:57 PM
Hey there people, how can i make a code that,

while os.time() >= 17 or os.time() <= 8 do
 rs.setOutput("back", true)
else
 rs.setOutput("back", false)
end
That keeps looping, instead of ending, so that i run the program once, and it will always check the time, and each day, at 17, it will trigger redstone power, and at 8 it will stop emitting redstone power
Thanks in advance!
OmegaVest #2
Posted 06 July 2012 - 11:04 PM
Well, you could wrap it in another while loop, but personally I would make that one an infinite loop (use true instead of another conditional), and make an if statement out of your present conditional.


And you don't need the else in your present code, though in the new code, you will.
MysticT #3
Posted 06 July 2012 - 11:19 PM
I don't know why, but I have never seen a program that uses alarms. This would be easier using them:

local side = "back" -- the side to output redstone

-- set the alarm
local alarm
if os.time() >= 8 then
  rs.setOutput(side, false)
  alarm = os.setAlarm(17)
else
  rs.setOutput(side, true)
  alarm = os.setAlarm(8)
end
while true do
  local evt, arg = os.pullEvent("alarm") -- wait for the alarm to trigger
  if arg == alarm then -- check if it's our alarm
	-- set the alarm again
	if os.time() >= 8 then
	  rs.setOutput(side, false) -- turn off the redstone
	  alarm = os.setAlarm(17)
	else
	  rs.setOutput(side, true) -- turn on the redstone
	  alarm = os.setAlarm(8)
	end
  end
end
This way, it will wait for that time to do something.
1337patchy #4
Posted 06 July 2012 - 11:37 PM
Thank you Lua god.
Allow me to ask, what exactly is os.pullEvent, never got that one correctly, what is its function and utility. So alarms are like..uhm..a.wait for it! As in when this value kicks in..do something?
I have another doubt. what is the local evt, arg ? You define alarm as os.setAlarm, so i guess this local evt, arg line is to cross check the time and alarm values, but i dont really see how that happens
Would you mind helping me dissipate those doubts? thanks :P/>/>
MysticT #5
Posted 06 July 2012 - 11:49 PM

alarm = os.setAlarm(17)
os.setAlarm, starts an alarm that will trigger an event when the time (the minecraft time) reaches the one you give it as a parameter (in the example above, the 17).
Now we need to catch that event, so we use os.pullEvent:

local evt, arg = os.pullEvent("alarm") -- wait for the alarm to trigger
os.pullEvent gets the next event in the queue. There's different events that can be queued, like when you press a key it queues a "key" event, when there's a change in redstone a "redstone" event is queued, etc.
Events also have some parameters, like the key code in case of a "key" event, so we need to store them to use them, that's what the "local evt, arg =" part is, it gets the event type and the first argument/parameter and stores them in those variables.
Using "os.pullEvent("alarm")" we make sure that the event we receive is an "alarm" event, so we don't need to check that. The only thing left is to check if the alarm is the one we set before:

if arg == alarm then -- check if it's our alarm
the argument of the alarm event is the value returned by os.setAlarm, so we compare with that to see if it's our alarm.

Ok, I'm not really good explaining things, so I hope you understand all that :P/>/>. If you have any other question, just ask, we'll try to help you.
archit #6
Posted 06 July 2012 - 11:56 PM
os.pullEvent is like a state machine for input, letting you perform any action in correlation with a specific input.

A nice easy to follow explanation can be found at http://www.computercraft.info/forums2/index.php?/topic/1516-ospullevent-what-is-it-and-how-is-it-useful/
1337patchy #7
Posted 07 July 2012 - 12:17 AM
Thanks archit and luagod :P/>/>
Really mind clearing! THanks you guys, nice to know people help :)/>/>
MysticT #8
Posted 07 July 2012 - 12:19 AM
No problem, we'r here to help :P/>/>
btw, I'm MysticT, Lua God is just a rank.
1337patchy #9
Posted 07 July 2012 - 12:36 AM
Oh lol didnt even notice, was just too soaked up on the code., but i have now tried your code and it doesnt work :s i mean the program does not time out but it does not power the redstone :/
The final part on your code, which you have commented, i inserted into the code btw.
MysticT #10
Posted 07 July 2012 - 12:56 AM
Try with this:

local side = "back"

local alarm

local function setAlarm()
  local time = os.time()
  if time >= 8 and time < 17 then
    rs.setOutput(side, false)
    alarm = os.setAlarm(17)
    print("Alarm set for 17")
  else
    rs.setOutput(side, true)
    alarm = os.setAlarm(8)
    print("Alarm set for 8")
  end
end

setAlarm()
while true do
  local evt, arg = os.pullEvent("alarm") -- wait for the alarm to trigger
  print("Alarm triggered")
  if arg == alarm then
    setAlarm()
  end
end
The print lines are just for debug purpouses, so you know what's going on.
1337patchy #11
Posted 07 July 2012 - 01:11 AM
Thanks a lot Mystic :)/>/>
This worked, pretty much appreciated. Hope one day il know half of what you know lua related :P/>/>
1337patchy #12
Posted 06 August 2012 - 11:58 PM


local function setAlarm()
  local time = os.time()
  if time >= 8 and time < 17 then
	rs.setOutput(side, false)
	alarm = os.setAlarm(17)
	print("Alarm set for 17")
  else
repeat
	rs.setOutput(side, true)
	sleep(2)
	rs.setOutput(side, false)
	sleep(2)
	alarm = os.setAlarm(8)
	print("Alarm set for 8")
until time == 8
  end
end

Alright, this is an edited code of the above posted by MysticT, and it works partially, when its night it executes the night command, it sends redstone signal, stops for 2 seconds, sends again, all ok, but it doesnt get out of that loop once its day, ive tried every kind of things in the until, and i cant get it to stop pulsing when its day…
any help?
MysticT #13
Posted 07 August 2012 - 01:23 AM
The loop never ends because the "time" variable never changes.
This should do it:

local side = "back"

local alarm
local timer -- timer for the pulse

local function setAlarm()
  local time = os.time()
  if time >= 8 and time < 17 then
	rs.setOutput(side, false)
	alarm = os.setAlarm(17)
	timer = nil -- turn off the timer
	print("Alarm set for 17")
  else
	alarm = os.setAlarm(8)
	timer = os.startTimer(2) -- turn on the timer
	print("Alarm set for 8")
  end
end

setAlarm()
while true do
  local evt, arg = os.pullEvent()
  if evt == "alarm" then
	if arg == alarm then
	  setAlarm()
	end
  elseif evt == "timer" then
	if arg == timer then
	  rs.setOutput(side, not rs.getOutput(side)) -- change the output (on -> off, off -> on) to make the pulse
	  timer = os.startTimer(2) -- restart the timer
	end
  end
end
It uses a timer instead of sleep, so the loop can continue to check for the alarm.
1337patchy #14
Posted 07 August 2012 - 08:42 PM
You good sir, are a genius may i say!
Cranium #15
Posted 07 August 2012 - 09:36 PM
No problem, we'r here to help ;)/>/>
btw, I'm MysticT, Lua God is just a rank.
Hrm…it says "request your own title" above your name for me… Bug?
MysticT #16
Posted 07 August 2012 - 09:45 PM
No problem, we'r here to help :(/>/>
btw, I'm MysticT, Lua God is just a rank.
Hrm…it says "request your own title" above your name for me… Bug?
Nah, it changed at 1000 posts. I think I have to ask an admin/mod to change it, not sure, there's no one with 1000 posts. I don't know what to change it to anyway ;)/>/>
Cranium #17
Posted 07 August 2012 - 09:56 PM
No problem, we'r here to help :(/>/>
btw, I'm MysticT, Lua God is just a rank.
Hrm…it says "request your own title" above your name for me… Bug?
Nah, it changed at 1000 posts. I think I have to ask an admin/mod to change it, not sure, there's no one with 1000 posts. I don't know what to change it to anyway ;)/>/>
Lua God maybe? :(/>/>