|
|
|
@ -5,6 +5,10 @@
|
|
|
|
|
# Cue "Blame it on the Weatherman" by B*Witched!
|
|
|
|
|
esphome:
|
|
|
|
|
name: "weatherman"
|
|
|
|
|
on_boot:
|
|
|
|
|
priority: 200.0
|
|
|
|
|
then:
|
|
|
|
|
- component.update: eink_display
|
|
|
|
|
|
|
|
|
|
esp32:
|
|
|
|
|
board: esp32dev
|
|
|
|
@ -19,6 +23,33 @@ api:
|
|
|
|
|
|
|
|
|
|
ota:
|
|
|
|
|
|
|
|
|
|
globals:
|
|
|
|
|
- id: data_updated
|
|
|
|
|
type: bool
|
|
|
|
|
restore_value: no
|
|
|
|
|
initial_value: 'false'
|
|
|
|
|
- id: initial_data_received
|
|
|
|
|
type: bool
|
|
|
|
|
restore_value: no
|
|
|
|
|
initial_value: 'false'
|
|
|
|
|
|
|
|
|
|
time:
|
|
|
|
|
- platform: homeassistant
|
|
|
|
|
id: homeassistant_time
|
|
|
|
|
on_time:
|
|
|
|
|
- seconds: 30
|
|
|
|
|
then:
|
|
|
|
|
- if:
|
|
|
|
|
condition:
|
|
|
|
|
lambda: 'return id(data_updated) == true;'
|
|
|
|
|
then:
|
|
|
|
|
- lambda: 'id(initial_data_received) = true;'
|
|
|
|
|
- logger.log: "Sensor data updated: Refreshing display..."
|
|
|
|
|
- component.update: eink_display
|
|
|
|
|
- lambda: 'id(data_updated) = false;'
|
|
|
|
|
else:
|
|
|
|
|
- logger.log: "No sensors updated - skipping display refresh."
|
|
|
|
|
|
|
|
|
|
wifi:
|
|
|
|
|
ssid: !secret wifi_ssid
|
|
|
|
|
password: !secret wifi_password
|
|
|
|
@ -103,42 +134,69 @@ sensor:
|
|
|
|
|
- platform: homeassistant
|
|
|
|
|
entity_id: sensor.gtfs_mta_subway_manhattan
|
|
|
|
|
id: train_manhattan_due_in
|
|
|
|
|
on_value:
|
|
|
|
|
then:
|
|
|
|
|
- lambda: 'id(data_updated) = true;'
|
|
|
|
|
|
|
|
|
|
- platform: homeassistant
|
|
|
|
|
entity_id: sensor.gtfs_mta_subway_canarsie
|
|
|
|
|
id: train_canarsie_due_in
|
|
|
|
|
on_value:
|
|
|
|
|
then:
|
|
|
|
|
- lambda: 'id(data_updated) = true;'
|
|
|
|
|
|
|
|
|
|
- platform: homeassistant
|
|
|
|
|
entity_id: sensor.gtfs_mta_subway_manhattan
|
|
|
|
|
attribute: Next bus due in
|
|
|
|
|
id: train_manhattan_next_train_due_in
|
|
|
|
|
on_value:
|
|
|
|
|
then:
|
|
|
|
|
- lambda: 'id(data_updated) = true;'
|
|
|
|
|
|
|
|
|
|
- platform: homeassistant
|
|
|
|
|
entity_id: sensor.gtfs_mta_subway_canarsie
|
|
|
|
|
attribute: Next bus due in
|
|
|
|
|
id: train_canarsie_next_train_due_in
|
|
|
|
|
on_value:
|
|
|
|
|
then:
|
|
|
|
|
- lambda: 'id(data_updated) = true;'
|
|
|
|
|
|
|
|
|
|
- platform: homeassistant
|
|
|
|
|
entity_id: weather.hourly
|
|
|
|
|
attribute: temperature
|
|
|
|
|
id: weather_temperature
|
|
|
|
|
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;'
|
|
|
|
|
|
|
|
|
|
- platform: wifi_signal
|
|
|
|
|
name: "WiFi Signal Sensor"
|
|
|
|
@ -151,78 +209,132 @@ text_sensor:
|
|
|
|
|
entity_id: sensor.gtfs_mta_subway_manhattan
|
|
|
|
|
attribute: Due at
|
|
|
|
|
id: train_manhattan_due_at
|
|
|
|
|
on_value:
|
|
|
|
|
then:
|
|
|
|
|
- lambda: 'id(data_updated) = true;'
|
|
|
|
|
|
|
|
|
|
- platform: homeassistant
|
|
|
|
|
entity_id: sensor.gtfs_mta_subway_canarsie
|
|
|
|
|
attribute: Due at
|
|
|
|
|
id: train_canarsie_due_at
|
|
|
|
|
on_value:
|
|
|
|
|
then:
|
|
|
|
|
- lambda: 'id(data_updated) = true;'
|
|
|
|
|
|
|
|
|
|
- platform: homeassistant
|
|
|
|
|
entity_id: sensor.gtfs_mta_subway_manhattan
|
|
|
|
|
attribute: Next bus
|
|
|
|
|
id: train_manhattan_next_train_due_at
|
|
|
|
|
on_value:
|
|
|
|
|
then:
|
|
|
|
|
- lambda: 'id(data_updated) = true;'
|
|
|
|
|
|
|
|
|
|
- platform: homeassistant
|
|
|
|
|
entity_id: sensor.gtfs_mta_subway_canarsie
|
|
|
|
|
attribute: Next bus
|
|
|
|
|
id: train_canarsie_next_train_due_at
|
|
|
|
|
on_value:
|
|
|
|
|
then:
|
|
|
|
|
- lambda: 'id(data_updated) = true;'
|
|
|
|
|
|
|
|
|
|
- platform: homeassistant
|
|
|
|
|
entity_id: sensor.mta_subway_l_service_status
|
|
|
|
|
id: train_service_status
|
|
|
|
|
on_value:
|
|
|
|
|
then:
|
|
|
|
|
- lambda: 'id(data_updated) = true;'
|
|
|
|
|
|
|
|
|
|
- platform: homeassistant
|
|
|
|
|
entity_id: weather.hourly
|
|
|
|
|
id: weather_state
|
|
|
|
|
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_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
|
|
|
|
|
on_value:
|
|
|
|
|
then:
|
|
|
|
|
- lambda: 'id(data_updated) = true;'
|
|
|
|
|
- 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.weatherman_data
|
|
|
|
|
attribute: train_status
|
|
|
|
|
id: train_status
|
|
|
|
|
on_value:
|
|
|
|
|
then:
|
|
|
|
|
- lambda: 'id(data_updated) = true;'
|
|
|
|
|
- platform: homeassistant
|
|
|
|
|
entity_id: sensor.weatherman_data
|
|
|
|
|
attribute: train_status_manhattan
|
|
|
|
|
id: train_status_manhattan
|
|
|
|
|
on_value:
|
|
|
|
|
then:
|
|
|
|
|
- lambda: 'id(data_updated) = true;'
|
|
|
|
|
- platform: homeassistant
|
|
|
|
|
entity_id: sensor.weatherman_data
|
|
|
|
|
attribute: train_status_canarsie
|
|
|
|
|
id: train_status_canarsie
|
|
|
|
|
on_value:
|
|
|
|
|
then:
|
|
|
|
|
- lambda: 'id(data_updated) = true;'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Define colors
|
|
|
|
@ -254,7 +366,8 @@ display:
|
|
|
|
|
busy_pin: GPIO25
|
|
|
|
|
reset_pin: GPIO26
|
|
|
|
|
model: 7.50inV2
|
|
|
|
|
update_interval: 2h # A shorter update interval will damage the screen.
|
|
|
|
|
update_interval: never
|
|
|
|
|
id: eink_display
|
|
|
|
|
rotation: 90°
|
|
|
|
|
lambda: |-
|
|
|
|
|
// Map weather states to MDI characters.
|
|
|
|
@ -295,44 +408,50 @@ display:
|
|
|
|
|
// Fill background in black.
|
|
|
|
|
it.fill(color_black);
|
|
|
|
|
|
|
|
|
|
// Weather Section
|
|
|
|
|
it.image(0, 88, id(title_weather));
|
|
|
|
|
|
|
|
|
|
it.printf(100, 158, id(font_mdi_large), color_white, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_now).state.c_str()].c_str());
|
|
|
|
|
|
|
|
|
|
it.printf(300, 158, id(font_large_bold), color_white, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature).state);
|
|
|
|
|
|
|
|
|
|
it.printf(105, 282, id(font_small_book), color_white, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_0).state.c_str());
|
|
|
|
|
it.printf(105, 306, id(font_mdi_medium), color_white, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_0).state.c_str()].c_str());
|
|
|
|
|
it.printf(105, 354, id(font_small_bold), color_white, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_0).state);
|
|
|
|
|
|
|
|
|
|
it.printf(195, 282, id(font_small_book), color_white, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_1).state.c_str());
|
|
|
|
|
it.printf(195, 306, id(font_mdi_medium), color_white, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_1).state.c_str()].c_str());
|
|
|
|
|
it.printf(195, 354, id(font_small_bold), color_white, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_1).state);
|
|
|
|
|
|
|
|
|
|
it.printf(285, 282, id(font_small_book), color_white, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_2).state.c_str());
|
|
|
|
|
it.printf(285, 306, id(font_mdi_medium), color_white, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_2).state.c_str()].c_str());
|
|
|
|
|
it.printf(285, 354, id(font_small_bold), color_white, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_2).state);
|
|
|
|
|
|
|
|
|
|
it.printf(375, 282, id(font_small_book), color_white, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_3).state.c_str());
|
|
|
|
|
it.printf(375, 306, id(font_mdi_medium), color_white, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_3).state.c_str()].c_str());
|
|
|
|
|
it.printf(375, 354, id(font_small_bold), color_white, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_3).state);
|
|
|
|
|
|
|
|
|
|
// Train Service Section
|
|
|
|
|
it.image(0, 420, id(title_train));
|
|
|
|
|
it.printf(240, 480, id(font_medium_bold), color_white, TextAlign::TOP_CENTER, "%s", id(train_status).state.c_str());
|
|
|
|
|
|
|
|
|
|
it.print(150, 536, id(font_small_bold), color_white, TextAlign::TOP_CENTER, "TO MANHATTAN");
|
|
|
|
|
it.print(330, 536, id(font_small_bold), color_white, TextAlign::TOP_CENTER, "TO CANARSIE");
|
|
|
|
|
|
|
|
|
|
it.printf(150, 576, id(font_medium_bold), color_white, TextAlign::TOP_CENTER, "%2.0f MIN", id(train_manhattan_due_in).state);
|
|
|
|
|
it.printf(330, 576, id(font_medium_bold), color_white, TextAlign::TOP_CENTER, "%2.0f MIN", id(train_canarsie_due_in).state);
|
|
|
|
|
it.printf(150, 608, id(font_small_book), color_white, TextAlign::TOP_CENTER, "%s", id(train_manhattan_due_at).state.c_str());
|
|
|
|
|
it.printf(330, 608, id(font_small_book), color_white, TextAlign::TOP_CENTER, "%s", id(train_canarsie_due_at).state.c_str());
|
|
|
|
|
|
|
|
|
|
it.printf(150, 652, id(font_medium_bold), color_white, TextAlign::TOP_CENTER, "%2.0f MIN", id(train_manhattan_next_train_due_in).state);
|
|
|
|
|
it.printf(330, 652, id(font_medium_bold), color_white, TextAlign::TOP_CENTER, "%2.0f MIN", id(train_canarsie_next_train_due_in).state);
|
|
|
|
|
it.printf(150, 684, id(font_small_book), color_white, TextAlign::TOP_CENTER, "%s", id(train_manhattan_next_train_due_at).state.c_str());
|
|
|
|
|
it.printf(330, 684, id(font_small_book), color_white, TextAlign::TOP_CENTER, "%s", id(train_canarsie_next_train_due_at).state.c_str());
|
|
|
|
|
|
|
|
|
|
captive_portal:
|
|
|
|
|
if (id(initial_data_received) == false) {
|
|
|
|
|
// ATTENTION!
|
|
|
|
|
// Please adjust coordinates I have a different display!
|
|
|
|
|
// ATTENTION!
|
|
|
|
|
it.printf(0, 420, id(font_small_bold), color_white, TextAlign::TOP_CENTER, "Waiting for data...");
|
|
|
|
|
} else {
|
|
|
|
|
// Weather Section
|
|
|
|
|
it.image(0, 88, id(title_weather));
|
|
|
|
|
|
|
|
|
|
it.printf(100, 158, id(font_mdi_large), color_white, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_now).state.c_str()].c_str());
|
|
|
|
|
|
|
|
|
|
it.printf(300, 158, id(font_large_bold), color_white, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature).state);
|
|
|
|
|
|
|
|
|
|
it.printf(105, 282, id(font_small_book), color_white, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_0).state.c_str());
|
|
|
|
|
it.printf(105, 306, id(font_mdi_medium), color_white, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_0).state.c_str()].c_str());
|
|
|
|
|
it.printf(105, 354, id(font_small_bold), color_white, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_0).state);
|
|
|
|
|
|
|
|
|
|
it.printf(195, 282, id(font_small_book), color_white, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_1).state.c_str());
|
|
|
|
|
it.printf(195, 306, id(font_mdi_medium), color_white, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_1).state.c_str()].c_str());
|
|
|
|
|
it.printf(195, 354, id(font_small_bold), color_white, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_1).state);
|
|
|
|
|
|
|
|
|
|
it.printf(285, 282, id(font_small_book), color_white, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_2).state.c_str());
|
|
|
|
|
it.printf(285, 306, id(font_mdi_medium), color_white, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_2).state.c_str()].c_str());
|
|
|
|
|
it.printf(285, 354, id(font_small_bold), color_white, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_2).state);
|
|
|
|
|
|
|
|
|
|
it.printf(375, 282, id(font_small_book), color_white, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_3).state.c_str());
|
|
|
|
|
it.printf(375, 306, id(font_mdi_medium), color_white, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_3).state.c_str()].c_str());
|
|
|
|
|
it.printf(375, 354, id(font_small_bold), color_white, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_3).state);
|
|
|
|
|
|
|
|
|
|
// Train Service Section
|
|
|
|
|
it.image(0, 420, id(title_train));
|
|
|
|
|
it.printf(240, 480, id(font_medium_bold), color_white, TextAlign::TOP_CENTER, "%s", id(train_status).state.c_str());
|
|
|
|
|
|
|
|
|
|
it.print(150, 536, id(font_small_bold), color_white, TextAlign::TOP_CENTER, "TO MANHATTAN");
|
|
|
|
|
it.print(330, 536, id(font_small_bold), color_white, TextAlign::TOP_CENTER, "TO CANARSIE");
|
|
|
|
|
|
|
|
|
|
it.printf(150, 576, id(font_medium_bold), color_white, TextAlign::TOP_CENTER, "%2.0f MIN", id(train_manhattan_due_in).state);
|
|
|
|
|
it.printf(330, 576, id(font_medium_bold), color_white, TextAlign::TOP_CENTER, "%2.0f MIN", id(train_canarsie_due_in).state);
|
|
|
|
|
it.printf(150, 608, id(font_small_book), color_white, TextAlign::TOP_CENTER, "%s", id(train_manhattan_due_at).state.c_str());
|
|
|
|
|
it.printf(330, 608, id(font_small_book), color_white, TextAlign::TOP_CENTER, "%s", id(train_canarsie_due_at).state.c_str());
|
|
|
|
|
|
|
|
|
|
it.printf(150, 652, id(font_medium_bold), color_white, TextAlign::TOP_CENTER, "%2.0f MIN", id(train_manhattan_next_train_due_in).state);
|
|
|
|
|
it.printf(330, 652, id(font_medium_bold), color_white, TextAlign::TOP_CENTER, "%2.0f MIN", id(train_canarsie_next_train_due_in).state);
|
|
|
|
|
it.printf(150, 684, id(font_small_book), color_white, TextAlign::TOP_CENTER, "%s", id(train_manhattan_next_train_due_at).state.c_str());
|
|
|
|
|
it.printf(330, 684, id(font_small_book), color_white, TextAlign::TOP_CENTER, "%s", id(train_canarsie_next_train_due_at).state.c_str());
|
|
|
|
|
}
|
|
|
|
|
captive_portal:
|