Help us understand the problem. What is going on with this article?

Siemens#Openness

Siemens Openness とは?

TIA Portal OpennessはSiemens社から提供したエンジニアリンクオーブンインタフェースです。このインタフェースを使うによってTIA Portal(Siemens社のエンジニアリンクツール)を外部アプリケーションから制御することも可能になります。

TIA Portal Opennessを使えば、こんなことができるようになります.

  • プロジェクト作成
  • プロジェクト修正
  • プロジェクト削除
  • プロジェクトデータを読む
  • プロジェクトデータをほかのアプリケーションを操作する

イメージがあまり浮いていませんが、下図のように表示するといかがでしょう?XMLFilesがありまして、中に作成したいDevicesなどを記入されています。そしてTIA Openness Projectがありまして、パソコンに入ってるTIA PortalのDevices追加、Connection作成などの動作はそのTIA Openness Project経由しXMLをImportし操作を行う。

image.png

紹介

ビデオ

Manual

作業環境

  • Python 3.7.1
  • pythonnet
  • Jupyter

インストールするときの不明点

プログラミングステップ

  1. TIA PortalをOpennessに連携できる環境を作る
  2. TIA Portalをアクセスのプログラム作る
  3. TIA PortalをアクセスのプログラムActivateし、TIA Portalをアクセスする
  4. TIA Portal起動する
  5. Projectを開く
  6. さまざまなコマンドを実行する
  7. Projectを保存・閉じる
  8. TIA Portalの間のアクセスを切断する

TIA Portal Openness Object Model

以下の図はObject Modelについて説明します。TIA PortalにF1を押しOpennessを検索すれば同じなものもでてきます。

Highest Level

image.png

GlobalLibrary

image.png

ProjectLibrary

image.png

HmiTarget

image.png

PlcSoftware

image.png

各Objectの関係:
image.png

本来ならC# でプログラミングしないといけないですが、ここでpythonnetを使ってOpennessのdllを読み込んでPythonでやりたいと思います。

実装

プロジェクト作成

以下はProject_testというProjectをC:\tiav15_1_projectに作ることができます。
(もし同じ名前のプロジェクトも既にあるだと例外が発生します。)

ProjectCreate.py
import clr
clr.AddReference('C:\\Program Files\\Siemens\\Automation\\Portal V15_1\PublicAPI\\V15.1\\Siemens.Engineering.dll')
from System.IO import DirectoryInfo,FileInfo
import Siemens.Engineering as tia
import Siemens.Engineering.HW.Features as hwf

project_path = DirectoryInfo ('C:\\tiav15_1_project')
project_name = 'Project_test'
print ('Starting TIA with UI')
mytia = tia.TiaPortal(tia.TiaPortalMode.WithUserInterface)
myproject = mytia .Projects.Create(project_path, project_name)

プロジェクト開く

以下はプロジェクトを開くのコードです。
(もし該当プロジェクト既に開いてるのあれば例外が発生します。)

ProjectOpen.py
import clr
clr.AddReference('C:\\Program Files\\Siemens\\Automation\\Portal V15_1\PublicAPI\\V15.1\\Siemens.Engineering.dll')
from System.IO import DirectoryInfo,FileInfo
import Siemens.Engineering as tia
import Siemens.Engineering.HW.Features as hwf

def openTIAProject(tia,open_path):
    try:
        project=tia.Projects.Open(open_path)
        return project
    except Exception as e:
        print(e)
        return None

open_path=FileInfo('C:\\tiav15_1_project\\project\\porject\\AppTest\\AppTest.ap15_1')

print ('Starting TIA with UI')
mytia = tia.TiaPortal(tia.TiaPortalMode.WithUserInterface)
myproject=openTIAProject(mytia,open_path)

プロジェクトを閉じる

myproject.Close()

プロジェクトを保存

myproject.Save()

プロジェクトの情報もらう

print('Project Information\n'
        '-Name:{}\n'
        '-Author:{}\n'
        '-Comment:{}\n'
        '-Copy Right:{}\n'
        '-Creation time:{}\n'
        '-Family:{}\n'\
        '-IsModified:{}\n'
        '-Language Settings:{}\n'
        '-Last Modified:{}\n'
        '-Last Modified By:{}\n'
        '-Name:{}\n'
        '-Path:{}\n'
        '-Size:{}\n'
        '-Version:{}\n'
            .format(
                myproject.Name
                ,myproject.Author
                ,myproject.Comment
                ,myproject.Copyright
                ,myproject.CreationTime
                ,myproject.Family
                ,myproject.IsModified
                ,myproject.LanguageSettings
                ,myproject.LastModified
                ,myproject.LastModifiedBy
                ,myproject.Name
                ,myproject.Path
                ,myproject.Size
                ,myproject.Version
        ))

Device操作

基本的にはデバイスのOrder Numberを参照してやります。(たまに新し過ぎるものが追加でません…)
デバイスのOrder Number常に見えるようにする設定:
image.png

そのCheckBox入れると、Hardware Catalogの表示はこんな風に変わります:
image.png

Device追加

CreateDevice.py
import clr
clr.AddReference('C:\\Program Files\\Siemens\\Automation\\Portal V15_1\PublicAPI\\V15.1\\Siemens.Engineering.dll')
from System.IO import DirectoryInfo,FileInfo
import Siemens.Engineering as tia
import Siemens.Engineering.HW.Features as hwf

project_path = DirectoryInfo ('C:\\tiav15_1_project')


project_name = 'Project_Demo16'

#Creating new project
print ('Creating project..')
#Starting TIA
print ('Starting TIA with UI')
mytia = tia.TiaPortal(tia.TiaPortalMode.WithUserInterface)


try: 
    myproject = mytia.Projects.Create(project_path, project_name)
except Exception as e:
    print(e)

#Addding Stations
print ('Creating station 1')
station1_mlfb = 'OrderNumber:6ES7 515-2AM01-0AB0/V2.0'
station1 = myproject.Devices.CreateWithItem(station1_mlfb, 'station1', 'station1')
print('Station1 is Created.')


TIAのViewを変わる

Topology view

myproject.ShowHwEditor(tia.HW.View.Topology)

image.png

NetworkView

myproject.ShowHwEditor(tia.HW.View.Network)

image.png

Device view

myproject.ShowHwEditor(tia.HW.View.Device)

image.png

Languages

英語追加

from System.Globalization import CultureInfo
EnlishLanguage=myproject.LanguageSettings.Languages.Find(CultureInfo('en-US'))
Comments=myproject.Comment
CommentsItem=Comments.Items
EnglishComment=CommentsItem.Find(EnlishLanguage)

SoftwareContainer

PLCを追加したあと、中のBlocks、Tagテーブル操作するにはこのSoftwareContainerが必要です。
ここで仮にPLCが追加済です。

SoftwareContainerもらう

SoftwareContainer=tia.IEngineeringServiceProvider((myproject.Devices[0].DeviceItems[1])).GetService[hwf.SoftwareContainer]()
software=SoftwareContainer.get_Software()

Tagテーブル追加

TagTableName='MyTable'
print('Creating PLC Tag Table:'+TagTableName)
TagTableGroup=software.get_TagTableGroup()
TagTable=TagTableGroup.get_TagTables()
TagTable.Create(TagTableName)
plcTable=TagTable.Find(TagTableName)

PLC Tag追加

tagComposition=plcTable.Tags
Start=10
End=11
print('Start to create IOTags..')
for k in range(Start,End+1):
    for i in range(0,8):
        dataType='Bool'
        tagName='MyTag_'+str(k)+'.'+str(i)
        Address='%Q'+str(k)+'.'+str(i)
        Comment='My Tag:)! {}'.format(str(k)+'.'+str(i))
        print('Creating tag..Name:{},Type:{},Address:{},Comment:{}'.format(tagName,dataType,Address,Comment))
        tag1=tagComposition.Create(tagName,dataType,Address)
        CommentTag1=tag1.Comment.Items
        CcTag1=CommentTag1.Find(EnlishLanguage)
        CcTag1.Text=Comment

image.png

プロジェクトコンパイル

import Siemens.Engineering.Compiler as cp
softwareComp=software.GetService[cp.ICompilable]()
softwareComp.Compile()

BlockとBlockグループ

Blockグループもらう

BlockGroup=software.BlockGroup

BlockグループにあるBlock情報もらう

def define_ProgrammingLanguage(ProgrammingLanguage):
    if ProgrammingLanguage == 2:
        return 'LAD'
    elif ProgrammingLanguage == 3:
        return 'FBD'
    elif ProgrammingLanguage == 1:
        return 'STL'
    elif ProgrammingLanguage == 4:
        return 'SCL'
    elif ProgrammingLanguage == 5:
        return 'DB'
    elif ProgrammingLanguage == 6:
        return 'GRAPH'

Groups=BlockGroup.get_Groups()

for bg in Groups:
    for b in bg.get_Blocks():
        AttributeInfos=b.GetAttributeInfos()
        for Attribute in AttributeInfos:
            print(Attribute.Name+':'+str(b.GetAttribute(Attribute.Name)))
        print('-'*30)

image.png

Blockグループ作成

def CreateBlockGroup(plcsoftware,GroupName):
    systemGroup=plcsoftware.BlockGroup
    groupComposition=systemGroup.Groups

    if software.BlockGroup.Groups.Find(GroupName):
        print(GroupName+' is existed. Can not Created..')
    else:
        createdGroup=groupComposition.Create(GroupName)

CreateBlockGroup(software,'Folder2221')

Blockグループ探す

Block_autoNumber=Groups.Find('TestGroup').Blocks.Find('Block_1').GetAttribute('AutoNumber')

Blockグループ削除

def DeleteBlockFolder(plcsoftware,GroupName):
    group=plcsoftware.BlockGroup.Groups.Find(GroupName)
    if group:
        group.Delete()
    else:
        print(GroupName+' is not existed in your project.')
DeleteBlockFolder(software,'Folder2221')

Blocksグループを回す

def EnumerateBlockUserGroups(blockUserGroup):
    for subBlockUserGroup in blockUserGroup.Groups:
        print('|-'+subBlockUserGroup.Name)

def EnumerateAllBlockGroupsAndSubgroups(plcsoftware):
    for blockUserGroup in plcsoftware.BlockGroup.Groups:
        print(blockUserGroup.Name)
        EnumerateBlockUserGroups(blockUserGroup)

EnumerateAllBlockGroupsAndSubgroups(software)

image.png

BlockをExport

from Siemens.Engineering import ExportOptions,ImportOptions
Block_ex=Groups.Find('TestGroup').Blocks.Find('Block_1')
save_path=FileInfo('C:\\Data\\f.xml')
Block_ex.Export(save_path,ExportOptions.WithDefaults)

BlockをImport

gex=Groups.Find('TestGroup')
bex=gex.Blocks.Import(save_path,ImportOptions.Override)

Blockをアクセス

def AccessASingleBlock(plcsoftware,blockname):
    return plcsoftware.BlockGroup.Blocks.Find(blockname)

block=AccessASingleBlock(software,'Main')

Blockの設定変更

block=AccessASingleBlock(software,'Block_1')
block.SetAttribute('AutoNumber',False)
block.SetAttribute('Number',999)

Blockをまわす

def EnumerateAllBlocks(plcsoftware):
    for block in software.BlockGroup.Blocks:
        print(block.Name)

EnumerateAllBlocks(software)

image.png

PLC操作

Online

from Siemens.Engineering.Online import OnlineProvider
plc=myproject.Devices[0]
plc1=plc.DeviceItems[1]
plc_online=plc1.GetService[OnlineProvider]()

image.png

Connection interface Configure

for configmode in onlineConfig.Modes:
    print('Interface:'+configmode.Name)
    for pcInteface in configmode.PcInterfaces:
        print('PC Interface Name:'+str(pcInteface.Name))
        print('PC Interface Number:'+str(pcInteface.Number))
        for tagetInterface in pcInteface.TargetInterfaces:
            print('Taget Interface:'+str(tagetInterface.Name))

image.png

Get the Connection By Name

mode=onlineConfig.Modes.Find('PN/IE')
pcInt=mode.PcInterfaces.Find('PLCSIM',1)
slot=pcInt.TargetInterfaces.Find('1 X1')

access subnets and gateways by their name or IP address

def AccessSubnetAndGatewayOfPCInterface(pcInterface):
    subnet=pcInteface.Subnets.Find('PN/IE_1')
    print(subnet.Name)
    subnetAddress=subnet.Addresses.Find('192.168.0.1')
    print(subnetAddress.Name)
    gateway=subnet.Gateways.Find('Gateway 1')
    print(gateway)
    if gateway:
        gatewayAddress=gateway.Address.Find('192.168.0.2')
        print(gatewayAddress)

AccessSubnetAndGatewayOfPCInterface(pcInt)

image.png

Go Offline/Online

def SetOnlineConnectionForAllPLCs(project,oper):
    for device in project.Devices:
        for deviceItem in device.DeviceItems:
            onlineProvider=deviceItem.GetService[OnlineProvider]()
            if onlineProvider:
                if oper==1:
                    onlineProvider.GoOnline()
                else:
                    onlineProvider.GoOffline()

SetOnlineConnectionForAllPLCs(myproject,0)

Network Connection作成

まず現在の構成:
image.png

#get the Devices
plc1=myproject.Devices[0]
v90=myproject.Devices[1]
print(v90.Name)
print(plc1.Name)

Subnet作る

myproject.Subnets.Create('System:Subnet.Ethernet','NewSubNet2')

Subnetがあるかを確認

もしなかったらNoneが戻ってきます。

subnet=myproject.Subnets.Find('NewSubNet2')

SubnetのIPなど変更

#Change IP and Connect to Subnet
n_interfaces=[]

device_item_aggregation =plc1.DeviceItems[1].DeviceItems
device_item=device_item_aggregation[3]

for d in device_item_aggregation:
    print(d.Name)

network_service = tia.IEngineeringServiceProvider(device_item).GetService[hwf.NetworkInterface]()
network_service.Nodes[0].SetAttribute('Address','192.168.0.126')
network_service.Nodes[0].ConnectToSubnet(subnet)
n_interfaces.append(network_service)

IOSytem作る

#Create IO System
ioSystem = n_interfaces[0].IoControllers[0].CreateIoSystem("PNIO");

接続

#Connect Other Devices
device_item_aggregation1 =v90.DeviceItems[1].DeviceItems
device_item=device_item_aggregation1[0]

print(device_item.Name)

network_service = tia.IEngineeringServiceProvider(device_item).GetService[hwf.NetworkInterface]()
network_service.Nodes[0].SetAttribute('Address','192.168.0.145')
network_service.Nodes[0].ConnectToSubnet(subnet)
n_interfaces.append(network_service)
len(n_interfaces)
n_interfaces[1].IoConnectors[0].ConnectToIoSystem(ioSystem)

Technology Objects

from Siemens.Engineering.SW.TechnologicalObjects import TechnologicalInstanceDB 
from System import Version as vr

PID_Compact

to11=software.TechnologicalObjectGroup.TechnologicalObjects
toName="PID_Compact_1"
toType='PID_Compact'
version=vr("2.3")
pid_compact=to11.Create(toName,toType,version)

#Config Constant
PID_COMPACT_MODE_INACTIVE=0
PID_COMPACT_MODE_PRETUNING=1
PID_COMPACT_MODE_FINETUNING=2
PID_COMPACT_MODE_AUTO=3
PID_COMPACT_MODE_MANUAL=4

#PhysicalQuantity
PID_COMPACT_PHYSICAL_GENERAL=0
PID_COMPACT_PHYSICAL_TEMPERATURE=1
PID_COMPACT_PHYSICAL_PRESSURE=2
PID_COMPACT_PHYSICAL_LENGTH=3
PID_COMPACT_PHYSICAL_FLOW=4
PID_COMPACT_PHYSICAL_BRIGHTNESS=5
PID_COMPACT_PHYSICAL_LLLUMINANCE=6
PID_COMPACT_PHYSICAL_FORCE=7
PID_COMPACT_PHYSICAL_TORQUE=8
PID_COMPACT_PHYSICAL_MASS=9
PID_COMPACT_PHYSICAL_CURRENT=10
PID_COMPACT_PHYSICAL_VOLTAGE=11
PID_COMPACT_PHYSICAL_POWER=12
PID_COMPACT_PHYSICAL_AREA=13
PID_COMPACT_PHYSICAL_VOLUME=14
PID_COMPACT_PHYSICAL_ANGLE=15
PID_COMPACT_PHYSICAL_VISCOSITY=16
PID_COMPACT_PHYSICAL_SPEED=17
PID_COMPACT_PHYSICAL_VELOCITY=18
PID_COMPACT_PHYSICAL_DENSITY=19
PID_COMPACT_PHYSICAL_FREQUENCY=20
PID_COMPACT_PHYSICAL_ANGULAR_VELOCITY=21

#PhysicalUnit

PID_COMPACT_PHYSICAL_GENERAL_UNIT_PERCENTAGE=0
PID_COMPACT_PHYSICAL_TEMPERATURE_UNIT_C=0
PID_COMPACT_PHYSICAL_TEMPERATURE_F=1
PID_COMPACT_PHYSICAL_TEMPERATURE_K=2

パラメータ設定

def SetTOParas(to,config,Value):
    paras=to.Parameters.Find(config)
    print(paras.Name+' is '+str(paras.Value)+'.')
    paras.Value=Value
    print(paras.Name+'is changed to '+str(paras.Value)+'.')

#Mode
config='Mode'
# paras=pid_compact.Parameters.Find(config)
SetTOParas(pid_compact,config,PID_COMPACT_MODE_MANUAL)

#PhysicalQuantity
config='PhysicalQuantity'
SetTOParas(pid_compact,config,PID_COMPACT_PHYSICAL_TEMPERATURE)

config='PhysicalUnit'
SetTOParas(pid_compact,config,PID_COMPACT_PHYSICAL_TEMPERATURE_F)

#PID values set by user
config='_Retain.CtrlParams.SetByUser'
SetTOParas(pid_compact,config,True)

config='Retain.CtrlParams.Gain'
SetTOParas(pid_compact,config,1.1)

config='Retain.CtrlParams.Ti'
SetTOParas(pid_compact,config,20.1)

config='Retain.CtrlParams.Td'
SetTOParas(pid_compact,config,0.1)

High_Speed_Counter

to_high_speed_counter=[]
for i in range(2):
    toName='High_Speed_Counter_'+str(i)
    toType='High_Speed_Counter'
    version=vr("3.0")
    temp=to11.Create(toName,toType,version)
    to_high_speed_counter.append(temp)

TO_PositioningAxis

いまの構成はこうです:
image.png

Object作成

to11=software.TechnologicalObjectGroup.TechnologicalObjects
TO_PositioningAxis=[]

for i in range(2):
    toName='TO_PositioningAxis'+str(i)
    toType='TO_PositioningAxis'
    version=vr("3.0")
    temp=to11.Create(toName,toType,version)
    TO_PositioningAxis.append(temp)
TO_PositioningAxis[0].Name

Objectのパラメータ設定

TO_PositioningAxis[0].Parameters.Find('Actor.DataAdaption').Value=1
TO_PositioningAxis[0].Parameters.Find('_Actor.Interface.Telegram').Value=105
TO_PositioningAxis[0].Parameters.Find('_Sensor[1].Interface.Telegram').Value=105

PLCとConnectする

#Get the Positioning Axis Object
x=TO_PositioningAxis[0]
#Get the AxisHardwareConnectionProvider from Motion packages
AxisHardwareConnectionProvider=x.GetService[Motion.AxisHardwareConnectionProvider]()

for device in myproject.Devices:
    for deviceitem in device.DeviceItems:
        print(deviceitem.Name)

v90=myproject.Devices[1].DeviceItems
v90_1=v90[1].DeviceItems[1]
v90_1_Deviceitem=v90[1].DeviceItems
v90_1_Deviceitem[2].DeviceItems[2].Name

AxisHardwareConnectionProvider.ActorInterface.Connect(v90_1_Deviceitem[2].DeviceItems[2])

image.png

Full Code

import clr
clr.AddReference('C:\\Program Files\\Siemens\\Automation\\Portal V15_1\PublicAPI\\V15.1\\Siemens.Engineering.dll')
from System.IO import DirectoryInfo,FileInfo
import Siemens.Engineering as tia
import Siemens.Engineering.HW.Features as hwf
import Siemens.Engineering.SW.TechnologicalObjects.Motion as Motion

from Siemens.Engineering.SW.TechnologicalObjects import TechnologicalInstanceDB 
from System import Version as vr

def openTIAProject(tia,open_path):

    try:
        project=tia.Projects.Open(open_path)
        return project
    except Exception as e:
        print(e)
        return None

open_path=FileInfo('C:\\tiav15_1_project\\project\\porject\\AppTest\\AppTest.ap15_1')

#Starting TIA
print ('Starting TIA with UI')
mytia = tia.TiaPortal(tia.TiaPortalMode.WithUserInterface)
myproject=openTIAProject(mytia,open_path)


kkkk=tia.IEngineeringServiceProvider((myproject.Devices[0].DeviceItems[1])).GetService[hwf.SoftwareContainer]()
software=kkkk.get_Software()
to11=software.TechnologicalObjectGroup.TechnologicalObjects
TO_PositioningAxis=[]



for i in range(2):
    toName='TO_PositioningAxis'+str(i)
    toType='TO_PositioningAxis'
    version=vr("3.0")
    temp=to11.Create(toName,toType,version)
    TO_PositioningAxis.append(temp)
TO_PositioningAxis[0].Name

kkkk=tia.IEngineeringServiceProvider((myproject.Devices[0].DeviceItems[1])).GetService[hwf.SoftwareContainer]()
software=kkkk.get_Software()

#Get the Positioning Axis Object
x=TO_PositioningAxis[0]
#Get the AxisHardwareConnectionProvider from Motion packages
AxisHardwareConnectionProvider=x.GetService[Motion.AxisHardwareConnectionProvider]()

for device in myproject.Devices:
    for deviceitem in device.DeviceItems:
        print(deviceitem.Name)

v90=myproject.Devices[1].DeviceItems
v90_1=v90[1].DeviceItems[1]
v90_1_Deviceitem=v90[1].DeviceItems
v90_1_Deviceitem[2].DeviceItems[2].Name

AxisHardwareConnectionProvider.ActorInterface.Connect(v90_1_Deviceitem[2].DeviceItems[2])

Processes

いま開いてるTIAをもらう。そのためにProcessesを使います。

import clr
clr.AddReference('C:\\Program Files\\Siemens\\Automation\\Portal V15_1\PublicAPI\\V15.1\\Siemens.Engineering.dll')
from System.IO import DirectoryInfo,FileInfo
import Siemens.Engineering as tia
import Siemens.Engineering.HW.Features as hwf
import Siemens.Engineering.SW.TechnologicalObjects.Motion as Motion

from Siemens.Engineering.SW.TechnologicalObjects import TechnologicalInstanceDB 
from System import Version as vr

print('Hello,let me to get your process..')
processes=tia.TiaPortal.GetProcesses()
i=1
for process in processes:
    print('---'*10)

    #get the Process information
    print('Process{} Information\n'
            '-Path:{}\n'
            '-Acquisition Time:{}\n'
            '-ID:{}\n'
            '-UI:{}\n'
                .format(
                    i
                    ,process.ProjectPath
                    ,process.AcquisitionTime
                    ,process.Id
                    ,('Yes' if process.Mode >=1 else 'No')


            ))

    attach=process.Attach()
    for project in attach.get_Projects():

        print('Project Information\n'
                '-Name:{}\n'
                '-Author:{}\n'
                '-Comment:{}\n'
                '-Copy Right:{}\n'
                '-Creation time:{}\n'
                '-Family:{}\n'\
                '-IsModified:{}\n'
                '-Language Settings:{}\n'
                '-Last Modified:{}\n'
                '-Last Modified By:{}\n'
                '-Name:{}\n'
                '-Path:{}\n'
                '-Size:{}\n'
                '-Version:{}\n'
                    .format(
                        project.Name
                        ,project.Author
                        ,project.Comment
                        ,project.Copyright
                        ,project.CreationTime
                        ,project.Family
                        ,project.IsModified
                        ,project.LanguageSettings
                        ,project.LastModified
                        ,project.LastModifiedBy
                        ,project.Name
                        ,project.Path
                        ,project.Size
                        ,project.Version
                ))

        print('Used Product:')
        for UsedProduct in project.get_UsedProducts():
            print('-'+UsedProduct.Name)
    i+=1

print('\n')
a= input('Press key to exit\n')
if a :
    exit(0)

Hmi

hmitarget

import Siemens.Engineering.Hmi as Hmi
import Siemens.Engineering.Hmi.Tag as HmiTag
import Siemens.Engineering.Hmi.Screen as HmiScreen
import Siemens.Engineering.Hmi.Cycle as HmiCycle
import Siemens.Engineering.Hmi.Communication as HmiCommunication
import Siemens.Engineering.Hmi.Globalization as HmiGlobalization
import Siemens.Engineering.Hmi.TextGraphicList as HmiTextGraphicList
import Siemens.Engineering.Hmi.RuntimeScripting as HmiRuntimeScripting
from Siemens.Engineering import ExportOptions as ExportOptions
from Siemens.Engineering import ImportOptions as ImportOptions

FUNCTION_END_WITHOUT_ERROR=7000
FUNCTION_END_WITH_ERROR=8900
IMPORT_HMI_PATH_CYCLES='C:\\tia_ExternalApps\\Export\\hmi\\templates\\templates.xml'
IMPORT_HMI_PATH_CYCLES_TEMP='C:\\tia_ExternalApps\\Export\\hmi\\templates\\_templates.xml'

Hmi1=project.Devices[2]

for Device in Hmi1.DeviceItems:
    print(Device.Name)

hmitarget=tia.IEngineeringServiceProvider(Hmi1.DeviceItems[3]).GetService[hwf.SoftwareContainer]().Software

Create Screen Folder

def CreateScreenFolder(hmitaget,FolderName=''):
    '''Function to Create the ScreenFodler Inside your HMI_RT

    Parameters
    ----------
    hmitarget:HmiTarget Objects
        The Object that you get from hwf.SoftwareContainer.
    FolderName:String
        The Folder Name that you would like to create.

    Returns
    ----------
    8900:
        If Exception is happened while Function executing.
    ScreenUserFolder:
        The Screen Folder Object that you created.

    '''
    try:
        hmitarget.ScreenFolder.Folders.Create(folderName)
    except Exception as e:
        print(e)
        return FUNCTION_END_WITH_ERROR
    return hmitarget.ScreenFolder.Folders.Find(folderName)

Delete Screen From Folder

def DeleteScreenFromFolder(hmitarget,FolderName,ScreenName):
    '''Function to Delete the Screen Locate on the folder Inside your HMI_RT

    Parameters
    ----------
    hmitarget:HmiTarget Objects
        The Object that you get from hwf.SoftwareContainer.
    FolderName:String
        The Name of Folder that contatins the Screen which you want to delete.
    ScreenName:String
        The Name of Screen that you want to delete.

    Returns
    ----------
    8000:
        Screen can not found inside the folder.
    8900:
        Screen is found, but Exception is happened while screen.Delete() executing.
    7000:
        Function is end without Error.

    '''
    try:
        screenuserFolder=hmitarget.ScreenFolder.Folders.Find(FolderName)
        screens=screenuserFolder.Screens
        screen=screens.Find(ScreebnName)
        if screen is None:
            return 8000
        else:
            screen.Delete()
    except Exception as e:
        print(e)
        return FUNCTION_END_WITH_ERROR

    return FUNCTION_END_WITHOUT_ERROR

Delete ScreenTemplate from folder

def DeleteScreenTemplateFromFolder(hmitarget,FolderName,ScreenName):
    '''Function to Delete the Templatescreen Locate on the Templatefolder Inside your HMI_RT

    Parameters
    ----------
    hmitarget:HmiTarget Objects
        The Object that you get from hwf.SoftwareContainer.
    FolderName:String
        The Name of Templatefolder that contatins the Screen which you want to delete.
    ScreenName:String
        The Name of Templatescreen that you want to delete.

    Returns
    ----------
    8000:
        Screen can not found inside the folder.
    8900:
        Screen is found, but Exception is happened while screen.Delete() executing.
    7000:
        Function is end without Error.

    '''
    try:
        folder=hmitarget.ScreenTemplateFolder.Folders.Find(FolderName)
        if folder is None:
            return 8000
        else:
            templates=folder.ScreenTemplates
            template=templates.Find(ScreenName)
            if template is None:
                return 8001
            else:
                template.Delete()
    except Exception as e:
        print(e)
        return FUNCTION_END_WITH_ERROR

    return FUNCTION_END_WITHOUT_ERROR

Delete All Screen from folder

def DeleteAllScreensFromFolder(hmitarget,FolderName):
    '''Function to Delete the All Scrrens Locate on the folder Inside your HMI_RT

    Parameters
    ----------
    hmitarget:HmiTarget Objects
        The Object that you get from hwf.SoftwareContainer.
    FolderName:String
        The Name of folder that contatins the Screen which you want to delete.

    Returns
    ----------
    8000:
        Screen can not found inside the folder.
    8900:
        Screen is found, but Exception is happened while screen.Delete() executing.
    7000:
        Function is end without Error.

    '''
    try:
        folder=hmitarget.ScreenFolder.Folders.Find(FolderName)
        if folder is None:
            return 8000
        else:
            screens=folder.Screens
            screenlist=[]
            for screen in screens:
                screenlist.append(screen)
            for screen in screenlist:
                print('{} is deleted.'.format(screen.Name))
                screen.Delete()
    except Exception as e:
        print(e)
        return FUNCTION_END_WITH_ERROR

    return FUNCTION_END_WITHOUT_ERROR

Delete Cycles

def DeleteCycle(hmitarget,CycleName):
    '''Function to Delete the Cycles Inside your HMI_RT

    Parameters
    ----------
    hmitarget:HmiTarget Objects
        The Object that you get from hwf.SoftwareContainer.
    Cycle:String
        The Name of cycles that  you want to delete.

    Returns
    ----------
    8000:
        Screen can not found inside the folder.
    8900:
        Screen is found, but Exception is happened while screen.Delete() executing.
    7000:
        Function is end without Error.

    '''
    try:
        cycles=hmitarget.Cycles
        cycle=cycles.Find(CycleName)
        if cycle is None:
            return 8000
        else:
            print('{} is deleted.'.format(cycle.Name))

            cycle.Delete()
    except Exception as e:
        print(e)
        return FUNCTION_END_WITH_ERROR

    return FUNCTION_END_WITHOUT_ERROR

DeleteCycle(hmitarget,'Cycle_2')

Create Cycles

まず、CyclesをExportしたらこのようなXMLがあります。

<Hmi.Cycle.Cycle ID="0">
    <AttributeList>
      <CycleTime>250</CycleTime>
      <CycleUnit>Second</CycleUnit>
      <Name>CYCLE TIME TEST</Name>
      <StartAtStartingPoint>true</StartAtStartingPoint>
      <StartingPoint>****-**-**T**:**:**</StartingPoint>
      <TriggerAtShutdown>false</TriggerAtShutdown>
      <TriggerAtStartup>false</TriggerAtStartup>
    </AttributeList>
    <ObjectList>
      <MultilingualText CompositionName="Comment" ID="1">
        <ObjectList>
          <MultilingualTextItem CompositionName="Items" ID="2">
            <AttributeList>
              <Culture>en-US</Culture>
              <Text></Text>
            </AttributeList>
          </MultilingualTextItem>
        </ObjectList>
      </MultilingualText>
    </ObjectList>
  </Hmi.Cycle.Cycle>

その中に触る必要あるのは、CycleTime,CycleUnit,Nameかな?
なので、ElementTree XMLを使ってXMLの中身を編集し、TIAをへImportします。

import xml.etree.ElementTree as ET
def CreateHmiCycles(hmitarget,Name='Cycle_',CycleTime='1',CycleUnit='Second'):

    tree=ET.parse(IMPORT_HMI_PATH_CYCLES)
    root=tree.getroot()
    AttributeList=root.find('AttributeList')
    AttributeList.find('CycleTime').text=CycleTime
    AttributeList.find('CycleUnit').text=CycleUnit

    i,CycleName=1,Name


    while True:
        Cycle=hmitarget.Cycles.Find(CycleName)
        if Cycle is not None:
            CycleName=Name+'_'+str(i)
            i+=1
            print(CycleName)
        else:
            AttributeList.find('Name').text=CycleName
            break

        if i>100:
            break


    tree.write(IMPORT_HMI_PATH_CYCLES_TEMP)

    hmitarget.Cycles.Import(FileInfo(IMPORT_HMI_PATH_CYCLES_TEMP),ImportOptions.Override)



CreateHmiCycles(hmitarget,'Cycle11',CycleTime='1')

はい、以上ですー

soup01
free access to information is important. 仕事でFA AREAをやって趣味はPythonなど。 楽しいことたくさんやりたい。 知らない世界へ飛び込みたい。 あと、外国人です。
http://soup01.com/ja/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした