fronthem, Reihenfolge in den cfg-Dateien

Begonnen von GammaTwin, 18 Februar 2021, 22:52:37

Vorheriges Thema - Nächstes Thema

GammaTwin

Grüße,

in den cfg-Dateien "fhserver.fronthem.cfg" und den Client-cfg werden bei jedem Speichern alle Einträge neu sortiert. Selbst innerhalb eines Eintrags ist Reihenfolge der Attribute unterschiedlich.

Beispiel für die unterschiedliche Attributanordnung
      "Jal_Sued.sperre" : {
         "reading" : "g1",
         "set" : "g1",
         "converter" : "OnOff",
         "device" : "KNX_0602023",
         "type" : "item"
      },
      "Jal_Nord.sperre" : {
         "set" : "g1",
         "reading" : "g1",
         "type" : "item",
         "device" : "KNX_0602043",
         "converter" : "OnOff"
      },


Ich würde gern den Fortschritt meiner Konfiguration mit git dokumentieren und dann wird dies alles immer als Änderung erkannt.

Kann man das irgendwie verändern?

herrmannj


GammaTwin

Ich begeistert von der Klarheit der Antwort  ;)

Dann muss ich was anderes überlegen.

herrmannj

Kannst auch gerne eine lange Antwort haben die sich inhaltlich aber nicht relevant unterscheidet. ;)

Etwas länger, Json ist ungeordnet. Ergo, nein

GammaTwin

Nehmen wir an, ich würde die Datei von Hand umsortieren und wieder einspielen - würden die Einstellungen übernommen werden?

herrmannj


GammaTwin

  :)
Ich habe überlegt, wie noch kürzer antworten kann  :D  :D

GammaTwin

#7
Ich habe mich mal ein Script gewagt. Eingebettet in ein DOIF. Werde ich noch präsentieren.

Ich hänge aber an einer simplen Stelle. Folgende Zeile führt zum Fehler.
if ($Row =~ /(\})$/) {$iContent_Start=$iContent;};

Der Fehler lautet: right bracket without left bracket

Die Regex soll die geschweifte Klammer ohne darauffolgendes Komma erkennen. Aber schein bekomme ich sie nicht escapet.

edit: Die geschweifte Klammer durch hex
if ($Row =~ /(\x7D)$/) {$iContent_Start=$iContent;};

GammaTwin

#8
Grüße,

Anbei das DOIF. Es lässt sich starten mit: set di_fronthem Run

Mit dem userattr "userattr_Pfad_fhserver_fronthem_cfg" gibt man, wo die Datei zum umsortieren liegt. Bei mir ist dies eine Kopie in meinem Sicherungsverzeichnis, nicht das Original.

als RAW:defmod di_fronthem DOIF ([$SELF:Sortierung] eq "Run") ({\
  ## Sicherung einlesen\
  my $fileName = AttrVal('$SELF', 'userattr_Pfad_fhserver_fronthem_cfg', '/Fehler');;\
  my ($err, @aContent) = FileRead({FileName => $fileName, ForceType => "file"});;\
  \
  ## Device finden und im Array sortieren, Ende_Device mit Komma extrahieren\
  my @aDevice=();;\
  my $iDevice=0;;\
  my $iContent=0;;\
  my $EndeDevice="leer";;\
  while ($iContent < scalar @aContent) {\
    if (index($aContent[$iContent], '"') == AttrVal('$SELF', 'userattr_AnzLeerProEinrueck', '') * 2) {\
  @aDevice[$iDevice] = $aContent[$iContent];;\
  if ($iDevice == 2) {$EndeDevice=$aContent[$iContent-1]};;\
  $iDevice++;;\
};;\
$iContent++;;\
  };;\
  @aDevice=sort {$a cmp $b} @aDevice;;\
  \
  ## der Anfang der Datei\
  my @aResult=();;\
  $iContent=0;;\
  while (index($aContent[$iContent], '"') < AttrVal('$SELF', 'userattr_AnzLeerProEinrueck', '') * 2) {\
    @aResult[$iContent++]=$aContent[$iContent];;\
  };;\
  \
  ## eigentlicher Vorgang\
  my $iResult=$iContent;;\
  my $iContent_Start=$iContent;;\
  $iDevice=0;;\
  ## alle Device (sortiertes Array) durchlaufen\
  while ($iDevice < scalar @aDevice) {\
## auf Device reagieren, ansonsten nächste Zeile\
if ($aContent[$iContent] eq $aDevice[$iDevice]) {\
  ## Device anhängen\
  @aResult[$iResult++]=$aDevice[$iDevice];;\
  ## Attribute sortieren, Besonderheit das letzte Komma, vorerst alle Zeilen mit Komma versehen\
  my @aAttr=();;\
  my $iAttr=0;;\
  $iContent++;;\
  while (index($aContent[$iContent], '"') > AttrVal('$SELF', 'userattr_AnzLeerProEinrueck', '') * 2) {\
    @aAttr[$iAttr]=$aContent[$iContent++];;\
if ($aAttr[$iAttr] !~ /(,)$/) {@aAttr[$iAttr]=$aAttr[$iAttr].","};;\
$iAttr++;;\
  };;\
  @aAttr=sort {$a cmp $b} @aAttr;;\
  ## Attribute anhängen, letztes Komma entfernen\
  my $i=0;;\
  foreach my $Row (@aAttr) {\
    @aResult[$iResult]= $Row;;\
chop($aResult[$iResult]) if ++$i == scalar(@aAttr);;\
$iResult++;;\
  };;\
  ## Ende des Attributs, Device beenden (außer beim letzten)\
  if (($iDevice +1) < scalar @aDevice) {\
@aResult[$iResult++]=$EndeDevice;;\
  };;\
  ## nächster Device, ursprünglicher Inhalt nach Anfang\
  $iDevice++;;\
  $iContent=$iContent_Start;;\
} else {\
  $iContent++;;\
};;\
  };;\
  \
  ## Das Ende der Datei, inkl. letztes Device abschließen\
  $iContent=0;;\
  foreach my $Row (@aContent) {\
## Regex mit hex\
my $regex=".{" . AttrVal('$SELF', 'userattr_AnzLeerProEinrueck', '') * 2 ."}\x7D";;\
if ($Row =~ /^($regex)$/) {$iContent_Start=$iContent;;};;\
$iContent++;;\
  };;\
  $iContent=$iContent_Start;;\
  while ($iContent < scalar @aContent) {\
    @aResult[$iResult++]=$aContent[$iContent++];;\
  };;\
  \
  ## Datei neu schreiben, im git-Verzeichnis bzw. Einleseverzeichnis\
  open (DATEI, ">", $fileName) or die $!;;\
  foreach my $Row (@aResult) {\
    print DATEI $Row."\n";;\
  };;\
  close (DATEI);;\
  \
  ## Aktion für beendet erklären\
  fhem("set $SELF Sortierung Done");;\
};;)
attr di_fronthem userattr userattr_AnzLeerProEinrueck userattr_Pfad_fhserver_fronthem_cfg
attr di_fronthem do always
attr di_fronthem readingList Sortierung
attr di_fronthem setList Sortierung:Run
attr di_fronthem userattr_AnzLeerProEinrueck 3
attr di_fronthem userattr_Pfad_fhserver_fronthem_cfg <Pfad zur fhserver.fronthem.cfg>


Noch eine Anmerkung: Anfang und Ende bleiben unsortiert, je nachdem wie das json vorher aussah. Stört mich weniger, da es mir um die Device ging.

Edit: Verbesserung einer regex.