Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Praktische Anwendungen (Showcase)
  4. [Vorlage] Synchronisation / Backup von Fileserver in Cloud und Erfolgsanzeige in VIS

NEWS

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    8.8k

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    13
    1
    2.2k

  • Neues Video "KI im Smart Home" - ioBroker plus n8n
    BluefoxB
    Bluefox
    16
    1
    3.4k

[Vorlage] Synchronisation / Backup von Fileserver in Cloud und Erfolgsanzeige in VIS

Geplant Angeheftet Gesperrt Verschoben Praktische Anwendungen (Showcase)
3 Beiträge 2 Kommentatoren 974 Aufrufe 1 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • MicM Offline
    MicM Offline
    Mic
    Developer
    schrieb am zuletzt editiert von
    #1

    ACHTUNG: Man sollte für folgendes auf jeden Fall (Grund)kenntnisse von JavaScript und Shell-Programmierung und Linux mitbringen, sowie vorher ein Backup der Daten machen.

    Hi,

    ich bin noch nicht so lange in der Linux-Welt unterwegs, aber mag es, mit Scripts Dinge zu steuern :)

    Daher möchte ich gerne mit der ioBroker-Community meine Vorgehensweise teilen. Sicherlich alles andere als perfekt, aber es läuft 8-)

    Das ganze hat mich etwas Zeit gekostet, vor allem mich einzuarbeiten in Bash, wie Linux tickt, Proxmox, etc. Ist für mich ein nettes Hobby.

    <size size="150">Ausgangssituation / Use Case:</size>

    Auf einem Linux-Server (bei mir: Proxmox-Virtualisierung) liegen Dateien, die ich Nachts in die Cloud (bei mir: Microsoft OneDrive) synchronisieren möchte. In VIS möchte ich sehen, ob die Synchronisierung erfolgreich lief, also sichergestellt ist, dass ein Backup in die Cloud erfolgte.

    <size size="150">Durchführung:</size>

    Tools:

    • https://rclone.org/ - sehr mächtig und kann mit vielen Clouds umgehen.

    • https://github.com/ioBroker/ioBroker.simple-api/blob/master/README.md

    Bei mir läuft auf einem Proxmox-Container ein Turnkey-Fileserver mit Samba. Im Endeffekt sollte hier eine typische Linux-Umgebung vorliegen.

    Auf diesem Container habe ich rclone installiert und über die Kommandozeile entsprechend eingerichtet und die Cloud entsprechend konfiguriert.

    Auf der Weboberfläche vom Turnkey-Fileserver habe ich dann entsprechende CronJobs eingerichtet, hier ein Bash-Script-Beispiel, das bei mir jede Nacht läuft. Das Script habe ich in eine Datei gepackt und auf dem Fileserver abgelegt und der CronJob führt es aus.

    #!/bin/bash
    
    # Variablen
    DATENOW=`date '+%Y-%m-%d_%H-%M-%S'`;
    LOCKDIR="/_myshare/_my-cron-jobs/mylock_onedrive_crypto" # Um zu prüfen, dass das Script nicht zweimal gleichzeitig ausgeführt wird.
    LOGFILE="/_myshare/_my-cron-jobs/rclone_crypto_$DATENOW.log"
    
    # ioBroker-Datenpunkte
    # Achtung: Zum setzen ist der simple-api Adapter notwendig, damit dieser Browser-Kommandos empfangen kann.
    IOBROKERSTATUS=javascript.0.mic.vis-support.proxmoxBackup.cryptomatorSuccessful
    IBROKERLASTTIME=javascript.0.mic.vis-support.proxmoxBackup.cryptomatorLastDateTime
    # ioBroker-IP:Port (Port von simple-api Adapter)
    IPP=10.10.0.140:8087
    
    # ################################################
    # Script nicht 2mal ausführen, daher arbeiten wir mit Lock.
    # http://wiki.bash-hackers.org/howto/mutex
    # https://askubuntu.com/questions/142002/generic-solution-to-prevent-a-long-cron-job-from-running-in-parallel
    # ##################################################
    
    if mkdir "${LOCKDIR}"; then
      echo "Locking succeeded (script is not already running), so we can continue with our script" >&2
      trap 'rm -rf "${LOCKDIR}"' EXIT # Lock dir deleted whenever script is exited, stopped, etc.
    else
      echo "Lock failed, script is already running - exit" >&2
      exit 1
    fi
    
    # Hier das eigentliche Kommando
    if rclone sync /_myshare/XYZ remote_OneDrive:XYZ --log-file "${LOGFILE}" --log-level "INFO"
        echo 'rclone successfully executed'
        DATENOWSUCC=`date '+%Y-%m-%dT%H:%M:%S'`;
        curl http://${IPP}/set/${IOBROKERSTATUS}?value=true
        curl http://${IPP}/set/${IBROKERLASTTIME}?value={$DATENOWSUCC}
    else
        echo 'rclone failed'
        DATENOWFAIL=`date '+%Y-%m-%dT%H:%M:%S'`;
        curl http://${IPP}/set/${IOBROKERSTATUS}?value=false
        curl http://${IPP}/set/${IBROKERLASTTIME}?value={$DATENOWFAIL}
    fi
    

    Dieses Bash-Script macht folgendes:

    1. Es führt die Synchronisierung des lokalen Verzeichnisses "/_myshare/XYZ" mit der Cloud im Verzeichnis "XYZ" durch. Das ganze ist "einweg", das heißt Änderungen in der Cloud werden nicht berücksichtigt. Also eine reine Backup-Lösung.

    2. Der Erfolg (oder Misserfolg) der tagtäglichen Synchronisierung wird im ioBroker in Datenpunkte (dank ioBroker-Adapter simple-api) geschrieben.

    ioBroker

    Damit das ganze läuft, muss im ioBroker der simple-api-Adapter laufen.

    Mit folgendem Script werden die benötigten Datenpunkte erstellt, die zum einen das obige Bash-Script füllt, und die zum anderen für die Anzeige im VIS dienen.

    /******************************************************************************************
     * ---------------------------
     * PROXMOX: Cloud-Backup mittels rclone: Datenpunkte erstellen und für VIS auswerten
     * ---------------------------
     * Diese werden direkt von den Bash-Scripts geschrieben (Fileserver: /_myshare/_my-cron-jobs)
     *
     * Siehe https://forum.iobroker.net/viewtopic.php?f=35&t=19004
     * 
     * Change Log
     *  0.2  Mic - Bug fix
     *  0.1  Mic - Initial release 
     *******************************************************************************************/
    
    const STATE_PATH = 'javascript.0.mic.vis-support.proxmoxBackup.';
    
    // Die verschiedenen Backups
    // schedule: wann wird das Script ausgeführt.
    // noOfDays: innerhalb wie vielen Tagen muss das Backup gelaufen sein, damit "Successful"=true
    const CONF_BACKUP = [
        {'name': 'keepass', 'schedule_hour': 5, 'schedule_minute': 15, 'noOfDays': 2},
        {'name': 'cryptomator', 'schedule_hour': 5, 'schedule_minute': 20, 'noOfDays': 2},
    ];
    
    // Erweitertes Log
    const LOG_DEBUG = true;
    
    /*******************************************************************************
     * Ab hier nichts mehr ändern / Stop editing here!
     ******************************************************************************/
    
    // Globale Variablen
    var G_ScheduleObjects = {};  // Contains the object for each schedule
    
    /*******************************************************************************
     * Executed on every script start.
     *******************************************************************************/
    init();
    function init() {
    
        // Create states
        createBackupStates();
    
        // Main Script starten, 3s nach State-Generierung
        setTimeout(main, 3000);
    
    }
    
    /*******************************************************************************
     * Haupt-Skript
     *******************************************************************************/
    function main() {
        for (let lpEntry of CONF_BACKUP) {
    
            var loopScheduleObjectId = lpEntry.name + '_schedule'; // ID for each schedule object. We define it here to be able to clear the schedule.
    
            /*********************        
             * 1\. Execute once Backup was performed
             ********************/
            on({id: STATE_PATH + lpEntry.name + 'LastDateTime', change: 'any'}, function(obj) {
                if (getState(STATE_PATH + lpEntry.name + 'Successful').val === true ) {
                    setState(STATE_PATH + lpEntry.name + 'ForVIS_BackupSuccessful', true);        
                } else {
                    setState(STATE_PATH + lpEntry.name + 'ForVIS_BackupSuccessful', false); // Jetzt nicht unbedingt "within last x days", aber jedenfalls war Backup nicht erfolgreich!
                }
            }); // Gelbes Dreieck Kann man links ignorieren, wir brauchen hier die Funktion innerhalb der Schleife
    
            /*********************        
             * 2\. Schedule for every day
             ********************/
            if(LOG_DEBUG) log('Proxmox-Cloud-Backup: Setze Schedule für ' + lpEntry.name + ', gesetzt auf Stunde ' + lpEntry.schedule_hour + ' und Minute ' + lpEntry.schedule_minute);
            clearSchedule(loopScheduleObjectId); // Let's clear the schedule to make sure no former schedules are running. Not sure if we really need this, but just in case.
            G_ScheduleObjects[loopScheduleObjectId] = schedule({hour: lpEntry.schedule_hour, minute: lpEntry.schedule_minute}, function () {
    
                let strDateLastBackup = getState(STATE_PATH + lpEntry.name + 'LastDateTime').val;
                if (g_myIsValueEmptyNullUndefined(strDateLastBackup) === false)  {
    
                    // Date/Time of backup + X days -- from https://stackoverflow.com/questions/3674539/incrementing-a-date-in-javascript
                    let noOfDaysToCheck = lpEntry.noOfDays;
                    let dtLastBackupPlusXDays = new Date(strDateLastBackup);
                    dtLastBackupPlusXDays = F_addDays(dtLastBackupPlusXDays, noOfDaysToCheck);
    
                    // Current date
                    let dtCurrentForCompare = new Date();    
    
                    // Compare
                    if (dtLastBackupPlusXDays > dtCurrentForCompare) {
                        // Last Backup took place within last X days, so we set state to true
                        setState(STATE_PATH + lpEntry.name + 'ForVIS_BackupSuccessful', true);
                    } else {
                        setState(STATE_PATH + lpEntry.name + 'ForVIS_BackupSuccessful', false);
                    }
    
                } else {
                    // Datenpunkt für letztes Backup nicht gesetzt, also setzen wir auf false (zur Sicherheit)
                    setState(STATE_PATH + lpEntry.name + 'ForVIS_BackupSuccessful', false);
                }
                if(LOG_DEBUG) log('Proxmox-Cloud-Backup: Update Datenpunkt für ' + lpEntry.name + ' durchgeführt.');
            }); // Gelbes Dreieck Kann man links ignorieren, wir brauchen hier die Funktion innerhalb der Schleife
    
        } // for
    }
    
    /*******************************************************************************
     * Create States
     *******************************************************************************/
    function createBackupStates() {
        for (let lpEntry of CONF_BACKUP) {
            createState(STATE_PATH + lpEntry.name + 'Successful', {'name': lpEntry.name + ' Successful?', 'type':'boolean', 'read':true, 'write':true, 'role':'info', 'def':false });
            createState(STATE_PATH + lpEntry.name + 'LastDateTime', {'name': lpEntry.name + ' Last Date/Time', 'type':'string', 'read':true, 'write':true, 'role':'info', 'def':'' });
            createState(STATE_PATH + lpEntry.name + 'ForVIS_BackupSuccessful', {'name': lpEntry.name + ' Status For VIS: Performed Successfully?', 'type':'boolean', 'read':true, 'write':true, 'role':'info', 'def':false });
       }
    }
    
    /*******************************************************************************
     * Function to add days to a given date/time. 
     *******************************************************************************/
    function F_addDays(startDateTime, numberOfDays) {
        return new Date(startDateTime.getTime() + (numberOfDays * 24 *60 * 60 * 1000));
    }
    
    

    Damit werden dann die entsprechenden Datenpunkte erzeugt, hier ein Auszug:
    6940_back1.png

    Zum Schluss kann man dann den Datenpunkt "javascript.0.mic.vis-support.XXXXBackup.cryptomatorForVIS_BackupSuccessful" entsprechend in VIS verwenden. Er gibt true/false zurück.
    6940_back2.png

    Das "smarte" an der ganzen Sache ist:

    Im VIS wird nur dann "Backup erfolgreich" angezeigt, wenn

    1. Der Cron-Job ausgeführt wurde

      • Die Synchronisierung mit der Cloud erfolgreich war
      • Die letzte erfolgreiche Ausführung innerhalb von X Tagen war (im JavaScript konfigurierbar, im Beispiel auf 2 Tage gesetzt, 'noOfDays': 2)

    Schlussbemerkungen:

    Die Installation und Einrichtung von rclone ist über den obigen Link und Google gut durchführbar.

    Sämtliche Pfade müssen natürlich im Bash-Script und Javascript angepasst werden etc.

    Bitte das ganze erst mal nur mit Test-Verzeichnissen durchführen, gerade das Tool rsync ist da gnadenlos und führt exakt das aus, was in den Parametern steht.

    Für Verbesserungsvorschläge usw. bin ich natürlich sehr dankbar :)

    P.S. Warum verwende ich Microsoft OneDrive? Nun, es bietet 1TB Speicherplatz in Verbindung mit dem MS-Office-Abo, daher aus meiner Sicht sehr günstig in dieser Kombination und mir ist ansonsten kein Cloud-Anbieter bekannt mit diesem guten Ratio aus "Euro pro GB Speicher".

    1 Antwort Letzte Antwort
    1
    • ruhr70R Offline
      ruhr70R Offline
      ruhr70
      schrieb am zuletzt editiert von
      #2

      Wow! Super durchdacht und schön gelöst.

      Danke fürs teilen und der ausführlichen Beschreibung!

      Adapter: Fritzbox, Unify Circuit
      Skripte: dynamic hue, Bluetooth Scan, Multi-Ereignisliste

      1 Antwort Letzte Antwort
      0
      • MicM Offline
        MicM Offline
        Mic
        Developer
        schrieb am zuletzt editiert von
        #3

        Gern geschehen und danke für Dein Feedback ruhr70!

        Hab oben im JavaScript übrigens noch einen Fehler behoben.

        1 Antwort Letzte Antwort
        0
        Antworten
        • In einem neuen Thema antworten
        Anmelden zum Antworten
        • Älteste zuerst
        • Neuste zuerst
        • Meiste Stimmen


        Support us

        ioBroker
        Community Adapters
        Donate

        354

        Online

        32.4k

        Benutzer

        81.5k

        Themen

        1.3m

        Beiträge
        Community
        Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
        ioBroker Community 2014-2025
        logo
        • Anmelden

        • Du hast noch kein Konto? Registrieren

        • Anmelden oder registrieren, um zu suchen
        • Erster Beitrag
          Letzter Beitrag
        0
        • Home
        • Aktuell
        • Tags
        • Ungelesen 0
        • Kategorien
        • Unreplied
        • Beliebt
        • GitHub
        • Docu
        • Hilfe