Skip to main content

La connexion à un broker MQTT

Dans tous les logiciels modernes, il est possible de publier des données pouvant être utilisées par d'autres applications. Dans QuickView, nous avons opter pour l'utilisation de MQTT. MQTT est une manière de publier des données selon un protocole standard (voir MQTT sur wikipedia ).

Création d'un "UNS" (Unified Name Space)

L'utilisation de MQTT doit se faire d'une manière standardisée en appliquant les standards ISA-95 dans l'architecture d'un UNS:

ISA-95 equipment hierarchy model.png

Exemple d'un Unified Name Space:

MQTT.png


MQTT.png

Dans l'exemple ci-dessus, ENTREPRISE, SITE et AREA correspondent à "Base Name". PRODUCTION LINE correspond à "Group Name".

La configuration

La configuration de la connexion se fait dans VKServer.ini. Une nouvelle section [MQTT] doit être créée. Il faut auparavant avoir obtenu la licence pour permettre cette connexion. La licence correspond à AMConnector car elle est aussi utilisée par VK A&M pour importer des données depuis QuickView.

assets_quickview_-MNbofKPQVP3lfIcEA04_-MNbs97iuZ0DBAv92vJq_0.png

Exemple de configuration:

[MQTT]
Enabled=1
Host=192.168.11.31
Port=8883
SSlEnable=1
ClientID=VKQuickView
GroupName=A34002
RefreshRate=30
Hierarchical=1
ForceIOType=0
AutoRestart=1
PublishRectifiers=1
PublishMachine=1
PublishCounters=1
PublishDailyData=1
ValueStyle=1
DecimalCount=2

La section [MQTT]

Les mots clef suivants peuvent être définis:

Mot clef

Type

Valeur par défaut

Description

Enabled

Boolean

0

Doit être activé pour que la connexion soit créée.

Host

String

vide

Adresse du broker MQTT

Port

Integer

1883

Numéro du port TCP

SSLEnable

Boolean

0

Vrai si la connexion utilise Open SSL (TLSv1.1) pour une connexion sécurisée. Pour pouvoir travailler en mode SSL sécurisé, il faut placer les dll d'OpenSSL dans le même répertoire que QuickView (version 32bits, version testée: 1.0.2.18)

ClientID

String

GUID

Nom du client MQTT

KeepAlive

Integer

60

Temps en secondes pour garder la connexion en vie lorsqu'il n'y a pas de communication

RefreshRate

Integer

30

Temps en secondes pour l'exécution d'un rafraîchissement des variables

Retain

Boolean

0

Vrai si le contenu des variables doit être préservé sur le broker après la déconnexion. Si ce flag est activé, alors des messages seront renvoyés à tous les clients lors de leur connexion au broker.

BaseName

String

VKQV

Nom de base des topics.

GroupName

String

MachineName

Nom de publication du groupe. En général correspond au code de la machine par exemple: A34002

ForceIOType

Boolean

1

Vrai si le type défini dans les I/O doit être respecté. Si faux alors le système utilise le type des registres des databanks.

Hierarchical

Boolean

0

Vrai pour forcer une hiérarchie dans la publication des variables par exemple: VKQV\23\Température actuelle. Si faux alors le système n'utilise pas le nom de la variable mais son numéro

exemple: VKQV\924

PublishMachine

Boolean

0

Vrai pour forcer la publication de la machine et des tableaux correspondants comme les redresseurs, les pompes doseuses.

AutoRestart

Boolean

1

Vrai pour forcer la reconnexion et le démarrage de la publication après une perte de connexion.

ValueStyle

Integer

1

Format des valeurs des variables:

0: (ISA-95)

Tous les changement de variable sont envoyés dans le même topic soit:

BaseName/GroupName/ToVKAM . Le format utilisé sera:

{ "Type":1, "Items":[{ "LB": "A34001/23/Température actuelle", "V": 12.4, "U":"°C","T":"Double"},{...}], "TS": "2019-04-06T13:46:15.145"}

 

1: (Legacy)

{"V":12.4,"U":"°C","T":"Double","TS":"2019-04-06T13:46:15.145"}

V=Value, U=Units, T=Type, TS=TimeStamp

DecimalCount

Integer

2

Nombre de décimales affichées dans les valeurs réelles

UserName

String

vide

Nom de l'utilisateur lorsqu'un login est demandé par le broker

Password

String

vide

Mot de passe lorsqu'un login est demandé par le broker

Language

Integer

0

Langue utilisée pour les textes des alarmes et messages

PublishAlarm

Boolean

0

Vrai pour forcer la publication des alarmes et des messages

UsePosNumber

Boolean

0

Vrai pour utiliser la valeur "display" de la position à la place de son index dans le nom des variables publiées.

PublishIOs

Boolean

0

Publie les IO dans l'items 'IOs' si le style ISA-95 est utilisé

ItemValueOnly

Boolean

0

Lorsque les I/O sont publiées avec le style ISA-95, si ce mot clef est activé alors les données des I/O seront publiées en valeurs numériques (sans TS, T et U)

PublishDailyData

Boolean

0

Vrai pour publier les données de fonctionnement journalier

La définition des variables dans QuickView

Les variables sont définies dans les IO de QuickView. Le flag 'Q' doit être ajouté à toutes les variables devant être publiées vers MQTT. Ceci se fait soit manuellement dans le fichier IO.ini soit en utilisant le navigateur d'équipement de VKClient10.

assets_quickview_-MNbofKPQVP3lfIcEA04_-MNbs97jk7GUF7nhWl0J_1.png

Exemple de définition dans [IO.INI]:

; Températures
; ============
300=1,Actual Temperature A,W,RQ,15,0,$FFFF,10,100
301=1,Actual Temperature B,W,RQ,15,1,$FFFF,10,100
302=3,Actual Temperature,W,RQ,15,2,$FFFF,10,100
303=4,Actual Temperature,W,RQ,15,3,$FFFF,10,100
304=5,Actual Temperature,W,RQ,15,4,$FFFF,10,100

La publication des variables

Le système publiera les I/O qui sont définies comme pouvant être publiées dans la définition ci-dessus. Il publiera également les valeurs globales de la machine comme par exemple la définition machine ou les redresseurs à condition que le mot clef "PublishMachine" soit activé.

Les variables sont publiées sous forme d'un enregistrement au format JSON. Exemple:

{"V":12.4,"U":"°C","T":"Double","TS":"2019-04-06T13:46:15.145"}

Les topics de publication dépendent du mot clef "ValueStyle". 2 styles sont définis: 0-ISA-95: Style utilisé avec VKAM ayant une version > 3.0.0.2. et 1-Legacy: Style utilisé avec VKAM ayant une version <= 3.0.0.2

VariableStyle=ISA-95

Ce style utilise des topics prédéfinis dont voici la liste:

Topics Description
BaseName/GroupName/VKQV/Datas

Topic dans lequel les changements des variables sont envoyés. Le format du topic sera le suivant:

 

{

   "Type": int,

   "Items": Array [

                             {

                               "LB": string,

                               "V": object,

                               "U": string,

                               "T": string,

                               "S": string

                              },

                             {

                              ....

                              }

                           ],

    "TS" : string

}

       

Type: Type de message. Toujours 1 pour l'instant

LB : Label de la variable

V  : valeur de la variable

U : unité de la variable

T: type de la variable

S: source de la variable

TS: Timestamp

 

Exemple:

{ "Type":1, "Items":[{ "LB": "A34001/23/Température actuelle", "V": 12.4, "U":"°C", "T":"Double"},{"LB":"A34001/78/Conductivité", "V":2.44, "U":"mS", "T":"Double"}], "TS": "2019-04-06T13:46:15.145"}

BaseName/GroupName/VKQV/Apps Topic dans lequel les clients se connectent à QuickView
BaseName/GroupName/VKQV/Apps/ClientID Topic dans lequel le client ClientID publie ses commandes.
BaseName/GroupName/VKQV/Apps/ClientID/Status Statut de la connexion avec le client ClientID.
BaseName/GroupName/VKQV/Apps/ClientID/Status/Connection

Topic dans lequel le client ClientID publie le statut de sa connexion.

Exemple:

{"TS":"2023-12-27T10:54:40.646125Z","T":"String","V":"Connected"}

Ce topic est également désigné comme Last Will Topic lors de la connexion du client.

BaseName/GroupName/VKQV/Apps/ClientID/Status/Watchdog

Topic dans lequel ClientID va écrire de temps en temps pour indiquer que la connexion est valide.

Exemple:

{"Id":"Server_92881d83-d3a0-4edf-8720-e8e700340346","Date":"2023-12-28T12:40:45.6958696+01:00"}

BaseName/GroupName/VKQV/Apps/ClientID/Login

Topic dans lequel ClientID va s'authentifier.

Exemple:

{"Id":"Server_92881d83-d3a0-4edf-8720-e8e700340346", "UserName":"MyUserName","Password":"MyPassword"} 

Lorsque VKQV constate qu'un client s'authentifie, il remplace le contenu par les informations de connexion:

Exemple:

{"jwtoken":"MyToken"}

Si le login n'aboutit pas alors la réponse sera:

{"Error":"Login fail !"}

Si le login aboutit alors il contient un jwt de connexion qui devra être utilisé à chaque commande vers VKQV.

Le client lit la réponse, l'enregistre puis efface le contenu du topic.

BaseName/GroupName/VKQV/Apps/ClientID/Commands

Topic dans lequel ClientID envoie des commandes à VKQV.

Exemple:

{"jwtoken":"MyToken", [{"Cmd":"WriteBit", "Addr":"20,4,2", "Value": true}] }

Lorsque VKQV accepte la commande, il l'execute si le jwtoken est valide puis efface le contenu.

BaseName/GroupName/VKQV/Status/Watchdog

Topic dans lequel VKQV va écrire à chaque rafraîchissement des variables. VKQV s'abonne à ce topic pour vérifier que le broker soit bien fonctionnel. Si celui-ci fonctionne correctement, il devrait renvoyer ce que VKQV a écrit. La liaison est déclarée comme dégradée si ce topic n'est pas envoyé par le broker après 5 fois le temps de rafraichissement. Dans ce cas, la liaison est interrompue et une nouvelle connexion est tentée.

 

Exemple du contenu envoyé par VKQV:

{"V":269,"T":"Int","TS":"2022-06-03T10:28:01.936"}

 

BaseName/GroupName/VKQV/Status/Machine  
BaseName/GroupName/VKQV/Status/Alarms  
BaseName/GroupName/VKQV/Status/Messages  
BaseName/GroupName/VKQV/Status/DailyData  
BaseName/GroupName/VKQV/Status/Rectifiers
BaseName/GroupName/VKQV/Status/Connection

Statut de la connexion VKQV. Lorsque VKQV démarre, il écrit le statut de la connexion soit: {"V":"Connected","T":"String","TS":"2022-06-02T09:20:00.642"}.

Avant de se déconnecter, il écrit: {"V":"Disconnected","T":"String","TS":"2022-06-02T10:24:35.123"}. Ce topic est également désigné comme Last Will Topic lors de la connexion.

BaseName/GroupName/VKQV/Status/Databanks/{#}

Liste des databanks de l'application. Le contenu de chaque databank est contenu dans le topic ayant comme nom le numéro du databank.

Exemple:

{"DB":1,"Device":1,"Channel":1,"Regi":0,"Regf":13,"Registers":[{"R":0,"T":"Int","V":0},{"R":1,"T":"Int","V":0},{"R":2,"T":"Int","V":0},{"R":3,"T":"Int","V":0},{"R":4,"T":"Int","V":0},{"R":5,"T":"Int","V":0},{"R":6,"T":"Int","V":0},{"R":7,"T":"Int","V":0},{"R":8,"T":"Int","V":0},{"R":9,"T":"Int","V":0},{"R":10,"T":"Int","V":0},{"R":11,"T":"Int","V":0},{"R":12,"T":"Int","V":0},{"R":13,"T":"Int","V":0}],"TS":"2023-12-28T11:22:22.923"}

BaseName/GroupName/VKQV/Datas/{#position}

Liste des I/O par position. Le nom des I/O est modifié pour ne pas interférer dans les noms de topics: les espaces, /, \,# sont remplacés par _

BaseName/GroupName/VKQV/Configuration/Machine

Définition de la machine

BaseName/GroupName/VKQV/Configuration/Graphics/{#NomduSynoptique}

Pages graphiques de l'application publiées sous forme de winjson

Pub/Sub

Il est possible de définir des variables en publication ou en souscription indépendamment du système d'I/O de QuickView. Ces variables sont définies dans 2 sections de IO.ini: [MQTTSub] et [MQTTPub].

MQTTSub

Dans cette section il est possible de définir jusqu'à 100 souscriptions à des topics MQTT.

;*************************************************************************
;Souscription à des variables MQTT
;1..100=nom de la variable,Type (IO/DB),N°I/O, Var type,N°DB, N°Reg, N°Bit
;*************************************************************************
[MQTTSub]
1=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/Conductivité_eau_recyclée_20uS,DB,0,F,36,90
2=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/Température_eau_recyclée_20uS,DB,0,F,36,91
3=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/pH_eau_recyclée_20uS,DB,0,F,36,92
4=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/Turbidité_eau_recyclée_20uS,DB,0,F,36,93
5=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/Conductivité_eau_recyclée_5uS,DB,0,F,36,94
6=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/Température_eau_recyclée_5uS,DB,0,F,36,95
7=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/pH_eau_recyclée_5uS,DB,0,F,36,96
8=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/Turbidité_eau_recyclée_5uS,DB,0,F,36,97
9=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/Conductivité_eau_DI,DB,0,F,36,98
10=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/Température_eau_DI,DB,0,F,36,99

Il est possible de souscrire à des topics MQTT et de les stocker dans des registres de databank. Il est possible de souscrire jusqu'à 100 topics. La définition se fait de la manière suivante:

Section [MQTTSub]

n=Nom du topic, type de donnée, n° de l'I/O, type de variable, n° du DB, n° du registre, n° du bit

n : numéro de souscription(1..100)

Nom du topic: nom du topic dans MQTT

type de donnée: IO => correspond à un numéro d'I/O  DB => correspond à un DB,Reg,Bit

n° d'I/O: si le type de donnée = IO alors indique le numéro d'I/O à utiliser pour stocker les données sinon pas utilisé

type de variable: 'F' => float, 'B' => boolean, 'W' => integer

n° du DB: numéro du databank si le type de donnée = DB sinon pas utilisé

n° du registre: numéro du registre du databank si type de donnée = DB sinon pas utilisé

n° du bit: numéro du bit du registre du databank si type de donnée = DB sinon pas utilisé

MQTTPub

Dans cette section il est possible de définir jusqu'à 100 publications dans des topics MQTT.

;*******************************************************************************************************************************
;Publication de variables vers MQTT
;1..100=nom du topic,Min time between refresh (sec),Force Refresh after (sec),Type (IO/DB),N° d'I/O,Var type, N°DB, N°Reg, N°Bit
;*******************************************************************************************************************************
[MQTTPub]
1=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/Conductivité_eau_recyclée_20uS,5,600,DB,0,F,36,121
2=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/Température_eau_recyclée_20uS,5,600,DB,0,F,36,122
3=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/pH_eau_recyclée_20uS,5,600,DB,0,F,36,123
4=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/Turbidité_eau_recyclée_20uS,5,600,DB,0,F,36,124
5=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/Conductivité_eau_recyclée_5uS,5,600,DB,0,F,36,125
6=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/Température_eau_recyclée_5uS,5,600,DB,0,F,36,126
7=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/pH_eau_recyclée_5uS,5,600,DB,0,F,36,127
8=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/Turbidité_eau_recyclée_5uS,5,600,DB,0,F,36,128
9=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/Conductivité_eau_DI,5,600,DB,0,F,36,129
10=Rolex/Bienne/Galvano_BB/A34003/VKQV/Pub/STEP/Température_eau_DI,5,600,DB,0,F,36,130

Il est possible de publier le contenu de DB ou d'I/O dans des topics MQTT. Il est possible de définir jusqu'à 100 publications. La définition se fait de la manière suivante:

Section [MQTTPub]

n=Nom du topic, Min time between refresh, Force refresh after, n° de l'I/O, type de donnée, type de variable, n° du DB, n° du registre, n° du bit

n : numéro de publication (1..100)

Nom du topic: nom du topic dans MQTT

Min time between refresh: correspond au temps minimum entre chaque publication si la variable à changée. Le temps est exprimé en secondes.

Force refresh after: correspond au temps minimum entre chaque publication quelque soit le valeur de la variable. Le temps est exprimé en secondes.

type de donnée: IO => correspond à un numéro d'I/O  DB => correspond à un DB,Reg,Bit

n° d'I/O: si le type de donnée = IO alors indique le numéro d'I/O à utiliser pour stocker les données sinon pas utilisé

type de variable: 'F' => float, 'B' => boolean, 'W' => integer

n° du DB: numéro du databank si le type de donnée = DB sinon pas utilisé

n° du registre: numéro du registre du databank si type de donnée = DB sinon pas utilisé

n° du bit: numéro du bit du registre du databank si type de donnée = DB sinon pas utilisé