One of the biggest missing feature of the Soundtouch system is the ability to program an alarm on it.
I solved this integrating my soundtouch system in openHAB and controlling it from there, including time to switch on and volume ramping
To run this, you need a working installation of openHAB 2, at least one soundTouch system and its working binding
i will simply add a series of switche and selectors to choose the time, the day, and if the alarm is enabled
first of all we define the soundtouch items (you dont need all these for the alarm, but this is my actual setup)
soundtouch.items
//SOUNDTOUCH
Switch SoundTouch_OnOff "Power: [%s]" <onoff_monochrome> (Sala, Home) { channel="bosesoundtouch:30:000C8A7E7A1C:power" }
Dimmer SoundTouch_Volume "Volume: [%d %%]" <soundvolume> (Sala) { channel="bosesoundtouch:30:000C8A7E7A1C:volume" }
String SoundTouch_nowPlayingStationName "Channel: [%s]" <speaker> (Sala) { channel="bosesoundtouch:30:000C8A7E7A1C:nowPlayingStationName" }
String SoundTouch_nowPlayingArtist "Artist: [%s]" <speaker> (Sala) { channel="bosesoundtouch:30:000C8A7E7A1C:nowPlayingArtist" }
String SoundTouch_nowPlayingTrack "Track: [%s]" <speaker> (Sala) { channel="bosesoundtouch:30:000C8A7E7A1C:nowPlayingTrack" }
String SoundTouch_nowPlayingAlbum "Album: [%s]" <speaker> (Sala) { channel="bosesoundtouch:30:000C8A7E7A1C:nowPlayingAlbum" }
Number SoundTouch_preset <speaker> (Sala) { channel="bosesoundtouch:30:000C8A7E7A1C:preset" }
next you need to add an alarm selector to your sitemap (and maybe the soundtouch control, here i added a basic one with power, volume, presets; inside every room the corresponding soundtouc got more info, like artist and track)
default.sitemap
//BASIC SOUNDTOUCH CONTROLLER
Frame label="SoundTouch" {
Switch item=SoundTouch_OnOff
Slider item=SoundTouch_Volume
Switch icon="speaker" label="Presets" item=SoundTouch_preset mappings=[
"1"="Virgin",
"2"="Radio24",
"3"="Dinner Jazz"
]
Switch label="" item=SoundTouch_preset mappings=[
"4"="Vocal Jazz",
"5"="Electro swing",
"6"="Virgin Electro Shock"
]
}
//A NEW PAGE WHERE I SET THE ALARM
Group item=Wakeup {
Frame label="Time" {
Switch item=alarmEnabled
Setpoint item=alarmTimeHour minValue=0 maxValue=23 step=1
Setpoint item=alarmTimeMinutes minValue=0 maxValue=55 step=5
}
Frame label="Weekdays" {
Switch item=alarm_MON
Switch item=alarm_TUE
Switch item=alarm_WED
Switch item=alarm_THU
Switch item=alarm_FRI
Switch item=alarm_SAT
Switch item=alarm_SUN
}
}
Next the rules, basically a cron that check every 5 minutes if the alarm should play (based on time and day), if it should play it calls a FadeIn function that sets the soundtouch volume to 0, select a preset and slowly increase the volume; both the preset and the target volume are hardcoded, but they could be easily added to the alarm configuratio as setpoints (the rule include quiete a lot of debug logging)
alarm.rules
rule "ClockAlarm"
when
Time cron "0 */5 * ? * *"
then
var day_number = now.getDayOfWeek
var minute_now = now.getMinuteOfHour
var hour_now = now.getHourOfDay
var day = ""
//logInfo("default.rules", "Enabled: "+alarmEnabled.state.toString)
switch day_number{
case 1: day = "MON"
case 2: day = "TUE"
case 3: day = "WED"
case 4: day = "THU"
case 5: day = "FRI"
case 6: day = "SAT"
case 7: day = "SUN"
}
if (gAlarmWeekdays.members.filter[s | s.name == "alarm_"+day].head.state == ON && alarmEnabled.state == ON) {
//logInfo("default.rules", "DAY should ring:"+day)
if ((alarmTimeHour.state as Number).intValue==hour_now.intValue && (alarmTimeMinutes.state as Number).intValue == minute_now.intValue) {
//logInfo("default.rules", "alarm: Time matched")
//logInfo("default.rules", "alarm minutes set: "+(alarmTimeMinutes.state as Number).intValue+" now: "+minute_now.intValue)
//logInfo("default.rules", "alarm hours set: "+(alarmTimeHour.state as Number).intValue+" now: "+hour_now.intValue)
sendCommand (FadeIn, ON)
} else {
//logInfo("default.rules", "alarm: Time not matched")
//logInfo("default.rules", "alarm minutes set: "+(alarmTimeMinutes.state as Number).intValue+" now: "+minute_now.intValue)
//logInfo("default.rules", "alarm hours set: "+(alarmTimeHour.state as Number).intValue+" now: "+hour_now.intValue)
}
} else {
//logInfo("default.rules", "alarm: should NOT ring")
}
end
default.rules (where i store generic function like FadeIn that i also use elsewhere)
rule "Fade In"
when
Item FadeIn received command ON
then
val vol=0 //set volume to 0
sendCommand(SoundTouch_preset,4) //hardoced presets
SoundTouch_Volume.sendCommand(vol)
Thread::sleep(10000)
while((vol=vol+1) < 30) {
SoundTouch_Volume.sendCommand(vol)
Thread::sleep(1000)
}
end
using this approach taking the function that play the alarm outside the function that check the alarm everything could be parametric, i can add a select for the type of alarm (instead that using FadeIn i can have multiple one with different devices)
Hope this could be useful