XML
To generate XMLs, I recommend using ElementTree to build xml documents instead of having to mix and match the XML and XSD schemas.
Schema
The schema can be found within the same parent directory of Siemens.Engineering.dll with the name Schemas.
Currently, I am playing with C:\Program Files\Siemens\Automation\Portal V18\PublicAPI\V18\Schemas
.
I don’t know how to read XMLSchemas so I am using xmlschema library.
I dump out the parts of schema instead.
import xmlschema
schema = xmlschema.XMLSchema(<<XSD FILE PATH HERE>>)
print("Elements:")
for element in schema.elements:
print(f"- {element} : {schema.elements[element]}")
print("\nTypes:")
for type_name, schema_type in schema.types.items():
print(f"- {type_name} : {schema_type}")
Each schemas in the directory are not dependent of each other. I think they act as a reference guide rather than a fully built XML schema (what I am thinking of is a generator or a builder).
When converting a decoded XML back to XML, sometimes you get issues such as this and this.
To fix this, simply add preserve_root=True
on both decoding and encoding phase.
obj = schema.decode(xxx, preserve_root=True)
collection = schema.encode(obj, preserve_root=True)
collection
This code is based on the documentation.
SW.InterfaceSections_v5.xsd
Validates the Sections
child element of Interface
.
This schema is useful for creating multi instancedb. |
For example:
<Interface>
<Sections>
<Section Name="Input" />
<Section Name="Output" />
<Section Name="InOut" />
<Section Name="Static">
<Member Name="Data_Point_Instance" Datatype=""Data_Point"" Accessibility="Public">
<AttributeList>
<BooleanAttribute Name="ExternalAccessible" SystemDefined="true">true</BooleanAttribute>
<BooleanAttribute Name="ExternalVisible" SystemDefined="true">true</BooleanAttribute>
<BooleanAttribute Name="ExternalWritable" SystemDefined="true">true</BooleanAttribute>
<BooleanAttribute Name="UserVisible" Informative="true" SystemDefined="true">true</BooleanAttribute>
<BooleanAttribute Name="UserReadOnly" Informative="true" SystemDefined="true">false</BooleanAttribute>
<BooleanAttribute Name="UserDeletable" Informative="true" SystemDefined="true">true</BooleanAttribute>
<BooleanAttribute Name="SetPoint" SystemDefined="true">true</BooleanAttribute>
</AttributeList>
<Sections>
<Section Name="Input">
<Member Name="Gate 2" Datatype="Bool" />
<Member Name="Gate 1" Datatype="Bool" />
</Section>
<Section Name="Output">
<Member Name="Open" Datatype="Bool" />
</Section>
<Section Name="InOut" />
<Section Name="Static" />
</Sections>
</Member>
</Section>
<Section Name="Temp" />
<Section Name="Constant" />
</Sections>
</Interface>
If the element Section contains an attribute, the validation will fail.
FlgNet
Wires
Every network calls (instances) will always have a wire named "en".
...
<NameCon UId="21" Name="en" />
...
New wires will be created similar to "en" with its specific parameter name from the parts with the UId of the call.
...
<NameCon UId="21" Name="Wire 1" />
...
...
<NameCon UId="21" Name="Wire 2" />
...
...
<NameCon UId="21" Name="Wire 3" />
...
If a wire is not connected to anything, it will always have "OpenCon" in its element.
...
<OpenCon UId="23" />
<NameCon UId="21" Name="en" />
...
Wire "en" will always connect to a network call, thus it will never have "OpenCon" as its connection at the end.
Organization Block
In general, UIds for all attributes should be unique to avoid errors.
An example of this error is There are at least two definitions for UIds. The incorrect unique ID is '132'.
<?xml version="1.0" encoding="utf-8"?>
<Document>
<SW.Blocks.OB ID="0">
<AttributeList>
<Name>$NAME</Name>
<Namespace />
<Number>$NUMBER</Number> (1)
<ProgrammingLanguage>$PROGRAMMING_LANGUAGE</ProgrammingLanguage>
<SecondaryType>ProgramCycle</SecondaryType>
</AttributeList>
<ObjectList>
<MultilingualText ID="1" CompositionName="Comment">
<ObjectList>
<MultilingualTextItem ID="2" CompositionName="Items">
<AttributeList>
<Culture>en-US</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
<SW.Blocks.CompileUnit /> (2)
<MultilingualText ID="D" CompositionName="Title">
<ObjectList>
<MultilingualTextItem ID="E" CompositionName="Items">
<AttributeList>
<Culture>en-US</Culture>
<Text>"Main Program Sweep (Cycle)"</Text>
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
</ObjectList>
</SW.Blocks.OB>
</Document>
1 | Acceptable values must be within this range: 1; 123-32767 . |
2 | Refer to this XML attribute: SW.Blocks.CompileUnit. |
<SW.Blocks.CompileUnit ID="$ID" CompositionName="CompileUnits">
<AttributeList>
<NetworkSource>
<FlgNet
xmlns="http://www.siemens.com/automation/Openness/SW/NetworkSource/FlgNet/v4">
<Parts>
$PARTS
</Parts>
<Wires>
<Wire /> (1)
</Wires>
</FlgNet>
</NetworkSource>
<ProgrammingLanguage>$PROGRAMMING_LANGUAGE</ProgrammingLanguage>
</AttributeList>
</SW.Blocks.CompileUnit>
1 | Refer to this XML attribute: Wire (First) or Wire. |
<Call UId="$UID">
<CallInfo Name="$NAME" BlockType="$BLOCK_TYPE">
<IntegerAttribute Name="BlockNumber" Informative="true">$BLOCK_NUMBER</IntegerAttribute>
<Instance Scope="GlobalVariable" UId="$INSTANCE_UID">
<Component Name="$COMPONENT_NAME" />
<Address Area="DB" Type="$DB_TYPE" BlockNumber="$DB_BLOCK_NUMBER" BitOffset="0" Informative="true" />
</Instance>
</CallInfo>
</Call>
<Wire UId="$UID">
<Powerrail />
<NameCon UId="$EN_UID" Name="en" /> (1)
</Wire>
1 | Must be a value from a Call UId. |
<Wire UId="$UID">
<NameCon UId="$ENO_UID" Name="eno" />
<NameCon UId="$EN_UID" Name="en" /> (1)
</Wire>
1 | Must be a value from a Call UId. |
Default XMLs
The base template of what’s needed when building your own XML.
Notice below that there are 5 common elements AttributeList:
-
Interface
-
Name
-
Namespace
-
Number
-
ProgrammingLanguage
OB
<?xml version="1.0" encoding="utf-8"?>
<Document>
<SW.Blocks.OB ID="0">
<AttributeList>
<Interface>
<Sections
xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
<Section Name="Input">
<Member Name="Initial_Call" Datatype="Bool" Informative="true">
<Comment>
<MultiLanguageText Lang="en-US">Initial call of this OB</MultiLanguageText>
</Comment>
</Member>
<Member Name="Remanence" Datatype="Bool" Informative="true">
<Comment>
<MultiLanguageText Lang="en-US">=True, if remanent data are available</MultiLanguageText>
</Comment>
</Member>
</Section>
<Section Name="Temp" />
<Section Name="Constant" />
</Sections>
</Interface>
<Name>Main</Name>
<Namespace />
<Number>1</Number>
<ProgrammingLanguage>LAD</ProgrammingLanguage>
<SecondaryType>ProgramCycle</SecondaryType>
</AttributeList>
<ObjectList>
<SW.Blocks.CompileUnit ID="3" CompositionName="CompileUnits">
<AttributeList>
<NetworkSource />
<ProgrammingLanguage>LAD</ProgrammingLanguage>
</AttributeList>
</SW.Blocks.CompileUnit>
</ObjectList>
</SW.Blocks.OB>
</Document>
FB
<?xml version="1.0" encoding="utf-8"?>
<Document>
<SW.Blocks.FB ID="0">
<AttributeList>
<Interface>
<Sections
xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
<Section Name="Input" />
<Section Name="Output" />
<Section Name="InOut" />
<Section Name="Static" />
<Section Name="Temp" />
<Section Name="Constant" />
</Sections>
</Interface>
<Name>FB_1</Name>
<Namespace />
<Number>1</Number>
<ProgrammingLanguage>FBD</ProgrammingLanguage>
</AttributeList>
<ObjectList>
<SW.Blocks.CompileUnit ID="3" CompositionName="CompileUnits">
<AttributeList>
<NetworkSource />
<ProgrammingLanguage>FBD</ProgrammingLanguage>
</AttributeList>
</SW.Blocks.CompileUnit>
</ObjectList>
</SW.Blocks.FB>
</Document>
FC
<?xml version="1.0" encoding="utf-8"?>
<Document>
<SW.Blocks.FC ID="0">
<AttributeList>
<Interface>
<Sections
xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
<Section Name="Input" />
<Section Name="Output" />
<Section Name="InOut" />
<Section Name="Temp" />
<Section Name="Constant" />
<Section Name="Return">
<Member Name="Ret_Val" Datatype="Void" />
</Section>
</Sections>
</Interface>
<Name>FC_1</Name>
<Namespace />
<Number>1</Number>
<ProgrammingLanguage>FBD</ProgrammingLanguage>
</AttributeList>
<ObjectList>
<SW.Blocks.CompileUnit ID="3" CompositionName="CompileUnits">
<AttributeList>
<NetworkSource />
<ProgrammingLanguage>FBD</ProgrammingLanguage>
</AttributeList>
</SW.Blocks.CompileUnit>
</ObjectList>
</SW.Blocks.FC>
</Document>
DB
<?xml version="1.0" encoding="utf-8"?>
<Document>
<SW.Blocks.GlobalDB ID="0">
<AttributeList>
<Interface>
<Sections
xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
<Section Name="Static" />
</Sections>
</Interface>
<Name>DB_1</Name>
<Namespace />
<Number>1</Number>
<ProgrammingLanguage>DB</ProgrammingLanguage>
</AttributeList>
<ObjectList>
<MultilingualText ID="3" CompositionName="Title">
<ObjectList>
<MultilingualTextItem ID="4" CompositionName="Items">
<AttributeList>
<Culture>en-US</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
</ObjectList>
</SW.Blocks.GlobalDB>
</Document>