# \[APP\]\[Pro\] Sonos (LocalAPI)

**URL:** <https://community.homey.app/t/app-pro-sonos-localapi/147985>\
**Category:** Apps\
**Tags:** app, homey-pro\
**Created:** [December 28, 2025, 12:48pm UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985 "2025-12-28T12:48:49Z")\
**Posts on this page:** 20\
**Page:** 16

<div class="post-metadata">

**Author:** ![SunBeech](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/sunbeech/32/111391_2.png) [@SunBeech](https://community.homey.app/u/SunBeech)\
**Post date:** [June 7, 2026, 9:47am UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/307 "2026-06-07T09:47:14Z")

</div>

> [@Crazy\_Avocado](#):
>
> 1. Artist & Track, when speakers are not playing anything, it always displays last played. Would love if it just shows nothing or it says not playing

Agree, though if changed, then please consider showing nothing, not a ‘nothing is playing’ text. I have various flows that depend on the contents of the Track tag, which I would have to change 😊. Leaving tags empty if there is not data would keep it consistent.

---

<div class="post-metadata">

**Author:** ![Amersfoort](https://avatars.discourse-cdn.com/v4/letter/a/94ad74/32.png) [@Amersfoort](https://community.homey.app/u/Amersfoort)\
**Post date:** [June 14, 2026, 9:36am UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/308 "2026-06-14T09:36:26Z")

</div>

What to do if multiple messages need to be played back-to-back?

For me, the first message stops and the second message starts playing. I have already tried using all sorts of variables, conditions, and timers to ensure that multiple messages are played consecutively, but that was too much hassle; it caused more disadvantages than advantages.

---

<div class="post-metadata">

**Author:** ![John\_William\_Brekke](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/john_william_brekke/32/111887_2.png) [@John\_William\_Brekke](https://community.homey.app/u/John_William_Brekke)\
**Post date:** [June 14, 2026, 8:23pm UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/309 "2026-06-14T20:23:30Z")

</div>

![image](https://us1.discourse-cdn.com/flex025/uploads/athom/original/3X/7/f/7f053e644af66e14d9dcd6cc9b16240bfdafae9d.png)

Sonos Beam is playing, Cloud says Beam is playing. Local says Beam isn’t playing, but Move 2 isn’t playing and Cloud says it is playing.. While Local says Move 2 isn’t playing..

But at the same time the Beam Local did switch track when i did…

 ![image](https://us1.discourse-cdn.com/flex025/uploads/athom/original/3X/2/e/2e62ef378538bb643091736b527a9df6b1feeef3.jpeg)

---

<div class="post-metadata">

**Author:** ![SunBeech](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/sunbeech/32/111391_2.png) [@SunBeech](https://community.homey.app/u/SunBeech)\
**Post date:** [June 14, 2026, 8:42pm UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/310 "2026-06-14T20:42:35Z")

</div>

Were those speakers perhaps powered down/switched off before?

If so, then restarting the Sonos app might help. I have a start-up flow that powers on my Sonos speakers, waits while they boot and then restarts the Sonos app.

Somehow both the Cloud and Local API app need some ‘help’ to re-initialize the playing state of a speaker after it was powered down.

---

<div class="post-metadata">

**Author:** ![John\_William\_Brekke](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/john_william_brekke/32/111887_2.png) [@John\_William\_Brekke](https://community.homey.app/u/John_William_Brekke)\
**Post date:** [June 14, 2026, 8:48pm UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/311 "2026-06-14T20:48:30Z")

</div>

I mean… my WiFi went off for a little.. So that might be the reason. I have Deco connected to Homey, so could probably make the apps restart when Deco comes back online.

---

<div class="post-metadata">

**Author:** ![Arie\_J\_Godschalk](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/arie_j_godschalk/32/63027_2.png) [@Arie\_J\_Godschalk](https://community.homey.app/u/Arie_J_Godschalk)\
**Post date:** [June 18, 2026, 2:00pm UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/312 "2026-06-18T14:00:57Z")

</div>

> [@Amersfoort](#):
>
> What to do if multiple messages need to be played back-to-back?

If by messages, you mean Text-To-Speech, I use the Google Services app. It knows how long the speech file is.

I then use Advanced Triggers to trigger the Google speech, which will play all speech in sequence (it has debounce/sequence flowcards). Even if you add other sounds in it with f.i. the Universal Media Player app.

---

<div class="post-metadata">

**Author:** ![Amersfoort](https://avatars.discourse-cdn.com/v4/letter/a/94ad74/32.png) [@Amersfoort](https://community.homey.app/u/Amersfoort)\
**Post date:** [June 18, 2026, 2:12pm UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/313 "2026-06-18T14:12:40Z")

</div>

Yes, Text-to-Speech messages.  
I had already created a script to determine the playback duration of an Text-to-Speech message MP3, but it remains complex. I link a base64 notification sound prior to the Text-to-Speech notification.

Could you share the Advanced Triggers settings and any other logic?

```auto
// Script: calculate_mp3_duration
// Argument: The full URL to your mp3 file (e.g., http://192.168.x.x:5080/file.mp3)

// Store the argument in a local variable
let url = args[0];

// Check if a URL was provided
if (!url) {
    throw new Error("No URL provided");
}

try {
    // Perform a 'HEAD' request. This only retrieves the metadata, not the entire file (fast execution)
    let response = await fetch(url, { method: 'HEAD' });
    
    // Check if the network response is successful
    if (!response.ok) {
        throw new Error(`Error fetching file: ${response.statusText}`);
    }

    // Retrieve the file size in bytes from the headers
    let bytes = response.headers.get('content-length');
    
    // Check if the file size header is present
    if (!bytes) {
        throw new Error("Could not determine file size.");
    }

    // Formula: Bytes / 12000 (since 96kbps / 8 bits = 12000 bytes/sec)
    // Round to 1 decimal place
    const bitrateBytesPerSec = 12000; 
    let durationSeconds = (parseInt(bytes) / bitrateBytesPerSec);
    
    // Format the final result as a number with one decimal place
    const result = Number(durationSeconds.toFixed(1));

    // Return the calculated duration in seconds
    return result;

} catch (err) {
    // Log the error and rethrow it
    console.error(err);
  
    throw err;
}

```

---

<div class="post-metadata">

**Author:** ![Amersfoort](https://avatars.discourse-cdn.com/v4/letter/a/94ad74/32.png) [@Amersfoort](https://community.homey.app/u/Amersfoort)\
**Post date:** [June 19, 2026, 12:55pm UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/314 "2026-06-19T12:55:50Z")

</div>

For me, this is the best possible result to prevent multiple TTS messages from being sent to Sonos, where the last message might cut off earlier playing messages.

 ![image](https://us1.discourse-cdn.com/flex025/uploads/athom/original/3X/8/9/89c9d3e1e0b5854007453473ada3f4430cdc8a6f.png)  
Since news headlines are also spoken aloud, I have also taken longer texts into account.

Can this primitive solution be improved?  
Most difficult to solve:

- wait time \> 30 seconds (time outs in scripts)
- variable wait times
- no Chronograph app to use, because the Advanced Trigger flow then thinks it has finished and starts the next text in the TTS queue.

---

<div class="post-metadata">

**Author:** ![Arie\_J\_Godschalk](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/arie_j_godschalk/32/63027_2.png) [@Arie\_J\_Godschalk](https://community.homey.app/u/Arie_J_Godschalk)\
**Post date:** [June 19, 2026, 3:34pm UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/315 "2026-06-19T15:34:15Z")

</div>

Well, the last part, after the HomeyScript, for the wait, you can replace with a wait function within the homeyscript i guess:

`await wait(2000);`

This being an await of 2000 milliseconds.

Not sure how long you can await for it, before the flowcard will timeout.

Perhaps use a second HS card with the above promise, and connect the error from itself, to the card itself (if the error was timeout)? Then it would just keep looping i guess till the delay has past.

One sec, working on example.

EDIT:

 ![image](https://us1.discourse-cdn.com/flex025/uploads/athom/original/3X/9/a/9a84381ed9b59273ea75f8cf8d09082567c431bc.png)

Just to give you an idea. Its still a horrible way, but i think its the most dynamic you can get in flowcards atm. and since its just a repeat of the exact same flowcard, i find it somewhat more easier for the eyes.

The 80000 is 80 seconds.  
Each flowcard will ‘error’ after 60 seconds. So just repeat this as many times as you would need minutes.

In this example, the first HS wait card times-out, but the second one completes after about 20sec.

---

<div class="post-metadata">

**Author:** ![Arie\_J\_Godschalk](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/arie_j_godschalk/32/63027_2.png) [@Arie\_J\_Godschalk](https://community.homey.app/u/Arie_J_Godschalk)\
**Post date:** [June 19, 2026, 4:19pm UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/316 "2026-06-19T16:19:40Z")

</div>

Oh, and you first row, when you trigger the Advanced Trigger for speech, set the await to no instead of yes. Else this card will timeout because it will take longer than 60sec. And there is no need to await for that card, since the Advanced Trigger will wait for itself since you put it on sequential 😉

---

<div class="post-metadata">

**Author:** ![SCLS79](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/scls79/32/160745_2.png) [@SCLS79](https://community.homey.app/u/SCLS79)\
**Post date:** [June 27, 2026, 5:48pm UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/317 "2026-06-27T17:48:23Z")

</div>

I can’t get the app to say anything. What am I doing wrong?

 ![IMG_0113](https://us1.discourse-cdn.com/flex025/uploads/athom/original/3X/d/3/d3a54f4fc03469eced73b43b63f8c8756ae60264.jpeg)

---

<div class="post-metadata">

**Author:** ![John\_William\_Brekke](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/john_william_brekke/32/111887_2.png) [@John\_William\_Brekke](https://community.homey.app/u/John_William_Brekke)\
**Post date:** [June 27, 2026, 5:49pm UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/318 "2026-06-27T17:49:42Z")

</div>

For this LocalAPI app you need a Azure TTS speech key. Use the official Sonos Cloud app by Athom for text to speech if you don’t want to pay. If you do have an Azure TTS speech key go in the Sonos LocalAPI app settings and enter it.

---

<div class="post-metadata">

**Author:** ![SCLS79](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/scls79/32/160745_2.png) [@SCLS79](https://community.homey.app/u/SCLS79)\
**Post date:** [June 27, 2026, 5:53pm UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/319 "2026-06-27T17:53:49Z")

</div>

Mmmmm, just edited ALL my flows. Going back then. Anoying…

---

<div class="post-metadata">

**Author:** ![John\_William\_Brekke](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/john_william_brekke/32/111887_2.png) [@John\_William\_Brekke](https://community.homey.app/u/John_William_Brekke)\
**Post date:** [June 27, 2026, 5:54pm UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/320 "2026-06-27T17:54:19Z")

</div>

Yeah..

---

<div class="post-metadata">

**Author:** ![Henk\_Renting](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/henk_renting/32/87634_2.png) [@Henk\_Renting](https://community.homey.app/u/Henk_Renting)\
**Post date:** [June 27, 2026, 6:32pm UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/321 "2026-06-27T18:32:24Z")

</div>

Ah, that is a pity.  
Have the same problem here.

Is there no other way to get Sonos to say something via this App, @xiutit?

Would have to revert to the Athom app as well then, paying for only this for Azure speech is a bit overdone… ☹

---

<div class="post-metadata">

**Author:** ![John\_William\_Brekke](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/john_william_brekke/32/111887_2.png) [@John\_William\_Brekke](https://community.homey.app/u/John_William_Brekke)\
**Post date:** [June 27, 2026, 6:35pm UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/322 "2026-06-27T18:35:13Z")

</div>

Personally, i just use a HomeyScript running Google translate speech URLs from Advanced flows, i start the HomeyScript with selected language and text. Then a Play URL with volume card from the Sonos LocalAPI plays the TTS.

---

<div class="post-metadata">

**Author:** ![xiutit](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/xiutit/32/175860_2.png) [@xiutit](https://community.homey.app/u/xiutit)\
**Post date:** [June 27, 2026, 6:50pm UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/323 "2026-06-27T18:50:08Z")

</div>

I’m working on a change for a next version where Azure TTS will work “out of the box”, without needing to configure your own Azure speech key. I’m going to sponsor the Azure costs myself/business-wise, with some kind of rate limiting in place to prevent abuse or accidental excessive usage.

I do need to monitor how much it is actually used once released, to make sure the costs stay reasonable.

---

<div class="post-metadata">

**Author:** ![smarthomesven](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/smarthomesven/32/79712_2.png) [@smarthomesven](https://community.homey.app/u/smarthomesven)\
**Post date:** [June 28, 2026, 1:18am UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/324 "2026-06-28T01:18:12Z")

</div>

Just a recommendation: maybe you can also add a “cache” of mp3’s (within the userdata folder or on a VPS/server), this prevents users who frequently use the same text from sending unnecessary API requests

---

<div class="post-metadata">

**Author:** ![Henk\_Renting](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/henk_renting/32/87634_2.png) [@Henk\_Renting](https://community.homey.app/u/Henk_Renting)\
**Post date:** [June 28, 2026, 6:01am UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/325 "2026-06-28T06:01:58Z")

</div>

Can you give an example of how to do this? Or point us to an example?

---

<div class="post-metadata">

**Author:** ![DirkG](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/dirkg/32/118897_2.png) [@DirkG](https://community.homey.app/u/DirkG)\
**Post date:** [June 28, 2026, 11:04am UTC](https://community.homey.app/t/app-pro-sonos-localapi/147985/326 "2026-06-28T11:04:39Z")

</div>

> [@SCLS79](#):
>
> Mmmmm, just edited ALL my flows. Going back then. Anoying…

You could have installed and run both Sonos apps at the same time and tried out the Sonos (LocalAPI) app first… 🤷🏼‍♂️

[Previous page](https://community.homey.app/t/app-pro-sonos-localapi/147985.md?page=15)

[Next page](https://community.homey.app/t/app-pro-sonos-localapi/147985.md?page=17)
