Feld verwildert – Zeit fĂŒr Smart Gardening!

👉 Direkt auf YouTube schauen und abonnieren:
Smart Home & More auf YouTube

Heute nehme ich euch mit auf unser zugewachsenes und verwildertes Familienfeld. In diesem Beitrag zeige ich den aktuellen Zustand und erklĂ€re, wie ich das GrundstĂŒck mit smarter Technik und einem MĂ€hroboter automatisiert pflegen möchte.


Willkommen auf meinem Kanal Smart Home & More

Mein Name ist Tobias Lerch. Heute bin ich nicht wie sonst im Studio, sondern draußen vor unserem wilden Feld. Dieses GrundstĂŒck gehört meiner Familie, und ich habe große PlĂ€ne fĂŒr die Zukunft.


Ziel: Autarker MĂ€hroboter ohne Stromanschluss

Ich möchte, dass hier bald ein autonomer MĂ€hroboter arbeitet – ganz ohne externe Stromversorgung. DafĂŒr muss aber erst die passende Infrastruktur aufgebaut werden. Dazu gehört einiges an Arbeit, aber ich werde das Projekt Schritt fĂŒr Schritt mit euch teilen.


Das Feld und die Technik vor Ort

Der Zustand des GrundstĂŒcks

Aktuell sieht das Feld sehr verwildert aus, mehrere Jahre ist hier nichts passiert. Das wird sich Àndern!

Vorhandene Technik

  • Ein Laderegler von Victron
  • Ein Wechselrichter
  • Ein Raspberry Pi (vermutlich Modell 2)
  • Geplant ist eine AGM-Batterie als Stromquelle

Diese Technik soll erneuert und erweitert werden, um das smarte System zuverlÀssig zu betreiben.


Geplante technische Umsetzung

Ich werde weiterhin den Victron Solarladeregler nutzen und einen DC/DC-Wandler einsetzen, um von 12 Volt auf 24 Volt fĂŒr den MĂ€hroboter zu kommen. Ein Shelly 1 Plus soll den Laderegler und den Wandler steuern, um den Betrieb nachts zu optimieren.

SpĂ€ter soll auch ein Home Assistant System integriert werden, um alles smart zu steuern. Zudem wird eine Kamera installiert, die fĂŒr Sicherheit sorgt.


Das Projekt in der Praxis

Ich bin gespannt, wie gut sich der MĂ€hroboter auf diesem eher rauen GelĂ€nde schlĂ€gt. Falls Hersteller oder Community-Mitglieder Interesse haben, unter realen Bedingungen zu testen, freue ich mich ĂŒber Nachrichten und Kommentare.


Familienzeit und weitere PlÀne

Das GrundstĂŒck soll nicht nur smart werden, sondern auch ein gemĂŒtlicher Ort fĂŒr die Familie.


Ausblick: Die Rodung beginnt

Im nÀchsten Video nehme ich euch mit bei der Rodung mit einer akkubetriebenen Motorsense. Es wird spannend zu sehen, wie ich das GelÀnde aufbereite, um den MÀhroboter einsatzbereit zu machen.


Deine Meinung ist gefragt!

Was haltet ihr von dem Projekt? Habt ihr Tipps, Ideen oder Erfahrungen? Schreibt mir gern in die Kommentare!


Wenn dir das Projekt gefÀllt

Dann freue ich mich ĂŒber einen Daumen hoch und ein Abo, damit ich weiterhin spannende Smart-Home- und Smart-Gardening-Inhalte produzieren kann.

đŸŒŠïžâ˜€ïž Automatisiere deine Markise mit Home Assistant und örtlichen Wetterdaten! â˜ïžđŸŒŹïž

Viele Smart-Home-Systeme greifen auf allgemeine Wetterdaten zurĂŒck. Diese sind allerdings hĂ€ufig ungenau oder zu weit vom eigenen Standort entfernt. Ich zeige dir, wie du die Daten einer örtlichen Wetterstation von einer Webseite ausliest und fĂŒr deine Automatisierungen nutzen kannst – ganz einfach mit Home Assistant!

🔧 Voraussetzungen

Um das Ganze umzusetzen, benötigst du:

  • Eine installierte und eingerichtete Instanz von Home Assistant
  • Zugriff auf eine Webseite mit Wetterdaten einer lokalen Wetterstation
  • Grundkenntnisse in Automatisierungen und Template-Sensoren in Home Assistant

đŸ§© Wetterdaten abrufen – So funktioniert’s

Wir nutzen die Integration von Wetterdaten ĂŒber RESTful Sensoren, um Informationen wie:

  • Regenstatus
  • Windgeschwindigkeit
  • Wetterlage (z.B. sonnig, bewölkt)
  • Temperatur

auszulesen. Diese Daten werden anschließend in eigene Sensoren ĂŒberfĂŒhrt, die Home Assistant versteht und in Automatisierungen verwendet.

ZunĂ€chst mĂŒssen wir uns auf die Seite von Weather Underground begeben. Dort lasst euch den Quelltext anzeigen und kopiert diesen in einen Editor Tool ( z.B. von Windows).

Um den API Eintrag zu finden, sucht nach der Zeichenkette

https://api.weather.com/v2/pws/observations/current

Kopiert euch die gesamte Zeichenkette inklusive apiKey und stationId und passt den Inhalt wie folgt an.

https://api.weather.com/v2/pws/observations/current?apiKey=**deinAPI-KEY**&stationId=**deineStationID**&numericPrecision=decimal&format=json&units=m

die „**“ sind nur zur eindeutigen Identifizierung zu verstehen und nicht dem Key und der StationID hinzuzufĂŒgen!

Als nĂ€chstes geht mit dem Editor eurer Wahl ( z.B. File Editor oder Studio Code Server ) in eurer Home Assistant Instanz und fĂŒgt in der configuration.yaml einen neuen Rest Sensor ein.

rest:
  - resource: https://api.weather.com/v2/pws/observations/current?apiKey=**deinAPI-KEY**&stationId=**deineStationID**&numericPrecision=decimal&format=json&units=m
    scan_interval: 600 
    sensor:
      - name: Wetterstation Lahr
        unique_id: 82413cbe-2261-4d41-a7f4-c271cba75645 #hier musst du eine eigene eindeutige ID erstellen !
        value_template: >
          {{ value_json.observations[0].metric.temp }}
        json_attributes:
          - observations

Hinweis: Bitte geht nicht unter 600 Sekunden beim Scan Interval. In der Regel sehen es die Betreiber einer Website nicht gerne , wenn zu viele Abfragen von einer IP – Adresse kommen. Mit den 600 Sekunden solltet ihr auf der sicheren Seite sein.

⚙ Automatisierung der Markise

Die Logik ist einfach:

  • Wenn es regnet oder starker Wind herrscht, fĂ€hrt die Markise automatisch ein.
  • Bei Sonne und angenehmen Bedingungen fĂ€hrt sie aus.

Die Automatisierung lĂ€sst sich natĂŒrlich noch weiter verfeinern – zum Beispiel durch Tageszeiten oder Anwesenheit.

Template Helfer Sensoren erstellen

Der nĂ€chste wichtige Schritt ist aus den Daten, die nun im Sensor Wetterstation Lahr (obervations) stehen alle relevanten Daten fĂŒr eine Automatisierung auszulesen.

Dazu legt euch 4 Helfer an vom Typ Template Sensor

Hinweis: Bei mir habe ich die Wetterstation „’sensor.wetterstation_lahr“ genannt. Hier mĂŒsst ihr in allen Code Zeilen den von euch vergebenen Namen verwenden!

Wetterstation Lahr Windgeschwindigkeit

{{ state_attr('sensor.wetterstation_Lahr', 'observations')[0]['metric']['windSpeed'] }}

Einheit : km/h

Wetterstation Lahr Wetterlage

{% set obs = state_attr('sensor.wetterstation_Lahr', 'observations')[0] %}
{% set radiation = obs['solarRadiation'] %}
{% set uv = obs['uv'] %}
{% set precip = obs['metric']['precipRate'] %}
{% if precip > 0 %}
   regen
{% elif radiation < 100 or uv <= 1 %}
   bewölkt
{% elif radiation < 500 or uv < 3 %}
   leicht bewölkt
{% else %}
   sonnig
{% endif %}

Einheit: keine

Wetterstation Lahr Temperatur

{{ state_attr('sensor.wetterstation_Lahr', 'observations')[0]['metric']['temp'] }}

Einheit: °C

Wetterstation Lahr Regen

{{ state_attr('sensor.wetterstation_Lahr', 'observations')[0]['metric']['precipRate'] > 0 }}

Einheit: keine

Automatisierung Markise steuern

Sobald

Und wenn

Dann

Gesamter Yaml Code

alias: Markise steuern
description: Steuert die Markise basierend auf den Wetterbedingungen
triggers:
  - entity_id: sensor.wetterstation_lahr_temperatur
    above: 18
    id: Temperatur hoch
    trigger: numeric_state
  - entity_id: sensor.wetterstation_lahr_temperatur
    below: 18.1
    id: Temperatur niedrig
    trigger: numeric_state
  - entity_id: sensor.wetterstation_lahr_wetterlage
    to: regen
    id: Regen
    trigger: state
  - entity_id: sensor.wetterstation_lahr_wetterlage
    to: sonnig
    id: Sonnig
    trigger: state
  - entity_id: sensor.wetterstation_lahr_wetterlage
    to: leicht bewölkt
    id: Leicht bewölkt
    trigger: state
  - entity_id: sensor.wetterstation_lahr_wetterlage
    to: bewölkt
    id: Bewölkt
    trigger: state
  - entity_id: sensor.wetterstation_lahr_windgeschwindigkeit
    above: 22
    id: Windgeschwindigkeit hoch
    trigger: numeric_state
  - entity_id: sensor.wetterstation_lahr_windgeschwindigkeit
    below: 22.1
    id: Windgeschwindigkeit niedrig
    trigger: numeric_state
conditions:
  - condition: time
    after: "10:00:00"
    before: "19:00:00"
actions:
  - choose:
      - conditions:
          - condition: or
            conditions:
              - condition: state
                entity_id: sensor.wetterstation_lahr_wetterlage
                state: regen
              - condition: numeric_state
                entity_id: sensor.wetterstation_lahr_windgeschwindigkeit
                above: 22
              - condition: numeric_state
                entity_id: sensor.wetterstation_lahr_temperatur
                below: 18.1
        sequence:
          - entity_id: switch.markise_markise2
            action: switch.turn_on
            alias: Markise einfahren
        alias: Schlechte Wetterlage -> Markise einfahren
      - conditions:
          - condition: and
            conditions:
              - condition: numeric_state
                entity_id: sensor.wetterstation_lahr_temperatur
                above: 18
              - condition: numeric_state
                entity_id: sensor.wetterstation_lahr_windgeschwindigkeit
                below: 22.1
              - condition: or
                conditions:
                  - condition: state
                    entity_id: sensor.wetterstation_lahr_wetterlage
                    state: sonnig
                  - condition: state
                    entity_id: sensor.wetterstation_lahr_wetterlage
                    state: leicht bewölkt
                  - condition: state
                    entity_id: sensor.wetterstation_lahr_wetterlage
                    state: bewölkt
            alias: Gute Wetterlage -> Markise ausfahren
        sequence:
          - entity_id: switch.markise
            action: switch.turn_on
            alias: Markise ausfahren
mode: single

Um die Markise um 19:00 Uhr generell wieder einzufahren habe ich eine separate Automatisierung erstellt. Es wĂ€re auch möglich in jedem „Optionsblock“ die Bedingung zwischen 10:00 Uhr – 19:00 Uhr vorzuschalten, ich fand die Variante mit einer separaten Automatisierung in diesem Fall allerdings sinnvoller.

Automatisierung Markise um 19:00 Uhr einfahren

alias: Markise einfahren
description: ""
triggers:
  - trigger: time
    at: "19:00:00"
conditions: []
actions:
  - action: switch.turn_on
    metadata: {}
    data: {}
    target:
      entity_id: switch.markise_markise2
mode: single

Hinweis: Wie schon im Video erwĂ€hnt, ist der Code nicht ausgiebig getestet. Gerne dĂŒrft ihr mir in den Youtube Kommentaren erweiterte Varianten oder angepassten Lösungen vorstellen, ich wĂŒrde diese dann auf meiner Blog Seite veröffentlichen.

🔒 Cyber Security im Smart Home – Wie sicher ist dein Netzwerk wirklich?

In diesem Video dreht sich alles um die Sicherheit im Smart Home! Ich spreche mit meinem Gast, einem YouTube-Kollegen, der sich intensiv mit der Unifi-Welt auseinandersetzt. Gemeinsam gehen wir auf typische Sicherheitsrisiken ein, teilen praktische Tipps und analysieren echte Angriffsbeispiele.

In der heutigen Zeit haben viele von uns unzĂ€hlige GerĂ€te im Heimnetzwerk. Doch wie gut sind diese eigentlich geschĂŒtzt? Welche Maßnahmen kann man ergreifen, um das eigene Smart Home sicherer zu machen? Das Video gibt Antworten auf diese Fragen und bietet wertvolle Einblicke in den Bereich der Smart Home-Sicherheit.

💡 Themen im Video:

  • SicherheitslĂŒcken in typischen Smart Home Setups
  • Tipps zur Absicherung deines Netzwerks
  • UniFi Firewalls & Best Practices
  • Erfahrungen aus der Praxis und ein Blick auf meine eigenen Firewall-Settings

Ob du gerade erst mit Smart Home beginnst oder bereits ein Fortgeschrittener bist – hier ist garantiert etwas fĂŒr dich dabei!

Schau dir das Video an und lass uns in den Kommentaren wissen, wie du dein Netzwerk absicherst oder ob du noch Fragen hast. Ich freue mich auf den Austausch!

Ein besonderer Dank geht an Jan, der sich sofort bereit erklĂ€rt hat, mich mit seiner Expertise in diesem Video zu unterstĂŒtzen. Schaut gerne mal bei ihm vorbei und abonniert seinen Kanal!

👉 Seinen Kanal findet ihr hier: @JanPoertner

Eine komplette Playlist aller seiner UniFi Videos findet ihr auch hier:
https://youtube.com/playlist?list=PLcKKIJBFoNTEtFXlUC9Sg12RA7v_8JHpg&si=XWu0-KVeMMTSSpxG

Anbei noch ein paar Gateways, die ich fĂŒr den Einsatz als Firewall empfehlen kann*:

Das Cloud Gateway Ultra ist ein gĂŒnstiger Einstieg, der aus meiner Sicht alle Netzwerkfunktionen, die man im normalen Hausgebrauch benötigt abdeckt. Ich habe diese Variante selber auch als Backup fĂŒr meine UDM Pro im Einsatz und bin sehr zufrieden mit der Leistung. Ein Backup der UDM Pro lĂ€sst sich ohne Probleme in wenigen Minuten auf das Cloud Gateway Ultra aufspielen.

Wenn man etwas mehr Leistung benötigt, gibt es den grĂ¶ĂŸeren Bruder des UCG Ultra, das Cloud Gateway Max. Mehr IPS Durchsatz, Protect etc.. ist damit umsetzbar.

Angebot


UbiQuiti UCG-MAX

  • UbiQuiti
  • Gateway

In der folgenden Tabelle habe ich euch noch ein paar Unifi Produkte aufgelistet, die ich gerne einsetze und wo ich sehr zufrieden mit bin.

📂 Paperless NGX: Dokumente synchronisieren mit OneDrive, Nextcloud, WebDAV & mehr! đŸ”„â˜ïž

In diesem Video zeige ich dir, wie du gescannte Dokumente direkt in die Cloud schicken und mit Paperless NGX automatisch verarbeiten lassen kannst. DafĂŒr stelle ich ein Tool fĂŒr Linux vor, mit dem du die Synchronisation mit OneDrive, Nextcloud, WebDAV & viele andere Dienste einrichtest. đŸ–šïžâžĄïžđŸ“‚ đŸ”č Themen im Video:

✔ Installation und Einrichtung des Synchronisationstools unter Linux 🐧

✔ Automatisches „Herunterladen“ gescannter Dokumente đŸ“€

✔ Effiziente Dokumentenverwaltung mit Paperless NGX 📑

Das Video zur Installation von paperless ngx: https://youtu.be/WRyBPMH9zf0

Blogbeitrag zum Video: https://smarthomeundmore.de/paperless-ngx-komplett-einrichten-mit-rest-api-home-assistant-sensor/

Das Tool kannst du aber auch unter Linux fĂŒr viele weitere Aufgaben verwenden.

Im Video habe ich ein paar Befehle verwendet. Damit ihr die Syntax nicht „kompliziert“ aus dem Video ablesen mĂŒsst, habe ich euch die wichtigsten Kommandos in diesem Blog Beitrag zusammengefasst.

Installation von rclone unter Linux ( getestet mit Ubuntu 24.10)

sudo apt-get install rclone

Die wichtigsten rclone Befehle kurz zusammengefasst. Im Video habe ich fĂŒr „remote:“ den Namen onedrive verwendet.

Grundlegende Befehle

  • rclone config – Konfiguration von Remotes (z. B. OneDrive,Google Drive, Dropbox).
  • rclone listremotes – Zeigt alle konfigurierten Remotes.
  • rclone lsd remote: – Listet die Verzeichnisse im Root des Remotes auf.
  • rclone ls remote: – Zeigt alle Dateien und Verzeichnisse im Remote an.
  • rclone copy Quelle Ziel – Kopiert Dateien/Ordner von einer Quelle zu einem Ziel.
  • rclone sync Quelle Ziel – Synchronisiert Quelle mit Ziel (Achtung: Ziel wird ĂŒberschrieben!).
  • rclone move Quelle Ziel – Verschiebt Dateien von Quelle nach Ziel.
  • rclone delete remote:Ordner – Löscht alle Dateien in einem Remote-Ordner.
  • rclone rmdir remote:Ordner – Löscht einen leeren Remote-Ordner.

Erweiterte Befehle

  • rclone check Quelle Ziel – Vergleicht Dateien zwischen Quelle und Ziel.
  • rclone mount remote: /lokaler/pfad – Mountet ein Remote-Laufwerk als lokales Verzeichnis.
  • rclone dedupe remote: – Findet und entfernt doppelte Dateien.
  • rclone about remote: – Zeigt Speicherinformationen des Remotes an.
  • rclone size remote: – Zeigt die GrĂ¶ĂŸe aller Dateien im Remote an.

Hinweis: rclone mount wird in einem unpriviligierten Container nicht funktionieren. Wenn ihr ein smb/cifs Laufwerk mounten möchtet, so empfehle ich euch eine „echte“ virtuelle Maschine zu verwenden. Alle „grundlegenden Befehle“ können hingegen ohne EinschrĂ€nkungen verwendet werden.

Um einen Scheduler ( Zeitplan ) fĂŒr einen „Kopiervorgang“ zu definieren mĂŒsst ihr zunĂ€chst einen „crontab“ Eintrag erstellen.

Ein Crontab (kurz fĂŒr Cron Table) ist eine Datei, die geplante Aufgaben (Cron-Jobs) fĂŒr das cron-Daemon unter Linux und Unix-basierten Systemen speichert. Diese Jobs werden zu festgelegten Zeiten oder in bestimmten Intervallen automatisch ausgefĂŒhrt.

Wichtige Befehle fĂŒr Crontab

  • crontab -e – Bearbeitet die Crontab-Datei des aktuellen Benutzers.
  • crontab -l – Listet alle aktuell gesetzten Cron-Jobs auf.
  • crontab -r – Löscht alle Cron-Jobs des aktuellen Benutzers.

Crontab-Syntax

Eine Crontab-Zeile besteht aus fĂŒnf Zeitfeldern und dem auszufĂŒhrenden Befehl:

* * * * * /pfad/zum/befehl.sh
- - - - -
| | | | |
| | | | +---- Wochentag (0 - Sonntag, 6 - Samstag)
| | | +------ Monat (1-12)
| | +-------- Tag des Monats (1-31)
| +---------- Stunde (0-23)
+------------ Minute (0-59)

Wir öffnen also den „Crontab Editor“ mit

crontab -e

und wĂ€hlen „nano“ als Editor aus.

Dann fĂŒgen wir folgende Zeile im Crontab Editor ein.

*/5 * * * * /usr/bin/rclone move onedrive:scans /data/paperless/consume --progress

Mit Strg++X speichern wir diesen Vorgang. Denkt daran den Namen eures Remote Laufwerks anzupassen.

Jetzt wird alle 5 Minuten auf dem Cloud Laufwerk geschaut, ob sich Daten im Verzeichnis „scans“ befinden. Ist das der Fall, werden diese Daten in den „consume“ Ordner von paperless verschoben.

📱 Home Assistant Notifications – So wird’s einfacher! 📱

In diesem Video zeige ich dir, wie du Benachrichtigungen in Home Assistant deutlich einfacher verwalten kannst! 🚀 Normalerweise muss man in jeder Automatisierung festlegen, wer welche Nachricht bekommt – sei es die Frau, die Kids oder man selbst. Dazu kommen noch kritische Benachrichtigungen, die extra Aufmerksamkeit erfordern. Ich habe eine Lösung entwickelt, mit der du das Ganze zentral steuern kannst. Selbst wenn sich GerĂ€te Ă€ndern, musst du nicht stundenlang deine Automatisierungen anpassen. 🔄

Um das Skript einzufĂŒgen, begib dich zu Home Assistant Skripte , lege eine neues Skript an und wĂ€hle ĂŒber die drei Punkte in der rechten oberen Ecke die YAML Bearbeitung aus. Dort kannst du das unten aufgefĂŒhrte Skript dann einfĂŒgen. Wichtig ! Die Dienstnamen fĂŒr die Benachrichtigungen der Alexa-Media Player Devices oder auch Mobile GerĂ€te mĂŒssen in der Variable „targets“ angepasst werden.

sequence:
  - variables:
      push_data: |-
        {% if critical %} {
          "push": {
            "sound": {
             "name": "default",
             "critical": 1,
              "volume": 1.0
             }
          }
        } {% else %} {} {% endif %}
    alias: push_data Variable, um den Channel "Critical" beim Iphone zu abonnieren
  - variables:
      targets: |-
        {% set t = [] %} 
        {% if group_admins %}
          {% set t = t + ["notify.mobile_app_iphone_tobias"] %}
        {% endif %} 
        {% if group_family %}
          {% set t = t + ["notify.mobile_app_iphone_tobias", "notify.mobile_app_slerch","notify.alexa_media_bad_oben"] %}
        {% endif %} 
        {% if alexa %}
          {% set t = t + ["notify.alexa_media_keller"] %}
        {% endif %} 
        {{ t | unique | list }}
    alias: targets fĂŒr alle gewĂŒnschten "notify" Dienste
  - variables:
      alexa_devices: "{{ targets | select('search', 'notify.alexa_media') | list }}"
    alias: "alexa_devices : Filter um nur die alexa Devices fĂŒr den Dienst zu filtern"
  - variables:
      media_players: >
        {% set media_players = alexa_devices | map('replace',
        'notify.alexa_media_', 'media_player.') | list %} {{ media_players }}
    alias: >-
      media_players: Aus dem Dienst werden automatisch alle Media_Player
      EntitÀtsnamen abgeleitet.
  - variables:
      volume_level: |
        {% if critical %}
          0.8
        {% else %}
          0.2
        {% endif %}
    alias: >-
      volume_level: Wenn critical aktiviert ist, wir eine andere LautstÀrke
      gewĂ€hlt , anonsten default fĂŒr die Ausgabe
  - repeat:
      for_each: "{{ media_players }}"
      sequence:
        - action: media_player.volume_set
          metadata: {}
          data:
            volume_level: "{{ volume_level }}"
          target:
            entity_id: "{{ repeat.item }}"
    enabled: true
  - repeat:
      sequence:
        - action: "{{ repeat.item }}"
          data:
            title: "{{ title }}"
            message: "{{ message }}"
            data: "{{ push_data }}"
      for_each: "{{ targets }}"
    enabled: true
  - delay:
      hours: 0
      minutes: 0
      seconds: 5
      milliseconds: 0
  - repeat:
      for_each: "{{ media_players }}"
      sequence:
        - action: media_player.volume_set
          metadata: {}
          data:
            volume_level: 0.1
          target:
            entity_id: "{{ repeat.item }}"
    enabled: true
  - action: persistent_notification.create
    metadata: {}
    data:
      message: "{{ targets }}"
alias: Notify All V2
description: ""
fields:
  message:
    selector:
      text:
        multiline: true
    name: message
  title:
    selector:
      text: null
    name: title
  group_admins:
    selector:
      boolean: {}
    name: group_admins
    required: true
  group_family:
    selector:
      boolean: {}
    name: group_family
    required: true
  critical:
    selector:
      boolean: {}
    name: critical
    required: true
  alexa:
    selector:
      boolean: {}
    name: alexa
    required: true

Folgende Videos kann ich dir als Grundlagenvideos zum Thema Notifications noch empfehlen.

💬 So schĂŒtzt ihr euer Zuhause mit Home Assistant vor der eigenen Vergesslichkeit

🔒 Mehr Sicherheit im eigenen Zuhause – ohne Alarmanlage! Vergesslichkeit kann schnell zu einem Problem werden: Offene Fenster, offene TĂŒren oder ein laufendes GerĂ€t können im Alltag leicht ĂŒbersehen werden. Genau hier kann Home Assistant helfen! 🏡✹ In diesem Video zeige ich euch zwei einfache Möglichkeiten, um euer Zuhause sicherer zu machen – nicht durch eine klassische Alarmanlage, sondern durch intelligente Automatisierungen, die eure Vergesslichkeit ausgleichen.

đŸ”č **Variante 1:** Eine schnelle und einfache Lösung – leicht umzusetzen und sofort nutzbar.

đŸ”č **Variante 2:** Eine elegantere, flexiblere Methode fĂŒr alle, die es noch smarter möchten.

Mit Home Assistant könnt ihr alltĂ€gliche Risiken minimieren und euer Smart Home noch nĂŒtzlicher gestalten. Seid gespannt! 🚀

Diesen Sensor verwende ich sehr gerne fĂŒr meine TĂŒren und Fenster *:

Die beiden Automatisierungsbeispiele aus dem Video:

alias: Warnung vor einer offenen TĂŒr
description: ""
triggers:
  - trigger: state
    entity_id:
      - input_boolean.notify_night
    to: "on"
  - trigger: numeric_state
    entity_id:
      - zone.home
    below: 1
conditions:
  - condition: state
    entity_id: binary_sensor.gruppe_aller_turen
    state: "on"
actions:
  - action: notify.mobile_app_iphone_tobias
    metadata: {}
    data:
      title: Hausinformation
      message: Es ist noch eine TĂŒre geöffnet
mode: single

Automatisierung 2

alias: Warnung vor einer offenen TĂŒr 2
description: ""
triggers:
  - trigger: state
    entity_id:
      - input_boolean.notify_night
    to: "on"
  - trigger: numeric_state
    entity_id:
      - zone.home
    below: 1
conditions:
  - condition: template
    value_template: |-
      {{ expand(states.binary_sensor)
        | selectattr('state', 'eq', 'on')
        | selectattr('attributes.device_class', 'eq', 'door')
        |rejectattr('entity_id', 'in' , ['binary_sensor.geschirrspuler_door'])
        | map(attribute='name')
        | list | count > 0
      }}
actions:
  - action: notify.mobile_app_iphone_tobias
    metadata: {}
    data:
      title: Hausinformation
      message: >-
        Es ist noch geöffnet: {{ expand(states.binary_sensor)   |
        selectattr('state', 'eq', 'on')   |
        selectattr('attributes.device_class', 'eq', 'door')  
        |rejectattr('entity_id', 'in' , ['binary_sensor.geschirrspuler_door'])  
        | map(attribute='name')   | list | join('\n') }}
mode: single

Weitere Videos, die zur Umsetzung hilfreich sein könnten und im Video erwÀhnt wurden:

🔧🚀 Immich – Komplette Installationsanleitung! So richtest du deine eigene Foto-Cloud ein đŸ“žđŸ’Ÿ

Heute möchte ich euch eine Software vorstellen, dir mir im Alltag viel Zeit einspart. Heutzutage haben wir tausende Bilder und Videos zu verwalten. Man dokumentiert den Wachstum der Kinder , will besondere Momente festhalten, oder nimmt einfach nur gerne Fotos von der Natur auf. Fotos und Videos gehören einfach zum heutigen Alltag. Lange Zeit habe ich mit Cloud Diensten gearbeitet. Ich will hier gar keine Namen nennen, aber die machen alle, mehr oder weniger gut, was ihre Aufgabe ist, nÀmlich Bilder verwalten. Irgendwie hat es mir nur nie gefallen, meine Bilder in die Cloud zu stellen. Deshalb möchte ich heute eine Software vorstellen, die mir aus meiner Sicht mindestens den gleichen Komfort bietet, aber lokal betrieben werden kann.

Um euch die Arbeit zu erleichtern, habe ich ein Installationsskript erstellt, welches euch den Einstieg in diese Software hoffentlich vereinfacht. Es kann als LXC Container unter Proxmox, VM oder direkt auf einer Hardware installiert werden.

Seht es mir nach, dass ich nicht alle Varianten durchtesten konnte. Voraussetzung ist ein 64 Bit basiertes Linux Betriebssystem ( mit Ubuntu getestet) . Auch solltet ihr ein wenig RAM mitbringen, da auch KI basierte Verfahren zum Einsatz kommen. Mehr dazu findet ihr im Video.

Immich ist kostenlos, bietet aber in der Software die Möglichkeit eine Lizenz zu erwerben. Damit erweitert ihr nicht den Funktionsumfang, aber ihr unterstĂŒtzt damit die Entwickler. Die Pflege und Entwicklung einer Software ist immer mit sehr viel Aufwand verbunden. Wenn euch die Software also gefĂ€llt, lege ich es jeden ans Herz , hier ggf. auch tĂ€tig zu werden 🙂

Home | Immich

Um das Skript zu installieren, fĂŒhrt folgenden Befehl aus:

wget https://smarthomeundmore.de/wp-content/uploads/install_immich.sh

danach muss das Skript noch ausfĂŒhrbar gemacht werden.

chmod +x install_immich.sh

Um jetzt die Installation auszufĂŒhren, mĂŒsst ihr nur noch das Skript aufrufen.

./install_immich.sh

Jetzt könnt ihr die bei der Installation angezeigte Adresse im Browser eingeben und loslegen.

Falls ihr euch das Skript manuell anlegen wollt, hier noch die Inhalte des Skriptes

#!/bin/bash

set -e  # Beende das Skript bei Fehlern

# Variablen definieren
INSTALL_DIR="/opt/immich-app"
IMMICH_USER="immich"
DOCKER_COMPOSE_YML_URL="https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml"
ENV_FILE_URL="https://github.com/immich-app/immich/releases/latest/download/example.env"

# Passwort f  r den Immich-Benutzer abfragen
echo "Bitte ein Passwort f  r den Benutzer '$IMMICH_USER' eingeben:"
read -s IMMICH_PASSWORD
echo "Bitte das Passwort erneut eingeben:"
read -s IMMICH_PASSWORD_CONFIRM

if [ "$IMMICH_PASSWORD" != "$IMMICH_PASSWORD_CONFIRM" ]; then
    echo "Passw  rter stimmen nicht   berein. Abbruch."
    exit 1
fi

# System aktualisieren
sudo apt update && sudo apt upgrade -y

# Notwendige Pakete installieren
sudo apt install -y curl wget apt-transport-https ca-certificates gnupg lsb-release pwgen

# Docker-Repository hinzuf  gen und Docker installieren
if ! command -v docker &> /dev/null; then
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    sudo apt update
    sudo apt install -y docker-ce docker-ce-cli containerd.io
    sudo usermod -aG docker $USER
    newgrp docker << END
    echo "Docker wurde installiert und ist sofort ohne Abmeldung nutzbar."
END
fi

# Docker Compose installieren
if ! command -v docker compose &> /dev/null; then
    sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    sudo chmod +x /usr/local/bin/docker-compose
fi

# Benutzer f  r Immich erstellen
if ! id "$IMMICH_USER" &>/dev/null; then
    sudo useradd -m -s /bin/bash "$IMMICH_USER"
    echo "$IMMICH_USER:$IMMICH_PASSWORD" | sudo chpasswd
    echo "Benutzer $IMMICH_USER wurde erstellt."
fi

# Benutzer zur Docker-Gruppe hinzuf  gen
sudo usermod -aG docker "$IMMICH_USER"

# Docker-Socket-Berechtigungen setzen
sudo chmod 666 /var/run/docker.sock

# Installationsverzeichnis erstellen und Berechtigungen setzen
sudo mkdir -p "$INSTALL_DIR"
sudo chown -R "$IMMICH_USER:$IMMICH_USER" "$INSTALL_DIR"
cd "$INSTALL_DIR"

# docker-compose.yml und .env herunterladen
sudo -u "$IMMICH_USER" wget -O docker-compose.yml "$DOCKER_COMPOSE_YML_URL"
sudo -u "$IMMICH_USER" wget -O .env "$ENV_FILE_URL"

# Standardwerte in der .env Datei setzen
sudo -u "$IMMICH_USER" sed -i "s|UPLOAD_LOCATION=./library|UPLOAD_LOCATION=$INSTALL_DIR/library|g" .env
sudo -u "$IMMICH_USER" sed -i "s|DB_DATA_LOCATION=./postgres|DB_DATA_LOCATION=$INSTALL_DIR/postgres|g" .env
sudo -u "$IMMICH_USER" sed -i "s|DB_PASSWORD=postgres|DB_PASSWORD=$IMMICH_PASSWORD|g" .env

# Container starten mit neuem Benutzer
sudo su - "$IMMICH_USER" -c "cd $INSTALL_DIR && docker compose up -d"

# IP-Adresse und Port ausgeben
IP_ADDRESS=$(hostname -I | awk '{print $1}')
PORT=$(sudo grep -oP 'IMMICH_SERVER_PORT=\K\d+' .env || echo "2283")

# Abschlussmeldung
echo "Installation abgeschlossen! Immich l  uft nun im Hintergrund unter dem Benutzer $IMMICH_USER."
echo "Installationsverzeichnis: $INSTALL_DIR"
echo "Datenbank-Passwort: $IMMICH_PASSWORD"
echo "Immich kann unter folgender Adresse erreicht werden: http://$IP_ADDRESS:$PORT"

💡 Warum ist EVCC 2025 ein Gamechanger?

EVCC ist eine der beliebtesten Lösungen fĂŒr das intelligente Laden von Elektroautos mit PV-Überschuss. Die neue Version bringt einige tiefgreifende Änderungen mit sich, die sowohl die Basisinstallation als auch die Konfiguration betreffen.

Einige Highlights der neuen Version:

✅ Überarbeitete Konfigurationsstruktur
✅ Verbesserte Integration in Home Assistant
✅ Erweiterte UnterstĂŒtzung fĂŒr verschiedene Wechselrichter und Stromtarife
✅ Neue Funktionen fĂŒr mehrphasiges Laden & Batteriespeicher

Egal, ob du bereits EVCC nutzt oder gerade erst startest – diese Änderungen solltest du kennen!

đŸ› ïž EVCC in Home Assistant 2025 installieren

Die Installation von EVCC unter Home Assistant ist einfacher geworden, erfordert aber einige Anpassungen. Hier sind die wichtigsten Schritte:

Basisinstallation und erste Konfiguration

Nach der Installation sind einige grundlegende Konfigurationsschritte erforderlich:

đŸ”č MQTT einrichten ( nicht zwingend notwendig )
đŸ”č Ladepunkt hinzufĂŒgen und mit dem EVCC-System verbinden
đŸ”č PV-Anlage & Batteriespeicher konfigurieren
đŸ”č Dynamische Stromtarife einbinden

Migration von einer bestehenden Installation

Falls du EVCC bereits nutzt, solltest du einige Punkte beachten:

⚡ Backup der aktuellen Konfiguration
⚡ ÜberprĂŒfung der YAML-Struktur (einige Parameter haben sich geĂ€ndert)
⚡ Anpassung an die neuen Konfigurationsmöglichkeiten

In meinem Video zeige ich dir Schritt fĂŒr Schritt, wie du EVCC installierst und die wichtigsten Änderungen ĂŒbernimmst.

🚀 Fazit: Lohnt sich das Update?

Definitiv! Die neuen Funktionen machen EVCC noch leistungsfĂ€higer und die Integration in Home Assistant wurde weiter verbessert. Besonders die neuen Einstellungen fĂŒr Stromtarife, PV-Prognosen und Batteriespeicher bringen das Smart Charging auf das nĂ€chste Level.

Wenn du bereits EVCC nutzt, solltest du dich mit den Änderungen vertraut machen – und falls du gerade erst startest, ist jetzt der perfekte Zeitpunkt, um EVCC in dein Smart Home zu integrieren!

🔋 Besuche die EVCC Homepage

EVCC Add-on ĂŒber HACS in Home Assistant installieren

EVCC kann ĂŒber das Home Assistant Community Store (HACS) Add-on integriert werden. Die aktuellste Version findest du hier:
👉 EVCC HACS Add-on auf GitHub

Damit bekommst du Zugriff und Steuerungsmöglichkeiten auf EVCC EntitÀten in Home Assistant. Beachte dabei meine Installationsanleitung.

Paperless NGX komplett einrichten – mit REST API Home Assistant Sensor

👉 Direkt auf YouTube schauen und abonnieren:
Smart Home & More auf YouTube

In diesem Video zeige ich euch, wie ihr unter Proxmox ( LXC oder VM), oder einem separaten PC Paperless NGX einrichtet. Da es recht viele Dinge dabei zu berĂŒcksichtigen gibt, habe ich euch dafĂŒr 3 Skripte erstellt.

  1. Installation
  2. Backup
  3. Restore

Mit diesen Skripten wird euch fast die gesamte Arbeit abgenommen.

Möchtest du Paperless ngx als Home Assistant Addon installieren, findest du hier eine Anleitung dazu:
https://youtu.be/wCiSkHQtYEE

Wichtiger Hinweis ! Bitte unbedingt beachten!

Ich habe die Freigabenamen umbenannt. Im Video bin ich darauf nochmal kurz eingegangen. Die Freigaben heißen nun:

consume

backup

restore

D.h. , wenn unter Windows die Freigaben gemountet werden, mĂŒssen diese Freigabenamen verwendet werden !

Skript install_paperless.sh

Hinweis: Die Skripte wurden auf Postgres 17, Redis 8 und Gotenberg „latest“ aktualisiert ( 12.11.2025)

#!/bin/bash
set -euo pipefail

# ---------------------------------------
# Helpers
# ---------------------------------------
log()  { echo -e "\033[1;32m[INFO]\033[0m $*"; }
warn() { echo -e "\033[1;33m[WARN]\033[0m $*"; }
err()  { echo -e "\033[1;31m[ERR ]\033[0m $*"; }

# ---------------------------------------
# Passwörter & Admin
# ---------------------------------------
prompt_for_password() {
  local password password_confirm
  if [[ "$1" == "PAPERLESS_PASSWORD" ]]; then
    echo -e "\n💡 Hinweis: Dieses Passwort wird fĂŒr den Linux-Benutzer 'paperless' und den Samba-Server verwendet."
    echo -e "Es wird fĂŒr den Zugriff auf freigegebene Samba-Ordner benötigt.\n"
  fi
  while true; do
    echo -e "\n🔒 Bitte geben Sie das Passwort fĂŒr **$1** ein:"
    read -s password
    echo -e "\n🔒 Bitte bestĂ€tigen Sie das Passwort:"
    read -s password_confirm
    if [[ "$password" == "$password_confirm" ]]; then
      echo -e "\n✅ Passwort erfolgreich gesetzt fĂŒr **$1**.\n"
      eval "$2='$password'"
      break
    else
      echo -e "\n❌ Die Passwörter stimmen nicht ĂŒberein. Bitte erneut eingeben.\n"
    fi
  done
}

prompt_for_admin_user() {
  echo -e "\nđŸ‘€ Bitte geben Sie den **Admin-Benutzernamen** ein (Standard: paperless):"
  read -r admin_user_input
  ADMIN_USER="${admin_user_input:-paperless}"
  echo -e "\n✅ Admin-Benutzer wurde auf **'$ADMIN_USER'** gesetzt.\n"
}

# Eingaben
prompt_for_password "PAPERLESS_PASSWORD" PAPERLESS_PASSWORD
prompt_for_admin_user
prompt_for_password "ADMIN_PASSWORD" ADMIN_PASSWORD

SAMBA_PASSWORD="$PAPERLESS_PASSWORD"
DB_PASSWORD="paperless"

# ---------------------------------------
# Pakete & Docker-Repo
# ---------------------------------------
update_and_install_dependencies() {
  log "Aktualisiere Paketliste und installiere benötigte Pakete
"
  sudo apt update
  sudo apt install -y apt-transport-https curl jq gnupg openssh-server \
                      samba samba-common-bin ca-certificates lsb-release
}

add_docker_repo() {
  log "FĂŒge Docker GPG-SchlĂŒssel und Repository hinzu
"
  sudo mkdir -p /etc/apt/keyrings
  if [[ ! -f /etc/apt/keyrings/docker.gpg ]]; then
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    sudo chmod a+r /etc/apt/keyrings/docker.gpg
  fi
  . /etc/os-release
  DOCKER_REPO="deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $VERSION_CODENAME stable"
  echo "$DOCKER_REPO" | sudo tee /etc/apt/sources.list.d/docker.list >/dev/null
  sudo apt update
}

# ---------------------------------------
# User/Gruppe
# ---------------------------------------
ensure_paperless_user_and_group() {
  if ! getent group paperless &>/dev/null; then
    log "Erstelle Gruppe 'paperless' mit GID 1002
"
    sudo groupadd -g 1002 paperless
  fi
  if ! id -u paperless &>/dev/null; then
    log "Erstelle Benutzer 'paperless' (UID 1002, GID 1002)
"
    sudo useradd -m -s /bin/bash -u 1002 -g paperless paperless
    echo "paperless:$PAPERLESS_PASSWORD" | sudo chpasswd
  fi
}

# ---------------------------------------
# Docker installieren
# ---------------------------------------
install_docker() {
  if ! command -v docker &>/dev/null; then
    log "Installiere Docker
"
    sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
    sudo systemctl enable --now docker
  fi
  if ! groups paperless | grep -q "\bdocker\b"; then
    log "FĂŒge Benutzer 'paperless' zur Gruppe 'docker' hinzu
"
    sudo usermod -aG docker paperless
  fi
}

# ---------------------------------------
# AppArmor/runc-Bug NUR bei Bedarf mitigieren
# ---------------------------------------
mitigate_if_apparmor_bug() {
  . /etc/os-release
  if [[ "${ID:-}" != "ubuntu" ]]; then
    log "Nicht Ubuntu – ĂŒberspringe AppArmor/runc-Erkennung."
    return 0
  fi
  if ! command -v docker >/dev/null 2>&1; then
    warn "Docker noch nicht installiert – Erkennung wird spĂ€ter erneut versucht."
    return 0
  fi

  sudo systemctl enable --now docker >/dev/null 2>&1 || true
  docker pull hello-world >/dev/null 2>&1 || true
  docker pull busybox:latest >/dev/null 2>&1 || true

  local TEST_OUT=0 OUTPUT
  if ! OUTPUT="$(docker run --rm --pull=never hello-world 2>&1)"; then
    TEST_OUT=1
  fi
  if [[ $TEST_OUT -ne 0 ]]; then
    if ! OUTPUT="$(docker run --rm --pull=never busybox:latest true 2>&1)"; then
      TEST_OUT=2
    else
      TEST_OUT=0
    fi
  fi

  if [[ $TEST_OUT -ne 0 ]] && echo "$OUTPUT" | grep -q 'net\.ipv4\.ip_unprivileged_port_start.*permission denied'; then
    warn "Erkannt: AppArmor/runc-Problem beim Container-Start."
    if ! dpkg -s containerd.io >/dev/null 2>&1; then
      warn "containerd.io nicht installiert (vermutlich Ubuntu-Containerd). Downgrade wird ĂŒbersprungen."
      return 0
    fi
    local TARGET_VERSIONS=()
    case "$VERSION_CODENAME" in
      plucky) TARGET_VERSIONS=("1.7.28-1~ubuntu.25.04~plucky" "1.7.27-1") ;;
      noble)  TARGET_VERSIONS=("1.7.28-1~ubuntu.24.04~noble"  "1.7.27-1") ;;
      jammy)  TARGET_VERSIONS=("1.7.28-1~ubuntu.22.04~jammy"  "1.7.27-1") ;;
      *)      TARGET_VERSIONS=("1.7.27-1") ;;
    esac
    local CURR; CURR="$(dpkg-query -W -f='${Version}\n' containerd.io || true)"
    for v in "${TARGET_VERSIONS[@]}"; do
      if [[ "$CURR" == "$v" ]]; then
        log "containerd.io bereits auf gewĂŒnschter Version ($v). Setze Hold."
        sudo apt-mark hold containerd.io || true
        return 0
      fi
    done
    local AVAILABLE SELECTED
    AVAILABLE="$(apt-cache madison containerd.io | awk '{print $3}')"
    SELECTED=""
    for v in "${TARGET_VERSIONS[@]}"; do
      if echo "$AVAILABLE" | grep -qx "$v"; then SELECTED="$v"; break; fi
    done
    if [[ -z "$SELECTED" ]]; then
      warn "Keine passende containerd.io-Version im Repo gefunden – Mitigation ĂŒbersprungen."
      return 0
    fi
    log "Mitigation: Downgrade/Pin containerd.io → $SELECTED"
    sudo apt-mark unhold containerd.io || true
    sudo apt-get install -y --allow-downgrades "containerd.io=${SELECTED}"
    sudo apt-mark hold containerd.io
    sudo systemctl restart containerd docker
  else
    log "Kein AppArmor/runc-Problem erkannt – keine Mitigation nötig."
  fi
}

# ---------------------------------------
# Samba
# ---------------------------------------
configure_samba() {
  sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak || true
  sudo mkdir -p /data/paperless/{backup,restore,consume,data,media,export,postgresql/_data,redis/_data}
  sudo chown -R paperless:paperless /data/paperless/
  sudo chmod -R 770 /data/paperless/

  if ! grep -q "^\[consume\]" /etc/samba/smb.conf; then
    sudo tee -a /etc/samba/smb.conf >/dev/null <<'EOF'

[consume]
   comment = Paperless Daten
   path = /data/paperless/consume
   browsable = yes
   writable = yes
   guest ok = no
   create mask = 0770
   directory mask = 0770
   valid users = paperless
EOF
  fi

  if ! grep -q "^\[backup\]" /etc/samba/smb.conf; then
    sudo tee -a /etc/samba/smb.conf >/dev/null <<'EOF'

[backup]
   comment = Paperless Backup Daten
   path = /data/paperless/backup
   browsable = yes
   writable = yes
   guest ok = no
   create mask = 0770
   directory mask = 0770
   valid users = paperless
EOF
  fi

  if ! grep -q "^\[restore\]" /etc/samba/smb.conf; then
    sudo tee -a /etc/samba/smb.conf >/dev/null <<'EOF'

[restore]
   comment = Paperless Restore Daten
   path = /data/paperless/restore
   browsable = yes
   writable = yes
   guest ok = no
   create mask = 0770
   directory mask = 0770
   valid users = paperless
EOF
  fi

  (echo "$SAMBA_PASSWORD"; echo "$SAMBA_PASSWORD") | sudo smbpasswd -a paperless -s
  sudo systemctl restart smbd
  log "Samba Shares [consume], [backup], [restore] wurden konfiguriert."
}

# ---------------------------------------
# Compose schreiben
# ---------------------------------------
write_compose() {
  log "Erstelle docker-compose.yml
"
  sudo mkdir -p /home/paperless
  sudo chown paperless:paperless /home/paperless

  cat <<EOL | sudo tee /home/paperless/docker-compose.yml >/dev/null
services:
  broker:
    image: redis:7
    container_name: broker
    restart: unless-stopped
    volumes:
      - /data/paperless/redis/_data:/data

  db:
    image: postgres:17
    container_name: db
    restart: unless-stopped
    volumes:
      - /data/paperless/postgresql/_data:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: paperless
      POSTGRES_USER: paperless
      POSTGRES_PASSWORD: $DB_PASSWORD

  gotenberg:
    image: gotenberg/gotenberg:latest
    container_name: paperless-gotenberg-1
    restart: unless-stopped
    command:
      - "gotenberg"
      - "--chromium-disable-javascript=false"
      - "--chromium-allow-list=.*"

  tika:
    image: apache/tika:latest
    container_name: tika
    restart: unless-stopped

  webserver:
    image: ghcr.io/paperless-ngx/paperless-ngx:latest
    container_name: webserver
    restart: unless-stopped
    depends_on:
      - db
      - broker
      - gotenberg
      - tika
    ports:
      - "8001:8000"
    volumes:
      - /data/paperless/consume:/usr/src/paperless/consume
      - /data/paperless/data:/usr/src/paperless/data
      - /data/paperless/media:/usr/src/paperless/media
      - /data/paperless/export:/usr/src/paperless/export
    environment:
      PAPERLESS_ADMIN_USER: $ADMIN_USER
      PAPERLESS_ADMIN_PASSWORD: $ADMIN_PASSWORD
      PAPERLESS_REDIS: redis://broker:6379
      PAPERLESS_DBHOST: db
      PAPERLESS_TIKA_ENABLED: 1
      PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
      PAPERLESS_TIKA_ENDPOINT: http://tika:9998
      PAPERLESS_OCR_LANGUAGE: deu
      PAPERLESS_TIME_ZONE: Europe/Berlin
      PAPERLESS_CONSUMER_ENABLE_BARCODES: "true"
      PAPERLESS_CONSUMER_ENABLE_ASN_BARCODE: "true"
      PAPERLESS_CONSUMER_BARCODE_SCANNER: ZXING
      PAPERLESS_EMAIL_TASK_CRON: '*/10 * * * *'
      USERMAP_UID: "1002"
      USERMAP_GID: "1002"
      PAPERLESS_DBSSLMODE: disable
EOL
}

# ---------------------------------------
# DB starten, pg_hba absichern, dann Rest starten
# ---------------------------------------
bringup_with_pg_hba_fix() {
  pushd /home/paperless >/dev/null

  log "Starte zunÀchst NUR Redis & Postgres
"
  sudo -u paperless docker compose up -d broker db

  # Auf DB warten
  log "Warte, bis Postgres erreichbar ist
"
  for i in {1..60}; do
    if sudo docker exec db pg_isready -q >/dev/null 2>&1; then
      break
    fi
    sleep 2
  done

  # Subnetz der Compose-Network ermitteln
  local NET="paperless_default"
  local SUBNET
  SUBNET="$(docker network inspect "$NET" 2>/dev/null | jq -r '.[0].IPAM.Config[0].Subnet' || true)"
  if [[ -z "${SUBNET:-}" || "${SUBNET}" == "null" ]]; then
    # Fallback: hÀufig 172.18.0.0/16
    SUBNET="172.18.0.0/16"
    warn "Konnte Subnetz nicht auslesen – nutze Fallback ${SUBNET}"
  else
    log "Ermitteltes Docker-Subnetz: ${SUBNET}"
  fi

  # pg_hba.conf patchen, falls Eintrag fehlt
  log "Sichere pg_hba.conf gegen 'no pg_hba.conf entry 
 no encryption' ab
"
  sudo docker exec db bash -lc "grep -q '${SUBNET} ' /var/lib/postgresql/data/pg_hba.conf || echo 'host all all ${SUBNET} scram-sha-256' >> /var/lib/postgresql/data/pg_hba.conf"

  # Postgres reload (ohne DB-Login)
  sudo docker exec db bash -lc 'kill -HUP 1'

  # Kurzer Probe-Connect (ohne SSL)
  export PGPASSWORD="$DB_PASSWORD"
  if ! sudo docker exec -e PGPASSWORD="$DB_PASSWORD" db psql -U paperless -d paperless -c 'SELECT 1;' >/dev/null 2>&1; then
    warn "Probe-Query fehlgeschlagen – fahre trotzdem fort (Paperless migriert beim Start)."
  else
    log "Probe-Query erfolgreich."
  fi
  unset PGPASSWORD

  log "Starte nun gotenberg, tika und webserver
"
  sudo -u paperless docker compose up -d gotenberg tika webserver
  popd >/dev/null
}

# ---------------------------------------
# MAIN
# ---------------------------------------
update_and_install_dependencies
add_docker_repo
ensure_paperless_user_and_group
install_docker
mitigate_if_apparmor_bug
configure_samba
write_compose
bringup_with_pg_hba_fix

sleep 2
sudo chown -R paperless:paperless /data/paperless

LOCAL_IP=$(hostname -I | awk '{print $1}')
echo -e "\n🚀 **Paperless ist jetzt bereit!**"
echo -e "🔗 **Zugriff im Browser:** http://$LOCAL_IP:8001\n"
echo -e "🔁 **Bitte einmal neu booten, falls Docker neu installiert wurde.**"

Um die Scripte unter Linux vom Webserver zu laden, kannst du auch folgenden Befehl verwenden.

wget https://smarthomeundmore.de/wp-content/uploads/install_paperless.sh
wget https://smarthomeundmore.de/wp-content/uploads/backup.sh
wget https://smarthomeundmore.de/wp-content/uploads/restore.sh

Danach mĂŒssen sie mit:

chmod +x install_paperless.sh
chmod +x backup.sh
chmod +x restore.sh

ausfĂŒhrbar gemacht werden.

Script backup.sh

#!/bin/bash
# Skript: backup.sh
# Dieses Skript fĂŒhrt ein Backup ĂŒber docker-compose aus und verschiebt anschließend die Backup-Datei(en).

echo "Starte Backup: Ein Backup wird jetzt durchgefĂŒhrt..."

# Wechsel in das Verzeichnis, in dem sich die docker-compose Datei befindet
cd /home/paperless || { echo "Fehler: Verzeichnis /home/paperless nicht gefunden."; exit 1; }

# FĂŒhre den docker-compose Befehl aus
sudo docker compose exec webserver document_exporter ../export -z

# PrĂŒfe, ob der Befehl erfolgreich war
if [ $? -eq 0 ]; then
  echo "Backup erfolgreich abgeschlossen."
  
  # PrĂŒfen, ob das Quellverzeichnis existiert
  if [ -d "/data/paperless/export" ]; then
    # Sicherstellen, dass das Zielverzeichnis existiert (falls nicht, wird es angelegt)
    mkdir -p /data/paperless/backup

    # PrĂŒfen, ob im Quellverzeichnis Dateien vorhanden sind
    if compgen -G "/data/paperless/export/*" > /dev/null; then
      echo "Verschiebe Backup-Datei(en) nach /data/paperless/backup..."
      mv /data/paperless/export/* /data/paperless/backup/
      
      if [ $? -eq 0 ]; then
        echo "Datei(en) erfolgreich verschoben."
      else
        echo "Fehler beim Verschieben der Datei(en)."
      fi
    else
      echo "Keine Datei(en) im Verzeichnis /data/paperless/export gefunden."
    fi
  else
    echo "Quellverzeichnis /data/paperless/export existiert nicht."
  fi
else
  echo "Fehler beim Backup."
fi

Script restore.sh

#!/bin/bash
# Skript: restore.sh
# Dieses Skript stellt ein Backup wieder her.

set -e

echo "Starte Wiederherstellung: Das Backup wird nun wiederhergestellt..."

DOCKER_COMPOSE_FILE="/home/paperless/docker-compose.yml"

# Funktion zum Auskommentieren der Umgebungsvariablen in docker-compose.yml
comment_out_env_vars() {
  echo "Kommentiere PAPERLESS_ADMIN_USER und PAPERLESS_ADMIN_PASSWORD in der docker-compose.yml aus..."

  # Erstelle ein Backup der Datei, falls noch nicht gesichert
  if [ ! -f "${DOCKER_COMPOSE_FILE}.bak" ]; then
    sudo cp "$DOCKER_COMPOSE_FILE" "${DOCKER_COMPOSE_FILE}.bak"
  fi

  # Setze sicherheitshalber Schreibrechte
  sudo chmod u+w "$DOCKER_COMPOSE_FILE"

  # FĂŒge das `#` nur hinzu, falls es noch nicht vorhanden ist
  sudo sed -i 's/^\( *PAPERLESS_ADMIN_USER: \)/#\1/' "$DOCKER_COMPOSE_FILE"
  sudo sed -i 's/^\( *PAPERLESS_ADMIN_PASSWORD: \)/#\1/' "$DOCKER_COMPOSE_FILE"

  echo "Variablen erfolgreich auskommentiert."
}

# Variablen auskommentieren, bevor das Skript weiterlÀuft
comment_out_env_vars

# Verzeichnisse definieren
BACKUP_DIR="/data/paperless/restore"
EXPORT_DIR="/data/paperless/export"
DIRECTORIES_TO_DELETE=(
  "/data/paperless/consume"
  "/data/paperless/export"
  "/data/paperless/media"
  "/data/paperless/postgresql"
  "/data/paperless/redis"
)

# PrĂŒfe, ob das Backup-Verzeichnis existiert
if [ ! -d "$BACKUP_DIR" ]; then
  echo "Fehler: Backup-Verzeichnis $BACKUP_DIR existiert nicht."
  exit 1
fi

# Schritt 1: Docker Compose herunterfahren
echo "Wechsle in /home/paperless und fahre Docker Compose herunter..."
cd /home/paperless || { echo "Fehler: Verzeichnis /home/paperless nicht gefunden."; exit 1; }
sudo docker compose down

# Schritt 2: Lösche die angegebenen Verzeichnisse
echo "Lösche die folgenden Verzeichnisse:"
for dir in "${DIRECTORIES_TO_DELETE[@]}"; do
  echo "  $dir"
  if [ -d "$dir" ]; then
    sudo rm -rf "$dir"
    echo "    -> $dir gelöscht."
  else
    echo "    -> $dir existiert nicht, ĂŒberspringe..."
  fi
done

# Schritt 3: Erstelle das Export-Verzeichnis neu
echo "Erstelle das Verzeichnis $EXPORT_DIR..."
sudo mkdir -p "$EXPORT_DIR"
if [ $? -ne 0 ]; then
  echo "Fehler: Konnte $EXPORT_DIR nicht erstellen."
  exit 1
fi

# Schritt 4: Suche nach einer Archivdatei im Backup-Verzeichnis (z. B. *.zip)
ARCHIVE_FILE=$(find "$BACKUP_DIR" -maxdepth 1 -type f -name "*.zip" | head -n 1)
if [ -z "$ARCHIVE_FILE" ]; then
  echo "Fehler: Keine Archivdatei (*.zip) im Backup-Verzeichnis gefunden."
  exit 1
fi
echo "Gefundene Archivdatei: $ARCHIVE_FILE"

# Schritt 5: Kopiere die Archivdatei in das Export-Verzeichnis
echo "Kopiere die Archivdatei nach $EXPORT_DIR..."
sudo cp "$ARCHIVE_FILE" "$EXPORT_DIR"
if [ $? -ne 0 ]; then
  echo "Fehler beim Kopieren der Archivdatei."
  exit 1
fi

# Schritt 6: Wechsel in das Export-Verzeichnis und entpacke die Archivdatei
cd "$EXPORT_DIR" || { echo "Fehler: Konnte nicht in $EXPORT_DIR wechseln."; exit 1; }

# ÜberprĂŒfe, ob 'unzip' installiert ist und installiere es gegebenenfalls
if ! command -v unzip >/dev/null 2>&1; then
  echo "Das Paket 'unzip' ist nicht installiert. Versuche, es zu installieren..."
  if command -v apt-get >/dev/null 2>&1; then
    sudo apt-get update && sudo apt-get install -y unzip
  elif command -v yum >/dev/null 2>&1; then
    sudo yum install -y unzip
  else
    echo "Kein unterstĂŒtzter Paketmanager gefunden. Bitte installiere 'unzip' manuell."
    exit 1
  fi
fi

# Entpacken der Archivdatei
ARCHIVE_BASENAME=$(basename "$ARCHIVE_FILE")
echo "Entpacke $ARCHIVE_BASENAME..."
unzip "$ARCHIVE_BASENAME"
if [ $? -ne 0 ]; then
  echo "Fehler beim Entpacken von $ARCHIVE_BASENAME."
  exit 1
fi
echo "Archiv erfolgreich entpackt."

# Optional: Entferne die kopierte Archivdatei, falls sie nicht mehr benötigt wird
# sudo rm "$ARCHIVE_BASENAME"

# Schritt 7: Starte Docker Compose Container neu
echo "Wechsle zurĂŒck nach /home/paperless und starte die Container..."
cd /home/paperless || { echo "Fehler: Verzeichnis /home/paperless nicht gefunden."; exit 1; }
sudo -u paperless docker compose up -d
if [ $? -ne 0 ]; then
  echo "Fehler: Docker Compose konnte nicht gestartet werden."
  exit 1
fi

sudo chown -R paperless:paperless /data/paperless/consume /data/paperless/media
sudo chmod -R 775 /data/paperless/consume /data/paperless/media
sudo chown paperless:paperless /home/paperless/docker-compose.yml


sleep 60

cd /home/paperless
# Schritt 8: FĂŒhre den Importbefehl aus
echo "FĂŒhre Importbefehl aus..."
sudo docker compose exec webserver document_importer ../export
sudo chown -R paperless:paperless /data/paperless 
if [ $? -eq 0 ]; then
  echo "Import erfolgreich abgeschlossen."
else
  echo "Fehler beim Import."
  exit 1
fi
echo " Bitte einmal das System neu booten ! "
echo "---------------------------ENDE--------------------------------"

Upgrade Postgres 16 zu Postgres 17 ( bei vorhandener Installation )

ACHTUNG: Bitte zuvor unbedingt ein Backup der virtuellen Maschine oder des LXC Containers machen !

ZunÀchst begebt euch im Container oder der VM in das Verzeichnis /home/paperless. Dort findet ihr eine Datei docker-compose.yml.

Als ersten Schritt mĂŒssen wir nun die Docker Container beenden.

docker compose down

mit nano docker-compose.yml kontrollieren wir die Eintragungen der Compose Datei. Dabei ist folgender Abschnitt relevant:

Hier sieht man , dass aktuell das Image postgres:16 verwendet wird. Das brauchen wir fĂŒr den Migrationsprozess in genau dieser Form. Merkt euch zudem auch den POSTGRES_USER , den brauchen wir fĂŒr den nĂ€chsten Schritt.

Mit Strg+X beenden wir den Dateieditor und begeben uns in die Konsole.
Dort geben wir nun folgenden Befehl zum starten der Datenbank ein:

docker compose up -d db

Im nÀchsten Schritt sichern wir uns nun die aktuelle Datenbank:

docker exec -t db pg_dumpall -U DATENBANKUSER > all.sql

Bei DATENBANKUSER mĂŒsst ihr den User aus eurer docker-compose.yml eintragen. Im Beispiel ist es der User paperless.

Nachdem die Sicherung erfolgt ist, beenden wir erneut die Container:

docker compose down

Jetzt können wir erneut mit:

nano docker-compose.yml

unser Compose File editieren.

Jetzt mĂŒssen folgende Eintragungen angepasst werden:

Wir Ă€ndern also image: postgres:16 in image: postgres:17 und die Zeile volumes: …../_data in …./datav17

Danach starten wir erneut den Datenbank Container mit

docker compose up -d db

Jetzt mĂŒssen wir unsere Sicherung der Datenbank und die neu initialisierte Datenbank zurĂŒckkopieren.

Das können wir mit

cat all.sql | docker exec -i db psql -U DATENBANKUSER

machen. Dabei ist DATENBANKUSER wieder unser POSTGRES Datenbank Benutzer. In unserem Beispiel paperless.

Wenn der Import Vorgang nun ohne Fehler durchgelaufen ist, können wir mit

docker compose down
docker compose up -d

alle Container wieder starten.

Redis und Gotenberg Update

Um Redis und Gotenberg auf eine neue Version zu updaten sind auch wieder Anpassungen in der docker-compose.yml nötig.

Dazu mĂŒssen zunĂ€chst die Container gestoppt werden.

docker compose down

Danach editieren wir erneut die docker-compose.yml mit

nano docker-compose.yml

und Àndern folgende Zeilen:

Hier tragt die gewĂŒnschte Redis Version ein. In meinem Beispiel habe ich von Version 7 auf 8 gewechselt.

FĂŒr Gotenberg gehen wir Ă€hnlich vor. Hier habe ich mich entschieden, die „latest“ Variante zu verwenden.

Nach den Änderungen , beendet den Editor mit Strg+X und speichert mit „Yes“ die Datei.

Jetzt mĂŒssen wir noch die Container aktualisieren.

docker compose pull

und erneut starten.

docker compose up -d

Jetzt sollten alle Container in der aktuellen eingetragenen Version zur VerfĂŒgung stehen.

Update 23.09.2025 – Paperless-ngx: 1:1-Backup & Restore (Docker/Proxmox/LXC)

Überblick

Diese ErgĂ€nzung zeigt eine einfache, robuste 1:1-Sicherung und Wiederherstellung einer Paperless-ngx-Instanz – ohne export/import und ohne Manifest-Probleme. Geeignet fĂŒr UmzĂŒge auf eine neue LXC/VM und fĂŒr regelmĂ€ĂŸige Vollbackups.

Vorteile:

  • VollstĂ€ndiges Abbild von /data/paperless (Dokumente, Postgres, Redis, Konfiguration)
  • VersionsunabhĂ€ngig (kein Versions-Matching beim Import nötig)
  • Schnelle Wiederherstellung des exakten Zustands

Wichtig: Nach dem Restore sind die alten Benutzer & Passwörter der Quellinstanz wieder aktiv – auch wenn beim Neuaufsetzen andere Zugangsdaten vergeben wurden.


Voraussetzungen

  • Paperless-ngx lĂ€uft via Docker Compose.
  • Datenpfad: /data/paperless, Compose-Projekt: /home/paperless.
  • Auf der Zielinstanz wurde Paperless vorab mit dem bekannten Install-Skript bereitgestellt (Container/Volumes/ENV).

A) Backup auf der Quellinstanz erstellen

1) In das Arbeitsverzeichnis wechseln

cd /root

2) Backup-Skript laden und ausfĂŒhrbar machen

wget https://smarthomeundmore.de/wp-content/uploads/backup_new.sh
chmod +x backup_new.sh

3) Backup starten

./backup_new.sh

Ablauf:

  • Paperless-Container werden gestoppt.
  • Ein komprimiertes Archiv wird erstellt und in /data/paperless/backup abgelegt.
  • Container werden automatisch neu gestartet.

4) Backup ĂŒbertragen

Das erzeugte Archiv (z. B. paperless-backup-YYYY-MM-DD_HH-MM.tar.gz) auf die Zielinstanz kopieren (z. B. mit scp oder rsync).

B) Restore auf der Zielinstanz durchfĂŒhren

1) Zielumgebung bereitstellen

Paperless auf der Zielinstanz wie gewohnt mit dem Install-Skript einrichten (Compose/ENV).
Hinweis: Nach dem Restore gelten wieder die alten Credentials aus der gesicherten Instanz.

2) Backup-Datei platzieren

Backup nach /home/paperless kopieren.
Nicht nach /data/paperless/restore legen – das Restore-Skript löscht /data/paperless vollstĂ€ndig.

3) Restore-Skript laden und ausfĂŒhrbar machen

cd /root
wget https://smarthomeundmore.de/wp-content/uploads/restore_new.sh
chmod +x restore_new.sh

4) Restore ausfĂŒhren (mit absolutem Pfad)

./restore_new.sh /home/paperless/paperless-backup-YYYY-MM-DD_HH-MM.tar.gz

Ablauf:

  • Container werden gestoppt.
  • /data/paperless wird gelöscht.
  • Das Backup wird 1:1 mit korrekten Besitzrechten zurĂŒckgespielt (tar --same-owner --numeric-owner).
  • Container starten automatisch wieder.

ASN QR Codes generieren

Avery Zweckform QR-Code Generator von Tobias L. Meier: https://tobiasmaier.info/asn-qr-code-label-generator/

ErgÀnzung & Dank an Murat

An dieser Stelle auch ein herzliches Dankeschön an Murat, der mich nach einem meiner YouTube-Videos auf eine interessante ErgÀnzung aufmerksam gemacht hat.

Er hatte bei der Nutzung des ASN-QR-Code-Label-Generators von Tobias Maier Schwierigkeiten, die QR-Codes korrekt und passgenau zu drucken. Deshalb hat er kurzerhand ein eigenes Projekt gestartet, mit dem sich mehr Kontrolle ĂŒber den Druck realisieren lĂ€sst:

👉 ASN-QR-Code-Label-Generator von Murat auf GitHub

Vielleicht ist das auch fĂŒr dich hilfreich, wenn du Ă€hnliche Probleme beim Druck hast. Murat freut sich sicherlich ĂŒber Feedback und Tests aus der Community.

Home Assistant Rest API Sensoren

Im Video habe ich auch gezeigt, wie man einen Sensor in Home Assistant erstellt, um sich die Anzahl der Dokumente im Posteingang anzeigen zu lassen. Die Informationen dazu habe ich von FlemmingŽs Blog, wo einige Beispielsensoren zu finden sind. Tolle Arbeit und sehr gut erklÀrt.

Monitoring Paperless-ngx in Home-Assistant – Flemming’s Blog

Empfohlene Hardware fĂŒr die Digitalisierung und die QR Codes

Ein weiterer Scanner, der hÀufiger im Kontext mit paperless-ngx genannt wird, ist der Brother ADS-1700W. Da ich diesen allerdings nicht selber getestet habe, kann ich keine direkte Empfehlung dazu aussprechen.

Solltest du in den Scripten noch Fehler finden, kannst du mir gerne deine Korrekturen als Mail zukommen lassen. Meine Kontakdaten findest du im Impressum.

📌 Home Assistant Sensordaten exportieren & in Excel nutzen! 🚀

Möchtest du Sensordaten aus Home Assistant exportieren und diese in Excel oder anderen Tools weiterverarbeiten? In meinem neuesten Video zeige ich dir, wie du mit einfachen Schritten deine Daten extrahierst, speicherst und optimal aufbereitest. Dabei erhĂ€ltst du praktische Tipps, die dir helfen, deine Daten in handliche Formate zu ĂŒberfĂŒhren – ideal fĂŒr den privaten Gebrauch oder berufliche Projekte.

Lass dich von den vielfÀltigen Möglichkeiten inspirieren und erweitere deine Kenntnisse im Umgang mit Home Assistant. So wird der Datenexport zu einem spannenden und unkomplizierten Prozess!

Was dich im Video erwartet:

  • Wie du Sensordaten aus Home Assistant extrahierst 📡
  • Welche Möglichkeiten es fĂŒr den Export gibt 🔄
  • Wie du die Daten fĂŒr Excel & Co. optimierst 📊

Video:
Schau dir das Video hier an: https://youtu.be/iEUIEaDh5XU