Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched. Close

Scripting - Beispiele und Rezepte

Anonymous
2011-04-04
2011-04-04
  • Anonymous - 2011-04-04

    Originally created by: M.Schaber

    In diesem Thread möchten wir Beispiele und Rezepte sammeln, wie man komplexere Vorgänge in der CoDeSys Scriptsprache implementieren kann.

     
  • Anonymous - 2011-04-04

    Originally created by: M.Schaber

    Dieses Beispiel ist eine Weiterentwicklung des Beispiel 1 aus der Dokumentation.

    Der Einsatzzweck: Aus einem externen Programm oder einer Batchdatei heraus wird eine Variable aus einer Steuerung ausgelesen, und auf der Standardausgabe ausgegeben, damit sie vom Aufrufer ausgewertet werden kann, zum Beispiel:

    C:\Program Files\3S CoDeSys V3.4 SP3\CoDeSys\Common>start /wait CoDeSys.exe --profile="CoDeSys V3.4 SP3" --noUI --runscript="D:\TestScripts\ReadVariable.py" 
    

    Und hier das eigentliche Programm:

    \# coding=utf-8
    \# Da wir in den Kommentaren Umlaute verwenden, müssen wir das Encoding des Quelltextes
    \# angeben.
    \# Wir nutzen die Python 3 Variante von print
    from __future__ import print_function
        
    \# Unsere Projektdatei liegt im Data-Unterverzeichnis aus dem Verzeichnis,
    \# in dem das Skript liegt, wir hangeln uns also relativ den Pfad entlang.
    import os
    scriptdir = os.path.dirname(__file__) # Da liegt unser Skript.
    datadir = os.path.join(scriptdir, "Data") # ins Unterverzeichnis rein.
    projectpath = os.path.join(datadir, "Ampel.project") # Und den Projektnamen dran.
    \# jetzt können wir unser Projekt öffnen.
    proj = projects.open(projectpath)
    \# Wir holen die aktive Applikation (aus dem Ampel-Projekt)
    app = proj.active_application
    \# Und die entsprechende online-Applikation dazu.
    onlineapp = online.create_online_application(app)
    \# Wir loggen uns aufs Gerät ein.
    onlineapp.login(OnlineChangeOption.Try, True)
    \# Falls die Applikation noch nicht läuft, starten wir sie.
    if not onlineapp.application_state == ApplicationState.run:
        onlineapp.start()
    \# Wir geben der Applikation etwas Zeit zum Arbeiten.
    system.delay(1000)
    \# Und lesen den Vert der gewünschten Variable aus
    value = onlineapp.read_value("PLC_PRG.iVar1")
    \# Wir geben den Wert auf der Standardausgabe aus, damit unser Aufrufer
    \# den Wert weiterbearbeiten kann.
    print(value)
    \# Und räumen am Ende auch schön auf.
    onlineapp.logout()
    proj.close()
    

    Das ganze sieht von einem CMD-Fenster aus dann wie folgt aus:

    C:\Program Files\3S CoDeSys V3.4 SP3\CoDeSys\Common>start /wait CoDeSys --profile="CoDeSys V3.4 SP3" --noUI --runscript="D:\TestScripts\Forum_ReadVariable.py"
    ------ Build started: Application: Device.App -------
    The application is up to date
    Build: Information: Size of generated code: 6419 bytes
    Build: Information: Size of global data: 2594 bytes
    Build: Information: Total allocated memory size for code and data: 10997 bytes
    Build: Information: Memory area 0 contains  Data, Input, Output, Memory and Code
    : highest used address: 1048576, largest contiguous memory gap: 1037579 (98 %)
    Compile complete -- 0 errors, 0 warnings
    INT#2263
    C:\Program Files\3S CoDeSys V3.4 SP3\CoDeSys\Common>
    
     
  • Anonymous - 2011-04-04

    Originally created by: M.Schaber

    Gerade wenn man Scripte über die Kommandozeile heraus aufruft, wäre es manchmal nützlich, wenn man Parameter an die Skripte übergeben könnte.

    Als Workaround für diese Funktionalität kann man mit Environment-Variablen arbeiten:

    from __future__ import print_function
    import os
    print("project to open: ", os.environ["PROJECT"])
    \# Wir gehen hier davon aus, dass die App auf dem Device bereits am laufen ist:
    proj = projects.open(os.environ["PROJECT"])
    onlineapp = online.create_online_application(proj.active_application)
    onlineapp.login(OnlineChangeOption.Try, True)
    print("variables to read:")
    for var in os.environ["VARIABLES"].split(","):
       print ("    ", var, " = ", onlineapp.read_value(var))
    

    Das kann man dann z. B. aus einer Batch-Datei wie folgt aufrufen:

    @echo off
    SET PROJECT=D:\TestScripts\Data\OnlineTest.project
    SET VARIABLES=POU.testint,POU.testoutput
    start /wait CoDeSys.exe --profile="CoDeSys V3.4 SP3" --noUI --runscript="D:\TestScripts\Forum_Environment.py"
    

    Das Ergebnis sieht dann so aus:

    C:\Program Files\3S CoDeSys V3.4 SP3\CoDeSys\Common>d:\TestScripts\Forum_Environment.bat
    project to open:  D:\TestScripts\Data\OnlineTest.project
    ------ Build started: Application: CoDeSys_Control_Win_V3.Application -------
    The application is up to date
    Build: Information: Size of generated code: 6453 bytes
    Build: Information: Size of global data: 2606 bytes
    Build: Information: Total allocated memory size for code and data: 12505 bytes
    Build: Information: Memory area 0 contains  Data, Input, Output, Memory and Code: highest used address: 1048576, largest contiguous memory gap: 1036071 (98 %)
    Compile complete -- 0 errors, 0 warnings
    variables to read:
         POU.testint  =  INT#1
         POU.testoutput  =  INT#3
    C:\Program Files\3S CoDeSys V3.4 SP3\CoDeSys\Common>
    
     
  • Anonymous - 2011-04-04

    Originally created by: M.Schaber

    Im Moment kann man Geräte per Skript nur anhand der Device ID hinzufügen. Wenn man die Device ID eines Gerätes nicht weiß, kann folgendes Skript dabei helfen. Man fügt das Gerät ins aktuelle Projekt ein, und startet das Skript:

    \# Prints out all devices and other objects in the currently open project.
    \# We enable the new python 3 print syntax
    from __future__ import print_function
    \# define the printing function
    def printtree(treeobj, depth=0):
        name = treeobj.get_name(False)    
        if treeobj.is_device:
          deviceid = treeobj.get_device_identification()
          print("{0} - {1} {2}".format("   "*depth, name, deviceid))
       
        for child in treeobj.get_children(False):
            printtree(child, depth+1)
    for obj in projects.primary.get_children():
       printtree(obj)
    print("--- Script finished. ---")
    

    Die Ausgabe sieht dann so aus:

    - CoDeSys_Control_Win_V3 DeviceID(type=4096, Id='0000 0001', Version='3.4.2.0')
       - CANbus DeviceID(type=15, Id='181015', Version='3.4.2.0')
          - CANopen_Manager DeviceID(type=16, Id='181016', Version='3.4.2.0')
    --- Script finished. ---
    

    Und schon kennt man die Device ID des gesuchten Gerätes.

     
  • Anonymous - 2011-04-04

    Originally created by: M.Schaber

    Einige Anwender möchten sich die Ausgangsbasis für ihre Projekte gerne aus einem Subversion-Repository holen.

    Das folgende Beispiel (das auch dem Beispiel 4 in der Dokumentation entspricht) erzeugt ein neues Projekt, und fügt darin via PLCOpenXML ein Gerät ein:

    \# Imports a Device in PLCOpenXML from Subversion via command line svn client.
    \# We enable the new python 3 print syntax
    from __future__ import print_function
    import sys, os
    \# some variable definitions:
    SVNEXE = r"C:\Program Files\Subversion\bin\svn.exe"
    XMLURL = "file:///D:/testrepo/testfolder/TestExport.xml"
    PROJECT = r"D:\test.project"
    \# clean up any open project:
    if projects.primary:
       projects.primary.close()
    \# Fetch the plcopenxml data from subversion. 
    \# The 'with' construct automatically closes the open pipe for us.
    with os.popen('"' + SVNEXE + '" cat ' + XMLURL, 'r') as pipe:
       xmldata = pipe.read()
    \# create a new project:
    proj = projects.create(PROJECT)
    \# create the import reporter
    class Reporter(ImportReporter):
       def error(self, message):
          system.write_message(Severity.Error, message)
       def warning(self, message):
          system.write_message(Severity.Warning, message)
       
       def resolve_conflict(self, obj):
          return ConflictResolve.Copy
       
       def added(self, obj):
          print("added: ", obj)
       def replaced(self, obj):
          print("replaced: ", obj)
       def skipped(self, obj):
          print("skipped: ", obj)
          
       @property
       def aborting(self):
          return False
    \# create the importer instance.
    reporter = Reporter()      
    \# import the data into the project.
    proj.import_xml(reporter, xmldata)
    \# and finally save. :-)
    proj.save()
    print("--- Script finished. ---")
    

    Den dazu notwendigen Kommandozeilen-Client für Subversion gibt es von verschiedenen Anbietern frei herunterzuladen. Die Subversion Download-Seite enthält Links zu einigen davon, im Cygwin-Projekt ist ein weiterer enthalten.

     

Log in to post a comment.