Sprawdzanie czy zamknięte są wszystkie okna

Chcę stworzyć przycisk, który po wciśnięciu będzie sprawdzał czy zamknięte są wszystkie okna.
W momencie nie zamknięcia któregoś pojawia się komunikat które okno jest otwarte.
Mam czujniki otwarcia/zamknięcia okna dodane już do home assistant z encją np: sensor.lazienka_okno_1
Do scryptów dodałem coś takiego

alias: Sprawdź okna
sequence:
  - service: browser_mod.popup
    data:
      title: Sprawdzenie okien
      content: >
        {% set okna = [
          'sensor.salon_okno_1',
          'sensor.sypialnia_okno_1',
          'sensor.lazienka_okno_1'
        ] %}
        {% set lista = [] %}
        {% for okno in okna %}
          {% if states(okno) == 'on' %}
            {% set nazwa = state_attr(okno, 'friendly_name') or okno %}
            {% set lista = lista + [nazwa] %}
          {% endif %}
        {% endfor %}
        {% if lista | count > 0 %}
          Otwartych okien: {{ lista | count }}  
          {{ lista | join(', ') }}
        {% else %}
          Wszystkie okna są zamknięte.
        {% endif %}
      dismissable: true
mode: single

Dodałem przycisk

show_name: true
show_icon: true
type: button
name: Sprawdź okna
icon: mdi:window-closed
tap_action:
  action: call-service
  service: script.sprawdz_okna

Ale jest problem bo za każdym razem nawet jak mam otwarte okno to i tak wyskakuje mi okno że wszystkie okna mam zamknięte.

A może tak, sprawdza dynamicznie:
Wszystkie zamknięte


Jedno otwarte:

Szablon:

{% set drzwi_wejsciowe = is_state('binary_sensor.on_off_frontowe_contact', 'on') %}
        {% set drzwi_ogrodowe = is_state('binary_sensor.on_off_ogrodowe_contact', 'on') %}
        {% set okno_salon = is_state('binary_sensor.on_off_okno_salon_contact', 'on') %}

        {% set lista = [] %}
        {% if drzwi_wejsciowe %}{% set lista = lista + ['drzwi wejściowe'] %}{% endif %}
        {% if drzwi_ogrodowe %}{% set lista = lista + ['drzwi ogrodowe'] %}{% endif %}
        {% if okno_salon %}{% set lista = lista + ['okno w salonie'] %}{% endif %}

        {{ 'Wszystko zamknięte' if lista | length == 0 else 'Otwarte: ' ~ lista | join(', ') }}

Problem masz w zacytowanym fragmencie, zmienna lista wymaga innej deklaracji, aby istniała wewnątrz bloku for. To jest specyficzna “przypadłość” jinja:

        {% set lista = namespace(x=[]) %}
        {% for okno in okna %}
          {% if states(okno) == 'on' %}
            {% set nazwa = state_attr(okno, 'friendly_name') or okno %}
            {% set lista.x = lista.x + [nazwa] %}
          {% endif %}
        {% endfor %}

I dalej używasz lista.x zamiast lista.

2 polubienia

Można też utworzyć grupę okien, gdy jedno jest otwarte zwraca otwarte.

2 polubienia

Teraz działa

alias: Sprawdź okna
sequence:
  - data:
      title: Sprawdzenie okien
      content:
        type: markdown
        content: >
          {% set okna = [
            'sensor.salon_okno_1',
            'sensor.sypialnia_okno_1',
            'sensor.lazienka_okno_1'
          ] %} {% set lista = namespace(x=[]) %} {% for okno in okna %}
            {% if states(okno) == 'on' %}
              {% set nazwa = state_attr(okno, 'friendly_name') or okno %}
              {% set lista.x = lista.x + [nazwa] %}
            {% endif %}
          {% endfor %} {% if lista.x | count > 0 %} **Otwartych okien: {{
          lista.x | count }}**  

          {% for item in lista.x %} - {{ item }} {% endfor %} {% else %} ✅
          Wszystkie okna są zamknięte. {% endif %}
      dismissable: true
    action: browser_mod.popup
mode: single

Ale jak zrobić aby wyświetlało to się w liście. Obecnie tak to wygląda
Otwartych okien: 2

SALON Okno 1 - ŁAZIENKA Okno 1

Zamiast

sporóbuj
<ul>{% for item in lista.x %} <li>{{ item }}</li> {% endfor %}</ul>

1 polubienie

Encje zdefiniowane jako grupy, kod dodany jako odznaki.
karta mushroom, wymagany browser_mod.popup

Screenshot - 11.05.2025 , 22_02_47

Okna:

type: custom:mushroom-chips-card
chips:
  - type: template
    icon: mdi:window-open
    entity: group.all_windows
    icon_color: blue
    tap_action:
      action: fire-dom-event
      browser_mod:
        service: browser_mod.popup
        data:
          title: Otwarte Okna
          content:
            type: custom:auto-entities
            filter:
              include:
                - group: group.all_windows
                  state: "on"
                  options:
                    type: custom:mushroom-light-card
                    show_brightness_control: true
                    layout: horizontal
                    tap_action:
                      action: toggle
                    use_light_color: true
                - entity_id: group.all_windows
                  state: "on"
                  options:
                    type: custom:mushroom-light-card
                    layout: horizontal
                    secondary_info: none
                    tap_action:
                      action: toggle
                    card_mod:
                      style: |
                        ha-card {
                          background: rgba(var(--rgb-state-light), 0.1);
                        }
                        :host {
                          margin: 0px 0px 12px !important;
                        }
              exclude: []
            card:
              type: custom:layout-card
              cards: []
              layout_type: masonry
            sort:
              method: friendly_name
          card_mod:
            style: |
              .content {
                margin: -12px -10px -4px -16px !important;
                --ha-card-border-width: 0;
                --ha-card-background: none;
                --ha-card-box-shadow: 0;
                --masonry-view-card-margin: -12px 0px 0px 0px;
              }
    card_mod:
      style: |
        ha-card:after {
          {% set lights_on = (expand(states.group.all_windows) | selectattr('state', 'eq', 'on') | list | count) %}
          {% if lights_on > 0 %}
            content: "{{ lights_on }}";
          {% endif %}
          position: absolute;
          display: flex;
          justify-content: center;
          align-items: center;
          background: rgb(var(--rgb-amber));
          color: var(--card-background-color);
          font-weight: bolder;
          border-radius: 50%;
          top: -5px;
          right: -5px;
          width: 16px;
          height: 16px;
          font-size: 11px; 
        }
        .content {
          {% if lights_on > 0 %}
            animation: boing 3s ease infinite;
          {% endif %}
          transform-origin: 50% 90%;
        }
        @keyframes boing {
          0% { transform: scale3d(1, 1, 1); }
          7% { transform: scale3d(1.25, 0.75, 1); }
          10% { transform: scale3d(0.75, 1.25, 1); }
          12% { transform: scale3d(1.15, 0.85, 1); }
          16% { transform: scale3d(0.95, 1.05, 1); }
          19% { transform: scale3d(1.05, 0.95, 1); }
          25% { transform: scale3d(1, 1, 1); }
        }

Oświetlenie:

type: custom:mushroom-chips-card
chips:
  - type: template
    icon: mdi:lightbulb
    entity: group.all_lights
    icon_color: amber
    tap_action:
      action: fire-dom-event
      browser_mod:
        service: browser_mod.popup
        data:
          title: Włączone Swiatła
          content:
            type: custom:auto-entities
            filter:
              include:
                - group: group.all_lights
                  state: "on"
                  options:
                    type: custom:mushroom-light-card
                    show_brightness_control: true
                    layout: horizontal
                    tap_action:
                      action: toggle
                    use_light_color: true
                - entity_id: group.all_lights
                  state: "on"
                  options:
                    type: custom:mushroom-light-card
                    layout: horizontal
                    secondary_info: none
                    tap_action:
                      action: toggle
                    card_mod:
                      style: |
                        ha-card {
                          background: rgba(var(--rgb-state-light), 0.1);
                        }
                        :host {
                          margin: 0px 0px 12px !important;
                        }
              exclude: []
            card:
              type: custom:layout-card
              cards: []
              layout_type: masonry
            sort:
              method: friendly_name
          card_mod:
            style: |
              .content {
                margin: -12px -10px -4px -16px !important;
                --ha-card-border-width: 0;
                --ha-card-background: none;
                --ha-card-box-shadow: 0;
                --masonry-view-card-margin: -12px 0px 0px 0px;
              }
    card_mod:
      style: |
        ha-card:after {
          {% set lights_on = (expand(states.group.all_lights) | selectattr('state', 'eq', 'on') | list | count) %}
          {% if lights_on > 0 %}
            content: "{{ lights_on }}";
          {% endif %}
          position: absolute;
          display: flex;
          justify-content: center;
          align-items: center;
          background: rgb(var(--rgb-amber));
          color: var(--card-background-color);
          font-weight: bolder;
          border-radius: 50%;
          top: -5px;
          right: -5px;
          width: 16px;
          height: 16px;
          font-size: 11px; 
        }
        .content {
          {% if lights_on > 0 %}
            animation: boing 3s ease infinite;
          {% endif %}
          transform-origin: 50% 90%;
        }
        @keyframes boing {
          0% { transform: scale3d(1, 1, 1); }
          7% { transform: scale3d(1.25, 0.75, 1); }
          10% { transform: scale3d(0.75, 1.25, 1); }
          12% { transform: scale3d(1.15, 0.85, 1); }
          16% { transform: scale3d(0.95, 1.05, 1); }
          19% { transform: scale3d(1.05, 0.95, 1); }
          25% { transform: scale3d(1, 1, 1); }
        }
layout: vertical
fill_container: true

Wentylatory:

type: custom:mushroom-chips-card
chips:
  - type: template
    icon: mdi:fan
    entity: group.wszystkie_wentylatory
    icon_color: white
    tap_action:
      action: fire-dom-event
      browser_mod:
        service: browser_mod.popup
        data:
          style: |

            --popup-border-width: 10px;
            --popup-border-radius: 12px;
            --dialog-backdrop-filter: blur(0.8em) brightness(1.2);        
          title: Włączone Wentylatory
          content:
            type: custom:auto-entities
            filter:
              include:
                - group: group.wszystkie_wentylatory
                  state: "on"
                  options:
                    type: custom:mushroom-fan-card
                    show_brightness_control: false
                    layout: horizontal
                    tap_action:
                      action: toggle
                    use_light_color: true
                - entity_id: group.wszystkie_wentylatory
                  state: "on"
                  options:
                    type: custom:mushroom-fan-card
                    layout: horizontal
                    secondary_info: none
                    tap_action:
                      action: toggle
                    card_mod:
                      style: |
                        ha-card {
                          background: rgba(var(--rgb-state-light), 0.1);
                        }
                        :host {
                          margin: 0px 0px 12px !important;
                        }
              exclude: []
            card:
              type: custom:layout-card
              cards: []
              layout_type: masonry
            sort:
              method: friendly_name
          card_mod:
            style: |
              .content {
                margin: -12px -10px -4px -16px !important;
                --ha-card-border-width: 0;
                --ha-card-background: none;
                --ha-card-box-shadow: 0;
                --masonry-view-card-margin: -12px 0px 0px 0px;
              }
    card_mod:
      style: |
        ha-card:after {
          {% set fan_on = (expand(states.group.wszystkie_wentylatory) | selectattr('state', 'eq', 'on') | list | count) %}
          {% if fan_on > 0 %}
            content: "{{ fan_on }}";
          {% endif %}
          position: absolute;
          display: flex;
          justify-content: center;
          align-items: center;
          background: rgb(var(--rgb-amber));
          color: var(--card-background-color);
          font-weight: bolder;
          border-radius: 50%;
          top: -5px;
          right: -5px;
          width: 16px;
          height: 16px;
          font-size: 11px; 
        }
        .content {
          {% if fan_on > 0 %}
            animation: spin 1s linear infinite;
          {% endif %}
          transform-origin: 50% 50%;
        }
        @keyframes rotation {
          0% { transform: scale3d(1, 1, 1); }
          7% { transform: scale3d(1.25, 0.75, 1); }
          10% { transform: scale3d(0.75, 1.25, 1); }
          12% { transform: scale3d(1.15, 0.85, 1); }
          16% { transform: scale3d(0.95, 1.05, 1); }
          19% { transform: scale3d(1.05, 0.95, 1); }
          25% { transform: scale3d(1, 1, 1); }
        }

Ten szablon wyświetla w liście i nie trzeba sprawdzać poszczegóknych okien. Tutaj więcej przydatnych szablonów Przydatne szablony jinja2 w HA

{% set open_windows = states.binary_sensor | selectattr('attributes.device_class', 'equalto', 'window') | selectattr('state', 'equalto', 'on') %}

{% if open_windows %}
    Otwarte okna: 
    {% for window in open_windows %}
        {{ window.name }} {% if not loop.last %} {% endif %}
    {% endfor %}
{% else %}
    Wszystkie okna są zamknięte.
{% endif %}

A można dołożyć do tego jeszcze komunikat głosowy na urządzeniu na którym jest to sprawdzane? Abo komunikat był typu “Wszystkie okna są zamknięte” lub jeśli jakieś jest otwarte to informacje które?

Przykład:

Automatyzacja. Powie Google, Alexa - jeśli któreś okna, drzwi zostaną otwarte
alias: test powiadomień
description: ""
mode: single
triggers:
  - entity_id:
      - binary_sensor.on_off_frontowe_contact
      - binary_sensor.on_off_ogrodowe_contact
      - binary_sensor.on_off_okno_salon_contact
      - binary_sensor.on_off_brama_garazowa_contact
    to: "on"
    trigger: state
conditions: []
actions:
  - data:
      entity_id: media_player.living_room
      language: pl-PL
      message: >-
        " {% if is_state('binary_sensor.on_off_frontowe_contact', 'on') %}  -
        Drzwi frontowe zostały otwarte{% endif %}{% if
        is_state('binary_sensor.on_off_ogrodowe_contact', 'on') %} Drzwi
        ogrodowe zostały otwarte {% endif %}{% if
        is_state('binary_sensor.on_off_okno_salon_contact', 'on') %}   Okno w
        salonie zosstało otwarteu{% endif %}{% if
        is_state('binary_sensor.on_off_brama_garazowa_contact', 'on') %}  -
        Brama garażowa została otwarta {% endif %}"
    action: tts.cloud_say
  - data:
      message: >-
        " {% if is_state('binary_sensor.on_off_frontowe_contact', 'on') %} 
                The front door was opened {% endif %}{% if        
        is_state('binary_sensor.on_off_ogrodowe_contact', 'on') %} 
                The garden door has been opened {% endif %}{% if        
        is_state('binary_sensor.on_off_okno_salon_contact', 'on') %}          
                The window in the living room was open {% endif %}{% if        
        is_state('binary_sensor.on_off_brama_garazowa_contact', 'on')
        %}          
                The garage door has been opened {% endif %}"
      data:
        type: tts
    action: notify.alexa_media_dom_echo_show

Dla potomności: powinno zadziałać coś takiego:

{{ states.binary_sensor | selectattr('state', 'eq', 'on') | selectattr('attributes.device_class', 'eq', 'window') | list }}

zamieniając ‘window’ na ‘door’ otrzymamy listę otwartych drzwi. Podobnie można zrobić dla świateł, przełączników itd.

Wynik:


[<template TemplateState(<state binary_sensor.on_off_ogrodowe_contact=on; device_class=door, friendly_name=Ogrodowe @ 2025-08-06T16:34:26.379971+01:00>)>]

Natomiast

Ile drzwi jest otwartych:

{{ states.binary_sensor 
  | selectattr('state', 'eq', 'on') 
  | selectattr('attributes.device_class', 'eq', 'door') 
  | list 
  | count }}

1

Które drzwi są otwarte:

{{ states.binary_sensor 
  | selectattr('state', 'eq', 'on') 
  | selectattr('attributes.device_class', 'eq', 'door') 
  | map(attribute='name') 
  | join(', ') }}

Ogrodowe

Otwarte drzwi- które. (jeśli wszystkie zamknięte “Wszystkie drzwi są zamknięte.”)

{% set drzwi = states.binary_sensor
  | selectattr('state', 'eq', 'on')
  | selectattr('attributes.device_class', 'eq', 'door') 
  | map(attribute='name') 
  | list %}

{% if drzwi | count > 0 %}
  Otwarte drzwi: {{ drzwi | join(', ') }}
{% else %}
 Wszystkie drzwi są zamknięte.
{% endif %}

Otwarte drzwi: Ogrodowe

3 polubienia