Zum Hauptinhalt springen

Fast Message Producer Modul "fmproducer"

Beschreibung​

Fast alle Datenquellen in der Prozesstechnik übertragen die Daten in gepackten Datenfeldern von Bytes. Der Inhalt und eventuell auch die Länge dieser Pakete sind über einen messageKey (oder auch "ID") indentifizierbar. Beispiele sind in der folgenden Tabelle angegeben.

ProtokollMessage KeyLänge des Keys
CAN-BusCAN-ID11 oder 29 bit
MVB-BusPort-Nummer12 bit
ProfiBusSlave-Node ID7 bit
ModbusRegister, Coil, Input, Status2 + 16-bit

Verschiedene smartCORE Plugins (z.B. fmudp, canbus, smartmvb) realisieren die Anbindung der Hardware über dedizierte Schnittstellen, Empfangen oder Versenden Datenpakete und speisen mit den empfangenen Paketen den sogenannten Fast Message Dispatcher (FMD). Dieser stellt eine effiziente Technologie im smartCORE bereit, um aus beliebigen Datenquellen nach immer wiederkehrendem Schema Messdaten und Statusinformationen herauszulesen und in einzelne smartCORE Kanäle zu produzieren (daher der Name "fm Producer").

Die Schnittstellen-Module erzeugen mindestens eine Instanz eines FMDs unter ihrem eigenen Namen. Dieser wird im fmProducer über die Eigenschaft fmd angebunden.

fm Producer

In den empfangenen Paketen sind neben der MessageID und einem Zeitstempel die Daten in einem Datenfeld aus Bytes enthalten. Für einen Kanal sind darin die Daten ab einem bestimmten bitOffset mit einer festgelegten bitLength zu finden. Dabei spielt noch die Anordnung der Bytes byteOrder im Puffer, sowie (leider) die addressSpec(ification) ein Rolle, mit der festgelegt wird, wie die Bits im Puffer gezählt werden.

Nachdem die Rohdaten-Bytes in die richtige Reihenfolge, der Wert korrekt verschoben und maskiert wurde, erfolgt die Interpretation über den imageType. Hat die Zahl ein Vorzeichen oder nicht? Ist die Zahl als BCD (Binary Coded Decimal) oder als Polarer-Wert (Fix-Komma) zu lesen? Ganzzahlig, Fließkomma oder sogar Text?

Nach einer optionalen Skalierung auf eine physikalische Messgröße (scale, offset, physicalUnit) gemäß

yphys=yraw⋅scale+offsety_{phys} = y_{raw} \cdot \rm{scale} + \rm{offset}

erfolgt die Produktion des Datenwertes in den smartCORE Kanal mit dem ebenfalls vom Schnittstellen-Modul übermittelten (Empfangs-)Zeitstempel.

Verwendete Schnittstellen & Protokolle​

  • Fast Message Dispatching

JSON-Konfiguration​

Im folgenden Abschnitt soll die gesamte JSON-Konfiguration des Moduls beschrieben und die einzelnen Parameter erläutert werden.

Beispielkonfiguration (minimal)​

{
"module":"FmProducer",
"factory":"fmproducer",
"config":{
"fmd":"FastMessageDispatcher",
"channels":[
{
"name":"Channel",
"messageKey":42,
"bitOffset":0,
"bitLength":32,
"imageType":"float"
},

[...]

]
}
}

Beispielkonfiguration (maximal)​

{
"module":"FmProducerSmartMVB",
"factory":"fmproducer",
"config":{
"fmd":"smartmvb0",
"bufferSize":1024,
"namespace":["directory","subDirectory"],
"channelPrefix":"SmartMVB",
"addressSpec": "EN61375_MVB",
"byteOrder": "bigEndian",
"channels":[
{
"name":"SmartMVBmessageData",
"bufferSize":1024,
"scale":3.14,
"offset":2.72,
"physicalDimension":"Length",
"physicalUnit":"m",
"messageKey":10012,
"bitOffset":0,
"bitLength":20,
"imageType":"unsigned",
"addressSpec": "AscendingFirstBit",
"byteOrder": "littleEndian",
"absoluteTolerance":0.5
},

[...]

]
}
}

Globale Modulparameter​

ParameternameErforderlichDatentypsinnvoller WertebereichDefaultBeschreibung
fmdJASTRINGFast Message Dispatcher des Sendemoduls
bufferSizeNein1INT1 -1024(default) Puffergröße der angelegten Kanäle
channelPrefixNeinSTRINGKanal Präfix (sinnvoll, wenn mehrere fmproducer Module verwendet werden und die Konfigurationen überlappende Kanalnamen besitzen)
namespaceNeinARRAY [STRING]Kanal Präfix in Form hierarchisch verketteter Namespaces
addressSpecNeinSTRING"EN61375_MVB"Default Schema der Adressierung
byteOrderNeinSTRING"BigEndian"Default Byte-Order
channelsJAJSON ArrayListe von JSON Objects konfigurierter Kanäle

Konfiguration eines Kanals (JSON Object)​

ParameternameErforderlichDatentypsinnvoller WertebereichDefaultBeschreibung
Filter
messageKeyNein2UINTID der empfangenen Botschaft (z.B. CAN-Bus Message ID, MVB Port, ...)
Process Image
addressSpecNeinSTRING(Wert aus globaler Einstellung)Schema der Adressierung, siehe nachfolgende Beschreibung
byteOrderNeinSTRING"BigEndian", "LittleEndian",
"[A-Z]+"
(Wert aus globaler Einstellung)Byte-Order des hinterlegten Wertes, siehe nachfolgende Beschreibung
imageTypeJASTRINGunterstützter Quelldatentyp des hinterlegten Wertes (siehe unten)
bitOffsetJAUINTBit-Offset des in der Botschaft hinterlegten Wertes
bitLengthNein3UINTBit-Länge des in der Botschaft hinterlegten Wertes
stringHintNein4STRINGHinweis zur Bestimmung der String-Länge (siehe unten)
stringEncoding5Nein4STRINGIANA-Name, z.B. "UTF-8", "windows-1252"6Zeichenkodierung des Strings im Datenpaket (siehe unten)
timeFix5Nein7STRING"RFC4330", "RFC5905""RFC4330"Behandlung des Überlaufs von time64 im Jahr 2036 (siehe unten)
scaleNein8FLOAT1Skalierungsfaktor des produzierten Werts
offsetNein8FLOAT0additiver Offset des produzierten Werts
smartCORE
nameJASTRINGName der Kanals
dataTypeNein9STRINGDatentyp des Kanals
bufferSizeNein1INT1 -1024Puffergröße des angelegten Kanals
physicalDimensionNeinSTRINGphysikalische Größe
physicalUnitNeinSTRINGphysikalische Einheit
noFilterNeinBOOLfalseSchaltet das DataReduction-Filter aus
absoluteToleranceNeinFLOAT0.0Absolute Toleranz für das DataReduction-Filter
cacheSizeNein10INT0Anzahl der Datensamples, die in einem lokalen Cache des Kanals gespeichert werden, bevor diese für andere Module veröffentlicht werden.
Reserviert
debugNeinBOOLfalseSchaltet Debug-Ausgaben für den Kanal frei.
numElementsNeinINT1Länge eines Datenfelds in Vielfachen des Grundelements

Adressspezifikationen 'addressSpec'​

Warum muss ein Adressierungs-Schema festgelegt werden?​

Der fmproducer zerlegt das von einem externen Gerät empfangene Datenpaket. Und die Spezifikation dieses Gerätes und der verwendeten Schnittstelle legen fest, wie einzelne Datenkanäle in dem Datenstrom zu lokalisieren sind. Hierbei gibt es leider viele Variationen, weil trotz Standardisierung in bestimmten Bereichen immer noch genügend proprietäre Implementierungen existieren.

Die Adress-Spezifikation addressSpec legt fest, in welcher Zählweise das MSBit oder das LSBit im bitOffset angegeben sind. Aus historischen Gründen (fmProducer wurde zuerst für den MVB entwickelt) ist die Einstellung EN61375_MVB auch die Default-Einstellung.

Einstellbare Werte​

Sofern nicht anders angegeben, wird jeweils die Position des ersten Bits (Msb/Lsb je nach byteOrder) adressiert. Die Angabe der addressSpec ist ohne Funktion, wenn als byteOrder ein freies Mapping gewählt wird.

EnumAliasBeschreibung
EN61375_MVBMVB
EN61375
RevNum
ReversedNum
ReversedForMsbNumerics
Folgt strikt der EN61375 mit Bezug auf ByteOrder, Datentypen, Alignment und Bit-Zählung.
- Der bitOffset ist byteOffset * 8 + rightShift
- Nicht konforme Konfigurationen werden abgelehnt.
ReversedForMsbRev
Reversed
11 Für alle Signale werden Bits in umgekehrter (Motorola) Reihenfolge gezählt.
AscendingFirstBitDBCFür alle Signale werden Bits mit aufsteigender Wertigkeit gezählt.
AscendingLSBitpositionLsbFür alle Signale werden Bits mit aufsteigender Wertigkeit gezählt.
Es wird immer die Position des LSBit adressiert.
AscendingMSBitpositionMsbFür alle Signale werden Bits mit aufsteigender Wertigkeit gezählt.
Es wird immer die Position des MSBit adressiert.

Festlegung der Image-Position für EN61375_MVB​

In der Norm EN 61375-2-1 gibt es ab §6.4.2 verschiedene Hinweise, wie Daten auf dem MVB übertragen werden müssen. Dabei sind bestimmte Fälle von vornherein ausgeschlossen. Kanäle mit einer nicht konformen Konfiguration werden im fmproducer ab smartCORE 2.10.1 als Fehler im Logfile ausgegeben und für die Verarbeitung gesperrt.

  • bitLength=2k\text{bitLength} = 2^k (Annahme und Grauzone)12 Die Norm definiert keine Datentypen, die nicht die Länge einer glatten 2-er Potenz haben. Ein Zahlenwert mit einer anderen bitLength wird verarbeitet, aber beim Start mit einer Warnung im Logfile gemeldet. Ausgenommen sind imageTypes, deren Länge der Typ selbst festlegt (z.B. timedate48).

  • bitOffset=byteOffset⋅8+rightShift\text{bitOffset}=\text{byteOffset} \cdot 8 + \text{rightShift} Damit verweist bitOffset nicht konsistent auf das MSBit oder LSBit einer Variablen, sondern entweder auf das erste (ganze) Byte oder das LSbit in einem Byte für bitLength<8\text{bitLength} < 8

  • Die Darstellung ist immer BigEndian. Damit werden LittleEndian Anordnungen ausgeschlossen.

  • Die Image-Position muss immer an einem Vielfachen ihrer Größe im Datenpuffer ausgerichtet sein. Für Datentypen mit 1, 2 oder 4 bit Länge können diese also ausschließlich innerhalb eines Bytes liegen. Alle anderen mit Länge 8, 16, 32, 64 bit müssen zwingend an einem Byte augerichtet sein. Ein Verschieben des Images ist nicht zulässig! => rightShift:=0\text{rightShift} := 0 ab bitLength≥8\text{bitLength} \geq 8.

  • Ein Wert unter 8 bit beginnt und endet im selben Byte. Das gilt auch für eine bitLength, die keine 2-er Potenz ist: Ein 3-bit-Wert mit rightShift=6\text{rightShift} = 6 überschreitet die Byte-Grenze und wird abgelehnt.

Geändertes Verhalten ab smartCORE 2.12

Ein Wert unter 8 bit, der die Byte-Grenze überschreitet, wird abgelehnt. Eine bitLength, die keine 2-er Potenz ist, wird gemeldet.

tipp

Falls eine Dekodierung mit diesem Schema EN61375_MVB nicht möglich ist, kann für einen einzelnen Kanal immer noch eines der anderen Schemata gewählt werden und dann auch eine Verschiebung und Neuausrichtung der Bits und Bytes probiert werden.

Zählung der Bit-Position​

Die wichtigste Unterscheidung für alle anderen Schemata ist zunächst, in welcher Reihenfolge die Bits gezählt werden.

Mit den Ascending*-Einstellungen zählen die Bits gemäß der aufsteigenden Wertigkeit. Dies ist typisch für CANbus- oder Profibus-Konfigurationen und entspricht auch Implementierungen in Programmiersprachen.

Mit der Einstellung ReversedForMsb werden die Bits in der byteOrder BigEndian (Motorola, MSB, Network) strikt von links nach rechts durchgezählt. Dies enspricht der Zählweise auf physikalischer Ebene in seriellen Datenübetragungsprotokollen, wie z.B. CANbus, SPI oder auch MVB.

Die Grafik zeigt die unterschiedliche Zählweise für exemplarisch 3 Bytes.

Zählweise für Bits

Festlegung des Anker-Bits für die Image-Position​

In den Ascending*-Einstellungen wird unterschieden, welches Bit des Datenwertes mit bitOffset adressiert wird. Üblicherweise ist es das erste Bit (AscendingFirstBit), also bei byteOrder bigEndian das MSBit und bei littleEndian das LSBit. Es gibt aber auch Ausnahmen, bei denen unabhängig von der byteOrder immer das MSBit oder das LSBit adressiert ist.

Im folgenden Diagramm werden aus einen Datentelegramm mit Ascending*- Zählung zwei 18-bit Integer-Werte extrahiert, die einmal mit byteOrder littleEndian und einmal bigEndian übertragen werden.

Dekodierung Zahlenwert Ascending

Und dieses Diagramm ergänzt einen 18-bit Integer Wert in ReversedForMsb-Zählung:

Dekodierung Zahlenwert Reversed

Die Tabelle gibt mögliche Adressierungsvarianten für die oben gezeigten int18-Werte.

addressSpecbyteOrderbitOffsetbitLength
ReversedForMsb
AscendingFirstBit
AscendingLSBit
LittleEndian1118
AscendingMSBitLittleEndian2818
(ohne Funktion)"CBA"111318
ReversedForMsbBigEndian1318
AscendingFirstBit
AscendingMSBit
BigEndian3418
AscendingLSBitBigEndian4918
(ohne Funktion)"ABC"331418

Boolsche Signale​

Nicht zuletzt entscheidet bei boolschen Signalen ausschließlich die Zählrichtung über das ausgewählte Bit:

Dekodierung Boolean

addressSpecbyteOrderbitOffsetbitLength
ReversedForMsbBigEndian131
(alle anderen)BigEndian
LittleEndian
101
(ohne Funktion)"A"10151

Anordnung der Bytes 'byteOrder'​

EnumAliasBeschreibung
BigEndianBig, MSB, Motorola, NetworkDas Byte mit dem höchstwertigen Bit (MSBit) steht in dem übertragenen Datenpaket vorne
LittleEndianLittle, LSB, IntelDas Byte mit dem niederwertigsten Bit (LSBit) steht in dem übertragenen Datenpaket vorne
Folge von A-ZWird ein Mapping-String verwendet, können die Bytes aus einer beliebig gemischten Anordnung in die korrekte Reihenfolge gebracht werden.
addressSpec ist damit ohne Funktion.

Verwendung eines Mapping-Strings​

Die Bytes im Empfangspuffer werden ab bitOffset / 8 beginnend mit 'A' aufsteigend indiziert. Die Reihenfolge der Bytes in absteigender Wertigkeit wird durch den String festgelegt. bitOffset MODULO 8 bestimmt, um wieviele Bits der extrahierte Wert nach rechts verschoben werden muss, damit das niederwertigste Bit (LSBit) an Position 202^0 steht.

Mit diesem freien Mapping können in der Regel alle Telegramme interpretiert werden, die einen langen Weg von einer Messklemme, durch Buskoppler, Steuerungen, Gateways, etc. genommen und dabei verschiedene Neuordnungen und Interpretationen der Bytereihenfolge erlebt haben. Jedes System bietet eigene Einstellmöglichkeiten und die werden auch reichlich genutzt. Es könnte so einfach sein...

Beispiel:

bytes: 0_______ 1_______ 2_______ 3_______ 4_______ 5_______ 6_______
bits: 76543210 76543210 76543210 76543210 76543210 76543210 76543210
bitOffset: --------------------->|
Indizierung: A B C D E ...

Extraktion für "CDBA"
value = ((((byte[4] << 8) // alias 'C' (bitOffset / 8) + 2
| byte[5] << 8) // alias 'D' (bitOffset / 8) + 3
| byte[3] << 8) // alias 'B' (bitOffset / 8) + 1
| byte[2]) // alias 'A' (bitOffset / 8) + 0
>> (bitOffset % 8);

Quelldatentypen 'imageType'​

EnumAliasBeschreibung
boolbooleanFeste bitLength von 1 und dataType Bool.
unsignedVorzeichenlose Ganzzahl mit bitLength 2..64.
Kann mit scale und offset zu einer skalierten physikalische Größe verrechnet werden.
antivalent, antivalent2=> unsigned mit bitLength = 2, meist im MVB Kontext für gesicherte Boolsche Werte verwendet:
0: ERROR
1: FALSE
2: TRUE
3: UNDEFINED
signedVorzeichenbehaftete Ganzzahl mit bitLength 2..64, das höchstwertige Bit ist das Vorzeichen-Bit.
Kann mit scale und offset zu einer skalierten physikalische Größe verrechnet werden.
bcdBinär-Codierte-Dezimalzahlen,
je 4-bits für die Darstellung einer Ziffer 0..9
float16 Feste bitLength von 32, IEEE 754
double16 Feste bitLength von 64, IEEE 754
timedate48Feste bitLength von 48,
EN 61375-2-1 §6.4.6.2 (TCN, WTB, MVB), siehe Zeitstempel
time64Feste bitLength von 64, RFC 1305, siehe Zeitstempel
bytearrayWeitere Eigenschaften legen fest, wie sich die Länge des Arrays errechnet
stringWeitere Eigenschaften legen fest, wie sich die Länge des Strings errechnet
UniPolar<M>.<N>Vorzeichenlose Fix-Kommazahl mit <M> Ganzzahl-Bits und einer festen bitLength von <N> Bits.
Kann mit scale und offset zu einer skalierten physikalische Größe verrechnet werden.
EN 61375-2-1 §6.4.3.7 (TCN, WTB, MVB)
BiPolar<M>.<N>Vorzeichenbehaftete Fix-Kommazahl mit <M> Ganzzahl-Bits (inklusive Vorzeichen) und einer festen bitLength von <N> Bits.
Kann mit scale und offset zu einer skalierten physikalische Größe verrechnet werden.
EN 61375-2-1 §6.4.3.8 (TCN, WTB, MVB)

Zeitstempel 'timedate48' und 'time64'​

Geändertes Verhalten ab smartCORE 2.12

time64 wird ab 1900 gezählt, wie RFC 1305 es festlegt; zuvor lag der Wert 70 Jahre daneben. Ein Zeitstempel 0 wird als 0 weitergegeben.

Beide imageTypes werden in Nanosekunden seit 01.01.1970 (UTC) als dataType int64 produziert. Die Umrechnung erfolgt ganzzahlig, der Sekundenbruchteil wird auf die nächste Nanosekunde gerundet.

imageTypeAufbauBezugszeitpunktgültig bis
timedate4832 bit Sekunden (vorzeichenlos) + 16 bit Bruchteil in 2−162^{-16} s01.01.197007.02.2106
time6432 bit Sekunden (vorzeichenlos) + 32 bit Bruchteil in 2−322^{-32} s01.01.1900siehe timeFix

Ein Zeitstempel, dessen Bits alle 0 sind, wird als 0 weitergegeben und kennzeichnet damit einen fehlenden Zeitstempel.

Überlauf von time64 im Jahr 2036 'timeFix'​

Der Sekundenzähler von time64 läuft am 07.02.2036 um 06:28:16 UTC über. Welche Epoche ein empfangener Wert meint, legt timeFix fest:

timeFixVerfahren
RFC4330 (Default)RFC 4330 §3: Ist das höchstwertige Bit der Sekunden gesetzt, liegt die Zeit zwischen 1968 und 2036, sonst zwischen 2036 und 2104. Feste Zuordnung ohne Bezug zur Systemzeit.
RFC5905RFC 5905 §6: Es gilt die Epoche, die dem Empfangszeitstempel am nächsten liegt. Setzt eine korrekte Systemzeit voraus.

Weicht ein Zeitstempel um mehr als 30 Jahre vom Empfangszeitstempel ab, wird dies einmalig je Kanal mit beiden Zeitpunkten im Logfile gemeldet. Typische Ursache ist eine Gegenstelle, die Sekunden seit 1970 statt seit 1900 sendet.

Hinweise zur Bestimmung der Länge eines Strings 'stringHint' und 'numElements'​

Geändertes Verhalten ab smartCORE 2.12
  • Jeder String endet am ersten Null-Zeichen, unabhängig vom stringHint.
  • bitOffset und bitLength von string und bytearray müssen Vielfache von 8 sein, addressSpec und byteOrder sind dafür ohne Funktion.
  • Ohne addressSpec (Default EN61375_MVB) werden Strings als ISO-8859-1 gelesen. "stringEncoding": "UTF-8" stellt das bisherige Verhalten her.

Strings und Datenfelder (imageType string und bytearray) liegen immer byteweise im Datenpaket:

  • bitOffset und bitLength müssen Vielfache von 8 sein. Andernfalls wird der Kanal beim Start mit einer Meldung im Logfile gesperrt.

  • bitOffset ist die Byte-Position × 8. addressSpec und byteOrder sind ohne Funktion; byteOrder bestimmt nur die Byte-Reihenfolge eines Längenfelds (siehe unten).

Der für den String reservierte Bereich im Datenpuffer ergibt sich aus

  • der bitLength,

  • numElements × bitLength, wenn numElements angegeben ist. bitLength ist dann die Breite eines Zeichens (Default 8 bit, bei U8WLength bis U32WLength und S7WLength 16 bit), oder

  • ohne beide Angaben dem Rest der Botschaft ab bitOffset.

Unabhängig vom stringHint endet jeder String am ersten Null-Zeichen (U+0000) nach der Dekodierung. Was danach im reservierten Bereich steht, wird verworfen. Werden alle Bytes benötigt, ist imageType bytearray zu verwenden.

EnumAliasBeschreibung
FixedLengthInBitsbitLength(Default) Der String füllt den reservierten Bereich.
NullTerminatedGleichwertig mit FixedLengthInBits, aus Kompatibilitätsgründen erhalten
FixedLengthnumElements definiert die Anzahl an Zeichen im String.
U8LengthEin uint8 vor dem Text gibt dessen Länge in Bytes an.
U16LengthEin uint16 vor dem Text gibt dessen Länge in Bytes an.
U32LengthEin uint32 vor dem Text gibt dessen Länge in Bytes an.
U8WLength5Ein uint8 vor dem Text gibt dessen Länge in Worten (2 Bytes, z.B. UTF-16) an.
U16WLength5Ein uint16 vor dem Text gibt dessen Länge in Worten an.
U32WLength5Ein uint32 vor dem Text gibt dessen Länge in Worten an.
S7Length5SIMATIC STRING, siehe unten
S7WLength5SIMATIC WSTRING, siehe unten
EndOfMessageDer String reicht immer bis zum Ende der Botschaft.

Strings mit Längenfeld​

Bei U8Length bis U32WLength steht ab bitOffset ein Längenfeld vor dem Text. Die reservierte Breite aus bitLength bzw. numElements gilt für den Text, das Längenfeld kommt hinzu. Ein Längenfeld aus 2 oder 4 Bytes wird bei byteOrder LittleEndian little endian gelesen, sonst big endian.

Gibt das Längenfeld mehr an, als der reservierte Bereich oder die Botschaft enthält, wird der Text gekürzt und dies einmalig je Kanal im Logfile gemeldet. Fehlt das Längenfeld in der Botschaft, wird kein Wert produziert.

Beispiel U16Length, byteOrder BigEndian, bitOffset 0:

00 02 41 42 43 → "AB"

SIMATIC-Strings 'S7Length' und 'S7WLength'​

SIMATIC-Steuerungen legen Strings mit einem Kopf aus deklarierter Maximallänge und aktueller Länge ab. Beide zählen Zeichen. Gelesen werden nur die Zeichen der aktuellen Länge, was dahinter im reservierten Bereich steht, ist ohne Bedeutung.

stringHintSIMATIC-DatentypKopfZeichenDefault stringEncodingMaximallänge
S7LengthSTRING[n]1 Byte Maximallänge, 1 Byte aktuelle Länge1 Bytewindows-1252254
S7WLengthWSTRING[n]2 Bytes Maximallänge, 2 Bytes aktuelle Länge, big endian2 BytesUTF-16BE16382

numElements entspricht der Deklaration n und ist optional; ohne Angabe gilt der Rest der Botschaft. Der Kopf von S7WLength ist unabhängig von byteOrder immer big endian.

Ist die aktuelle Länge größer als die Maximallänge, wird auf die Maximallänge gekürzt. Dies sowie eine Maximallänge über der Grenze oder abweichend von numElements wird einmalig je Kanal im Logfile gemeldet, der Wert wird trotzdem gelesen.

Beispiel STRING[10] := 'abcdef' mit numElements 10:

0A 06 61 62 63 64 65 66 xx xx xx xx → "abcdef"

Zeichenkodierung 'stringEncoding'​

Intern verarbeitet smartCORE alle Strings als Unicode. stringEncoding gibt an, in welcher Kodierung die Bytes im Datenpaket stehen. Ohne Angabe gilt für S7Length "windows-1252", für S7WLength "UTF-16BE", für addressSpec EN61375_MVB "ISO-8859-1" (Latin-1), sonst "UTF-8".

Zulässig sind die Namen und Aliase aus dem IANA-Register "Character Sets". Groß- und Kleinschreibung spielt keine Rolle. Die Aliase mit Präfix cs (z.B. csUTF8) werden nicht unterstützt. Ein unbekannter Name wird beim Start im Logfile gemeldet und der Kanal gesperrt.

Häufig verwendete Kodierungen und die Bytes einiger Zeichen:

stringEncodingäÄ߀°µ²
UTF-8C3 A4C3 84C3 9FE2 82 ACC2 B0C2 B5C2 B2
ISO-8859-1 (Latin-1)E4C4DF–B0B5B2
ISO-8859-15 (Latin-9)E4C4DFA4B0B5B2
windows-1252E4C4DF80B0B5B2
IBM437 (cp437)848EE1–F8E6FD
UTF-16BE (MVB UNICODE16)00 E400 C400 DF20 AC00 B000 B500 B2
US-ASCII–––––––

US-ASCII kennt nur die Bytes 00 bis 7F. Ein Zeichen, das in der Kodierung nicht vorhanden ist, oder eine ungültige Bytefolge erscheint im Kanal als Ersatzzeichen „�“ (U+FFFD).

Jede Botschaft wird für sich dekodiert. Eine Bytefolge, die am Ende des Datenbereichs abgeschnitten ist, wird nicht mit der nächsten Botschaft zusammengesetzt, sondern ebenfalls als „�“ ausgegeben.

Typische Fehlerbilder bei falscher Einstellung:

Anzeige im KanalUrsache
ä statt äDie Daten sind UTF-8, eingestellt ist ISO-8859-1 oder windows-1252.
� statt äDie Daten sind ISO-8859-1 oder windows-1252, eingestellt ist UTF-8.
„ statt äDie Daten sind IBM437, eingestellt ist windows-1252.

Hinweise zur Bestimmung der Länge eines Datenfeldes 'numElements'​

Auch für Datenfelder gilt die Byte-Ausrichtung von bitOffset und bitLength (siehe oben).

warnung

imageType: ByteArray
Die Funktion zum Dekodieren von Datenfeldern ist noch nicht verifiziert. Verwendung nur nach Rücksprache!

Kanaldatentypen (Zieldatentypen) 'dataType'​

Der dataType wird immer automatisch aus dem imageType bestimmt, wenn er nicht spezifiziert wird. Dabei wird ein Zielformat eingestellt, mit dem ein Informationsverlust bei kleinstmöglichem Speicherbedarf vermieden wird.

EnumAliasWertebereichAnwednung
Booleanboolfalse/trueStatus-/Steuersignale
Floatbis 3.40⋅10383.40\cdot10^{38}Messdaten
Doublebis 1.80⋅103081.80\cdot10^{308}
Integer8int8−27…27−1-2^{7}\dots2^{7}-1
Integer16int16−215…215−1-2^{15}\dots2^{15}-1
Integer32int32−231…231−1-2^{31}\dots2^{31}-1
Integer64int64−263…263−1-2^{63}\dots2^{63}-1Zeitstempel
UnsignedInteger8uint80…28−10\dots2^{8}-1Status-Codes
UnsignedInteger16uint160…216−10\dots2^{16}-1
UnsignedInteger32uint320…232−10\dots2^{32}-1
UnsignedInteger64uint640…264−10\dots2^{64}-1
ByteArray
StringText

Erzwungene Datentypen:​

Ist die bitLength == 1 oder der imageType == bool, so ist auch der dataType automatisch immer bool.

Für imageType == string oder bytearray ist auch der dataType immer string oder bytearray.

Die imageTypes time64 oder timedate48 erzwingen mit int64 den dataType, um die Zeitstempel korrekt und vollständig in Nano-Sekunden seit 01.01.1970 konvertieren zu können.

Eine Angabe von numElements > 1 erzwingt den dataType ByteArray, sofern nicht ein imageType String eingestellt ist.

Ein numerischer imageType kann keinen dataType String, ByteArray oder GpsLocation füllen; ein solcher Kanal wird beim Start mit einer Meldung abgeschaltet, die beide Typen nennt.5

Automatische Datentypen:​

Dabei haben Fließkommaformate float und double Vorrang, sofern eines der folgenden Kriterien erfüllt ist:

  • die Datenquelle liefert über den imagetype (float, double, unipolar, bipolar) schon einen Fließ- oder Festkommawert,
  • scale≠1.0\text{scale} \neq 1.0 oder offset≠0.0\text{offset} \neq 0.0,
  • eine physicalUnit ist spezifiziert.

Sofern die bitLength≤24\text{bitLength} \leq 24 ist, genügt ein float für die verlustfreie Umsetzung.

Integer-Formate werden ebenfalls über die bitLength und das Vorhandensein eines Vorzeichens (signed) im imageType für den kleinstmöglichen Datenbereich ausgewählt:

  • (Unsigned)Integer8 für bitLength≤8\text{bitLength} \leq 8
  • (Unsigned)Integer16 für bitLength≤16\text{bitLength} \leq 16
  • (Unsigned)Integer32 für bitLength≤32\text{bitLength} \leq 32
  • (Unsigned)Integer64 für bitLength≤64\text{bitLength} \leq 64

Das optionale Vorzeichen wird aus dem höchstwertigen Bit des Images auf die Breite des dataType aufgefüllt.

Manuelle Datentypen und Konvertierung:​

warnung

Die manuelle Auswahl des dataType kann zu einem Verlust der Genauigkeit, der Auflösung oder einer signifikanten Einschränkung des verfügbaren Wertebereichs führen und ist deshalb in der Regel zu vermeiden!

Wenn die Datenquelle nach zuvor genannten Regeln eine Fließkommazahl liefert, wird für die Konvertierung in einen Integer dataType gerundet: ab .50 auf den nächst größeren Integer Wert.

In jedem Fall werden die Wertebereiche der gewählten Integer-Typen berücksichtigt. Liegt der Wert aus dem Image außerhalb des verfügbaren Bereichs, wird das entsprechend Minimum oder Maximum, das darstellbar ist, ersetzt und eine Meldung im Log-File ausgegeben.

Datenreduktions-Filter​

Für jeden Kanal wird ein Datenreduktions-Filter konfiguriert. Dieses sorgt in der Grundeinstellung dafür, dass neue Datensätze nur dann in den Kanal geschrieben werden, wenn sich der Dateninhalt ändert (OnChange). Der Empfangszeitstempel der Daten wird hingegen mit jedem verarbeiteten Datensatz weiter aktualisiert, sodass eine Verarbeitung der (konstanten) Daten in anderen Plugins bis zum jüngsten Zeitpunkt ermöglicht wird.

Mit der Option absoluteTolerance wird ein Toleranzband um den zuletzt geschriebenen Wert gelegt. Ein neuer Datensatz wird erst dann veröffentlicht, wenn die Differenz zum zuletzt geschriebenen Wert um mehr als dieses Toleranzband abweicht. Diese Einstellung ist für stark verrauschte Signale hilfreich, um die Datenmenge signifikant zu reduzieren.

Wird die Option noFilter auf true gesetzt, wird kein Datenreduktionsfilter erstellt. Diese Einstellung ist sinnvoll für schnelle Daten, die nicht reduziert werden dürfen, weil z.B. für Schwingungssignale eine Betrachtung im Frequenzbereich folgt.

Modul-Informationen​

InformationWert
AutorenoptiMEAS GmbH
seit smartCORE0.103
ModultypFast Message Receiver, Producer
AbhängigkeitenFast Message Sendemodul (z.B. fmudp, canbus, smartmvb, rawplayback, ...)

Footnotes​

  1. Die Angabe der bufferSize bestimmt, wieviele Samples im smartCORE-Kanal zur Verwendung für andere Module vorgehalten wird. Sie sollte so gewählt werden, dass ca. 5 .. 10 Sekunden gepuffert werden können. Periodische Datenlücken in den OSF-Daten deuten auf eine zu kleine bufferSIze hin. ↩ ↩2

  2. Ist der "messageKey" nicht konfiguriert, so werden Daten aus allen Messages weiterverarbeitet (dies ist z.B. sinnvoll für CAN RAW und Debugging-Anwendungen). ↩

  3. Ist die "bitLength" nicht konfiguriert, wird diese aus dem imageType bestimmt. Für imageType string und bytearray reicht der Wert dann bis zum Ende der Botschaft. ↩

  4. Nur für imageType string, bei anderen imageTypes ohne Funktion. ↩ ↩2

  5. Ab smartCORE 2.12 verfügbar. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8

  6. "windows-1252" für S7Length, "UTF-16BE" für S7WLength, "ISO-8859-1" für addressSpec EN61375_MVB, sonst "UTF-8". ↩

  7. Nur für imageType time64, bei anderen imageTypes ohne Funktion. ↩

  8. Die Angabe von scale != 1 oder offset != 0 führt mit einem numerischen imageType zur Ausgabe mit dataType float oder double. ↩ ↩2

  9. In der Regel sollte die Angabe des Datentyps weggelassen werden, da er dann optimiert aus dem imageType und der bitLength bestimmt wird. Für manche Kombinationen wird der Datentyp durch das Modul zwingend festgelegt. ↩

  10. Die Angabe einer cacheSize reduziert für sehr schnelle Datenquellen (>100Hz> 100 Hz) die CPU Auslastung, da zunächst neue Datensätze in einem Cache zwischengespeichert werden und erst mit vollständiger Füllung des Caches an andere Module veröffentlicht werden. Die Angabe sollte so gewählt werden, dass eine Veröffentlichung mit einer Rate von 55 bis 20Hz20 Hz erfolgt. ↩

  11. Gilt explizit nur für byteOrder bigEndian. Für byteOrder littleEndian wird das Schema AscendingFirstBit gezählt. ↩

  12. Obwohl in der EN an manchen Stellen die Länge eines Datentyps# mit (# = any unsigned integer) offen gehalten wird, sind alle expliziten Ausführungen immer in ganzen 2er-Potenzen angegeben (ENUM4, ENUM8, INTEGER8, INTEGER16, ...). Es gibt keinen Hinweis, wie mit Bitlängen außerhalb dieses Rasters im Bezug auf das Alignment zu verfahren ist. ↩

  13. byte 1 * 8 + rightShift 3 = 11 ↩

  14. byte 4 * 8 + rightShift 1 = 33 ↩

  15. byte 1 * 8 + rightShift 2 = 10 ↩

  16. Liefert die Datenquelle einen NAN oder INF Wert, wird dieser explizit nicht in den smartCORE-Kanal produziert. ↩ ↩2