我一直在寻找一个有趣的编码项目来在空闲时间工作,所以我记得我有一个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
- 在Raspberry Pi上创建了Webhook端点
-
触发Webhook时执行Python脚本,这是魔术发生的地方。
此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()
这个项目非常有趣,而且非常容易实现。我喜欢我如何与已经运行的家庭助理设置一起使用,这将使我将电子纸显示显示与其他自动化相结合。
只需几个简单的步骤,我就可以创建一个凉爽的怪异小工具来显示在我的桌子上。家庭助理的强大整合,覆盆子皮的多功能性和Waveshare的电子纸显示的结合使该项目变得轻而易举。
我的下一个迭代将包括:
- 在Webhook有效载荷本身中发送所有必要的数据,以避免Python脚本中的所有这些请求
- 调整并过滤专辑封面,并使用黑色和白色显示器更好的算法
- 添加即将到来的工作日历事件
- 在显示屏中使用那些四个按钮键
- 将代码上传到github(我需要先清洁代码并设置适当的env vars)
如果您正在寻找一个有趣的编码项目,我强烈建议您尝试一下!