J'ai déjà présenté dans de précédents articles le couteau suisse de la connectivité OT/IT : KEPServerEX. Indispensable pour exposer les données d'une grande variété de machines via un serveur OPC/UA. Il est prévu pour fonctionner sous un environnement Windows.
Nous allons voir ici comment utiliser son pendant pour serveurs Linux : ThingWorx Kepware Edge.
Pour les besoins de cet article, nous utiliserons de nouveau notre PLC Siemens Logo! 8.
Contrairement à la version pour Windows, celle-ci ne dispose pas d'interface graphique. En revanche, elle expose une interface REST très complète et très bien documentée dans le ThingWorx Kepware Edge User Manual disponible en téléchargement. Elle est même autodocumentée, via des APIs spécifiques. Par exemple :
Définition des drivers/channels spécifiques
La requête suivante renvoie les éléments nécessaires à la création de channels dédiés au type de machine/équipement à connecter :
GET https://localhost:57513/config/v1/doc/drivers/Siemens%20TCP%2FIP%20Ethernet/channels
Réponse :
{
"type_definition": {
"name": "Channel",
"collection": "channels",
"namespace": "servermain",
"can_create": true,
"can_delete": true,
"can_modify": true,
"auto_generated": false,
"requires_driver": true,
"access_controlled": true,
"child_collections": [
"devices",
"phonebooks"
]
},
"property_definitions": [
{
"symbolic_name": "common.ALLTYPES_NAME",
"display_name": "Name",
"display_description": "Specify the identity of this object.",
"read_only": false,
"type": "String",
"default_value": null,
"minimum_length": 1,
"maximum_length": 256
},
{
"symbolic_name": "common.ALLTYPES_DESCRIPTION",
"display_name": "Description",
"display_description": "Provide a brief summary of this object or its use.",
"read_only": false,
"type": "String",
"default_value": null,
"minimum_length": 0,
"maximum_length": 255
},
{
"symbolic_name": "servermain.MULTIPLE_TYPES_DEVICE_DRIVER",
"display_name": "Driver",
"display_description": "",
"read_only": true,
"type": "String",
"default_value": "Siemens TCP/IP Ethernet",
"minimum_length": 0,
"maximum_length": -1
},
{
"symbolic_name": "servermain.CHANNEL_DIAGNOSTICS_CAPTURE",
"display_name": "Diagnostics Capture",
"display_description": "Select whether or not to make the channel's diagnostic information available to an OPC application.",
"read_only": false,
"type": "EnableDisable",
"default_value": false
},
{
"symbolic_name": "servermain.CHANNEL_UNIQUE_ID",
"display_name": "Unique Id",
"display_description": "Unique identifier associated with this object.",
"read_only": false,
"type": "Integer",
"default_value": 422613010,
"minimum_value": null,
"maximum_value": null
},
{
"symbolic_name": "servermain.CHANNEL_ETHERNET_COMMUNICATIONS_NETWORK_ADAPTER_STRING",
"display_name": "Network Adapter",
"display_description": "Specify the name of a network adapter to bind or allow the OS to select the default.",
"read_only": false,
"type": "StringWithBrowser",
"default_value": null,
"minimum_length": 0,
"maximum_length": -1,
"hints": [
"",
"wlp3s0",
"eno1"
]
},
...
]
}
Définition des devices
La requête suivante renvoie les éléments nécessaires à la création de devices dédiés au type de machine/équipement à connecter :
GET https://localhost:57513/config/v1/doc/drivers/Siemens%20TCP%2FIP%20Ethernet/devices
Réponse :
{
"type_definition": {
"name": "Device",
"collection": "devices",
"namespace": "servermain",
"can_create": true,
"can_delete": true,
"can_modify": true,
"auto_generated": false,
"requires_driver": true,
"access_controlled": true,
"child_collections": [
"services",
"tag_groups",
"tags"
]
},
"property_definitions": [
{
"symbolic_name": "common.ALLTYPES_NAME",
"display_name": "Name",
"display_description": "Specify the identity of this object.",
"read_only": false,
"type": "String",
"default_value": null,
"minimum_length": 1,
"maximum_length": 256
},
{
"symbolic_name": "common.ALLTYPES_DESCRIPTION",
"display_name": "Description",
"display_description": "Provide a brief summary of this object or its use.",
"read_only": false,
"type": "String",
"default_value": null,
"minimum_length": 0,
"maximum_length": 255
},
{
"symbolic_name": "servermain.MULTIPLE_TYPES_DEVICE_DRIVER",
"display_name": "Driver",
"display_description": "",
"read_only": true,
"type": "String",
"default_value": "Siemens TCP/IP Ethernet",
"minimum_length": 0,
"maximum_length": -1
},
{
"symbolic_name": "servermain.DEVICE_MODEL",
"display_name": "Model",
"display_description": "Select the specific type of device associated with this ID. Options depend on the type of communications in use.",
"read_only": false,
"type": "Enumeration",
"default_value": null,
"enumeration": {
"S7-200": 0,
"S7-300": 1,
"S7-400": 2,
"S7-1200": 3,
"S7-1500": 4,
"NetLink: S7-300": 5,
"NetLink: S7-400": 6
}
},
{
"symbolic_name": "servermain.DEVICE_UNIQUE_ID",
"display_name": "Unique Id",
"display_description": "Unique identifier associated with this object.",
"read_only": false,
"type": "Integer",
"default_value": 4145021575,
"minimum_value": null,
"maximum_value": null
},
{
"symbolic_name": "servermain.DEVICE_ID_FORMAT",
"display_name": "ID Format",
"display_description": "Indicate the format of the device ID (set by the driver by default).",
"read_only": false,
"type": "Enumeration",
"default_value": 0,
"enumeration": {
"Octal": 0,
"Decimal": 1,
"Hex": 2
}
},
...
]
}
Munissez-vous donc d'un client d'API comme Postman, d'un client OPC/UA comme UAExpert, et c'est parti!
Les endpoints
La documentation ThingWorx Kepware Edge Quick Start décrit les étapes nécessaires pour connecter un premier client UAExpert au serveur OPC/UA, via le endpoint créé par défaut par l'installation standard. Ce dernier est sécurisé et requiert une validation manuelle pour accepter la connexion du client au serveur.
Mais il est fréquent que le client qui sera utilisé dans une application (que vous découvrirez dans un prochain article ;) ne supporte pas ce mécanisme d'authentification. Il devient donc nécessaire de créer en premier lieu un nouveau endpoint "non sécurisé".
Ceci peut donc être fait via l'API REST de Kepware Edge :
POST https://localhost:57513/config/v1/admin/ua_endpoints
Body :
{
"common.ALLTYPES_NAME": "UnsecureEndpoint",
"common.ALLTYPES_DESCRIPTION": "Available adapters: Default; wlp3s0:192.168.1.94; vboxnet0:192.168.56.1; eno1:; localhost",
"libadminsettings.UACONFIGMANAGER_ENDPOINT_ENABLE": true,
"libadminsettings.UACONFIGMANAGER_ENDPOINT_ADAPTER": "Default",
"libadminsettings.UACONFIGMANAGER_ENDPOINT_PORT": 49331,
"libadminsettings.UACONFIGMANAGER_ENDPOINT_URL": "opc.tcp://localhost:49331",
"libadminsettings.UACONFIGMANAGER_ENDPOINT_SECURITY_NONE": true,
"libadminsettings.UACONFIGMANAGER_ENDPOINT_SECURITY_BASIC128_RSA15": 0,
"libadminsettings.UACONFIGMANAGER_ENDPOINT_SECURITY_BASIC256": 0,
"libadminsettings.UACONFIGMANAGER_ENDPOINT_SECURITY_BASIC256_SHA256": 0
}
Il sera nécessaire de redémarrer le serveur pour prendre en compte cette modification. Ce nouveau endpoint apparaitra donc dans le client OPC/UA :
Le Channel
En s'appuyant sur la documentation récupérée plus haut, nous pouvons créer le channel spécifique à notre PLC Siemens :
POST https://localhost:57513/config/v1/project/channels
Body :
{
"common.ALLTYPES_NAME": "SiemensChannel",
"servermain.MULTIPLE_TYPES_DEVICE_DRIVER": "Siemens TCP/IP Ethernet",
"servermain.CHANNEL_DIAGNOSTICS_CAPTURE": false,
"servermain.CHANNEL_WRITE_OPTIMIZATIONS_METHOD": 2,
"servermain.CHANNEL_WRITE_OPTIMIZATIONS_DUTY_CYCLE": 10,
"servermain.CHANNEL_NON_NORMALIZED_FLOATING_POINT_HANDLING": 0,
"servermain.CHANNEL_ETHERNET_COMMUNICATIONS_NETWORK_ADAPTER_STRING":"wlp3s0"
}
Le Device
Nous pouvons maintenant associer à notre Channel un Device représentant notre Logo! 8 :
POST https://localhost:57513/config/v1/project/channels/SiemensChannel/devices
Body :
{
"common.ALLTYPES_NAME": "Logo8",
"servermain.DEVICE_ID_STRING": "192.168.1.13",
"servermain.MULTIPLE_TYPES_DEVICE_DRIVER": "Siemens TCP/IP Ethernet",
"servermain.DEVICE_MODEL": 0,
"servermain.DEVICE_ID_FORMAT": 0,
"servermain.DEVICE_ID_HEXADECIMAL": 0,
"servermain.DEVICE_ID_DECIMAL": 0,
"servermain.DEVICE_ID_OCTAL": 0,
"servermain.DEVICE_DATA_COLLECTION": true,
"servermain.DEVICE_SIMULATED": false,
"servermain.DEVICE_SCAN_MODE": 0,
"servermain.DEVICE_SCAN_MODE_RATE_MS": 1000,
"servermain.DEVICE_SCAN_MODE_PROVIDE_INITIAL_UPDATES_FROM_CACHE": false,
"servermain.DEVICE_CONNECTION_TIMEOUT_SECONDS": 3,
"servermain.DEVICE_REQUEST_TIMEOUT_MILLISECONDS": 2000,
"servermain.DEVICE_RETRY_ATTEMPTS": 2,
"servermain.DEVICE_INTER_REQUEST_DELAY_MILLISECONDS": 0,
"servermain.DEVICE_AUTO_DEMOTION_ENABLE_ON_COMMUNICATIONS_FAILURES": false,
"servermain.DEVICE_AUTO_DEMOTION_DEMOTE_AFTER_SUCCESSIVE_TIMEOUTS": 3,
"servermain.DEVICE_AUTO_DEMOTION_PERIOD_MS": 10000,
"servermain.DEVICE_AUTO_DEMOTION_DISCARD_WRITES": false,
"servermain.DEVICE_TAG_GENERATION_ON_STARTUP": 1,
"servermain.DEVICE_TAG_GENERATION_DUPLICATE_HANDLING": 0,
"servermain.DEVICE_TAG_GENERATION_GROUP": "",
"servermain.DEVICE_TAG_GENERATION_ALLOW_SUB_GROUPS": true,
"siemens_tcpip_ethernet.DEVICE_COMMUNICATIONS_PORT_NUMBER": 102,
"siemens_tcpip_ethernet.DEVICE_COMMUNICATIONS_MPI_ID": 0,
"siemens_tcpip_ethernet.DEVICE_S7_COMMUNICATIONS_MAX_PDU": 960,
"siemens_tcpip_ethernet.DEVICE_S7_COMMUNICATIONS_200_LOCAL_TSAP": 200,
"siemens_tcpip_ethernet.DEVICE_S7_COMMUNICATIONS_200_REMOTE_TSAP": 200,
"siemens_tcpip_ethernet.DEVICE_S7_COMMUNICATIONS_300_400_1200_1500_LINK_TYPE": 3,
"siemens_tcpip_ethernet.DEVICE_S7_COMMUNICATIONS_CPU_RACK": 0,
"siemens_tcpip_ethernet.DEVICE_S7_COMMUNICATIONS_CPU_SLOT": 2,
"siemens_tcpip_ethernet.DEVICE_ADDRESSING_BYTE_ORDER": 0,
"siemens_tcpip_ethernet.DEVICE_TAG_IMPORT_TYPE": 0,
"siemens_tcpip_ethernet.DEVICE_TAG_IMPORT_CODE_PAGE": 4294967295,
"siemens_tcpip_ethernet.DEVICE_TAG_IMPORT_STEP_7_PROJECT_FILE": "",
"siemens_tcpip_ethernet.DEVICE_TAG_IMPORT_PROGRAM_PATH": "",
"siemens_tcpip_ethernet.DEVICE_TAG_IMPORT_TIA_EXPORT_FILE": ""
}
Toutes ces informations correspondent à ce qui est demandé par l'assistant de configuration dans la version Windows.
Les Tags
Terminons par le plus important, exposer les informations de l'automate via les tags OPC/UA :
POST https://localhost:57513/config/v1/project/channels/SiemensChannel/devices/Logo8/tags
Body :
[
{
"common.ALLTYPES_NAME": "Entree1",
"servermain.TAG_ADDRESS": "I0.0",
"servermain.TAG_DATA_TYPE": 1,
"servermain.TAG_READ_WRITE_ACCESS": 1,
"servermain.TAG_SCAN_RATE_MILLISECONDS": 100,
"servermain.TAG_SCALING_TYPE": 0
},
{
"common.ALLTYPES_NAME": "EntreeReseau1",
"servermain.TAG_ADDRESS": "V0.0",
"servermain.TAG_DATA_TYPE": 1,
"servermain.TAG_READ_WRITE_ACCESS": 1,
"servermain.TAG_SCAN_RATE_MILLISECONDS": 100,
"servermain.TAG_SCALING_TYPE": 0
},
{
"common.ALLTYPES_NAME": "Output1",
"servermain.TAG_ADDRESS": "Q0.0",
"servermain.TAG_DATA_TYPE": 1,
"servermain.TAG_READ_WRITE_ACCESS": 1,
"servermain.TAG_SCAN_RATE_MILLISECONDS": 100,
"servermain.TAG_SCALING_TYPE": 0
}
]
Et voilà! Notre serveur est prêt à être utilisé :
Pour aller plus loin
Si vous avez besoin de configuration spécifique, avec des attributs particuliers, pour ne pas avoir à fouiller dans toute la documentation, il est possible d'exporter un projet déjà existant sous Kepware version Windows au format JSON : vous retrouverez ainsi tout le contenu nécessaire pour appeler les APIs REST!
Récupération des logs
Les logs du serveur, habituellement visibles sous Windows dans la console, peuvent être récupérés via cette interface :
GET https://localhost:57513/config/v1/event_log
0 commentaires:
Enregistrer un commentaire