Creating a YouTube Thumbnail Sensor in Home Assistant

Hey, I’ve been playing with this again. Here’s what I’ve come up with so far

apperently yt_dlp is available in home assistant so just

import yt_dlp
import json

URL = "https://www.youtube.com/feed/history"

ydl_opts = {
    "cookiefile": "/config/python/.cookies.txt",
    "skip_download": True,
    "playlist_items": "1",
    "quiet": True,
    "no_warnings": True,
}

with yt_dlp.YoutubeDL(ydl_opts) as ydl:
    info = ydl.extract_info(URL, download=False)
    data = ydl.sanitize_info(info)
    entry = data.get("entries", [data])[0]
    print(
        json.dumps(
            {
                "channel": entry.get("channel"),
                "title": entry.get("fulltitle"),
                "video_id": entry.get("id"),
                "thumbnail": entry.get("thumbnail"),
                "original_url": entry.get("original_url"),
            },
            indent=2,
        )
    )

and to “force” set entity_picture on the media player

import argparse
import requests
from secrets import get_secret

HOST = get_secret("ha_host")
TOKEN = get_secret("ha_token")


def update_entity_picture(entity_id, entity_picture):
    url = f"{HOST}/api/states/{entity_id}"
    headers = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        data = response.json()
        data["attributes"]["entity_picture"] = entity_picture
        response = requests.post(url, headers=headers, json=data)
        if response.status_code == 200:
            print("ok")
        else:
            print("Error posting update: ", response.text)
    else:
        print("Error retrieving state: ", response.text)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="update entity_picture")
    parser.add_argument("--entity_id", required=True, help="entity_id")
    parser.add_argument("--entity_picture", required=True, help="entity_picture")
    args = parser.parse_args()
    update_entity_picture(args.entity_id, args.entity_picture)

alias: Set youtube entity_picture
triggers:
  - trigger: state
    entity_id:
      - media_player.sovrum
      - media_player.vardagsrum
    to:
      - playing
      - paused
conditions:
  - condition: template
    value_template: >
      {% set entity_id = trigger.entity_id %}
      {% set youtube = 'sensor.youtube_thumbnail' %}

      {{ is_state_attr(entity_id, 'app_id', 'com.google.ios.youtube')
      and (state_attr(entity_id, 'media_artist') != state_attr(youtube, 'channel')) 
      and (state_attr(entity_id, 'media_title') != state_attr(youtube, 'title')) }}
actions:
  - action: homeassistant.update_entity
    data:
      entity_id:
        - sensor.youtube_thumbnail
  - action: shell_command.set_entity_picture
    data:
      entity_id: >
        {{ trigger.entity_id }}
      entity_picture: >
        {{ states('sensor.youtube_thumbnail') }}
mode: single

still some quirks, like pausing the media player will remove entity_picture, and because it’s not a session every yt fetch takes like 3 seconds. I’ve tried a container with GitHub - LuanRT/YouTube.js: A JavaScript client for YouTube's private API, known as InnerTube. and that is much faster

1 Like