Skip to content

Instantly share code, notes, and snippets.

@g4bri3lDev
Last active January 29, 2025 19:07
Show Gist options
  • Select an option

  • Save g4bri3lDev/67088ab7a7ec605909f4d60299312910 to your computer and use it in GitHub Desktop.

Select an option

Save g4bri3lDev/67088ab7a7ec605909f4d60299312910 to your computer and use it in GitHub Desktop.
blueprint:
name: MVV Departure Board (960x672)
description: >
Update a 960x672 e-paper display with MVV departure information every 5 minutes.
Optionally only run if a specified person is home.
domain: automation
author: g4bri3lDev
source_url: https://gist.githubusercontent.com/g4bri3lDev/67088ab7a7ec605909f4d60299312910/raw/9b52f169039aabaddf24e1f45dcd313c5eae4e93/mvv_epaper_big_blueprint.yaml
input:
departure_sensor:
name: Departure Sensor
description: "Sensor containing the MVV departure info (and attributes)."
selector:
entity:
filter:
domain: sensor
integration: "munich_public_transport"
displays:
name: E-Paper Displays
description: "One or more e-paper displays that support open_epaper_link.drawcustom."
selector:
device:
filter:
integration: open_epaper_link
multiple: true
person:
name: Person (Optional)
description: >
If set, updates only when this person is home.
Leave blank to run unconditionally.
selector:
entity:
filter:
domain: person
default: ""
font_file:
name: Font File
description: "TTF filename/path for the e-paper text."
default: "ppb.ttf"
selector:
text: {}
mode: single
trigger:
- trigger: time_pattern
minutes: "/5"
variables:
# Entities
departure_sensor_entity: !input "departure_sensor"
person_entity: !input "person"
font_file: !input "font_file"
departures: >
{{ state_attr(departure_sensor_entity, 'departures') }}
station_name: >-
{% set friendly_name = state_attr(departure_sensor_entity, 'friendly_name') %}
{{ friendly_name.replace(' All Departures','') if friendly_name else '' }}
condition:
- condition: template
value_template: >-
{% if person_entity != '' %}
{{ is_state(person_entity, 'home') }}
{% else %}
true
{% endif %}
action:
- action: open_epaper_link.drawcustom
target:
device_id: !input "displays"
data:
background: white
rotate: 0
payload:
# - type: debug_grid
- type: text
value: "{{ station_name }}"
x: "50%"
y: 40
size: 50
anchor: mm
font: "{{ font_file }}"
- type: line
x_start: 0
x_end: 960
y_start: 80
fill: black
width: 2
- type: text
anchor: lm
x: 20
y: 70
value: Line
- type: text
anchor: lm
x: 130
y: 70
value: Destination
- type: text
anchor: rm
x: 820
y: 70
value: Occupancy
- type: text
anchor: rm
x: 960
y: 70
value: Departure
- type: rectangle_pattern
x_start: 20
y_start: 100
x_offset: 0
y_offset: 20
x_size: 80
y_size: 40
fill: r
outline: r
width: 1
x_repeat: 1
y_repeat: "{{ departures | length }}"
- type: multiline
delimiter: ";"
x: 60
font: "{{ font_file }}"
size: 40
start_y: 120
offset_y: 60
color: white
anchor: mm
value: >-
{% for departure in departures or [] %}
{{- departure.line -}}
{%- if not loop.last %};{% endif -%}
{% endfor %}
- type: multiline
delimiter: ";"
x: 130
font: "{{ font_file }}"
size: 50
start_y: 120
offset_y: 60
color: black
anchor: lm
value: >-
{% for departure in departures or [] %}
{{- (departure.destination[:21]) if departure.destination else '' -}}
{%- if not loop.last %};{% endif -%}
{% endfor %}
- type: icon_sequence
x: 790
y: 120
anchor: mm
direction: down
size: 50
spacing: 10
fill: black
icons: |-
[
{% for d in departures %}
{% if d.occupancy == 'HIGH' %}
"mdi:account-group"
{% elif d.occupancy == 'MEDIUM' %}
"mdi:account-multiple"
{% elif d.occupancy == 'LOW' %}
"mdi:account"
{% elif d.occupancy == 'UNKNOWN' %}
"mdi:help-circle-outline"
{% else %}
"mdi:help"
{% endif %}
{%- if not loop.last %}, {% endif -%}
{% endfor %}
]
- type: multiline
delimiter: ";"
x: 960
font: "{{ font_file }}"
size: 50
start_y: 120
offset_y: 60
color: black
anchor: rm
value: >-
{% for departure in departures or [] %}
{{- departure.realtime_departure if departure.realtime_departure else '' -}}
{%- if not loop.last %};{% endif -%}
{% endfor %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment