在CoDeSys中脚本语言的实现,提供了一个强大的CoDeSys序列。单命令或者复杂的命令序列,可以直接从CoDeSys中的编程环境或者通过窗口命令行中进行。在CoDeSys中脚本的模块化语言是基于 IronPython 2.7。为此CoDeSys的插件‘ScriptEngine’中集成了 IronPython解释器在CoDeSys环境中。该实现使用Python提供的外部的框架库去访问网络中的文件。
             
            
                
                IronPython的脚本文件
               Python是一种动态语言,用于各种广泛的用途,是一种强调清洁和表达性的代码。它能够为开发人员提供最大的灵活性,同时又保持代码的可读性。
IronPython 促使 Python 转到.NET,并允许本地访问 .NET 架构和类。实施 IronPyhon 的解释是基于Python 版本 2.7。
               在网络上有很多免费的教程和帮助。以下链接会给你一个有关 IronPython的详细介绍及说明:
               
             
            
            
            
                
               脚本命令
               依据广泛的 Python 命令库大约有150 多个特殊的脚本命令在CoDeSys命令中进行处理。
               
                  
                     
                         
                      | 
                     
                        
                         有关脚本命令的帮助文档没有完成,并且没有放在CoDeSys在线帮助文件中。更多相关信息请参阅CoDeSys的“在线帮助”中的“ScriptEngine.chm”详细说明。 
                      | 
                  
               
               
                  读 .NET API 文档理解 python 编程
               
               目前初步版本的脚本文件是依靠 .NET / C# 代码自动生成的。因此它包含了一些 Python 程序员不常见的语法结构。下面的列表中给出了如何将它们转化成 python化的语言。
               
                  
                     -  .NET 中的接口是关于类(方法,属性)中必须包含执行接口的定义,在 IronPython中,一个接口可以通过派生它们作为一个基类的方式实现一个或者多个 .NET接口。当一个接口的成员没有定义时,一个异常将会在运行系统中被抛出。(DeviceImportFromSvn.py示例表示一个类实现了ImportReporter接口。)
 
                     - 在.NET中,所有的参数,属性和函数的返回值都是静态类型。在参数之前允许使用一些类型。对于函数来说,返回值的类型定义在函数名的前方。子类的实例允许被父类(或者接口)进行调用。
 
                     - 方法可以被重载,一个类中可以包含相同名称的多个方法,但是他们必须具有不同数量的参数类型和/或者数量。IronPython 将会自动调用最匹配的函数。
 
                     - 一个int型的变量可以包含一个 -2 147 483 648到2 147 483 647之间的数,bool变量等同于 python类型的 bool (True 和 False),类型string等同于python中的类型str,unicode(等同于 IronPython中的类型)。IDictionary<Object, Object>表示一个通常的python路径。IronPython会自动在 Python 和 .NET 类型间进行转化。
 
                     - 如果一个类型T来自IBaseObject<T>,该类型可以通过其他插件扩展更多的成员。在参数或者返回值中该类型T将会被标记为IExtendedObject<T>。
 
                     - 接口IEnumerable<T>描述了任意序列(列表,数组),这些类型序列都是类型T的对象(子对象)。当序列产生不兼容的对象,在运行系统中会抛出一个异常。
 
                     - 接口IList<T>描述了一个包含对象类型T(或者子对象)的列表。当添加一个不匹配的对象时,一个异常将会抛出。
 
                     - 语法params T [] name等同于 python 中的语法 *name中的可变参数列表,但是对输入参数T(或者子类)有限制。
 
                     - 	枚举变量 (enum) 在 python中不是作为一种语言结构。他们用于定义一定数量的常量,例如,一周的天数。定义在 .NET中的枚举变量可以在 IronPython 中通过名称.Member 的语法结构进行调用(类似于类成员的调用)例如 OnlineChangeOption.Try。 在 python中有多种枚举形式,比如http://pypi.python.org/pypi/enum/或者http://www.ironpython.info/index.php/Enumerations
                     
 
                     - 标记在{ get; set; }中的属性是读写变量,标记在{ get; }中的属性是只读类型。类似于python中@property的定义。
 
                  
                
             
            
                
               
               
                  对于脚本文件以下切入点是可以允许的:
                  
                     - 
                        system:在CoDeSys系统中整合的函数。这个对象提供了所有描述在  "ISystem Interface"下的函数,例如,CoDeSys的退出,消息窗口的访问或者通过使用ui-present命令运行的 --noUI 模式。
 
                     - 
                        projects:工程管理的基本函数。这些对象提供了多有在  "IScriptProjects Interface"中描述的函数,例如,加载项目及项目档案。此外,它也是个别项目的入口点。
 
                     - 
                        online:在线连接设备的基本函数。通过使用"create_online_application" 对一个应用对象的在线对象进行管理。这个在线对象允许登录到控制器,启动应用程序并且初始化变量的值。
 
                  
                
             
            
                
               
                  
 接口点的相信说明
 
               
                  
                      
                     
                        
                           
                           
                           
                        
                        
                           
                              | 
                                  对象 
                               | 
                              
                                  名称(类型) 
                               | 
                              
                                  描述 
                               | 
                           
                        
                        
                           
                              | 
                                  系统 
                               | 
                              
                                  system (ISystem) 
                               | 
                              
                                  CoDeSys系统基本函数 
                               | 
                           
                           
                              |   | 
                              
                                  Severity 
                               | 
                              
                                  消息优先级的枚举 
                               | 
                           
                           
                              |   | 
                              
                                  Guid 
                               | 
                              
                                  数据类型 'g全局变量 u联合变量 Id识别 
                               | 
                           
                           
                              |   | 
                              
                                  PromptResult 
                               | 
                              
                                  用户需求的返回变量的枚举 
                               | 
                           
                           
                              |   | 
                              
                                  MultipleChoiceSelector 
                               | 
                              
                                  选择类型提示 
                               | 
                           
                           
                              |   | 
                              
                                  PromptChoiceFilter 
                               | 
                              
                                  选择文件类型提示 
                               | 
                           
                           
                              | 
                                  工程 
                               | 
                              
                                  projects (IScriptProjects) 
                               | 
                              
                                  工程管理的基本功能 
                               | 
                           
                           
                              |   | 
                              
                                  ExportReporter 
                               | 
                              
                                  导出过程中的事件接口 
                               | 
                           
                           
                              |   | 
                              
                                  ImportReporter 
                               | 
                              
                                  导入过程中的事件接口 
                               | 
                           
                           
                              |   | 
                              
                                  ConflictResolve 
                               | 
                              
                                  导入过程中冲突的枚举 
                               | 
                           
                           
                              | 
                                  在线 
                               | 
                              
                                  online (IScriptOnline) 
                               | 
                              
                                  在线连接设备的基本功能 
                               | 
                           
                           
                              |   | 
                              
                                  OnlineChangeOption 
                               | 
                              
                                  登录到设备下载类型的枚举 
                               | 
                           
                           
                              |   | 
                              
                                  ApplicationState 
                               | 
                              
                                  应用状态的枚举 
                               | 
                           
                           
                              |   | 
                              
                                  OperatingState 
                               | 
                              
                                  操作模式的枚举 
                               | 
                           
                           
                              |   | 
                              
                                  ValuesFailedException 
                               | 
                              
                                  在线异常表达错误 
                               | 
                           
                           
                              |   | 
                              
                                  TimeoutException 
                               | 
                              
                                  在线操作异常 
                               | 
                           
                           
                              | 
                                  设备对象 
                               | 
                              
                                  DeviceID 
                               | 
                              
                                  类型封装设备识别 
                               | 
                           
                        
                     
                   
                
             
            
                
               
                  
 脚本示例1:读取变量
 
               
                  在以下示例列表中可以从CoDeSys的用户接口或者命令行启动。
                  要启动它,需要改变CoDeSys的安装路径(<installation path of CoDeSys>\CoDeSys\Common)并且输入命令start /wait CoDeSys.exe --runscript="D:\data\scripts\ReadVariable.py" 
                  
                  脚本打开了CoDeSys,并且登录设备。如果控制器不是在“运行”模式将会设置为“运行”。然后变量iVar1 被读取并且显示在消息窗口或者命令行。最后应用程序被关闭。
                  
                      
                     # 脚本示例 ReadVariable.py
                     
                        
# Close all projects
while len(projects.all) > 0:            
    projects.all[0].close()
# opens project
proj = projects.open("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()
                         
                      
                   
                
             
            
                
               
                  
 脚本示例2: 从配方中读取值并发送邮件
 
               
                  在下面的示例列表中可以通过CoDeSys用户接口或者命令行开始。
                  要启动它,首先在命令行中输入CoDeSys版本中 "Common" 的路径(<安装路径 CoDeSys>\CoDeSys\Common) 并且输入命令start /wait CoDeSys.exe --runscript="D:\data\scripts\ScriptEmail.py" 
                  
                  脚本打开CoDeSys的一个应用并且登录设备。如果控制器没有在“运行”状态将会被设置为“运行”。然后变量 iVar1 的值将会被读取并且显示在消息窗口或者命令行。最后应用程序被关闭。
                  
                      
                     #脚本示例ScriptEmail.py
                     
                        
# 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@3s-software.com"
to = "info@3s-software.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()
                         
                      
                   
                
             
            
                
               
                  
 脚本示例 3: 确定工程中的设备树中打开项目
 
               
                  此示例用于确定打开项目中设备树中的所有对象,并显示在命令行或者消息视图中。可以通过示例1描述的方法启动。
                  
                      
                     # 脚本示例 DevicePrintTree.py
                     
                        
# We enable the new python 3 print syntax
from __future__ import print_function
import sys
# define the printing function
def printtree(treeobj, depth=0):
    if treeobj.is_root:
        name = treeobj.path
        deviceid = ""
    else:
        name = treeobj.get_name(False)    
        if treeobj.is_device:
            deviceid = treeobj.get_device_identification()
        else:
            deviceid = ""
    print("{0} - {1} {2}".format("   "*depth, name, deviceid))
    for child in treeobj.get_children(False):
        printtree(child, depth+1)
# Now see whether a primary project is open.
if not projects.primary:
    print("Error: Please open a project file first!", file=sys.stderr)
    sys.exit()
# And the actual output
print("--- The current tree of devices: ---")
printtree(projects.primary)
print("--- Script finished. ---")
                         
                      
                   
                
             
            
                
               
                  
 脚本示例 4: 从子版本中导入设备 PLCOpenXML 文件
 
               
                  示例展示从一个子版本中通过SVN端读取设备的PLCOpenXML文件。可以通过示例1描述的启动方式进行启动。
                  
                      
                     # 脚本示例 DeviceImportFromSvn.py
                     
                        
# 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. ---")