Xero Macro: Unterschied zwischen den Versionen

Aus Amium_Wiki
Wechseln zu: Navigation, Suche
(Macro - macro / macro_end)
 
(4 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
{{todo|Conditional Macros}}
 
 
  
 
=== Normnamen ===
 
=== Normnamen ===
Zeile 64: Zeile 62:
 
Der <tt>this</tt> Operator wird bei der Macroabarbeitung durch den Normnamen des aktuellen Moduls ersetzt
 
Der <tt>this</tt> Operator wird bei der Macroabarbeitung durch den Normnamen des aktuellen Moduls ersetzt
  
{{todo|marq: Ein Beispiel wäre noch toll}}
+
 
 +
Beispiel:
 +
 
 +
Module (bzw. dessen Werte/Parameter) werden in der XERO immer im Haupt-Schema ("root") ''gesucht''. Verwendet man z.B. die Referenz <tt>THC</tt> so wird das Modul "THC" im Hauptschema referenziert (sofern es vorhanden ist).
 +
Befindet sich das Modul "THC" jetzt in einem übergeordneten ("Parent") Modul, so muss es mit <tt>FID.THC</tt> angesprochen werden.
 +
 
 +
Um einen Wert/Parameter eines Moduls in einem Macro innerhalb dieses Moduls zu referenzieren (z.B. den Parameter "Status") müsste man nun jedes mal den gesamten ''Pfad'' dieses Moduls in der Arena angeben, also z.B.:
 +
:<tt>THC.Status = Ready</tt>
 +
oder
 +
:<tt>FID.THC.Status = Ready</tt>
 +
 
 +
 
 +
Um dies zu vermeiden, kann/soll der "this" Operator verwendet werden, welcher immer das aktuelle Modul referenziert (egal wo in einem ''Pfad'' sich das Modul befindet):
 +
:<tt>this.Status = Ready</tt>
 +
 
  
 
==== 'parent' Operator ====
 
==== 'parent' Operator ====
 
Der <tt>parent</tt> Operator wird bei der Macroabarbeitung durch den Normnamen des Übergeordneten Moduls ersetzt
 
Der <tt>parent</tt> Operator wird bei der Macroabarbeitung durch den Normnamen des Übergeordneten Moduls ersetzt
  
{{todo|marq: Ein Beispiel wäre noch toll}}
 
  
==== Macro - macro / macro_end ====
+
Beispiel:
  
{{todo|marq: Bitte ein Beispiel für alle Unterpunkte ergänzen}}
+
Annahme ist ein Modul "FID" welches zwei (Sub-)Module zur Messung von THC und CH4 liefert. Will man nun z.B. die beiden Messwerte verknüpfen, würde man dazu z.B. ein Modul CalculatedValue "CV_SUM" verwenden:
 +
 
 +
[[Datei:Macro_example_parent_operator.png|400px]]
 +
 
 +
Da sich alle Module auf gleicher Ebene (im Modul M_1) befinden, sind die Module "THC" und "CH4" aus Sicht von "CV_SUM" in dessen "parent" zu finden. Somit ist THC aus Sicht von CV_SUM über "<tt>parent.THC</tt>" anzusprechen!
 +
 
 +
Im Screenshot oben ist die verwendete Formel für den CalculatedValue ersichtlich:  
 +
:<tt>{parent.THC} + {parent.CH4}</tt>
 +
 
 +
 
 +
Dies gilt natürlich auch für ein Macro im Modul "CV_SUM": will man darin das Modul "THC" referenzieren, so kann man dies über den "parent" operator machen:
 +
:<tt>THC_inPercent = {parent.THC} / 10000</tt>
 +
 
 +
 
 +
Falls sich das Modul "M_1" im Haupt-Schema ("root") befinden würde, könnte man obiges auch durch
 +
:<tt>THC_inPercent = {M_1.THC} / 10000</tt>
 +
ersetzen.
 +
 
 +
 
 +
Sobald dieses Modul jedoch in anderen Modulen verwendet wird, müssten jeweils die Referenzen angepasst werden:
 +
:<tt>THC_inPercent = {NEW_MODULE.M_1.THC} / 10000</tt>
 +
:<tt>THC_inPercent = {SOME_OTHER_MODULE.M_1.THC} / 10000</tt>
 +
 
 +
 
 +
Die Verwendung von "parent" löst dieses Problem auf einfache Weise!
 +
 
 +
 
 +
 
 +
==== Macro - macro / macro_end ====
  
 
*<tt>macro [Macroname]()</tt>
 
*<tt>macro [Macroname]()</tt>
 
:Beginn eines Macros
 
:Beginn eines Macros
  
*<tt>endmacro</tt>
+
*<tt>macro_end</tt>
 
:Ende des Makroblocks
 
:Ende des Makroblocks
  
*<tt>hideif</tt>
+
:Beispiel:
:Sichtbarkeit in Abhängigkeit des Modulstatus (Status)
+
<div style="margin-left: 2em;">
 +
<tt>
 +
  macro SetReady()  
 +
      this.Status = Ready
 +
  macro_end
 +
</tt>
 +
</div>
 +
 
  
 
*<tt>showif</tt>
 
*<tt>showif</tt>
 
:Sichtbarkeit in Abhängigkeit des Modulstatus (Status)
 
:Sichtbarkeit in Abhängigkeit des Modulstatus (Status)
 +
 +
:Beispiel:
 +
<div style="margin-left: 2em;">
 +
<tt>
 +
  macro this.Purge()
 +
      this.ShowIf = "Purge, Ready"
 +
  macro_end
 +
</tt>
 +
</div>
 +
 +
:In diesem Beispiel wird der Macrobutton "Purge" nur angezeigt, falls sich das System gerade in "Purge" oder "Ready" befindet.
 +
 +
 +
*<tt>hideif</tt>
 +
:Sichtbarkeit in Abhängigkeit des Modulstatus (Status)
 +
 +
:Der Befehl <tt>hideif</tt> verhält sich genau umgekehrt - d.h. ein Macrobutton wird bei den angegebenen System-Stati nicht angezeigt.
 +
 +
:Beispiel: siehe <tt>showif</tt>
 +
  
 
*<tt>Access</tt>
 
*<tt>Access</tt>
 
:Sichtbarkeit in Abhängigkeit des Zugriffslevel
 
:Sichtbarkeit in Abhängigkeit des Zugriffslevel
 +
:Soll ein Macrobutton nur für spezielle Benutzer-Rollen (Service, Admin) sichtbar sein, so kann dies mit <tt>Access = Service</tt> bzw. <tt>Access = Admin</tt> erreicht werden.
  
*<tt>Process</tt>
 
:<tt>Process = direct</tt> &rarr; Macro wird sofort aufgerufen - ohne Rückfrage, falls ein Macro bereits läuft
 
  
 
*<tt>Process</tt>
 
*<tt>Process</tt>
 +
:Mit dem Befehl <tt>Process</tt> kann in einem Macro definiert werden, wie sich das Macro verhält, falls zum Zeitpunkt des Macro-Aufrufes bereits ein Macro läuft:
 +
:<tt>Process = direct</tt> &rarr; Macro wird sofort aufgerufen - ohne Rückfrage, falls ein Macro bereits läuft
 
:<tt>Process = simultaneous</tt> &rarr; Macro wird parallel zu einem bereits laufenden Macro ausgeführt
 
:<tt>Process = simultaneous</tt> &rarr; Macro wird parallel zu einem bereits laufenden Macro ausgeführt
 
*<tt>macroend</tt>
 
:Ende des Makroblocks
 
  
  
Beispielmacro: Standby
+
:Beispielmacro mit allen obigen Befehlen:
 
<div style="margin-left: 2em;">
 
<div style="margin-left: 2em;">
 
<tt>
 
<tt>
 
   macro Standby()  
 
   macro Standby()  
 +
      this.ShowIf = "Purge, Ready"
 +
      this.Access = "Service"
 +
      this.Process = simultaneous
 +
      ...
 +
      delay(2s)
 +
      this.Status = Ready
 
       ...
 
       ...
      ...
 
 
   macro_end
 
   macro_end
 
</tt>
 
</tt>
 
</div>
 
</div>
 +
  
 
Es wird '''dringend empfohlen''', dass das <tt>Ready()</tt>-Macro in jedem Modul inkl. Hauptfenster (Main) zu integrieren.<br/>  
 
Es wird '''dringend empfohlen''', dass das <tt>Ready()</tt>-Macro in jedem Modul inkl. Hauptfenster (Main) zu integrieren.<br/>  
Zeile 114: Zeile 184:
 
Es empfiehlt sich auch bei umfangreichen Macroabläufen (Testsequenzen) am Beginn bzw. am Ende dieser Macrosequenz das <tt>'Ready()'</tt>-Macro des Hauptfenster (Main)aufzurufen, damit ein definierter Zustand am Beginn der Macroabarbeitung bzw. ein definierter Zustand am Ende der Macroabarbeitung herrscht.<br/>
 
Es empfiehlt sich auch bei umfangreichen Macroabläufen (Testsequenzen) am Beginn bzw. am Ende dieser Macrosequenz das <tt>'Ready()'</tt>-Macro des Hauptfenster (Main)aufzurufen, damit ein definierter Zustand am Beginn der Macroabarbeitung bzw. ein definierter Zustand am Ende der Macroabarbeitung herrscht.<br/>
 
Grundsätzlich sollte das <tt>'Ready()'</tt>-Macro des Hauptfenster (Main) einen definierten Zustand des Hauptfensters herstellen bzw. die <tt>'Ready()'</tt>-Makros der Untermodule aufrufen (&rarr; hierarchische/rekursive Abarbeitung), die Untermodule rufen wiederum die <tt>'Ready()'</tt>-Macros deren Untermodule auf, usw.<br/>
 
Grundsätzlich sollte das <tt>'Ready()'</tt>-Macro des Hauptfenster (Main) einen definierten Zustand des Hauptfensters herstellen bzw. die <tt>'Ready()'</tt>-Makros der Untermodule aufrufen (&rarr; hierarchische/rekursive Abarbeitung), die Untermodule rufen wiederum die <tt>'Ready()'</tt>-Macros deren Untermodule auf, usw.<br/>
 +
  
 
==== Empfohlene Standard Macronormnamen für Prüfstandautomatisierung, allg. Messtechnik, Analysatoren und Messanlagen ====
 
==== Empfohlene Standard Macronormnamen für Prüfstandautomatisierung, allg. Messtechnik, Analysatoren und Messanlagen ====
Zeile 222: Zeile 293:
  
 
=== Default Macroaufrufe ===
 
=== Default Macroaufrufe ===
 +
 +
{{todo|marq: Ist das so umgesetzt? Wird das entsprechende Makro, z.B. Main.Exit automatisch beim schließen der XERO ausgeführt. Wenn es vorhanden ist? Muss, es zuvor angelegt werden? Sind noch weitere Einstellungen vorzunehmen. Bitte ergänzen!}}
 +
 +
 
Standardaufruf beim Starten der XERO Software
 
Standardaufruf beim Starten der XERO Software
 
<div style="margin-left: 2em;">
 
<div style="margin-left: 2em;">
Zeile 264: Zeile 339:
 
</tt>
 
</tt>
 
</div>
 
</div>
 
  
 
=== Zuweisung ===
 
=== Zuweisung ===

Aktuelle Version vom 3. Dezember 2014, 11:03 Uhr

Normnamen

Jedes Modul einer Anlage (=Arena) ist eindeutig über seinen hierarchischen aufgebauten (Norm-)Namen identifizierbar. Alle Module des Hauptfensters (=Root) sind direkt über ihren Namen adressierbar ("RootModul").

Ein Modul "innherhalb" eines Root-Moduls wird über "RootModul.SubModul" adressiert.

Da auch jeder "Wert" bzw. "Parameter" eines Moduls von einem Modul repräsentiert wird, werden diese Werte ebenfalls durch einen Punkt vom übergeordneten "Parent" Modul getrennt.


Beispiel:

Eine Arena besteht aus einem FID und einem FlowController (FC).

Der FID besitzt eine Messkomponente TCH.

Dieser wiederum hat einen Wert für das Spangas (=Kalibriergas); somit kann dieser Spangaswert über

FID.THC.Spangas

angesprochen werden.

Bei der [Macroprogrammierung] gilt zusätzlich die Vereinbarung, dass das "eigene" Modul (also das Modul welches das Macro speichert) über das Prefix "this." angesprochen werden kann. Ist also beim Modul THC (im FID) ein Macro gespeichert, so kann obiger Spangaswert in diesem Macro mit

this.Spangas

angesprochen werden. Von einem Macro das im FID gespeichert ist, kann dieser Wert mit

this.THC.Spangas

erreicht werden.

Für Macros im Root-Modul gilt die Ausnahme, dass hier kein "this." vorangestellt werden darf. D.h. in obigem Beispiel wäre die Referenz

this.FID.THC.Spangas

für ein Macro im Hauptfenster ungültig! (Richtig wäre hier FID.THC.Spangas)


Macronamen und -aufruf

Ein Macro wird über

 macro MacroName()
   ...
   ...
 macro_end

definiert.

Falls der MacroName ein Präfix enthält (z.B. "FID.") so legt dieses fest, in welchem Modul das Macro angezeigt wird. Die Macrodefinition

 macro FID.Ready()
   ...

würde also bewirken, dass dieses Macro im Modulfenster des FID dargestellt wird. Ausgeführt werden kann das Macro kann allerdings von jeder beliebigen Stelle aus über "FID.Ready()".


Grundlegende Macrobefehle

'this' Operator

Der this Operator wird bei der Macroabarbeitung durch den Normnamen des aktuellen Moduls ersetzt


Beispiel:

Module (bzw. dessen Werte/Parameter) werden in der XERO immer im Haupt-Schema ("root") gesucht. Verwendet man z.B. die Referenz THC so wird das Modul "THC" im Hauptschema referenziert (sofern es vorhanden ist). Befindet sich das Modul "THC" jetzt in einem übergeordneten ("Parent") Modul, so muss es mit FID.THC angesprochen werden.

Um einen Wert/Parameter eines Moduls in einem Macro innerhalb dieses Moduls zu referenzieren (z.B. den Parameter "Status") müsste man nun jedes mal den gesamten Pfad dieses Moduls in der Arena angeben, also z.B.:

THC.Status = Ready

oder

FID.THC.Status = Ready


Um dies zu vermeiden, kann/soll der "this" Operator verwendet werden, welcher immer das aktuelle Modul referenziert (egal wo in einem Pfad sich das Modul befindet):

this.Status = Ready


'parent' Operator

Der parent Operator wird bei der Macroabarbeitung durch den Normnamen des Übergeordneten Moduls ersetzt


Beispiel:

Annahme ist ein Modul "FID" welches zwei (Sub-)Module zur Messung von THC und CH4 liefert. Will man nun z.B. die beiden Messwerte verknüpfen, würde man dazu z.B. ein Modul CalculatedValue "CV_SUM" verwenden:

Macro example parent operator.png

Da sich alle Module auf gleicher Ebene (im Modul M_1) befinden, sind die Module "THC" und "CH4" aus Sicht von "CV_SUM" in dessen "parent" zu finden. Somit ist THC aus Sicht von CV_SUM über "parent.THC" anzusprechen!

Im Screenshot oben ist die verwendete Formel für den CalculatedValue ersichtlich:

{parent.THC} + {parent.CH4}


Dies gilt natürlich auch für ein Macro im Modul "CV_SUM": will man darin das Modul "THC" referenzieren, so kann man dies über den "parent" operator machen:

THC_inPercent = {parent.THC} / 10000


Falls sich das Modul "M_1" im Haupt-Schema ("root") befinden würde, könnte man obiges auch durch

THC_inPercent = {M_1.THC} / 10000

ersetzen.


Sobald dieses Modul jedoch in anderen Modulen verwendet wird, müssten jeweils die Referenzen angepasst werden:

THC_inPercent = {NEW_MODULE.M_1.THC} / 10000
THC_inPercent = {SOME_OTHER_MODULE.M_1.THC} / 10000


Die Verwendung von "parent" löst dieses Problem auf einfache Weise!


Macro - macro / macro_end

  • macro [Macroname]()
Beginn eines Macros
  • macro_end
Ende des Makroblocks
Beispiel:

  macro SetReady() 
     this.Status = Ready
  macro_end


  • showif
Sichtbarkeit in Abhängigkeit des Modulstatus (Status)
Beispiel:

  macro this.Purge() 
     this.ShowIf = "Purge, Ready"
  macro_end

In diesem Beispiel wird der Macrobutton "Purge" nur angezeigt, falls sich das System gerade in "Purge" oder "Ready" befindet.


  • hideif
Sichtbarkeit in Abhängigkeit des Modulstatus (Status)
Der Befehl hideif verhält sich genau umgekehrt - d.h. ein Macrobutton wird bei den angegebenen System-Stati nicht angezeigt.
Beispiel: siehe showif


  • Access
Sichtbarkeit in Abhängigkeit des Zugriffslevel
Soll ein Macrobutton nur für spezielle Benutzer-Rollen (Service, Admin) sichtbar sein, so kann dies mit Access = Service bzw. Access = Admin erreicht werden.


  • Process
Mit dem Befehl Process kann in einem Macro definiert werden, wie sich das Macro verhält, falls zum Zeitpunkt des Macro-Aufrufes bereits ein Macro läuft:
Process = direct → Macro wird sofort aufgerufen - ohne Rückfrage, falls ein Macro bereits läuft
Process = simultaneous → Macro wird parallel zu einem bereits laufenden Macro ausgeführt


Beispielmacro mit allen obigen Befehlen:

  macro Standby() 
     this.ShowIf = "Purge, Ready"
     this.Access = "Service"
     this.Process = simultaneous
     ...
     delay(2s)
     this.Status = Ready
     ...
  macro_end


Es wird dringend empfohlen, dass das Ready()-Macro in jedem Modul inkl. Hauptfenster (Main) zu integrieren.
Das 'Ready()'-Macro des Hauptfenster (Main) wird im Fehlerfall standardmäßig aufgerufen (wenn es nicht implementiert ist, kann es auch nicht aufgerufen werden!).
Es empfiehlt sich auch bei umfangreichen Macroabläufen (Testsequenzen) am Beginn bzw. am Ende dieser Macrosequenz das 'Ready()'-Macro des Hauptfenster (Main)aufzurufen, damit ein definierter Zustand am Beginn der Macroabarbeitung bzw. ein definierter Zustand am Ende der Macroabarbeitung herrscht.
Grundsätzlich sollte das 'Ready()'-Macro des Hauptfenster (Main) einen definierten Zustand des Hauptfensters herstellen bzw. die 'Ready()'-Makros der Untermodule aufrufen (→ hierarchische/rekursive Abarbeitung), die Untermodule rufen wiederum die 'Ready()'-Macros deren Untermodule auf, usw.


Empfohlene Standard Macronormnamen für Prüfstandautomatisierung, allg. Messtechnik, Analysatoren und Messanlagen

  • Ready() bzw. <Modulnormname>.Ready()
→ Standby, Bereitschaft (erforderlich bei Gasanalysesystemen)
  • ECO_Mode() bzw. <Modulnormname>.ECO_Mode()
→ Pause, Stromsparmodus
  • Sample() bzw. <Modulnormname>.Sample()
→ Messen, (erforderlich bei Gasanalysesystemen)
  • SampleZero() bzw. <Modulnormname>.SampleZero()
→ Messen Nullwert, Nullgas messen
  • SampleSpan() bzw. <Modulnormname>.SampleSpan()
→ Messen Endwert, Endgas messen
  • Clean() bzw. <Modulnormname>.Clean()
→ Spülen, allgemeine Reinigung der Systems (erforderlich bei Gasanalysesystemen)
  • Adjust() bzw. <Modulnormname>.Adjust()
→ Justierung Gerat/Komponente (erforderlich bei Gasanalysesystemen)
  • AdjustZero() bzw. <Modulnormname>.AdjustZero()
→ Justierung Nullwert
  • AdjustSpan() bzw. <Modulnormname>.AdjustSpan()
→ Justierung Endwert


Bedingte Ausführung - if / if_else / if_end

  • if ([Bedingung])
Beginn einer bedingten Ausführung
→ wenn die [Bedingung] in den Klammern wahr (true) ist, dann werden die Macroanweisungen von hier bis zum Ende der bedingten Ausführung bzw. zur if_else-Anweisung ausgeführt, andernfalls übersprungen bzw. wenn ein else Zweig deklariert ist dieser ausgeführt.
  • if_else
Wenn die [Bedingung] in den Klammern unwahr (false) ist, dann werden die Macroanweisungen von hier bis zum Ende der bedingten Ausführung ausgeführt
  • if_end
Ende der bedingten Ausführung


Beispiel für die Bedingung, dass Temperaturen des Sensor 'TI_1' grösser 100 °C

  if (TI_1 > 100)  
     ...
     ...
  if_end


Beispiel für die Bedingung, dass Temperaturen des Sensor 'TI_1' grösser 100 °C (mit if_else)

  if (TI_1 > 100)  
     ...
     ...
  if_else
     ...
  if_end


Wartezeit - delay

  • delay([Verzögerung])
Verzögerung im Macroablauf
→ die angegebene Verzögerung warten und danach mit der Macroabarbeitung fortfahren.


Beispiele für eine Verzögerung von 1 Stunde

  delay(3600)
  delay(3600s)
  delay(60m)
  delay(1h)

Bedingtes Warten - wait(for)

  • wait(for = ([Bedingung]), timeout = [max. Wartezeit])
Begin bedingtes Warten
→ solange die [Bedingung] in den Klammern unwahr (false) ist, wird mit die Macroabarbeitung unterbrochen.
Wird die [Bedingung] in den Klammern wahr (true), dann wird mit der nächsten/folgenden Macroanweisung fortgefahren.
Nach Ablauf der angegebenen max. Wartezeit wird auch, ohne dass die [Bedingung] wahr (true) wird, fortgefahren.

  wait(for = (TI_1 > 100), timeout = 200s))

Schleife - loop / loop_end

  • loop([Durchläufe])
Beginn einer Schleifen-Bedingung
→ die Macroanweisungen innerhalb der Schleife wird [Durchläufe] mal ausgeführt
  • loop_end
Ende der Schleife


Beispiel für eine Schleife mit 10 maligem Durchlauf

  loop (10)
     ...
     ... 
  loop_end

Default Macroaufrufe

TODO: marq: Ist das so umgesetzt? Wird das entsprechende Makro, z.B. Main.Exit automatisch beim schließen der XERO ausgeführt. Wenn es vorhanden ist? Muss, es zuvor angelegt werden? Sind noch weitere Einstellungen vorzunehmen. Bitte ergänzen!


Standardaufruf beim Starten der XERO Software

  macro Main.Ready()
     ...
     ...
  macro_end


Standardaufruf beim Beenden der XERO Software

  macro Main.Exit()
     ...
     ...
  macro_end


Standardaufruf bei Aktivierung eines Modules

  macro Main.Activate()
     ...
     ...
  macro_end


Standardaufruf bei Deaktivierung eines Modules

  macro Main.Deactivate()
     ...
     ...
  macro_end

Zuweisung

  • Id
Id ohne Gruppierung verweist auf Main.Id
→ siehe Abschnitt ??

Beispiel für die Zuweisung der Main.Id [Zielvariable] = Id

  • &[Modulname]
Zugriff auf einen Zahlenwert über eine Textreferenz [Modulname] innerhalb einer Textanweisung
  • Beispiel für die Zuweisung eines Endgaswertes über den Referenznamen;
THC.Spangas = 932ppm

[Zielvariable] = EGAK K0 &THC.Spangas; → wird zu 'EGAK K0 923'


Default Aliasnamen

  • OnEin
OffAus
  • ReadyStandby
ECO_ModePause
IgniteZünden
CleanSpülen
  • SampleMessen
  • SampleZeroMessen Nullwert
  • SampleSpanMessen Endwert
  • AdjustJustierung
  • AdjustZeroJustierung Nullwert
  • AdjustSpanJustierung Endwert
  • AdjustCuvetteJustierung Küvette