My goal here was to get a morning alarm with an as smooth as possible wake up experience. I first ramp up the dimmable lights in the room slowly over the course of a minute. After that I slowly start to ramp up the sound level for a random track from a Sonos playlist. Currently, I use a playlist of nature sounds, this can be configured at will.
For time configuration, I use the Sonos controller with a special playlist. It is essential that the playlist starts with one minute of silence. This can be found online here:
I would recommend to run the wake-up music from a local share. The alarm mode must not be set to shuffle. The rule will take care of this after the alarm has started. The rule will wait for a bit until Sonos has ramped up the volume to the programmed level and then store it. This way, it will always use the volume you programmed for the alarm in the Sonos controller.
The rule will not mess about when the Sonos buzzer is played, as this is often on purpose or otherwise the fall-back mode in case of connectivity problems. Thus I hope for maximum reliability.
First , a few dummy items need to be configured for the player to be used:
Dimmer SonosSchlafzimmerL_Alarm_Volume "Alarm end volume dummy"
Dimmer SonosSchlafZimmerL_Alarm_Dimmer "Alarm light dimmer dummy"
They have no channels, I just use them for a persistent variable storage.
For the light items involved in the wake-up sequence, I added them to a group that contains all dimmable lights in the room.
Group:Dimmer gDimmableSZ "Dimmable lights in Schlafzimmer"
This is the code for my rule. It makes extensive use of timers to sequence things. I have included a value from a light sensor to not switch on the lights in case the room is already brightly lit, by removing the if clause and its brackets this can be modified to always work if you don’t have a brightness sensor.
var Timer alarmTimerSZ = null
var Timer lightTimerSZ = null
var Timer musicTimerSZ = null
rule "Sonos Alarm SZ"
// Enhance Sonos alarm with light ramp up and slow volume ramp up
when
Item SonosSchlafzimmerL_Alarmrunning changed
then
//stop in case it's the buzzer. don't mess with backstop case
if (SonosSchlafzimmerL_Currenttrackuri.state == "x-rincon-buzzer:0") {return;}
if (SonosSchlafzimmerL_Alarmrunning.state == ON){
//wait 45 seconds for volume ramp up to programmed volume; we need silent track to start playlist, shuffle must be off
alarmTimerSZ = createTimer(now.plusSeconds(45)) [|
SonosSchlafzimmerL_Alarm_Volume.postUpdate(SonosSchlafzimmerL_Volume.state)
SonosSchlafZimmerL_Alarm_Dimmer.postUpdate(0)
SonosSchlafzimmerL_Volume.sendCommand(0)
//orchestrate lights if dark
if (Bewegungsmelder_SZ_MeasurementIlluminance.state < 17) { //remove line when no brightness sensor present
lightTimerSZ= createTimer(now) [|
if (SonosSchlafZimmerL_Alarm_Dimmer.state < 96) {
gDimmableSZ.sendCommand((SonosSchlafZimmerL_Alarm_Dimmer.state as Number) + 5)
SonosSchlafZimmerL_Alarm_Dimmer.postUpdate((SonosSchlafZimmerL_Alarm_Dimmer.state as Number) + 5)
lightTimerSZ.reschedule(now.plusSeconds(5))
}
else {
lightTimerSZ.cancel()
}
]
} //remove line when no brightness sensor present
//random next track, after one minute (and 45 seconds) ramp up volume
SonosSchlafzimmerL_Shuffle.sendCommand(ON)
SonosSchlafzimmerL_Control.sendCommand(NEXT)
musicTimerSZ = createTimer(now.plusMinutes(1)) [|
if (SonosSchlafzimmerL_Volume.state < SonosSchlafzimmerL_Alarm_Volume.state) {
SonosSchlafzimmerL_Volume.sendCommand((SonosSchlafzimmerL_Volume.state as Number) + 1)
musicTimerSZ.reschedule(now.plusSeconds(2))
}
else {
musicTimerSZ.cancel()
}
]
]
}
else {
//alarm was turned off, cancel all automation still running
if (alarmTimerSZ !== null) {alarmTimerSZ.cancel()}
if (lightTimerSZ !== null) {lightTimerSZ.cancel()}
if (musicTimerSZ !== null) {musicTimerSZ.cancel()}
}
end