If you really want to go nuts, here is what I did. I have an old G3 laptop that nobody was using, so I set it up with some external speakers and wrote a script that is called by launchd to run this script:
--Second iteration of the Play2Tracks script, since the first one seems unable to be overwritten!!!
--MOdified on 21 Oct 2006
property Alarm_Run : 0
set log_Name to "AlarmLog2.txt"
set log_path to (path to documents folder as Unicode text) & log_Name
do shell script "echo " & ("Called at: " & (current date) & " - Alarm_Run = " & Alarm_Run) & " >> " & quoted form of (POSIX path of log_path)
set right_now to (current date)'s time string
if right_now's (word -1) = "AM" and right_now's word 1 = "6" and right_now's (word 2) ≥ "30" and right_now's (word 2) ≤ "35" then
if Alarm_Run = 0 then
set volume 7 --7 is max
tell application "iTunes"
delete every track in playlist "Today"
set voice_Track to my PickLowPlayedTrack("Alarm-Voice") --random number from 1 to (count every track in playlist "Alarm-Voice")
set music_Track to my PickLowPlayedTrack("Alarm") --random number from 1 to (count every track in playlist "Alarm")
duplicate track voice_Track of playlist "Alarm-Voice" to playlist "Today"
duplicate track music_Track of playlist "Alarm" to playlist "Today"
play track 1 of playlist "Today"
end tell
set Alarm_Run to 1
end if
else if Alarm_Run = 1 then
set Alarm_Run to 0
end if
repeat with vol from 6 to 5 by -1
delay 45
set volume vol
end repeat
on PickLowPlayedTrack(alb)
set {alb_track_list_sorted, counter} to {{}, 1}
tell application "iTunes"
set the_playlist to every track in playlist alb
repeat with a_track in the_playlist
set end of alb_track_list_sorted to {counter, (a_track's played count)}
set counter to counter + 1
end repeat
end tell
set theChoice to random number from 1 to 3
set the_chosen_track to item theChoice of my SortTheList(alb_track_list_sorted)
return item 1 of the_chosen_track
end PickLowPlayedTrack
to SortTheList(array)
repeat with i from length of array to 2 by -1 --> go backwards
repeat with j from 1 to i - 1 --> go forwards
tell array
if (item 2 of item j) > (item 2 of item (j + 1)) then
set {item j, item (j + 1)} to {item (j + 1), item j} -- swap
end if
end tell
end repeat
end repeat
return array
end SortTheList
Since launchd is not quite perfected yet, I have to have it call this script every 4 minutes to check the time, and if it is between 6:30 and 6:35 AM, the script runs, deletes any tracks in the Today playlist, loads up two random tracks into the same playlist, then plays them. My sons are 8 and 12, and this is the first school year that we have had ZERO problems getting them up in the morning. We are constantly updating the two playlists (Alarm & Alarm-Voice with all sorts of things (their mother speaking, video game sound effects, clips from movies, etc.) and they get a nice randomized set every morning, and we do not have to bug them to get up at all.
I shut it down on the weekends to let the components cool off, since I have not yet updated the script to only trigger on Mon-Fri.