Module Fast Message Producer « fmproducer »
Description
Presque toutes les sources de données de la technique des procédés transmettent les données dans des champs de données d'octets empaquetés. Le contenu et éventuellement aussi la longueur de ces paquets sont identifiables au moyen d'un messageKey (ou « ID »). Le tableau suivant en donne des exemples.
| Protocole | Message Key | Longueur de la clé |
|---|---|---|
| CAN-Bus | CAN-ID | 11 ou 29 bit |
| MVB-Bus | Numéro de port | 12 bit |
| ProfiBus | Slave-Node ID | 7 bit |
| Modbus | Register, Coil, Input, Status | 2 + 16-bit |
Différents plug-ins smartCORE (par exemple fmudp, canbus, smartmvb) réalisent le raccordement du matériel via des interfaces dédiées, reçoivent ou envoient des paquets de données et alimentent, avec les paquets reçus, le Fast Message Dispatcher (FMD). Celui-ci fournit dans le smartCORE une technologie efficace pour extraire de sources de données quelconques, selon un schéma toujours identique, des données de mesure et des informations d'état et les produire dans des canaux smartCORE individuels (d'où le nom « fm Producer »).
Les modules d'interface créent au moins une instance d'un FMD sous leur propre nom. Celle-ci est raccordée dans le fmProducer via la propriété fmd.
Les paquets reçus contiennent, outre le MessageID et un horodatage, les données dans un champ de données d'octets. Pour un canal, les données s'y trouvent à partir d'un bitOffset donné, avec une bitLength définie. L'ordre des octets byteOrder dans le tampon joue également un rôle, de même que (malheureusement) l'addressSpec(ification), qui définit comment les bits sont comptés dans le tampon.
Une fois les octets de données brutes remis dans le bon ordre, la valeur correctement décalée et masquée, l'interprétation s'effectue via l'imageType. Le nombre est-il signé ou non ? Faut-il le lire comme BCD (Binary Coded Decimal) ou comme valeur polaire (virgule fixe) ? Entier, virgule flottante, ou même texte ?
Après une mise à l'échelle optionnelle vers une grandeur de mesure physique (scale, offset, physicalUnit) selon
la valeur de donnée est produite dans le canal smartCORE avec l'horodatage (de réception) également transmis par le module d'interface.
Interfaces et protocoles utilisés
- Fast Message Dispatching
Configuration JSON
La section suivante décrit l'ensemble de la configuration JSON du module et explique chacun des paramètres.
Exemple de configuration (minimale)
{
"module":"FmProducer",
"factory":"fmproducer",
"config":{
"fmd":"FastMessageDispatcher",
"channels":[
{
"name":"Channel",
"messageKey":42,
"bitOffset":0,
"bitLength":32,
"imageType":"float"
},
[...]
]
}
}
Exemple de configuration (maximale)
{
"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
},
[...]
]
}
}
Paramètres globaux du module
| Nom du paramètre | Requis | Type de données | Plage de valeurs pertinente | Défaut | Description |
|---|---|---|---|---|---|
| fmd | OUI | STRING | Fast Message Dispatcher du module émetteur | ||
| bufferSize | Non1 | INT | 1 - | 1024 | (par défaut) Taille de tampon des canaux créés |
| channelPrefix | Non | STRING | Préfixe de canal (utile lorsque plusieurs modules fmproducer sont utilisés et que les configurations comportent des noms de canaux qui se chevauchent) | ||
| namespace | Non | ARRAY [STRING] | Préfixe de canal sous forme de namespaces enchaînés hiérarchiquement | ||
| addressSpec | Non | STRING | "EN61375_MVB" | Schéma d'adressage par défaut | |
| byteOrder | Non | STRING | "BigEndian" | Ordre des octets par défaut | |
| channels | OUI | JSON Array | Liste d'objets JSON des canaux configurés |
Configuration d'un canal (objet JSON)
| Nom du paramètre | Requis | Type de données | Plage de valeurs pertinente | Défaut | Description |
|---|---|---|---|---|---|
| Filter | |||||
| messageKey | Non2 | UINT | ID du message reçu (par exemple CAN-Bus Message ID, MVB Port, ...) | ||
| Process Image | |||||
| addressSpec | Non | STRING | (valeur du réglage global) | Schéma d'adressage, voir la description ci-après | |
| byteOrder | Non | STRING | "BigEndian", "LittleEndian", "[A-Z]+" | (valeur du réglage global) | Ordre des octets de la valeur stockée, voir la description ci-après |
| imageType | OUI | STRING | type de données source pris en charge de la valeur stockée (voir ci-dessous) | ||
| bitOffset | OUI | UINT | Décalage en bits de la valeur stockée dans le message | ||
| bitLength | Non3 | UINT | Longueur en bits de la valeur stockée dans le message | ||
| stringHint | Non4 | STRING | Indication pour déterminer la longueur de la chaîne (voir ci-dessous) | ||
| scale | Non5 | FLOAT | 1 | Facteur d'échelle de la valeur produite | |
| offset | Non5 | FLOAT | 0 | Offset additif de la valeur produite | |
| smartCORE | |||||
| name | OUI | STRING | Nom du canal | ||
| dataType | Non6 | STRING | Type de données du canal | ||
| bufferSize | Non1 | INT | 1 - | 1024 | Taille de tampon du canal créé |
| physicalDimension | Non | STRING | grandeur physique | ||
| physicalUnit | Non | STRING | unité physique | ||
| noFilter | Non | BOOL | false | Désactive le filtre DataReduction | |
| absoluteTolerance | Non | FLOAT | 0.0 | Tolérance absolue pour le filtre DataReduction | |
| cacheSize | Non7 | INT | 0 | Nombre d'échantillons de données stockés dans un cache local du canal avant d'être publiés pour d'autres modules. | |
| Réservé | |||||
| debug | Non | BOOL | false | Active les sorties de débogage pour le canal. | |
| numElements | Non | INT | 1 | Longueur d'un champ de données en multiples de l'élément de base |
Spécifications d'adresse 'addressSpec'
Pourquoi un schéma d'adressage doit-il être défini ?
Le fmproducer décompose le paquet de données reçu d'un appareil externe. Et la spécification de cet appareil et de l'interface utilisée détermine comment localiser les différents canaux de données dans le flux de données. Il existe malheureusement ici de nombreuses variantes, car malgré la normalisation, il existe encore suffisamment d'implémentations propriétaires dans certains domaines.
La spécification d'adresse addressSpec d éfinit selon quel mode de comptage le MSBit ou le LSBit est indiqué dans le bitOffset. Pour des raisons historiques (le fmProducer a d'abord été développé pour le MVB), le réglage EN61375_MVB est aussi le réglage par défaut.
Valeurs réglables
Sauf indication contraire, c'est chaque fois la position du premier bit (Msb/Lsb selon le byteOrder) qui est adressée. L'indication de l'addressSpec est sans effet lorsqu'un mappage libre est choisi comme byteOrder.
| Enum | Alias | Description |
|---|---|---|
| EN61375_MVB | MVB EN61375 RevNum ReversedNum ReversedForMsbNumerics | Suit strictement la EN61375 en ce qui concerne ByteOrder, types de données, alignement et comptage des bits. - Le bitOffset est byteOffset * 8 + rightShift - Les configurations non conformes sont rejetées. |
| ReversedForMsb | Rev Reversed | 8 Pour tous les signaux, les bits sont comptés dans l'ordre inverse (Motorola). |
| AscendingFirstBit | DBC | Pour tous les signaux, les bits sont comptés par poids croissant. |
| AscendingLSBit | positionLsb | Pour tous les signaux, les bits sont comptés par poids croissant. C'est toujours la position du LSBit qui est adressée. |
| AscendingMSBit | positionMsb | Pour tous les signaux, les bits sont comptés par poids croissant. C'est toujours la position du MSBit qui est adressée. |
Définition de la position d'image pour EN61375_MVB
La norme EN 61375-2-1 contient, à partir du §6.4.2, diverses indications sur la manière dont les données doivent être transmises sur le MVB. Certains cas sont ainsi exclus d'emblée. À partir de smartCORE 2.10.1, les canaux dont la configuration n'est pas conforme sont signalés comme erreur dans le fichier journal par le fmproducer et bloqués pour le traitement.
-
(hypothèse et zone grise)9 La norme ne définit pas de types de données dont la longueur n'est pas une puissance de 2 exacte.
-
Ainsi, le bitOffset ne renvoie pas de manière cohérente au MSBit ou au LSBit d'une variable, mais soit au premier octet (entier), soit au LSbit dans un octet pour
-
La représentation est toujours BigEndian. Les agencements LittleEndian sont ainsi exclus.
-
La position d'image doit toujours être alignée sur un multiple de sa taille dans le tampon de données. Les types de données de 1, 2 ou 4 bits ne peuvent donc se trouver qu'à l'intérieur d'un octet. Tous les autres, de longueur 8, 16, 32, 64 bits, doivent impérativement être alignés sur un octet. Un décalage de l'image n'est pas autorisé ! => à partir de .
Si un décodage avec ce schéma EN61375_MVB n'est pas possible, l'un des autres schémas peut toujours être choisi pour un canal individuel, et un décalage et un réalignement des bits et des octets peuvent alors aussi être essayés.
Comptage de la position des bits
La distinction la plus importante pour tous les autres schémas est d'abord l'ordre dans lequel les bits sont comptés.
Avec les réglages Ascending*, les bits sont comptés selon le poids croissant. C'est typique des configurations CANbus ou Profibus et cela correspond aussi aux implémentations dans les langages de programmation.
Avec le réglage ReversedForMsb, les bits sont comptés strictement de gauche à droite pour le byteOrder BigEndian (Motorola, MSB, Network). Cela correspond au comptage au niveau physique dans les protocoles de transmission de données série, comme par exemple CANbus, SPI ou aussi MVB.
Le graphique montre les différents modes de comptage pour 3 octets à titre d'exemple.
Définition du bit d'ancrage pour la position d'image
Dans les réglages Ascending*, on distingue quel bit de la valeur de donnée est adressé avec bitOffset. Il s'agit généralement du premier bit (AscendingFirstBit), donc du MSBit pour le byteOrder bigEndian et du LSBit pour littleEndian. Il existe toutefois aussi des exceptions où, indépendamment du byteOrder, c'est toujours le MSBit ou le LSBit qui est adressé.
Dans le diagramme suivant, deux valeurs entières de 18 bits sont extraites d'un télégramme de données avec comptage Ascending*, transmises une fois avec le byteOrder littleEndian et une fois avec bigEndian.
Et ce diagramme ajoute une valeur entière de 18 bits avec comptage ReversedForMsb :
Le tableau donne des variantes d'adressage possibles pour les valeurs int18 présentées ci-dessus.
| addressSpec | byteOrder | bitOffset | bitLength |
|---|---|---|---|
| ReversedForMsb AscendingFirstBit AscendingLSBit | LittleEndian | 11 | 18 |
| AscendingMSBit | LittleEndian | 28 | 18 |
| (sans effet) | "CBA" | 1110 | 18 |
| ReversedForMsb | BigEndian | 13 | 18 |
| AscendingFirstBit AscendingMSBit | BigEndian | 34 | 18 |
| AscendingLSBit | BigEndian | 49 | 18 |
| (sans effet) | "ABC" | 3311 | 18 |
Signaux booléens
Enfin, pour les signaux booléens, seul le sens de comptage détermine le bit sélectionné :
| addressSpec | byteOrder | bitOffset | bitLength |
|---|---|---|---|
| ReversedForMsb | BigEndian | 13 | 1 |
| (tous les autres) | BigEndian LittleEndian | 10 | 1 |
| (sans effet) | "A" | 1012 | 1 |
Ordre des octets 'byteOrder'
| Enum | Alias | Description |
|---|---|---|
| BigEndian | Big, MSB, Motorola, Network | L'octet contenant le bit de poids le plus fort (MSBit) se trouve en premier dans le paquet de données transmis |
| LittleEndian | Little, LSB, Intel | L'octet contenant le bit de poids le plus faible (LSBit) se trouve en premier dans le paquet de données transmis |
| Suite de A-Z | Si une chaîne de mappage est utilisée, les octets peuvent être remis dans le bon ordre à partir d'un agencement mélangé de manière quelconque. addressSpec est alors sans effet. |
Utilisation d'une chaîne de mappage
Les octets du tampon de réception sont indexés par ordre croissant en commençant par 'A', à partir de bitOffset / 8. L'ordre des octets par poids décroissant est défini par la chaîne. bitOffset MODULO 8 détermine de combien de bits la valeur extraite doit être décalée vers la droite pour que le bit de poids le plus faible (LSBit) se trouve à la position .
Avec ce mappage libre, on peut en général interpréter tous les télégrammes ayant parcouru un long chemin depuis une borne de mesure, via des coupleurs de bus, des automates, des passerelles, etc., et ayant subi au passage différents réordonnancements et interprétations de l'ordre des octets. Chaque système offre ses propres possibilités de réglage, et elles sont largement utilisées. Cela pourrait être si simple...
Exemple :
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);
Types de données source 'imageType'
| Enum | Alias | Description |
|---|---|---|
| bool | boolean | bitLength fixe de 1 et dataType Bool. |
| unsigned | Entier non signé avec bitLength 2..64. Peut être combiné avec scale et offset pour obtenir une grandeur physique mise à l'échelle. | |
| antivalent, antivalent2 | => unsigned avec bitLength = 2, utilisé le plus souvent dans le contexte MVB pour des valeurs booléennes sécurisées : 0 : ERROR 1 : FALSE 2 : TRUE 3 : UNDEFINED | |
| signed | Entier signé avec bitLength 2..64, le bit de poids le plus fort est le bit de signe. Peut être combiné avec scale et offset pour obtenir une grandeur physique mise à l'échelle. | |
| bcd | Nombres décimaux codés en binaire, 4 bits chacun pour représenter un chiffre 0..9 | |
| float | 13 bitLength fixe de 32, IEEE 754 | |
| double | 13 bitLength fixe de 64, IEEE 754 | |
| timedate48 | bitLength fixe de 48, EN 61375-2-1 §6.4.6.2 (TCN, WTB, MVB) | |
| time64 | bitLength fixe de 64, RFC 1305 | |
| bytearray | D'autres propriétés définissent comment la longueur du tableau est calculée | |
| string | D'autres propriétés définissent comment la longueur de la chaîne est calculée | |
UniPolar<M>.<N> | Nombre à virgule fixe non signé avec <M> bits entiers et une bitLength fixe de <N> bits.Peut être combiné avec scale et offset pour obtenir une grandeur physique mise à l'échelle. EN 61375-2-1 §6.4.3.7 (TCN, WTB, MVB) | |
BiPolar<M>.<N> | Nombre à virgule fixe signé avec <M> bits entiers (signe inclus) et une bitLength fixe de <N> bits.Peut être combiné avec scale et offset pour obtenir une grandeur physique mise à l'échelle. EN 61375-2-1 §6.4.3.8 (TCN, WTB, MVB) |
Indications pour déterminer la longueur d'une chaîne 'stringHint' et 'numElements'
imageType : String
La fonction de décodage des chaînes n'est pas encore vérifiée. À n'utiliser qu'après concertation !
La zone réservée à la chaîne dans le tampon de données résulte
-
de la bitLength en multiples entiers de 8 ou
-
de l'indication de numElements comme nombre de caractères.
| Enum | Alias | Description |
|---|---|---|
| FixedLengthInBits | bitLength | bitLength / 8 définit le nombre fixe de caractères de la chaîne |
| NullTerminated | Le premier caractère nul (0x00) ou la fin de la zone de données détermine la fin de la chaîne | |
| FixedLength | numElements définit le nombre fixe de caractères de la chaîne | |
| U8Length | La chaîne commence par un uint8 qui indique dynamiquement la longueur de la chaîne. | |
| U16Length | La chaîne commence par un uint16 qui indique dynamiquement la longueur de la chaîne. | |
| U32Length | La chaîne commence par un uint32 qui indique dynamiquement la longueur de la chaîne. | |
| EndOfMessage | La zone de données disponible est toujours étendue jusqu'à la fin du tampon de données. |
Indications pour déterminer la longueur d'un champ de données 'numElements'
imageType : ByteArray
La fonction de décodage des champs de données n'est pas encore vérifiée. À n'utiliser qu'après concertation !
Types de données de canal (types de données cibles) 'dataType'
Le dataType est toujours déterminé automatiquement à partir de l'imageType s'il n'est pas spécifié. Un format cible est alors choisi, qui évite toute perte d'information avec le besoin en mémoire le plus faible possible.
| Enum | Alias | Plage de valeurs | Application |
|---|---|---|---|
| Boolean | bool | false/true | Signaux d'état/de commande |
| Float | jusqu'à | Données de mesure | |
| Double | jusqu'à | ||
| Integer8 | int8 | ||
| Integer16 | int16 | ||
| Integer32 | int32 | ||
| Integer64 | int64 | Horodatage | |
| UnsignedInteger8 | uint8 | Codes d'état | |
| UnsignedInteger16 | uint16 | ||
| UnsignedInteger32 | uint32 | ||
| UnsignedInteger64 | uint64 | ||
| ByteArray | |||
| String | Texte |
Types de données imposés :
Si la bitLength == 1 ou l'imageType == bool, le dataType est lui aussi toujours automatiquement bool.
Pour imageType == string ou bytearray, le dataType est lui aussi toujours string ou bytearray.
Les imageTypes time64 ou timedate48 imposent int64 comme dataType, afin de pouvoir convertir les horodatages correctement et intégralement en nanosecondes depuis le 01.01.1970.
Une indication de numElements > 1 impose le dataType ByteArray, sauf si un imageType String est réglé.
Types de données automatiques :
Les formats à virgule flottante float et double ont alors la priorité, dès que l'un des critères suivants est rempli :
- la source de données fournit déjà, via l'imagetype (float, double, unipolar, bipolar), une valeur à virgule flottante ou fixe,
- ou ,
- une physicalUnit est spécifiée.
Si , un float suffit pour une conversion sans perte.
Les formats entiers sont également choisis, via la bitLength et la présence d'un signe (signed) dans l'imageType, pour la plus petite plage de données possible :
- (Unsigned)Integer8 pour
- (Unsigned)Integer16 pour
- (Unsigned)Integer32 pour
- (Unsigned)Integer64 pour
Le signe optionnel est complété, à partir du bit de poids le plus fort de l'image, jusqu'à la largeur du dataType.
Types de données manuels et conversion :
La sélection manuelle du dataType peut entraîner une perte de précision, de résolution ou une restriction significative de la plage de valeurs disponible et doit donc en règle générale être évitée !
Si la source de données fournit un nombre à virgule flottante selon les règles précitées, la conversion vers un dataType entier se fait par arrondi : à partir de .50, à la valeur entière supérieure suivante.
Dans tous les cas, les plages de valeurs des types entiers choisis sont prises en compte. Si la valeur de l'image se situe en dehors de la plage disponible, elle est remplacée par le minimum ou le maximum représentable et un message est écrit dans le fichier journal.
Filtre de réduction de données
Un filtre de réduction de données est configuré pour chaque canal. Dans le réglage de base, il fait en sorte que de nouveaux enregistrements ne soient écrits dans le canal que lorsque le contenu des données change (OnChange). L'horodatage de réception des données continue en revanche d'être mis à jour à chaque enregistrement traité, de sorte que le traitement des données (constantes) dans d'autres plug-ins reste possible jusqu'à l'instant le plus récent.
L'option absoluteTolerance place une bande de tolérance autour de la dernière valeur écrite. Un nouvel enregistrement n'est publié que lorsque l'écart par rapport à la dernière valeur écrite dépasse cette bande de tolérance. Ce réglage est utile pour les signaux fortement bruités, afin de réduire significativement la quantité de données.
Si l'option noFilter est mise à true, aucun filtre de réduction de données n'est créé. Ce réglage est judicieux pour les données rapides qui ne doivent pas être réduites, parce que, par exemple pour des signaux de vibrations, une analyse dans le domaine fréquentiel suit.
Informations sur le module
| Information | Valeur |
|---|---|
| Auteurs | optiMEAS GmbH |
| depuis smartCORE | 0.103 |
| Type de module | Fast Message Receiver, Producer |
| Dépendances | Module émetteur Fast Message (par exemple fmudp, canbus, smartmvb, rawplayback, ...) |