Einen Geräte-Scan durchführen

Ein Gerätescan erkennt die angeschlossene Hardware und trägt sie in die I/O-Konfiguration ein. Der Scan wird über ProduceXml(false) auf dem I/O-Knoten ausgelöst. Dieser Aufruf startet den Scan implizit und liefert die gefundenen Geräte synchron als XML zurück. Die Geräte werden anschließend aus dem XML ausgelesen, einzeln mit CreateChild angelegt und ihre Adressen per ConsumeXml gesetzt. Im letzten Schritt lädt ein Box-Scan auf jedem Gerät die untergeordneten Klemmen.

Voraussetzungen

C# Beispiel: Scan per ProduceXml als vollständiger Workflow

Soll der Scan auf einem entfernten Zielsystem laufen, wird zuerst die Target-NetId über SetTargetNetId gesetzt. Bei lokalem Betrieb entfällt dieser Schritt. ProduceXml(false) liefert die gefundenen Geräte unter dem Pfad TreeItem/DeviceGrpDef/FoundDevices/Device. Für jeden Geräteknoten werden ItemSubType und AddressInfo ausgelesen, das Gerät mit CreateChild angelegt und seine Adresse per ConsumeXml gesetzt. Zum Schluss lädt ScanBoxes die Klemmen jedes Geräts.

ITcSysManager3 systemManager = /* ... */;
systemManager.SetTargetNetId("1.2.3.4.5.6"); // remote target (omit for local)

ITcSmTreeItem ioDevicesItem = systemManager.LookupTreeItem("TIID");

// ProduceXml(false) triggers an implicit ScanDevices and returns found devices
string scannedXml = ioDevicesItem.ProduceXml(false);

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(scannedXml);

// Extract found devices from XML
XmlNodeList xmlDeviceList =
    xmlDoc.SelectNodes("TreeItem/DeviceGrpDef/FoundDevices/Device");

List<ITcSmTreeItem> devices = new List<ITcSmTreeItem>();
int deviceCount = 0;

foreach (XmlNode node in xmlDeviceList)
{
    int itemSubType = int.Parse(node.SelectSingleNode("ItemSubType").InnerText);
    XmlNode xmlAddress = node.SelectSingleNode("AddressInfo");

    // Create device in I/O configuration
    ITcSmTreeItem device = ioDevicesItem.CreateChild(
        string.Format("Device_{0}", ++deviceCount),
        itemSubType,
        string.Empty,
        null);

    // Apply address parameters from AddressInfo node
    string xml = string.Format(
        "<TreeItem><DeviceDef>{0}</DeviceDef></TreeItem>",
        xmlAddress.OuterXml);
    device.ConsumeXml(xml);

    devices.Add(device);
}

// Scan boxes/terminals for each found device
foreach (ITcSmTreeItem device in devices)
{
    string xml = "<TreeItem><DeviceDef><ScanBoxes>1</ScanBoxes></DeviceDef></TreeItem>";
    try
    {
        device.ConsumeXml(xml);
    }
    catch (Exception ex)
    {
        Console.WriteLine("Warning: {0}", ex.Message);
    }

    foreach (ITcSmTreeItem box in device)
    {
        Console.WriteLine(box.Name);
    }
}

PowerShell Beispiel

$ioDevicesItem = $systemManager.LookupTreeItem("TIID")

# ProduceXml(false) triggers an implicit ScanDevices and returns found devices
$scannedXml = $ioDevicesItem.ProduceXml($false)

[xml]$xmlDoc = $scannedXml
$xmlDeviceList = $xmlDoc.SelectNodes("TreeItem/DeviceGrpDef/FoundDevices/Device")

$devices = @()
$deviceCount = 0

foreach ($node in $xmlDeviceList) {
    $itemSubType = [int]$node.SelectSingleNode("ItemSubType").InnerText
    $xmlAddress  = $node.SelectSingleNode("AddressInfo")
    $deviceCount++

    # Create device in I/O configuration
    $device = $ioDevicesItem.CreateChild("Device_$deviceCount", $itemSubType, "", $null)

    # Apply address parameters from AddressInfo node
    $xml = "<TreeItem><DeviceDef>$($xmlAddress.OuterXml)</DeviceDef></TreeItem>"
    $device.ConsumeXml($xml)

    $devices += $device
}

# Scan boxes/terminals for each found device
foreach ($device in $devices) {
    try {
        $device.ConsumeXml("<TreeItem><DeviceDef><ScanBoxes>1</ScanBoxes></DeviceDef></TreeItem>")
    } catch {
        Write-Warning $_.Exception.Message
    }
}

Besonderheit bei CX/K-Bus-Geräten für CX9020 und KL-Klemmen

Bei CX-Steuerungen mit K-Bus-Interface muss vor dem Box-Scan ein explizites ReloadDevices auf dem I/O-Knoten aufgerufen werden. Ohne diesen Schritt liefert ScanBoxes bei diesen Geräten kein Ergebnis. Der Aufruf von ReloadDevices erzwingt das Neu-Einlesen der angeschlossenen Hardware durch den Treiber.

ITcSmTreeItem ioDevicesItem = systemManager.LookupTreeItem("TIID");
try
{
    ioDevicesItem.ConsumeXml(
        "<TreeItem><DeviceGrpDef><ReloadDevices>true</ReloadDevices></DeviceGrpDef></TreeItem>");
}
catch (Exception ex)
{
    Console.WriteLine("Warning: {0}", ex.Message);
}
// Afterwards run the regular scan via ProduceXml(false) (see above)
Einen Geräte-Scan durchführen 1:

ProduceXml(false) löst den Scan implizit aus und liefert die Ergebnisse synchron zurück. Die Geräte stehen im XML unter TreeItem/DeviceGrpDef/FoundDevices/Device. Jeder Knoten enthält ItemSubType für CreateChild und AddressInfo für die Gerätekonfiguration. Der ScanBoxes-Schritt lädt die untergeordneten Klemmen eines Geräts.