#!/usr/bin/perl -w use strict; local $| = 1; my $repeatDelay = 60; my $delay1 = @ARGV > 0 ? 0+$ARGV[0] : 9; my $target = time+3600*$delay1; my $targetStr = localtime($target); my $delay2 = @ARGV > 2 ? $ARGV[2] : 4; my $timeout = $target+3600*$delay2; my $timeoutStr = localtime($timeout); my $message = @ARGV > 1 ? $ARGV[1] : 'Wake up'; $message =~ s/\.*$/./os; print "Message: $message\n" if length($message); print "Waking at: $targetStr\n"; print "Stopping at: $timeoutStr\n"; while (time < $target) { sleep $repeatDelay; } system {'/usr/bin/osascript'} '/usr/bin/osascript', '-e', 'set Volume 10'; my $count = 0; while (time < $timeout) { wakeup($count++); sleep $repeatDelay; } say("The alarm is now shutting down. If you are not yet awake, too bad. $message. For the last time. $message. Sleep well."); sub wakeup { my $count = $_[0]; my($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); if ($count < 10) { if ($count % 4 > 0) { return; # 0, 4, 8 } } elsif ($count < 20) { if ($count % 6 > 0) { return; # 12, 18 } } elsif ($count < 140) { if ($count % 12 > 0) { return; # 24, 36, 48, 60, 72, 84, 96, 108, 120, 132 } } elsif ($count < 210) { if ($count % 5 > 0) { return; # 140, 145, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195, 200, 205 } } else { if ($count % 15 > 0) { return; # 210, 225, 240... } } my $time = getTime($hour, $min); print "\nWake up minute $count at $time. Press Ctrl+C to cancel.\n"; say("Wake up. The time is $time. $message. The time is $time."); } sub getTime { my($hour, $min) = @_; my $time; if ($min <= 2) { $time = ''; } elsif ($min > 2 and $min <= 7) { $time = '5 past '; } elsif ($min > 7 and $min <= 12) { $time = '10 past '; } elsif ($min > 12 and $min <= 17) { $time = 'quarter past '; } elsif ($min > 17 and $min <= 22) { $time = '20 past '; } elsif ($min > 22 and $min <= 27) { $time = '25 past '; } elsif ($min > 27 and $min <= 32) { $time = 'half past '; } else { $hour += 1; if ($hour > 23) { $hour = 0; } if ($min > 32 and $min <= 37) { $time = '25 to '; } elsif ($min > 37 and $min <= 42) { $time = '20 minutes to '; } elsif ($min > 42 and $min <= 47) { $time = 'quarter to '; } elsif ($min > 47 and $min <= 52) { $time = '10 minutes to '; } elsif ($min > 52 and $min <= 57) { $time = '5 minutes to '; } else { $time = ''; } } if ($hour == 12) { if (length($time) > 0) { $time .= '12'; } else { $time = 'noon'; } } elsif ($hour == 0) { $time .= 'midnight'; } else { if ($hour > 12) { $hour -= 12; } if (length($time) > 0) { $time .= $hour; } else { $time = "$hour o'clock"; } } return $time; } sub say { system {'/usr/bin/say'} '/usr/bin/say', @_; }