Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- substitutions:
- esp_name: lilygo-epaper
- run_time: 5min
- sleep_time: 20min
- night_sleep_time: 8h
- esphome:
- name: lilygo-epaper
- external_components:
- - source: github://ashald/esphome@lilygo-t5-47
- components: ["lilygo_t5_47"]
- esp32:
- board: esp32dev
- framework:
- type: arduino
- # Enable logging
- logger:
- # Enable Home Assistant API
- api:
- encryption:
- key: ""
- ota:
- - platform: esphome
- password: ""
- wifi:
- ssid: !secret wifi_ssid
- password: !secret wifi_password
- # Enable fallback hotspot (captive portal) in case wifi connection fails
- ap:
- ssid: "Lilygo-Epaper Fallback Hotspot"
- password: ""
- captive_portal:
- deep_sleep:
- run_duration: ${run_time}
- sleep_duration: ${sleep_time}
- id: deep_sleep_1
- # esp32_ext1_wakeup:
- # pins: GPIO39
- # mode: ALL_LOW
- spi:
- clk_pin: 18
- mosi_pin: 23
- button:
- - platform: restart
- name: "${esp_name} Restart"
- - platform: template
- name: "${esp_name} Refresh"
- icon: "mdi:update"
- on_press:
- then:
- - component.update: t5_display
- script:
- - id: all_data_received
- then:
- - component.update: batt_volt
- - component.update: batt
- - component.update: t5_display
- - script.execute: enter_sleep
- - id: enter_sleep
- then:
- - if:
- condition:
- lambda: |-
- auto time = id(ntp).now();
- if (!time.is_valid()) {
- return false;
- }
- return (time.hour < 6);
- then:
- - logger.log: "It's nighttime, entering long sleep for ${night_sleep_time}"
- - deep_sleep.enter:
- id: deep_sleep_1
- sleep_duration: ${night_sleep_time}
- else:
- - logger.log: "It's daytime, entering short sleep for ${sleep_time}"
- - deep_sleep.enter:
- id: deep_sleep_1
- sleep_duration: ${sleep_time}
- sensor:
- - platform: adc
- pin: GPIO36
- name: "${esp_name} Battery Voltage"
- id: batt_volt
- attenuation: 11db
- update_interval: never
- filters:
- - multiply: 2
- - platform: homeassistant
- entity_id: sensor.city_temperature
- id: ext_temp
- internal: true
- - platform: homeassistant
- entity_id: sensor.city_wind_chill
- id: feels_like
- internal: true
- - platform: template
- name: "Windchill"
- id: windchill
- internal: true
- # lambda: |-
- # if (id(feels_like).state == "unknown") {return "--";} else {return id(feels_like).state;};
- - platform: template
- name: "${esp_name} Battery"
- id: batt
- unit_of_measurement: "%"
- accuracy_decimals: 0
- device_class: battery
- lambda: |-
- int y = (1-(4.1-id(batt_volt).state)/(4.1-3.3))*100;
- if (y < 100) {return y;} else {return 100;};
- update_interval: never
- binary_sensor:
- - platform: gpio
- pin:
- number: GPIO39
- inverted: true
- name: "${esp_name} Button 1"
- on_press:
- then:
- - component.update: t5_display
- - platform: gpio
- pin:
- number: GPIO34
- inverted: true
- name: "${esp_name} Button 2"
- - platform: gpio
- pin:
- number: GPIO35
- inverted: true
- name: "${esp_name} Button 3"
- text_sensor:
- - platform: homeassistant
- id: yyc_weather
- name: "Weather Forecast"
- entity_id: "sensor.city_forecast"
- internal: True
- - platform: homeassistant
- entity_id: "weather.city"
- id: forecast_0
- internal: True
- attribute: temperature_unit
- on_value: # Actions to perform once data for the last sensor has been received
- then:
- - script.execute: all_data_received
- time:
- - platform: homeassistant
- id: ntp
- timezone: "America/Timezone"
- display:
- - platform: lilygo_t5_47
- full_update_every: 1 # optional (default: 1): 0 - never, 1 (default) - every, 2+ - throttled
- cycles_render: 20 # optional (default: 20): higher number -> less ghosting, crisper image, more time
- cycles_invert: 20 # optional (default: 20): higher number -> more timef or full update, but mor burn-in protection
- id: t5_display
- rotation: 270
- update_interval: never
- lambda: |-
- #define xres 540
- #define yres 960
- #define x_pad 10 // border padding
- #define y_pad 10 // border padding
- #define cat_pad 85 // padding before category
- #define val_pad 70 // padding before value
- #define icon_pad 35 //padding after icons
- #define x1n 20 //x position 1st column name
- #define x1v 25 //x position 1st column value
- #define x1i 50 //x position 1st column icon
- #define x2n xres/2 //x position 2nd column name
- #define x2v xres/2 //x position 2nd column value
- #define x2i xres/2 //x position 1st column icon
- int y = 0;
- // Date
- it.strftime(xres/2, y+y_pad, id(font_name), TextAlign::TOP_CENTER, "%A %d/%b/%Y", id(ntp).now());
- y+=val_pad+cat_pad+10;
- //external temperature
- it.print(x1n, y, id(font_name), TextAlign::BASELINE_LEFT, "Outside");
- it.print(x2n, y, id(font_name), TextAlign::BASELINE_LEFT, "Feels Like");
- y+=val_pad;
- it.printf(x1v, y, id(font_value), TextAlign::BASELINE_LEFT, "%.1f °C", id(ext_temp).state);
- it.printf(x2v, y, id(font_value), TextAlign::BASELINE_LEFT, "%.1f °C", id(feels_like).state);
- #define div_pad 40
- #define div_thickness 4
- it.filled_rectangle(x_pad, y+div_pad, xres-2*x_pad, div_thickness);
- //word wrap weather
- std::string s = id(city_weather).state;
- int limit = 35;
- int space = 0;
- int i = 0;
- int line = 0;
- y= 305; // start Y
- while(i<s.length()){ //loop through string, counting all the spaces, and replacing the last one with ~ [marked by space variable] if the count exceeds limit of 35
- if(s.substr(i,1) == " "){space = i; }
- if(line>limit-1){s=s.substr(0,space)+"~"+s.substr(space+1);line = 0;}
- i++;line++;}
- size_t pos = s.find("~"); //find the first line break
- int linecount = 1; //need number of lines to store the break positions in an array
- int breakpositions[10]; //store breakpositions [the '~']
- breakpositions[0] = -1; // start at -1 cause we need to truncate the replaced characters and without this will cut off 1st character of message
- while ( pos != std::string::npos) //loop through replacing the ~ with CR - though this doesnt matter here it will never be displayed, but need to change them to keep the loop from repeating at the start
- {
- s.replace(pos,1, "\n");
- breakpositions[linecount] = pos; //store the position of the break in an array
- pos = s.find("~"); // move forward
- linecount++; // we have a new line, count it
- }
- breakpositions[linecount] = s.length(); //set the last entry in array to the length of string for calculation below
- std::string singleline; //this will be the line we print
- i = 0;
- while (i < linecount ) { // count through the lines
- singleline = s.substr(breakpositions[i]+1,(breakpositions[i+1]-breakpositions[i]-1)); //extract each line of text from the string - strip off the CRLF and the space.
- it.printf(10, y, id(font_footer), "%s", singleline.c_str()); //print it!
- y=y+30; // increment y to print properly on display
- i++;
- }
- //bottom divisor
- it.filled_rectangle(x_pad, (y+30), xres-2*x_pad, div_thickness);
- //test
- it.printf(x_pad, (y+50), id(font_footer), "%s", id(forecast_0).state.c_str());
- y+=div_pad*3+div_thickness;
- // Footer
- it.strftime(x_pad, yres-y_pad/2, id(font_footer), TextAlign::BASELINE_LEFT, "Updated: %H:%M", id(ntp).now());
- it.printf(xres-x_pad, yres-y_pad/2, id(font_footer), TextAlign::BASELINE_RIGHT, "%.2fV/%.0f%%", id(batt_volt).state, id(batt).state);
- font:
- - file: "GoogleSans-Bold.ttf"
- id: font_name
- size: 38
- - file: "GoogleSans-Medium.ttf"
- id: font_value
- size: 56
- - file: "GoogleSans-Medium.ttf"
- id: font_footer
- size: 28
- # https://pictogrammers.github.io/@mdi/font/5.3.45/
- - file: 'materialdesignicons-webfont.ttf'
- id: font_icons
- size: 160
- glyphs:
- - "\U000F0594" # clear-night
- - "\U000F0590" # cloudy
- - "\U000F0595" # partlycloudy
- - "\U000F0591" # fog
- - "\U000F0592" # hail
- - "\U000F0593" # lightning
- - "\U000F067E" # lightning-rainy
- - "\U000F0596" # pouring
- - "\U000F0597" # rainy
- - "\U000F0F36" # snowy
- - "\U000F067F" # snowy-rainy
- - "\U000F0599" # sunny
- - "\U000F059D" # windy
- - "\U000F059E" # windy-variant
- - "\U000F0F38" # exceptional
- - file: 'materialdesignicons-webfont.ttf'
- id: font_icons_small
- size: 56
- glyphs:
- - "\U000F10C2" # Temperature High
- - "\U000F10C3" # Temperature Low
- - "\U000F07E4" # CO2
- - "\U000F054B" # umbrella
- - "\U000F0592" # hail
- - "\U000F0593" # lightning
- - "\U000F067E" # lightning-rainy
- - "\U000F0597" # rainy
- - "\U000F0F36" # snowy
- - "\U000F0594" # clear-night
- - "\U000F0599" # sunny
- - "\U000F07CA" # fuel
- - "\U000F024A" # flower
- - "\U000F051F" # time-remaining
- - "\U000F140B" # Energy
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement