6 Commits

5 changed files with 240 additions and 94 deletions
+110 -67
View File
@@ -139,6 +139,10 @@
trigger: time trigger: time
conditions: [] conditions: []
actions: actions:
- action: notify.mobile_app_apollo
data:
message: Lodere es, Lustknabe.
title: 420!
- data: - data:
title: 420! title: 420!
message: Lodere es, Lustknabe. message: Lodere es, Lustknabe.
@@ -179,10 +183,6 @@
topic: awtrix_desk/notify topic: awtrix_desk/notify
payload: '{"text": "420, lodere es, Lustknabe!"}' payload: '{"text": "420, lodere es, Lustknabe!"}'
action: mqtt.publish action: mqtt.publish
- action: notify.mobile_app_apollo
data:
message: Lodere es, Lustknabe.
title: 420!
mode: single mode: single
- id: '1623911524804' - id: '1623911524804'
alias: TV Anti-Reflexion (undo) alias: TV Anti-Reflexion (undo)
@@ -227,28 +227,28 @@
action: light.turn_on action: light.turn_on
- data: - data:
cache: true cache: true
media_player_entity_id: media_player.home_assistant_voice_0a7c6b_media_player media_player_entity_id: media_player.home_assistant_voice_0a7c6b
message: Ab ins Bett, Schlafenszeit. message: Ab ins Bett, Schlafenszeit.
target: target:
entity_id: tts.piper entity_id: tts.piper
enabled: true
action: tts.speak action: tts.speak
enabled: true
- data: - data:
cache: true cache: true
media_player_entity_id: media_player.home_assistant_voice_09c0e7_media_player media_player_entity_id: media_player.home_assistant_voice_09c0e7_media_player_2
message: Ab ins Bett, Schlafenszeit. message: Ab ins Bett, Schlafenszeit.
target: target:
entity_id: tts.piper entity_id: tts.piper
enabled: true
action: tts.speak action: tts.speak
enabled: true
- data: - data:
cache: true cache: true
media_player_entity_id: media_player.m5stack_atom_echo media_player_entity_id: media_player.m5stack_atom_echo
message: Ab ins Bett, Schlafenszeit. message: Ab ins Bett, Schlafenszeit.
target: target:
entity_id: tts.piper entity_id: tts.piper
enabled: true
action: tts.speak action: tts.speak
enabled: true
mode: single mode: single
- id: '1623954512941' - id: '1623954512941'
alias: Licht im Schlafzimmer zum Aufwachen einschalten alias: Licht im Schlafzimmer zum Aufwachen einschalten
@@ -278,10 +278,8 @@
alias: 'Anruf: Beim Klingeln grün blinken' alias: 'Anruf: Beim Klingeln grün blinken'
description: '' description: ''
triggers: triggers:
- entity_id: - entity_id: sensor.fritz_box_7490_call_monitor_dem_commander1024_seine_cloud
- sensor.fritz_box_7690_anrufmonitor_dem_commander1024_seine_cloud to: ringing
to:
- ringing
trigger: state trigger: state
- entity_id: - entity_id:
- sensor.le2123_phone_state_2 - sensor.le2123_phone_state_2
@@ -303,8 +301,8 @@
- 0 - 0
target: target:
entity_id: entity_id:
- light.awtrix_b8658c_indicator_1 - light.awtrix_desk_indicator_1
- light.awtrix_528bd4_indicator_1 - light.awtrix_kitchen_indicator_1
action: light.turn_on action: light.turn_on
- data: - data:
scene_id: wled_last_state scene_id: wled_last_state
@@ -337,18 +335,16 @@
- data: {} - data: {}
target: target:
entity_id: entity_id:
- light.awtrix_b8658c_indicator_1 - light.awtrix_desk_indicator_1
- light.awtrix_528bd4_indicator_1 - light.awtrix_kitchen_indicator_1
action: light.turn_off action: light.turn_off
mode: single mode: single
- id: '1625481640348' - id: '1625481640348'
alias: 'Anruf: Beim Telefonieren Musik pausieren' alias: 'Anruf: Beim Telefonieren Musik pausieren'
description: '' description: ''
triggers: triggers:
- entity_id: - entity_id: sensor.fritz_box_7490_call_monitor_telefonbuch
- sensor.fritz_box_7690_anrufmonitor_dem_commander1024_seine_cloud to: talking
to:
- talking
trigger: state trigger: state
- entity_id: - entity_id:
- sensor.le2123_phone_state_2 - sensor.le2123_phone_state_2
@@ -366,8 +362,9 @@
- data: - data:
scene_id: media_last_state scene_id: media_last_state
snapshot_entities: snapshot_entities:
- media_player.wohnzimmer - media_player.wohnzimmer_main
- media_player.lg_webos_smart_tv - media_player.lg_webos_smart_tv
- media_player.ccze
- media_player.spotify_marcus_scholz - media_player.spotify_marcus_scholz
- media_player.xboxonex - media_player.xboxonex
action: scene.create action: scene.create
@@ -388,7 +385,7 @@
trigger: state trigger: state
- target: - target:
entity_id: entity_id:
- scene.wled_last_state - scene.media_last_state
action: scene.turn_on action: scene.turn_on
data: {} data: {}
mode: single mode: single
@@ -618,33 +615,12 @@
action: notify.mobile_app_le2123 action: notify.mobile_app_le2123
- data: - data:
cache: true cache: true
media_player_entity_id: media_player.home_assistant_voice_0a7c6b_media_player media_player_entity_id: media_player.raspiaudio_muse_luxe
message: '{{message}} message: '{{message}}
' '
target: target:
entity_id: tts.piper entity_id: tts.piper
enabled: true
action: tts.speak
- data:
cache: true
media_player_entity_id: media_player.home_assistant_voice_09c0e7_media_player
message: '{{message}}
'
target:
entity_id: tts.piper
enabled: true
action: tts.speak
- data:
cache: true
media_player_entity_id: media_player.m5stack_atom_echo
message: '{{message}}
'
target:
entity_id: tts.piper
enabled: true
action: tts.speak action: tts.speak
variables: variables:
message: 'Die Außentemperatur ist mit {{states(''sensor.aussentemperatur'')}} message: 'Die Außentemperatur ist mit {{states(''sensor.aussentemperatur'')}}
@@ -689,33 +665,12 @@
action: notify.mobile_app_le2123 action: notify.mobile_app_le2123
- data: - data:
cache: true cache: true
media_player_entity_id: media_player.home_assistant_voice_0a7c6b_media_player media_player_entity_id: media_player.raspiaudio_muse_luxe
message: '{{message}} message: '{{message}}
' '
target: target:
entity_id: tts.piper entity_id: tts.piper
enabled: true
action: tts.speak
- data:
cache: true
media_player_entity_id: media_player.home_assistant_voice_09c0e7_media_player
message: '{{message}}
'
target:
entity_id: tts.piper
enabled: true
action: tts.speak
- data:
cache: true
media_player_entity_id: media_player.m5stack_atom_echo
message: '{{message}}
'
target:
entity_id: tts.piper
enabled: true
action: tts.speak action: tts.speak
mode: single mode: single
variables: variables:
@@ -1438,3 +1393,91 @@
device_id: 6d1be741876624a70ab5b01b54c6fd6f device_id: 6d1be741876624a70ab5b01b54c6fd6f
entity_id: 621e4377a089b7f5d92c7c9f2cc171a1 entity_id: 621e4377a089b7f5d92c7c9f2cc171a1
domain: switch domain: switch
- id: '1773000000001'
alias: epaperframe - Kalender Events laden
description: Ruft alle Events von calendar.privat und calendar.tkrz_kalender für heute und morgen ab und schreibt sie in input_text-Helfer.
triggers:
# Täglich um 00:01 neu holen
- trigger: time
at: '00:01:00'
id: daily
actions:
# ── Events für heute (00:00 bis 23:59) holen ──
- action: calendar.get_events
target:
entity_id:
- calendar.privat
- calendar.tkrz_kalender
data:
start_date_time: "{{ now().replace(hour=0, minute=0, second=0) }}"
end_date_time: "{{ (now().replace(hour=0, minute=0, second=0) + timedelta(days=1)) }}"
response_variable: today_evts
# ── Events für morgen (00:00 bis 23:59) holen ──
- action: calendar.get_events
target:
entity_id:
- calendar.privat
- calendar.tkrz_kalender
data:
start_date_time: "{{ (now() + timedelta(days=1)).replace(hour=0, minute=0, second=0) }}"
end_date_time: "{{ (now() + timedelta(days=1)).replace(hour=0, minute=0, second=0) + timedelta(days=1) }}"
response_variable: tomorrow_evts
# ── input_text Helfer schreiben ──
- action: input_text.set_value
target:
entity_id: input_text.kalender_heute_privat
data:
value: >-
{%- set evts = today_evts['calendar.privat']['events'] if 'calendar.privat' in today_evts else [] -%}
{%- set items = [] -%}
{%- for e in evts[:5] -%}
{%- set s = (e['summary'] | default('', true) | string)[:40] if e is mapping and 'summary' in e else '-' -%}
{%- set st = e['start'] if e is mapping and 'start' in e else '' -%}
{%- set hhmm = st[11:16] if st|length >= 16 else '??' -%}
{%- set items = items + [hhmm ~ ' - ' ~ s] -%}
{%- endfor -%}
{{ items | join('│') if items else '-' }}
- action: input_text.set_value
target:
entity_id: input_text.kalender_heute_arbeit
data:
value: >-
{%- set evts = today_evts['calendar.tkrz_kalender']['events'] if 'calendar.tkrz_kalender' in today_evts else [] -%}
{%- set items = [] -%}
{%- for e in evts[:5] -%}
{%- set s = (e['summary'] | default('', true) | string)[:40] if e is mapping and 'summary' in e else '-' -%}
{%- set st = e['start'] if e is mapping and 'start' in e else '' -%}
{%- set hhmm = st[11:16] if st|length >= 16 else '??' -%}
{%- set items = items + [hhmm ~ ' - ' ~ s] -%}
{%- endfor -%}
{{ items | join('│') if items else '-' }}
- action: input_text.set_value
target:
entity_id: input_text.kalender_morgen_privat
data:
value: >-
{%- set evts = tomorrow_evts['calendar.privat']['events'] if 'calendar.privat' in tomorrow_evts else [] -%}
{%- set items = [] -%}
{%- for e in evts[:5] -%}
{%- set s = (e['summary'] | default('', true) | string)[:40] if e is mapping and 'summary' in e else '-' -%}
{%- set st = e['start'] if e is mapping and 'start' in e else '' -%}
{%- set hhmm = st[11:16] if st|length >= 16 else '??' -%}
{%- set items = items + [hhmm ~ ' - ' ~ s] -%}
{%- endfor -%}
{{ items | join('│') if items else '-' }}
- action: input_text.set_value
target:
entity_id: input_text.kalender_morgen_arbeit
data:
value: >-
{%- set evts = tomorrow_evts['calendar.tkrz_kalender']['events'] if 'calendar.tkrz_kalender' in tomorrow_evts else [] -%}
{%- set items = [] -%}
{%- for e in evts[:5] -%}
{%- set s = (e['summary'] | default('', true) | string)[:40] if e is mapping and 'summary' in e else '-' -%}
{%- set st = e['start'] if e is mapping and 'start' in e else '' -%}
{%- set hhmm = st[11:16] if st|length >= 16 else '??' -%}
{%- set items = items + [hhmm ~ ' - ' ~ s] -%}
{%- endfor -%}
{{ items | join('│') if items else '-' }}
+3
View File
@@ -49,6 +49,9 @@ sql:
# calendar integration # calendar integration
calendar: !include calendars.yaml calendar: !include calendars.yaml
# Helpers for epaperframe calendar display
input_text: !include text_helpers.yaml
# DB-recorder configuration # DB-recorder configuration
recorder: !include recorder.yaml recorder: !include recorder.yaml
+80 -27
View File
@@ -15,7 +15,7 @@ esphome:
priority: -10 priority: -10
then: then:
- delay: 10s - delay: 10s
- display.page.show: environment # temporary for power page dev - display.page.show: calendar # temporary for power page dev
- component.update: epaper - component.update: epaper
esp32: esp32:
@@ -23,10 +23,13 @@ esp32:
framework: framework:
type: esp-idf type: esp-idf
network:
enable_ipv6: true
wifi: wifi:
ssid: "Voltage-legacy" ssid: "Voltage-legacy"
password: !secret voltage_legacy_psk password: !secret voltage_legacy_psk
use_address: epaperframe.home # use_address: epaperframe.home
power_save_mode: high power_save_mode: high
fast_connect: on fast_connect: on
min_auth_mode: WPA2 min_auth_mode: WPA2
@@ -234,6 +237,27 @@ text_sensor:
entity_id: weather.zuhause entity_id: weather.zuhause
id: weather id: weather
# ── Kalender-Ereignisse (from HA input_text helpers) ──
- platform: homeassistant
entity_id: sensor.kalender_heute_privat
id: kalender_heute_privat
internal: true
- platform: homeassistant
entity_id: sensor.kalender_heute_arbeit
id: kalender_heute_arbeit
internal: true
- platform: homeassistant
entity_id: sensor.kalender_morgen_privat
id: kalender_morgen_privat
internal: true
- platform: homeassistant
entity_id: sensor.kalender_morgen_arbeit
id: kalender_morgen_arbeit
internal: true
graph: graph:
- id: line_power_graph - id: line_power_graph
sensor: power_total sensor: power_total
@@ -1132,45 +1156,74 @@ display:
it.image(10, 37, id(c1024_logo)); it.image(10, 37, id(c1024_logo));
/* ── LEFT PANE: Today ── */ /* ── LEFT PANE: Today ── */
int leftX = 0; int leftX = 10;
int leftY = 85; // start below header row int leftY = 70; // start below header row
it.print(10 + leftX, 10 + leftY, id(sensor_unit), "Heute"); it.print(15 + leftX, 10 + leftY, id(sensor_unit), "Heute");
it.filled_rectangle(64 + leftX, 21 + leftY, 370, 3); it.filled_rectangle(80 + leftX, 21 + leftY, 240, 3);
/* Today's date strip */ /* Today's date strip */
it.printf(50 + leftX, 50 + leftY, id(big_sensor_font), "%d", today_day); it.printf(50 + leftX, 50 + leftY, id(big_sensor_font), "%d", today_day);
it.printf(130 + leftX, 45 + leftY, id(sub_sensor_font), "%s.", today_weekday_str); it.printf(145 + leftX, 45 + leftY, id(sub_sensor_font), "%s.", today_weekday_str);
it.printf(160 + leftX, 45 + leftY, id(sensor_unit), "%02d.%04d.", today_month, today_year); it.printf(205 + leftX, 45 + leftY, id(sensor_unit), "%02d.%04d.", today_month, today_year);
/* Event placeholder row (top) */ /* Event lines (Privat / Arbeit) */
int eventOffsetY = 90; int eventOffsetY = 90;
it.print(10 + leftX, 50 + leftY + eventOffsetY, id(mdi_med), TextAlign::BASELINE_LEFT, "󰀦");
it.print(40 + leftX, 50 + leftY + eventOffsetY, id(sub_sensor_font), "Eintrag 1");
/* Event placeholder row (bottom) */ // Helper lambda: draw one event line at given Y offset with the given text sensor id
it.print(10 + leftX, 85 + leftY + eventOffsetY, id(mdi_med), TextAlign::BASELINE_LEFT, "󰀦"); // Privat today
it.print(40 + leftX, 85 + leftY + eventOffsetY, id(sub_sensor_font), "Eintrag 2"); if (id(kalender_heute_privat).has_state() && !id(kalender_heute_privat).state.empty()) {
it.print(10 + leftX, 50 + leftY + eventOffsetY, id(mdi_med), TextAlign::BASELINE_LEFT, "\U0001f32e" );
// Split by │ separator and display first line of events
auto parts = id(kalender_heute_privat).state.c_str();
it.printf(40 + leftX, 50 + leftY + eventOffsetY, id(sub_sensor_font), "%s",
id(kalender_heute_privat).state.substr(0, 60).c_str());
} else {
it.print(10 + leftX, 50 + leftY + eventOffsetY, id(mdi_med), TextAlign::BASELINE_LEFT, "\U0001f32e" );
it.printf(40 + leftX, 50 + leftY + eventOffsetY, id(sub_sensor_font), "Kein Termin");
}
// Arbeit today
if (id(kalender_heute_arbeit).has_state() && !id(kalender_heute_arbeit).state.empty()) {
it.print(10 + leftX, 85 + leftY + eventOffsetY, id(mdi_med), TextAlign::BASELINE_LEFT, "\U0001f32e" );
it.printf(40 + leftX, 85 + leftY + eventOffsetY, id(sub_sensor_font), "%s",
id(kalender_heute_arbeit).state.substr(0, 60).c_str());
} else {
it.print(10 + leftX, 85 + leftY + eventOffsetY, id(mdi_med), TextAlign::BASELINE_LEFT, "\U0001f32e" );
it.printf(40 + leftX, 85 + leftY + eventOffsetY, id(sub_sensor_font), "Kein Termin");
}
/* ── RIGHT PANE: Tomorrow ── */ /* ── RIGHT PANE: Tomorrow ── */
int rightX = 390; int rightX = 315;
int rightY = 85; int rightY = 70;
it.print(10 + rightX, 10 + rightY, id(sensor_unit), "Morgen"); it.print(45 + rightX, 10 + rightY, id(sensor_unit), "Morgen");
it.filled_rectangle(64 + rightX, 21 + rightY, 370, 3); it.filled_rectangle(130 + rightX, 21 + rightY, 200, 3);
/* Date strip */ /* Date strip */
it.printf(50 + rightX, 50 + rightY, id(big_sensor_font), "%d", tomorrow_day); it.printf(50 + rightX, 50 + rightY, id(big_sensor_font), "%d", tomorrow_day);
it.printf(130 + rightX, 45 + rightY, id(sub_sensor_font), "%s.", tomorrow_weekday_str); it.printf(145 + rightX, 45 + rightY, id(sub_sensor_font), "%s.", tomorrow_weekday_str);
it.printf(160 + rightX, 45 + rightY, id(sensor_unit), "%02d.%04d.", tomorrow_month, tomorrow_year); it.printf(205 + rightX, 45 + rightY, id(sensor_unit), "%02d.%04d.", tomorrow_month, tomorrow_year);
/* Event placeholder row (top) */ /* Event lines (Privat / Arbeit) */
it.print(10 + rightX, 50 + rightY + eventOffsetY, id(mdi_med), TextAlign::BASELINE_LEFT, "󰀦"); // Privat tomorrow
it.print(40 + rightX, 50 + rightY + eventOffsetY, id(sub_sensor_font), "Eintrag 1"); if (id(kalender_morgen_privat).has_state() && !id(kalender_morgen_privat).state.empty()) {
it.print(10 + rightX, 50 + rightY + eventOffsetY, id(mdi_med), TextAlign::BASELINE_LEFT, "\U0001f32e" );
/* Event placeholder row (bottom) */ it.printf(40 + rightX, 50 + rightY + eventOffsetY, id(sub_sensor_font), "%s",
it.print(10 + rightX, 85 + rightY + eventOffsetY, id(mdi_med), TextAlign::BASELINE_LEFT, "󰀦"); id(kalender_morgen_privat).state.substr(0, 60).c_str());
it.print(40 + rightX, 85 + rightY + eventOffsetY, id(sub_sensor_font), "Eintrag 2"); } else {
it.print(10 + rightX, 50 + rightY + eventOffsetY, id(mdi_med), TextAlign::BASELINE_LEFT, "\U0001f32e" );
it.printf(40 + rightX, 50 + rightY + eventOffsetY, id(sub_sensor_font), "Kein Termin");
}
// Arbeit tomorrow
if (id(kalender_morgen_arbeit).has_state() && !id(kalender_morgen_arbeit).state.empty()) {
it.print(10 + rightX, 85 + rightY + eventOffsetY, id(mdi_med), TextAlign::BASELINE_LEFT, "\U0001f32e" );
it.printf(40 + rightX, 85 + rightY + eventOffsetY, id(sub_sensor_font), "%s",
id(kalender_morgen_arbeit).state.substr(0, 60).c_str());
} else {
it.print(10 + rightX, 85 + rightY + eventOffsetY, id(mdi_med), TextAlign::BASELINE_LEFT, "\U0001f32e" );
it.printf(40 + rightX, 85 + leftY + eventOffsetY, id(sub_sensor_font), "Kein Termin");
}
/* FOOTER */ /* FOOTER */
it.strftime(614, 380, id(footer_font), TextAlign::BASELINE_RIGHT, "Aktualisiert um %d.%m.%Y %H:%M", id(homeassistant_time).now()); it.strftime(614, 380, id(footer_font), TextAlign::BASELINE_RIGHT, "Aktualisiert um %d.%m.%Y %H:%M", id(homeassistant_time).now());
+27
View File
@@ -145,3 +145,30 @@
unit_of_measurement: 'Mbps' unit_of_measurement: 'Mbps'
attributes: attributes:
last_reset: '1970-01-01T00:00:00+00:00' last_reset: '1970-01-01T00:00:00+00:00'
# ── Kalender-Ereignisse für epaperframe ──
# Alle Events werden per Automation (automations.yaml) in input_text Helfer geschrieben.
# Diese template sensors lesen nur noch daraus. Das verhindert doppelte Logik und garantiert,
# dass sowohl "heute" als auch "morgen" Events mit Titeln, Uhrzeiten und Beschreibungen verfügbar sind.
- sensor:
# ── HEUTE ──
- name: "Kalender heute Privat"
unique_id: kalender_heute_privat
state: "{{ states('input_text.kalender_heute_privat') }}"
icon: mdi:calendar-account
- name: "Kalender heute Arbeit"
unique_id: kalender_heute_arbeit
state: "{{ states('input_text.kalender_heute_arbeit') }}"
icon: mdi:calendar-account
# ── MORGEN ──
- name: "Kalender morgen Privat"
unique_id: kalender_morgen_privat
state: "{{ states('input_text.kalender_morgen_privat') }}"
icon: mdi:calendar-calendar-today
- name: "Kalender morgen Arbeit"
unique_id: kalender_morgen_arbeit
state: "{{ states('input_text.kalender_morgen_arbeit') }}"
icon: mdi:calendar-calendar-today
+20
View File
@@ -0,0 +1,20 @@
kalender_heute_privat:
name: "Kalender heute Privat"
initial: "-"
icon: mdi:calendar-account
mode: text
kalender_heute_arbeit:
name: "Kalender heute Arbeit"
initial: "-"
icon: mdi:calendar-account
mode: text
kalender_morgen_privat:
name: "Kalender morgen Privat"
initial: "-"
icon: mdi:calendar-calendar-today
mode: text
kalender_morgen_arbeit:
name: "Kalender morgen Arbeit"
initial: "-"
icon: mdi:calendar-calendar-today
mode: text