Ankündigung

Einklappen
Keine Ankündigung bisher.

Multistart von linKNX

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    [linKNX] Multistart von linKNX

    linKNX ist eine bewährte Logik-Engine, hat aber den Nachteil, dass die Konfigurationsdatei (linknx.xml) mit der Zeit sehr groß und unübersichtlich wird.

    Wie hier schon im Forum diskutiert, gibt es bei linKNX kein Problem, wenn es mehrfach gestartet wird. Es muss nur für jede Instanz eine Konfigurationsdatei erzeugt und beim Aufruf angegeben werden. Der Nachteil ist, dass z.B. zentrale Objekte mehrfach (in jeder Konfigurationsdatei) gepflegt werden müssen.

    Das folgende kleine Skript nimmt sich dieser Problematik an und startet automatisch für jede in einem Verzeichnis vorhandene Konfigurationsdatei eine linKNX Instanz.
    Zusätzlich werden zentrale Konfigurationsdateien (Beginnen immer mit einem Unterstrich (_) und enden mit .xml) in die "Hauptkonfigurationen" eingebunden.

    Das Einbinden der zentralen Konfigurationen geschieht genau dort, wo in der Hauptkonfiguration folgende Zeile steht (_xyz.xml ist durch den Dateinamen der Konfigurationsdatei zu ersetzen):
    Code:
    <!-- replace _xyz.xml -->
    Die Pfad-Angaben im folgenden Skript verwende ich so auf meinem Wiregate und müssen entsprechend angepasst werden.

    Dies ist die erste (veraltete) Version des Skripts:
    Code:
    #!/bin/bash
    # Some configuration variables
    # 
    # (Temp-)Path to the combined linknx configuration files
    OUTPUT_PATH=/etc/linknx/tmp
    
    # Path to the configuration file which should be combined (see important info)
    CONFIG_PATH=/etc/linknx
    
    # Path to linKNX
    LINKNX=/usr/bin/linknx
    PID_PATH=/var/run
    
    # Important info:
    #   Confguration files that should be insert in an other file (called central configs),
    #   must beginn with an underline (_) and end with .xml
    #   The Place in the main configuration-file should be marked in 
    #   an new line and with the following text: <!-- replace _xxx.xml -->
    #   _xxx.xml is the name of the file which should be insert
    
    # Configuration end
    
    # Combine the configuration files
    # find all configuartion files (not the central files with _-prefix)
    for FILE in `find $CONFIG_PATH -type f \( -iname "*.xml" ! -iname "_*" \) -printf "%f\n"`
      do
      # copy xml-file to start with a clean configuration
      cp -f $CONFIG_PATH/$FILE $OUTPUT_PATH
      # find line with <!-- replace _xxx.xml -->
      while read line; do
        [[ $line =~ \<!--.replace.(_.*\.xml).--\> ]] || continue
          # get content to insert
          INSERT_CONTENT=`cat "$CONFIG_PATH/$(echo "$line" | sed -e 's|.*\(_.*\.xml\) .*|\1|')"`
          # get the content before and after the found line with config _xxx.xml
          FIRST_LINES=`cat "$OUTPUT_PATH/$FILE" | sed -e '/'"$line"'/,$d'`
          LAST_LINES=`cat "$OUTPUT_PATH/$FILE" | sed -e '1,/'"$line"'/d'`
          # Make a new file with the three parts
          echo "$FIRST_LINES" > "$OUTPUT_PATH/$FILE"
          echo "$INSERT_CONTENT" >> "$OUTPUT_PATH/$FILE"
          echo "$LAST_LINES" >> "$OUTPUT_PATH/$FILE"
       done < $FILE
    done
    
    # Start a linKNX-instance for every configuration file
    for FILE in `find $OUTPUT_PATH -type f \( -iname "*.xml" ! -iname "_*" \)`
      do
        INSTANCE_NAME=`echo "$FILE" | sed -e 's|.*\/\(.*\)\.xml|\1|'`
        # kill a runnung linknx instance
        if [ -f "$PID_PATH/linknx-$INSTANCE_NAME.pid" ]; then kill `cat "$PID_PATH/linknx-$INSTANCE_NAME.pid"`; fi 
        # Start linKNX-Instance
        echo "Starting $LINKNX -c$FILE -p$PID_PATH/linknx-$INSTANCE_NAME.pid -d -w"
        `$LINKNX -c$FILE -p$PID_PATH/linknx-$INSTANCE_NAME.pid -d -w`
    done
    Im Anhang ist ein Beispiel für drei linKNX-Instanzen (lights, multiroom, misc) und zwei zentralen Konfigurationen (_objects.xml und _services.xml), die in die drei eingebunden werden, angehängt. Bei mir habe ich die Dateien unter /etc/linknx gespeichert.

    Das obige Skript muss ausführbar gespeichert und z.B. von einem Startskript aufgerufen werden. Getestet und im Einsatz habe ich es nur auf meinem Wiregate.
    Angehängte Dateien

    #2
    Meine Multistartkonfiguration läuft nun schon mehrer Monate ohne Probleme und daher habe ich vor einiger Zeit das Multistart-Skript überarbeitet.

    Es startet jetzt ohne Parameter nur die linknx-Instanzen neu, bei denen sich die Konfiguartion geändert hat.
    Bei einem Aufruf des Skripts mit dem Parameter -a werden alle Instanzen neu gestartet.
    Wird das Skript mit dem Parameter -c config aufgerufen, wird nur die Instanz mit der angegebenen Konfiguration neu gestartet.

    Ansonsten gilt das geschriebene aus dem ersten Post und hier ist das überarbeitete Skript:

    Code:
    #!/bin/bash
    # Some configuration variables
    #
    # (Temp-)Path to the combined linknx configuration files
    OUTPUT_PATH=/etc/linknx/tmp
    
    # Path to the configuration file which should be combined (see important info)
    CONFIG_PATH=/etc/linknx
    
    # Path to linKNX
    LINKNX=/usr/bin/linknx
    PID_PATH=/var/run
    
    # Important info:
    #   Confguration files that should be insert in an other file (called central configs),
    #   must beginn with an underline (_) and end with .xml
    #   The Place in the main configuration-file should be marked in
    #   an new line and with the following text: <!-- replace _xxx.xml -->
    #   _xxx.xml is the name of the file which should be insert
    
    # Clean all configuration files
    function clean_all ()
    {
        echo "  Killing and cleaning all linknx processes..."
        killall -9 linknx
        rm -f $PID_PATH/linknx*.pid
        rm -f $OUTPUT_PATH/*.xml
    }
    
    # Clean tmp and stop linknx if no configuration file
    clean()
    {
        # Kill Instance an remove pid to force restart
        INSTANCE_NAME=`echo "$1" | sed -e 's|\(.*\)\.xml|\1|'`
        FILE="$INSTANCE_NAME.xml";
        echo "Killing instance for configfile $FILE and remove pid"
        if [ ! -e "$CONFIG_PATH/$FILE" ]; then
            echo "  No configuration for $FILE"
            rm -f $OUTPUT_PATH/$FILE
        fi
        if [ -e "$PID_PATH/linknx-$INSTANCE_NAME.pid" ]; then
            kill -9 `cat "$PID_PATH/linknx-$INSTANCE_NAME.pid"`
        fi
        # Remove pid-file
        if [ -e "$PID_PATH/linknx-$INSTANCE_NAME.pid" ]; then
            rm -f $PID_PATH/linknx-$INSTANCE_NAME.pid
        fi
    }
    
    combine ()
    {
        # Combine the configuration files
        # find all configuartion files (not the central files with _-prefix)
        # copy xml-file to start with a clean configuration
        FILE=`echo "$1" | sed -e 's|\(.*\)\.xml|\1|'`.xml
        if [ -e "$CONFIG_PATH/$FILE" ]; then
            echo "  Combining configuration file $FILE"
            cp -f "$CONFIG_PATH/$FILE" "$OUTPUT_PATH"
            # find line with <!-- replace _xxx.xml -->
            while read line; do
                [[ $line =~ \<!--.replace.(_.*\.xml).--\> ]] || continue
                # get content to insert
                INSERT_CONTENT=`cat "$CONFIG_PATH/$(echo "$line" | sed -e 's|.*\(_.*\.xml\) .*|\1|')"`
                # get the content before and after the found line with config _xxx.xml
                FIRST_LINES=`cat "$OUTPUT_PATH/$FILE" | sed -e '/'"$line"'/,$d'`
                LAST_LINES=`cat "$OUTPUT_PATH/$FILE" | sed -e '1,/'"$line"'/d'`        # Make a new file using the three parts
                echo "$FIRST_LINES" > "$OUTPUT_PATH/$FILE"
                echo "$INSERT_CONTENT" >> "$OUTPUT_PATH/$FILE"
                echo "$LAST_LINES" >> "$OUTPUT_PATH/$FILE"
            done < $FILE
        fi
    }
    
    start ()
    {
        INSTANCE_NAME=`echo "$1" | sed -e 's|\(.*\)\.xml|\1|'`
        # kill a runnung linKNX instance
        if [ -e "$PID_PATH/linknx-$INSTANCE_NAME.pid" ]; then
            kill -9 `cat "$PID_PATH/linknx-$INSTANCE_NAME.pid"`
        fi
        # and remove the pid-file
        if [ -e "$PID_PATH/linknx-$INSTANCE_NAME.pid" ]; then
            rm -f $PID_PATH/linknx-$INSTANCE_NAME.pid
        fi
        # Start linKNX-Instance
        echo "  Starting $LINKNX -c$OUTPUT_PATH/$INSTANCE_NAME.xml -p$PID_PATH/linknx-$INSTANCE_NAME.pid -d -w"
        `$LINKNX -c$OUTPUT_PATH/$INSTANCE_NAME.xml -p$PID_PATH/linknx-$INSTANCE_NAME.pid -d -w`
        }
    
    case $1 in
      -a) # Restart every linknx instance
         echo "Starting all linKNX instances..."
         clean_all
         for FILE in `find $CONFIG_PATH  -maxdepth 1 -type f \( -name "*.xml" ! -iname "_*" \) -printf "%f\n"`
         do
            combine $FILE;
            start $FILE;
         done
         ;;
    
      -c) # Restarting only the specified instance
         echo "Starting linKNX process $2..."
         clean $2;
         combine $2;
         start $2;
         ;;
    
      *) # Restarting only changed instances
         echo "You could use the following parameter:"
         echo "  -c name     - (re)start only the specified instance"
         echo "  -a          - (re)start every linKNX instance"
         echo " "
         echo "No parameter, (re))starting only changed configuration files..."
         for FILE in `find $CONFIG_PATH  -maxdepth 1 -type f \( -name "*.xml" ! -iname "_*" \) -printf "%f\n"`
         do
            INSTANCE_NAME=`echo "$FILE" | sed -e 's|\(.*\)\.xml|\1|'`
            if [ "$CONFIG_PATH/$INSTANCE_NAME.xml" -nt "$PID_PATH/linknx-$INSTANCE_NAME.pid" ]; then
                combine $FILE;
                # Start a linKNX-instance for every configuration file if newer than pid file
                start $FILE;
            else
                echo "  No change: $FILE"
            fi
         done
         ;;
    esac
    Angehängte Dateien

    Kommentar

    Lädt...
    X