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

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

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

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

IOBroker Automatisiertes Deployment

Geplant Angeheftet Gesperrt Verschoben Skripten / Logik
12 Beiträge 3 Kommentatoren 361 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!

    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

                      262

                      Online

                      32.4k

                      Benutzer

                      81.4k

                      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