So we have a Sonos Playbar hooked up to our TV in the living room, and a Sonos 3 in the kitchen (permanently grouped to the Playbar) that we sometimes unmute when cooking. Wouldn’t it be cooler if it automatically unmuted when cooking or when I walk in to grab a beer?
I’ve also been thinking - if you group all of your Sonos speakers as one, you could have your music follow you anywhere in the house, as long as they’re paired with motion detectors. Pretty baller if you ask me.
/**
* Sonos Unmute on Motion, Mute on No Motion
* Based on a couple of other templates/scripts, which I can't be bothered to dig up
*
* Author: Alex Keybl
*/
definition(
name: "Sonos on Motion",
namespace: "alexkeybl",
author: "alexkeybl",
description: "Sonos unmute on motion, mute on no motion. For grouped Sonos, mostly.",
category: "Convenience",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/sonos.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/sonos@2x.png"
)
preferences {
section("On motion (or lack of)...") {
input "motions", "capability.motionSensor", multiple: true, title: "Where?", required: true
}
section("Mute/unmute...") {
input "sonos", "capability.musicPlayer", multiple: true, title: "Which Sonos?", required: true
}
section("And off when there's been no movement for..."){
input "minutes1", "number", title: "Minutes?", required: true
}
}
def installed()
{
subscribe(motions, "motion", motionHandler)
}
def updated()
{
unsubscribe()
subscribe(motions, "motion", motionHandler)
}
def motionHandler(evt) {
log.debug "$evt.name: $evt.value"
if (evt.value == "active") {
log.debug "unmuting Sonos"
sonos?.each {
it.unmute()
}
} else if (evt.value == "inactive") {
runIn(minutes1 * 60, scheduleCheck, [overwrite: false])
}
}
def scheduleCheck() {
log.debug "schedule check"
def is_motion = false
def last_time = 0
motions?.each {
if(it.currentState("motion").value != "inactive") {
is_motion = true
}
else if(it.currentState("motion").rawDateCreated.time > last_time) {
last_time = it.currentState("motion").rawDateCreated.time
}
}
if (is_motion == false) {
def elapsed = now() - last_time
def threshold = 1000 * 60 * minutes1 - 1000
if (elapsed >= threshold) {
log.debug "Motion has stayed inactive long enough since last check ($elapsed ms): muting Sonos"
sonos?.each {
it.mute()
}
} else {
log.debug "Motion has not stayed inactive long enough since last check ($elapsed ms): doing nothing"
}
} else {
log.debug "Motion is active, do nothing and wait for inactive"
}
}