Sonos connectivity, SmartThings Labs, etc

Got a reply from Smartthings:

Hey Eric,

Unfortunately this is a known issue and the team is working to correct it.

Sorry for the inconvenience in the meantime. We expect to have this dealt with soon.

Kind Regards

Bummer :frowning:

It is easy and probably better to use your own audio files as you can make ST and Sonos say whatever you want in any voice you want. I posted files to a server I have and edited the ST Labs app and it works great. “Sir Oliver” now greets us in the morning and throughout the day, or warns us if there is an issue in our home.

On a mac you can make TTS files easily- just type whatever text you want in anything (browser, text editor, mail etc), highlight the text, right click, choose “Export to iTunes as a spoken track”, and choose your voice. You can download different voices in Settings: Dictation & Speech. The you have to convert the file to .mp3 in iTunes or another app. Then upload the file to the server and use the url in the code for the sons app. Works perfect.

I might make a bunch of audio files with common sayings and post the urls for people to use until ST Labs adds more features.

Still haven’t figured out how to use something like dropbox to host the file as the sharing url’s are not direct link- if anyone knows how to use something like dropbox, google drive, etc to host the audio files it might make this even easier- could potentially build a shared repository.

@ Wheeler I can’t figure out for the life of me how you are uploading the audio files to Sonos, any helpful hints (sorry new to this)

The audio files don’t get uploaded to Sonos. They just need to be hosted somewhere on the internet where Sonos/Smartthings can acesss them. In the case of the default Sonos apps that SmartThings built they simply uploaded audio files to Amazon S3 and specified the direct path to the audio file in the app.

def length  = 5000
		switch ( actionType) {
			case "Bell 1":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/bell1.mp3")
				break;
			case "Bell 2":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/bell2.mp3")
				break;
			case "Dogs Barking":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/dogs.mp3")
				length += 4000
				break;
			case "Fire Alarm":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/alarm.mp3")
				length += 9000
				break;
			case "The mail has arrived":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/the%20mail%20has%20arrived.mp3")
				break;
			case "A door opened":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/a%20door%20opened.mp3")
				break;
			case "There is motion":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/there%20is%20motion.mp3")
				break;
			case "Smartthings detected a flood":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/smartthings%20detected%20a%20flood.mp3")
				break;
			case "Smartthings detected smoke":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/smartthings%20detected%20smoke.mp3")
				break;
			case "Someone is arriving":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/someone%20is%20arriving.mp3")
				break;
			case "Piano":
				length += 11000
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/piano2.mp3")
				break;
			case "Lightsaber":
				length += 11000
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/lightsaber.mp3")
				break;
			default:
				log.debug "Missing Sound Choice"
				break;

So you’ll need to host your custom audio file somewhere (Amazon s3 is cheap and pretty easy) and then edit the Sonos Control app to include another audio track by just copying the examples above.

@ Wheeler, are you editing in the IDE under “MySmartAps” (keeps saying access Denied) or are you doing this under “My Devices” or “My Device Types”

You’ll have to create a new smartapp in the IDE. You can’t directly edit an app that you didn’t create. Once you get to the part where it lets you start codeing on your own app there is a dropdown menu in the top right that will let you copy the code from an existing app

@MWeston followed your direction got access to the app but it still doesn’t play. any thought??

/**

  • Sonos (Control)

  • Author: SmartThings

  • Date: 2013-12-10
    */
    preferences {
    section(“Choose one or more, when…”){
    input “motion”, “capability.motionSensor”, title: “Motion Here”, required: false, multiple: true
    input “contact”, “capability.contactSensor”, title: “Contact Opens”, required: false, multiple: true
    input “contactClosed”, “capability.contactSensor”, title: “Contact Closes”, required: false, multiple: true
    input “acceleration”, “capability.accelerationSensor”, title: “Acceleration Detected”, required: false, multiple: true
    input “mySwitch”, “capability.switch”, title: “Switch Turned On”, required: false, multiple: true
    input “mySwitchOff”, “capability.switch”, title: “Switch Turned Off”, required: false, multiple: true
    input “arrivalPresence”, “capability.presenceSensor”, title: “Arrival Of”, required: false, multiple: true
    input “departurePresence”, “capability.presenceSensor”, title: “Departure Of”, required: false, multiple: true
    input “smoke”, “capability.smokeDetector”, title: “Smoke Detected”, required: false, multiple: true
    input “water”, “capability.waterSensor”, title: “Water Sensor Wet”, required: false, multiple: true
    input “button1”, “capability.button”, title: “Button Press”, required:false, multiple:true //remove from production
    }

    section(“Perform this action”){
    input “actionType”, “enum”, title: “Action?”, required: true, options: [
    “Play”,
    “Kitchen”,
    “Stop Playing”,
    “Bell 1”,
    “Bell 2”,
    “Dogs Barking”,
    “Fire Alarm”,
    “The mail has arrived”,
    “A door opened”,
    “There is motion”,
    “Smartthings detected a flood”,
    “Smartthings detected smoke”,
    “Someone is arriving”,
    “Piano”,
    “Lightsaber”]
    }

    section {
    input “sonos”, “capability.musicPlayer”, title: “Sonos Device”, required: true
    }

    section(“Minimum time between actions (optional, defaults to every event)”) {
    input “frequency”, “decimal”, title: “Minutes”, required: false
    }

    section(“More option”, expandable: false, expanded: false) {
    input “volume”, “number”, title: “Temporarily change volume”, description: “0-100%”, required: false
    }
    }

def installed() {
log.debug "Installed with settings: ${settings}"
subscribeToEvents()
}

def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
subscribeToEvents()
}

def subscribeToEvents() {
subscribe(contact, “contact.open”, eventHandler)
subscribe(contactClosed, “contact.closed”, eventHandler)
subscribe(acceleration, “acceleration.active”, eventHandler)
subscribe(motion, “motion.active”, eventHandler)
subscribe(mySwitch, “switch.on”, eventHandler)
subscribe(mySwitchOff, “switch.off”, eventHandler)
subscribe(arrivalPresence, “presence.present”, eventHandler)
subscribe(departurePresence, “presence.not present”, eventHandler)
subscribe(smoke, “smoke.detected”, eventHandler)
subscribe(smoke, “smoke.tested”, eventHandler)
subscribe(smoke, “carbonMonoxide.detected”, eventHandler)
subscribe(water, “water.wet”, eventHandler)
subscribe(button1, “button.pushed”, eventHandler)
}

def eventHandler(evt) {
if (frequency) {
def lastTime = state[evt.deviceId]
if (lastTime == null || now() - lastTime >= frequency * 60000) {
sendMessage(evt)
}
}
else {
takeAction(evt)
}
}

private takeAction(evt) {
log.debug “takeAction($actionType)”

if (actionType == "Play") {
	log.trace "sonos.on()"
	sonos.on()
}
else if (actionType == "Stop Playing") {
	log.trace "sonos.off()"
	sonos.off()
}
else {
	def interval = 250

	def currentVolume = sonos.currentState("level")?.integerValue
	def currentTrack = sonos.currentValue("trackUri")
	def currentMetadata = sonos.currentValue("trackMetadata")
	def currentStatus = sonos.currentValue("status")

	log.trace "uri: " + currentTrack?.encodeAsHTML()
	log.trace "metadata: " + currentMetadata?.encodeAsHTML()
	log.trace "status: " + currentStatus?.encodeAsHTML()
	log.trace "volume: " + currentVolume

	log.trace "Stopping current song"
	sonos.stop()
	if (volume != null) {
		log.trace "Setting volume to $volume"
		pause(interval)
		sonos.setLevel(volume)
	}

	pause(interval)
	log.trace "Playing $actionType"

	def length  = 5000
	switch ( actionType) {
		case "Bell 1":
			sonos.playTrack("http://www.mediafire.com/listen/ihed33frttx4log/kitchenlightson.mp3")
			break;
		case "Bell 2":
			sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/bell2.mp3")
			break;
		case "Dogs Barking":
			sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/dogs.mp3")
			length += 4000
			break;
		case "Fire Alarm":
			sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/alarm.mp3")
			length += 9000
			break;
		case "The mail has arrived":
			sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/the%20mail%20has%20arrived.mp3")
			break;
		case "A door opened":
			sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/a%20door%20opened.mp3")
			break;
		case "There is motion":
			sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/there%20is%20motion.mp3")
			break;
		case "Smartthings detected a flood":
			sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/smartthings%20detected%20a%20flood.mp3")
			break;
		case "Smartthings detected smoke":
			sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/smartthings%20detected%20smoke.mp3")
			break;
		case "Someone is arriving":
			sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/someone%20is%20arriving.mp3")
			break;
		case "Piano":
			length += 11000
			sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/piano2.mp3")
			break;
		case "Lightsaber":
			length += 11000
			sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/lightsaber.mp3")
			break;
		case "kitchen":
			length += 11000
			sonos.playTrack("http://www.mediafire.com/listen/ihed33frttx4log/kitchenlightson.mp3")
			break;                
		default:
			log.debug "Missing Sound Choice"
			break;

Hi I have been trying to get my hub updated so I can test things out but I haven’t gotten a reply. If you guys have any help in a way to have this expedited that would be appreciated. I have emailed a couple times and have checked the chat a few times but no answers. Thanks for your help in advance.

@erickanasgmail-com - I was able to get your mp3 file working with the code below. I tried it first using your mediafire link but it wasn’t working. I’m guessing it is because the way mediafire links to the mp3 file. Possibly because it is going to their player and not the actual MP3 file.

I hosted your sound file in my Amazon S3 bucket and it seems to be working well via the code below. You may just want to make your own Amazon S3 account and upload the file to there, I often purge files from my account and don’t want to break it on you in the future. I believe an S3 account may even be free for low volume, if not my bill is usually no more than 20 cents a month for my personal files.

/**
 *  Sonos (Control) - Custom
 *
 *  Author: Mweston
 *  Date: 2014-01-31
 */
preferences {
	section("Choose one or more, when..."){
		input "motion", "capability.motionSensor", title: "Motion Here", required: false, multiple: true
		input "contact", "capability.contactSensor", title: "Contact Opens", required: false, multiple: true
		input "contactClosed", "capability.contactSensor", title: "Contact Closes", required: false, multiple: true
		input "acceleration", "capability.accelerationSensor", title: "Acceleration Detected", required: false, multiple: true
		input "mySwitch", "capability.switch", title: "Switch Turned On", required: false, multiple: true
		input "mySwitchOff", "capability.switch", title: "Switch Turned Off", required: false, multiple: true
		input "arrivalPresence", "capability.presenceSensor", title: "Arrival Of", required: false, multiple: true
		input "departurePresence", "capability.presenceSensor", title: "Departure Of", required: false, multiple: true
		input "smoke", "capability.smokeDetector", title: "Smoke Detected", required: false, multiple: true
		input "water", "capability.waterSensor", title: "Water Sensor Wet", required: false, multiple: true
		input "button1", "capability.button", title: "Button Press", required:false, multiple:true //remove from production
	}

	section("Perform this action"){
		input "actionType", "enum", title: "Action?", required: true, options: [
			"Play",
			"Stop Playing",
			"Bell 1",
			"Bell 2",
			"Dogs Barking",
			"Fire Alarm",
			"The mail has arrived",
			"A door opened",
			"There is motion",
			"Smartthings detected a flood",
			"Smartthings detected smoke",
			"Someone is arriving",
			"Piano",
			"Lightsaber",
            "Kitchen lights activated"]
	}

	section {
		input "sonos", "capability.musicPlayer", title: "Sonos Device", required: true
	}

	section("Minimum time between actions (optional, defaults to every event)") {
		input "frequency", "decimal", title: "Minutes", required: false
	}

	section("More option", expandable: false, expanded: false) {
		input "volume", "number", title: "Temporarily change volume", description: "0-100%", required: false
	}
}

def installed() {
	log.debug "Installed with settings: ${settings}"
	subscribeToEvents()
}

def updated() {
	log.debug "Updated with settings: ${settings}"
	unsubscribe()
	subscribeToEvents()
}

def subscribeToEvents() {
	subscribe(contact, "contact.open", eventHandler)
	subscribe(contactClosed, "contact.closed", eventHandler)
	subscribe(acceleration, "acceleration.active", eventHandler)
	subscribe(motion, "motion.active", eventHandler)
	subscribe(mySwitch, "switch.on", eventHandler)
	subscribe(mySwitchOff, "switch.off", eventHandler)
	subscribe(arrivalPresence, "presence.present", eventHandler)
	subscribe(departurePresence, "presence.not present", eventHandler)
	subscribe(smoke, "smoke.detected", eventHandler)
	subscribe(smoke, "smoke.tested", eventHandler)
	subscribe(smoke, "carbonMonoxide.detected", eventHandler)
	subscribe(water, "water.wet", eventHandler)
	subscribe(button1, "button.pushed", eventHandler)
}

def eventHandler(evt) {
	if (frequency) {
		def lastTime = state[evt.deviceId]
		if (lastTime == null || now() - lastTime >= frequency * 60000) {
			sendMessage(evt)
		}
	}
	else {
		takeAction(evt)
	}
}

private takeAction(evt) {
	log.debug "takeAction($actionType)"

	if (actionType == "Play") {
		log.trace "sonos.on()"
		sonos.on()
	}
	else if (actionType == "Stop Playing") {
		log.trace "sonos.off()"
		sonos.off()
	}
	else {
		def interval = 250

		def currentVolume = sonos.currentState("level")?.integerValue
		def currentTrack = sonos.currentValue("trackUri")
		def currentMetadata = sonos.currentValue("trackMetadata")
		def currentStatus = sonos.currentValue("status")

		log.trace "uri: " + currentTrack?.encodeAsHTML()
		log.trace "metadata: " + currentMetadata?.encodeAsHTML()
		log.trace "status: " + currentStatus?.encodeAsHTML()
		log.trace "volume: " + currentVolume

		log.trace "Stopping current song"
		sonos.stop()
		if (volume != null) {
			log.trace "Setting volume to $volume"
			pause(interval)
			sonos.setLevel(volume)
		}

		pause(interval)
		log.trace "Playing $actionType"

		def length  = 5000
		switch ( actionType) {
			case "Bell 1":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/bell1.mp3")
				break;
			case "Bell 2":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/bell2.mp3")
				break;
			case "Dogs Barking":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/dogs.mp3")
				length += 4000
				break;
			case "Fire Alarm":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/alarm.mp3")
				length += 9000
				break;
			case "The mail has arrived":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/the%20mail%20has%20arrived.mp3")
				break;
			case "A door opened":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/a%20door%20opened.mp3")
				break;
			case "There is motion":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/there%20is%20motion.mp3")
				break;
			case "Smartthings detected a flood":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/smartthings%20detected%20a%20flood.mp3")
				break;
			case "Smartthings detected smoke":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/smartthings%20detected%20smoke.mp3")
				break;
			case "Someone is arriving":
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/someone%20is%20arriving.mp3")
				break;
			case "Piano":
				length += 11000
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/piano2.mp3")
				break;
			case "Lightsaber":
				length += 11000
				sonos.playTrack("http://s3.amazonaws.com/smartapp-media/sonos/lightsaber.mp3")
				break;
            case "Kitchen lights activated":
				length += 11000
				sonos.playTrack("http://assets.vss.s3.amazonaws.com/kitchenlightson.mp3")
				break;
			default:
				log.debug "Missing Sound Choice"
				break;
		}
		sonos.play()

		// Stop after allowed time
		pause(length)

		log.trace "Stopping $actionType"
		sonos.stop()

		// Reset volume
		if (volume != null) {
			log.trace "Restoring volume to $currentVolume"
			pause(interval)
			sonos.setLevel(currentVolume)
		}

		// Reset to original track
		pause(interval)
		log.trace "Setting track to '$currentTrack'"
		sonos.playTrack(currentTrack)

		// Resume previous status
		if (currentStatus == "playing") {
			log.trace "Resuming play"
			pause(interval)
			sonos.play()
		}
		else {
			log.trace "Not playing because device was not playing before"
		}
	}

	if (frequency) {
		state[evt.deviceId] = now()
	}
}

@MWeston, you are GENIUS! Its clearly an issue with where I am uploading in Amazon, Where are you hosting your files? I keep trying to put them here and it does not like it: https://s3.amazonaws.com/homeautomationsystem/kitchenlightson.mp3

the folder: https://console.aws.amazon.com/s3/home?region=us-east-1

@erickanasgmail-com I think where you are placing it is fine but you may have the wrong content type specified. When you go to the URL in your browser it should play the file not download it like it is doing now.

I would verify that your content type in the S3 console (under the metadata section) is set to “audio/mpeg”… Mine looks like this: http://bryan.cx/wwi5/11SRQCAi

I’m guessing that is probably the issue.

@MWeston, YOU ARE A GENIUS!!! Got it to work perfectly! Thanks My home is now controlled by J.A.R.V.I.S. :slight_smile:

Nice! Yeah, I have to set a few more of these up also. I haven’t figured out if there is a way to include multiple sonos speakers in one app. So far it looks like we have to duplicate the app for every speaker we want it to play on and I have 5. :-\

@slimvaio try emailing them again or chatting through the app, maybe your request got lost?

@mweston
Yikes! That’s a lot of work! Do we have to make a new app for each sound effect ?

You should be able to just add another line for each audio file but you’ll have to install multiple versions of the app for each sound effect and/or each sonos speaker you have.

This thing id going to be the death of me… stopped working this morning and now getting this error AHHHHHHHHHHH!!
9:45:35 AM EST: error Pause times greater than 15 seconds are not permitted.
9:45:35 AM EST: trace Playing Kitchen lights activated
9:45:34 AM EST: trace Stopping current song
9:45:34 AM EST: trace volume: 45
9:45:34 AM EST: trace status: stopped
9:45:34 AM EST: trace metadata: null

        case "Kitchen lights activated":
			length += 11000
			sonos.playTrack("https://s3.amazonaws.com/homeautomationsystem/kitchenlightson.mp3")
			break;
		default:

Mine is not working very well either. I’m thinking there is a bug or smartthings servers are not updating properly.

It doesn’t seem to be recognizing when you change an audio track.

I changed the audio file and completely removed the track so it is no where in the code yet it still keeps playing that track.

Yours is likely still triggering the old code which contained the audio track that I had on my amazon account but I deleted the file last night so it plays nothing.

When I switch back to the default code that Smartthings wrote and try to play one of their tracks I can see in the console log that it triggers the “a door opened” event yet it plays the piano track…

11:42:41 AM: trace uri: http://s3.amazonaws.com/smartapp-media/sonos/piano2.mp3
11:42:41 AM: debug takeAction(A door opened)

Not sure why it is doing that. I’ll let you know if I come up with anything though.

Grrrr. I was ready to toss this thing out the window! I am glad its not just me, but sorry to hear your having the issue to. When i talked to support earlier in the week they said there is a known issue with the sonos events so they may be trying to work through some things… I just wish there was another way to do the sound events without using sonos… seems like it makes it way more complex than it should be… I am going to look into other avenues… maybe a sound board with relay or something…

Yeah, I like the idea of using Sonos because I already have a speaker in pretty much every room of my house but there are still some kinks that need to be worked out.

It looks like the Sonos control app keeps playing the last played audio file instead of the file specified in the settings. I just started playing a Rdio song from the Sonos app, paused it and then set off an event to play “a door opened” and it started playing the Rdio song I was listening to previously for a few seconds instead of playing “a door opened”.

If you have an android device you can also use the Tasker app to speak whatever notifications that smartthings sends you.