I think you have a misunderstanding of what createTimer does. createTimer schedules a function to execute at some point in the future and immediately returns. It doesn’t block the execution of the Rule for two minutes like you appear to be trying to do. For that you would use Thread::sleep. But, Thread::sleep for more than a few hundred milliseconds is a really bad idea. A minimum two minute sleep with no set maximum is a really bad idea. See Why have my Rules stopped running? Why Thread::sleep is a bad idea for details.
What you should use is a Design Pattern: Looping Timers. And also realize that the addition of the Snooze is a pretty significant complication. Also, I know of no way to stop a sound from playing once it has started so the snooze button will only be able to extend how long it takes for the sound to play again once it finishes.
var Timer wakeupTimer = null
rule "Wakeup Alarm"
when
Item Morning_Mode_Ready changed to ON or
then
Mbed_GH_Volume.sendCommand("50")
wakeupTimer?.cancel
wakeupTimer = createTimer(now, [ |
if(Morning_Mode_Ready.state != ON) return;
if(Snooze.state == OFF) playSound("chromecast:chromecast:c245712d07d19a769446974721aa5e95", "tsb.mp3")
if(Morning_Mode_Ready.state == ON) wakeupTimer.reschedule(now.plusMinutes(if(Snooze.state == ON) 5+<tsb.mp3 runtime> else 2+<tsb.mp3 runtime>))
])
end
I’m pretty sure that playSound does not block until the sound is done being played so you must add the runtime to the 5 or 2 when rescheduling the Timer.
The above Rule gets triggered when Morning_Mode_Ready changes to ON.
It creates a timer and schedules it to execute immediately.
If Morning_Mode_Ready is OFF we immediately exit the Timer.
If the Snooze isn’t ON we play the sound.
Once the sound has finished playing we check Morning_Mode_Ready is ON again (it may have changed while the sound was plying.
If it is still ON, we reschedule the timer to run again in 5 minutes if Snooze is ON or 2 minutes if not.
But, this is probably not what you want. Instead you probably want the snooze button to stop the sound that is playing on the chromecast. I don’t have a chromecast so I can’t be certain whether this will work but here goes anyway.
We need multiple Rules to handle this. One that triggers on Morning_Mode_Ready and one that triggers on Snooze.
var Timer wakeupTimer = null
rule "Wakeup Alarm"
when
Item Morning_Mode_Ready changed
then
// Start the alarm
wakeupTimer?.cancel // this should never be needed but it is a good thing just in case
wakeupTimer = createTimer(now, [ |
playSound("chromecast:chromecast:c245712d07d19a769446974721aa5e95", "tsb.mp3")
if(Morning_Mode_Ready.state == ON) wakeupTimer.reschedule(now.plusMinutes(2+<tsb.mp3 runtime>))
else wakeupTimer = null
)]
end
rule "Snooze"
when
Channel dash:some:channel:id triggered START or // NOTE: if you plan on using the Dash binding, there will be no Item, just a triggering channel
Item Morning_Mode_Ready changed to OFF
then
// Stop playing the mp3
<sendCommand(PAUSE_ to the Item lined to the Control channel on the Chromecast Thing to stop playing the sound if it is currently playing>
// Turn off the repeating alarm
if(Morning_Mode_Ready.state == OFF) {
// stop the timer
wakeupTimer?.cancel
wakeupTimer = null
}
// Snooze the repeating alarm
else if(Morning_Mode_Ready.state == ON previousState === null){ // previousState will be null if the Rule was triggered by the dash button
wakeupTimer.reschedule(now.plusMinutes(2))
}
end
As with the first Rule, replace the stuff in < >
with what is appropriate.