AppleScript On Idle Alarm Clock

Hey AppleScript geniuses and rookies alike. I’m in the process of learning, and have a few months under my belt. I want to learn more on the on idle, but am having an issue. I got this idea from Bill Cheeseman http://macscripter.net/viewtopic.php?id=24568

But I cannot seem to find where I’m going wrong. The difference is, I want the alarm clock to have multiple alarms and don’t want to set a dialog box to enter them, instead just hard code them in.

global firstTime, alarmTime, myDate, theScript





on run -- this happens on Launch
	
	set theScript to initialize
	
	
end run


script initialize
	set currentDate_Time to current date -------- sets current time/date to variable
	set time_now to time of currentDate_Time ------gets time of date
	set myDate to currentDate_Time - time_now ---- sets to midnight of today
	set firstTime to true
	run Alarm1
	
end script


script Alarm1
	
	set alarm1_lunch to myDate + (9.5 * hours)  -- adds hours to equal 930
	try
		set timeStr to date string of (current date)
		set alarmTime to date ((timeStr) & "at " & alarm1_lunch)
	end try
	
	set firstTime to true
	
end script

script Alarm2
	set alarm2_lunch to myDate + (10.5 * hours) 
	try
		set timeStr to date string of (current date)
		set alarmTime to date ((timeStr) & "at " & alarm2_lunch)
	end try
	
	set firstTime to true
end script

script Alarm3
	set alarm3_leave to myDate + (15 * hours)
	try
		set timeStr to date string of (current date)
		set alarmTime to date ((timeStr) & "at " & alarm3_leave)
	end try
	
	set firstTime to true
	
	
end script

script Alarm4
	set alarm4_punchTomorrow to myDate + (30 * hours) -- gets tomorrow's clock in time
	try
		set timeStr to date string of (current date)
		set alarmTime to date ((timeStr) & "at " & alarm4_punchTomorrow)
	end try
	
	set firstTime to true
	
	
end script


on idle
	run script theScript
	if theScript is Alarm1 then
		set theScript to Alarm2
	else if theScript is Alarm2 then
		set theScript to Alarm3
	else if theScript is Alarm3 then
		set theScript to Alarm4
	else
		set theScript to Alarm1
	end if
	if firstTime then
		set firstTime to false
		return (alarmTime - (current date))
	else
		beep 2
		set bbuton to button returned of (display dialog "This is an Alarm")
		if bbuton is "Cancel" then quit
	end if
end idle

Thank you to all those that have posted something, as your contributions have helped me to get this far.
Sincerely,
Michael

Sacramento, CA

Hi. In order to escape from one script and call another, you use “my”. “Run” is implied, so you don’t have to specify it.


   set theScript to initialize

script initialize
	...
	run my Alarm1
end script

The result of a script object is the value returned from its last expression. Initialize runs Alarm1, which returns “true;” the idle handler can’t run that. Perhaps you can explain your goal, because I’m not seeing why the script objects and idle handler even exist.

Hi Michael,

Firstly, you should set the times to shorter times for testing like 10 seconds or you’ll have to wait many hours for results. I know what article you’re writing about. Went over it many times myself.

gl,
kel

Hi Michael,

Not sure, but I think there’s a bug with global variables in Yosemite. I have to review global variable in AppleScriptLanguageGuide.pdf. Mainly the scope and differences with property declaration.

Edited: think I know what is wrong with the global variables. I just started cooking something. Later.

gl,
kel

Fixed your script for testing. Also, added some beeps so you would know what is happening.

global firstTime, alarmTime, myDate, theScript

on run -- this happens on Launch
	
	set theScript to initialize
	
end run

script initialize
	
	set currentDate_Time to (current date) -------- sets current time/date to variable
	set time_now to time of currentDate_Time ------gets time of date
	
	-- use current date for now
	set myDate to currentDate_Time -- - time_now ---- sets to midnight of today
	
	set firstTime to true
	run my Alarm1 -- added my
	
end script

script Alarm1
	
	-- changed to add 10 secs
	set alarm1_lunch to time string of (myDate + 10) --(9.5 * hours) -- adds hours to equal 930
	try
		set dateStr to date string of (current date)
		set alarmTime to date (dateStr & "at " & alarm1_lunch)
	end try
	
	set firstTime to true
	beep 1
end script

script Alarm2
	
	set alarm2_lunch to time string of (myDate + 20) --(10.5 * hours)
	try
		set dateStr to date string of (current date)
		set alarmTime to date (dateStr & "at " & alarm2_lunch)
	end try
	
	set firstTime to true
	beep 2
end script

script Alarm3
	
	set alarm3_leave to myDate + 30 --(15 * hours)
	try
		set dateStr to date string of (current date)
		set alarmTime to date (dateStr & "at " & alarm3_leave)
	end try
	
	set firstTime to true
	beep 3
end script

script Alarm4
	
	set alarm4_punchTomorrow to time string of (myDate + 40) --(30 * hours) -- gets tomorrow's clock in time
	try
		set dateStr to date string of (current date)
		set alarmTime to date (dateStr & "at " & alarm4_punchTomorrow)
	end try
	
	set firstTime to true
	beep 4
end script

on idle
	run theScript -- changed run script to run
	
	if theScript is Alarm1 then
		set theScript to Alarm2
	else if theScript is Alarm2 then
		set theScript to Alarm3
	else if theScript is Alarm3 then
		set theScript to Alarm4
	else
		set theScript to Alarm1
	end if
	if firstTime then
		set firstTime to false
	else
		set bbuton to button returned of (display dialog "This is an Alarm")
		if bbuton is "Cancel" then quit
	end if
	--display dialog (alarmTime - (current date)) as string
	return (alarmTime - (current date))
end idle

You can debug it.

gl,
kel

After reading through, it seems this combines Cheeseman’s #7 and #8 examples. I played around with it and came up with a variant, as it doesn’t look like the initialize portion should be separate from the run handler or contain a call to the first alarm. I’m also not sure under what circumstance this method is advisable, as it’s so overwrought; this could easily be a very terse script without any script objects.

--on run --implied
set text item delimiters to return
global thescript, dateObj, alarmtime
set dateObj to current date
--set witchingHour to date (dateObj's date string) --@ midnight
set thescript to my alarm1
--end

script alarm1 --first lunch
	set addedTime to 1 --9.5 * hours
	set alarmtime to (dateObj + addedTime)
	set alarmComponents to alarmtime's {date string, time string}
end script
script alarm2 --second lunch
	set addedTime to 2 --10.5 * hours
	set alarmtime to (dateObj + addedTime)
	set alarmComponents to alarmtime's {date string, time string}
end script
script alarm3 --clock out
	set addedTime to 3 --15 * hours
	set alarmtime to (dateObj + addedTime)
	set alarmComponents to alarmtime's {date string, time string}
end script
script alarm4 --punch in
	set addedTime to 4 --30 * hours
	set alarmtime to (dateObj + addedTime)
	set alarmComponents to alarmtime's {date string, time string}
end script


on idle
	try
		run thescript
		if thescript is alarm1 then
			display dialog ((run alarm1) as text) & return & return & "delayed: " & alarmtime - dateObj with title "alarm1"
			set thescript to alarm2
		else if thescript is alarm2 then
			display dialog ((run alarm2) as text) & return & return & "delayed: " & alarmtime - dateObj with title "alarm2"
			set thescript to alarm3
		else if thescript is alarm3 then
			display dialog ((run alarm3) as text) & return & return & "delayed: " & alarmtime - dateObj with title "alarm3"
			set thescript to alarm4
		else
			display dialog ((run alarm4) as text) & return & return & "delayed: " & alarmtime - dateObj with title "alarm4"
			quit
		end if
		return alarmtime - dateObj --delay
	on error
		quit
	end try
end idle

Hi Marc,

I would do about the same also, but thinking that the op was trying to learn about AppleScript.

In the first place, if you want an alarm many hours later, then there are many better ways. I’d probably use a launch agent one of the many apps. Running an idle handler for that long might not be a good idea.

Nice script though with an interesting concept.

Edited: I do the initializing in the run handler also.

Have a good day,
kel