Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # WEATHERMAN DASHBOARD
- # For Home Assistant and ESPHome
- # Designed by Madelena Mak 2022 - https://mmak.es
- # Cue "Blame it on the Weatherman" by B*Witched!
- esphome:
- name: "weatherman"
- on_boot:
- priority: 200.0
- then:
- - component.update: eink_display
- - wait_until:
- condition:
- lambda: 'return id(data_updated) == true;'
- # Wait a bit longer so all the items are received
- - delay: 5s
- - logger.log: "Initial sensor data received: Refreshing display..."
- - lambda: 'id(initial_data_received) = true;'
- - script.execute: update_screen
- esp32:
- board: esp32dev
- framework:
- type: arduino
- # Enable logging
- logger:
- # Enable Home Assistant API
- api:
- ota:
- button:
- - platform: shutdown
- name: "Weatherman - Shutdown"
- - platform: restart
- name: "Weatherman - Restart"
- - platform: template
- name: "Weatherman - Refresh Screen"
- entity_category: config
- on_press:
- - script.execute: update_screen
- # Global variables for detecting if the display needs to be refreshed. (Thanks @paviro!)
- globals:
- - id: data_updated
- type: bool
- restore_value: no
- initial_value: 'false'
- - id: initial_data_received
- type: bool
- restore_value: no
- initial_value: 'false'
- - id: recorded_display_refresh
- type: int
- restore_value: yes
- initial_value: '0'
- # Script for updating screen - Refresh display and publish refresh count and time. (Thanks @paviro!)
- script:
- - id: update_screen
- then:
- - lambda: 'id(data_updated) = false;'
- - component.update: eink_display
- - lambda: 'id(recorded_display_refresh) += 1;'
- - lambda: 'id(display_last_update).publish_state(id(homeassistant_time).now().timestamp);'
- # Check whether the display needs to be refreshed every minute,
- # based on whether new data is received or motion is detected. (Thanks @paviro!)
- time:
- - platform: homeassistant
- id: homeassistant_time
- on_time:
- - seconds: 0
- minutes: /1
- then:
- - if:
- condition:
- lambda: 'return id(data_updated) == true;'
- then:
- - if:
- condition:
- binary_sensor.is_on: motion_detected
- then:
- - logger.log: "Sensor data updated and activity in home detected: Refreshing display..."
- - script.execute: update_screen
- else:
- - logger.log: "Sensor data updated but no activity in home - skipping display refresh."
- else:
- - logger.log: "No sensors updated - skipping display refresh."
- # Wifi information
- wifi:
- ssid: !secret wifi_ssid
- password: !secret wifi_password
- # Enable fallback hotspot (captive portal) in case wifi connection fails
- ap:
- ssid: "Esphome-Web-901078"
- password: "2JOrpBYEHQsV"
- # Include custom fonts
- font:
- - file: 'fonts/GothamRnd-Book.ttf'
- id: font_small_book
- size: 18
- glyphs: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'X', 'Y', 'Z', 'Å', 'Ä', 'Ö', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '-', ' ', '°', '.']
- - file: 'fonts/GothamRnd-Bold.ttf'
- id: font_large_bold
- size: 108
- glyphs: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'X', 'Y', 'Z', 'Å', 'Ä', 'Ö', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '-', ' ', '°', '.']
- - file: 'fonts/GothamRnd-Bold.ttf'
- id: font_title
- size: 54
- glyphs: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'X', 'Y', 'Z', 'Å', 'Ä', 'Ö', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '-', ' ', '°', '.']
- - file: 'fonts/GothamRnd-Bold.ttf'
- id: font_medium_bold
- size: 30
- glyphs: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'X', 'Y', 'Z', 'Å', 'Ä', 'Ö', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '-', ' ', '°', '.']
- - file: 'fonts/GothamRnd-Bold.ttf'
- id: font_small_bold
- size: 18
- glyphs: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'X', 'Y', 'Z', 'Å', 'Ä', 'Ö', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '-', ' ', '°', '.']
- # Include Material Design Icons font
- # Thanks to https://community.home-assistant.io/t/display-materialdesign-icons-on-esphome-attached-to-screen/199790/16
- - file: 'fonts/materialdesignicons-webfont.ttf'
- id: font_mdi_large
- size: 96
- glyphs: &mdi-weather-glyphs
- - "\U000F0590" # mdi-weather-cloudy
- - "\U000F0F2F" # mdi-weather-cloudy-alert
- - "\U000F0E6E" # mdi-weather-cloudy-arrow-right
- - "\U000F0591" # mdi-weather-fog
- - "\U000F0592" # mdi-weather-hail
- - "\U000F0F30" # mdi-weather-hazy
- - "\U000F0898" # mdi-weather-hurricane
- - "\U000F0593" # mdi-weather-lightning
- - "\U000F067E" # mdi-weather-lightning-rainy
- - "\U000F0594" # mdi-weather-night
- - "\U000F0F31" # mdi-weather-night-partly-cloudy
- - "\U000F0595" # mdi-weather-partly-cloudy
- - "\U000F0F32" # mdi-weather-partly-lightning
- - "\U000F0F33" # mdi-weather-partly-rainy
- - "\U000F0F34" # mdi-weather-partly-snowy
- - "\U000F0F35" # mdi-weather-partly-snowy-rainy
- - "\U000F0596" # mdi-weather-pouring
- - "\U000F0597" # mdi-weather-rainy
- - "\U000F0598" # mdi-weather-snowy
- - "\U000F0F36" # mdi-weather-snowy-heavy
- - "\U000F067F" # mdi-weather-snowy-rainy
- - "\U000F0599" # mdi-weather-sunny
- - "\U000F0F37" # mdi-weather-sunny-alert
- - "\U000F14E4" # mdi-weather-sunny-off
- - "\U000F059A" # mdi-weather-sunset
- - "\U000F059B" # mdi-weather-sunset-down
- - "\U000F059C" # mdi-weather-sunset-up
- - "\U000F0F38" # mdi-weather-tornado
- - "\U000F059D" # mdi-weather-windy
- - "\U000F059E" # mdi-weather-windy-variant
- - "\U000F1508" # mdi-water-off-outline
- - "\U000F0E0A" # mdi-water-outline
- - "\U000F1503" # mdi-water-alert-outline
- - "\U000F081D" # mdi-fan-off
- - "\U000F1B5A" # mdi-weather-dust
- - "\U000F02D6" # mdi-help
- - "\U000F0717" # mdi-snowflake
- - "\U000F0F29" # mdi-snowflake-alert
- - file: 'fonts/materialdesignicons-webfont.ttf'
- id: font_mdi_medium
- size: 36
- glyphs: *mdi-weather-glyphs
- # Include Custom Titles
- # image:
- # - file: "images/weatherman-title-train.png"
- # id: title_train
- # type: BINARY
- # - file: "images/weatherman-title-weather.png"
- # id: title_weather
- # type: BINARY
- # Check if motion is detected in the living room.
- binary_sensor:
- - platform: homeassistant
- entity_id: binary_sensor.weatherman_motion_detected
- id: motion_detected
- sensor:
- # Create sensors for monitoring Weatherman remotely.
- - platform: template
- name: "Weatherman - Display Last Update"
- device_class: timestamp
- entity_category: "diagnostic"
- id: display_last_update
- - platform: template
- name: "Weatherman - Recorded Display Refresh"
- accuracy_decimals: 0
- unit_of_measurement: "Refreshes"
- state_class: "total_increasing"
- entity_category: "diagnostic"
- lambda: 'return id(recorded_display_refresh);'
- - platform: wifi_signal
- name: "WiFi Signal Sensor"
- id: wifisignal
- update_interval: 60s
- - platform: homeassistant
- entity_id: sensor.weatherman_data
- attribute: weather_temperature_now
- id: weather_temperature_now
- on_value:
- then:
- - lambda: 'id(data_updated) = true;'
- - platform: homeassistant
- entity_id: sensor.weatherman_data
- attribute: weather_temperature_0
- id: weather_temperature_0
- on_value:
- then:
- - lambda: 'id(data_updated) = true;'
- - platform: homeassistant
- entity_id: sensor.weatherman_data
- attribute: weather_temperature_1
- id: weather_temperature_1
- on_value:
- then:
- - lambda: 'id(data_updated) = true;'
- - platform: homeassistant
- entity_id: sensor.weatherman_data
- attribute: weather_temperature_2
- id: weather_temperature_2
- on_value:
- then:
- - lambda: 'id(data_updated) = true;'
- - platform: homeassistant
- entity_id: sensor.weatherman_data
- attribute: weather_temperature_3
- id: weather_temperature_3
- on_value:
- then:
- - lambda: 'id(data_updated) = true;'
- text_sensor:
- - platform: homeassistant
- entity_id: sensor.weatherman_data
- attribute: finn_mossen_arrive
- id: finn_mossen_arrive
- on_value:
- then:
- - lambda: 'id(data_updated) = true;'
- - platform: homeassistant
- entity_id: sensor.weatherman_data
- attribute: finn_mossen_depart
- id: finn_mossen_depart
- on_value:
- then:
- - lambda: 'id(data_updated) = true;'
- - platform: homeassistant
- entity_id: sensor.weatherman_data
- attribute: finn_mossen_weekday
- id: finn_mossen_weekday
- on_value:
- then:
- - lambda: 'id(data_updated) = true;'
- - platform: homeassistant
- entity_id: sensor.weatherman_data
- attribute: weather_condition_now
- id: weather_condition_now
- on_value:
- then:
- - lambda: 'id(data_updated) = true;'
- - platform: homeassistant
- entity_id: sensor.weatherman_data
- attribute: weather_wind_today
- id: weather_wind_today
- on_value:
- then:
- - lambda: 'id(data_updated) = true;'
- - platform: homeassistant
- entity_id: sensor.weatherman_data
- attribute: weather_rain_today
- id: weather_rain_today
- on_value:
- then:
- - lambda: 'id(data_updated) = true;'
- - platform: homeassistant
- entity_id: sensor.weatherman_data
- attribute: weather_condition_0
- id: weather_condition_0
- on_value:
- then:
- - lambda: 'id(data_updated) = true;'
- - platform: homeassistant
- entity_id: sensor.weatherman_data
- attribute: weather_timestamp_0
- id: weather_timestamp_0
- - platform: homeassistant
- entity_id: sensor.weatherman_data
- attribute: weather_condition_1
- id: weather_condition_1
- on_value:
- then:
- - lambda: 'id(data_updated) = true;'
- - platform: homeassistant
- entity_id: sensor.weatherman_data
- attribute: weather_timestamp_1
- id: weather_timestamp_1
- on_value:
- then:
- - lambda: 'id(data_updated) = true;'
- - platform: homeassistant
- entity_id: sensor.weatherman_data
- attribute: weather_condition_2
- id: weather_condition_2
- on_value:
- then:
- - lambda: 'id(data_updated) = true;'
- - platform: homeassistant
- entity_id: sensor.weatherman_data
- attribute: weather_timestamp_2
- id: weather_timestamp_2
- on_value:
- then:
- - lambda: 'id(data_updated) = true;'
- - platform: homeassistant
- entity_id: sensor.weatherman_data
- attribute: weather_condition_3
- id: weather_condition_3
- on_value:
- then:
- - lambda: 'id(data_updated) = true;'
- - platform: homeassistant
- entity_id: sensor.weatherman_data
- attribute: weather_timestamp_3
- id: weather_timestamp_3
- on_value:
- then:
- - lambda: 'id(data_updated) = true;'
- - platform: homeassistant
- entity_id: sensor.time
- id: update_time
- # Pins for Waveshare ePaper ESP Board
- spi:
- clk_pin: GPIO13
- mosi_pin: GPIO14
- # Now render everything on the ePaper screen.
- display:
- - platform: waveshare_epaper
- id: eink_display
- cs_pin: GPIO15
- dc_pin: GPIO27
- busy_pin: GPIO25
- reset_pin: GPIO26
- reset_duration: 2ms
- model: 7.50inV2
- update_interval: never
- rotation: 270°
- lambda: |-
- // Map weather states to MDI characters.
- std::map<std::string, std::string> weather_icon_map
- {
- {"cloudy", "\U000F0590"},
- {"cloudy-alert", "\U000F0F2F"},
- {"cloudy-arrow-right", "\U000F0E6E"},
- {"fog", "\U000F0591"},
- {"hail", "\U000F0592"},
- {"hazy", "\U000F0F30"},
- {"hurricane", "\U000F0898"},
- {"lightning", "\U000F0593"},
- {"lightning-rainy", "\U000F067E"},
- {"night", "\U000F0594"},
- {"night-partly-cloudy", "\U000F0F31"},
- {"partlycloudy", "\U000F0595"},
- {"partly-lightning", "\U000F0F32"},
- {"partly-rainy", "\U000F0F33"},
- {"partly-snowy", "\U000F0F34"},
- {"partly-snowy-rainy", "\U000F0F35"},
- {"pouring", "\U000F0596"},
- {"rainy", "\U000F0597"},
- {"snowy", "\U000F0598"},
- {"snowy-heavy", "\U000F0F36"},
- {"snowy-rainy", "\U000F067F"},
- {"sunny", "\U000F0599"},
- {"sunny-alert", "\U000F0F37"},
- {"sunny-off", "\U000F14E4"},
- {"sunset", "\U000F059A"},
- {"sunset-down", "\U000F059B"},
- {"sunset-up", "\U000F059C"},
- {"tornado", "\U000F0F38"},
- {"windy", "\U000F059D"},
- {"windy-variant", "\U000F059E"},
- {"fan-off", "\U000F081D"},
- {"weather-windy", "\U000F059D"},
- {"weather-hurricane", "\U000F0898"},
- {"weather-dust", "\U000F1B5A"},
- {"help", "\U000F02D6"},
- {"water-off-outline", "\U000F1508"},
- {"water-outline", "\U000F0E0A"},
- {"water-alert-outline", "\U000F1503"},
- {"snowflake", "\U000F0717"},
- {"snowflake-alert", "\U000F0F29"},
- };
- // Show loading screen before data is received.
- if (id(initial_data_received) == false) {
- it.printf(240, 390, id(font_small_bold), TextAlign::TOP_CENTER, "VÄNTAR PÅ DATA...");
- } else {
- // Weather Section
- // it.image(0, 88, id(title_weather));
- it.printf(240, 84, id(font_title), TextAlign::TOP_CENTER, "VÄDER");
- it.printf(100, 158, id(font_mdi_large), TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_now).state.c_str()].c_str());
- it.printf(300, 158, id(font_large_bold), TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_now).state);
- it.printf(150, 275, id(font_mdi_medium), TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_wind_today).state.c_str()].c_str());
- it.printf(330, 275, id(font_mdi_medium), TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_rain_today).state.c_str()].c_str());
- it.printf(105, 332, id(font_small_book), TextAlign::TOP_CENTER, "%s", id(weather_timestamp_0).state.c_str());
- it.printf(105, 356, id(font_mdi_medium), TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_0).state.c_str()].c_str());
- it.printf(105, 404, id(font_small_bold), TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_0).state);
- it.printf(195, 332, id(font_small_book), TextAlign::TOP_CENTER, "%s", id(weather_timestamp_1).state.c_str());
- it.printf(195, 356, id(font_mdi_medium), TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_1).state.c_str()].c_str());
- it.printf(195, 404, id(font_small_bold), TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_1).state);
- it.printf(285, 332, id(font_small_book), TextAlign::TOP_CENTER, "%s", id(weather_timestamp_2).state.c_str());
- it.printf(285, 356, id(font_mdi_medium), TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_2).state.c_str()].c_str());
- it.printf(285, 404, id(font_small_bold), TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_2).state);
- it.printf(375, 332, id(font_small_book), TextAlign::TOP_CENTER, "%s", id(weather_timestamp_3).state.c_str());
- it.printf(375, 356, id(font_mdi_medium), TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_3).state.c_str()].c_str());
- it.printf(375, 404, id(font_small_bold), TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_3).state);
- // Train Service Section
- // it.image(0, 470, id(title_train));
- it.printf(240, 458, id(font_title), TextAlign::TOP_CENTER, "FINN");
- it.printf(240, 532, id(font_small_bold), TextAlign::TOP_CENTER, "%s", id(finn_mossen_weekday).state.c_str());
- it.print(150, 558, id(font_small_bold), TextAlign::TOP_CENTER, "LÄMNA");
- it.printf(150, 584, id(font_small_book), TextAlign::TOP_CENTER, "%s", id(finn_mossen_arrive).state.c_str());
- it.print(330, 558, id(font_small_bold), TextAlign::TOP_CENTER, "HÄMTA");
- it.printf(330, 584, id(font_small_book), TextAlign::TOP_CENTER, "%s", id(finn_mossen_depart).state.c_str());
- it.printf(240, 665, id(font_small_book), TextAlign::TOP_CENTER, "SENAST UPPDATERAD:", id(update_time).state.c_str());
- }
- captive_portal:
Advertisement
Add Comment
Please, Sign In to add comment