Home Assistant: harmonogram odbioru śmieci w Polsce – HACS + „Najbliższy wywóz” na pulpicie

W moim dashboardzie Home Assistant chciałem mieć zawsze pod ręką informację, kiedy i jakie śmieci będą odebrane – najlepiej w dwóch wersjach: prostej (sama liczba dni) i opisowej (np. „jutro papier + plastik/metal”). Poniżej znajdziesz pełny, praktyczny przewodnik: od instalacji integracji przez HACS (dla polskich operatorów typu Eko Harmonogram, PreZero itd.), po czytelne sensory i kafelki z „Najbliższym wywozem”. Dodaję też wariant manualny, gdy Twojej lokalizacji nie ma na liście.

Wymagania i przygotowanie środowiska

  • Aktualny Home Assistant

  • HACS (Home Assistant Community Store) – w filmie mówię „Hacks”, ale poprawnie jest HACS

  • File Editor do edycji plików YAML (lub alternatywnie Samba Share, jeśli wolisz wgrywać pliki z komputera)

Po większych zmianach w YAML: Ustawienia → System → Kontrole serwera → Sprawdź konfigurację → Uruchom ponownie.

Metoda 1: Automatyczna integracja przez HACS (Polska)

Ta ścieżka jest najwygodniejsza – terminy pobiorą się same z serwisu operatora dla Twojej miejscowości.

  1. Dodaj integrację przez HACS

    • HACS → Integrations → wyszukaj Waste Collection ScheduleInstall → restart HA (jeśli wymagany).

  2. Skonfiguruj integrację w HA

    • Ustawienia → Urządzenia i usługi → Dodaj integrację → wpisz Waste Collection Schedule.

    • Kraj: Poland.

    • Źródło: wybierz operatora (np. Eko Harmonogram, PreZero Bielsko-Biała, inne wskazane na liście).

    • Uzupełnij miasto, ulicę i numer domu. Jeżeli pojawi się pytanie o typ zabudowy (jednorodzinna / wielolokalowa), wybierz właściwy wariant.

  3. Weryfikacja

    • Integracja doda kalendarze dla frakcji (papier, bio, plastik/metal, szkło, zmieszane, czasem popiół).

    • Otwórz Kalendarz w HA i sprawdź, czy pojawiły się zdarzenia.

Jeśli Twojej miejscowości nie ma, przejdź do Metody 2 (manualnej). Obie metody można też łączyć – integrację używać do pobierania dat, a własne sensory/template’y do czytelnej prezentacji.

Metoda 2: Manualny harmonogram (gdy brak operatora)

Jeżeli integracja nie obsługuje Twojego adresu, masz dwie proste opcje:

  • Local Calendar (UI): utwórz w HA lokalne kalendarze dla frakcji i ręcznie dodaj terminy.

  • Plik YAML z sensorami/template’ami, które bazują na istniejących kalendarzach (z integracji lub lokalnych).

W dalszej części pokażę gotowe sensory i template czytające z kalendarzy (niezależnie, czy pochodzą z HACS, czy Local Calendar). Dzięki temu w UI dostaniesz „dni do odbioru” oraz „opis + dni” dla każdej frakcji i zbiorczy „Najbliższy wywóz”.

Wrzuć do configuration.yaml:

waste_collection_schedule: !include smieci.yaml

Stwórz plik smieci.yaml i uzupełnij:

sources:
  - name: static
    calendar_title: "Śmieci — Zmieszane"
    args:
      type: zmieszane
      dates:
        - "2025-01-03"
        - "2025-01-17"
        - "2025-01-31"
        - "2025-02-14"
        - "2025-02-28"
        - "2025-03-14"
        - "2025-03-28"
        - "2025-04-11"
        - "2025-04-25"
        - "2025-05-09"
        - "2025-05-23"
        - "2025-06-06"
        - "2025-06-23"
        - "2025-07-04"
        - "2025-07-18"
        - "2025-08-01"
        - "2025-08-18"
        - "2025-08-29"
        - "2025-09-12"
        - "2025-09-26"
        - "2025-10-10"
        - "2025-10-24"
        - "2025-11-07"
        - "2025-11-21"
        - "2025-12-05"
        - "2025-12-18"

  - name: static
    calendar_title: "Śmieci — Plastik / Metal"
    args:
      type: plastik
      dates:
        - "2025-01-15"
        - "2025-02-12"
        - "2025-03-12"
        - "2025-04-09"
        - "2025-05-07"
        - "2025-06-04"
        - "2025-07-02"
        - "2025-07-30"
        - "2025-08-27"
        - "2025-09-24"
        - "2025-10-22"
        - "2025-11-19"
        - "2025-12-17"

  - name: static
    calendar_title: "Śmieci — Papier"
    args:
      type: papier
      dates:
        - "2025-01-15"
        - "2025-02-12"
        - "2025-03-12"
        - "2025-04-09"
        - "2025-05-07"
        - "2025-06-04"
        - "2025-07-02"
        - "2025-07-30"
        - "2025-08-27"
        - "2025-09-24"
        - "2025-10-22"
        - "2025-11-19"
        - "2025-12-17"

  - name: static
    calendar_title: "Śmieci — Bio"
    args:
      type: bio
      dates:
        - "2025-01-17"
        - "2025-02-14"
        - "2025-03-14"
        - "2025-04-11"
        - "2025-04-25"
        - "2025-05-09"
        - "2025-05-23"
        - "2025-06-06"
        - "2025-06-23"
        - "2025-07-04"
        - "2025-07-18"
        - "2025-08-01"
        - "2025-08-18"
        - "2025-08-29"
        - "2025-09-12"
        - "2025-09-26"
        - "2025-10-10"
        - "2025-10-24"
        - "2025-11-21"
        - "2025-12-18"

  - name: static
    calendar_title: "Śmieci — Szkło"
    args:
      type: szklo
      dates:
        - "2025-01-07"
        - "2025-02-04"
        - "2025-03-04"
        - "2025-04-01"
        - "2025-04-28"
        - "2025-05-27"
        - "2025-06-24"
        - "2025-07-22"
        - "2025-08-20"
        - "2025-09-16"
        - "2025-10-14"
        - "2025-11-12"
        - "2025-12-09"

  - name: static
    calendar_title: "Śmieci — Popiół"
    args:
      type: popiol
      dates:
        - "2025-01-03"
        - "2025-01-16"
        - "2025-01-30"
        - "2025-02-13"
        - "2025-02-27"
        - "2025-03-13"
        - "2025-03-27"
        - "2025-04-10"
        - "2025-04-25"
        - "2025-06-26"
        - "2025-08-28"
        - "2025-10-09"
        - "2025-10-23"
        - "2025-11-06"
        - "2025-11-20"
        - "2025-12-04"
        - "2025-12-18"

Configuration.yaml dodajemy do sensors:

sensor:
  # ZMIESZANE
  - platform: waste_collection_schedule
    name: "Śmieci — Zmieszane (dni)"
    source_index: 0
    details_format: generic
    add_days_to: true
    value_template: "{{ value.daysTo }}"
    types: [zmieszane]

  - platform: waste_collection_schedule
    name: "Śmieci — Zmieszane (opis)"
    source_index: 0
    details_format: generic
    add_days_to: true
    value_template: >-
      {% if value.daysTo == 0 %}Dziś – Zmieszane
      {% elif value.daysTo == 1 %}Jutro – Zmieszane
      {% else %}Za {{ value.daysTo }} dni – Zmieszane{% endif %}
    types: [zmieszane]

  # PLASTIK / METAL
  - platform: waste_collection_schedule
    name: "Śmieci — Plastik/Metal (dni)"
    source_index: 1
    details_format: generic
    add_days_to: true
    value_template: "{{ value.daysTo }}"
    types: [plastik]

  - platform: waste_collection_schedule
    name: "Śmieci — Plastik/Metal (opis)"
    source_index: 1
    details_format: generic
    add_days_to: true
    value_template: >-
      {% if value.daysTo == 0 %}Dziś – Plastik/Metal
      {% elif value.daysTo == 1 %}Jutro – Plastik/Metal
      {% else %}Za {{ value.daysTo }} dni – Plastik/Metal{% endif %}
    types: [plastik]

  # PAPIER
  - platform: waste_collection_schedule
    name: "Śmieci — Papier (dni)"
    source_index: 2
    details_format: generic
    add_days_to: true
    value_template: "{{ value.daysTo }}"
    types: [papier]

  - platform: waste_collection_schedule
    name: "Śmieci — Papier (opis)"
    source_index: 2
    details_format: generic
    add_days_to: true
    value_template: >-
      {% if value.daysTo == 0 %}Dziś – Papier
      {% elif value.daysTo == 1 %}Jutro – Papier
      {% else %}Za {{ value.daysTo }} dni – Papier{% endif %}
    types: [papier]

  # BIO
  - platform: waste_collection_schedule
    name: "Śmieci — Bio (dni)"
    source_index: 3
    details_format: generic
    add_days_to: true
    value_template: "{{ value.daysTo }}"
    types: [bio]

  - platform: waste_collection_schedule
    name: "Śmieci — Bio (opis)"
    source_index: 3
    details_format: generic
    add_days_to: true
    value_template: >-
      {% if value.daysTo == 0 %}Dziś – Bio
      {% elif value.daysTo == 1 %}Jutro – Bio
      {% else %}Za {{ value.daysTo }} dni – Bio{% endif %}
    types: [bio]

  # SZKŁO
  - platform: waste_collection_schedule
    name: "Śmieci — Szkło (dni)"
    source_index: 4
    details_format: generic
    add_days_to: true
    value_template: "{{ value.daysTo }}"
    types: [szklo]

  - platform: waste_collection_schedule
    name: "Śmieci — Szkło (opis)"
    source_index: 4
    details_format: generic
    add_days_to: true
    value_template: >-
      {% if value.daysTo == 0 %}Dziś – Szkło
      {% elif value.daysTo == 1 %}Jutro – Szkło
      {% else %}Za {{ value.daysTo }} dni – Szkło{% endif %}
    types: [szklo]

  # POPIÓŁ
  - platform: waste_collection_schedule
    name: "Śmieci — Popiół (dni)"
    source_index: 5
    details_format: generic
    add_days_to: true
    value_template: "{{ value.daysTo }}"
    types: [popiol]

  - platform: waste_collection_schedule
    name: "Śmieci — Popiół (opis)"
    source_index: 5
    details_format: generic
    add_days_to: true
    value_template: >-
      {% if value.daysTo == 0 %}Dziś – Popiół
      {% elif value.daysTo == 1 %}Jutro – Popiół
      {% else %}Za {{ value.daysTo }} dni – Popiół{% endif %}
    types: [popiol]

Configuration.yaml dodajemy do template:

template:
  - sensor:
      - name: "Śmieci — Najbliższy (dni)"
        unique_id: smieci_najblizszy_dni
        icon: mdi:trash-can-clock
        unit_of_measurement: "dni"
        state: >
          {% set m = {
            'Zmieszane': states('sensor.smieci_zmieszane_dni')|int(999),
            'Plastik/Metal': states('sensor.smieci_plastik_metal_dni')|int(999),
            'Papier': states('sensor.smieci_papier_dni')|int(999),
            'Bio': states('sensor.smieci_bio_dni')|int(999),
            'Szkło': states('sensor.smieci_szklo_dni')|int(999),
            'Popiół': states('sensor.smieci_popiol_dni')|int(999)
          } %}
          {% set vals = m.values()|select('lt', 999)|list %}
          {{ (vals|min) if vals|length > 0 else 999 }}

      - name: "Śmieci — Najbliższy (opis)"
        unique_id: smieci_najblizszy_opis
        icon: mdi:trash-can-clock
        state: >
          {% set m = {
            'Zmieszane': states('sensor.smieci_zmieszane_dni')|int(999),
            'Plastik/Metal': states('sensor.smieci_plastik_metal_dni')|int(999),
            'Papier': states('sensor.smieci_papier_dni')|int(999),
            'Bio': states('sensor.smieci_bio_dni')|int(999),
            'Szkło': states('sensor.smieci_szklo_dni')|int(999),
            'Popiół': states('sensor.smieci_popiol_dni')|int(999)
          } %}
          {% set vals = m.values()|select('lt', 999)|list %}
          {% if vals|length == 0 %}
            Brak terminu
          {% else %}
            {% set min_d = vals|min %}
            {% set who = m|dictsort(false, 'value')|selectattr('1', 'equalto', min_d)|map(attribute='0')|list %}
            {% set names = who|join(' + ') %}
            {% if min_d == 0 %} Dziś – {{ names }}
            {% elif min_d == 1 %} Jutro – {{ names }}
            {% else %} Za {{ min_d }} dni – {{ names }} {% endif %}
          {% endif %}

Dzięki temu zyskujesz jeden, „sprytny” opis, który zawsze pokazuje najbliższy termin i łączy frakcje, jeżeli wypadają tego samego dnia (np. „jutro plastik + metal + papier”).


Dodanie do dashboardu (Lovelace)

Masz kilka wariantów:

  • Entities: jedna karta z:

    • sensor.smieci_najblizsze_dni

    • sensor.smieci_najblizszy_opis

    • (opcjonalnie) poszczególne „opis” i „dni” dla frakcji

  • Mushroom / Tile / Markdown: zgrabny, duży kafelek tylko z najważniejszą informacją (opisem + dniami).

Jeśli czegoś „brakuje ikon”, możesz je wymusić we właściwościach encji lub kart (np. mdi:trash-can-outline, mdi:recycle, mdi:delete-empty, mdi:bottle-soda itd.).


Dobre praktyki i typowe pułapki

  • Nie duplikuj nagłówków sensor: i template: – trzymaj wszystko pod jedną sekcją każdego typu (albo rozbij na pliki i dołącz !include do jednej sekcji).

  • W YAML liczą się wcięcia – kopiując fragmenty, zachowaj spacje.

  • Po dodaniu integracji przez HACS czasem potrzebny jest restart HA.

  • Jeśli masz integrację i lokalny kalendarz – upewnij się, z których encji korzystają template’y.

  • Przy dużych dashboardach rozważ wyświetlanie warunkowe (pokazuj kafelek tylko, gdy do odbioru zostało ≤ X dni).


Co dalej?

  • Powiadomienia o odbiorze (telefon, TTS, TV, przypominajka dzień wcześniej).

  • Wersja mini kafelka do „nagłówka” dashboardu.

  • Grupowanie frakcji i automatyczna zmiana ikon/kolorów zależnie od tego, co „najbliżej”.

 

automatyzacja z odcinka:

alias: Śmieci - przypomnienie 20:00 dzień wcześniej (osobne)
triggers:
  - id: papier
    entity_id: calendar.smieci_papier
    event: start
    offset: "-04:00:00"
    trigger: calendar
  - id: plastik_metal
    entity_id: calendar.smieci_plastik_metal
    event: start
    offset: "-04:00:00"
    trigger: calendar
  - id: szklo
    entity_id: calendar.smieci_szklo
    event: start
    offset: "-04:00:00"
    trigger: calendar
  - id: bio
    entity_id: calendar.static_source_4
    event: start
    offset: "-4:0:0"
    trigger: calendar
  - id: popiol
    entity_id: calendar.smieci_popiol
    event: start
    offset: "-04:00:00"
    trigger: calendar
  - id: zmieszane
    entity_id: calendar.smieci_zmieszane
    event: start
    offset: "-04:00:00"
    trigger: calendar
actions:
  - choose:
      - conditions:
          - condition: trigger
            id: papier
        sequence:
          - data:
              title: Jutro wywóz – Papier
              message: Wystaw niebieski pojemnik/worek.
              data:
                group: Smieci
            action: notify.mobile_app_oneplus_12
      - conditions:
          - condition: trigger
            id: plastik_metal
        sequence:
          - data:
              title: Jutro wywóz – Plastik/Metal
              message: Wystaw żółty pojemnik/worek.
              data:
                group: Smieci
            action: notify.mobile_app_oneplus_12
      - conditions:
          - condition: trigger
            id: szklo
        sequence:
          - data:
              title: Jutro wywóz – Szkło
              message: Wystaw zielony pojemnik/worek.
              data:
                group: Smieci
            action: notify.mobile_app_oneplus_12
      - conditions:
          - condition: trigger
            id: bio
        sequence:
          - data:
              title: Jutro wywóz – Bio
              message: Wystaw brązowy pojemnik.
              data:
                group: Smieci
            action: notify.mobile_app_oneplus_12
      - conditions:
          - condition: trigger
            id: popiol
        sequence:
          - data:
              title: Jutro wywóz – Popiół
              message: Wystaw szary pojemnik.
              data:
                group: Smieci
            action: notify.mobile_app_oneplus_12
      - conditions:
          - condition: trigger
            id: zmieszane
        sequence:
          - data:
              title: Jutro wywóz – Zmieszane
              message: Wystaw czarny pojemnik.
              data:
                group: Smieci
            action: notify.mobile_app_oneplus_12