Skip to content
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

Show the sensor state using the coordinatordata instead of initial data #94008

Merged
merged 3 commits into from
Jun 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 6 additions & 11 deletions homeassistant/components/youtube/entity.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
"""Entity representing a YouTube account."""
from __future__ import annotations

from typing import Any

from homeassistant.const import ATTR_ID
from homeassistant.helpers.device_registry import DeviceEntryType
from homeassistant.helpers.entity import DeviceInfo, EntityDescription
from homeassistant.helpers.update_coordinator import CoordinatorEntity
Expand All @@ -21,20 +18,18 @@ def __init__(
self,
coordinator: YouTubeDataUpdateCoordinator,
description: EntityDescription,
channel: dict[str, Any],
channel_id: str,
) -> None:
"""Initialize a Google Mail entity."""
"""Initialize a YouTube entity."""
super().__init__(coordinator)
self.entity_description = description
self._attr_unique_id = (
f"{coordinator.config_entry.entry_id}_{channel[ATTR_ID]}_{description.key}"
f"{coordinator.config_entry.entry_id}_{channel_id}_{description.key}"
)
self._channel_id = channel_id
self._attr_device_info = DeviceInfo(
entry_type=DeviceEntryType.SERVICE,
identifiers={
(DOMAIN, f"{coordinator.config_entry.entry_id}_{channel[ATTR_ID]}")
},
identifiers={(DOMAIN, f"{coordinator.config_entry.entry_id}_{channel_id}")},
manufacturer=MANUFACTURER,
name=channel[ATTR_TITLE],
name=coordinator.data[channel_id][ATTR_TITLE],
)
self._channel = channel
14 changes: 9 additions & 5 deletions homeassistant/components/youtube/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ async def async_setup_entry(
COORDINATOR
]
async_add_entities(
YouTubeSensor(coordinator, sensor_type, channel)
for channel in coordinator.data.values()
YouTubeSensor(coordinator, sensor_type, channel_id)
for channel_id in coordinator.data
for sensor_type in SENSOR_TYPES
)

Expand All @@ -84,16 +84,20 @@ class YouTubeSensor(YouTubeChannelEntity, SensorEntity):
@property
def native_value(self) -> StateType:
"""Return the value reported by the sensor."""
return self.entity_description.value_fn(self._channel)
return self.entity_description.value_fn(self.coordinator.data[self._channel_id])

@property
def entity_picture(self) -> str:
"""Return the value reported by the sensor."""
return self.entity_description.entity_picture_fn(self._channel)
return self.entity_description.entity_picture_fn(
self.coordinator.data[self._channel_id]
)

@property
def extra_state_attributes(self) -> dict[str, Any] | None:
"""Return the extra state attributes."""
if self.entity_description.attributes_fn:
return self.entity_description.attributes_fn(self._channel)
return self.entity_description.attributes_fn(
self.coordinator.data[self._channel_id]
)
return None
35 changes: 29 additions & 6 deletions tests/components/youtube/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ def execute(self) -> dict[str, Any]:
class MockChannels:
"""Mock object for channels."""

def __init__(self, fixture: str):
"""Initialize mock channels."""
self._fixture = fixture

def list(
self,
part: str,
Expand All @@ -28,41 +32,60 @@ def list(
maxResults: int | None = None,
) -> MockRequest:
"""Return a fixture."""
return MockRequest(fixture="youtube/get_channel.json")
return MockRequest(fixture=self._fixture)


class MockPlaylistItems:
"""Mock object for playlist items."""

def __init__(self, fixture: str):
"""Initialize mock playlist items."""
self._fixture = fixture

def list(
self,
part: str,
playlistId: str,
maxResults: int | None = None,
) -> MockRequest:
"""Return a fixture."""
return MockRequest(fixture="youtube/get_playlist_items.json")
return MockRequest(fixture=self._fixture)


class MockSubscriptions:
"""Mock object for subscriptions."""

def __init__(self, fixture: str):
"""Initialize mock subscriptions."""
self._fixture = fixture

def list(self, part: str, mine: bool, maxResults: int | None = None) -> MockRequest:
"""Return a fixture."""
return MockRequest(fixture="youtube/get_subscriptions.json")
return MockRequest(fixture=self._fixture)


class MockService:
"""Service which returns mock objects."""

def __init__(
self,
channel_fixture: str = "youtube/get_channel.json",
playlist_items_fixture: str = "youtube/get_playlist_items.json",
subscriptions_fixture: str = "youtube/get_subscriptions.json",
):
"""Initialize mock service."""
self._channel_fixture = channel_fixture
self._playlist_items_fixture = playlist_items_fixture
self._subscriptions_fixture = subscriptions_fixture

def channels(self) -> MockChannels:
"""Return a mock object."""
return MockChannels()
return MockChannels(self._channel_fixture)

def playlistItems(self) -> MockPlaylistItems:
"""Return a mock object."""
return MockPlaylistItems()
return MockPlaylistItems(self._playlist_items_fixture)

def subscriptions(self) -> MockSubscriptions:
"""Return a mock object."""
return MockSubscriptions()
return MockSubscriptions(self._subscriptions_fixture)
6 changes: 6 additions & 0 deletions tests/components/youtube/fixtures/get_channel_2.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@
"totalItemCount": 6178,
"newItemCount": 0,
"activityType": "all"
},
"statistics": {
"viewCount": "214141263",
"subscriberCount": "2290000",
"hiddenSubscriberCount": false,
"videoCount": "5798"
}
}
]
Expand Down
215 changes: 215 additions & 0 deletions tests/components/youtube/fixtures/get_playlist_items_2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
{
"kind": "youtube#playlistItemListResponse",
"etag": "O0Ah8Wd5pUD2Gsv-n0A42RDRcX8",
"nextPageToken": "EAAaBlBUOkNBVQ",
"items": [
{
"kind": "youtube#playlistItem",
"etag": "pU0v49jXONlQfIJEX7ldINttRYM",
"id": "VVVfeDVYRzFPVjJQNnVaWjVGU005VHR3LmhsZUxsY0h3UUxN",
"snippet": {
"publishedAt": "2023-05-10T22:30:48Z",
"channelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw",
"title": "Google I/O 2023 Developer Keynote in 5 minutes",
"description": "Discover what’s new from Google, including top takeaways and highlights announced at Google I/O 2023. From deep investments in the largest mobile platform, to breakthroughs in AI, learn about the latest capabilities in mobile, web, Cloud, AI, and more. \n\nCatch the full Developer Keynote →https://goo.gle/dev-keynote-23 \nWatch all the Keynotes from Google I/O 2023→ https://goo.gle/IO23_keynotes\nWatch all the Google I/O 2023 Sessions → https://goo.gle/IO23_all \n\n0:00 - Welcome\n0:25 - MakerSuite\n0:49 - Android Studio Bot\n1:38 - Large screens\n2:04 - Wear OS\n2:34 - WebGPU\n2:58 - Baseline\n3:27 - MediaPipe\n3:57 - Duet AI for Google Cloud\n4:59 - Closing\n\nSubscribe to Google Developers → https://goo.gle/developers\n\n#GoogleIO #developers",
"thumbnails": {
"default": {
"url": "https://i.ytimg.com/vi/hleLlcHwQLM/default.jpg",
"width": 120,
"height": 90
},
"medium": {
"url": "https://i.ytimg.com/vi/hleLlcHwQLM/mqdefault.jpg",
"width": 320,
"height": 180
},
"high": {
"url": "https://i.ytimg.com/vi/hleLlcHwQLM/hqdefault.jpg",
"width": 480,
"height": 360
},
"standard": {
"url": "https://i.ytimg.com/vi/hleLlcHwQLM/sddefault.jpg",
"width": 640,
"height": 480
},
"maxres": {
"url": "https://i.ytimg.com/vi/hleLlcHwQLM/maxresdefault.jpg",
"width": 1280,
"height": 720
}
},
"channelTitle": "Google for Developers",
"playlistId": "UU_x5XG1OV2P6uZZ5FSM9Ttw",
"position": 1,
"resourceId": {
"kind": "youtube#video",
"videoId": "hleLlcHwQLM"
},
"videoOwnerChannelTitle": "Google for Developers",
"videoOwnerChannelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw"
},
"contentDetails": {
"videoId": "hleLlcHwQLM",
"videoPublishedAt": "2023-05-10T22:30:48Z"
}
},
{
"kind": "youtube#playlistItem",
"etag": "fht9mKDuIBXcO75k21ZB_gC_4vM",
"id": "VVVfeDVYRzFPVjJQNnVaWjVGU005VHR3LmxNS2p0U0Z1amN3",
"snippet": {
"publishedAt": "2023-05-10T21:25:47Z",
"channelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw",
"title": "What's new in Google Pay and Wallet in less than 1 minute",
"description": "A quick recap on the latest updates to Google Pay and Wallet from Google I/O 2023.\n\nTo learn more about what's new in Google Pay and Wallet, check out the keynote → https://goo.gle/IO23_paywallet\n\nSubscribe to Google Developers → https://goo.gle/developers\n\n#GoogleIO",
"thumbnails": {
"default": {
"url": "https://i.ytimg.com/vi/lMKjtSFujcw/default.jpg",
"width": 120,
"height": 90
},
"medium": {
"url": "https://i.ytimg.com/vi/lMKjtSFujcw/mqdefault.jpg",
"width": 320,
"height": 180
},
"high": {
"url": "https://i.ytimg.com/vi/lMKjtSFujcw/hqdefault.jpg",
"width": 480,
"height": 360
},
"standard": {
"url": "https://i.ytimg.com/vi/lMKjtSFujcw/sddefault.jpg",
"width": 640,
"height": 480
},
"maxres": {
"url": "https://i.ytimg.com/vi/lMKjtSFujcw/maxresdefault.jpg",
"width": 1280,
"height": 720
}
},
"channelTitle": "Google for Developers",
"playlistId": "UU_x5XG1OV2P6uZZ5FSM9Ttw",
"position": 2,
"resourceId": {
"kind": "youtube#video",
"videoId": "lMKjtSFujcw"
},
"videoOwnerChannelTitle": "Google for Developers",
"videoOwnerChannelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw"
},
"contentDetails": {
"videoId": "lMKjtSFujcw",
"videoPublishedAt": "2023-05-10T21:25:47Z"
}
},
{
"kind": "youtube#playlistItem",
"etag": "nYKXoKd8eePAZ_xFa3dL5ZmvM5c",
"id": "VVVfeDVYRzFPVjJQNnVaWjVGU005VHR3LmMwbXFCdVhQcnBB",
"snippet": {
"publishedAt": "2023-05-10T20:47:57Z",
"channelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw",
"title": "Developers guide to BigQuery export for Google Analytics 4",
"description": "With Google Analytics 4 (GA4), anyone can set up export of granular measurement data to BigQuery.\n\nIn this session, you will learn how to use the BigQuery export for solving business problems, doing complex reporting, implementing advanced use cases with ML models, and creating custom audiences by joining with first-party data. You can use this framework for detailed or large-scale data analysis. We will also share some best practices to get you started.\n\nResources:\nDevelopers guide to BigQuery export for Google Analytics 4 → https://goo.gle/ga-io23\n\nSpeaker: Minhaz Kazi\n\nWatch more:\nWatch all the Technical Sessions from Google I/O 2023 → https://goo.gle/IO23_sessions\nWatch more Mobile Sessions → https://goo.gle/IO23_mobile\nWatch more Web Sessions → https://goo.gle/IO23_web\nAll Google I/O 2023 Sessions → https://goo.gle/IO23_all\n\nSubscribe to Google Developers → https://goo.gle/developers\n\n#GoogleIO",
"thumbnails": {
"default": {
"url": "https://i.ytimg.com/vi/c0mqBuXPrpA/default.jpg",
"width": 120,
"height": 90
},
"medium": {
"url": "https://i.ytimg.com/vi/c0mqBuXPrpA/mqdefault.jpg",
"width": 320,
"height": 180
},
"high": {
"url": "https://i.ytimg.com/vi/c0mqBuXPrpA/hqdefault.jpg",
"width": 480,
"height": 360
},
"standard": {
"url": "https://i.ytimg.com/vi/c0mqBuXPrpA/sddefault.jpg",
"width": 640,
"height": 480
},
"maxres": {
"url": "https://i.ytimg.com/vi/c0mqBuXPrpA/maxresdefault.jpg",
"width": 1280,
"height": 720
}
},
"channelTitle": "Google for Developers",
"playlistId": "UU_x5XG1OV2P6uZZ5FSM9Ttw",
"position": 3,
"resourceId": {
"kind": "youtube#video",
"videoId": "c0mqBuXPrpA"
},
"videoOwnerChannelTitle": "Google for Developers",
"videoOwnerChannelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw"
},
"contentDetails": {
"videoId": "c0mqBuXPrpA",
"videoPublishedAt": "2023-05-10T20:47:57Z"
}
},
{
"kind": "youtube#playlistItem",
"etag": "--gb8pSHDwp9c-fyjhZ0K2DklLE",
"id": "VVVfeDVYRzFPVjJQNnVaWjVGU005VHR3Ll9uOXh3dVRPUmFz",
"snippet": {
"publishedAt": "2023-05-10T20:46:29Z",
"channelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw",
"title": "What's new in Google Home - American Sign Language",
"description": "To watch this Session without American Sign Language (ASL) interpretation, please click here → https://goo.gle/IO23_homekey\n\nDiscover how your connected devices can do more with Google Home using Matter and Automations.\n\nResources:\nGoogle Home Developer Center → https://goo.gle/3KcD5xr\n\nDiscover how your connected devices can do more with Google Home using Matter and Automations\nGoogle Home APIs Developer Preview → https://goo.gle/3UakRl0\nAutomations Developer Preview → https://goo.gle/3KgEcMy\n\nSpeakers: Taylor Lehman, Indu Ramamurthi\n\nWatch more:\nWatch more Mobile Sessions → https://goo.gle/IO23_mobile\nAll Google I/O 2023 Sessions → https://goo.gle/IO23_all\n\nSubscribe to Google Developers → https://goo.gle/developers\n\n#GoogleIO",
"thumbnails": {
"default": {
"url": "https://i.ytimg.com/vi/_n9xwuTORas/default.jpg",
"width": 120,
"height": 90
},
"medium": {
"url": "https://i.ytimg.com/vi/_n9xwuTORas/mqdefault.jpg",
"width": 320,
"height": 180
},
"high": {
"url": "https://i.ytimg.com/vi/_n9xwuTORas/hqdefault.jpg",
"width": 480,
"height": 360
},
"standard": {
"url": "https://i.ytimg.com/vi/_n9xwuTORas/sddefault.jpg",
"width": 640,
"height": 480
},
"maxres": {
"url": "https://i.ytimg.com/vi/_n9xwuTORas/maxresdefault.jpg",
"width": 1280,
"height": 720
}
},
"channelTitle": "Google for Developers",
"playlistId": "UU_x5XG1OV2P6uZZ5FSM9Ttw",
"position": 4,
"resourceId": {
"kind": "youtube#video",
"videoId": "_n9xwuTORas"
},
"videoOwnerChannelTitle": "Google for Developers",
"videoOwnerChannelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw"
},
"contentDetails": {
"videoId": "_n9xwuTORas",
"videoPublishedAt": "2023-05-10T20:46:29Z"
}
}
],
"pageInfo": {
"totalResults": 5798,
"resultsPerPage": 5
}
}