ESPHome Spotify OLED Display
July 8, 2019Background
I've created an OLED Display that cycles through the time, what's playing on Spotify, and the current temperature based on other ESP8266 sensors in the room. All of this is possible with ESPHome to program the ESP8266 microcontroller (in this case a Wemos D1 Mini) connected to Home-Assistant.
I later added a feature to make the screen turn blank when a switch on the Home-Assistant Dashboard is flipped, so the screen wouldn't illuminate my room at night. Please check the code for the Template Switch at the bottom.
Instructions
-
upload the .tff fonts like arial.tff and the others into the esphome directory on your Home-Assistant instance.
- they can be pulled from your windows font directory or downloaded from the internet.
-
create sensor.spotify_song and sensor.spotify_artist sensors using this yaml and your already configured spotify media player integration.
Spotify Sensor YAML Code:
spotify_song:
friendly_name: "Spotify Song"
value_template: "{{ state_attr('media_player.spotify', 'media_title') }}"
spotify_artist:
friendly_name: "Spotify Artist"
value_template: "{{ state_attr('media_player.spotify', 'media_artist') }}"
ESPHome YAML Code
wifi:
ssid: "wifi_network"
password: "wifi_password"
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "OLED Display01 Fallback Hotspot"
password: "password"
captive_portal:
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
time:
- platform: homeassistant
id: time1
text_sensor:
- platform: homeassistant
id: spotify_song
entity_id: sensor.spotify_song
internal: true
- platform: homeassistant
id: spotify_artist
entity_id: sensor.spotify_artist
internal: true
sensor:
### temp sensors
- platform: homeassistant
id: room_temperature
entity_id: sensor.sn1_temperature
internal: true
- platform: homeassistant
id: stereo_temperature
entity_id: sensor.stereo_amp_temperature
internal: true
switch:
- platform: template
name: "OLED_Display01 Screen"
id: oled_display01_dnd
optimistic: True
# inverted: True
on_turn_on:
- logger.log: "Switch Turned On!"
# - delay: 2s
- display.page.show: page4
# - delay: 2s
- component.update: my_display
font:
- file: 'arial.ttf' #'slkscr.ttf'
id: font1
size: 12
- file: 'BebasNeue-Regular.ttf'
id: font2
size: 48
- file: 'arial.ttf'
id: font3
size: 18
- file: 'arialbd.ttf'
id: font4
size: 14
- file: 'arial.ttf'
id: font5
size: 20
i2c:
# sda: D1
# scl: D2
# scan: False
# swap for Wemos D1 Mini
sda: D2
scl: D1
scan: False
display:
- platform: ssd1306_i2c
model: "SSD1306 128x64"
reset_pin: D0
address: 0x3C
id: my_display
pages:
- id: page1
lambda: |-
// Print time in HH:MM format
it.strftime(0, 60, id(font2), TextAlign::BASELINE_LEFT, "%l:%M", id(time1).now());
// Print AM/PM
it.strftime(127, 60, id(font5), TextAlign::BASELINE_RIGHT, "%P", id(time1).now());
- id: page2
lambda: |-
// it.print(0, 10, id(font1), "This is page 2!");
// Print "Spotify Song" in top center.
if (id(spotify_artist).has_state()) {
it.printf(0, 8, id(font5), TextAlign::TOP_LEFT, "%s", id(spotify_artist).state.c_str());
}
if (id(spotify_song).has_state()) {
it.printf(0, 55, id(font5), TextAlign::BASELINE_LEFT, "%s", id(spotify_song).state.c_str());
}
- id: page3
lambda: |-
// it.print(0, 10, id(font1), "This is page 3!");
// Print room temperature (from homeassistant sensor)
if (id(room_temperature).has_state()) {
it.printf(0, 15, id(font5), TextAlign::TOP_LEFT, "Room: %.1f°", id(room_temperature).state);
}
// Print stereo temperature (from homeassistant sensor)
if (id(stereo_temperature).has_state()) {
it.printf(0, 60, id(font5), TextAlign::BASELINE_LEFT, "Stereo: %.1f°", id(stereo_temperature).state);
}
- id: page4
lambda: |-
it.print(0, 10, id(font1), "");
interval:
- interval: 3s
then:
if:
condition:
lambda: return !id(oled_display01_dnd).state;
then:
- display.page.show: !lambda |-
static int pagenum = 0;
static display::DisplayPage* pages[] = {id(page1), id(page2), id(page3)};
auto page = pages[pagenum++];
if (pagenum >= 3)
pagenum = 0;
return page;
- component.update: my_display
Template Sensor
This template sensor inverses the ESPHome Switch. I couldn't find a way to invert it natively in ESPHome, so I went this route. Please let me know if you've figured out a better way!
### template switch to reverse the oled_display01 switch
- platform: template
switches:
oled_display01_inverted:
friendly_name: "OLED Display"
value_template: "{{ is_state('switch.oled_display01_screen', 'off') }}"
turn_on:
service: switch.turn_off
data:
entity_id: switch.oled_display01_screen
turn_off:
service: switch.turn_on
data:
entity_id: switch.oled_display01_screen
icon_template: "{% if is_state('switch.oled_display01_screen', 'on') %}mdi:flash-outline{% else %}mdi:flash{% endif %}"