The dimensions are 145.5 x 105mm. 70mm deep.
This is so nice - are you able to share your yaml for the weather screen, i am just trying to set one up and an example config would be really helpful.
Andy
@psp888 it would really be in the spirit of this open source community if you could share your yaml and your 3D print files.
Community Guides https://community.home-assistant.io/c/community-guides/51 is a good place to put a howto, with a link back here. Also thingiverse is a good place to put the 3d print files.
It is not compulsory of course, but it would point to you being a good community citizen
Nick … an emerging role in the pressure squad !
Nah but plenty of people have expressed interest and I think it would make a good project to write up. I should have said that I am more than willing to help do a write up!
Me too but I don’t think there’s any onous. Would be appreciated though.
Afternoon - I have ploughed on and managed to get the display running - i am using my own weather data but the config could be easily changed for Open Weather etc.
Yaml so far is below (edited with the latest version) - i was wondering if anyone knows how to add the weather forecast element, looking to add three icons at the bottom of the display to show the next three days weather from openweather…
esphome:
name: 2incheink
platform: ESP8266
board: nodemcuv2
wifi:
ssid: !secret WIFI
password: !secret WIFIPASS
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "2Incheink Fallback Hotspot"
password: "e3d2h2WY9LL3"
captive_portal:
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
# Example configuration entry
sensor:
- platform: homeassistant
id: outtemp
entity_id: sensor.outdoor_temp
icon: "mdi:thermometer"
- platform: homeassistant
id: outtempmin
entity_id: sensor.outdoor_temp_min
- platform: homeassistant
id: outtempmax
entity_id: sensor.outdoor_temp_max
- platform: homeassistant
id: pressure
entity_id: sensor.pressure
- platform: homeassistant
id: pressuremin
entity_id: sensor.pressure_min
- platform: homeassistant
id: pressuremax
entity_id: sensor.pressure_max
- platform: homeassistant
id: wind
entity_id: sensor.wind
- platform: homeassistant
id: raintempest
entity_id: sensor.tempest
text_sensor:
- platform: homeassistant
id: winddir
entity_id: sensor.wind_dir
- platform: homeassistant
id: conditionswd
entity_id: sensor.conditionswd
- platform: homeassistant
name: forecast
id: weather_forecast
entity_id: sensor.forecast
internal: true
font:
- file: 'materialdesignicons-webfont.ttf'
id: icon_font_30
size: 30
glyphs:
- "\U000F050F" # Temp
- "\U000F029A" # Pressure
- "\U000F15FA" # Wind
- "\U000F058C" # Rain
- file: 'materialdesignicons-webfont.ttf'
id: icon_font_10
size: 20
glyphs:
- "\U000F0E02" # Tempmin
- "\U000F0E03" # Tempmax
- file: 'materialdesignicons-webfont.ttf'
id: conditions
size: 70
glyphs:
- "\U000F0594" # Night Time Clear
- "\U000F0F31" # Night Time Dry/Part Cloudy
- "\U000F0595" # Partly Cloudy
- "\U000F0590" # Cloudy.
- "\U000F059B" #Dusk/Dry
- file: 'Roboto-Medium.ttf'
id: roboto
size: 25
glyphs:
['&', '@', '!', ',', '.', '"', '%', '+', '-', '_', ':', '°', '0',
'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z', '/', 'è']
- file: 'Roboto-Medium.ttf'
id: robotosm
size: 16
glyphs:
['&', '@', '!', ',', '.', '"', '%', '+', '-', '_', ':', '°', '0',
'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z', '/', 'è']
# Example configuration entry
spi:
clk_pin: D0
mosi_pin: D1
display:
- platform: waveshare_epaper
cs_pin: D2
dc_pin: D6
busy_pin: D7
reset_pin: D5
model: 2.90in
full_update_every: 6000
update_interval: 10s
lambda: |-
if (id(conditionswd).state == "Night Time, Clear") {
it.print(30, 0, id(conditions), "\U000F0594");}
if (id(conditionswd).state == "Partly Cloudy") {
it.print(30, 0, id(conditions), "\U000F0595");}
if (id(conditionswd).state == "Cloudy/Dry") {
it.print(30, 0, id(conditions), "\U000F0590");}
if (id(conditionswd).state == "Dusk/Dry") {
it.print(30, 0, id(conditions), "\U000F059B");}
if (id(conditionswd).state == "Night_time/Dry") {
it.print(30, 0, id(conditions), "\U000F0F31");}
it.print(5, 70, id(icon_font_30), "\U000F050F");
it.printf(40, 85, id(roboto), "%.1f", id(outtemp).state);
it.print(5, 105, id(icon_font_30), "\U000F029A");
it.printf(40, 120, id(roboto), "%.1f", id(pressure).state);
it.print(5, 140, id(icon_font_30), "\U000F15FA");
it.printf(40, 155, id(roboto), "%.1f", id(wind).state);
it.printf(40, 180, id(roboto), "%s", id(winddir).state.c_str());
it.print(5, 200, id(icon_font_30), "\U000F058C");
it.printf(40,215, id(roboto), "%.1f", id(raintempest).state);
it.line(5, 240, 120, 240);
it.print(15, 250, id(icon_font_10), "\U000F0E03");
it.printf(40,260, id(robotosm), "%.1f", id(outtempmax).state);
it.print(15, 270, id(icon_font_10), "\U000F0E02");
it.printf(40,280, id(robotosm), "%.1f", id(outtempmin).state);
Nice one!
Have a look at my project above.
Just to update - I have made some progress and have published a case on thingiverse (https://www.thingiverse.com/thing:4692418) I have also commented my Yaml as it might be useful for those starting out with eink and esphome (below).
will do a proper guide in the new year
esphome:
name: 2incheink
platform: ESP8266
board: nodemcuv2
# Set up your wifi - I am using !secret to keep it more secure.
wifi:
ssid: !secret WIFI
password: !secret WIFIPASS
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "2Incheink Fallback Hotspot"
password: "e3d2h2WY9LL3"
captive_portal:
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
# Configuration - simply change the id's for the sensors you want to display
sensor:
- platform: homeassistant
id: outtemp
entity_id: sensor.outdoor_temp
icon: "mdi:thermometer"
- platform: homeassistant
id: outtempmin
entity_id: sensor.outdoor_temp_min
- platform: homeassistant
id: outtempmax
entity_id: sensor.outdoor_temp_max
- platform: homeassistant
id: pressure
entity_id: sensor.pressure
- platform: homeassistant
id: pressuremin
entity_id: sensor.pressure_min
- platform: homeassistant
id: pressuremax
entity_id: sensor.pressure_max
- platform: homeassistant
id: wind
entity_id: sensor.wind
- platform: homeassistant
id: rainvue
entity_id: sensor.vue
text_sensor:
- platform: homeassistant
id: winddir
entity_id: sensor.wind_dir
- platform: homeassistant
id: conditionswd
entity_id: sensor.conditionswd
- platform: homeassistant
name: forecast
id: weather_forecast
entity_id: sensor.forecast
internal: true
- platform: homeassistant
name: temptrend
id: temptrend
entity_id: sensor.temperature_trend
internal: true
# Various fonts - Icons and text at various sizes
# Icons are mapped to the code next to the Material Design Icons Preview.html (fonts need to be uploaded to the esphome folder)
# I am using Roboto-medium from Google Fonts
font:
- file: 'materialdesignicons-webfont.ttf'
id: icon_font_30
size: 30
glyphs:
- "\U000F050F" # Temp
- "\U000F029A" # Pressure
- "\U000F15FA" # Wind
- "\U000F058C" # Rain
- "\U000F0737" # Rising
- "\U000F072E" # Falling
- file: 'materialdesignicons-webfont.ttf'
id: icon_font_10
size: 20
glyphs:
- "\U000F0E02" # Tempmin
- "\U000F0E03" # Tempmax
- file: 'materialdesignicons-webfont.ttf'
id: conditions
size: 70
glyphs:
- "\U000F0594" # Night Time Clear
- "\U000F0F31" # Night Time Dry/Part Cloudy
- "\U000F0595" # Partly Cloudy
- "\U000F0590" # Cloudy.
- "\U000F059B" #Dusk/Dry
- "\U000F0599" #Sunny/Dry
- "\U000F0596" #Raining
- "\U000F0F33" #Stopped Raining
- "\U000F067F" #Sleet
- "\U000F0F36" #Snowing
- "\U000F0591" #Fog
- file: 'Roboto-Medium.ttf'
id: roboto
size: 25
glyphs:
['&', '@', '!', ',', '.', '"', '%', '+', '-', '_', ':', '°', '0',
'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z', '/', 'è']
- file: 'Roboto-Medium.ttf'
id: robotosm
size: 16
glyphs:
['&', '@', '!', ',', '.', '"', '%', '+', '-', '_', ':', '°', '0',
'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z', '/', 'è']
# Configuration for the 2.9inch Waveshare - note the pin numbers so they match your NodeMCU
# The screen does a full update every hour and partial every 10s - edit these according to your use
spi:
clk_pin: D0
mosi_pin: D1
display:
- platform: waveshare_epaper
cs_pin: D2
dc_pin: D6
busy_pin: D7
reset_pin: D5
model: 2.90in
full_update_every: 3600
rotation: 180
update_interval: 10s
# Layout - The main part to edit will be the conditions state - this is set for my live weather feed, so edit according to your
# weather icons - probably codes. The Trend arrow reads -1 for falling, 1 for rising - edit out as needs be. The last two
# under the line are the smaller min/max temp icons and data.
lambda: |-
if (id(conditionswd).state == "Night Time, Clear") {
it.print(30, 0, id(conditions), "\U000F0594");}
if (id(conditionswd).state == "Partly_cloudy/Dry") {
it.print(30, 0, id(conditions), "\U000F0595");}
if (id(conditionswd).state == "Cloudy/Dry") {
it.print(30, 0, id(conditions), "\U000F0590");}
if (id(conditionswd).state == "Mainly_cloudy/Dry") {
it.print(30, 0, id(conditions), "\U000F0590");}
if (id(conditionswd).state == "Sunny/Dry") {
it.print(30, 0, id(conditions), "\U000F0599");}
if (id(conditionswd).state == "Raining") {
it.print(30, 0, id(conditions), "\U000F0599");}
if (id(conditionswd).state == "Cloudy/Moderate_drizzle") {
it.print(30, 0, id(conditions), "\U000F0596");}
if (id(conditionswd).state == "Cloudy/Light_rain") {
it.print(30, 0, id(conditions), "\U000F0596");}
if (id(conditionswd).state == "Dusk/Dry") {
it.print(30, 0, id(conditions), "\U000F059B");}
if (id(conditionswd).state == "Night_time/Dry") {
it.print(30, 0, id(conditions), "\U000F0F31");}
if (id(conditionswd).state == "Dawn/Fog") {
it.print(30, 0, id(conditions), "\U000F0591");}
if (id(conditionswd).state == "Fog") {
it.print(30, 0, id(conditions), "\U000F0591");}
it.print(5, 70, id(icon_font_30), "\U000F050F");
it.printf(40, 85, id(roboto), "%.1f", id(outtemp).state);
if (id(temptrend).state == "-1") {
it.print(75, 70, id(icon_font_30), "\U000F072E");}
if (id(temptrend).state == "1") {
it.print(75, 70, id(icon_font_30), "\U000F0737");}
it.print(5, 105, id(icon_font_30), "\U000F029A");
it.printf(40, 120, id(roboto), "%.1f", id(pressure).state);
it.print(5, 140, id(icon_font_30), "\U000F15FA");
it.printf(40, 155, id(roboto), "%.1f", id(wind).state);
it.printf(40, 180, id(roboto), "%s", id(winddir).state.c_str());
it.print(5, 200, id(icon_font_30), "\U000F058C");
it.printf(40,215, id(roboto), "%.1f", id(rainvue).state);
it.line(5, 240, 120, 240);
it.print(15, 250, id(icon_font_10), "\U000F0E03");
it.printf(40,260, id(robotosm), "%.1f", id(outtempmax).state);
it.print(15, 270, id(icon_font_10), "\U000F0E02");
it.printf(40,280, id(robotosm), "%.1f", id(outtempmin).state);
Evening - I am now looking at doing the same thing on the 4.2 inch waveshare screen - this screen does not have partial updates so I’m using a timed refresh.
My problem is all the sensors come in as NAN with the screen refreshing before the data arrives - I have looked up all the forums (and posted but prob should have posted in this thread first)
I thought i had solved it - by wrapping my print function in an has_state (for example):
Copy to clipboard
if (id(outtemp).has_state()) {
it.printf(40, 85, id(roboto), "%.1f", id(outtemp).state);
}
but no joy.
I am at a loss, any ideas or hints would be great, the data is all in HA via mqtt, not sure if that would make a difference.
Andy
@psp888. Is there a chance you will post your 3 display casing print file for everyone or is that a ‘no’?
I’m sure it would be much appreciated.
Have you verified there are actually MQTT topics with the information?
MQTT Explorer is great for this.
I have a 4.2" waveshare monocrome display; I at the moment just ran a python script to make a clock. I have it on a pi and not an ESP device. The display was a nice extra, the main purpose of the pi is the USB speaker I use for Text to Speech via Kodi on the pi via Home Assistant. I need to print a new case, but not bad for a first attempt.
Thanks for the reply - nice clock and case.
Yep i am using MQTT Explorer - your right it is great. I also have another display next to it, updating on a 2.9 inch screen (these have partial updates).
The pi works well with eink screens and i guess I’m a little more at ease with python than c++ - i did a tutorial on making a Time, News and Headline device using the InkyWhat screen last year ([https://connected-environments.org/making/the/]
Just for the life of me I cant get it working with HA (well it works but NAN on all data).
edit - solved! i had somehow forgotten to integrate the new esp32 to HA! ugh a rookie error…
Andy
been busy. I have no problem sharing my clock STL files, but I cannot attach files on here
Main Clock YAML
font:
- file: 'Roboto-Medium.ttf'
id: clock_font
size: 85
- file: 'Roboto-Medium.ttf'
id: clock_sec_font
size: 60
- file: 'Roboto-Medium.ttf'
id: date_font
size: 50
- file: 'Roboto-Medium.ttf'
id: date_text_font
size: 14
- file: 'Roboto-Medium.ttf'
id: sun_font
size: 20
- file: 'materialdesignicons-webfont.ttf'
id: weather_font
size: 45
glyphs: [
# Moon
"チ", # new_moon
"ト", # waxing_crecent
"セ", # first_quarter
"ナ", # waxing_gibbous
"ソ", # full_moon
"テ", # waning_gibbous
"タ", # last_quarter
"ツ", # waning_crescent
]
- file: 'materialdesignicons-webfont.ttf'
id: sun_icon_font
size: 20
glyphs: [
"", # sun rise
"", # sun set
]
spi:
clk_pin: D0
mosi_pin: D1
display:
- platform: waveshare_epaper
id: epaper
cs_pin: D2
busy_pin: D7
reset_pin: D5
dc_pin: D6
model: 2.90in
rotation: 90
full_update_every: 14400
update_interval: 1s
lambda: |-
/* Moon icon */
if(id(moon_icon).has_state()) {
//ESP_LOGI("Moon icon", "%s", id(moon_icon).state.c_str());
it.printf(25, 42, id(weather_font), TextAlign::BASELINE_CENTER, "%s", id(moon_icon).state.c_str());
}
//sun set-rise
it.printf(85, 22, id(sun_icon_font), TextAlign::BASELINE_RIGHT, "");
it.printf(135, 22, id(sun_font), TextAlign::BASELINE_RIGHT, "%s", id(sunrise).state.c_str());
it.printf(85, 44, id(sun_icon_font), TextAlign::BASELINE_RIGHT, "");
it.printf(135, 44, id(sun_font), TextAlign::BASELINE_RIGHT, "%s", id(sunset).state.c_str());
//date
it.strftime(210, 43, id(date_font), TextAlign::BASELINE_RIGHT, "%d", id(sntp_time).now());
it.printf(213, 43, id(date_text_font), TextAlign::BASELINE_LEFT, "D");
it.strftime(280, 43, id(date_font), TextAlign::BASELINE_RIGHT, "%m", id(sntp_time).now());
it.printf(283, 43, id(date_text_font), TextAlign::BASELINE_LEFT, "M");
//line
it.line(0, 54, 296, 54);
//Time
it.strftime(3, 45, id(clock_font), "%H:%M", id(sntp_time).now());
it.strftime(225, 68, id(clock_sec_font), "%S", id(sntp_time).now());
it.strftime(250, 58, id(date_text_font), "%a", id(sntp_time).now());
text_sensor:
- platform: homeassistant
id: moon_icon
entity_id: sensor.moon_tpl
- platform: homeassistant
id: sunrise
entity_id: sensor.nextsunrise
- platform: homeassistant
id: sunset
entity_id: sensor.nextsunset
time:
- platform: sntp
timezone: Europe/London
id: sntp_time
Temperature Screen
font:
- file: 'Roboto-Medium.ttf'
id: main_75_font
size: 75
- file: 'Roboto-Medium.ttf'
id: main_60_font
size: 60
- file: 'Roboto-Medium.ttf'
id: main_50_font
size: 50
- file: 'Roboto-Medium.ttf'
id: main_30_font
size: 30
- file: 'Roboto-Medium.ttf'
id: main_20_font
size: 20
- file: 'materialdesignicons-webfont.ttf'
id: icon_45_font
size: 45
glyphs: [
# Moon
"チ", # new_moon
"ト", # waxing_crecent
"セ", # first_quarter
"ナ", # waxing_gibbous
"ソ", # full_moon
"テ", # waning_gibbous
"タ", # last_quarter
"ツ", # waning_crescent
]
- file: 'materialdesignicons-webfont.ttf'
id: icon_20_font
size: 20
glyphs: [
"", # sun rise
"", # sun set
]
spi:
clk_pin: D0
mosi_pin: D1
display:
- platform: waveshare_epaper
id: epaper
cs_pin: D2
busy_pin: D7
reset_pin: D5
dc_pin: D6
model: 2.90in
rotation: 90
full_update_every: 14400
update_interval: 60s
lambda: |-
it.print(0, 20, id(main_20_font), TextAlign::BASELINE_LEFT , "OUT");
it.printf(190, 60, id(main_75_font), TextAlign::BASELINE_RIGHT , "%.1f", id(outside_temp).state);
it.printf(190, 45, id(main_30_font), TextAlign::BASELINE_LEFT , "°");
it.printf(191, 60, id(main_30_font), TextAlign::BASELINE_LEFT , "C");
it.printf(280, 60, id(main_50_font), TextAlign::BASELINE_RIGHT , "%.0f", id(outside_humidity).state);
it.printf(296, 60, id(main_20_font), TextAlign::BASELINE_RIGHT , "%%");
//line
it.line(0, 70, 296, 70);
it.print(0, 95, id(main_20_font), TextAlign::BASELINE_LEFT , "IN");
it.printf(190, 125, id(main_60_font), TextAlign::BASELINE_RIGHT , "%.1f", id(inside_temp).state);
it.printf(190, 110, id(main_30_font), TextAlign::BASELINE_LEFT , "°");
it.printf(191, 125, id(main_30_font), TextAlign::BASELINE_LEFT , "C");
it.printf(280, 125, id(main_50_font), TextAlign::BASELINE_RIGHT , "%.0f", id(inside_humidity).state);
it.printf(296, 125, id(main_20_font), TextAlign::BASELINE_RIGHT , "%%");
sensor:
- platform: homeassistant
entity_id: sensor.temperature_158d000245dc33
id: outside_temp
internal: true
- platform: homeassistant
entity_id: sensor.living_room_temperature
id: inside_temp
internal: true
- platform: homeassistant
entity_id: sensor.humidity_158d000245dc33
id: outside_humidity
internal: true
- platform: homeassistant
entity_id: sensor.living_room_humidity
id: inside_humidity
internal: true
Weather Screen
font:
- file: 'Roboto-Light.ttf'
id: size_12_font
size: 12
- file: 'Roboto-Medium.ttf'
id: size_15_font
size: 15
- file: 'Roboto-Medium.ttf'
id: size_20_font
size: 20
- file: 'Roboto-Medium.ttf'
id: size_25_font
size: 25
- file: 'Roboto-Medium.ttf'
id: size_30_font
size: 30
- file: 'materialdesignicons-webfont.ttf'
id: weather_font
size: 120
glyphs: [
# Weather
"", # mdi-weather-sunny
"", # mdi-weather-cloudy
"", # mdi-weather-pouring
"", # mdi-weather-snowy-rainy
"s", # mdi-weather-snowy-heavy
"", # mdi-weather-windy-variant
"", # mdi-weather-fog
"n", # mdi-weather-night-partly-cloudy
"", # mdi-weather-partly-cloudy
"", # mdi-weather-rainy
"", # mdi-weather-snowy
"", # mdi-weather-clear-night
"", # unknown
]
- file: 'materialdesignicons-webfont.ttf'
id: weather_temp_icon_font
size: 25
glyphs: [
"﹢", # mdi-down
"﹣", # mdi-up
"", # raindrop
"", # wind
]
- file: 'materialdesignicons-webfont.ttf'
id: home_icon_font
size: 15
glyphs: [
"ﵜ", # mdi-house1
"ﵝ", # mdi-house2
"ﵞ", # mdi-house3
"", # mdi-bowl
"", #mdi-knifeandfork
]
spi:
clk_pin: D0
mosi_pin: D1
display:
- platform: waveshare_epaper
id: epaper
cs_pin: D2
busy_pin: D7
reset_pin: D5
dc_pin: D6
model: 2.90in
rotation: 180
full_update_every: 14400
update_interval: 120s
lambda: |-
if (id(forecast_condition).has_state()) {
if (id(forecast_condition).state == "snowy-rainy") {
it.printf(64, 98, id(weather_font), TextAlign::BASELINE_CENTER , "");
} else if (id(forecast_condition).state == "snowy-heavy") {
it.printf(64, 98, id(weather_font), TextAlign::BASELINE_CENTER , "s");
} else if (id(forecast_condition).state == "rainy") {
it.printf(64, 98, id(weather_font), TextAlign::BASELINE_CENTER , "");
} else if (id(forecast_condition).state == "pouring") {
it.printf(64, 98, id(weather_font), TextAlign::BASELINE_CENTER , "");
} else if (id(forecast_condition).state == "cloudy") {
it.printf(64, 98, id(weather_font), TextAlign::BASELINE_CENTER , "");
} else if (id(forecast_condition).state == "partlycloudy") {
it.printf(64, 98, id(weather_font), TextAlign::BASELINE_CENTER , "");
} else if (id(forecast_condition).state == "sunny") {
it.printf(64, 98, id(weather_font), TextAlign::BASELINE_CENTER , "");
} else if (id(forecast_condition).state == "windyvariant") {
it.printf(64, 98, id(weather_font), TextAlign::BASELINE_CENTER , "");
} else if (id(forecast_condition).state == "fog") {
it.printf(64, 98, id(weather_font), TextAlign::BASELINE_CENTER , "");
} else if (id(forecast_condition).state == "nightpartlycloudy") {
it.printf(64, 98, id(weather_font), TextAlign::BASELINE_CENTER , "n");
} else if (id(forecast_condition).state == "partlycloudy") {
it.printf(64, 98, id(weather_font), TextAlign::BASELINE_CENTER , "");
} else if (id(forecast_condition).state == "snowy") {
it.printf(64, 98, id(weather_font), TextAlign::BASELINE_CENTER , "");
} else if (id(forecast_condition).state == "clear-night") {
it.printf(64, 98, id(weather_font), TextAlign::BASELINE_CENTER , "");
} else {
it.printf(64, 98, id(weather_font), TextAlign::BASELINE_CENTER , "");
}
}
it.printf(64, 122, id(size_20_font), TextAlign::BASELINE_CENTER , "%s", id(forecast_condition).state.c_str());
it.printf(24, 152, id(weather_temp_icon_font), TextAlign::BASELINE_CENTER , "﹣");
if (id(forecast_temperature).has_state()) {
it.printf(98, 154, id(size_30_font), TextAlign::BASELINE_RIGHT , "%.1f", id(forecast_temperature).state);
it.printf(99, 148, id(size_20_font), TextAlign::BASELINE_LEFT , "°");
it.printf(100, 154, id(size_20_font), TextAlign::BASELINE_LEFT , "C");
}
it.printf(24, 183, id(weather_temp_icon_font), TextAlign::BASELINE_CENTER , "﹢");
if (id(forecast_temperature_low).has_state()) {
it.printf(98, 185, id(size_30_font), TextAlign::BASELINE_RIGHT , "%.1f", id(forecast_temperature_low).state);
it.printf(99, 179, id(size_20_font), TextAlign::BASELINE_LEFT , "°");
it.printf(100, 185, id(size_20_font), TextAlign::BASELINE_LEFT , "C");
}
std::string str = id(forecast_precipitation).state;
//ESP_LOGI("Weather", "%s", str.c_str());
it.printf(24, 214, id(weather_temp_icon_font), TextAlign::BASELINE_CENTER , "");
if (id(forecast_precipitation).has_state()) {
if (str != "unknown") {
it.printf(98, 216, id(size_30_font), TextAlign::BASELINE_RIGHT , "%s", id(forecast_precipitation).state.c_str());
it.printf(99, 216, id(size_12_font), TextAlign::BASELINE_LEFT , "mm");
}
else {
it.printf(98, 216, id(size_30_font), TextAlign::BASELINE_RIGHT , "0.0");
it.printf(99, 216, id(size_12_font), TextAlign::BASELINE_LEFT , "mm");
}
}
it.printf(24, 245, id(weather_temp_icon_font), TextAlign::BASELINE_CENTER , "");
if (id(forecast_wind_speed).has_state()) {
it.printf(98, 247, id(size_30_font), TextAlign::BASELINE_RIGHT , "%.1f", id(forecast_wind_speed).state * 2.237);
it.printf(99, 247, id(size_12_font), TextAlign::BASELINE_LEFT , "mph");
}
//line
it.line(0, 260, 128, 260);
//bedroom1
it.printf(0, 280, id(home_icon_font), TextAlign::BASELINE_LEFT , "ﵜ");
it.printf(50, 280, id(size_15_font), TextAlign::BASELINE_RIGHT , "%.1f", id(bedroom1).state);
//bedroom2
it.printf(78, 280, id(home_icon_font), TextAlign::BASELINE_LEFT , "ﵝ");
it.printf(128, 280, id(size_15_font), TextAlign::BASELINE_RIGHT , "%.1f", id(bedroom2).state);
//bedroom3
it.printf(0, 294, id(home_icon_font), TextAlign::BASELINE_LEFT , "ﵞ");
it.printf(50, 294, id(size_15_font), TextAlign::BASELINE_RIGHT , "%.1f", id(bedroom3).state);
//kitchen
it.printf(78, 294, id(home_icon_font), TextAlign::BASELINE_LEFT , "");
it.printf(128, 294, id(size_15_font), TextAlign::BASELINE_RIGHT , "%.1f", id(kitchen).state);
text_sensor:
- platform: homeassistant
entity_id: sensor.openweathermaphourly_forecast_condition
id: forecast_condition
internal: true
- platform: homeassistant
entity_id: sensor.openweathermap_forecast_precipitation
id: forecast_precipitation
internal: true
sensor:
- platform: homeassistant
entity_id: sensor.openweathermap_forecast_temperature
id: forecast_temperature
internal: true
- platform: homeassistant
entity_id: sensor.openweathermap_forecast_temperature_low
id: forecast_temperature_low
internal: true
- platform: homeassistant
entity_id: sensor.openweathermaphourly_forecast_wind_speed
id: forecast_wind_speed
internal: true
- platform: homeassistant
entity_id: sensor.bedroom_temperature
id: bedroom1
internal: true
- platform: homeassistant
entity_id: sensor.kids_room_temperature
id: bedroom2
internal: true
- platform: homeassistant
entity_id: sensor.temperature_158d0002477c72
id: bedroom3
internal: true
- platform: homeassistant
entity_id: sensor.temperature_158d000237110c
id: kitchen
internal: true
Thought those interested in the thread might like to see the 4.2 inch version of using eink for HA data. The layout is a little challenging as there is no style sheet so its x/y pixels and the centre align needs tweaking according to the data…
I was going to do a write up so people dont have to go through the hoops i had to to learn it… as ever with things its quite easy once you know how, but knowing how took a few threads, a couple of bricking the node mcu and a few tweaks on the 3D print (which i will put on thingiverse)…
Andy
Just updating the 2.9 inch display to include a clock, maximum wind gust and some minor layout changes - now also updated on Thingiverse (https://www.thingiverse.com/thing:4692418)
Yaml -
esphome:
name: 2incheink
platform: ESP8266
board: nodemcuv2
time:
- platform: homeassistant
id: homeassistant_time
# Set up your wifi - I am using !secret to keep it more secure.
wifi:
ssid: !secret WIFI
password: !secret WIFIPASS
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "2Incheink Fallback Hotspot"
password: "e3d2h2WY9LL3"
captive_portal:
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
# Configuration - simply change the id's for the sensors you want to display
sensor:
- platform: homeassistant
id: outtemp
entity_id: sensor.outdoor_temp
- platform: homeassistant
id: outtempmin
entity_id: sensor.outdoor_temp_min
- platform: homeassistant
id: outtempmax
entity_id: sensor.outdoor_temp_max
- platform: homeassistant
id: pressure
entity_id: sensor.pressure
- platform: homeassistant
id: pressuremin
entity_id: sensor.pressure_min
- platform: homeassistant
id: pressuremax
entity_id: sensor.pressure_max
- platform: homeassistant
id: wind
entity_id: sensor.wind
- platform: homeassistant
id: windav10
entity_id: sensor.wind_average_10_min
- platform: homeassistant
id: rainvue
entity_id: sensor.vue
- platform: homeassistant
id: windmax
entity_id: sensor.max_wind
text_sensor:
- platform: homeassistant
id: winddir
entity_id: sensor.wind_dir
- platform: homeassistant
id: conditionswd
entity_id: sensor.conditionswd
- platform: homeassistant
name: forecast
id: weather_forecast
entity_id: sensor.forecast
internal: true
- platform: homeassistant
name: temptrend
id: temptrend
entity_id: sensor.temperature_trend
internal: true
# Various fonts - Icons and text at various sizes
# Icons are mapped to the code next to the Material Design Icons Preview.html (fonts need to be uploaded to the esphome folder)
# I am using Roboto-medium from Google Fonts
font:
- file: 'materialdesignicons-webfont.ttf'
id: icon_font_30
size: 30
glyphs:
- "\U000F050F" # Temp
- "\U000F029A" # Pressure
- "\U000F15FA" # Wind
- "\U000F058C" # Rain
- "\U000F0737" # Rising
- "\U000F072E" # Falling
- file: 'materialdesignicons-webfont.ttf'
id: icon_font_10
size: 20
glyphs:
- "\U000F0E02" # Tempmin
- "\U000F0E03" # Tempmax
- "\U000F15FA" # Wind
- "\U000F0150" # Clock
- file: 'materialdesignicons-webfont.ttf'
id: conditions
size: 70
glyphs:
- "\U000F0594" # Night Time Clear
- "\U000F0F31" # Night Time Dry/Part Cloudy
- "\U000F0595" # Partly Cloudy
- "\U000F0590" # Cloudy.
- "\U000F059B" #Dusk/Dry
- "\U000F0599" #Sunny/Dry
- "\U000F0596" #Raining
- "\U000F0F33" #Stopped Raining
- "\U000F067F" #Sleet
- "\U000F0F36" #Snowing
- "\U000F0591" #Fog
- file: 'Roboto-Medium.ttf'
id: roboto
size: 25
glyphs:
['&', '@', '!', ',', '.', '"', '%', '+', '-', '_', ':', '°', '0',
'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z', '/', 'è']
- file: 'Roboto-Medium.ttf'
id: robotosm
size: 16
glyphs:
['&', '@', '!', ',', '.', '"', '%', '+', '-', '_', ':', '°', '0',
'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z', '/', 'è']
# Configuration for the 2.9inch Waveshare - note the pin numbers so they match your NodeMCU
# The screen does a full update every hour and partial every 10s - edit these according to your use
spi:
clk_pin: D0
mosi_pin: D1
display:
- platform: waveshare_epaper
cs_pin: D2
dc_pin: D6
busy_pin: D7
reset_pin: D5
model: 2.90in
full_update_every: 60
rotation: 180
update_interval: 60s
# Layout - The main part to edit will be the conditions state - this is set for my live weather feed, so edit according to your
# weather icons - probably codes. The Trend arrow reads -1 for falling, 1 for rising - edit out as needs be. The last two
# under the line are the smaller min/max temp icons and data.
lambda: |-
if (id(conditionswd).state == "Night Time, Clear") {
it.print(30, 0, id(conditions), "\U000F0594");}
if (id(conditionswd).state == "Partly_cloudy/Dry") {
it.print(30, 0, id(conditions), "\U000F0595");}
if (id(conditionswd).state == "Cloudy/Dry") {
it.print(30, 0, id(conditions), "\U000F0590");}
if (id(conditionswd).state == "Mainly_cloudy/Dry") {
it.print(30, 0, id(conditions), "\U000F0590");}
if (id(conditionswd).state == "Sunny/Dry") {
it.print(30, 0, id(conditions), "\U000F0599");}
if (id(conditionswd).state == "Raining") {
it.print(30, 0, id(conditions), "\U000F0599");}
if (id(conditionswd).state == "Cloudy/Moderate_drizzle") {
it.print(30, 0, id(conditions), "\U000F0596");}
if (id(conditionswd).state == "Cloudy/Light_rain") {
it.print(30, 0, id(conditions), "\U000F0596");}
if (id(conditionswd).state == "Night_time/Moderate_drizzle") {
it.print(30, 0, id(conditions), "\U000F0596");}
if (id(conditionswd).state == "Night_time/Moderate_rain") {
it.print(30, 0, id(conditions), "\U000F0596");}
if (id(conditionswd).state == "Night_time/Stopped_raining") {
it.print(30, 0, id(conditions), "\U000F0F31");}
if (id(conditionswd).state == "Cloudy/Stopped_raining") {
it.print(30, 0, id(conditions), "\U000F0F33");}
if (id(conditionswd).state == "Dusk/Dry") {
it.print(30, 0, id(conditions), "\U000F059B");}
if (id(conditionswd).state == "Night_time/Dry") {
it.print(30, 0, id(conditions), "\U000F0F31");}
if (id(conditionswd).state == "Dawn/Fog") {
it.print(30, 0, id(conditions), "\U000F0591");}
if (id(conditionswd).state == "Fog") {
it.print(30, 0, id(conditions), "\U000F0591");}
if (id(conditionswd).state == "Night_time/Sleet_fall") {
it.print(30, 0, id(conditions), "\U000F067F");}
if (id(conditionswd).state == "Cloudy/Fog") {
it.print(30, 0, id(conditions), "\U000F0591");}
it.print(5, 70, id(icon_font_30), "\U000F050F");
it.printf(40, 85, id(roboto), "%.1f", id(outtemp).state);
if (id(temptrend).state == "-1") {
it.print(95, 70, id(icon_font_30), "\U000F072E");}
if (id(temptrend).state == "1") {
it.print(95, 70, id(icon_font_30), "\U000F0737");}
it.print(5, 105, id(icon_font_30), "\U000F029A");
it.printf(40, 120, id(roboto), "%.1f", id(pressure).state);
it.print(5, 140, id(icon_font_30), "\U000F15FA");
it.printf(40, 155, id(roboto), "%.1f", id(windav10).state);
it.printf(40, 180, id(roboto), "%s", id(winddir).state.c_str());
it.print(5, 200, id(icon_font_30), "\U000F058C");
it.printf(40,215, id(roboto), "%.1f", id(rainvue).state);
it.line(5, 240, 125, 240);
it.print(5, 250, id(icon_font_10), "\U000F0E03");
it.printf(30,260, id(robotosm), "%.1f", id(outtempmax).state);
it.print(5, 270, id(icon_font_10), "\U000F0E02");
it.printf(30,280, id(robotosm), "%.1f", id(outtempmin).state);
it.print(65, 250, id(icon_font_10), "\U000F15FA");
it.printf(95,260, id(robotosm), "%.1f", id(windmax).state);
it.print(61, 270, id(icon_font_10), "\U000F0150");
it.strftime(87, 270, id(robotosm), "%H:%M", id(homeassistant_time).now());
```
I have a slightly unique issue. When I loose internet (due to power outages), I have have a generator for backup power but I loose connection to a time server. I noticed that over an 4 hour period my time is off by over 30 mins.
What are some good options here; I’m running my display on a pi and not an ESP.
My Home Assistant instance is on a PC with a real time clock.
So, should I pull the time from a GPS; a docker network time server, …
There is a chrony addon.
For anyone interested, the 4.2 inch case (pictured a few posts up) is now on Thingiverse to print:
https://www.thingiverse.com/thing:4721366
Andy