Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. IOBroker Automatisiertes Deployment

    NEWS

    • Amazon Alexa - ioBroker Skill läuft aus ?

    • Monatsrückblick – September 2025

    • Neues Video "KI im Smart Home" - ioBroker plus n8n

    IOBroker Automatisiertes Deployment

    This topic has been deleted. Only users with topic management privileges can see it.
    • OliverIO
      OliverIO @Vippis last edited by

      @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 1 Reply Last reply Reply Quote 0
      • V
        Vippis @OliverIO last edited by

        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?

        OliverIO Marc Berg 2 Replies Last reply Reply Quote 0
        • OliverIO
          OliverIO @Vippis last edited by

          @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

          1 Reply Last reply Reply Quote 0
          • Marc Berg
            Marc Berg Most Active @Vippis last edited by 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 1 Reply Last reply Reply Quote 0
            • V
              Vippis @Marc Berg last edited by 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 1 Reply Last reply Reply Quote 0
              • V
                Vippis @Vippis last edited by

                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?

                OliverIO 1 Reply Last reply Reply Quote 0
                • OliverIO
                  OliverIO @Vippis last edited by OliverIO

                  @vippis

                  Da würde ich vorhandenes nutzen
                  Backitup

                  Oder dort nachschauen wie es dort gemacht wird

                  V 1 Reply Last reply Reply Quote 0
                  • V
                    Vippis @OliverIO last edited by 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 1 Reply Last reply Reply Quote 0
                    • V
                      Vippis @Vippis last edited by 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

                      OliverIO 1 Reply Last reply Reply Quote 0
                      • OliverIO
                        OliverIO @Vippis last edited by

                        @vippis

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

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post

                        Support us

                        ioBroker
                        Community Adapters
                        Donate

                        1.1k
                        Online

                        32.2k
                        Users

                        80.9k
                        Topics

                        1.3m
                        Posts

                        3
                        12
                        189
                        Loading More Posts
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes
                        Reply
                        • Reply as topic
                        Log in to reply
                        Community
                        Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                        The ioBroker Community 2014-2023
                        logo