Zeige mir die zuletzt gestarteten Automatisationen und/oder Scripte mit Link direkt in den Editor-Modus

Im Post Übersicht über ausgelöste Automationen wurden einige Ideen diskutiert und ich hatte mich mit einer Markdownkarte eingebracht.

Diese hatte ich für den Urlaub auf der HA Startseite platziert. Es war einfach super, um auf einen Blick die letzten Aktionen zu sehen und bei Bedarf direkt in die Automatisation zu springen. Was mir fehlte, waren die Auflistung von gestarteten Scripten.

Genau das habe ich heute nachgeholt und stelle den Code für Nachbauer zur Verfügung.

Im Jinja Code der Markdownkarte läßt sich folgendes Verhalten konfigurieren.

  • Anzahl Stunden
  • Anzahl Haupteinträge
  • Sollen nur Automatisationen oder Scripte oder beides gelistet werden
  • Möglichkeit Namenskosmetik (z.B. finde “xyz” und ersetze durch “xxx”)
  • Möglichkeit bestimmte Automatisationen oder Scripte nicht anzuzeigen
  • Anzeige langer Namen begrenzen (besser auf Handy zu lesen)
  • Möglichkeit direkt in den Editor Modus der entsperechenden Aut. bzw. Scriptes zu springen

HowTo

  • Markdownkarte erstellen
  • Im Inhalt diesen Code hineinkopieren
  • Variablen anpassen
Zusammenfassung
{#
Version 2.2

Listet getriggerte Automatisationen und/oder Scripte
- der letzten xxx Stunden
- verschiebt ab xxx unter "mehr als" Teil
- kann wahlweise Automatisationen und/oder Scripte berücksichtigen
- versieht Namen der Automatisation mit Präfix "a_" sowie Scripte mit "s_"
- kann Namenskosmetik vornehmen (ersetze "xyz" durch "xxx")
- kann bestimmte Automatisationen/Scripte ignorieren
- Kann auf bestimmte Namenslänge reduzieren (z.B. für bessere Lesbarkeit auf Handy)
#}

<!--+++ Individuelle Konfiguration +++-->

<!-- Wieviel Stunden soll zurückgegangen werden -->
{%- set shown_last_hours = 24 -%}
<!-- Wieviel Haupteinträge (Rest über "mehr" Dialog) -->
{%- set show_always = 10 -%}
<!-- Sollen Automatisationen und/ oder Scripte angezeigt werden -->
{%- set show_autom = true -%}
{%- set show_script = true -%}
<!-- Ausschluß von Automatisationen mit diesen Namensteilen werden nicht angezeigt  -->
{%- set exceptions = ['ping_custom', 'xxxxx'] -%} 
<!-- Diese Namensteil werden ersetzt z.B. "om_aut" durch "" (case sensitive) -->
{%- set name_replacements = {
  'om_scr_': '',
  'om_aut_': '',
  'tech_': '',
  'draussen_': 'drau_',
  'mitte_': 'mitt_',
  'unten_': 'unt_',
  'oben_': 'ob_'
} -%}
<!-- max. Zeichen Namensdarstellung -->
{%- set name_max = 40 -%}
<!-- Andere zentrale Variablen -->
{%- set now_ts = as_timestamp(now()) -%}
{%- set ns = namespace(entries=[]) -%}


<!--+++ Auslesen/Bearbeiten der Automatisationen +++-->
{% if show_autom -%}
  {%- for state in states.automation
    | selectattr('attributes.last_triggered', 'defined')
    | rejectattr('attributes.last_triggered', 'equalto', none)
    | sort(attribute='attributes.last_triggered', reverse=true) -%}
    {%- set ts = as_timestamp(state.attributes.last_triggered) -%}
    {%- if ts is number and (now_ts - ts < shown_last_hours * 3600) -%}
      {%- set raw_name = state.name | string -%}

      {# Ausschluß bestimmter Automatisationen #}
      {%- if (exceptions | select('in', raw_name) | list | count) == 0 -%}

        {# Ersetzen von Namensteilen + Präfix "a_" #}
        {%- set name_ns = namespace(name=raw_name) -%}
        {%- for old, new in name_replacements.items() -%}
          {%- set name_ns.name = name_ns.name | replace(old, new) -%}
        {%- endfor -%}
        {%- set prefix = 'a_' -%}
        {%- set cleaned_name = prefix ~ name_ns.name -%}
        {%- if cleaned_name | length > name_max -%}
          {%- set cleaned_name = cleaned_name[:name_max] ~ '…' -%}
        {%- endif -%}

        {%- set t = ts | timestamp_custom('%H:%M:%S', true) -%}
        
        {# nur mit der ID läßt sich in den Editor Modus springen #}
        {%- if 'id' in state.attributes -%}
          {%- set link = '/config/automation/edit/' ~ state.attributes.id -%}
        {%- else -%}
          {%- set link = '/config/automation/edit/' ~ state.entity_id | replace('automation.', '') -%}
        {%- endif -%}
        {%- set ns.entries = ns.entries + [(ts, t, cleaned_name, link)] -%}
      {%- endif -%}
    {%- endif -%}
  {%- endfor -%}
{%- endif -%}


<!--+++ Auslesen/Bearbeiten der Scripte +++-->
{# Ohne weitere Kommentare da sehr ähnlich zu obigen Automatisationsblock #}
{% if show_script -%}
  {%- for state in states.script
    | selectattr('attributes.last_triggered', 'defined')
    | rejectattr('attributes.last_triggered', 'equalto', none)
    | sort(attribute='attributes.last_triggered', reverse=true) -%}
    {%- set ts = as_timestamp(state.attributes.last_triggered) -%}
    {%- if ts is number and (now_ts - ts < shown_last_hours * 3600) -%}
      {%- set raw_name = state.name | string -%}
      {%- if (exceptions | select('in', raw_name) | list | count) == 0 -%}
        {%- set name_ns = namespace(name=raw_name) -%}
        {%- for old, new in name_replacements.items() -%}
          {%- set name_ns.name = name_ns.name | replace(old, new) -%}
        {%- endfor -%}
        {%- set prefix = 's_' -%}
        {%- set cleaned_name = prefix ~ name_ns.name -%}
        {%- if cleaned_name | length > name_max -%}
          {%- set cleaned_name = cleaned_name[:name_max] ~ '…' -%}
        {%- endif -%}
        {%- set t = ts | timestamp_custom('%H:%M:%S', true) -%}
        {%- if 'id' in state.attributes -%}
          {%- set link = '/config/script/edit/' ~ state.attributes.id -%}
        {%- else -%}
          {%- set link = '/config/script/edit/' ~ state.entity_id | replace('script.', '') -%}
        {%- endif -%}
        {%- set ns.entries = ns.entries + [(ts, t, cleaned_name, link)] -%}
      {%- endif -%}
    {%- endif -%}
  {%- endfor -%}
{%- endif -%}


<!--+++ Ausgabe: Ab hier mit Vorsicht ändern. HTML Konstrukte in Markdownkarte sind fragil ("-%} = wichtig") +++-->

### In den letzten {{ shown_last_hours }} Stunden

{% if show_autom or show_script -%}
{%- set sorted = ns.entries | sort(attribute=0, reverse=true) -%}

<table border=0>
  {%- for row in sorted[:show_always] -%}
    <tr>
      <td>{{ row[1] }}</td>
      <td><a href="{{ row[3] }}">{{ row[2] }}</a></td>
    </tr>
  {%- endfor -%}
</table>

{%- if sorted | length > show_always -%}
<br>
<details>
  <summary><b>mehr als {{show_always}} Einträge zeigen</b></summary>
  <table border=0>
    {%- for row in sorted[show_always:] -%}
      <tr>
        <td>{{ row[1] }}</td>
        <td><a href="{{ row[3] }}">{{ row[2] }}</a></td>
      </tr>
    {%- endfor -%}
  </table>
</details>
{%- endif -%}
{%- else -%}
Laut Deiner Konfiguration der Variablen sollen weder Automatisationen noch Scripte angezeigt werden.
{%- endif -%}

Viel Spaß beimn Probieren und bitte publiziert nützliche Änderungen.
Und wenn es Fehler gibt, unbedingt auch diese.

7 „Gefällt mir“

Sehr schöne Idee, habe ich direkt übernommen. Allerdings scheint bei mir die Zeitspanne nicht zu passen. Statt 24 Stunden zurück, werden bei mir nur ca. 16 Stunden zurück angezeigt.

Hast du eine Idee woran das liegen könnte?
Edit: Habe gerade gesehen, dass die 16 Stunden zufällig waren. Es werden bei „Mehr als 10 …“ einfach nochmal 10 angezeigt. Anstatt alle im Zeitraum bis 24 Stunden. Allerdings selbst wenn ich von 24 auf 48 ändere. Und einige, bei denen ich weiß das sie gelaufen, werden komplett ausgelassen? Ich weiß nur nicht wieso.

Und zweite Frage: Kennst du einen Weg, dass die Hyperlinks nicht unterstrichen und nicht blau hervorgehoben sind?
So funktioniert es leider nicht:

<td><a href="{{ row[3] }}" style="color: inherit; text-decoration: none;">{{ row[2] }}</a></td>

Bin gerade erst hierüber gestolpert. Zuerst einmal erbleiche ich in Ehrfurcht wegen deiner Mühe. Bis ich soweit in den Jinja-Code eingestiegen wäre, würden wahrscheinlich Jahre vergehen. Deswegen erst einmal meinen größten Dank an dich.

Aber eine Sache würde ich für mich gern ändern: wenn ich es richtig sehe, wird jede getriggerte Automation aufgenommen, auch wenn sie aufgrund einer Folgebedingung keine Aktion ausgelöst hat. Das ist mir ein wenig zu viel Information. Wäre es auch irgendwie möglich, nur die Automationen aufzulisten, die auch eine Aktion ausgelöst haben?

Danke für die netten Worte aber nicht alles ist von mir. Die Kernidee dieses Code habe ich aus dem anderen Post. Und, so hätte ich vor 2 Jahren auch gedacht aber es gab und gibt immer Leute hier mit sehr guten Jinja Kenntnissen von deren Beispielen man in Häppchen lernen/probieren kann. Und die KI kannst Du auch immer befragen aber mit Vorsicht.

Nun, zu Deiner Idee. Ich finde kein Kriterium, an denen sich unterscheiden läßt ob eine Automatisation nur ein Script triggert oder selbst etwas macht oder etwas von beiden. ChatGPT spricht bspw. von dem Attribut last_action was wieder mal frei erfunden ist.

Pragmatisch würde ich so vorgehen:

  • Ich würde alle Deine Automatisationen durchgehen und bei denen, die Du dort nicht gelistet haben willst und hänge ihn ein “__card_exclude” an.
  • Dann suchst Du Dir im oberen Code die Zeile

{%- set exceptions = ['ping_custom', 'xxxxx'] -%}
und setzt dort ein
{%- set exceptions = ['ping_custom', '__card_exclude'] -%}

Damit werden diese nicht gelistet.

Hm, bei mir sind es heute knapp 22 h aber 22-24 h ist ganz sicher auch etwas gestartet wurden. Verändere ich auf 27 h
image
sehe ich eine Lücke zwischen 18:15 und 14:38. Schaue ich in das Logbook (Aktivitäten), dann sind dort auch andere Automatisationen gestartet wurden.

Interessant und nein, ich habe keine Idee.
Ich habe mal mit 1 und 2 h probiert und entsprechend wird alles richtig angezeigt.

Nach etwas Probieren mit Card_mod hatte ich es.
Wichtig, Du darfst den Code nicht im Markdown Editor einsetzen (wie den anderen Code) sondern vorher “Code-Editor anzeigen”.

card_mod:
  style:
    ha-markdown$: |
      a {
        color: var(--primary-text-color) !important;
        text-decoration: none !important;
      }
1 „Gefällt mir“

Habe in meinem Beitrag ergänzt, dass bei mir auch Einträge fehlen. Komisch.

Danke für den Tipp mit card_mod. Probiere ich später mal, muss sozialen Geflogenheiten nachgehen. :sweat_smile:

Ich auch, ein Pärchen mit 2 Kleinkindern ist angekommen. Selbst wenn ich es wollte, da ist keine Denksport möglich :slight_smile:

Das kann ich nachvollziehen. :wink:

Card_mod hat prima geklappt. Auf die Idee bin ich gar nicht gekommen und habe es die ganze Zeit versucht im HTML zu lösen. Manchmal hat man einfach ein Brett vor dem Kopf. Danke nochmals!

Das mit der lückenhaften Ausgabe muss ich mir noch mal genauer ansehen. Aber das ist so komplex, da muss man erst einmal durchblicken. :sweat_smile:

Schönen Sonntag

Update: Mir ist aufgefallen:

  • Bei derselben Automation die mehrmals im definierten Zeitraum gelaufen ist, wird immer nur die letzte bzw. aktuellste Ausführung angezeigt.

Wir können/müssen uns darauf verlassen wie States und hier states.automisation in HA gepflegt wird.

Der obige Jinja Code liest es nur selektiv aus. Ich finde die Lücken auch erstaunlich aber ich will die Karte auf der Startseite nicht mehr missen, ein erster Blick was gerade so passierte. Eine echte Fehleranalyse wird das nicht ersetzen aber es ist mein erste Stelle wo ich gelernt habe zu schauen.

Seit dem HA Update 2025.12.x erzwingt das <table> Element Tabellenbordes <table border=0> geht nicht mehr, was unschön ist. Aber man kann dies mit Card_Mod erzwingen was in diesem Konstrukt sowieso verwendet wird. Die Anpassung ist:

card_mod:
  style:
    ha-markdown $:
      ha-markdown-element: |
        a {
          color: var(--primary-text-color) !important;
          text-decoration: none !important;
        }
        td {
          border: 0 !important;
          padding-top: 0px  !important;
        }