Ich zweifle an mir selbst

Hallo an alle,

ich verzweifle gerade an einem simplen Codestück. Ein Script bei mir speichert zyklisch die Daten in verschiedene RRD-Datenbanken. Hat einwandfrei funktioniert bis ich vor ein paar Tagen wieder eine neue Datenbank hinzugefügt habe. Seither spinnt das ganze.

Ich habe jetzt testweise den Code drastisch reduziert und im Prinzip kommt heraus: Eine For-Schleife mit 2 Durchgängen. In jedem Durchgang wird über eine 2.Schleife 13x die gleiche Variable ausgelesen und der Inhalt an einen String angehängt. Danach wird der String an die RRD-Datenbank zum Speichern übergeben.

Im 1. Durchgang geht alles ok und RRD bringt keine Fehler, im 2. Durchgang funktioniert GetValue() nicht mehr richtig. Es werden einfach Doppelpunkte irgendwo im Text hinzugefügt. Ich komme einfach da nicht weiter. Habs auf 2 Systemem probiert. Wichtig ist scheinbar auch der Variableninhalt. Eine Float-Var mit 390.0

Bitte hinterfragt nicht den Sinn des Codes. Wie gesagt: In Wirklichkeit sieht das ganz anders und komplizierter aus. Funktioniert aber trotzdem nicht.

Hier mal der Code zum Anlegen der RRD-DB

	$startzeit = mktime(0,0,0,date("m"),date("d"),date("Y"));

	$para1 = "create Anspeisung.rrd --start ".$startzeit." --step 300 ";
	$para = "DS:EB_SUM:GAUGE:600:0:200000 ";
	$para .= "DS:EL_SUM:GAUGE:600:0:200000 ";
	$para .= "DS:I_L1:GAUGE:600:-100:100 ";
	$para .= "DS:I_L2:GAUGE:600:-100:100 ";
	$para .= "DS:I_L3:GAUGE:600:-100:100 ";
	$para .= "DS:I_SUM:GAUGE:600:-100:100 ";
	$para .= "DS:P_L1:GAUGE:600:-20000:20000 ";
	$para .= "DS:P_L2:GAUGE:600:-20000:20000 ";
	$para .= "DS:P_L3:GAUGE:600:-20000:20000 ";
	$para .= "DS:P_SUM:GAUGE:600:-20000:20000 ";
	$para .= "DS:U_L1:GAUGE:600:0:1000 ";
	$para .= "DS:U_L2:GAUGE:600:0:1000 ";
	$para .= "DS:U_L3:GAUGE:600:0:1000 ";
	$para .= "RRA:AVERAGE:0.5:1:8640 ";   //30 Tage alle Werte
	$para .= "RRA:AVERAGE:0.5:288:1825 ";  //5 Jahre Tages-Mittelwert
	$para .= "RRA:MAX:0.5:288:1825 ";  //5 Jahre Tages-Maxwert
	//Database anlegen
	echo RRD_Execute($para1.$para);

Und hier mein Testskript

		For ($x=1; $x <3;$x++)
	{
		echo "Durchlauf ".$x." Start
";
		$para = "update "."rrd_data/Anspeisung.rrd N";

		for ($y=1;$y < 14;$y++)
		{

		   //Wert hinzufügen
		   $value = GetValue(15943 /*[System\Dummy]*/); //Float-Variable mit Inhalt 390.00
		   echo $value."
";
		   
		   $para .= ":".$value;

		}
		echo $para."
";
		//Schreibe in Datenbank
	 	echo RRD_Execute($para);
		echo "Durchlauf ".$x." Ende 

";

	}


Und hier die Ausgabe des Skrip:

Durchlauf 1 Start
390
390
390
390
390
390
390
390
390
390
390
390
390
update rrd_data/Anspeisung.rrd N:390:390:390:390:390:390:390:390:390:390:390:390:390
Durchlauf 1 Ende 

Durchlauf 2 Start
38:
38:
38:
38:
38:
38:
38:
38:
38:
38:
38:
38:
38:
update rrd_data/Anspeisung.rrd N:38::38::38::38::38::38::38::38::38::38::38::38::38:
ERROR: expected 13 data source readings (got 26) from N:38::38::38::38::38::38::38::38::38::38::38::38::38:
Durchlauf 2 Ende 

wie man sieht, wird im 2. Durchlauf nicht 390 aus der Var ausgelesen sondern 38:

Wenn das noch wer anders reproduzieren kann, bin ich zumindest sicher, dass mein IPS nicht irgendwo inkonsistent ist.

Wäre echt dankbar für Tipps

Rubberduck

ich hatte auch mal diese Probleme - meine mich an folgendes zu erinnern:

  1. Fehler kommt von rrd - der Aufruf (bzw. die Vewendung der entsprechenden dll) scheint irgendwas in IPS zu zerschiessen
  2. Bin dem Problem mit Typ Konvertierungen beigekommen - sprich, die Daten, die in die rrd Datenbak eingetragen werden vor dem Zusammenbauen im Kommandostring auf einen Typ explizit casten. Ich glaube, ich habe sie seinerzeit auf „string“ gecasted, wobei man noch mit „.“ und „,“ bei floats aufpassen muss.

Übrigens liefert - zumindest bei mir - rrd_execute TRUE bei Fehler und FALSE bei success zurück …

Finde es schade, dass mittlerweile rrd so stiefmütterlich in IPS behandelt wird - finde es, wenn auch komplexer, erheblich leistungsfähiger als die eingebauten Graphen.

Good luck
darx

Du hast recht! Lasse ich rrd_execute weg, läuft der Rest einwandfrei:confused:

Hoffe paresy liest das und kann mir einen Tipp dazu geben:)

Stimme dir voll zu. RRD ist zwar etwas kompliziert, aber dafür super schnell.

Rubberduck

Hi Erich,

ich hab zwar keine Erfahrungen mit RDD, aber irgend wie erinnert mich das an die Problematik bei der Verwendung der seriellen Schnittstelle:

„Bitte verwenden Sie den Buffer…, weil…“

versetzt mich irgendwie in die Zeit der Programmierung des C64 (Tokens) und erweckt den Eindruck,

als wenn IPS intern bei bestimmten „ASCII Werten“ mit Kurzbefehlen arbeitet anstatt der gelieferten Werte.

Nur so´ne blöde Idee kurz vor High-Noon.

mfg

Bernd

@rubberduck

schau mal, was passiert, wenn Du

$para .= ":".$value;

durch

$para .= ":".(string)$value;

ersetzt

Das mit (string) hilft leider auch nicht.

Hier eine noch vereinfachtere Version ohne Schleife:

		$cmd = "update "."Anspeisung.rrd N";


	   //Wert holen
	   $value = GetValue(15943 /*[System\Dummy]*/); //Float-Variable mit Inhalt 390.00
	   echo $value."
";
	   
		//Schreibe in Datenbank
	 	echo RRD_Execute($cmd.":".(string)$value);

	   //Wert holen
	   $value = GetValue(15943 /*[System\Dummy]*/); //Float-Variable mit Inhalt 390.00
	   echo $value."
";

		//Schreibe in Datenbank
	 	echo RRD_Execute($cmd.":".(string)$value);

Und das Script für die RRD-Datenbankerstellung:

	$startzeit = mktime(0,0,0,date("m"),date("d"),date("Y"));

	$para1 = "create Anspeisung.rrd --start ".$startzeit." --step 300 ";
	$para = "DS:EB_SUM:GAUGE:600:0:20000 ";
	$para .= "RRA:AVERAGE:0.5:1:8640 ";   //30 Tage alle Werte
	$para .= "RRA:AVERAGE:0.5:288:1825 ";  //5 Jahre Tages-Mittelwert
	$para .= "RRA:MAX:0.5:288:1825 ";  //5 Jahre Tages-Maxwert
	//Database anlegen
	echo RRD_Execute($para1.$para);

Nach dem Ausführen des RRD_Execute funktioniert einfach das Get_Value nicht mehr! Aber nur bei bestimmten Werten: Steht in der VAR zB 120 oder 389 oder 391 geht es, bei 390 nicht!!!

Rubberduck

Hallo,

Mein Problem tritt auch auf, wenn ich ein externes Programm über IPS-ExecuteEx starte. Aber nur, wenn der Variableninhalt genau 390 ist.

Kann bitte jemand kurz mal das unten angeführte Script bei sich ausprobieren und mir sagen, ob bei ihm auch beim zweiten Auslesen der Variable ein falscher Output kommt.



		$var_dummy = IPS_CreateVariable(2);
		SetValue($var_dummy,390);
		
		ips_sleep(100);

	   //Wert holen
	   $value = GetValue($var_dummy);
	   echo "1. Auslesen der Variable. Inhalt: ".$value."
";
	   
	   //Aufruf irgend eines externen Programmes
      IPS_ExecuteEx("ips_tray.exe","",false,false,0);

	   //Wert holen
	   $value = GetValue($var_dummy);
	   echo "2. Auslesen der Variable. Inhalt: ".$value."
";

      IPS_DeleteVariable($var_dummy);


Mein Output in der Skriptausgabe:

1. Auslesen der Variable. Inhalt: 390
2. Auslesen der Variable. Inhalt: 38:

Danke
Rubberduck

Ich habe keine Ahnung von RDD … also bitte um Nachsicht …

Der Fehlerteil

ERROR: expected 13 data source readings (got 26)

Riecht mir danach, als wäre irgendein Buffer nicht geleert worden und die alten 13 Werte stehen da noch drin und die neuen 13 werden dran gehängt.

Gibt es sowas wie einen „Buffer Flush“?

Würde aus dem Bauch raus mal folgendes (testweise) probieren:

Zwei separate Scripte.

Eins, das ausliest und die Werte zusammenbaut und eins, das zurückschreibt.

Wenn es Bufferproblem ist, könnte das helfen, weil ja bei jedem Schreiben ne neue Instanz im PHP rennt und damit eigentlich (wenn es nicht im Treiber hängt) der Buffer leer sein müsste.

Und dass es ein Timing-Problem ist, und Dein GetValue zu schnell kommt, ist ausgeschlossen?

jwka

Hallo jwka,

probier bitte mal das Script von vor 5 Minuten. Das ist ganz ohne RRD. Es wird nur einmal ein externes Programm aufgerufen.

Danke
Rubberduck

1. Auslesen der Variable. Inhalt: 390

Warning:  There were no token found for specified session: 0 in [Test\Test] on line 12
2. Auslesen der Variable. Inhalt: 390

Servus

produziert auch hier den gleichen Fehler.
Da hast demnach scheinbar irgendwas mit IPS.

Läßt man di
IPS_ExecuteEx(„ips_tray.exe“,"",false,false,0);
Zeile weg funktionierts.

gruß
bb

Na dann bin ich ja froh, dass es nicht nur bei mir einen Fehler produziert.

Mittlerweile hab ich auch schon herausgefunden, dass der Fehler auch bei 17, 19, 29, 170, 190 und 290 kommt. Ist schon irgendwie seltsam.

Deklariert man die Variable als String, macht es keine Probleme. Ich werde mal eine Fehlermeldung einbringen. (Edit: Hier der Link zur Fehlermeldung: http://www.ip-symcon.de/forum/project.php?issueid=871)

Danke
Rubberduck

Ich habe das mal ausprobiert.

Kriege auch den Fehler. Jetzt Festhalten:

Wenn ich einen Integer-Wert anlege, IPS_CreateVariable(1), dann kriege ich die korrekten Werte zurück. DAs muss wohl was mit FLOAT zu tun haben … (???)

jwka

Ich muss mir den Fehler mal genauer ansehen. Die Funktion scheint irgendwelche Speicherbereiche zu überschreiben, die es nicht beschreiben dürfte.

paresy