Skip to main content

Utilisation de scripts pour accéder CODESYS Fonctionnalités

Tous les objets et commandes qui CODESYS des services de scripts sont également disponibles dans le "scriptengine " Module Python. Chaque fois qu'un script est démarré, un <code>from scriptengine import *</code> résultats. Cela permet un accès facile aux CODESYS. Cependant, si votre script importe des modules qui nécessitent un accès CODESYS API, ces modules doivent alors importer le module scriptengine eux-mêmes.

Le tableau suivant présente les principaux objets (catégories) pouvant servir de points d'entrée dans les scripts Python. Pour une documentation complète sur les points d'entrée, consultez la documentation de référence de l'API. CODESYS Moteur de script : API de script CODESYS.

Objets

Description

system

Accès au général CODESYS fonctionnalités

Exemples:

  • Sortie CODESYS

  • Gestion de l'interface utilisateur générale

  • Accès à la mémoire des messages (y compris les messages du compilateur)

  • Contrôle des barres de retard et de progression

projects

Accès à la CODESYS projet sous forme d'arborescence d'objets qui combine les trois vues du navigateur (périphériques, POU, modules) dans une arborescence de projet

Permet également le chargement, la création, l'enregistrement et la fermeture de projets

Pour la plupart des objets d'un projet, il existe des méthodes spéciales avec des fonctionnalités détaillées, par exemple la compilation, l'accès aux POU ST, l'exportation, l'importation, la configuration des appareils, etc.

online

Accès aux fonctionnalités en ligne

Exemples:

  • Connectez-vous aux appareils et aux applications

  • Gestion des données d'accès (nom d'utilisateur, mot de passe)

  • Performances des analyses de réseau

  • Gestion de la passerelle

librarymanager

Permet la gestion des référentiels de bibliothèques et la visualisation, l'installation et la suppression des bibliothèques

device_repository

Gestion des référentiels d'appareils ; importation et exportation des descriptions d'appareils

modulerepository

Gestion de CODESYS Application Composer modules et CODESYS Application Composer dépôts

Consultez les exemples de scripts spécifiques suivants pour connaître les moyens d'y accéder CODESYS fonctionnalités. Pour des informations détaillées, consultez la documentation de référence de l'API CODESYS Moteur de script : API de script CODESYS.

Exemple : Impression de l'arborescence des périphériques du projet en cours

Le scénario PrintDeviceTree.py Voici un exemple de navigation dans un projet. Il génère un affichage hiérarchique de tous les appareils du projet ouvert.

Chargez un projet contenant des objets de périphérique et exécutez le script.

Exemple 22. Exemple: PrintDeviceTree.py
# encoding:utf-8
# We enable the new python 3 print syntax
from __future__ import print_function

# Prints out all devices in the currently open project.

print("--- Printing the devices of the project: ---")

# Define the printing function. This function starts with the
# so called "docstring" which is the recommended way to document
# functions in python.
def print_tree(treeobj, depth=0):
    """ Print a device and all its children

    Arguments:
    treeobj -- the object to print
    depth -- The current depth within the tree (default 0).

    The argument 'depth' is used by recursive call and
    should not be supplied by the user.
    """

    # if the current object is a device, we print the name and device identification.
    if treeobj.is_device:
        name = treeobj.get_name(False)
        deviceid = treeobj.get_device_identification()
        print("{0}- {1} {2}".format("--"*depth, name, deviceid))

    # we recursively call the print_tree function for the child objects.
    for child in treeobj.get_children(False):
        print_tree(child, depth+1)

# We iterate over all top level objects and call the print_tree function for them.
for obj in projects.primary.get_children():
    print_tree(obj)

print("--- Script finished. ---")

L'arborescence des périphériques (de la vue « Périphériques ») s'affiche dans la vue des messages et tous les objets non périphériques sont laissés de côté :

_cds_script_messages_print_device_tree.png


Exemple : Lecture de variables

Le scénario ReadVariable.py se connecte à l'appareil et lance l'application si nécessaire. La valeur de la variable PLC_PRG.iVar1 est lu et généré. Pour tester le script, vous devez modifier le chemin du projet et les noms des variables.

Exemple 23. Exemple: ReadVariable.py
# encoding:utf-8
from __future__ import print_function

# close open project if necessary:
if projects.primary:
    projects.primary.close()

# opens project
proj = projects.open(r"D:\data\projects\Ampel.project")

# set "Ampel.project" to active application
app = proj.active_application
onlineapp = online.create_online_application(app)

# login to device
onlineapp.login(OnlineChangeOption.Try, True)

# set status of application to "run", if not in "run"
if not onlineapp.application_state == ApplicationState.run:
    onlineapp.start()

# wait 1 second
system.delay(1000)

# read value of iVar1
value = onlineapp.read_value("PLC_PRG.iVar1")

# display value in message view or command line
print(value)

# log out from device and close "Ampel.project"
onlineapp.logout()
proj.close()

Dans le prolongement du script ReadVariable.py, le scénario MailVariables.py Charge les variables et expressions d'un fichier de recette et lit leurs valeurs actuelles depuis le contrôleur. Ces valeurs sont ensuite réécrites dans le même fichier. De plus, il utilise la bibliothèque SMTP Python pour envoyer un e-mail avec une pièce jointe contenant la liste de toutes les variables.

Pour utiliser le script, vous devez modifier les chemins, l'adresse e-mail et le nom du serveur SMTP de votre environnement.

Exemple 24. Exemple: MailVariables.py
# encoding:utf-8
from __future__ import print_function

# Close current project if necessary and open "ScriptTest.project"
if not projects.primary == None:
    projects.primary.close()
project = projects.open("D:\\Data\\projects\\scriptTest.project")

# retrieve active application
application = project.active_application

# create online application
online_application = online.create_online_application(application)

# login to application.
online_application.login(OnlineChangeOption.Try, True)

# start PLC if necessary
if not online_application.application_state == ApplicationState.run:
    online_application.start()

# wait 2 seconds
system.delay(2000)

# open recipe file to read values.
recipe_input_file = open("D:\\Data\\projects\\RecipeInput.txt", "r")

watch_expressions = []

for watch_expression in recipe_input_file:
    watch_expressions.append(watch_expression.strip())

print watch_expressions

# read values from the controllerd
watch_values = online_application.read_values(watch_expressions)

print watch_values

# open output file to write values
recipe_output_file = open("D:\\Data\\projects\\RecipeOutput.txt", "w")
for i in range(len(watch_expressions)):
    recipe_output_file.write(watch_expressions[i])
    recipe_output_file.write(" = ")
    recipe_output_file.write(watch_values[i])
    recipe_output_file.write("\n")

# Close files
recipe_input_file.close()
recipe_output_file.close()

# send Email
# import respective libraries
import smtplib
from email.mime.text import MIMEText

#open output file
recipe_output_file = open("D:\\Data\\projects\\RecipeOutput.txt", "r")
mail = MIMEText(recipe_output_file.read())
recipe_output_file.close()

#email address sender and recipient
fromm = "info@example.com"
to = "info@example.com"

# set sender and recipient
mail["Subject"] = "Attention value has changed"
mail["From"] = fromm
mail["To"] = to

# send email
smtp = smtplib.SMTP("name of smtp server")
smtp.sendmail(fromm, [to], mail.as_string())
smtp.quit()

# logout and close application
online_application.logout()
project.close()




Exemple : création et modification de POU

Le scénario CreateDut.py crée les objets MyStruct, MyAlias, et MyUnion dans le CODESYS projet. Le dossier DataTypes doit déjà être présent.

Exemple 25. Exemple: CreateDut.py
# encoding:utf-8
from __future__ import print_function

STRUCT_CONTENT = """\
    a : BOOL;
    b : BIT;
    c : BIT;
"""

UNION_WHOLE = """\
TYPE MyUnion :
UNION
    Zahl : INT;
    Prozent : MyAlias;
    Bits : MyStruct;
END_UNION
END_TYPE
"""

proj = projects.primary

folder = proj.find('DataTypes', recursive = True)[0]

# Create a struct DUT and insert the list of variables just into the right
# place in line two, row 0 (line numbering starts with line 0)
struktur = folder.create_dut('MyStruct') # DutType.Structure is the default
struktur.textual_declaration.insert(2, 0, STRUCT_CONTENT)

# Alias types get their "content" via the base type, which will just end up
# as one line in the declaration part:
# TYPE MyAlias : INT (0..100); END_TYPE
bereich = folder.create_dut('MyAlias', DutType.Alias, "INT (0..100)")

# Instead of injecting the variables into the existing declaration,
# one can also just replace the complete declaration part, including the
# boilerplate code.
union = folder.create_dut('MyUnion', DutType.Union)
union.textual_declaration.replace(UNION_WHOLE)


Exemple : Interface utilisateur / Interaction avec l'utilisateur

Dans certains cas, les scripts doivent interagir avec l'utilisateur. Nous fournissons des API simples pour les interactions les plus courantes. Exemple de script. System_UI_Test.py montre toutes les fonctions possibles à cet égard.

Exemple 26. Exemple: System_UI_Test.py
# encoding:utf-8
from __future__ import print_function

"""Performs some tests on the messagestore and UI."""

print("Some Error, Warning and Information popups:")
system.ui.error("Fatal error: Everything is OK. :-)")
system.ui.warning("Your bank account is surprisingly low")
system.ui.info("Just for your information: 42")

print("Now, we ask the user something.")
res = system.ui.prompt("Do you like this?", PromptChoice.YesNo, PromptResult.Yes);
print("The user selected '%s'" % res)

print("Now, the user can choose between custom options:")
res = system.ui.choose("Please choose:", ("First", 2, 7.5, "Something else"))
print("The user selected option '%s'" % str(res)) # res is a tuple

print("Now, the user can choose several options:")
res = system.ui.select_many("Please select one or more options", PromptChoice.OKCancel, PromptResult.OK, ("La Premiere", "The Second", "Das Dritte"))
print("The returned result is: '%s'" % str(res)) # res is a tuple

print("Now, the user can select files and directories")
res = system.ui.open_file_dialog("Choose multiple files:", filter="Text files (*.txt)|*.txt|Image Files(*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF|All files (*.*)|*.*", filter_index = 0, multiselect=True)
print("The user did choose: '%s'" % str(res)) # res is a tuple as multiselect is true.

res = system.ui.save_file_dialog("Choose a file to save:", filter="Text files (*.txt)|*.txt|Image Files(*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF|All files (*.*)|*.*", filter_index = 0)
print("The user did choose: '%s'" % res)

res = system.ui.browse_directory_dialog("Choose a directory", path="C:\\")
print("The user did choose: '%s'" % res)

print("Now we query a single line string")
res = system.ui.query_string("What's your name?")
print("Nice to meet you, dear %s." % res)

print("Now we query a multi line string")
res = system.ui.query_string("Please tell me a nice story about your life!", multi_line=True)
if (res):
        print("Huh, that has been a long text, at least %s characters!" % len(res))
else:
        print("Hey, don't be lazy!")


Exemple : manipulation de l'objet Informations sur le projet

Dans le script ProjectInfoExample.py, nous avons mis quelques informations dans le Informations sur le projet objet. Les informations les plus importantes, telles que Titre et Version, possèdent des propriétés explicites. Cependant, vous pouvez lire et écrire tout autre champ d'information au moyen de dictionary syntaxe. Par exemple, celles recommandées pour les propriétés d'un projet de bibliothèque.

L'exemple ci-dessous peut paraître irréaliste, mais un code similaire est utilisé dans les serveurs de build qui créent, testent et, éventuellement, publient des projets de bibliothèques automatiques et d'autres projets. Le ScriptEngine est un élément clé de la création de systèmes d'intégration continue (CI) et de livraison continue (CD).

Exemple 27. Exemple: ProjectInfoExample.py
# encoding:utf-8
from __future__ import print_function

proj = projects.load("D:\Some.library")

info = proj.get_project_info()

# Set some values
info.company = "Test Library Ltd"
info.title = "Script Test Project"
info.version = (0, 8, 15, 4711)
info.default_namespace = "testlibrary"
info.author = "Python von Scriptinger"

# some values recommended in the library toolchain
info.values["DefaultNamespace"] = "testlibrary"
info.values["Placeholder"] = "testlibrary"
info.values["DocFormat"] = "reStructuredText"

# now we set a custom / vendor specific value.
info.values["SpecialDeviceId"] = "PLC0815_4711"

# Enable generation of Accessor functions, so the IEC
# application can display the version in an info screen.
info.change_accessor_generation(True)

# And set the library to released
info.released = True;

proj.save()


Exemple : appel de commandes externes et importation de fichiers PLCopenXML

L'exemple de script DeviceImportFromSVN.py obtient un fichier PLCopenXML à partir d'un programme externe (dans ce cas, un client SVN) et l'importe dans un nouveau fichier créé CODESYS projet.

Pour utiliser le script, vous devez modifier les chemins d'accès à votre environnement.

Exemple 28. Exemple: DeviceImportFromSVN.py
# encoding:utf-8
# 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.
# We'll catch the output of the program into the xmldata variable.
# 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)

# import the data into the project.
proj.import_xml(xmldata, False)

# and finally save. :-)
proj.save()

print("--- Script finished. ---")


Exemples : Archivage de projets

Les fonctions open_archive() et save_archive() sont des fonctions de script permettant d'extraire une archive de projet ou de sauvegarder un projet en tant qu'archive. Pour ces deux fonctions, ArchiveCategories peut être spécifié.

  • Pour ça, open_archive() accepte le paramètre categories_to_extract.

  • save_archive() accepte le paramètre additional_categories.

ArchiveCategories sont des catégories d'archives de projet qui sont extraites avec les archives de projet dans le cas de open_archive() ou archivé avec les archives du projet dans le cas de save_archive().

Exemples: open_archive()

Divers exemples de open_archive() avec le paramètre categories_to_extract sont présentés ci-dessous :

Comportement par défaut: categories_to_extract=None

Si categories_to_extract ne sont pas explicitement spécifiés, alors le paramètre est défini sur None. Toutes les catégories sont extraites des archives du projet.

Exemple 29. Exemple
# Default
projects.open_archive(stArchiveFile=r"D:\Tests\Test.projectarchive", stProjectPath=r"D:\Tests", bOverwrite=True)


Liste vide: categories_to_extract=[]

Si le paramètre categories_to_extract est explicitement spécifié avec une liste vide, alors aucune catégorie n'est extraite de l'archive du projet.

Exemple 30. Exemple
# Passing empty list
projects.open_archive(stArchiveFile=r"D:\Tests\Test.projectarchive", stProjectPath=r"D:\Tests", bOverwrite=True, categories_to_extract=[])


Plusieurs catégories

Plusieurs catégories peuvent être spécifiées dans le paramètre categories_to_extract Seules les catégories spécifiées sont également extraites.

Exemple 31. Exemple
# Multiple categories
projects.open_archive(stArchiveFile=r"D:\Tests\Test.projectarchive", stProjectPath=r"D:\Tests", bOverwrite=True, categories_to_extract=[ArchiveCategories.libraries, ArchiveCategories.devices])


Erreurs possibles

Si les catégories sont spécifiées dans categories_to_extract qui n'existent pas dans le présent CODESYS Lors de l'installation, un message d'erreur s'affiche. L'archive du projet ne peut être extraite tant que la catégorie manquante n'est pas installée ou que la catégorie n'est pas supprimée du paramètre du script.

Exemples: save_archive()

Divers exemples de save_archive() avec le paramètre additional_categories sont présentés ci-dessous :

Comportement par défaut

Si additional_categories ne sont pas explicitement définies, alors les catégories par défaut de la CODESYS Les interfaces sont également archivées.

Aucune catégorie: additional_categories=None

Si additional_categories est explicitement défini sur None dans le script, aucune catégorie ne sera archivée.

Plusieurs catégories

Plusieurs catégories peuvent être spécifiées dans le paramètre additional_categories Seules les catégories spécifiées seront incluses dans les archives.

Exemple 32. Exemple
# Muliple categories
projects.save_archive(path=r"D:\Tests", comment="A new project", additional_files=[], additional_categories=[ArchiveCategories.libraries, ArchiveCategories.devices])


Exemple avancé : Appeler une bibliothèque depuis SVN et l'installer dans CODESYS

L'exemple de script suivant permet d'appeler et d'installer une bibliothèque dans un environnement de test continu (CT) afin de la tester. Outre les tests standard,CODESYS, le CODESYS SVN le module complémentaire doit également être installé avec une licence valide.

Exemple 33. Exemple
import tempfile

if projects.primary:
    projects.primary.close()

tempdir = tempfile.mkdtemp()
URL = "svn://localhost/testrepo/trunk/SvnTestLibrary/"

proj = svn.checkout(URL, tempdir, "testlibrary", as_library=True)
proj.save()

repo = librarymanager.repositories[0]
librarymanager.install_library(proj.path, repo, True)

proj.close()