jens-maus / RaspberryMatic

:house: A feature-rich but lightweight, buildroot-based Linux operating system alternative for your CloudFree CCU3/ELV-Charly 'homematicIP CCU' IoT smarthome central. Running as a pure virtual appliance (ProxmoxVE, Home Assistant, LXC, Docker/OCI, Kubernetes/K8s, etc.) on a dedicated embedded device (RaspberryPi, etc.) or generic x86/ARM hardware.
https://raspberrymatic.de
Apache License 2.0
1.53k stars 186 forks source link

ReGaHSS: foreach [2/12 BP-2] -> Anweisung akzeptiert nur bestimmte Datentypen im 1. Parameter #2612

Open BadenPower opened 8 months ago

BadenPower commented 8 months ago

Describe the issue you are experiencing

Ist der 2. Parameter der foreach-Anweisung vom Datentyp string oder idarray, dann muss die Variable des 1. Parameter zwingend vom Variabletyp string sein. Das Ergebnis des 1. Parameter iist ebenso vom Variabletyp string. Ist hingegen der 2. Parameter vom Datentyp integer, dann muss die Variable des 1. Parameter vom Variabletyp string oder integer sein. Hierbei ist das Ergebnis des 1. Parameter in beiden Fällen vom Variabletyp integer. Bei allen weiteren Variabletypen wird die Schleifen nicht durchlaufen.

Describe the behavior you expected

Erwartet würde, dass die verwendete Variable automatisch in den Variabletyp des Ergebnisses konvertiert wird, egal welchen Variabletyp diese vor der Ausführung der foreach-Anweisung hatte.

Steps to reproduce the issue

Ausführung des folgenden Skriptes unter "Skript testen":

WriteLine("Start");
WriteLine(dom.BuildLabel());
real lResult;
var lParam1;
var lParam2;
string lParam1Type;
string lParam2Type;
integer lEnumParam1;
integer lEnumParam2;
boolean lExecute;

idarray lIdArray = (dom.GetObject("Admin")).UserTempViewIDs3();
lIdArray.Add(111111); lIdArray.Add(222222); lIdArray.Add(333333);
xml lXml;
var lVar;

foreach(lEnumParam2,10)
{
  lExecute = false;
  !if(lEnumParam2 ==  1) { lExecute = true; lParam2Type = "boolean"; lParam2 = true; }
  !if(lEnumParam2 ==  2) { lExecute = true; lParam2Type = "boolean"; lParam2 = false; }
  if(lEnumParam2 ==  3) { lExecute = true; lParam2Type = "idarray"; lParam2 = lIdArray; }
  if(lEnumParam2 ==  4) { lExecute = true; lParam2Type = "integer"; lParam2 = 3; }
  if(lEnumParam2 ==  5) { lExecute = true; lParam2Type = "object";  lParam2 = root; }
  if(lEnumParam2 ==  6) { lExecute = true; lParam2Type = "real";    lParam2 = 3.5; }
  if(lEnumParam2 ==  7) { lExecute = true; lParam2Type = "string";  lParam2 = "A\tB\tC"; }
  if(lEnumParam2 ==  8) { lExecute = true; lParam2Type = "time";    lParam2 = localtime; }
  if(lEnumParam2 ==  9) { lExecute = true; lParam2Type = "var";     lParam2 = lVar; }
  if(lEnumParam2 == 10) { lExecute = true; lParam2Type = "xml";     lParam2 = lXml; }

  if(lExecute)
  {
    WriteLine("--------------------------------------------------");
    foreach(lEnumParam1,9)
    {
      lExecute = false;
      if(lEnumParam1 == 1) { lExecute = true; lParam1Type = "boolean"; boolean lParam1; }
      if(lEnumParam1 == 2) { lExecute = true; lParam1Type = "idarray"; idarray lParam1; }
      if(lEnumParam1 == 3) { lExecute = true; lParam1Type = "integer"; integer lParam1; }
      if(lEnumParam1 == 4) { lExecute = true; lParam1Type = "object";  object  lParam1; }
      if(lEnumParam1 == 5) { lExecute = true; lParam1Type = "real";    real    lParam1; }
      if(lEnumParam1 == 6) { lExecute = true; lParam1Type = "string";  string  lParam1; }
      if(lEnumParam1 == 7) { lExecute = true; lParam1Type = "time";    time    lParam1; }
      if(lEnumParam1 == 8) { lExecute = true; lParam1Type = "var";     var     lParam1; }
      if(lEnumParam1 == 9) { lExecute = true; lParam1Type = "xml";     xml     lParam1; }

      if(lExecute)
      {
        WriteLine("--------------------------------------------------");
        WriteLine("     Parametyp 1: " # lParam1Type # " / Parametertyp 2: " # lParam2Type # " / Parameter 2: " # lParam2);
        foreach(lParam1,lParam2)
        {
          WriteLine(lParam1.Type() # " " # lParam1);
        }
      }
    }
  }
}
WriteLine("");
WriteLine("Ende");

What is the version this bug report is based on?

CCU3 mit ReGaHSS-Version R1.00.0388.0235

Which base platform are you running?

rpi3 (RaspberryPi3)

Which HomeMatic/homematicIP radio module are you using?

n/a

Anything in the logs that might be useful for us?

bestehend seit:
unbekannt (bereits mit ReGaHss-Version R1.00.0388.0102)

Additional information

Ausgabe des Skriptes:

Start
R1.00.0388.0235
--------------------------------------------------
--------------------------------------------------
     Parametyp 1: boolean / Parametertyp 2: boolean / Parameter 2: false
--------------------------------------------------
     Parametyp 1: idarray / Parametertyp 2: boolean / Parameter 2: false
--------------------------------------------------
     Parametyp 1: integer / Parametertyp 2: boolean / Parameter 2: false
--------------------------------------------------
     Parametyp 1: object / Parametertyp 2: boolean / Parameter 2: false
--------------------------------------------------
     Parametyp 1: real / Parametertyp 2: boolean / Parameter 2: false
--------------------------------------------------
     Parametyp 1: string / Parametertyp 2: boolean / Parameter 2: false
--------------------------------------------------
     Parametyp 1: time / Parametertyp 2: boolean / Parameter 2: false
--------------------------------------------------
     Parametyp 1: var / Parametertyp 2: boolean / Parameter 2: false
--------------------------------------------------
     Parametyp 1: xml / Parametertyp 2: boolean / Parameter 2: false
--------------------------------------------------
--------------------------------------------------
     Parametyp 1: boolean / Parametertyp 2: idarray / Parameter 2: 
--------------------------------------------------
     Parametyp 1: idarray / Parametertyp 2: idarray / Parameter 2: 
--------------------------------------------------
     Parametyp 1: integer / Parametertyp 2: idarray / Parameter 2: 
--------------------------------------------------
     Parametyp 1: object / Parametertyp 2: idarray / Parameter 2: 
--------------------------------------------------
     Parametyp 1: real / Parametertyp 2: idarray / Parameter 2: 
--------------------------------------------------
     Parametyp 1: string / Parametertyp 2: idarray / Parameter 2: 
string 111111
string 222222
string 333333
--------------------------------------------------
     Parametyp 1: time / Parametertyp 2: idarray / Parameter 2: 
--------------------------------------------------
     Parametyp 1: var / Parametertyp 2: idarray / Parameter 2: 
--------------------------------------------------
     Parametyp 1: xml / Parametertyp 2: idarray / Parameter 2: 
--------------------------------------------------
--------------------------------------------------
     Parametyp 1: boolean / Parametertyp 2: integer / Parameter 2: 3
--------------------------------------------------
     Parametyp 1: idarray / Parametertyp 2: integer / Parameter 2: 3
--------------------------------------------------
     Parametyp 1: integer / Parametertyp 2: integer / Parameter 2: 3
integer 1
integer 2
integer 3
--------------------------------------------------
     Parametyp 1: object / Parametertyp 2: integer / Parameter 2: 3
--------------------------------------------------
     Parametyp 1: real / Parametertyp 2: integer / Parameter 2: 3
--------------------------------------------------
     Parametyp 1: string / Parametertyp 2: integer / Parameter 2: 3
integer 1
integer 2
integer 3
--------------------------------------------------
     Parametyp 1: time / Parametertyp 2: integer / Parameter 2: 3
--------------------------------------------------
     Parametyp 1: var / Parametertyp 2: integer / Parameter 2: 3
--------------------------------------------------
     Parametyp 1: xml / Parametertyp 2: integer / Parameter 2: 3
--------------------------------------------------
--------------------------------------------------
     Parametyp 1: boolean / Parametertyp 2: object / Parameter 2: Root
--------------------------------------------------
     Parametyp 1: idarray / Parametertyp 2: object / Parameter 2: Root
--------------------------------------------------
     Parametyp 1: integer / Parametertyp 2: object / Parameter 2: Root
--------------------------------------------------
     Parametyp 1: object / Parametertyp 2: object / Parameter 2: Root
--------------------------------------------------
     Parametyp 1: real / Parametertyp 2: object / Parameter 2: Root
--------------------------------------------------
     Parametyp 1: string / Parametertyp 2: object / Parameter 2: Root
--------------------------------------------------
     Parametyp 1: time / Parametertyp 2: object / Parameter 2: Root
--------------------------------------------------
     Parametyp 1: var / Parametertyp 2: object / Parameter 2: Root
--------------------------------------------------
     Parametyp 1: xml / Parametertyp 2: object / Parameter 2: Root
--------------------------------------------------
--------------------------------------------------
     Parametyp 1: boolean / Parametertyp 2: real / Parameter 2: 3.500000
--------------------------------------------------
     Parametyp 1: idarray / Parametertyp 2: real / Parameter 2: 3.500000
--------------------------------------------------
     Parametyp 1: integer / Parametertyp 2: real / Parameter 2: 3.500000
--------------------------------------------------
     Parametyp 1: object / Parametertyp 2: real / Parameter 2: 3.500000
--------------------------------------------------
     Parametyp 1: real / Parametertyp 2: real / Parameter 2: 3.500000
--------------------------------------------------
     Parametyp 1: string / Parametertyp 2: real / Parameter 2: 3.500000
--------------------------------------------------
     Parametyp 1: time / Parametertyp 2: real / Parameter 2: 3.500000
--------------------------------------------------
     Parametyp 1: var / Parametertyp 2: real / Parameter 2: 3.500000
--------------------------------------------------
     Parametyp 1: xml / Parametertyp 2: real / Parameter 2: 3.500000
--------------------------------------------------
--------------------------------------------------
     Parametyp 1: boolean / Parametertyp 2: string / Parameter 2: A B   C
--------------------------------------------------
     Parametyp 1: idarray / Parametertyp 2: string / Parameter 2: A B   C
--------------------------------------------------
     Parametyp 1: integer / Parametertyp 2: string / Parameter 2: A B   C
--------------------------------------------------
     Parametyp 1: object / Parametertyp 2: string / Parameter 2: A  B   C
--------------------------------------------------
     Parametyp 1: real / Parametertyp 2: string / Parameter 2: A    B   C
--------------------------------------------------
     Parametyp 1: string / Parametertyp 2: string / Parameter 2: A  B   C
string A
string B
string C
--------------------------------------------------
     Parametyp 1: time / Parametertyp 2: string / Parameter 2: A    B   C
--------------------------------------------------
     Parametyp 1: var / Parametertyp 2: string / Parameter 2: A B   C
--------------------------------------------------
     Parametyp 1: xml / Parametertyp 2: string / Parameter 2: A B   C
--------------------------------------------------
--------------------------------------------------
     Parametyp 1: boolean / Parametertyp 2: time / Parameter 2: 2024-01-14 19:33:46
--------------------------------------------------
     Parametyp 1: idarray / Parametertyp 2: time / Parameter 2: 2024-01-14 19:33:46
--------------------------------------------------
     Parametyp 1: integer / Parametertyp 2: time / Parameter 2: 2024-01-14 19:33:46
--------------------------------------------------
     Parametyp 1: object / Parametertyp 2: time / Parameter 2: 2024-01-14 19:33:46
--------------------------------------------------
     Parametyp 1: real / Parametertyp 2: time / Parameter 2: 2024-01-14 19:33:46
--------------------------------------------------
     Parametyp 1: string / Parametertyp 2: time / Parameter 2: 2024-01-14 19:33:46
--------------------------------------------------
     Parametyp 1: time / Parametertyp 2: time / Parameter 2: 2024-01-14 19:33:46
--------------------------------------------------
     Parametyp 1: var / Parametertyp 2: time / Parameter 2: 2024-01-14 19:33:46
--------------------------------------------------
     Parametyp 1: xml / Parametertyp 2: time / Parameter 2: 2024-01-14 19:33:46
--------------------------------------------------
--------------------------------------------------
     Parametyp 1: boolean / Parametertyp 2: var / Parameter 2: null
--------------------------------------------------
     Parametyp 1: idarray / Parametertyp 2: var / Parameter 2: null
--------------------------------------------------
     Parametyp 1: integer / Parametertyp 2: var / Parameter 2: null
--------------------------------------------------
     Parametyp 1: object / Parametertyp 2: var / Parameter 2: null
--------------------------------------------------
     Parametyp 1: real / Parametertyp 2: var / Parameter 2: null
--------------------------------------------------
     Parametyp 1: string / Parametertyp 2: var / Parameter 2: null
--------------------------------------------------
     Parametyp 1: time / Parametertyp 2: var / Parameter 2: null
--------------------------------------------------
     Parametyp 1: var / Parametertyp 2: var / Parameter 2: null
--------------------------------------------------
     Parametyp 1: xml / Parametertyp 2: var / Parameter 2: null
--------------------------------------------------
--------------------------------------------------
     Parametyp 1: boolean / Parametertyp 2: xml / Parameter 2: 
--------------------------------------------------
     Parametyp 1: idarray / Parametertyp 2: xml / Parameter 2: 
--------------------------------------------------
     Parametyp 1: integer / Parametertyp 2: xml / Parameter 2: 
--------------------------------------------------
     Parametyp 1: object / Parametertyp 2: xml / Parameter 2: 
--------------------------------------------------
     Parametyp 1: real / Parametertyp 2: xml / Parameter 2: 
--------------------------------------------------
     Parametyp 1: string / Parametertyp 2: xml / Parameter 2: 
--------------------------------------------------
     Parametyp 1: time / Parametertyp 2: xml / Parameter 2: 
--------------------------------------------------
     Parametyp 1: var / Parametertyp 2: xml / Parameter 2: 
--------------------------------------------------
     Parametyp 1: xml / Parametertyp 2: xml / Parameter 2: 

Ende
jens-maus commented 8 months ago

In der Tat ist es so, das foreach nur eine bestimmte Menge an Datentypen für den 1. bzw. 2. Parameter akzeptiert bzw. verarbeiten kann. Dies ist in der offiziellen Doku sogar auf eine Zeichenkette (string) für den ersten und zweiten Parameter beschränkt worden. Siehe:

Bildschirmfoto 2024-01-16 um 08 45 50

Allerdings verarbeitet foreach in der Tat (wie man auch hier sehen kann) auch gewisse andere Datentypen. So z.B. integer für die index Angabe (1. Parameter) sowie idarray oder integer für die Liste (2. Parameter). Und auch wenn bei anderen Datentypen hier foreach nicht abbricht, so ist das Ergebnis bzw. das Verhalten in der Tat unspezifiziert wenn andere Datentypen – vor allem komplexe – hier Eingang finden. Hier geht foreach im Grunde recht strikt vor und erwartet im Grunde immer string als Datentyp für den 1. und 2. Parameter und lediglich idarray und integer sind als gewisse Ausnahmen dort in sehr limitierter Art&Weise umgesetzt. Deshalb überrascht es nicht das foreach hier mit anderen Datentypen im Grunde durcheinander kommt.

Die Frage ist jedoch wie man nun damit umgeht. Aktuell halte ich eine Erweiterung von foreach() um weitere Datentypen nicht für sinnvoll bzw. gefährlich. Und ob man die im Grunde nicht erlaubten Datentypen in einen erlaubten Datentyp verlustfrei bzw. sinnvoll umkonvertieren kann bin ich mir auch noch nicht so sicher. Deshalb gerne Meinungen/Hinweise usw. hier rein.

BadenPower commented 8 months ago

Es geht ja hier in diesem Bug nur um den 1. Parameter. Es sollte hier dabei egal sein, welchen Datentyp der 1. Parameter vor seiner Verwendung in der foreach-Schleife hat, denn dies spielt für die Abarbeitung der Schleife gar keine Rolle, da der ausgegebene Datentyp sowieso fix festgelegt ist.

Im Falle eines strings oder idarrays als 2. Parameter wird (bleibt) der Variabletyp immer string auch nach Abarbeitung der Schleife (falls kein anderer Bug zuschlägt)

Im Falle eines Integers als 2. Parameter kann der 1. Parameter vor seiner Verwendung in der Schleife string oder integer sein und wird in der Schleife automatisch immer zu integer, auch wenn dierser vor der Schleife string war.

Im 2. Fall findet ja auch eine Konvertierung in einen anderen Variabletyp statt. Weshalb sollte dies nicht für alle Variabletypen im 1. Parameter gelten, da ja der Wert der Variable ja gar keine Rolle spielt und es ja eigentlich nur eine "Ausgabe"-Variable darstellt.