Le serveur HttpWebSocket

1. Description

Il est possible d'activer un serveur Http permettant de publier des pages statiques ainsi qu'un serveur WebSocket permettant de publier les changements des données du serveur. L'activation se fait au niveau du fichier <VKServer.ini> dans la section [Http]. Le mot clef Enabled=1 doit être défini. Il faut également que la licence permette cette option. Le serveur WebSocket transmet les modifications des données du serveur sous la forme de messages JSON. Il peut également recevoir des commandes sous le même format.

2. Les mots clef

Dans la section [http], les mots clef suivants sont disponibles:

Mot clef

Type

Description

Enabled

Boolean

Vrai si la fonctionnalité est activée.

BaseHttpURL

String

Adresse de base du serveur http

HttpPort

Integer

Numéro du port http

BaseWSURL

String

Adresse de base du serveur Websocket. Par défaut, l'adresse de base est /websocket

WSPort

Integer

Numéro du port WebSocket. Par défaut, le port du WebSocket sera le même que le port http

RootPath

String

Adresse du répertoire dans lequel les fichiers des pages htlm sont sauvegardés. Par défaut, definitionpath+\www

DomainName

String

Nom du domain. Par défaut, +

Exemple de définition:

[HTTP]
Enabled=1
httpPort=8484

3. Le protocole de communication

Un protocole de communication spécialement conçu pour QuickView est implémenté. Les messages JSON sont formés comme suit:

Exemple de message:

Les clients doivent se connecter sur le serveur à l'aide d'un websocket. Avant d'ouvrir le websocket, les clients devront s'identifier sur le serveur Web en effectuant un POST à l'adresse /auth avec comme paramètres "?username=xxx&pass=yyy". Les "userName" et "Password" correspondant aux identifiants de QuickView. Si l'identification est correct, le serveur renvoie un jwt ( JSon Web Token) enregistré dans un Cookie (jwtoken=.....). Lorsque le client ouvre le websocket, le serveur vérifie le contenu du token et accepte ou non son ouverture. Le token est valable 24 heures après quoi il est nécessaire de renouveler son identification si le websocket est fermé.

Il est aussi possible d'utiliser le mode d'authentification basic des websocket pour se connecter. En utilisant ce schéma, le serveur attend le token Authorization: Basic xxxx dans l'entête de la requête de connexion (voir https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Authorizationarrow-up-right ).

3.1 Les commandes possibles

Pour pouvoir lire, écrire, etc... le protocole demande l'utilisation de commandes. Les commandes possibles sont décrit dans le tableau suivant:

Commandes

Description

read

Lecture du contenu d'un registre.

Format de la commande "read" :

{"function":"read", "register":n }

{"function":"read", "databank":n }

n étant un entier et correspond au numéro de registre désiré.

write

Écriture de données dans un registre.

Format de la commande "write":

{"function":"write", "register":n, "data": {json object}}

{"function":"write", "databank":n, "reg":m, "bit":b, "value":true or false}

{"function":"write", "databank":n, "reg":m, "value": number or "string"}

n étant un entier correspondant au numéro de registre. data correspond à un objet JSOn qui est spécifique pour chaque registre.Lors de l'écriture dans un registre d'un databank, il faut spécifier le databand, le registre et la valeur pour une donnée complète du registre ou alors spécifier le bit et l'état de ce bit pour une valeur boolean.

readall

Demande le rafraîchissement de tous les registres du système. Le serveur renvoie tous les registres disponibles.

Format de la commande "refreshall":

{"function":"readall"}

subscribe

Souscrit au rafraîchissement d'un ou de plusieurs registres. Le serveur renvoie chaque changement d'un registre à tous les clients ayant souscrit à ce registre.

Format de la commande "subscribe":

{"function":"subscribe", "register":[x,y,z,...]} => souscrit aux changements de registres {"function":"subscribe", "databank":[x,y,z,...]} => souscrit aux changements des databanks {"function":"subscribe"} => souscrit à tous les changements

unsubscribe

Annule la souscription à un ou plusieurs registres.

Format de la commande "unsubscribe":

{"function":"unsubscribe", "register":[x,y,z,...]} => annule les souscriptions aux changements de registres

{"function":"unsubscribe", "databank":[x,y,z,...]} => annule les souscriptions aux changements de databank

{"function":"unsubscribe"} => annule toutes les souscriptions

3.2 Les registres

Les registres suivants sont disponibles:

Registre

Data

Description

10

"modeprogram":boolean Statut du mode programme

"modebuffer":boolean Statut du mode gare

"simulation":boolean Vrai si en mode simulation

"endofcycle":boolean Vrai si en fin de cycle

"workingmode":integer Mode de fonctionnement (0:DIA/OPI, 1:Priority, 2:OSCILine)

"timesynch":integer Nombre de secondes depuis le 01/01/1980. Permet de synchroniser les horloges

Statuts de la machine

32

"DateOfData" : string Date des données au format yyyymmdd

"Date" : string Date des données au format du PC

"BatchesIn" : Integer Nombre de chargements

"BatchesOut" : Integer Nombre de déchargements

"IdleTime" : Integer Nombre de minutes avec poste de charge vide

"ErrorStopTime" : Integer Nombre de minutess en stop causé par une alarme

"ErrorWarningTime" : Integer Nombre de minutes en stop causé par une alarme système en Auto

"ManuModeTime" : Integer Nombre de minutes en mode manuel

"SafetyDoorTime" : Integer Nombre de minutes pendant lesquelles les portes sont ouvertes

"PowerOnTime" : Integer Nombre de minute pendant lesquelles la machine est en marche

"Utilization-RPT" : Integer (PowerOnTime-Idle Time)/Power On Time = % d'utilisation

"Reliability" : Integer (Power On Time-Error Stop Time)/Power on Time = %

Données journalières

33

"labels" : Array 0..23arrow-up-right of strings Heures

"BatchsIn": Array 0..23 of integer Nombre de chargements par heure

"BatchesOut": Array 0..23 of integer Nombre de déchargements par heure

... Comme registre 32

Données journalières sur 24 heures

40

"alarmcount":integer Nombre d'alarme en cours

"alarms": array of alarm

[

"evt":integer Type d'événement: 1=Rtn, 2=Ack, 3=Ala, 4=Wrn

"num":integer Numéro de l'alarme

"time":Time Heure de l'alarme

"type":string Type de l'alarme

"group":string Groupe de l'alarme

"mess":string Message de l'alarme

"val":float Valeur associée à l'alarme

]

Liste des alarmes actives

42

"messagecount":integer Nombre de messages en cours

"messages": array of message

[

"evt":integer Type d'événement: 1=Rtn, 2=Ack, 3=Ala, 4=Wrn

"num":integer Numéro du message

"time":Time Heure du message

"type":string Type du message

"group":string Groupe du message

"mess":string Texte du message

"val":float Valeur associée au message

]

Liste des messages actifs

2000

"positioncount":integer Nombre de positions dans la machine

"hoistcount":integer Nombre de transporteurs dans la machine

"positions":array of position

[

"pos":integer Numéro de la position

"name": string Nom de la position

"flag":integer Flag de la position

"addr":integer Adresse de la position

"group":integer Numéro du groupe de la position

"tank": integer Numéro de la cuve

"disable":boolean Vrai si la position peut être mise hors service

"width":integer Largeur de la position

"process":integer Numéro de la page graphique

"dist":integer Distance entre position précédente et centre de la position

"branch";integer Numéro de la branche de la machine

"num":integer Numéro de la position à afficher

"layout":integer Layout de la position (0=standard, 1=en avant, 2=en arrière)

]

"hoists":array of hoist

[

"hoist":integer Numéro du transporteur

"type":integer Type de transporteur

"driptray":Boolean True si un bac d'égouttage est défini

"halfup":Boolean True si le transporteur peut faire un up demi

"pmin":integer Position minimale du transporteur

"pmax":integer Position maximale du transporteur

]

Définition de la machine

3000

"rectifiercount":integer Nombre de redresseur défini

"rectifiers": array of rectifier

[

"rectifier":integer numéro du redresseur

"position":integer position dans laquelle se trouve le redresseur

"name":string Nom du redresseur

"status":integer Statut du redresseur

"step":integer Step actuel du profil de courant

"ahamn":boolean True si Ah

"surface":float surface exposée

"density":float densité de courant

"current":float courant actuel

"voltage":float tension actuelle

"Q":float compteur Ah

"QTheo:float quantité d'Ah théorique

"QTheoAct:float écart actuel des Ah

"QTotal":float totalisateur des Ah

"setpoint":float consigne actuelle

"reverse":float consigne actuelle inverse

"maxU":float tension maximale

"maxI":float courant maximum

"minU":float tension à vide

"minI":float courant max lorsque la tension min est appliquée

"pcsetpoint":integer pourcentage de la consigne lorsque plusieurs redresseurs sont utilisés sur la même position

"alternation":integer temps entre chaque alternance

"surfaceflag":integer partie de la surface prise en considération

"currentform":integer numéro du profil de courant

"flag0":integer

"flag1:integer

"flag2:integer

]

Les redresseurs

5001..5100

"device":integer Numéro du device utilisé dans QuickView (0=interne)

"channel":integer Numéro du canal

"db":integer Numéro du db de l'automate

"regstart":integer Numéro du premier registre

"regend":integer Numéro du dernier registre

"registers": array of registre

[

"reg":integer Numéro du registre

"type":string Type de registre (byte,word,dword,real,string,int)

"value": string | number | float Valeur du registre

]

Contenu des databanks du serveur

12000

"ios" : array of IO

[

"io" : Integer Numéro de l'I/O

"Name" : string Nom de l'I/O

"unit" : string Unité de l'I/O

"type" : Integer Type d'I/O

"db" : Integer Numéro du DB

"reg" : Integer Numéro du registre

"bit" : Integer Numéro du bit

"mask" : Integer Mask à appliquer

"flags" : Integer Flags de l'I/O

"position" : Integer Position associée

"min" : Integer Valeur minimum

"max" : Integer valeur maximum

"value" : Integer|boolean|string selon le type de variable

]

Définition de toutes les I/O

12001..12999

"io" : Integer Numéro de l'I/O

"Name" : string Nom de l'I/O

"unit" : string Unité de l'I/O

"type" : Integer Type d'I/O

"db" : Integer Numéro du DB

"reg" : Integer Numéro du registre

"bit" : Integer Numéro du bit

"mask" : Integer Mask à appliquer

"flags" : Integer Flags de l'I/O

"position" : Integer Position associée

"min" : Integer Valeur minimum

"max" : Integer valeur maximum

"value" : Integer|boolean|string selon le type de variable

I/O individuelle

14000

"io1" : Integer|Boolean|String Donnée de l'I/O 1

"io2": Integer|Boolean|String Donnée de l'I/O 2

...

"io999": Integer|Boolean|String Donnée de l'I/O 999

Données de toutes les I/O sans définition

14100

"hoistsdata" : array hoistType

[

"hoist" : Integer Numéro du bras

"ready" : Boolean Vrai si le transporteur est prêt

"blockingalarms" : Integer Alarmes bloquantes

"height" : Integer Hauteur actuelle

"destheight" : Integer Hauteur de destination

"position" : Integer Position actuelle

"destination" : Integer Position de destination

"mode" : Integer Mode du robot

"movingleft" : Boolean Vrai si le robot se déplace à gauche

"movingright" : Boolean Vrai si le robot se déplace à droite

"movingup" : Boolean Vrai si le robot se déplace en haut

"movingdown" : Boolean Vrai si le robot se déplace en bas

"racknum" : Integer numéro de rack si présent sinon pas dans le record

"rackstatus" : Integer statut du rack si présent sinon pas dans le record

"rackprog" : Integer N° de programme du rack si présent sinon pas dans le record

]

Données de tous les robots

14101

"positionsdist" : array PositionDist

[

"position":integer numéro de position

"dist":integer distance depuis le début de la machine

]

"hoistsdist" : array HoistDist

[

"hoist":integer numéro du transporteur

"dist":integer distance actuelle depuis le début de la machine

]

14200

"positiondata" : array PositionDataType

[

"position" : Integer Numéro de la position

"racknum" : Integer numéro de rack si présent sinon pas dans le record

"rackstatus" : Integer statut du rack si présent sinon pas dans le record

"rackprog" : Integer N° de programme du rack si présent sinon pas dans le record

"program": String Nom du programme du rack

"ref": String Nom de la référence de la charge sur le rack

"tmin": Integer Temps minimum défini

"tmax": Integer Temps maximum défini

"teff": Integer Temps d'entrée dans la position (temps en secondes)

"disable" : Boolean Etat de la position si la position peut être mise hors service

"inalarm" : Boolean Etat d'alarme de la position

"ready" : Boolean Etat des équipements de la position par rapport au "Mode machine ready"

]

Données d'état des positions

14300

json de la page graphique

Données du dessin d'une page graphique

14301

"Registers" : array RegisterData

[

"db":integer numéro du databank

"reg":integer numéro du registre

"type":string type du registre (integer, real, string)

"value": integer or real or string valeur du registre

]

4. Utilisation en tant que API

Il est possible de faire des requêtes API sur le serveur. Pour obtenir les registres ci-dessus dans un GET HTTP, il faut effectuer les requêtes comme l'exemple suivant:

La réponse est un objet JSON comme suit:

{ "function":"write", "register":10, "Data": { "modeprogram": true, "modebuffer": true,..... }}

5. Utilisation comme serveur Web

Il est possible de fonctionner en tant que serveur web. Les fichiers doivent se trouver dans le répertoire RootPatharrow-up-right .

6. Dashboard

Il est possible de faire fonctionner le site web avec Freeboard.

Pour fonctionner, il faut décompresser le fichier www.ziparrow-up-right ci-dessous et le placer dans le répertoire défini dans rootPath.

file-archive
2MB
archive
www.zip

Pour le lancer, il faut soit taper l'adresse web du site pour avoir l'éditeur de freeboard ou soit http://localhost:8484/index.html#source=dashboard.jsonarrow-up-right pour lancer directement un dashboard prédéfini.

Dans le fichier index.html, le bouton donnant l'accès aux modification du dashboard a été commenté. Pour permettre des modifications, il faut dé-commenter les lignes 48 à 96 et 110 à 111

Mis à jour

Ce contenu vous a-t-il été utile ?