带有覆盆子PI和电子纸显示的Spotify Desk小部件
#python #raspberrypi #epaper #spotify

我一直在寻找一个有趣的编码项目来在空闲时间工作,所以我记得我有一个2.7英寸的电子纸显示,并决定最终使用它。作为整天在Spotify上听音乐的人,我发现自己不断打开该应用程序,以检查我喜欢的歌曲的当前标题和艺术家。这是当我拥有制作Spotify电子纸桌窗口小部件的very original idea时。

为了构建这个项目,我使用了我在另一个PI中运行的本地家庭助理。每当播放一首新歌曲时,自动化就会触发,然后将网络钩发射到我的Raspberry Pi 4. Webhook执行Python脚本,从Home Assistant的API中检索当前的歌曲信息,然后使用Python PIL库,我们可以使用python pil库来创建模板专辑封面,最后我们在电子纸显示上渲染。

这是您如何构建这个的总体一般指南:

  • 设置带有Waveshare电子纸显示的覆盆子Pi。
  • 安装和配置本地Home Assistant实例。
  • 创建一个Spotify开发人员帐户并注册一个新应用以获取必要的API密钥。
  • 在您的家庭助理中配置Spotify集成。
  • 创建一个家庭助理自动化脚本,每当在Spotify上播放新歌曲时,会触发RESTFULS命令。

注册Restful命令作为家庭助手配置文件中的服务:

rest_command:
 spotify_epaper:
 url: "http://YOURLOCAL_RASPBERRYPI/hooks/spotify-e-paper-webhook"
 verify_ssl: false
 method: GET

家庭助理自动化脚本非常简单:

alias: Spotify ePaper Automation
description: ""
trigger:
 — platform: state
 entity_id:
 — media_player.spotify
 attribute: media_title
condition: []
action:
 — service: rest_command.spotify_epaper
 data: {}
mode: single

此Python脚本用epd2in7.EPD()epd2in7 is provided by Waveshare)初始化了电子纸显示。字体已加载,并使用Image.new()创建新图像。 ImageDraw.Draw()方法用于创建矩形和文本。

然后,脚本使用请求库将请求发送到本地家庭助理实例,以检索天气和Spotify信息。然后,使用draw.text()draw.multiline_text()处理数据并将其粘贴到图像上。

最后,图像显示在带有epd.display()的电子纸上,并将显示器放在睡眠状态以用epd.sleep()节省电源。

#!/usr/bin/python
# -*- coding:utf-8 -*-
import sys
import os
picdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'pic')
libdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'lib')
if os.path.exists(libdir):
    sys.path.append(libdir)

import logging
from waveshare_epd import epd2in7
import time
from PIL import Image, ImageDraw, ImageFont
import traceback
import requests, json
from datetime import date

today = date.today()
logging.basicConfig(level=logging.DEBUG)

try:
    logging.info("Start...")

    epd = epd2in7.EPD()
    logging.info("Init and Clear")
    epd.init()
    epd.Clear(0xFF)

    font15 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 15)
    font20 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 20)
    font25 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 25)

    # Create the image
    logging.info("Create the image...")
    image = Image.new('1', (epd.height, epd.width), 255)
    draw = ImageDraw.Draw(image)
    draw.rectangle([(121,0),(270,119)],fill = 0)

    weather_url = "http://HOME_ASSISTANT_LOCAL:8123/api/states/weather.forecast_home"
    weather_headers = {
        "Authorization": "Bearer TOKEN",
        "content-type": "application/json",
    }

    weather_response = requests.get(weather_url, headers=weather_headers)

    if weather_response.status_code == 200:
        print('Connection to Weather successful.')
        # get data in json format
        data = weather_response.json()

        attributes = data['attributes']
        state = data['state']

        temperature = attributes['temperature']
        temperature_unit = attributes['temperature_unit']

        # Set strings to be printed to screen
        date = today.strftime("%A %d")
        draw.multiline_text((130, 60), str(temperature) + temperature_unit + "\n" + date, font=font25, fill= 1)

    spotify_url = "http://HOME_ASSISTANT_LOCAL:8123/api/states/media_player.spotify"
    spotify_headers = {
        "Authorization": "Bearer TOKEN",
        "content-type": "application/json",
    }

    spotify_response = requests.get(spotify_url, headers=spotify_headers)

    if spotify_response.status_code == 200:
        print('Connection to Spotify successful.')
        # get data in json format
        data = spotify_response.json()

        attributes = data['attributes']
        media_title = attributes['media_title']
        media_artist = attributes['media_artist']
        entity_picture = attributes['entity_picture']

        # get album cover and save it as png file
        img_url = 'http://HOME_ASSISTANT_LOCAL:8123' + entity_picture
        path = os.path.join(picdir, 'album_cover.png')
        response = requests.get(img_url)
        if response.status_code == 200:
            with open(path, 'wb') as f:
                f.write(response.content)

        # Open album image, resize and paste 
        album_cover = Image.open(os.path.join(picdir, 'album_cover.png'))
        album_cover.thumbnail((120, 120), reducing_gap=2.0)
        image.paste(album_cover, (0,0))  

        # Set strings to be printed to screen
        draw.text((5, 120), media_title, font = font25, fill = 0)
        draw.text((5, 150), media_artist, font = font15, fill = 0)


    epd.display(epd.getbuffer(image))

    logging.info("Go to sleep and save power...")
    epd.sleep()

except IOError as e:
    logging.info(e)

except KeyboardInterrupt:    
    logging.info("ctrl + c:")
    epd2in7.epdconfig.module_exit()
    exit()

Image description

这个项目非常有趣,而且非常容易实现。我喜欢我如何与已经运行的家庭助理设置一起使用,这将使我将电子纸显示显示与其他自动化相结合。

只需几个简单的步骤,我就可以创建一个凉爽的怪异小工具来显示在我的桌子上。家庭助理的强大整合,覆盆子皮的多功能性和Waveshare的电子纸显示的结合使该项目变得轻而易举。

我的下一个迭代将包括:

  • 在Webhook有效载荷本身中发送所有必要的数据,以避免Python脚本中的所有这些请求
  • 调整并过滤专辑封面,并使用黑色和白色显示器更好的算法
  • 添加即将到来的工作日历事件
  • 在显示屏中使用那些四个按钮键
  • 将代码上传到github(我需要先清洁代码并设置适当的env vars)

如果您正在寻找一个有趣的编码项目,我强烈建议您尝试一下!