RS232 Werte nur bei Änderung an KNX übergeben

Die Register Variable updated sich ja alle 5 sec - sehe ich im Debug dass da auch was ankommt.

Aber irgendwie aktualisiert sich gerade nichts mehr.
Ich habe das hier wieder reingenommen und da kommt nichts mehr…

SetValue(21051 , $datastr); // eigentlich nicht nötig

Ich habe die Prüfung, ob die erste Ziffer eine 0 ist ein wenig umgebaut. Ggf. ist da was falsch. Mach doch mal unmittelbar nach if($_IPS['SENDER']== "RegisterVariable"){ noch ein IPS_LogMessage

Er führt aber generell es nur aus wenn der String zum Anfang eine „2“ hat und länger gleich 35 Werte ist…

IPS_LogMessage of „MC1200“ $datastr liefert nichts

Hast du dir jetzt an den passenden Stellen Debug Infos ins Logfile geschrieben, um zu sehen, welcher Part nicht mehr ausgeführt wird? Welchen Wert die Registervariable hat, etc?

Ich stehe auf dem Schlauch…

Also:
Hier habe ich einmal die RegisterVariable abgefragt:

if($_IPS['SENDER']== "RegisterVariable"){
    // bereits im Puffer der Instanz vorhandene Daten in $data kopieren HIER AUSKOMMENTIEREN
	$data  = RegVar_GetBuffer($_IPS['INSTANCE']);
	// neu empfangene Daten an $data anhängen
	$data .= $_IPS['VALUE'];
	// Inhalt von $data im Puffer der RegisterVariable-Instanz speichern
	RegVar_SetBuffer($_IPS['INSTANCE'], $data);

	// Daten in hex umwandeln
	$datastr = strToHex($data);

    IPS_LogMessage($_IPS['SENDER'], "". $datastr);
    
    if(substr($datastr, 0, 1) == "2" and (strlen($datastr) >= 35)) {

Die zeigt mir:

also unedlich langer string - scheint immer weiter anzuhängen bei jeder Abfrage.
Daher wohl auch kein Update der Stati da ja immer ungleich ist…?

Habe etwas wieder zurück gedreht - damit er nicht die Variable flutet - geht auch.

if(strpos($datastr, "2" ) == 0 and (strlen($datastr) >= 35)) {

Aber nu kommt:

14.02.2022, 17:15:32 | Register Variable |
Notice: Undefined variable: datastring in C:\ProgramData\Symcon\scripts\28602.ips.php on line 53

Warning: Zeitüberschreitung beim Warten auf Antwort in C:\ProgramData\Symcon\scripts\28602.ips.php on line 63

Notice: Undefined variable: datastring in C:\ProgramData\Symcon\scripts\28602.ips.php on line 53

Notice: Undefined variable: datastring in C:\ProgramData\Symcon\scripts\28602.ips.php on line 53

Notice: Undefined variable: datastring in C:\ProgramData\Symcon\scripts\28602.ips.php on line 53

Notice: Undefined variable: datastring in C:\ProgramData\Symcon\scripts\28602.ips.php on line 53

Notice: Undefined variable: datastring in C:\ProgramData\Symcon\scripts\28602.ips.php on line 53

Notice: Undefined variable: datastring in C:\ProgramData\Symcon\scripts\28602.ips.php on line 53

Notice: Undefined variable: datastring in C:\ProgramData\Symcon\scripts\28602.ips.php on line 53

Notice: Undefined variable: datastring in C:\ProgramData\Symcon\scripts\28602.ips.php on line 53

Notice: Undefined variable: datastring in C:\ProgramData\Symcon\scripts\28602.ips.php on line 53

Notice: Undefined variable: datastring in C:\ProgramData\Symcon\scripts\28602.ips.php on line 53

Notice: Undefined variable: datastring in C:\ProgramData\Symcon\scripts\28602.ips.php on line 53

Notice: Undefined variable: datastring in C:\ProgramData\Symcon\scripts\28602.ips.php on line 53

Notice: Undefined variable: datastring in C:\ProgramData\Symcon\scripts\28602.ips.php on line 53

Notice: Undefined variable: datastring in C:\ProgramData\Symcon\scripts\28602.ips.php on line 53

Notice: Undefined variable: datastring in C:\ProgramData\Symcon\scripts\28602.ips.php on line 53

CODE:

<?php
$confarray = array( 
	array(11, 58812, "extern bereit"),
	array(29, 58270, "intern bereit"),
	array(21, 48587, "intern scharf"),
    //array(21, 33544, "extern scharf"),
    //array("21f1f280330111910000000000000001001911910043", 32662, "OG: Notruf"),
    //array("21f1f280330111910000000000000000101911910043", 11163, "EG: Notruf"),
    array(26, 30617, "KG: Büro/Gäste/Vorrat"),
    array(25, 26610, "KG: Abstell/HWR"),
    array(14, 21234, "EG: Eingang"),
    array(15, 11540, "EG: Küche"),
    array(16, 41463, "EG: Essen"),
    array(17, 14293, "EG: Wohnen"),
    array(18, 31717, "EG: Gästebad"),
    array(19, 53013, "EG: Büro"),
    array(20, 31254, "OG: Elternbad"),
    array(21, 57272, "OG: Ankleide"),
    //array(21, 50950, "OG: Schlafen"),
    array(22, 38621, "OG: Kinderbad"),
    array(23, 29071, "OG: Sophia"),
    array(24, 41380, "OG: Sarah")
    //array("21f1f280330111910000000000010000011911910053", 26768, "OG: Sophia Seite"),
    //array("21f1f280330111910000000000001000011911910053", 57710, "OG: Sarah Seite"),

);

//if($_IPS['SENDER'] == "Execute"){
RegVar_SetBuffer(32952, ""); // Aufräumen, wenn über Konsole gestartet
//}
if($_IPS['SENDER']== "RegisterVariable"){
    // bereits im Puffer der Instanz vorhandene Daten in $data kopieren HIER AUSKOMMENTIEREN
	$data  = RegVar_GetBuffer($_IPS['INSTANCE']);
	// neu empfangene Daten an $data anhängen
	$data .= $_IPS['VALUE'];
	// Inhalt von $data im Puffer der RegisterVariable-Instanz speichern
	RegVar_SetBuffer($_IPS['INSTANCE'], $data);

	// Daten in hex umwandeln
	$datastr = strToHex($data);

    IPS_LogMessage($_IPS['SENDER'], "". $datastr);
    
    if(strpos($datastr, "2" ) == 0 and (strlen($datastr) >= 35)) {
		//IPS_LogMessage("MC1200", "".$datastr);
		RegVar_SetBuffer($_IPS['INSTANCE'], ""); // Registervariable aufräumen
		// String in Variable ausgeben wenn mit 2 beginnt und gößer gleich 35 lang
		SetValue(21051 , $datastr); // eigentlich nicht nötig
		// übergibt zusätzlich noch gesamten string an KNX als text
		// KNX_WriteDPT16(21274, $datastr); // Verhindert KNX Fehler, weil Daten zu lang
	
		foreach($confarray as $conf){
			$substr = substr($datastring, $conf[0], 1);
			$newvalue = ($substr == "1") ? true : false;
			$variableID = IPS_GetObjectIDByIdent("Value", $conf[1]);
			$oldvalue  = GetValueBoolean($variableID);
			if($newvalue && !$oldvalue){
				// neuer Wert true, alter Wert false, daher Änderung schreiben
				SetValue(30068, $conf[2]); 
				KNX_WriteDPT1($conf[1], true);  
			}elseif(!$newvalue && $oldvalue){
				// neuer Wert false, alter Wert true, daher Änderung schreiben
				KNX_WriteDPT1($conf[1], false);
			}
			// Else: aktuell nichts zu tun
		}// Ende foreach
	} /// Ende if len>=35
} // Ende if RegisterVariable


function strToHex($string)
{
    $hex='';
    for ($i=0; $i < strlen($string); $i++)
    {
        IPS_sleep(25); // Wofür steht das?
        $hex .= dechex(ord($string[$i]));
    }
    return $hex;
}
?>

$datastring auf $datastr geändert liefert jetzt was - muss mich jetzt mal mit den Positionen noch mal beschäftigen.
Wertet Dein Skript ab wo genau aus?

Was noch kommt ist:

14.02.2022, 17:19:27 | Register Variable |
Warning: Zeitüberschreitung beim Warten auf Antwort in C:\ProgramData\Symcon\scripts\28602.ips.php on line 60

Warning: Zeitüberschreitung beim Warten auf Antwort in C:\ProgramData\Symcon\scripts\28602.ips.php on line 60

Da scheint die Ermittlung der Instanz nicht korrekt zu funktionieren.
Du musst in die Confarray die ID der Instanz setzen. Kann es sein, dass ggf. die ein oder andere Instanz ID (zum Testen) die falsche ist?

Durchaus kann das sein.
Zählst du die ID ab der 2 ganz vorne?

Leider updaten die KNX Variablen / Werte nicht.
Die HEX codes werden mittlerweile richtig ausgewertet und kommt auch an.

Ferner kommt, sobald ich ein Fenster aufmache:

Und es scheint ein unheimlicher Verzug in der Abarbeitung des Scriptes zu sein.
Ggf durch die Zeitüberschreitung?

Was kann das sein?

CODE:

<?php
ini_set( 'max_execution_time', 300);
$confarray = array( 
	//array(19, 58812, "extern bereit"),
	//array(20, 58270, "intern bereit / Verschluss OG"),
	//array(21, 48587, "intern scharf")
    //array(11, 58812, "extern bereit"),
	//array(29, 58270, "intern bereit"),
	//array(21, 48587, "intern scharf"),
    //array(21, 33544, "extern scharf"),
    array(18, 21234, "EG: Eingang"),
    array(19, 11540, "EG: Küche"),
    array(20, 41463, "EG: Essen"),
    array(21, 14293, "EG: Wohnen"),
    array(22, 31717, "EG: Gästebad"),
    array(23, 53013, "EG: Büro"),
    array(24, 31254, "OG: Elternbad"),
    array(25, 57272, "OG: Ankleide"),
    array(25, 50950, "OG: Schlafen"),
    array(26, 38621, "OG: Kinderbad"),
    array(27, 29071, "OG: Sophia"),
    array(28, 41380, "OG: Sarah"),
    array(29, 26610, "KG: Abstell/HWR"),
    array(30, 30617, "KG: Büro/Gäste/Vorrat")
    //array(31, 32662, "OG: Notruf"),
    //array(32, 11163, "EG: Notruf")
    //array("21f1f280330111910000000000010000011911910053", 26768, "OG: Sophia Seite"),
    //array("21f1f280330111910000000000001000011911910053", 57710, "OG: Sarah Seite"),

);

//if($_IPS['SENDER'] == "Execute"){
RegVar_SetBuffer(32952, ""); // Aufräumen, wenn über Konsole gestartet
//}
if($_IPS['SENDER']== "RegisterVariable"){
    // bereits im Puffer der Instanz vorhandene Daten in $data kopieren HIER AUSKOMMENTIEREN
	$data  = RegVar_GetBuffer($_IPS['INSTANCE']);
	// neu empfangene Daten an $data anhängen
	$data .= $_IPS['VALUE'];
	// Inhalt von $data im Puffer der RegisterVariable-Instanz speichern
	RegVar_SetBuffer($_IPS['INSTANCE'], $data);

	// Daten in hex umwandeln
	$datastr = strToHex($data);
    
    //IPS_LogMessage($_IPS['SENDER'], "". $datastr);
    //IPS_LogMessage($_IPS['INSTANCE'], "". $datastr);
    
    if(strpos($datastr, "2" ) == 0 and (strlen($datastr) >= 35)) {
		//IPS_LogMessage("MC1200", "".$datastr);
		RegVar_SetBuffer($_IPS['INSTANCE'], ""); // Registervariable aufräumen
        //RegVar_SetBuffer($_IPS['SENDER'], ""); // Registervariable aufräumen
		// String in Variable ausgeben wenn mit 2 beginnt und gößer gleich 35 lang
		SetValue(21051 , $datastr); // eigentlich nicht nötig
		// übergibt zusätzlich noch gesamten string an KNX als text
		// KNX_WriteDPT16(21274, $datastr); // Verhindert KNX Fehler, weil Daten zu lang
	    //SetValue(30068, "");
		foreach($confarray as $conf){
			$substr = substr($datastr, $conf[0], 1);
			$newvalue = ($substr == "1") ? true : false;
			$variableID = IPS_GetObjectIDByIdent("Value", $conf[1]);
			$oldvalue  = GetValueBoolean($variableID);
			if($newvalue && !$oldvalue){
				// neuer Wert true, alter Wert false, daher Änderung schreiben
				SetValue(30068, $conf[2]); 
				KNX_WriteDPT1($conf[1], true);
                print_r ($conf[1]) ; 
			}elseif(!$newvalue && $oldvalue){
				// neuer Wert false, alter Wert true, daher Änderung schreiben
				KNX_WriteDPT1($conf[1], false);
			}
			// Else: aktuell nichts zu tun
		}// Ende foreach
	} /// Ende if len>=35
} // Ende if RegisterVariable


function strToHex($string)
{
    $hex='';
    for ($i=0; $i < strlen($string); $i++)
    {
        //IPS_sleep(25); // Wofür steht das?
        $hex .= dechex(ord($string[$i]));
    }
    return $hex;
}
?>

Der Part der foreach Schleife hier mal mit Debug Meldungen im Meldungs-Fenster.
Ich habe aktuell kaum zeit, daher konnte ich nicht prüfen, ob das mindestens einen gültigen Syntax hat. Ggf. musst du wie oben schonmal ein paar Tipp-/Flüchtigkeitsfehler ausbauen.

foreach($confarray as $conf){
			$substr = substr($datastr, $conf[0], 1);
			$newvalue = ($substr == "1") ? true : false;
			$variableID = IPS_GetObjectIDByIdent("Value", $conf[1]);
			$oldvalue  = GetValueBoolean($variableID);
			IPS_LogMessage("RegVarAlarmanlage", "Ident: ".$conf[1]
					." Variable: ".$variableID
					." Newv: ".(($newvalue) ? "true" : "false")
					." Oldv: ".(($oldvalue) ? "true" : "false")
			if($newvalue && !$oldvalue){
				// neuer Wert true, alter Wert false, daher Änderung schreiben
				//SetValue(30068, $conf[2]); 
				//KNX_WriteDPT1($conf[1], true);
				IPS_LogMessage("RegVarAlarmanlage", "Möchte KNX Instanz ".$conf[1]." auf true setzen");
                print_r ($conf[1]) ; 
			}elseif(!$newvalue && $oldvalue){
				// neuer Wert false, alter Wert true, daher Änderung schreiben
				//KNX_WriteDPT1($conf[1], false);
				IPS_LogMessage("RegVarAlarmanlage", "Möchte KNX Instanz ".$conf[1]." auf false setzen");
			}else{
				IPS_LogMessage("RegVarAlarmanlage", "Für KNX Instanz ".$conf[1]." nichts zu tun");
			}

Moin,

ersteinmal Danke für den ganzen SUPPORT!

Die foreach schleife muss ich noch testen - bin gerade mit dem Umzug auf einem RaspPi beschäftigt.

Zurück nun zu meinem neuen Problem.
Ich benutze einen Digitus RS232 zu USB Wandler am USB Port des RaspPi. Der hat auch unter Windows gut funktioniert.

Nun gucke ich in den Debug des Seriellen Ports und sehe dass die langen Strings von der RS232 gestückelt sind.

In deinem 9. Post hattest Du geschrieben, dass ggf der Buffer korrekt zusammengesetzt werden muss und auch sauber gelöscht werden muss.

Wie gehe ich das denn an?

LG

Das geht theoretisch schon. Du musst nur an der passenden Stelle die Daten schneiden.
Aber ACHTUNG: Mach dir das leben einfach. Entweder testest du die ganze Magie, das an den KNX zu senden, den String sauber zu verarbeiten, etc.
Oder du testest erstmal die Daten sauber einzulesen. Dazu gibt es im Grunde ein paar Beispiele in der Doku, aus der du auch deine Codeschnipsel gezogen hast.

Also, die foreach schleife setzt in der Tat An / Aus an den KNX Werten - schon mal gut!

Nur habe ich eben das Problem, dass wie hier beschrieben:

mit den unterschiedlich langen RS232 Strings - scheinen so von der RS232 Schnittstelle aufgenommen zu werden am RaspPi - da die Alarmanlage wohl alles korrekt schickt (wie vorher auf Windows).

Das ist so seit dem ich:

  1. auf dem RaspPi bin - ggf ein Timing Fehler? Stoppbit kommt evtl nicht?
  2. ich die neuen RS232 Kommandos habe, da die alten nicht mehr gingen:
    ALT:
    COM_Port xxxxxxxxxxxxxxx
    NEU:
    SPRT_SendText (34375,$str9);

Geht das serielle Senden schon nicht? Empfangen kommen die Daten zerstückt (daran kann man arbeiten) oder total kaputt? Dann liegt es eher an der Schnittstelle.

Grundsätzlich hatte ich bisher unter Linux weniger Probleme mit den RS232<>USB Adaptern als unter Windows.

Das senden geht da Kommandos schicken funktioniert.

Nur Stati Pollen - da kommt alles durcheinander an.

Habe gerade noch so ein RS233 to TTL board bestellt - Ggf hilft das direkt am GPIO?

Wie schon im anderen Thema geschrieben (bitte entscheide dich jetzt in welchen es weitergeht!) ist das kein Garant das es besser läuft!
Es ist vollkommen normal das die unterschiedlichen OS bzw HW (RPi, x64) den Stream stückweise durchreichen.
Das kann auch z.b. am Empfangsbuffer des OS oder einfach der Taktung liegen.

Eine korrekte Implementierung im Script oder ein entsprechender Cutter sind da unerlässlich.
Versuche den Cutter Mal auf Startzeichen Hex 02 1F 1F 02 und/oder Endzeichen 1B 03 einzustellen.
Außerdem Timeout auf 1 oder 10.
Damit auch die einzelnen ACK durchkommen.
Das Ergebnis siehst du im Debug der RegisterVariable.
Musst dann im Script nur bedenken, dass die Trennzeichen des Cutter nicht im Script landen. Diese werden vom Cutter entfernt.
Michael

Moin,

also ich glaube wirklich was bringen wird es erst wenn ich alles in einzelne HEX Werte zerlege dann, da zum Teil von diesem >40 HEX code nur zb „02 1F“ ankommen gefolgt von dem Rest.

Sowie jetzt ist eine verlässliche Auswertung fast unmöglich.

Ich gucke mal nachher was der RS232 zu TTL Wandler so bringt wenn der ankommt und dann schaue ich weiter.

VG

Ich habs - es liegt an der Einstellung der seriellen Schnittstelle.
Mit der min Zeichenlänge klappt es - ggf war die free floating oder so vorher.

„stty -F /dev/ttyUSB0 speed 19200 cs8 -cstopb -parenb min 40“

Help:
„min N mit -icanon, N Zeichen Minimum für ein vollständiges Lesen setzen“

Wir haben dir jetzt mehrmals gesagt, dass du das entsprechend zusammenbauen musst. Hierfür gibt es den Cutter bzw. man kann es auch selbst im Script lösen. Und du hast schon 90% der Dinge dafür im Script eingebaut. Das befüllen der Register Variable mit SetBuffer ist genau dafür da.

Dich auf die Schnittstelle zu verlassen, ist doof. Und die Mindestlänge auf 40 zu stellen, ist auch doof. Denn wie kommen damit kurze „ACK“ an?