RELEASE Generic Media Renderer (DLNA Speakers). Cheap Sonos Alternative (Update V2)

Try this for selecting a song with Sonos

Hi @jt323bd, Each track you play in your speaker, the uri its saved in track list , after you played the track, it going to appear in several apps like sonos mood music or media renderer events, you can select some track to play when some event occurs, if your speaker support containers, you can select the container (in media renderer events app) to play all the container, read the first post to known about control point and containers


I am trying to insert a code to get weather from weather underground in my own language.
However, Groovy is a least-known language and I can’t find sample code for using it with Weatherunderground API.
For example, WU requires specifying the output format but I don’t know how to do that in Groovy.

How can I find a sample ?

 debug resp data: [response:[error:[description:you must supply a valid output format, type:invalidformat], features:[:], termsofService:, version:0.1]]

Can I use this for event announce on the cheap?



I really need help on this. Any ideas ?

ps. I don’t mean to disturb this thread with unrelated content but I have no other place to ask.
I also asked on the weatherunderground api forum, but Groovy is not widely known…

Hi, @TEWphotography, almost any Doña media rendered works, but some have some issues , check the confirmed working list Working Speakers (44 Devices Confirmed , 29 waiting Confirmation) last addition: Klipsch Stadium, Help Us to increase the list

Hi @mrmrmrmr, I think you must read a basic groovy tutorial, I suggest to read the UG API docs too

I read the WU api docs but what it says about this problem is that I should send the output format as json.
I don’t know how to do that in Groovy.
And the Groovy documentation does not tell it.

I can only see the last song title played on the speaker on ST device interface.
How can I get to the previous tracks ?

Btw, you wrote that an advantage of using original Sonos device instead of your Generic Media Renderer is “grouping” feature.
However, I don’t see that feature on Smartthings interface. Where is it ?

I have an interesting problem when I try to use Sonos speakers with Generic Media Renderer.
I deleted original sonos devices and added sonos speakers with media renderer connect.

I use Ivone with Turkish language and my access key is correct.

Now when I try the “speak” command, it does not work for a long phrase.
For example, if I make it speak “1 2 3 4” it works.
If I try “1 2 3 4 5 6” it does not work.

The same setup with my Android UPNP player works fine. It can play both “1 2 3 4 " and " 1 2 3 4 5 6”

What is the problem with long messages and Sonos speaker with media renderer ?

Btwi for speak command I use “media renderer events” app.

When I check on the Sonos app for the non-playing (long) message, I see error message “song is not encoded correctly”

When I get log from the API there is not much difference in the formed URI:

3a4b2073-ce2a-4787-ad3a-f148a28b8620  11:26:35 PM: trace
3a4b2073-ce2a-4787-ad3a-f148a28b8620  11:25:31 PM: trace

the first one is the long (non-playing) message, the last one is the shorter and working message.

Any ideas about the issue ?
could that be a wrong calculated duration ?

please note that this occurs on Ivona TTS
I tested also with English language on Ivona and it occurs with English as well.


Hi @mrmrmrmr, Sonos its a speaker who needs a different protocol to play some files, right now we use the x-rincon-mp3radio, you could test if removing this can help to play all the audio, I have not a sonos speaker, Some other users have help me to determine how sonos can play this kind of sources. you can check this and if ivonna can weork without the protocol change I can patch the device and smartapp


I’d be more than happy to help you. But I could not understand what you ask me to do.

I think you ask me to remove some parameter on the device handler. But what is it that I should remove ?

I just tried removing

/*        if (!model?.toLowerCase()?.contains("sonos")){
        	uri = uri.replace("x-rincon-mp3radio:","http:")
        } */

but it did not fix the problem.

In fact the problem only happens if the duration of the created message is longer. So I think it should be something other than the protocol. Am I wrong ?

btw, what I see in the media renderer event app is that the Ivona selection makes send the URI with “http” not “x-rincon-mp3radio”

see here:

def ttsIvona(message){
    def regionName = "us-east-1";
    def df = new java.text.SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'")
    def amzdate = df.format(new Date())
    def canonicalQueryString = "${URLEncoder.encode(message, "UTF-8").replaceAll(/\+/,'%20')}%3F&Input.Type=text%2Fplain&OutputFormat.Codec=MP3&OutputFormat.SampleRate=22050&Parameters.Rate=medium&Voice.Language=${voiceIvona.getAt(0..4)}&Voice.Name=${voiceIvona.getAt(6..-1)}&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=$ttsAccessKey%2F${amzdate.getAt(0..7)}%2F$regionName%2Ftts%2Faws4_request&X-Amz-Date=$amzdate&X-Amz-SignedHeaders=host";  
    "${now()}=${URLEncoder.encode("$canonicalQueryString&X-Amz-Signature=${hmac_sha256(hmac_sha256(hmac_sha256(hmac_sha256(hmac_sha256("AWS4$ttsSecretKey".bytes,amzdate.getAt(0..7)),regionName),"tts"),"aws4_request"), "AWS4-HMAC-SHA256\n$amzdate\n${amzdate.getAt(0..7)}/$regionName/tts/aws4_request\n${sha256Hash("GET\n/CreateSpeech\nInput.Data=$canonicalQueryString\nhost:tts.${regionName}\n\nhost\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")}").collect { String.format("%02x", it) }.join('')}")}"

so I changed that http with x-rincon-mp3radio

and now I can playlong messages from my sonos speaker

I can also play messages on my non-sonos player

BUT; if I try to add a mixture of them in the media renderer event (1 sonos and 1 non-sonos speaker) , it does not work.
I think that the app is creating only one URI even if there are 2 different devices in the list.
How can we make it create seperate URI for each ?


I have found a way; I created a copy of your app “media renderer connect” and your device handler "dlna player"
with names “media renderer connect sonos” and “dlna player sonos”

Then removed my sonos speakers and added with the new device type.

I removed the part where the device handler decides if the device model name includes sonos or not.
I made it static in each device handler.

Now if I play a long message, both device types can handle the URI because Sonos receives rincon-mp3radio and non-sonos receives http.

Please let me know if this approach is not good. Maybe it would be better (and easier ?) if we could handle different device types in the media renderer event app but I couldn’t find how to do that.


Now, I’ll come back to the weatherunderground problem. Please forgive me…

I read the WU api docs but what it says about this problem is that I should send the output format as json.
I don’t know how to do that in Groovy.
And the Groovy documentation does not tell it.

What can I do about it ?

ok. weatherunderground api is also solved.

the following code works (if anyone is interested - don’t forget to change APIKEY):

	def deviceListParams = [
    uri: "",
    path: "/api/___APIKEY___/forecast/lang:TR/q/TR/İstanbul.json",
    headers: ["Content-Type": "text/json", dataType : "jsonp"]
		def forecast = [:]
    	httpGet(deviceListParams) { resp ->
        log.debug "response:"
        log.debug resp
		if(resp.status == 200)
		   forecast =[0].fcttext_metric
			log.debug "http status: ${resp.status}"
	log.debug "forecast: ${forecast}"

This is excellent work! Would you willing to post the full modified code for the sonos that can play long text?

I am not a coder, so this would be much appreciated!

Does the weather underground read out in your chosen language?

Would I still need to delete the Smartthings sonos device handler?

I think it will be better if @ule would comment on this.
I made a workaround for myself and it uses static definitions (Turkish for language and my own api access credentials)

Also, I am not a coder ; I just copied ule’s work and made slight modifications. So , my code is not perfect. I really would like some coder to check if it is a good solution.

But if you want my code “as is” , I can of course share…

Ok thanks @mrmrmrmr, I just wanted your code as an example to see what lines to paste your modified code onto @ule original code!

Then I can code my desired language and set my personal weather underground location myself!


ok. just send me your email address with a private message; I will send my customized code to you.
Since, ule did not respond, I believe he doesn’t have any other suggestions.

If I select “scheduled time” on the weather announcement app , it is repeating the announcement until next minute and it takes like 15 times for a short announcement. Is there an option to disable it ?

“once per day” could solve this issue but on the other hand it would be nice to have it at least 2 or 3 times repeat.