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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/f278ba83-47a8-4eb4-4b49-74917c0624ee.png)


#紹介
- [TIA Portal Openness: Introduction and Demo Application](https://support.industry.siemens.com/cs/document/108716692/tia-portal-openness%3A-introduction-and-demo-application?dti=0&lc=en-US)
- [Basic example on how to use openness with Python using Pythonnet](https://github.com/Maroder1/TIA-openness)
- [Advantages & Disadvantages of Siemens' TIA Openness](https://www.dmcinfo.com/latest-thinking/blog/id/9877/advantages-disadvantages-of-siemens-tia-openness)

##ビデオ
- [TIA Portal Openness - Generation of multiple customised projects, at the same time!](https://www.youtube.com/watch?v=KCmhM9Eyyss)
- [TIA Portal Openness - Automatic project generation](https://www.youtube.com/watch?v=xew__sEwZlA)
- [Openness - Efficient generation of program code using code generators	
](https://www.youtube.com/watch?v=Ki12pLbEcxs)

##Manual
- [SIMATIC Openness: Automating creation of projects](https://support.industry.siemens.com/cs/document/109477163/simatic-openness%3A-automating-creation-of-projects?dti=0&lc=en-WW)
- [TIA Portal Openness: Generating a Modular Machine with S7-1500]()

##作業環境
- Python 3.7.1
- pythonnet
- Jupyter

##インストールするときの不明点
- [FAQ – Import/Export Tool for TIA Portal](http://www.itris-automation.com/faq-importexport-tool-tia-portal/)

##プログラミングステップ
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/570550c6-c1cb-e145-f1ea-9088ef00d3ea.png)
###GlobalLibrary
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/06d21d05-994e-6f4a-8e6e-38c00901e087.png)
###ProjectLibrary
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/43260533-122c-d041-a458-624299692004.png)
###HmiTarget
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/73e58e0d-a854-0a52-c0ad-257405358416.png)
###PlcSoftware
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/98bc54f7-5148-f5bb-22a0-40fa5f1056a8.png)

各Objectの関係：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/54832f2f-9ab4-87cf-48de-45270afe1d39.png)


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

#実装

##プロジェクト作成

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

```Python: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)
```

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

```Python: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)
```


##プロジェクトを閉じる
```Python
myproject.Close()
```
##プロジェクトを保存
```Python
myproject.Save()
```

##プロジェクトの情報もらう
```Python
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/880ce345-0630-3ef2-ca33-19852c8ad764.png)

そのCheckBox入れると、Hardware Catalogの表示はこんな風に変わります：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/b920b2a8-a8a3-7dd7-8d88-83d060feb667.png)

###Device追加

```Python: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

```Python
myproject.ShowHwEditor(tia.HW.View.Topology)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/2b5827aa-da35-9d35-2f6a-0a6deec2dbf0.png)

###NetworkView
```Python
myproject.ShowHwEditor(tia.HW.View.Network)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/114a0c55-843d-cfe3-08a8-34ffbc3d9cb3.png)

###Device view
```Python
myproject.ShowHwEditor(tia.HW.View.Device)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/4b475e3b-d9df-b524-ae52-eee9dfc5a1ba.png)

##Languages
###英語追加
```Python
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もらう
```Python
SoftwareContainer=tia.IEngineeringServiceProvider((myproject.Devices[0].DeviceItems[1])).GetService[hwf.SoftwareContainer]()
software=SoftwareContainer.get_Software()
```
###Tagテーブル追加

```Python
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追加
```Python
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/b5b89627-2654-c090-3c32-15ee95cb1f63.png)

###プロジェクトコンパイル

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

##BlockとBlockグループ
###Blockグループもらう
```Python
BlockGroup=software.BlockGroup
```

###BlockグループにあるBlock情報もらう
```Python
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/dfc47860-9597-3c9a-9cc4-5ac3199fd163.png)

###Blockグループ作成
```Python
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グループ探す
```Python
Block_autoNumber=Groups.Find('TestGroup').Blocks.Find('Block_1').GetAttribute('AutoNumber')
```
###Blockグループ削除
```Python
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グループを回す
```Python
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/2d2e1b05-9ae2-3a40-11b1-56026c62a7f0.png)

###BlockをExport
```Python
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
```Python
gex=Groups.Find('TestGroup')
bex=gex.Blocks.Import(save_path,ImportOptions.Override)
```
###Blockをアクセス
```Python
def AccessASingleBlock(plcsoftware,blockname):
    return plcsoftware.BlockGroup.Blocks.Find(blockname)

block=AccessASingleBlock(software,'Main')
```

###Blockの設定変更
```Python
block=AccessASingleBlock(software,'Block_1')
block.SetAttribute('AutoNumber',False)
block.SetAttribute('Number',999)
```

###Blockをまわす
```Python
def EnumerateAllBlocks(plcsoftware):
    for block in software.BlockGroup.Blocks:
        print(block.Name)
    
EnumerateAllBlocks(software)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/a7fb45f0-d4c6-aa16-00ef-dd6b3df5b2c9.png)

##PLC操作
###Online
```Python
from Siemens.Engineering.Online import OnlineProvider
plc=myproject.Devices[0]
plc1=plc.DeviceItems[1]
plc_online=plc1.GetService[OnlineProvider]()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/01d1f968-3502-866d-3255-2889a2ad2623.png)

####Connection interface Configure
```Python
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/31760262-e6fc-883d-adcb-847ed357c3ce.png)

####Get the Connection By Name
```Python
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
```Python
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/98f31e6c-9141-4d9a-36aa-e6b6ca6c6f54.png)

###Go Offline/Online
```Python
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/47ce3f5b-c8fc-9f61-4ec1-69a0b39f520a.png)

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

###Subnet作る
```Python
myproject.Subnets.Create('System:Subnet.Ethernet','NewSubNet2')
```

###Subnetがあるかを確認
もしなかったらNoneが戻ってきます。

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

###SubnetのIPなど変更
```Python
#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作る
```Python
#Create IO System
ioSystem = n_interfaces[0].IoControllers[0].CreateIoSystem("PNIO");
```

###接続
```Python
#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
```Python
from Siemens.Engineering.SW.TechnologicalObjects import TechnologicalInstanceDB 
from System import Version as vr
```
###PID_Compact
```Python
to11=software.TechnologicalObjectGroup.TechnologicalObjects
toName="PID_Compact_1"
toType='PID_Compact'
version=vr("2.3")
pid_compact=to11.Create(toName,toType,version)

```
####
```Python
#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

```
####パラメータ設定
```Python
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
```Python
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/18ad101d-a92e-f46a-7cbd-ed97403a1926.png)

###Object作成
```Python
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のパラメータ設定
```Python
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する
```Python
#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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/9a7251f1-a1fd-6e21-41d1-efff56ed1724.png)

##Full Code
```Python
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を使います。

```Python
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
```Python
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
```Python
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
```Python
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
```Python
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
```Python
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
```Python
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があります。

```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します。

```Python
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')
```

はい、以上ですー