スクリプトを使用してアクセスする CODESYS 機能性
すべてのオブジェクトとコマンド CODESYS スクリプトの提供は、「scriptengine
"Pythonモジュール。スクリプトが開始されるたびに、暗黙的に <code>from scriptengine import *</code>
結果。これにより、簡単にアクセスできます CODESYS。ただし、スクリプトがアクセスを必要とするモジュールをインポートする場合 CODESYS APIの場合、これらのモジュールはモジュールをインポートする必要があります scriptengine
彼ら自身。
Pythonスクリプトのエントリポイントとして使用できる主なオブジェクト(カテゴリ)を次の表に示します。エントリポイントの詳細なドキュメントは、 APIリファレンスドキュメント に CODESYS ScriptEngine。
オブジェクト | 説明 |
---|---|
システム | 一般へのアクセス CODESYS 機能性 例:
|
プロジェクト | へのアクセス CODESYS 3つのナビゲータービュー(デバイス、POU、モジュール)を1つのプロジェクトツリーに結合するオブジェクトツリーとしてのプロジェクト プロジェクトのロード、作成、保存、およびクローズも可能です プロジェクト内のほとんどのオブジェクトには、コンパイル、ST POUへのアクセス、エクスポート、インポート、デバイス構成など、詳細な機能を備えた特別なメソッドがあります。 |
オンライン | オンライン機能へのアクセス 例:
|
librarymanager | ライブラリリポジトリの管理、およびライブラリの表示、インストール、削除を許可します |
device_repository | デバイスリポジトリの処理。デバイスの説明のインポートとエクスポート |
modulerepository | の管理 CODESYS Application Composer モジュールと CODESYS Application Composer リポジトリ |
アクセス用の特定のサンプルスクリプトについては、以下を参照してください CODESYS-機能。詳細については、を参照してください。 APIリファレンスドキュメント に CODESYS。
例:現在のプロジェクトのデバイスツリーを印刷する
スクリプト PrintDeviceTree.py
プロジェクト内を移動するための例です。開いているプロジェクト内のすべてのデバイスの階層表示の出力を作成します。
いくつかのデバイスオブジェクトを含むプロジェクトをロードし、スクリプトを実行します。
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. ---")
(「デバイス」ビューからの)デバイスツリーがメッセージビューに表示され、デバイス以外のすべてのオブジェクトが除外されます。

例:変数の読み取り
スクリプト ReadVariable.py
デバイスにログインし、必要に応じてアプリケーションを起動します。次に、変数の値 PLC_PRG.iVar1
読み取られて出力されます。スクリプトを試すには、プロジェクトパスと変数名を変更する必要があります。
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()
スクリプトの拡張で ReadVariable.py
、 スクリプト MailVariables.py
レシピファイルから変数と式をロードし、コントローラーからそれらの現在の値を読み取ります。次に、これらの値が同じファイルに書き戻されます。さらに、はPython SMTPライブラリを使用して、すべての変数のリストを含む添付ファイル付きの電子メールを送信します。
スクリプトを使用するには、環境へのパス、電子メールアドレス、およびSMTPサーバーの名前を変更する必要があります。
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()
例:POUの作成と編集
スクリプト CreateDut.py
オブジェクトを作成します MyStruct
、 MyAlias
、 と MyUnion
の中に CODESYS 事業。フォルダ DataTypes
すでに存在している必要があります。
# 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)
例:ユーザーインターフェース/ユーザーとの対話
場合によっては、スクリプトはユーザーと対話する必要があります。最も一般的なインタラクション用にいくつかのシンプルなAPIを提供します。サンプルスクリプト System_UI_Test.py
この点で可能なすべての機能を示しています。
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!") print("Username and passwort prompts...") res = system.ui.query_password("Please enter your favourite password!", cancellable=True) if res: print("Huh, it's very careless to tell me your favourite password '%s'!" % res) else: print("Ok, if you don't want...") res = system.ui.query_credentials("Now, for real...") if res: print("Username '%s' and password '%s'" % res) # res is a 2-tuple else: print("Sigh...")
例:操作 プロジェクト情報 物体
スクリプト内 ProjectInfoExample.py
、にいくつかの情報を設定します プロジェクト情報 物体。などの最も重要な情報項目 タイトル と バージョン、明示的なプロパティがあります。ただし、を使用して他の情報フィールドを読み書きできます。 dictionary
構文。たとえば、ライブラリプロジェクトのプロパティに推奨されるもの。
以下の例はやや非現実的に見えるかもしれませんが、自動ライブラリプロジェクトやその他のプロジェクトを作成、テスト、場合によってはリリースするビルドサーバーで同様のコードが使用されています。 ScriptEngineは、CI(継続的インテグレーション)およびCD(継続的デリバリー)システムを作成するための重要な要素の1つです。
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()
例:外部コマンドの呼び出しとPLCOpenXMLファイルのインポート
サンプルスクリプト DeviceImportFromSVN.py
外部プログラム(この場合はSVNクライアント)からPLCOpenXMLファイルを取得し、新しく作成されたものにインポートします CODESYS 事業。
スクリプトを使用するには、環境へのパスを変更する必要があります。
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. ---")
高度な例:SVNからライブラリを呼び出してインストールする CODESYS
次のサンプルスクリプトは、CT(継続的テスト)環境の一部としてライブラリの呼び出しとインストールを実行して、ライブラリをテストできるようにすることができます。標準に加えて-CODESYS、 CODESYS SVN アドオンも有効なライセンスでインストールする必要があります。
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()