dynamische Variable

Allgemeines zur HomeMatic Haussteuerung

Moderator: Co-Administratoren

Antworten
bo90411
Beiträge: 9
Registriert: 30.09.2018, 12:25

dynamische Variable

Beitrag von bo90411 » 01.10.2018, 13:42

Hallo Zusammen,

für eine Heizungssteuerung habe ich folgendes Teilscript für eine ccu2 geschrieben:

Code: Alles auswählen


real zz_temp_hk1 = 25.0;
real zz_temp_hk2 = 21.0;
real zz_temp_hk3 = 22.0;
real zz_temp_hk4 = 23.0;

integer i=1;
while (i<5)
{
var zzz_hk = "zz_hk" + i.ToString();
string zzz_temp_hk = "zz_temp_hk" + i.ToString();
dom.GetObject( zzz_hk ).State( zzz_temp_hk );
var temp_neu = dom.GetObject( zzz_hk ).State();
WriteLine ( temp_neu );
i=i+1;
}
Mit diesem Script sollen den Systemvariablen zz_hk1; zz_hk2; zz_hk3 und zz_hk4 die Werte der Variablen zz_temp1 bis zz_temp4 zugewiesen werden.
Leider ändern sich die Werte für zz_hk1 usw nicht.

Hätte hier jemand einen Tip?

Vielen Dank

dtp
Beiträge: 10658
Registriert: 21.09.2012, 08:09
System: CCU
Wohnort: Stuttgart
Hat sich bedankt: 320 Mal
Danksagung erhalten: 501 Mal

Re: dynamische Variable

Beitrag von dtp » 01.10.2018, 14:02

Was passiert denn, wenn du es mit nachfolgendem Skript versuchst?

Code: Alles auswählen

real zz_temp_hk1 = 25.0;
real zz_temp_hk2 = 21.0;
real zz_temp_hk3 = 22.0;
real zz_temp_hk4 = 23.0;
integer i = 1;

while(i<5){
  (dom.GetObject(ID_SYSTEM_VARIABLES).Get("zz_hk"+i.ToString())).State("zz_temp_hk"+i.ToString());
  i=i+1;
}
Ich gehe davon aus, dass du die entsprechenden Systemvariablen vom Typ Zahl angelegt hast.
CCU3 mit stets aktueller FW und den Addons "CUxD" und "Programmedrucken", ioBroker auf Synology DiskStation DS718+ im Docker-Container;
einige Projekte: zentrales Push-Nachrichten-Programm zPNP, DoorPi-Videotürsprechanlage, An- und Abwesenheitsdetektion per Haustürschloss, zentrales Programm zur Steuerung von Beschattungsgeräten zBSP.

bo90411
Beiträge: 9
Registriert: 30.09.2018, 12:25

Re: dynamische Variable

Beitrag von bo90411 » 01.10.2018, 14:36

Vielen Dank für die Antwort.

Die Systemvariablen zz_hk1 - zz_hk4; zz_temp_hk1 - zz_temp_hk4 sind als Zahl angelegt.

Folgende Script ändern den Wert der Systemvariable zz_hk1, habe die Schleife entsprechend rausgenommen:

Code: Alles auswählen

var i = 1;
real zz_temp_hk1 = 24.0;
(dom.GetObject(ID_SYSTEM_VARIABLES).Get("zz_hk"+i.ToString())).State(zz_temp_hk1);
und zum Beispiel:

Code: Alles auswählen

var i = 1;
(dom.GetObject(ID_SYSTEM_VARIABLES).Get("zz_hk"+i.ToString())).State(24.0);
Nur wenn ich meine Variable zzz_temp_hk mit zzz_temp_hk + i "zusammenbaue" habe ich keinen Zugriff auf die Variablen real = zz_temp_hk1 usw oben im Script, obwohl diese per WriteLine richtig mit zz_temp_hk1 bis zz_temp_hk4 ausgegeben werden.

Wo ist hier mein Denkfehler?

Bratmaxe
Beiträge: 1573
Registriert: 28.05.2015, 12:48
Wohnort: Willich
Hat sich bedankt: 4 Mal
Danksagung erhalten: 10 Mal

Re: dynamische Variable

Beitrag von Bratmaxe » 01.10.2018, 15:11

versuch mal bitte ein # statt dem + Zeichen

Code: Alles auswählen

(dom.GetObject(ID_SYSTEM_VARIABLES).Get(("zz_hk"#i.ToString()))).State(24.0);
Gruß Carsten

dtp
Beiträge: 10658
Registriert: 21.09.2012, 08:09
System: CCU
Wohnort: Stuttgart
Hat sich bedankt: 320 Mal
Danksagung erhalten: 501 Mal

Re: dynamische Variable

Beitrag von dtp » 01.10.2018, 15:26

bo90411 hat geschrieben:
01.10.2018, 14:36
Wo ist hier mein Denkfehler?
Ich hatte schon mal ein ähnlich gelagertes Problem und meine mich daran zu erinnern, dass es nicht möglich ist, innerhalb des State()-Kommandos die Inhalte von aus Substrings zusammengesetzten Variablennamen zu setzen. Kann aber sein, dass es da eine Umgehungslösung gibt, die mir nur nicht bekannt ist.
CCU3 mit stets aktueller FW und den Addons "CUxD" und "Programmedrucken", ioBroker auf Synology DiskStation DS718+ im Docker-Container;
einige Projekte: zentrales Push-Nachrichten-Programm zPNP, DoorPi-Videotürsprechanlage, An- und Abwesenheitsdetektion per Haustürschloss, zentrales Programm zur Steuerung von Beschattungsgeräten zBSP.

bo90411
Beiträge: 9
Registriert: 30.09.2018, 12:25

Re: dynamische Variable

Beitrag von bo90411 » 01.10.2018, 15:39

die Variable die ich setzen will z.B. zz_hk1 kann ich mit "zz_hk"+i zusammenbauen.

Nur die Variable für State(), welche am Anfang des Script stehen kann nicht per "zz_temphk"#1 bzw. +i zusammengesetzt werden.

Trage ich bei State die Variable zz_temphk1 ein, ist ein Zugriff auf diese Variable am Anfang des scripts möglich.
Möchte ich mir jedoch die Variable innerhalb der Schliefe mit den "zz_temphk"#1 zusammenbauen lassen, wird nicht mehr auf die Wertevergabe am Anfang des scripts zurückgegriffen und die Variable nicht geändert.

Ziel wäre es diverse Variablen für Tag, Nacht; Urlaub am Anfang des Script zu definieren und dann über if Bedingungen und Schleifen den Heizkörpern zuzuweisen. Eine Änderung der Vorgaben würde dann in meinen Fall für die 15 Heizkörper durch die Werte der Variablen zz_temphk1 bis zz_temphk15 einmalig im Script erfolgen.
Zuletzt geändert von bo90411 am 01.10.2018, 17:37, insgesamt 1-mal geändert.

Bratmaxe
Beiträge: 1573
Registriert: 28.05.2015, 12:48
Wohnort: Willich
Hat sich bedankt: 4 Mal
Danksagung erhalten: 10 Mal

Re: dynamische Variable

Beitrag von Bratmaxe » 01.10.2018, 15:49

Ich nehme mal an, das die Variable zz_hk1 vom Typ Float ist, du schreibst aber so einen String in die Variable, ich weiss nicht ob die RaGa das sauber umsetzt. Versuch doch mal den Wert vorher umzuwandeln mit .ToFloat()

Code: Alles auswählen

(dom.GetObject(ID_SYSTEM_VARIABLES).Get(("zz_hk"#i.ToString()))).State( temp_neu1.ToFloat() );
Gruß Carsten

bo90411
Beiträge: 9
Registriert: 30.09.2018, 12:25

Re: dynamische Variable

Beitrag von bo90411 » 01.10.2018, 17:11

Vielen Dank für die Antworten.

Habe das Problem nun wie folgt gelöst

Code: Alles auswählen

! Systemvariablen Zahl zz_hk1 bis zz_hk4

! Liste der Temperaturen pro Heizkoerper

real pos1 = 20;
real pos2 = 21;
real pos3 = 22;
real pos4 = 23;

!Liste zum Auslesen erstellen 

string liste_hktag = "0\t" # pos1 # "\t" # pos2 # "\t" # pos3 # "\t" # pos4;

!Temperaturen in die Systemvariablen schreiben

integer i=1;
while (i<5)
{
string temp_stell = liste_hktag.StrValueByIndex("\t", i  ); 
WriteLine ( temp_stell );
(dom.GetObject(ID_SYSTEM_VARIABLES).Get("zz_hk"#i.ToString())).State( temp_stell );
i = i + 1;
}

! XXXXXXX = Seriennummer HMIP-eTRV
! Systemvariablen als State() benutzen
object regler1 = dom.GetObject("BidCos-RF.XXXXXXXXXX:2.SET_TEMPERATURE");
regler1.State( zz_hk1 );

alchy
Beiträge: 10754
Registriert: 24.02.2011, 01:34
System: CCU
Hat sich bedankt: 65 Mal
Danksagung erhalten: 673 Mal

Re: dynamische Variable

Beitrag von alchy » 02.10.2018, 09:21

@bo90411
Wie du richtig erkannt hast:
Es ist *IMHO* nicht möglich Scriptvariablennamen mittels String Concatenation zusammenzusetzen und dann auf den Wert derselben zuzugreifen.

Eine Möglichkeit dein Ziel zu erreichen wäre natürlich die Temperaturen in einer Liste zu schreiben wie in deinem Versuch.
Bitte folgendes nur als Hinweis verstehen
  • es gibt eine automatische Typumwandlung - real pos1 = 20; macht pos1 nicht zum real nur weil es davor steht, es bleibt ein Integer
  • Mittels String Concatenation eine Liste zusammenzusetzen ist nicht nötig oder ein unnötiger Umweg. Dann schreib gleich die Temperaturen in die Liste
  • ^^ die liste ist ein string
  • wenn du TAB als Trenner innerhalb einer Liste benutzt brauchst du StrValueByIndex nicht
  • while ist nicht nötig zum Auslesen einer Liste
  • das Ergebnis von .StrValueByIndex() ist ein string
  • .StrValueByIndex() mit 2 oder mehr Buchstaben funktioniert nicht - nicht erst angewöhnen
- trotzdem,wie du ja siehst, funktioniert deine Version trotzdem. :mrgreen:
Es gibt immer verschiedene Weg zum Ziel


[EDIT]
schnell mal zusammengepinselt, bevor es Haue gibt

Code: Alles auswählen

! Systemvariablen Zahl zz_hk1 bis zz_hk4 mit Werten aus Liste füllen
! Liste der Temperaturen pro Heizkoerper
string liste_hktag = "20.0\t21.0\t22.0\t23.0\t24.0";
string index;integer i =0;
foreach (index,liste_hktag)
{
i=i+1;
if ( (dom.GetObject(ID_SYSTEM_VARIABLES)).Get("zz_hk"#i) ) { dom.GetObject(ID_SYSTEM_VARIABLES).Get("zz_hk"#i).State( (index.ToFloat())); WriteLine("Wert: "#index.ToFloat()#" in Variable: " #"zz_hk"#i #" eingetragen");}else{WriteLine("Achtung: Variable: " #"zz_hk"#i #" : für den Wert: "#index.ToFloat()#" nicht vorhanden");}
}
[/EDIT]

Alchy
Zuletzt geändert von alchy am 02.10.2018, 09:34, insgesamt 1-mal geändert.

Blacklist................... almost full
Ignoranz ist die Summe aller Maßnahmen die man ergreift, um bestehende Tatsachen nicht sehen zu müssen.

© Sandra Pulsfort (*1974)

Lies bitte die Logik von WebUI Programmen und die Tipps und Tricks für Anfänger.

Wichtig auch CUxD ersetzt System.exec. Die HM Script Doku (Downloadart Skripte) hilft auch weiter.
Zum Testen von Scripten den >> HomeMatic Script Executor << von Anli benutzen.

dtp
Beiträge: 10658
Registriert: 21.09.2012, 08:09
System: CCU
Wohnort: Stuttgart
Hat sich bedankt: 320 Mal
Danksagung erhalten: 501 Mal

Re: dynamische Variable

Beitrag von dtp » 02.10.2018, 09:27

alchy hat geschrieben:
02.10.2018, 09:21
[*]while ist nicht nötig zum Auslesen einer Liste
Um das kurz zu ergänzen. Dafür gibt es den foreach-Befehl.

Auf die Liste hätte ich aber auch kommen können, zumal ich es an vielen Stellen ja selbst so umgesetzt habe. Nun ja, Betriebsblindheit. ;)

Bis dann,

Thorsten
CCU3 mit stets aktueller FW und den Addons "CUxD" und "Programmedrucken", ioBroker auf Synology DiskStation DS718+ im Docker-Container;
einige Projekte: zentrales Push-Nachrichten-Programm zPNP, DoorPi-Videotürsprechanlage, An- und Abwesenheitsdetektion per Haustürschloss, zentrales Programm zur Steuerung von Beschattungsgeräten zBSP.

Antworten

Zurück zu „HomeMatic allgemein“