-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Google Photos integration #124835
Add Google Photos integration #124835
Conversation
with patch( | ||
"homeassistant.components.google_photos.async_setup_entry", return_value=True | ||
) as mock_setup: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create a generic fixture for this because you have more places where you will use this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only currently used once so I avoided adding a fixture. How about adding when it's needed in future PRs? Unless you're saying it's needed in more cases in this PR.
Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍 |
Co-authored-by: Joost Lekkerkerker <[email protected]>
Thank you for the speedy high quality review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What use cases do you have in mind for media source?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use cases I am thinking would be useful are:
- display "favorites" or a shared album on a display
- use as a generic way to read media content for automations e.g. for an automation like sending to google generative ai vision service
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there any actions that give access to media sources? AFAIK, they are only used in the frontend for manually browsing so the only use case right now that I can think of is to browse your library for casting a single item to a media player.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is discussion here home-assistant/architecture#1079 so -- fair -- a future use case.
The upload service can return a media id in the service response, though, which could be used to form a media source identifier. The first half of this is a real use case, but the second half is not really:
- "Ok nabu, take a photo" (based on context of the device i'm speaking from)
- Automation calls camera snapshot
- Automation calls
google_photos.upload
with the snapshot filename, which returns a media id - Automation calls a display automation with the media id to show it somewhere
I may play around in a custom component as well, possibly exposing something like the service mentioned above, or code doing generally processing on media sources. I was thinking if there were useful integrations to call google_generative_ai_conversation.generate_content
with a media source, but maybe it doesn't make sense in core until there are more actions/hooks.
|
||
# Currently supports a single album of recent photos | ||
RECENT_PHOTOS_ALBUM = "recent" | ||
RECENT_PHOTOS_TITLE = "Recent Photos" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this to strings.json for localization?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can see how to do a one-off for google photos translations, however that doesn't appear to be a common pattern. I think if we want to support this it would make sense to do for all media sources. I spent about 45 minutes looking at what it might take to do this and am pausing as it looks quite involved given the current media player APIs. If there is a simple common pattern here i'm missing happy follow it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just looked at it too. It doesn't seem it's possible without a hack such as adding the string as an exception. Maybe introduce a generic strings section in strings.json and add a function similar to async_get_exception_message in helpers.translation? The functions could share most of the code. Do you think you could open a design discussion?
# Media Sources do not support paging, so we only show a subset of recent | ||
# photos when displaying the users library. We fetch a minimum of 50 photos | ||
# unless we run out, but in pages of 100 at a time given sometimes responses | ||
# may only contain a handful of items Fetches at least 50 photos. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment and constant name are confusing. I had to look at the code below to understand. Can you rename the constant and rephrase the comment? Or change the code below to truly have max 50 photos?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What i'm trying to hack around is if we set PAGE_SIZE = 50 you can get back like 10 photos (presumably due to server side filtering) and as a result spend a bunch of time on server side round trips. Given that context, have a suggestion for naming?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I understand the potential server side filtering that might return less photos than requested in the page.
But there is a punctuation missing in the comment, I think a period before "Fetches at least 50 photos", and it's confusing having MAX_ in the constant (and now max_photos in SpecialAlbumDetails) when it's actually MIN_, but only if you have that many photos in your library, otherwise it's a MAX_. Unfortunately I don't have a good suggestion.
""" | ||
width = media_item["mediaMetadata"]["width"] | ||
height = media_item["mediaMetadata"]["height"] | ||
key = "h" if height > width else "w" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make more sense to always have "h" here? If the image is shown fullscreen in a 4k screen we want max h2160. Similarly I assume the HA frontend when showing the grid of thumbnails caps the height? Depending on what resolution of thumbnails the HA frontend uses, maybe use both w and h? And maybe c too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did have a version setting h and w and couldn't convince myself what the right behavior is. I've updated to "h" since I agree the height is often what matters. For the full image, just setting it to be largeish in case someone wants a large image outside of the media player.
I can't convince myself what the right behavior here is or that c should be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think just h is better than longest edge, at least for the full screen case. I haven't tried this integration yet but HA frontend in the grid for other images seems to already do some cropping by centering the image. That's why I think ideally for thumbnails we would specify w, h, and c that match what HA frontend does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I trust your judgement here from your past experience optimizing photos on displays :) I'll experiment with it. I didn't notice the cropping until i saw some recent photos and they are cropped poorly (faces at top of the photo cut off -- didn't see if this is smart crop or not but it if is that would be useful)
media_class=MediaClass.IMAGE if not is_video else MediaClass.VIDEO, | ||
media_content_type=MediaType.IMAGE if not is_video else MediaType.VIDEO, | ||
title=media_item["filename"], | ||
can_play=is_video, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be True for images too? I just tried the Media tab in Home Assistant and I was able to "play" an image entity (FullyKiosk screenshot image entity) on the browser by displaying it and also casting it by connecting it to a Nest Hub. Have you tried that playing images and videos works on media players?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll give it a try. I may not understand what 'can_play' means.
Proposed change
Add Google Photos integration with an initial media source platform. The main parts of this integration have been copied from Google Tasks (config flow, client library, etc) with minor modernization updates.
Milestones for future PRs include:
Currently this requests scopes for read access to the entire library. As more features are added above, users can select which scopes they want for giving access to home assistant and the integration will respect those choices.
In the future we can consider expanding media sources to support paging and search to make them more useful for this integration.
Type of change
Additional information
Checklist
ruff format homeassistant tests
)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest
.requirements_all.txt
.Updated by running
python3 -m script.gen_requirements_all
.To help with the load of incoming pull requests: