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. Skripten / Logik
  4. IOBroker Automatisiertes Deployment

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.2k

IOBroker Automatisiertes Deployment

Geplant Angeheftet Gesperrt Verschoben Skripten / Logik
12 Beiträge 3 Kommentatoren 377 Aufrufe 4 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.
  • V Vippis

    Hallo Community,

    ich bin dabei ein Deployment Skript für IOBroker zu erstellen, um automatisiert Raspberry Pis aufzusetzen mit einem immer gleichen Basissystem.

    Docker compose läuft. Ich brauche Hilfe bei folgenden Deployment per IOB CLI:

    • IOB Admin Passwort automatisiert setzen

    • Welcome Screen überspringen

    • Land/Stadt in Systemeinstellungen setzen (für Javascript astro)

    • Javascript+MQTT-Client Adapter installieren

    • MQTT-Client Instanz mit Username/PW/Host vom MQTT Broker konfigurieren

    • Bestimmte NPM Pakete für Javascript installieren

    • Javascripte aus Backup importieren (aus Dropbox)

    • 0.userdata Baum aus Backup importieren (aus Dropbox)

    • Bestimmte Datenpunkte in 0.userdata mit Infos befüllen, damit die Skripte zum Beispiel InfluxDB Credentials kennen

    Habe zu den meisten Punkten von ChatGPT gefragt, aber der stößt an seine Grenzen.

    Bedanke mich recht herzlich für Eure Hilfe!

    Marc BergM Offline
    Marc BergM Offline
    Marc Berg
    Most Active
    schrieb am zuletzt editiert von
    #2

    @vippis sagte in IOBroker Automatisiertes Deployment:

    Habe zu den meisten Punkten von ChatGPT gefragt, aber der stößt an seine Grenzen.

    Bedanke mich recht herzlich für Eure Hilfe!

    Einen Teil der Anforderungen habe ich mit einem userscript umgesetzt, welches beim ersten Start des Containers automatisch ausgeführt wird. Dazu wird z.B. ein Scriptverzeichnis in den Container gemappt

        volumes:
          - /opt/docker/iobroker2:/opt/iobroker
          - /opt/docker/userscripts/test:/opt/userscripts
    

    Das Script muss "userscript_firststart.sh" heißen. Mein Script sieht dann so aus (weil es ein testsytem ist, Sentry abgeschaltet). Das lässt sich sicher noch um einige deiner Punkte ergänzen

    #!/bin/bash
    
    # To run the Script on the first start of a new container you have to rename it to userscript_firststart.sh.
    echo " "
    echo "Checking if Discovery Adapter is installed..."
    
    # Check if the Discovery Adapter is installed
    if iob list adapters | grep -q "discovery"; then
        echo "Deleting Discovery Adapter ..."
        iob del discovery
    else
        echo "Discovery Adapter is not installed."
    fi
    
    echo " "
    
    # Define variables for system.config parameters
    LICENSE_CONFIRMED=true
    SITE_NAME="TEST  +++++++  TEST  +++++++  TEST  +++++++  TEST"
    DIAG="none"
    REPO="beta"
    LANGUAGE="en"
    CITY="Test"
    COUNTRY="Germany"
    LONGITUDE="10.0000"
    LATITUDE="52.0000"
    
    echo "Confirm license ..."
    current_license=$(iob object get system.config | jq -r '.common.licenseConfirmed')
    if [ "$current_license" != "$LICENSE_CONFIRMED" ]; then
        iob object set system.config common.licenseConfirmed=$LICENSE_CONFIRMED
    fi
    
    echo "Setting Site Name ..."
    current_siteName=$(iob object get system.config | jq -r '.common.siteName')
    if [ "$current_siteName" != "$SITE_NAME" ]; then
        iob object set system.config common.siteName="$SITE_NAME"
    fi
    
    echo "Setting Diag Data ..."
    current_diag=$(iob object get system.config | jq -r '.common.diag')
    if [ "$current_diag" != "$DIAG" ]; then
        iob object set system.config common.diag="$DIAG"
    fi
    
    echo "Setting Repo ..."
    current_repo=$(iob object get system.config | jq -r '.common.activeRepo')
    if [ "$current_repo" != "$REPO" ]; then
        iob object set system.config common.activeRepo="$REPO"
    fi
    
    echo "Setting Language ..."
    current_language=$(iob object get system.config | jq -r '.common.language')
    if [ "$current_language" != "$LANGUAGE" ]; then
        iob object set system.config common.language="$LANGUAGE"
    fi
    
    echo "Setting miscellaneous ..."
    current_city=$(iob object get system.config | jq -r '.common.city')
    if [ "$current_city" != "$CITY" ]; then
        iob object set system.config common.city="$CITY"
    fi
    
    current_country=$(iob object get system.config | jq -r '.common.country')
    if [ "$current_country" != "$COUNTRY" ]; then
        iob object set system.config common.country="$COUNTRY"
    fi
    
    current_longitude=$(iob object get system.config | jq -r '.common.longitude')
    if [ "$current_longitude" != "$LONGITUDE" ]; then
        iob object set system.config common.longitude="$LONGITUDE"
    fi
    
    current_latitude=$(iob object get system.config | jq -r '.common.latitude')
    if [ "$current_latitude" != "$LATITUDE" ]; then
        iob object set system.config common.latitude="$LATITUDE"
    fi
    
    echo " "
    echo "Disable Sentry ..."
    iob plugin disable sentry
    echo " "
    
    exit 0
    

    NUC10I3+Ubuntu+Docker+ioBroker+influxDB2+Node Red+RabbitMQ+Grafana

    Pi-hole, Traefik, Checkmk, Conbee II+Zigbee2MQTT, ESPSomfy-RTS, LoRaWAN, Arduino, KiCad

    Benutzt das Voting im Beitrag, wenn er euch geholfen hat.

    1 Antwort Letzte Antwort
    0
    • V Vippis

      Hallo Community,

      ich bin dabei ein Deployment Skript für IOBroker zu erstellen, um automatisiert Raspberry Pis aufzusetzen mit einem immer gleichen Basissystem.

      Docker compose läuft. Ich brauche Hilfe bei folgenden Deployment per IOB CLI:

      • IOB Admin Passwort automatisiert setzen

      • Welcome Screen überspringen

      • Land/Stadt in Systemeinstellungen setzen (für Javascript astro)

      • Javascript+MQTT-Client Adapter installieren

      • MQTT-Client Instanz mit Username/PW/Host vom MQTT Broker konfigurieren

      • Bestimmte NPM Pakete für Javascript installieren

      • Javascripte aus Backup importieren (aus Dropbox)

      • 0.userdata Baum aus Backup importieren (aus Dropbox)

      • Bestimmte Datenpunkte in 0.userdata mit Infos befüllen, damit die Skripte zum Beispiel InfluxDB Credentials kennen

      Habe zu den meisten Punkten von ChatGPT gefragt, aber der stößt an seine Grenzen.

      Bedanke mich recht herzlich für Eure Hilfe!

      OliverIOO Offline
      OliverIOO Offline
      OliverIO
      schrieb am zuletzt editiert von
      #3

      @vippis

      ein paar der punkte kannst du aus dem dev-server nehmen
      https://github.com/ioBroker/dev-server/blob/93790110fa07cf60da42bfd97cbf51c6dc75b6f9/src/index.ts#L1352

      da wird für die entwicklung eine iobroker instanz erstellt mit bestimmten voreinstellungen.
      vieles findest du im datenpunkt
      system.config

      Meine Adapter und Widgets
      TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
      Links im Profil

      V 1 Antwort Letzte Antwort
      0
      • OliverIOO OliverIO

        @vippis

        ein paar der punkte kannst du aus dem dev-server nehmen
        https://github.com/ioBroker/dev-server/blob/93790110fa07cf60da42bfd97cbf51c6dc75b6f9/src/index.ts#L1352

        da wird für die entwicklung eine iobroker instanz erstellt mit bestimmten voreinstellungen.
        vieles findest du im datenpunkt
        system.config

        V Offline
        V Offline
        Vippis
        schrieb am zuletzt editiert von
        #4

        Vielen Dank schonmal @OliverIO und @Marc-Berg

        Die härteste Nuss finde ich fast das Admin PW setzen.

        Im Fall von Docker kann man ja

        docker exec iobroker bash -lc "iobroker user passwd '${IOB_ADMIN_USER}' '${IOB_ADMIN_PASSWORD}'"

        ausführen, aber ich lande immer in einer User-Eingabe das Passwort zu setzen. Geht das nicht per Skript?

        Und die NPM Pakete für den JS Adapter. Habt ihr da auch ein Kommando?

        OliverIOO Marc BergM 2 Antworten Letzte Antwort
        0
        • V Vippis

          Vielen Dank schonmal @OliverIO und @Marc-Berg

          Die härteste Nuss finde ich fast das Admin PW setzen.

          Im Fall von Docker kann man ja

          docker exec iobroker bash -lc "iobroker user passwd '${IOB_ADMIN_USER}' '${IOB_ADMIN_PASSWORD}'"

          ausführen, aber ich lande immer in einer User-Eingabe das Passwort zu setzen. Geht das nicht per Skript?

          Und die NPM Pakete für den JS Adapter. Habt ihr da auch ein Kommando?

          OliverIOO Offline
          OliverIOO Offline
          OliverIO
          schrieb am zuletzt editiert von
          #5

          @vippis

          wenn du solche dinge machen willst, wirst du dich mit den tieferen ebenen des iobrokers beschäftigen müssen
          https://github.com/ioBroker/ioBroker.js-controller/blob/68fdbe2f4c4f0bef8b50f5e3b534363ebe77a15d/packages/common-db/src/lib/common/password.ts

          keine ahnung ob das angegebene beispiel auch genau so funktioniert und gültige passwörter für die aktuelle instanz ausspuckt, die man dann schreiben kann

          Meine Adapter und Widgets
          TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
          Links im Profil

          1 Antwort Letzte Antwort
          0
          • V Vippis

            Vielen Dank schonmal @OliverIO und @Marc-Berg

            Die härteste Nuss finde ich fast das Admin PW setzen.

            Im Fall von Docker kann man ja

            docker exec iobroker bash -lc "iobroker user passwd '${IOB_ADMIN_USER}' '${IOB_ADMIN_PASSWORD}'"

            ausführen, aber ich lande immer in einer User-Eingabe das Passwort zu setzen. Geht das nicht per Skript?

            Und die NPM Pakete für den JS Adapter. Habt ihr da auch ein Kommando?

            Marc BergM Offline
            Marc BergM Offline
            Marc Berg
            Most Active
            schrieb am zuletzt editiert von Marc Berg
            #6

            @vippis sagte in IOBroker Automatisiertes Deployment:

            docker exec iobroker bash -lc "iobroker user passwd '${IOB_ADMIN_USER}' '${IOB_ADMIN_PASSWORD}'"

            docker exec -it iobroker2 bash -c 'printf "dein_neues_passwort\ndein_neues_passwort\n" | iobroker user passwd admin'
            Enter your password:
            Repeat your password:
            Password for "admin" was successfully set.
            

            So kann man das Passwort automatisch setzen. (ohne Abfrage)

            NUC10I3+Ubuntu+Docker+ioBroker+influxDB2+Node Red+RabbitMQ+Grafana

            Pi-hole, Traefik, Checkmk, Conbee II+Zigbee2MQTT, ESPSomfy-RTS, LoRaWAN, Arduino, KiCad

            Benutzt das Voting im Beitrag, wenn er euch geholfen hat.

            V 1 Antwort Letzte Antwort
            0
            • Marc BergM Marc Berg

              @vippis sagte in IOBroker Automatisiertes Deployment:

              docker exec iobroker bash -lc "iobroker user passwd '${IOB_ADMIN_USER}' '${IOB_ADMIN_PASSWORD}'"

              docker exec -it iobroker2 bash -c 'printf "dein_neues_passwort\ndein_neues_passwort\n" | iobroker user passwd admin'
              Enter your password:
              Repeat your password:
              Password for "admin" was successfully set.
              

              So kann man das Passwort automatisch setzen. (ohne Abfrage)

              V Offline
              V Offline
              Vippis
              schrieb am zuletzt editiert von Vippis
              #7

              Für die Installation der NPM Module:

              #!/bin/bash
              log() { echo -e "[INFO] $1"; }
              
              IOBROKER_CID="iobroker"
              IOBROKER_NPM_PACKAGES=("moment" "axios" "influxdb-client" "@influxdata/influxdb-client" "@influxdata/influxdb-client-apis")
              
              # Array in Leerzeichen-getrennten String umwandeln
              libs_string=$(printf "%s " "${IOBROKER_NPM_PACKAGES[@]}")
              libs_string="${libs_string%" "}"   # letztes Leerzeichen entfernen
              
              log "➡️ Setze libraries für javascript.0 auf: ${libs_string}"
              
              docker exec -u 0 "${IOBROKER_CID}" bash -c \
                "iobroker object extend system.adapter.javascript.0 '{\"native\":{\"libraries\":\"${libs_string}\"}}'"
              
              # Danach sicherstellen, dass die Instanz die Pakete kennt
              docker exec -u 0 "${IOBROKER_CID}" bash -c "iobroker upload javascript"
              docker exec -u 0 "${IOBROKER_CID}" bash -c "iobroker restart javascript.0 || true"
              
              
              V 1 Antwort Letzte Antwort
              0
              • V Vippis

                Für die Installation der NPM Module:

                #!/bin/bash
                log() { echo -e "[INFO] $1"; }
                
                IOBROKER_CID="iobroker"
                IOBROKER_NPM_PACKAGES=("moment" "axios" "influxdb-client" "@influxdata/influxdb-client" "@influxdata/influxdb-client-apis")
                
                # Array in Leerzeichen-getrennten String umwandeln
                libs_string=$(printf "%s " "${IOBROKER_NPM_PACKAGES[@]}")
                libs_string="${libs_string%" "}"   # letztes Leerzeichen entfernen
                
                log "➡️ Setze libraries für javascript.0 auf: ${libs_string}"
                
                docker exec -u 0 "${IOBROKER_CID}" bash -c \
                  "iobroker object extend system.adapter.javascript.0 '{\"native\":{\"libraries\":\"${libs_string}\"}}'"
                
                # Danach sicherstellen, dass die Instanz die Pakete kennt
                docker exec -u 0 "${IOBROKER_CID}" bash -c "iobroker upload javascript"
                docker exec -u 0 "${IOBROKER_CID}" bash -c "iobroker restart javascript.0 || true"
                
                
                V Offline
                V Offline
                Vippis
                schrieb am zuletzt editiert von
                #8

                Wie kann ich die erstellten Javascripts, die ich über die GUI aus einem Quellsystem exportiert habe mit der nativen Funktion, per CLI wieder importieren, so dass sie unter "Scripts" in der Admin GUI erscheinen?

                Wie kann ich einen Usertree unter 0_userdata wieder per CLI importieren?

                OliverIOO 1 Antwort Letzte Antwort
                0
                • V Vippis

                  Wie kann ich die erstellten Javascripts, die ich über die GUI aus einem Quellsystem exportiert habe mit der nativen Funktion, per CLI wieder importieren, so dass sie unter "Scripts" in der Admin GUI erscheinen?

                  Wie kann ich einen Usertree unter 0_userdata wieder per CLI importieren?

                  OliverIOO Offline
                  OliverIOO Offline
                  OliverIO
                  schrieb am zuletzt editiert von OliverIO
                  #9

                  @vippis

                  Da würde ich vorhandenes nutzen
                  Backitup

                  Oder dort nachschauen wie es dort gemacht wird

                  Meine Adapter und Widgets
                  TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
                  Links im Profil

                  V 1 Antwort Letzte Antwort
                  0
                  • OliverIOO OliverIO

                    @vippis

                    Da würde ich vorhandenes nutzen
                    Backitup

                    Oder dort nachschauen wie es dort gemacht wird

                    V Offline
                    V Offline
                    Vippis
                    schrieb am zuletzt editiert von Vippis
                    #10

                    @oliverio

                    Ich wollte euch mal ein funktionierendes Skript posten, wie ihr voll automatisiert Skripte in IOBroker importieren könnt.

                    Das Skript geht davon aus, dass ihr eure Skripte vorher per Export aus der Skripte GUI exportiert habt (scripts.zip). Das Zip File hat also eine entsprechend vorgegebene Struktur.

                    Usage:
                    sudo ./script.sh <pfad/zur/zip>

                    #!/usr/bin/env bash
                    set -uo pipefail
                    
                    usage() {
                      cat <<'USAGE'
                    Usage:
                      import_iob_scripts_zip_docker.sh <scripts.zip> [--container iobroker] [--instance javascript.0] [--dry-run]
                    
                    Options:
                      --container   ioBroker container name (default: iobroker)
                      --instance    JavaScript adapter instance (default: javascript.0)
                      --dry-run     Print actions only (no changes)
                    USAGE
                    }
                    
                    [[ $# -ge 1 ]] || { usage; exit 1; }
                    ZIP="$1"; shift || true
                    CONTAINER="iobroker"
                    ENGINE_INSTANCE="javascript.0"
                    DRY_RUN=0
                    while [[ $# -gt 0 ]]; do
                      case "$1" in
                        --container) CONTAINER="${2:-iobroker}"; shift 2 ;;
                        --instance)  ENGINE_INSTANCE="${2:-javascript.0}"; shift 2 ;;
                        --dry-run)   DRY_RUN=1; shift ;;
                        -h|--help)   usage; exit 0 ;;
                        *) echo "Unknown option: $1" >&2; usage; exit 2 ;;
                      esac
                    done
                    
                    for bin in docker unzip jq iconv sed; do
                      command -v "$bin" >/dev/null 2>&1 || { echo "ERROR: missing $bin"; exit 3; }
                    done
                    [[ -f "$ZIP" ]] || { echo "ERROR: ZIP not found: $ZIP"; exit 4; }
                    docker ps --format '{{.Names}}' | grep -qx "$CONTAINER" || { echo "ERROR: container '$CONTAINER' not running"; exit 5; }
                    
                    # Ensure jq in container
                    if ! docker exec -i "$CONTAINER" sh -lc 'command -v jq >/dev/null'; then
                      echo "ERROR: jq fehlt im Container."
                      exit 6
                    fi
                    
                    iob(){ docker exec -i "$CONTAINER" iobroker "$@"; }
                    
                    TMPDIR="$(mktemp -d -t iob-scripts-zip-XXXXXX)"
                    trap 'rm -rf "$TMPDIR"' EXIT
                    
                    echo "==> Entpacke ZIP auf dem Host: $TMPDIR"
                    unzip -q "$ZIP" -d "$TMPDIR"
                    
                    CONTAINER_TMP="/tmp/iob-scripts-import"
                    docker exec -i "$CONTAINER" sh -lc "rm -rf '$CONTAINER_TMP' && mkdir -p '$CONTAINER_TMP'" >/dev/null
                    
                    echo "==> Stoppe Adapter: $ENGINE_INSTANCE"
                    [[ $DRY_RUN -eq 1 ]] || iob stop "$ENGINE_INSTANCE"
                    
                    # Sammle Ordner (_dir.json) und Skripte (*.json ohne _dir.json)
                    mapfile -d '' DIR_FILES    < <(find "$TMPDIR" -type f -name '_dir.json' -print0)
                    mapfile -d '' SCRIPT_FILES < <(find "$TMPDIR" -type f -name '*.json' -print0 | grep -z -v '_dir.json$')
                    
                    TOTAL=$(( ${#DIR_FILES[@]} + ${#SCRIPT_FILES[@]} ))
                    echo "==> Gefundene Objekte: $TOTAL (Ordner: ${#DIR_FILES[@]}, Skripte: ${#SCRIPT_FILES[@]})"
                    [[ $TOTAL -gt 0 ]] || { echo "Keine importierbaren Objekte gefunden."; exit 0; }
                    
                    # Fortschrittsanzeige
                    progress_file="$TMPDIR/progress.count"
                    : > "$progress_file"
                    
                    show_progress() {
                      local total=$1
                      local width=40
                      while true; do
                        local done
                        done=$(wc -l < "$progress_file")
                        [[ $done -gt $total ]] && done=$total
                        local filled=$(( done * width / total ))
                        local empty=$(( width - filled ))
                        printf "\r[%s%s] %d/%d" \
                          "$(printf '#%.0s' $(seq 1 $filled))" \
                          "$(printf ' %.0s' $(seq 1 $empty))" \
                          "$done" "$total"
                        [[ $done -ge $total ]] && break
                        sleep 0.2
                      done
                      echo
                    }
                    show_progress "$TOTAL" &
                    PROGRESS_PID=$!
                    
                    # Import Ordner aus _dir.json (type, common inkl. lokalisierter Namen, native)
                    import_dir() {
                      local dirjson="$1"
                      local obj_id folder_obj
                    
                      obj_id="$(jq -r '._id' "$dirjson")"
                      [[ -n "$obj_id" && "$obj_id" != "null" ]] || return
                    
                      # Übernehme type/common/native vollständig; system Felder (from, ts, acl) lässt ioBroker selbst setzen
                      folder_obj="$(jq -c '{type,common,native}' "$dirjson")"
                    
                      if [[ $DRY_RUN -eq 1 ]]; then
                        echo "[dry-run] Ordner: $obj_id"
                      else
                        docker exec -i "$CONTAINER" iobroker object set "$obj_id" "$folder_obj"
                      fi
                      echo 1 >> "$progress_file"
                    }
                    
                    # Import Skriptobjekt + Source
                    import_script() {
                      local scriptjson="$1"
                      local base rel orig_root root_mapped path obj_id script_key
                      base="$(basename "$scriptjson")"
                      rel="${scriptjson#"$TMPDIR/"}"
                      orig_root="${rel%%/*}"
                    
                      # Mappe lokalisierte Root-Namen
                      case "$orig_root" in
                        "Allgemeine Skripte (common)") root_mapped="common" ;;
                        "Globale Skripte (global)")    root_mapped="global" ;;
                        *)                              root_mapped="$orig_root" ;;
                      esac
                    
                      path="${rel#"$orig_root/"}"
                      path="${path%.json}"
                      path="${path//\//.}"
                      obj_id="script.js.$root_mapped.$path"
                      script_key="$(echo "$obj_id" | tr '/ ' '__')"
                    
                      local common_json_host source_txt_host
                      common_json_host="$TMPDIR/common_${script_key}.json"
                      source_txt_host="$TMPDIR/source_${script_key}.txt"
                    
                      if jq -er 'type=="object" and has("common") and .common|has("source")' "$scriptjson" >/dev/null 2>&1; then
                        local name engineType expert debug verbose enabled
                        name="$(jq -r '.common.name // empty' "$scriptjson")"
                        [[ -n "$name" && "$name" != "null" ]] || name="${base%.json}"
                        engineType="$(jq -r '.common.engineType // "Javascript/Node.js"' "$scriptjson")"
                        expert="$(jq -r '.common.expert // false' "$scriptjson")"
                        debug="$(jq -r  '.common.debug  // false' "$scriptjson")"
                        verbose="$(jq -r '.common.verbose // false' "$scriptjson")"
                        enabled="$(jq -r '.common.enabled // false' "$scriptjson")"
                    
                        jq -c -n --arg name "$name" \
                                 --arg engine "system.adapter.$ENGINE_INSTANCE" \
                                 --arg engineType "$engineType" \
                                 --argjson expert "$expert" \
                                 --argjson debug "$debug" \
                                 --argjson verbose "$verbose" \
                                 --argjson enabled "$enabled" '
                          { name:$name, engine:$engine, engineType:$engineType,
                            expert:$expert, debug:$debug, verbose:$verbose, enabled:$enabled }' > "$common_json_host"
                    
                        jq -r '.common.source' "$scriptjson" > "$source_txt_host"
                      else
                        # Reines Source-JSON: Header entfernen, Defaults setzen
                        sed -e '/\/\* -- do not edit following lines - START --/,/-- do not edit previous lines - END --\*\//d' "$scriptjson" > "$source_txt_host"
                        jq -c -n --arg name "${base%.json}" \
                                 --arg engine "system.adapter.$ENGINE_INSTANCE" \
                                 --arg engineType "Javascript/Node.js" '
                          { name:$name, engine:$engine, engineType:$engineType,
                            expert:false, debug:false, verbose:false, enabled:false }' > "$common_json_host"
                      fi
                    
                      # Encoding säubern
                      iconv -f UTF-8 -t UTF-8 -c "$source_txt_host" | tr -d '\000' > "$source_txt_host.clean"
                      mv "$source_txt_host.clean" "$source_txt_host"
                    
                      if [[ $DRY_RUN -eq 1 ]]; then
                        echo "[dry-run] Script: $obj_id"
                      else
                        # Objekt anlegen (idempotent)
                        docker exec -i "$CONTAINER" iobroker object set "$obj_id" '{"type":"script","common":{"name":""},"native":{}}' >/dev/null
                    
                        # common setzen
                        docker cp "$common_json_host" "$CONTAINER:$CONTAINER_TMP/common_${script_key}.json" >/dev/null
                        docker exec -i "$CONTAINER" sh -lc "C=\$(cat $CONTAINER_TMP/common_${script_key}.json); iobroker object set '$obj_id' \"common=\$C\"" >/dev/null
                    
                        # source setzen (als JSON-String)
                        docker cp "$source_txt_host" "$CONTAINER:$CONTAINER_TMP/source_${script_key}.txt" >/dev/null
                        docker exec -i "$CONTAINER" sh -lc "SRC_JSON=\$(jq -Rn --rawfile s '$CONTAINER_TMP/source_${script_key}.txt' '\$s'); iobroker object set '$obj_id' \"common.source=\$SRC_JSON\"" >/dev/null
                      fi
                    
                      echo 1 >> "$progress_file"
                    }
                    
                    export -f import_dir import_script show_progress
                    export TMPDIR CONTAINER CONTAINER_TMP ENGINE_INSTANCE progress_file
                    
                    echo "==> Importiere Ordner (_dir.json) ..."
                    printf "%s\n" "${DIR_FILES[@]}" \
                      | xargs -P4 -n1 -I{} bash -c 'import_dir "{}"'
                    
                    echo "==> Importiere Skripte (*.json) ..."
                    printf "%s\n" "${SCRIPT_FILES[@]}" \
                      | xargs -P4 -n1 -I{} bash -c 'import_script "{}"'
                    
                    # Fortschrittsanzeige beenden
                    wait "$PROGRESS_PID"
                    
                    echo -e "\n==> Import abgeschlossen: $TOTAL Objekte."
                    
                    echo "==> Starte Adapter: $ENGINE_INSTANCE"
                    [[ $DRY_RUN -eq 1 ]] || iob start "$ENGINE_INSTANCE"
                    
                    echo "==> Fertig."
                    
                    V 1 Antwort Letzte Antwort
                    0
                    • V Vippis

                      @oliverio

                      Ich wollte euch mal ein funktionierendes Skript posten, wie ihr voll automatisiert Skripte in IOBroker importieren könnt.

                      Das Skript geht davon aus, dass ihr eure Skripte vorher per Export aus der Skripte GUI exportiert habt (scripts.zip). Das Zip File hat also eine entsprechend vorgegebene Struktur.

                      Usage:
                      sudo ./script.sh <pfad/zur/zip>

                      #!/usr/bin/env bash
                      set -uo pipefail
                      
                      usage() {
                        cat <<'USAGE'
                      Usage:
                        import_iob_scripts_zip_docker.sh <scripts.zip> [--container iobroker] [--instance javascript.0] [--dry-run]
                      
                      Options:
                        --container   ioBroker container name (default: iobroker)
                        --instance    JavaScript adapter instance (default: javascript.0)
                        --dry-run     Print actions only (no changes)
                      USAGE
                      }
                      
                      [[ $# -ge 1 ]] || { usage; exit 1; }
                      ZIP="$1"; shift || true
                      CONTAINER="iobroker"
                      ENGINE_INSTANCE="javascript.0"
                      DRY_RUN=0
                      while [[ $# -gt 0 ]]; do
                        case "$1" in
                          --container) CONTAINER="${2:-iobroker}"; shift 2 ;;
                          --instance)  ENGINE_INSTANCE="${2:-javascript.0}"; shift 2 ;;
                          --dry-run)   DRY_RUN=1; shift ;;
                          -h|--help)   usage; exit 0 ;;
                          *) echo "Unknown option: $1" >&2; usage; exit 2 ;;
                        esac
                      done
                      
                      for bin in docker unzip jq iconv sed; do
                        command -v "$bin" >/dev/null 2>&1 || { echo "ERROR: missing $bin"; exit 3; }
                      done
                      [[ -f "$ZIP" ]] || { echo "ERROR: ZIP not found: $ZIP"; exit 4; }
                      docker ps --format '{{.Names}}' | grep -qx "$CONTAINER" || { echo "ERROR: container '$CONTAINER' not running"; exit 5; }
                      
                      # Ensure jq in container
                      if ! docker exec -i "$CONTAINER" sh -lc 'command -v jq >/dev/null'; then
                        echo "ERROR: jq fehlt im Container."
                        exit 6
                      fi
                      
                      iob(){ docker exec -i "$CONTAINER" iobroker "$@"; }
                      
                      TMPDIR="$(mktemp -d -t iob-scripts-zip-XXXXXX)"
                      trap 'rm -rf "$TMPDIR"' EXIT
                      
                      echo "==> Entpacke ZIP auf dem Host: $TMPDIR"
                      unzip -q "$ZIP" -d "$TMPDIR"
                      
                      CONTAINER_TMP="/tmp/iob-scripts-import"
                      docker exec -i "$CONTAINER" sh -lc "rm -rf '$CONTAINER_TMP' && mkdir -p '$CONTAINER_TMP'" >/dev/null
                      
                      echo "==> Stoppe Adapter: $ENGINE_INSTANCE"
                      [[ $DRY_RUN -eq 1 ]] || iob stop "$ENGINE_INSTANCE"
                      
                      # Sammle Ordner (_dir.json) und Skripte (*.json ohne _dir.json)
                      mapfile -d '' DIR_FILES    < <(find "$TMPDIR" -type f -name '_dir.json' -print0)
                      mapfile -d '' SCRIPT_FILES < <(find "$TMPDIR" -type f -name '*.json' -print0 | grep -z -v '_dir.json$')
                      
                      TOTAL=$(( ${#DIR_FILES[@]} + ${#SCRIPT_FILES[@]} ))
                      echo "==> Gefundene Objekte: $TOTAL (Ordner: ${#DIR_FILES[@]}, Skripte: ${#SCRIPT_FILES[@]})"
                      [[ $TOTAL -gt 0 ]] || { echo "Keine importierbaren Objekte gefunden."; exit 0; }
                      
                      # Fortschrittsanzeige
                      progress_file="$TMPDIR/progress.count"
                      : > "$progress_file"
                      
                      show_progress() {
                        local total=$1
                        local width=40
                        while true; do
                          local done
                          done=$(wc -l < "$progress_file")
                          [[ $done -gt $total ]] && done=$total
                          local filled=$(( done * width / total ))
                          local empty=$(( width - filled ))
                          printf "\r[%s%s] %d/%d" \
                            "$(printf '#%.0s' $(seq 1 $filled))" \
                            "$(printf ' %.0s' $(seq 1 $empty))" \
                            "$done" "$total"
                          [[ $done -ge $total ]] && break
                          sleep 0.2
                        done
                        echo
                      }
                      show_progress "$TOTAL" &
                      PROGRESS_PID=$!
                      
                      # Import Ordner aus _dir.json (type, common inkl. lokalisierter Namen, native)
                      import_dir() {
                        local dirjson="$1"
                        local obj_id folder_obj
                      
                        obj_id="$(jq -r '._id' "$dirjson")"
                        [[ -n "$obj_id" && "$obj_id" != "null" ]] || return
                      
                        # Übernehme type/common/native vollständig; system Felder (from, ts, acl) lässt ioBroker selbst setzen
                        folder_obj="$(jq -c '{type,common,native}' "$dirjson")"
                      
                        if [[ $DRY_RUN -eq 1 ]]; then
                          echo "[dry-run] Ordner: $obj_id"
                        else
                          docker exec -i "$CONTAINER" iobroker object set "$obj_id" "$folder_obj"
                        fi
                        echo 1 >> "$progress_file"
                      }
                      
                      # Import Skriptobjekt + Source
                      import_script() {
                        local scriptjson="$1"
                        local base rel orig_root root_mapped path obj_id script_key
                        base="$(basename "$scriptjson")"
                        rel="${scriptjson#"$TMPDIR/"}"
                        orig_root="${rel%%/*}"
                      
                        # Mappe lokalisierte Root-Namen
                        case "$orig_root" in
                          "Allgemeine Skripte (common)") root_mapped="common" ;;
                          "Globale Skripte (global)")    root_mapped="global" ;;
                          *)                              root_mapped="$orig_root" ;;
                        esac
                      
                        path="${rel#"$orig_root/"}"
                        path="${path%.json}"
                        path="${path//\//.}"
                        obj_id="script.js.$root_mapped.$path"
                        script_key="$(echo "$obj_id" | tr '/ ' '__')"
                      
                        local common_json_host source_txt_host
                        common_json_host="$TMPDIR/common_${script_key}.json"
                        source_txt_host="$TMPDIR/source_${script_key}.txt"
                      
                        if jq -er 'type=="object" and has("common") and .common|has("source")' "$scriptjson" >/dev/null 2>&1; then
                          local name engineType expert debug verbose enabled
                          name="$(jq -r '.common.name // empty' "$scriptjson")"
                          [[ -n "$name" && "$name" != "null" ]] || name="${base%.json}"
                          engineType="$(jq -r '.common.engineType // "Javascript/Node.js"' "$scriptjson")"
                          expert="$(jq -r '.common.expert // false' "$scriptjson")"
                          debug="$(jq -r  '.common.debug  // false' "$scriptjson")"
                          verbose="$(jq -r '.common.verbose // false' "$scriptjson")"
                          enabled="$(jq -r '.common.enabled // false' "$scriptjson")"
                      
                          jq -c -n --arg name "$name" \
                                   --arg engine "system.adapter.$ENGINE_INSTANCE" \
                                   --arg engineType "$engineType" \
                                   --argjson expert "$expert" \
                                   --argjson debug "$debug" \
                                   --argjson verbose "$verbose" \
                                   --argjson enabled "$enabled" '
                            { name:$name, engine:$engine, engineType:$engineType,
                              expert:$expert, debug:$debug, verbose:$verbose, enabled:$enabled }' > "$common_json_host"
                      
                          jq -r '.common.source' "$scriptjson" > "$source_txt_host"
                        else
                          # Reines Source-JSON: Header entfernen, Defaults setzen
                          sed -e '/\/\* -- do not edit following lines - START --/,/-- do not edit previous lines - END --\*\//d' "$scriptjson" > "$source_txt_host"
                          jq -c -n --arg name "${base%.json}" \
                                   --arg engine "system.adapter.$ENGINE_INSTANCE" \
                                   --arg engineType "Javascript/Node.js" '
                            { name:$name, engine:$engine, engineType:$engineType,
                              expert:false, debug:false, verbose:false, enabled:false }' > "$common_json_host"
                        fi
                      
                        # Encoding säubern
                        iconv -f UTF-8 -t UTF-8 -c "$source_txt_host" | tr -d '\000' > "$source_txt_host.clean"
                        mv "$source_txt_host.clean" "$source_txt_host"
                      
                        if [[ $DRY_RUN -eq 1 ]]; then
                          echo "[dry-run] Script: $obj_id"
                        else
                          # Objekt anlegen (idempotent)
                          docker exec -i "$CONTAINER" iobroker object set "$obj_id" '{"type":"script","common":{"name":""},"native":{}}' >/dev/null
                      
                          # common setzen
                          docker cp "$common_json_host" "$CONTAINER:$CONTAINER_TMP/common_${script_key}.json" >/dev/null
                          docker exec -i "$CONTAINER" sh -lc "C=\$(cat $CONTAINER_TMP/common_${script_key}.json); iobroker object set '$obj_id' \"common=\$C\"" >/dev/null
                      
                          # source setzen (als JSON-String)
                          docker cp "$source_txt_host" "$CONTAINER:$CONTAINER_TMP/source_${script_key}.txt" >/dev/null
                          docker exec -i "$CONTAINER" sh -lc "SRC_JSON=\$(jq -Rn --rawfile s '$CONTAINER_TMP/source_${script_key}.txt' '\$s'); iobroker object set '$obj_id' \"common.source=\$SRC_JSON\"" >/dev/null
                        fi
                      
                        echo 1 >> "$progress_file"
                      }
                      
                      export -f import_dir import_script show_progress
                      export TMPDIR CONTAINER CONTAINER_TMP ENGINE_INSTANCE progress_file
                      
                      echo "==> Importiere Ordner (_dir.json) ..."
                      printf "%s\n" "${DIR_FILES[@]}" \
                        | xargs -P4 -n1 -I{} bash -c 'import_dir "{}"'
                      
                      echo "==> Importiere Skripte (*.json) ..."
                      printf "%s\n" "${SCRIPT_FILES[@]}" \
                        | xargs -P4 -n1 -I{} bash -c 'import_script "{}"'
                      
                      # Fortschrittsanzeige beenden
                      wait "$PROGRESS_PID"
                      
                      echo -e "\n==> Import abgeschlossen: $TOTAL Objekte."
                      
                      echo "==> Starte Adapter: $ENGINE_INSTANCE"
                      [[ $DRY_RUN -eq 1 ]] || iob start "$ENGINE_INSTANCE"
                      
                      echo "==> Fertig."
                      
                      V Offline
                      V Offline
                      Vippis
                      schrieb am zuletzt editiert von Vippis
                      #11

                      @Marc-Berg @OliverIO

                      Könnt ihr mir sagen wie ich vom mqtt-client username/passwort und host setzen kann?

                      Alles bis auf Passwort kann ich so setzen:

                      docker exec -u 0 "${MQTT_CID}" iobroker object extend "system.adapter.${MQTT_ADAPTER}" "$(cat <<EOF
                      {
                        "native": {
                          "type": "client",
                          "host": "mosquitto",
                          "port": 1883,
                          "clientId": "${MQTT_CLIENT_ID}",
                          "username": "${MQTT_USER}",
                          "password": "${MQTT_HASH}",
                          "prefix": "",
                          "publishAll": false,
                          "keepalive": 60,
                          "clean": true,
                          "qos": 0,
                          "retain": false,
                          "subscribe": "#",
                          "ssl": false
                        }
                      }
                      EOF
                      )"
                      
                      

                      Das Problem ist das Passwort, weil der Adapter einen Hash will, den nur die GUI erzeugt

                      OliverIOO 1 Antwort Letzte Antwort
                      0
                      • V Vippis

                        @Marc-Berg @OliverIO

                        Könnt ihr mir sagen wie ich vom mqtt-client username/passwort und host setzen kann?

                        Alles bis auf Passwort kann ich so setzen:

                        docker exec -u 0 "${MQTT_CID}" iobroker object extend "system.adapter.${MQTT_ADAPTER}" "$(cat <<EOF
                        {
                          "native": {
                            "type": "client",
                            "host": "mosquitto",
                            "port": 1883,
                            "clientId": "${MQTT_CLIENT_ID}",
                            "username": "${MQTT_USER}",
                            "password": "${MQTT_HASH}",
                            "prefix": "",
                            "publishAll": false,
                            "keepalive": 60,
                            "clean": true,
                            "qos": 0,
                            "retain": false,
                            "subscribe": "#",
                            "ssl": false
                          }
                        }
                        EOF
                        )"
                        
                        

                        Das Problem ist das Passwort, weil der Adapter einen Hash will, den nur die GUI erzeugt

                        OliverIOO Offline
                        OliverIOO Offline
                        OliverIO
                        schrieb am zuletzt editiert von
                        #12

                        @vippis

                        Dann musst du in den Adapter schauen was die gui des Adapters mit dem Passwort macht, was der Nutzer einträgt.

                        Meine Adapter und Widgets
                        TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
                        Links im Profil

                        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

                        883

                        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