List & Tree :Speichern und Laden

Hallo,

ich habe eine Verständnisfrage und bin in der Doku für das „List“ Objekt nicht final fündig geworden.

Wie (mit welchem Key) werden die in den Moduleigenschaften gespeicherten Werte einer Liste beim Laden der FORM den in den Values übergebenen Einträgen zugeordnet?

Mir geht es darum, was passiert wenn ich bei einem Update des Moduls per Value in die bestehende Liste (irgendwo in der Mitte) einen neuen Eintrag ergänze. Dann ist bei dem neuen Laden der Form ja 1 Eintrag mehr in der Liste die per Value übergeben wird als in der Liste, die in der Moduleigenschaft gespeichert ist. Wie finden dann die Werte aus der Moduleigenschaft die richtigen Value Einträge?

Ich habe bei mir getestet, und auch nach dem ergänzen in der Mitte der Value-Liste stimmten nach dem Update die aus den Moduleigenschaften zugeordneten gespeicherten Werte.
Von daher würde ich sagen die Zuordnung funktioniert auch in dem Fall, ich will nur sicher gehen dass dem immer so ist und die Logik verstehen.

VG
Philipp

Es gibt einfach keinen Key.
Es ist eine Liste von assozierten Arrays. Kein assoziiertes Array von Arrays.
Michael

Hallo Michael,

danke für die Antwort.
Evtl. stehe ich ja auf dem Schlauch…
Wie „treffen“ sich dann die Einträge aus der über VALUE übertragenen Liste mit den dazu gespeicherten Werten in der Liste der Moduleigenschaft?
Denn wenn nur VALUE-Listen-Eintrag[0] zu Moduleigenschaft-Listen Eintrag[0] ( [1] zu [1], usw) zugeordnet wird, dann müsste es doch eigentlich eine fehlerhafte Zuordnung geben wenn ich über den Value ein zusätzlichen Eintrag in der Mitte der Liste übergebe, welcher bisher in der Moduleigenschaft Liste nicht vorhanden/gespeichert ist, oder?
Mein Test hat aber in dem Fall eine korrekte Zuordnung gezeigt…

VG
Philipp

Das ist doch solange egal, wie du nicht versuchst mit den nummerischen Index zu arbeiten, welcher sich ja jederzeit ändern kann.
Michael

Ich glaube wir reden aneinander vorbei :slight_smile:

Es geht mir nicht darum wie ich darauf zugreife, sondern um die native Logik wie die Liste & der Tree die Daten speichert und dann beim erneuten Laden der Liste/Trees wieder abruft.
In der Doku findet sich dies:

Ich verstehe das so, dass zuerst Werte aus der gesicherten Modul-Eigenschaft gelesen werden und dann mit weiteren Infos ( bei mir Farbe und „editable“ ) dann aus der VALUES Liste ergänzt werden.
Aber wie findet dann hier die richtige Zeile aus der Modul-Eigenschaft zu der korrekten Zeile aus den VALUES, dass die korrekte Farbe und „editable“ zugeordnet wird, falls die VALUES Liste durch ein Modul Update ergänzt wurde und somit der numerische Index der beiden Listen nicht mehr synchron ist?

Als Alternative probiere ich mal loadValuesFromConfiguration auf false zu stellen und update dann Values mit den Werten aus den Modul-Eigenschaften selbst in der GetConfigurationForm, dann kann ich selbst die korrekten Einträge zuordnen.

VG
Philipp

Bin gerade überlegen, ich glaube ich habe es Mal benutzt um die Zeilen einzufärben.
Aber dennoch wäre das ja egal, wenn du values ausliefern willst, musst du das in der gleichen Reihenfolge machen wie die Elemente aktuell in der Eigenschaft gespeichert sind.
Ein einfaches durchlaufen der Eigenschaft mit foreach sollte daher reichen um values zu bauen, einen Index braucht man dafür entsprechend nicht.
Und wenn du Zeilen ergänzen willst, kannst du sie nur anhängen, steht ja oben das überzählige Elemente aus Values ggfls mit Add Werten ergänzt werden.
Klar kann man dann auch loadValuesFromConfiguration auf false setzen und einfach alle Einträge und Felder ausliefern.
Michael

Bei mir ist es ja gerade anders rum, ich will ja neue Werte über VALUES ausliefern, und hab daher VALUES Elemente zuviel, und nicht wie oben beschrieben zuviel Werte in den Eigenschaften.

Aber egal, ich probiere jetzt einfach mal mit loadValuesFromConfiguration false und versorge die Werte selbst.

Vielen Dank fürs „Mitdenken“ :slight_smile:

VG
Philipp

Mehr ist ja kein Problem, musst ja eh z.b. die Rowcolor ausgeben und hängst hinten neue an.
Schlimm wird es wenn es weniger werden sollen, da kommt man dann nicht an loadValuesFromConfiguration false vorbei.
Michael

Der „Key“ bei den values ist einfach die Position. Es werden also für jede Zeile pro Spalte primär der Wert aus der Eigenschaft, sekundär der Wert aus Values und tertiär der add-Wert verwendet. Möchtest du also beispielsweise der zweiten Zeile eine Farbe verpassen, aber sonst die Werte aus den Eigenschaften verwenden könntest du

"values": [
  [],
  [
    "rowColor": "#FFFFC0"
  ]
]

verwenden

Bin noch mal bei dem Thema :sweat_smile:

Mein Verständnis von loadValuesFromConfiguration „false“ beim Tree wäre, dass ich den ganzen Tree selbst per „Values“ jedes Mal aufbauen kann/muss, und keinerlei Werte aus der Eigenschaft in den Tree geladen werden.

Das klappt aber bei mir nicht richtig. Wenn ich einen Wert in einer Zeile über „Values“ in der GetConfigurationForm() ändere, welcher in der Eigenschaft gespeichert wurde, wird im Tree trotzdem der Wert aus der Eigenschaft angezeigt. Sollte nicht gerade das mit dem loadValuesFromConfiguration „false“ unterbunden werden?

VG
Philipp

Genau so sollte es sein, bei loadValuesFromConfiguration auf false wird die Eigenschaft fürs Formular einfach ignoriert. Kannst du dein aktuelles Beispiel mal posten? Dann schaue ich gerne, was da schiefläuft.

Moin,

ich habe im Tibber_Realtime Modul die Listen-„Values“ dynamisch erstellen lassen

	$ListValues = [];
			foreach (static::$Variables as $Pos => $Variable) {
				$Pos          	= $Variable[0];
				$Ident        	= str_replace(' ', '', $Variable[1]);
				$Name         	= $Variable[1];
				$Tag		   	= $Variable[2];
				$VarType      	= $Variable[3];
				$Profile      	= $Variable[4];
				$Factor       	= $Variable[5];
				$Action       	= $Variable[6];
				$Keep         	= $Variable[7];

				$ListValues[] = ["Pos"=>"$Pos", "Ident"=>"$Ident", "Name"=>"$Name", "Tag"=>"$Tag", "VarType"=>"$VarType", "Profile"=>"$Profile", "Factor"=>"$Factor", "Action"=>"$Action", "Keep"=>"$Keep" ];

			}	
				$jsonform["elements"][3]['values'] = $ListValues; // in der json.form steht dann unter den columns nur  "values":[]

Fügst Du Zeilen in der „static::$Variables“ hinzu, werden diese automatisch mit den default Einträgen deiner „static::$Variables“ gefüllt ansonsten werden die der User benutzt.

Hi Kris,

genau dynamisch mache ich es auch, und das geht auch problemlos, so lange man nichts mehr an bestehenden Einträgen was anpassen will. ( In meinem Fall gehts um geänderte MQTT Topics).

Und daher will ich, dass immer meine Werte aus der „static::$Variables“ in den Tree übernommen werden, dass Änderungen an bestehenden „static::$Variables“-Werten auch berücksichtigt werden.
Den einzigen, durch den User änderbaren Wert in der Liste in der Spalte „Keep“, lese ich deshalb beim befüllen der Values aus der gespeicherten Tree Eigenschaft nach (Referenz ist der IDENT).

Und trotz „loadValuesFromConfiguration“ FALSE wird bei allen „bestehenden“ Zeilen trotzdem der Eigenschaftswert genommen und nicht mein über Value übergebener Wert.

public function GetConfigurationForm()
		{
			// Read FORM.JSON from directory to adjust Tree Values
			$jsonform = json_decode(file_get_contents(__DIR__."/form.json"), true);

			// Read actual Tree Property with the stored Data to transfer the Keep Status 
			$StoredRows = json_decode($this->ReadPropertyString('Variables'), true);

			$Variables_Form = [];
			// Process the Static ARRAY with the Variable Definitions
        	foreach (static::$Variables as $Pos => $Variable) {
				// Get Keep Status of stored Dataset from selected Datasets by User
				$keep = $Variable[10];
				if ($this->ReadPropertyString('Variables') != '' ){
					foreach ($StoredRows as $Index => $Row) {
						if ($Variable[3] == str_replace(' ', '', $Row['Ident'])) {
							$keep = $Row['Keep'];
						}
					}
				}
				$Variables_Form[] = [
					'id'          	=> $Variable[1],
					'parent'		=> $Variable[2],
					'Namespace'	  	=> $this->Translate($Variable[0]),
					'Ident'        	=> str_replace(' ', '', $Variable[3]),
					'Name'         	=> $this->Translate($Variable[3]),
					'Tag'		   	=> $Variable[4],
					'MQTT'		   	=> $Variable[5],
					'VarType'      	=> $Variable[6],
					'Profile'      	=> $Variable[7],
					'Factor'       	=> $Variable[8],
					'Action'       	=> $Variable[9],
					'Keep'         	=> $keep,
					'rowColor'     	=> $this->set_color($Variable[2]),
					'editable'     	=> $this->set_editable($Variable[2])
				];
        	}
			// Update Tree Values in the respective Form Array	
			$jsonform["elements"][0]["values"] = $Variables_Form;
			$this->SendDebug('RSCP Form_post', json_encode($jsonform),0);
			return json_encode($jsonform);
		}

Und hier der Ausschnitt aus der Form:

{
    "elements": [
        {
            "type": "Tree",
            "name": "Variables",
            "caption": "",
            "loadValuesFromConfiguration": false,
            "add": false,
            "delete": false,
            "columns": [
                {
                    "caption": "Index",
                    "name": "id",
                    "width": "65px",
                    "save": true
                },
                {
                    "caption": "Parent",
                    "name": "parent",
                    "visible": false,
                    "width": "0px",
                    "save": true
                },
                {
                    "caption": "Namespace",
                    "name": "Namespace",
                    "width": "50px",
                    "visible": false,
                    "save": true
                },

VG
Philipp

ich weiß das zu gut, das war der Grund warum das Tibber_Realtime Module die reviews nicht bestanden hat ;). Danke nochmals an allen Review-Beteiligten an dieser stelle für eure Engelsgeduld :smiley:

So mache ich das auch, aber nicht mit „loadValuesFromConfiguration“.

der Auschnitt der json.form von Tibber würde dann so aussehen:

        {
            "type": "List",
            "name": "Variables",
            "caption": "",
            "sort": {
                "column": "Pos",
                "direction": "ascending"
            },
            "add": false,
            "delete": false,
            "columns": [
                {
                    "caption": "Ident",
                    "name": "Ident",
                    "visible": false,
                    "width": "0px",
                    "save": true
                },
 
                {
                    "caption": "Action",
                    "name": "Action",
                    "visible": false,
                    "width": "0px",
                    "save": true
                },
                {
                    "caption": "Active",
                    "name": "Keep",
                    "width": "75px",
                    "edit": {
                        "caption": "Active",
                        "type": "CheckBox"
                    }
                }],

                "values":[]
        }
           

man beachte das einsame
"values":[]
am Ende welches in der GetConfigurationForm() gefüllt wird

$ListValues = [];
			foreach (static::$Variables as $Pos => $Variable) {
				$Pos          	= $Variable[0];
				$Ident        	= str_replace(' ', '', $Variable[1]);
				$Name         	= $Variable[1];
				$Tag		   	= $Variable[2];
				$VarType      	= $Variable[3];
				$Profile      	= $Variable[4];
				$Factor       	= $Variable[5];
				$Action       	= $Variable[6];
				$Keep         	= $Variable[7];

				$ListValues[] = ["Pos"=>"$Pos", "Ident"=>"$Ident", "Name"=>"$Name", "Tag"=>"$Tag", "VarType"=>"$VarType", "Profile"=>"$Profile", "Factor"=>"$Factor", "Action"=>"$Action", "Keep"=>"$Keep" ];

			}	
				$jsonform["elements"][3]['values'] = $ListValues; // in der json.form steht dann unter den columns nur  "values":[]

Da du die Werte ja nicht zur Laufzeit hinzufügst sondern maximal bei einem Modulupdate, klappt das so ganz gut…

Hi Kris,

danke für deinen Input.

Das hinzufügen ist alles kein Problem und funktioniert :slight_smile: Ich will nur die Möglichkeit haben an bestehenden Werten was anzupassen. (Natürlich nur Werte die sowieso vom Modul vordefiniert sind/werden → auf die der User keinen Einfluss hat). Die Usereingabe („Keep“ true oder false) berücksichtige ich daher ja, damit ich den „User-Wille“ erfülle.

Ich habe jetzt das „einsame“ VALUES auch mal testweise in die Form gemacht, bringt aber leider keine Änderung… neue Einträge werden wie bisher übernommen und Änderungen ignoriert.

@Dr.Niels : Hast du noch eine Idee wo der Fehler liegen kann?

VG
Philipp

Denkt daran, dass je nach Anwendungsfall loadValuesFromConfiguration potentiell auch Overkill sein kann. Wenn beispielsweise die Liste 5 Einträge zum ankreuzen via CheckBox hat, welche jeweils einen Titel haben, dann wird der Titel ja sowieso nicht gespeichert und wird jedes mal wieder aus values genommen und kann damit von euch vorgegeben werden. Problematisch wird es erst dann wenn der Index als ID nicht mehr ausreicht, also beispielsweise ein neuer Eintrag mittendrin dazukommen soll. Dann braucht man loadValuesFromConfiguration.

Auf den ersten Blick sieht euer Code aber korrekt aus. Habt ihr das jeweilige Modul sonst einfach mal zum Ausprobieren für mich und eine Möglichkeit den Fehler auch ohne Geräte zu provozieren? In unserem Testmodul klappt es auf jeden Fall schonmal einwandfrei: https://github.com/symcon/SymconTest/tree/master/ListLoadValuesFromConfigurationTest

Fehler gefunden. Der Parameter loadValuesFromConfiguration hat einfach bei Tree noch nicht funktioniert, bei List hats aber einwandfrei geklappt. Fix kommt.

1 „Gefällt mir“

Super! Vielen Dank…