Ah- there’s so many posts I hadn’t read far enough. For those readers who are also a tad lazy who want background on the red exclamation device connection problem, read back to posts from December 2025.
I don’t think the device awakening problem is necessarily it- because all my devices still appear in my Connect list. For reference here, my web browser is my work computer (I’m currently in the office). My computer hasn’t played anything since last night- so definitely an expired token- but still lists. My phone didn’t list at all until I opened the app, at which point it listed and I can swap playback to it. None of these devices are on the same network.
Now over the weekend when I was fiddling with this, availability for playback was dropping within seconds of swapping playback elsewhere- far sooner than a token would expire. The Connect support page does say same wifi for the first connection, but farther down mentions once we’re logged in using credentials we should see the device even if not on the same wifi (the behavior I’m seeing). I’m not convinced tokens are the answer.
There are no second accounts involved, nor other people connecting.
Now the extra funky part- I tried using the official app to transfer playback from my browser to my phone (no playback in 12+ hrs) and it worked flawlessly. So if all else fails, maybe chat with a Athem employee to see how their app is doing it? I know they love to support community developers.
An additional note: I took a moment to have Claude (my work has the super advanced model) read the entire Web API Reference, this forum, AND the whole github, and it found a solution. Maybe. Try giving this a shot:
After reading through the app source code (GitHub), here’s what I found:
How devices work now: The Spotify device ID is stored permanently at pairing time. Every 15 seconds, _sync() calls GET /me/player/devices, looks for that stored ID, and checks is_active. If the device isn’t in the response OR is_active is false, Homey marks it unavailable (red exclamation mark). The device ID is never refreshed after pairing.
The app never calls Transfer Playback. It passes the stored device_id as a query parameter to PUT /me/player/play (Start/Resume Playback), which behaves inconsistently — often returning 404 if the device isn’t already the active player. The actual Transfer Playback endpoint is PUT /me/player, which is designed to wake up and activate a known device. The app never uses it.
Three problems:
-
No Transfer Playback — The app can’t activate an inactive device. PUT /me/player with {"device_ids": ["<id>"], "play": true} is the correct way to push playback to a device that Spotify’s servers know about but isn’t currently active. This is likely how the official Homey Spotify app can swap to devices that this app can’t see.
-
Availability check is too strict — Gating on is_active means the device shows unavailable anytime it’s not the current playback target, even if Spotify’s servers still know about it. The check could be loosened to just verify the device exists in the response, or removed entirely and let Transfer Playback fail gracefully with a user-facing error.
-
Frozen device IDs — Spotify can reassign device IDs when hardware reconnects. Since the stored ID never updates, the Homey device can become permanently broken with no fix other than deleting and re-pairing. A periodic ID refresh (matching on device name/type) would prevent this.
Suggested fix: Call PUT /me/player to transfer playback before issuing play commands, loosen the availability check, and add device ID refresh logic.
Now while I have Claude open… I asked about the play/pause cards toggling instead of being absolute commands:
-
The play/pause handler toggles a locally cached boolean (this.devicePlaying = !this.devicePlaying) instead of calling the API endpoints directly. Since the cache only syncs every 15 seconds, if Spotify’s state changes outside Homey in that window, the toggle fires the wrong command.
-
Fix: “Play” should always call /me/player/play, “Pause” should always call /me/player/pause. Skip the boolean entirely.
And as for the not finding all playlists problem:
getMyPlaylists() calls GET /me/playlists?limit=50 once with no offset and no pagination loop. If you have more than 50 playlists, the rest are silently dropped. Spotify-generated playlists like Discover Weekly and Daily Mix likely exist in the library but fall outside that first page of 50.
I do hope this is helpful! I’m a mechanical engineer, not software, so it’s difficult to verify if anything is a genuine fix. If it’s garbage, let me know.
Thank you for the support, love the app!