Hilfe beim Script

Gegeben sind Daten über RS232.

Die Daten werden korrekt eingelesen über Comport-CutChar-RegisterVariable.

Daten sind Tempdaten und Alarmmeldungen von einem MC.

Auswertung erfolgt über ein Script, wobei die Tempdaten ohne Probleme eingelesen und auch ausgewertet werden. Im Gegensatz zu den Alarm werten.

Hier mal der Code zum einlesen.

<?
/*
*******************************
 IP-SYMCON Event Scripting
*******************************
File     : Daten_Temp_Alarm.ips.php
Trigger  : OnUpdate Daten_Temp
Interval : 
*/

//------------------------------------------------------------------------------
//Alle Daten werden im ASCII-Format empfangen. Tempwerte mit aktueller
//Temperatur, Alarmwerte mit aktuellem Zustand. 1 = geschlossen, 0 = offen.
//
//Die Datenübertragung erfolgt im Sekundentakt, wobei die Alarmkontakte
//Vorrang haben.
//Das heisst, je mehr Tempsensoren angeschlossen sind(max16)
//umsolänger dauert die Übertragung, sollte ein Alarmkontakt zwischen melden,
//verschiebt sich das ganze.(Alarm hat Vorrang) um 1 Sek.
//
//Jeder Temperaturwert ist ein eigenes Datenpaket Abschluss je wert (CR).
//Die Alarmeingänge A-D sind ein Datenpaket, wobei je Wert ein (CR) erfolgt.
//
//
//------------------------------------------------------------------------------

 //Dateneingang von Registervariable
 $Daten = GetValueString ("Daten_Temp");

 //Einlesen der Daten in ein Array
 //Temperaturdaten je Temperaturwert ein Datenpaket, z.B. 1: 22.9CR, 2: 23.9CR
 $buffer_temperatur1 = array();
 $buffer_temperatur2 = array();
 $buffer_temperatur3 = array();
 
 //Kennung nach Trennzeichen.
 $separator_temperatur1 ="1: ";
 $separator_temperatur2 ="2: ";
 $separator_temperatur3 ="3: ";
 
 //Alarmdaten, alle 4 Werte sind ein Datenpaket, z.B. A:1CR B:0CR
 $buffer_Alarm1      = array();
 $buffer_Alarm2      = array();
 $buffer_Alarm3      = array();
 $buffer_Alarm4      = array();

 $separator_Alarm1      ="A:";
 $separator_Alarm2      ="B:";
 $separator_Alarm3      ="C:";
 $separator_Alarm4      ="D:";
 
 //Array nach Kennung aufteilen
 $buffer_temperatur1 = explode ($separator_temperatur1, $Daten);
 $buffer_temperatur2 = explode ($separator_temperatur2, $Daten);
 $buffer_temperatur3 = explode ($separator_temperatur3, $Daten);
 $buffer_Alarm1      = explode ($separator_Alarm1, $Daten);
 $buffer_Alarm2      = explode ($separator_Alarm2, $Daten);
 $buffer_Alarm3      = explode ($separator_Alarm3, $Daten);
 $buffer_Alarm4      = explode ($separator_Alarm4, $Daten);
 
 //Daten nach Trennung und Aufteilung zuordnen
 $temperatur1 = $buffer_temperatur1[1];
 $temperatur2 = $buffer_temperatur2[1];
 $temperatur3 = $buffer_temperatur3[1];
 $Alarm1      = $buffer_Alarm1[1];
 $Alarm2      = $buffer_Alarm2[1];
 $Alarm3      = $buffer_Alarm3[1];
 $Alarm4      = $buffer_Alarm4[1];

 //Daten zuteilen und umrechnen
 $temperatur1 = (float) $temperatur1;
 $temperatur2 = (float) $temperatur2;
 $temperatur3 = (float) $temperatur3;
 $Alarm1      = (integer) $Alarm1;
 $Alarm2      = (integer) $Alarm2;
 $Alarm3      = (integer) $Alarm3;
 $Alarm4      = (integer) $Alarm4;
  
 // Daten ausgeben
 SetValueFloat ("T1", $temperatur1);
 SetValueFloat ("T2", $temperatur2);
 SetValueFloat ("T3", $temperatur3);

 SetValueInteger ("A1", $Alarm1);
 SetValueInteger ("A2", $Alarm2);
 SetValueInteger ("A3", $Alarm3);
 SetValueInteger ("A4", $Alarm4);
  
?>

und zum Verarbeiten

<?
/*
*******************************
 IP-SYMCON Event Scripting
*******************************
File     : Temperatur_1Wire.ips.php
Trigger  :  OnChange Temp....................
Interval : 
*/


$T1 = GetValueFloat("T1");
$T2 = GetValueFloat("T2");
$A1 = GetValueInteger("A1");


SetValueInteger("Alarm1", $A1);

if($T1 == 0)
{
$T1 == $T1;
}
else
{
SetValueFloat("Temp1", $T1);
}

if($T2 == 0)
{
$T2 == $T2;
}
else
{
SetValueFloat("Temp2", $T2);
}


?>

Wo ist mein Fehler im Kopp :slight_smile:

Eingang RS 232

alarm_temp.png

Hallo RWN,

wo liegt genau Dein Problem, im Script kann ich auf die schnelle keinen Fehler sehen, im String kommt beim ersten Alarmwert eine 1 raus und die sollte am Ende in Alarm1 stehen, tut sie das denn nicht?

Gruß Thomas

Hi Thomas,

warts ja schnell.

Hab was vergessen.

Die Daten kommen alle im 1Sec Takt ein im Paket.

Außer die Alarmdaten. Alle 4 Alarmdaten sind ein Paket im 1 Sek-Takt, Also je 250 ms.
Das erkennt das Array anscheinden nicht.
Ich vermute eher, meine Programmierung passt nicht, nur wo, ich such schon fast 5 Tage wegen dem Mist.

Möglicherweise hier:


if($T1 == 0) // das ist ein Vergleich . 
//Warum darf die Temperatur nicht 0 sein? dann besser auf exists im Array testen, um zu sehen, ob was dabei ist
{ 
$T1 == $T1; // hier aber auch!!
//eine Zuweisung mit nur einem "=" macht aber genauso wenig Sinn
} 

Edit:

Eines fällt mir noch ein:
Eine andere Quelle liegt in den Daten selber.
Wird die Daten IPS-Variable mit Append gefüllt? wenn ja,wird sie nach dem lesen eines Blockes wieder geleert?
Wenn alle Alarm-Blöcke in einem String liegen, muss man erst die Teilblöcke auf <cr> splitten . Dann kann man die Ergebnisse wie gewohnt weiter verarbeiten.

Tommi

Wird das Script dann aller 250ms getriggert oder kommen die Alarmdaten mit einem Paket jede Sec. 1 x ?

Gruß Thomas

Hallo Tommi,

das liegt leider an meiner beschränkten Beschreibung.

Sorry. Die Tempdaten funktionieren alle perfekt, nur die Alarmeingänge nicht.

Das liegt aber auch daran, das die Daten alle wieder von 0 anfangen.

Deswegen sichere ich die Daten mit dem 2ten Script.

Sonsrt würde mir bei jeden Durchlauf eine 0 erscheienn.

Deswegen. denke ich, hab ich irgendwo den Hund begraben.

Hi Thomas,

Wird das Script dann aller 250ms getriggert oder kommen die Alarmdaten mit einem Paket jede Sec. 1 x ?

Ich hab mir ja schon Mühe gegeben das Script zu erläutern.

Alle Daten kommen im 1sec-Takt. von der Registervariable.

Ist denn eine so kurze Auflösung notwendig, oder kann das Script nicht mit einem Semaphore geschützt werden, nur so ne Idee, vieleicht verschluckt er sich beim bearbeiten der Daten?

Thomas

Verschlucken ist gut, Daran hatte ich auch schon gedacht.

Zumal ja die Daten vom Alarm je Port innerhalb 1sek ankommen x4 ,also 250 ms.

Ups anderts rum innerhal 1 Sek kommen 4 Daten an. also je 250ms. Ein Datenpaket.

Hallo Rainer,

um Dein Skript zu testen mach bitte folgendes:

  1. Stoppe den Trigger für die Registervariable!
  2. Vergewissere dich, dass sowohl Temperatur- als auch Alarmmeldungen in der Registervariablen stehen. Wenn nicht, dann ändere die Variable entsprechend von Hand.
  3. Füge ein paar „echo“-Befehle in die verschiedenen Abarbeitungsphasen ein und lass Dir die Alarmvariablen anzeigen.
  4. Führe Dein Skript per Execute aus.

Jetzt solltest Du in der Lage sein festzustellen ob das Skript korrekt läuft, bzw. an welcher Stelle es hakt.

Dein Skript ist so ausgelegt, dass es immer auch die Alarmmeldungen abfragt, auch dann, wenn gar keine vorhanden sind. Ich vermute, dass Du deshalb leere Variablen bekommst.

Gruß
HJH

Hallo Hans-Jörg,

  1. Stoppe den Trigger für die Registervariable!
  2. Vergewissere dich, dass sowohl Temperatur- als auch Alarmmeldungen in der Registervariablen stehen. Wenn nicht, dann ändere die Variable entsprechend von Hand.

alles schon gemacht. Auch deine Vorschläge. nichts.

  1. Führe Dein Skript per Execute aus.

Jetzt solltest Du in der Lage sein festzustellen ob das Skript korrekt läuft, bzw. an welcher Stelle es hakt.

Zig mal gemacht.

Undefinend offset:1

offset bezieht sich auf temp1= buffer_temp[1].

Nur ist das ja das auslesen des arrays.

wie bekomme ich die meldungen von ips hierein.?

Nix copy paste

Hallo Rainer,

wie ich schon sagte: wenn keine Alarmmeldungen kommen, ist das Array natürlich leer und somit gibt es kein Element 1 (offset 1).

Du darfst Alarmmeldungen nur dann bearbeiten, wenn auch welche da sind.

Es ist also noch eine zusätzliche Abfrage nötig.

Gruß
HJH

Naja, die Meldungen sind ja da,

ich versteh es einfach nicht.

Zumal ich dieses Script schon 3 mal erfolgreich einsetzt, nur das da halt die Daten nicht im Sekundentakt reinkommen.

:confused: :confused: :confused:

Hallo Rainer,

ich möchte jetzt von Dir wissen:
was steht in der internen Variablen $Alarm1 und
was steht in der externen Variablen „A1“.

Gruß
HJH

Also wenn das Script aller 250ms durch einen Alarmwert getriggert wird und wie im oben gezeigten Bild jeder Alarmwert durch die gleiche Variable abgefragt wird, ist es ja klar das Undefinend offset:1 auftritt, weil ja auch immer nur ein Alarmwert in das Array geschrieben wird und die anderen dann leer sind.
Was ist wenn Du mal in das Script am Anfang schreibst:


 if ($Run) // Mehrfaches Triggern in kurzer Zeit verhindern
 {
 return;
 }

und ins zweite Script am Ende ein:


SetValueBoolean("Run", false);

Gruß Thomas

ich möchte jetzt von Dir wissen:
was steht in der internen Variablen $Alarm1 und
was steht in der externen Variablen „A1“.

Umgekehrt. egal. 0.

es muss 1 drinn stehen

es läuft alles im sekunden Takt ab, sieht man ganz deutlich. Die Alarmeingänge auch, es sind halt nur 4 Ein Datenpaket !!!

Also wenn das Script aller 250ms durch einen Alarmwert getriggert wird und wie im oben gezeigten Bild jeder Alarmwert durch die gleiche Variable abgefragt wird, ist es ja klar das Undefinend offset:1 auftritt, weil ja auch immer nur ein Alarmwert in das Array geschrieben wird und die anderen dann leer sind.
Was ist wenn Du mal in das Script am Anfang schreibst:

Hallo Rainer,

Deine Temperaturwerte kommen jede Sekunde.

Manchmal kommt auch eine Alarmmeldung, normalerweise aber keine.

Wenn aber eine Alarmmeldung kommt, dann wird sie in der nächsten Sekunde, wenn wieder eine Temperaturmeldung kommt, wieder überschrieben.

Daher bekommst Du die Alarme nicht mit.

Ich sage es nocheinmal: Du musst vor der Verarbeitung der Alarmwerte erst abfragen, ob überhaupt Alarmwerte gekommen sind!

Gruß
HJH