Is there any way to force a state update on an entity?
Take a light for example. If I execute a light.turn_on action, but the data provided matches the already existing state, then the state is not updated. But I want the state to always update, because I want the light’s context.id to match that of my automation, so that the next time the automation runs I can detect whether the light is under the automation’s control, without resorting to helpers etc. Is this possible?
I found a homeassistant.update_entity action but that doesn’t seem to do much of anything? Well It does change the entity’s last_reported timestamp but not much else. (For a completely different use case I had hoped that it would also run the entity’s internal _update() function, which would work as a workaround for a bug in Sonos’s Spotify Connect implementation, but no such luck…)
Not sure how that will help my scenario? This is not about the state displayed on the frontend being out of date, but about forcing/tricking the backend state machine to register a “change” even though an actual change ideally was never made. As already explained my goal is for every entity that a certain automation controls to always get an updated context.id value each time the automation runs.
My best idea right now would be to perhaps make a tiny unnoticeable brightness change of 1. If the change is made in the “optimal” direction, it shouldn’t even be registered on the dashboard as brightness is only displayed as an integer percentage.
This particular bug is that when seeking/scrubbing the timeline, either manually in the HASS UI or by using the media_player.media_seek action, the player’s media_position and media_position_updated_at attributes are not updated. This only happens with Spotify Connect specifically, i.e. when you start playback from Spotify. If you start playback from the Sonos client (even with Spotify as source) the updated media position is correctly broadcasted from Sonos to HASS. This is either a bug on Sonos’s end or in whatever library Spotify has given them to implement Connect.
This was an issue for me as I was making a blueprint for a remote control (IKEA Symfonisk) where I wanted the back button to behave like it normally does on every other media player other than HASS. I.e. if you are not already at the very beginning of the track, then first go back to the beginning rather than immediately skip all the way to the previous track.
If I modified the Python integration code to manually execute an _update() at the end of the call for seek then the integration will ask Sonos for an update which it will correctly receive. I had hoped that homeassistant.update_entity would also accomplish this, but no luck. My current workaround is to first pause or start playback depending on the player’s current state, which makes Sonos broadcast a position update, do the seek, then either resume playback or re-pause again. Only if Spotify Connect on Sonos is detected specifically of course.
In this automation do you also call the update entity command? Context is only assigned if a change was made. This is what I assume you are doing and while update may not register as a change, reloading it might.
Okay, now I see what you mean. But what is the config entry for a light, just the encapsulating device or the whole integration? I tried the homeassistant.reload_config_entry and targeted just the one entity id of a single light but it looks like all entities on the integration got an updated state…
Yes, unfortunately that’s what I did. I only fed it a single entity id. Just confirmed with the Jinja config_entry_id filter that the id is the same for all lights within the same integration, so sadly reloading the config entry will update the state of many more lights than intended (and would prevent other automations on the same blueprint from functioning correctly).
@Mayhem_SWE
I think the reason for that is to cut down on the number of state updates, meaning it only updates every 30 seconds instead of every second (for the position change). It manually keeps track of the current position by subtracting current time offset from media_position_updated_at timestamp. Most of the front-end media players (my SpotifyPlus Card included) keep track of position that way, updating from real-time data media_position_updated_at when the update event actually fires and a Spotify Web API request is made to get play state.
My SpotifyPlus Integration does allow you to change the update interval to a minimum of 4 seconds (to 60 max) if you want. It also supports Sonos device playback functions natively, including the skip previous functionality returning to start of track (if less than 8 seconds into the track) or skipping to previous track (if more than 8 seconds into the track).
Yes, I know how those two attributes work/are supposed to work. If playing continuously they will normally only update when the track changes, but they should also update immediately on pause, play or seek or the correct position can no longer be calculated. For any other source Sonos will correctly update the attributes on play/pause/next/previous/seek, and for Spotify Connect it will still correctly update on play/pause/next/previous. It just will not do so on seek specifically.
The SpotifyPlus Integration does update the media_position_updated_at for all deck control functions (pause, seek, resume, etc) at the point the request was made, as well as every second for 4 seconds afterward (a “command update” window if you will). Note that this update only occurs if the deck control function was requested via the HA SpotifyPlus integration media player though - any changes made from other players (e.g. Spotify Desktop Player, Web, Mobile) will not be recognized until the 30 second update window.
Until Spotify gives us web-socket support (to notify us of player events) that’s the best we can do (with polling).