4
$\begingroup$

I'm doing a Mathematica Notebook and I want to make an alarm clock. Something like this:

SetAttributes[Horas, HoldRest] 

(* Get System Hour *)
Hours = Dynamic[Refresh[DateList[][[4]], UpdateInterval -> 1]];  

SetAttributes[Mins, HoldRest] 

(* Get System Mins *)
Mins = Dynamic[Refresh[DateList[][[5]], UpdateInterval -> 1]]; 

If[
  SameQ[ToString[Hours], ToString[alarmh]] 
    && SameQ[ToString[Mins],ToString[alarmm]],   
  Quiet@EmitSound[Sound[SoundNote["D", 1,"Tinklebell"]]]
];

alarmm and alarmh are variables that the user select from a listbox When the variables from the listbox are the same with the system hour I want to sound a bell.

The problem is that if I make Dynamic variable I can't compare them, but if I do this:

Refresh[DateList[][[5]], UpdateInterval -> 1];

I can compare between them, but the time doesn't update...

How can I make it update?

$\endgroup$
8
  • 2
    $\begingroup$ Hey ... 2012 questions tagged Mma on 2012 ... this will never going to happen again ... $\endgroup$ Mar 13, 2012 at 14:47
  • $\begingroup$ Anyone knows how can i do this? $\endgroup$
    – GRiPHuS
    Mar 13, 2012 at 19:12
  • $\begingroup$ I´m trying to build an alarm clock, I think the problem is when I make a dynamic variable, this variable has not a format like String, int..., for this reason I cant compare a dynamic variable with another literal variable... Thanks! $\endgroup$
    – GRiPHuS
    Mar 14, 2012 at 8:58
  • $\begingroup$ Welcome user1266140 to Mathematica.SE! As to your question: Dynamic for a a background task is generally not a good idea as it only executes as long as the cell containing it is visible in the frontend. I feel what you're looking for can be achieved with timed evaluations. $\endgroup$ Mar 14, 2012 at 9:29
  • $\begingroup$ Thank you for your comment. But I have a question, if I use timed evaluations, could I compare the values between the hour system and a literal variable? $\endgroup$
    – GRiPHuS
    Mar 14, 2012 at 10:01

3 Answers 3

7
$\begingroup$

Manipulate will work. This simple alarm will sound for 1 minute or shorter period if you hit reset:

Manipulate[If[Refresh[DateList[], UpdateInterval -> 1][[4 ;; 5]] == 
 {hours, minutes} && oo, EmitSound[Sound[SoundNote["C", 1]]]];
 Text@Style[DateString[], 20], {{hours, 0}, Range[25] - 1}, {{minutes, 0}, 
 Range[61] - 1}, {{oo, True, "alarm"}, {True -> "ON", False -> "OFF"}}]

enter image description here

$\endgroup$
3
$\begingroup$

Dynamic doesn't work the way you think it does. See this answer for a full explanation.

In short, Dynamic doesn't do anything until it is actually displayed on screen. Therefore you only make a (string) copy of your code when you do:

hours = Dynamic[Refresh[DateList[][[4]], UpdateInterval -> 1]];

ToString[hours]
"Dynamic[Refresh[DateList[][[4]], UpdateInterval -> 1]]"   (* output *)

ToString is apparently extraneous

The format returned by DateList[] is list of numerical values. As far as I can tell you should not be using ToString here at all.

You probably want something else anyway

I don't really understand what you are trying to do. My closest guess is this:

PopupMenu[Dynamic[alarmh], Range[0, 23]]
PopupMenu[Dynamic[alarmm], Range[0, 59]]

DynamicModule[{hours, mins},
 Dynamic[
  {hours, mins} = DateList[][[{4, 5}]];
  If[
   alarmh == hours && alarmm == mins,
   Quiet@EmitSound[Sound[SoundNote["D", 1, "Tinklebell"]]]
  ];
  "This must be displayed!",
  UpdateInterval -> 1
 ]
]

The hours and minutes are selected from the menus. Observe that the output of Dynamic, here arbitrarily "This must be displayed!" must remain visible for the alarm to work. As soon as you delete that output expression, the alarm will cease.

I suspect that you probably want a background alarm process.
If that is the case you should look at Timed Evaluations.
If you use Mathematica version 7 you should find this of interest.

$\endgroup$
3
  • $\begingroup$ +1 But your sentence "Dynamic doesn't work the way you think it does" is quite weak. Actually, Dynamic doesn't work the way almost everybody think it does. $\endgroup$ Mar 15, 2012 at 1:51
  • $\begingroup$ @belisarius that's why I immediately followed the sentence with a link. How would you write this differently? I wanted to concisely yet firmly convey that the reader needs to reexamine the behavior of Dynamic. (thanks for +1) $\endgroup$
    – Mr.Wizard
    Mar 15, 2012 at 8:18
  • 1
    $\begingroup$ Mine was not a critique. Just an observation about the mind setting needed to use Dynamic. It follows an unusual paradigm. Perhaps someone versed on CS could come up with a name for it. $\endgroup$ Mar 15, 2012 at 14:08
3
$\begingroup$

Setting the alarm one minute from now:

{alarmh, alarmm} = Date[][[{4, 5}]] + {0, 1};

Defining a timed task. It executes once every second:

myTask =
  CreateScheduledTask[
   If[
     Date[][[{4, 5}]] == {alarmh, alarmm},
     EmitSound[Sound[SoundNote[]]]
     ];, 
  1];

Note that this rings for a whole minute once the set time is reached since the task is executed 60 times in the minute you have set. It's easy to update the code to change this behaviour.

Start the task:

StartScheduledTask[myTask];

Remove it if no longer useful. Either this task:

RemoveScheduledTask[myTask];

...or all tasks that may be running:

RemoveScheduledTask[ScheduledTasks[]];

Based on your comments it seems that the problem you really have is using the dynamic values of the Hours and Minutes variables. You assigned these variables to the rather complex but mostly invisible output of Dynamic. If you move the assignments to within Dynamic it works OK. See the difference here:

s1 = Dynamic[Date[][[6]], UpdateInterval -> 1]
Dynamic[s2 = Date[][[6]], UpdateInterval -> 1]
Dynamic[{s1, Head[s1], s2, Head[s2]}]

Mathematica graphics

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.