How to scan devices and boxes

Requirements

When creating a new configuration, it is often necessary to align the TwinCAT XAE configuration to the actually available hardware. One option to fulfill this is to start a new TwinCAT XAE configuration from scratch and process the following steps: Creation of a new TwinCAT XAE configuration

Procedure

The procedure to create the ITcSysManager interface (the 'systemManager' instance here) is described in the chapter Accessing TwinCAT Configurations. This interface has a LookupTreeItem method that returns a ITcSmTreeItem pointer to a specific tree item given by its pathname, in this case the shortcut "TIID" which references the I/O devices node.

Code snippet (C#):

ITcSysManager3 systemManager = null; // How to create the System Manager instance and how to open configuration is shown in Concepts chapter     

public void ScanDevicesAndBoxes()
{
     systemManager.SetTargetNetId("1.2.3.4.5.6"); // Setting of the target NetId.
     ITcSmTreeItem ioDevicesItem = systemManager.LookupTreeItem("TIID"); // Get The IO Devices Node
     
     // Scan Devices (Be sure that the target system is in Config mode!)
     string scannedXml = ioDevicesItem.ProduceXml(false); // Produce Xml implicitly starts the ScanDevices on this node.
     
     XmlDocument xmlDoc = newXmlDocument();
     xmlDoc.LoadXml(scannedXml); // Loads the Xml data into an XML Document
     XmlNodeList xmlDeviceList = xmlDoc.SelectNodes("TreeItem/DeviceGrpDef/FoundDevices/Device");
     List<ITcSmTreeItem> devices = newList<ITcSmTreeItem>();
     
     int deviceCount = 0;
       
     // Add all found devices to configuration
     foreach (XmlNode node in xmlDeviceList)
     {
          // Add a selection or subrange of devices
          int itemSubType = int.Parse(node.SelectSingleNode("ItemSubType").InnerText);
          string typeName = node.SelectSingleNode("ItemSubTypeName").InnerText;
          XmlNode xmlAddress = node.SelectSingleNode("AddressInfo");
    
          ITcSmTreeItem device = ioDevicesItem.CreateChild(string.Format("Device_{0}",++deviceCount),itemSubType,string.Empty,null);
         
          string xml = string.Format("<TreeItem><DeviceDef>{0}</DeviceDef></TreeItem>",xmlAddress.OuterXml);
          device.ConsumeXml(xml); // Consume Xml Parameters (here the Address of the Device)
          devices.Add(device);
     }
 
     // Scan all added devices for attached boxes
     foreach (ITcSmTreeItem device in devices)
     {
          string xml = "<TreeItem><DeviceDef><ScanBoxes>1</ScanBoxes></DeviceDef></TreeItem>"; // Using the "ScanBoxes XML-Method"
          try
          {
               device.ConsumeXml(xml); // Consume starts the ScanBoxes and inserts every found box/terminal into the configuration
          }
          catch (Exception ex)
          { 
               Console.WriteLine("Warning: {0}",ex.Message);
          } 
    
          foreach (ITcSmTreeItem box in device)
          {
               Console.WriteLine(box.Name);
          }
     }
}

Code snippet (IronPython):

import xml.etree.ElementTree as ET 

# Create the System Manage 
instance “sysMan” first
ioDevicesItem = sysMan.LookupTreeItem("TIID") # Get the IO Devices Node
scannedXml = ioDevicesItem.ProduceXml(False)  # Produce Xml implicitly starts the ScanDevices on this node

xmlDoc =      ET.fromstring(scannedXml) # Loads the Xml data into an XML Document
xmlDeviceList = xmlDoc.findall("./DeviceGrpDef/FoundDevices/Device")
devices = [] # Container to store Scanned devices
deviceCount = 0


# Add the Scanned devices
for device in xmlDeviceList:
       typeName = device.findtext("ItemSubTypeName")
    itemSubType = device.findtext("ItemSubType")
     xmlAddress = device.find("AddressInfo")
 deviceCount = deviceCount + 1;
  device =      ioDevicesItem.CreateChild("Device_" + str(deviceCount) + typeName, itemSubType,"",None)
      xml = "<TreeItem><DeviceDef>" + ET.tostring(xmlAddress) + "</DeviceDef></TreeItem>"
    device.ConsumeXml(xml); # Consumes Xml Parameters (here the Address of the Device)
    devices.append(device);

for device in devices:
      xml = "<TreeItem><DeviceDef><ScanBoxes>true</ScanBoxes></DeviceDef></TreeItem>"
      try:
      print device.ConsumeXml(xml) # Consumes starts the ScanBoxes and inserts every found box/Terminal into the config
     except:
        print "Scan Failed!"

for box in device:
   print box.Name