Betrifft: ForgeIEC Studio tongs-* Anvil server (anvild)

Was ist ein Device?

Ein Bus-Device ist ein einzelnes Gerät innerhalb eines Segments — Modbus-TCP-Slave (E/A-Block, Frequenzumrichter), EtherCAT-Slave (Servo-Achse, I/O-Koppler), Profibus-DP-Slave oder EtherNet/IP-Adapter. Pro Device führt der Bridge-Daemon eine logische Verbindung, polled die konfigurierten Register und publiziert die Daten über Anvil-Zero-Copy-IPC an die PLC-Runtime.

Ein Device kann modular sein: ein Buskoppler (Slot 0) trägt 1..N I/O-Module in den Slots 1..N. Kompaktgeräte ohne Erweiterungs- Slots haben eine leere modules-Liste — die Variablen liegen dann direkt am Slot 0.


FDD-Integration

Statt jedes Gerät manuell zu beschreiben, importieren Sie eine Hersteller-FDD beim Anlegen. ForgeIEC Studio:

  1. Liest <Identification>, <DiagnosticDecode>, <ModuleProtocol>, <Document> aus der FDD
  2. Zeigt das eingebettete PDF-Datenblatt im Documents-Tab des Properties-Panels
  3. Füllt Status-Variablen aus den Diagnose-Bit-Definitionen
  4. Filtert den Module-Picker so dass nur kompatible Module sichtbar sind (per <ModuleProtocol>-Match)

Im catalogRef-Feld des Devices steht der Verweis auf die verwendete FDD. Sie können eine FDD austauschen (z.B. weidmueller/UR20-FBC-PN-IRT-V2 → -V3), behalten aber alle I/O-Variablen-Bindings — die Identität hängt an der deviceId- UUID, nicht am Hersteller-Eintrag.

Eigene FDDs anlegen über File → New FDD (Diagnostics-Tab + Documents-Tab im FDD-Editor).

Mehr zum FDD-System: News-Eintrag.


Felder eines Devices

Die Struct-Definition liegt in editor/include/model/FBusSegmentConfig.h. Persistiert wird ein Device im .forge-Projekt als <fi:device> unter <fi:segment> (siehe Bus-Konfiguration).

Identität + Adressierung

FeldTypBedeutung
deviceIdUUIDStabiler Primärschlüssel — automatisch beim Anlegen, überlebt Hostname-Rename und IP-Wechsel. Hält damit alle Variablen-Bindings stabil.
hostnameStringUser-sichtbares Label ("Stachelbeere", "Maibeere"). Ist Teil des IEC-Namespaces (anvil.<Segment>.Stachelbeere.<...>). DHCP-sicher, aber kein Primärschlüssel.
ipAddressString (IP)IP-Adresse (Modbus TCP / EtherNet/IP). Leer für Geräte ohne IP (EtherCAT-Slaves identifizieren sich über Bus-Position).
portIntTCP-Port. Default 502 (Modbus TCP).
slaveIdIntModbus-Slave-ID (1..247). Bei TCP meist 1.
catalogRefStringVerweis auf den FDD-Katalogeintrag, z.B. "weidmueller/UR20-FBC-PN-IRT-V2". Treibt Module-Picker + Diagnose-Bit-Auflösung.
descriptionStringFrei-Text ("Bewaesserungsventil Sued").

Module (Slots)

FeldTypBedeutung
modulesListe FBusModuleConfigI/O-Module des Geräts. Slot 0 = Koppler / Kompaktgerät, Slots 1..N = Erweiterungs-Module. Pro Modul: slotIndex, catalogRef, name, baseAddress, settings.

Bei modularen Couplern kommt jedes Modul mit seiner eigenen FDD-Datei daher — wieder mit Diagnose-Bits + Datenblatt. Der Picker zeigt nur Module die der Coupler laut seiner <ModuleProtocol> versteht.

Per-Device-Overrides

Überschreiben — nur für dieses Device — die entsprechenden Werte des Segments. 0 bzw. leerer String bedeutet vom Segment erben. Im Properties-Panel meist unter Advanced Overrides eingeklappt.

FeldTypBedeutung
macString AA:BB:CC:DD:EE:FFMAC-Adresse für statisches ARP / Identitätskontrolle. Schützt vor IP-Klau bei DHCP-Geräten.
endiannessEnum"ABCD" (Big-Endian, IEC-Default), "DCBA" (Word-Swap), "BADC" (Byte-Swap), "CDAB" (beide). Leer = vom Segment erben.
timeoutOverrideMsInt (ms)Per-Device-Timeout. 0 = Segment-Timeout.
retryCountIntWiederholungen pro Request. 0 = Segment-Default.
connectionModeEnum"always" (TCP offen halten) oder "on_demand" (pro Transaktion neu verbinden). Leer = Segment-Default.
gatewayOverrideString (IP)Eigenes Gateway wenn das Device in einem anderen Subnet sitzt als die Bind-NIC.

Device-spezifische Settings

Im settings-Map (Key/Value) liegen Werte die nur für dieses Gerät oder seinen Gerätetyp Sinn ergeben — z.B. ein Schwellenwert eines Frequenzumrichters oder ein bevorzugter Modbus-Funktionscode.


Edit-Pfad in ForgeIEC Studio

AktionWirkung
Einfach-Klick auf einen Device-KnotenFPropertiesPanel zeigt alle Felder als Inline-Editoren — Allgemein, Override-Block, Diagnose-Bits mit Live-Werten, Status-Tabelle.
DoppelklickModal-Dialog FBusDeviceDialog. Im Edit-Modus ist der “Import aus Katalog”-Button gesperrt, damit ein nachträglicher FDD-Import keine bestehenden I/O-Variablen-Bindings überschreibt.

Status-Variablen (read-only)

Jedes Device veröffentlicht zur Laufzeit eine Status-Struktur. Diese Werte zeigt das Properties-Panel als read-only Tabelle — die Bridge schreibt sie, der ST-Code liest sie. Auf der ST-Seite sind sie unter anvil.<Segment>.<Device>.Status.<Var> zugänglich:

Status-VariableTypBedeutung
xOnlineBOOLGerät aktuell erreichbar (letzter Request hat geantwortet)
eStateINTZustands-Enum: 0=offline, 1=connecting, 2=online, 3=error
wErrorCountWORDFehlgeschlagene Requests seit Bridge-Start
sLastErrorMsgSTRINGLetzte Fehlermeldung (Timeout, Modbus-Exception, …)

Zusätzlich erscheinen alle Bits aus der FDD-<DiagnosticDecode>- Sektion als typsichere Status-Member — z.B. WireBreak, ShortCircuit, OverTemperature. Bedeutung + Schweregrad sieht das Properties-Panel mehrsprachig (DE/EN) aus der FDD.

ST-Beispiel:

IF anvil.Halle1.Maibeere.Status.xOnline AND
   anvil.Halle1.Maibeere.Status.wErrorCount < 10 AND
   NOT anvil.Halle1.Maibeere.Status.WireBreak THEN
    bSensor_OK := TRUE;
END_IF;

KI-Helfer-Diagnose-Loop via MCP catalog.diag_bits liefert die aufgelöste Bedeutung dieser Bits in Klartext.


Beispiel: Weidmueller-UR20-Buskoppler mit zwei Modulen

Ein ProfiNet-IRT-Coupler (UR20-FBC-PN-IRT-V2) mit einem 8-DI-Modul und einem 8-DO-Modul:

[[bus_segments.devices]]
device_id    = "0e5d5537-e328-44e6-8214-78d529b18ebd"
hostname     = "Stachelbeere"
ip_address   = "192.168.24.25"
port         = 502
slave_id     = 1
catalog_ref  = "weidmueller/UR20-FBC-PN-IRT-V2"
description  = "Buskoppler Halle 1, Reihe A"

[[bus_segments.devices.modules]]
slot_index   = 0
catalog_ref  = "weidmueller/UR20-FBC-PN-IRT-V2"
name         = "Koppler"
base_address = 0

[[bus_segments.devices.modules]]
slot_index   = 1
catalog_ref  = "weidmueller/UR20-8DI-P"
name         = "8 DI Slot 1"
base_address = 0

[[bus_segments.devices.modules]]
slot_index   = 2
catalog_ref  = "weidmueller/UR20-8DO-P"
name         = "8 DO Slot 2"
base_address = 0

Effekt:

  • Die 8 Eingänge erscheinen im Adress-Pool als %IX0.0..%IX0.7 mit deviceId=0e5d5537-..., moduleSlot=1, modbusAddress=0..7
  • Die 8 Ausgänge analog mit moduleSlot=2
  • ST-Zugriff: anvil.Halle1.Stachelbeere.IO.DI_1 / anvil.Halle1.Stachelbeere.IO.DO_1
  • Diagnose-Bits aus der FDD: Status.WireBreak, Status.ShortCircuit, etc. — typsicher, mehrsprachig erklärt

Verwandte Themen