Database

Les valeurs qu'un système de l'usine garde dans une table de base de données (SQL Server, PostgreSQL, MySQL et MariaDB, SQLite, ou toute base de données par ODBC) lues comme tags, et réécrites là où un tag le demande : les cartes Base de données et Connexion à la base, un tag qui lit une cellule par sa table, sa colonne et sa ligne ou exécute une requête propre, les deux façons dont un tag écrit, le balayage qui propose un tag par colonne, quatre exemples complets et ce que le pilote ne fait pas.

Afficher en Markdown

Le pilote Database lit les valeurs qu'un système de l'usine garde dans une table de base de données : l'ordre de fabrication que tient le MES, la recette ou la consigne que garde l'ERP, le résultat qu'un autre système d'essai a enregistré. Chaque tag lit une valeur d'une table, et ses valeurs arrivent là où arrivent celles de tout autre tag : dans Logic, sur les tableaux de bord, dans les essais d'un banc de test de Process. Là où un tag le demande, le pilote écrit aussi en retour : dans la cellule que lit le tag, ou par une commande propre au tag.

SQL Server, PostgreSQL, MySQL et MariaDB, et SQLite sont atteints sans rien installer sur l'ordinateur. Toute autre base de données (Oracle, Access, Firebird et d'autres) est atteinte par son propre pilote ODBC, qui doit être installé sur l'ordinateur dans sa version 64 bits.

La lecture est l'usage principal, et son chemin est court : un équipement dit où se trouve sa base de données et comment la station s'y connecte, le balayage propose un tag par colonne de ses tables, et chaque tag naît en lecture seule. Ce qui relève de l'écriture n'apparaît sur un tag qu'une fois que son accès laisse la station écrire.

Un équipement de ce pilote est une base de données : deux bases de données du même serveur sont deux équipements. Les équipements se rangent sous le pilote et peuvent être classés dans des dossiers, Pilote → Dossier → Équipement → Tag, comme sous tout pilote sans ligne série ni broker.

La page du pilote

La ligne sous l'en-tête indique « Chaque équipement lit une base de données. Ajoutez un équipement, saisissez où se trouve sa base de données et comment la station se connecte, puis balayez-le pour ajouter ses colonnes comme tags. » Pour Configurer le connector, la page porte la carte Portée du balayage propre au pilote, avec l'équipement dont le balayage lit la base de données (voir Découverte). En dessous se trouve le tableau Équipements de tout pilote (voir Le tableau des équipements), qui grandit avec Ajouter un équipement, à droite de son titre; vide, il indique « Aucun équipement pour l'instant. » La barre du pilote porte Découvrir, grisé tant que la carte Portée du balayage n'est pas complète. Le pilote est rangé sous Fichiers et bases de données, à côté du pilote File.

Équipement

Un équipement de ce pilote n'a pas de carte Connexion : la carte Base de données en tient la place, suivie de la carte Connexion à la base sur toute base de données sauf SQLite, qui n'a pas de connexion. L'Intervalle de scrutation (ms) de la carte Équipement, 1000 par défaut, dit à quelle fréquence les tags lisent la base de données, et chaque tag peut le remplacer comme sous tout pilote.

Un nouvel équipement est un SQL Server sans serveur : il indique « Serveur pas encore saisi », sa page dit « La station n'atteint pas cet équipement tant qu'il ne dit pas où se trouve sa base de données : rien n'est donc encore lu depuis lui et il n'y a aucune erreur à afficher. Saisissez-le dans la carte Base de données ci-dessous (le serveur et le nom de la base de données, le fichier ou la source de données) et la station s'y connecte. » et rien n'est lu tant qu'il ne le dit pas. La Base URI que montre l'en-tête est l'adresse d'exécution, qui ne contient jamais l'utilisateur ni le mot de passe : database://sqlserver?server=mes-sql&instance=SQLEXPRESS&database=MES pour une instance SQL Server, database://sqlite?file=C%3A%5CData%5Crecipes.db pour un fichier SQLite, database://odbc?source=ERP pour une source de données ODBC.

La carte Base de données

Champ Affiché Sens Par défaut
Type de base de données toujours SQL Server, PostgreSQL, MySQL / MariaDB, SQLite ou Autre (ODBC), qui indique « Utilise le pilote ODBC 64 bits installé sur cet ordinateur pour cette base de données (Oracle, Access, Firebird et d'autres). » SQL Server
Serveur SQL Server, PostgreSQL, MySQL / MariaDB Sur SQL Server : « Un nom d'hôte ou une adresse IP. SERVEUR\INSTANCE et SERVEUR,PORT sont répartis dans leurs champs. » Sur les deux autres : « Un nom d'hôte ou une adresse IP. Un port écrit après deux-points va dans le champ Port. » vide
Port les mêmes Vide pour le port propre à la base de données, que la case vide affiche : 1433, 5432 ou 3306. Avec une instance SQL Server et sans port, la case n'affiche rien et le SQL Server Browser du serveur donne le port. vide
Nom d'instance SQL Server « Vide pour l'instance par défaut. Une instance nommée sans port est trouvée par le SQL Server Browser. » Jusqu'à 16 lettres, chiffres, _ et $, en commençant par une lettre ou _. vide
Nom de la base de données SQL Server, PostgreSQL, MySQL / MariaDB La base de données du serveur qui contient les tables, jusqu'à 128 caractères. vide
Fichier de base de données SQLite « Le chemin complet du fichier SQLite, atteint avec les droits Windows du compte sous lequel roule la station. Il est ouvert en lecture seule tant qu'aucun tag n'écrit. » La case affiche C:\Data\recipes.db comme indication. Le fichier n'est jamais créé. vide
Source de données ou texte de connexion Autre (ODBC) « Le nom d'une source de données des Sources de données ODBC de Windows (64 bits), ou un texte de connexion comme Driver=;Dbq=C:\Data\plant.accdb. Le mot de passe va dans le champ du mot de passe, jamais dans le texte. » vide

Un champ que le type choisi ne lit pas n'est pas affiché, et garde sa valeur pour le jour où il le lit. Choisir un autre type vide un port resté sur le port propre à l'ancienne base de données, pour que la nouvelle soit atteinte sur le sien. La case Serveur répartit ce que les outils de bases de données écrivent ensemble :

Saisi dans Serveur Devient
mes-sql\SQLEXPRESS (SQL Server) Serveur mes-sql, Nom d'instance SQLEXPRESS
mes-sql,1433 (SQL Server) Serveur mes-sql, Port 1433
10.0.0.5:5433 Serveur 10.0.0.5, Port 5433

Tant que la carte ne dit pas où se trouve la base de données, l'équipement est enregistré tel quel et attend, point gris, sans rien lire et sans afficher d'erreur :

Type de base de données Attend L'équipement indique
SQL Server, PostgreSQL, MySQL / MariaDB Le serveur, puis le nom de la base de données « Serveur pas encore saisi », puis « Nom de la base de données pas encore saisi »
SQLite Le fichier « Fichier de base de données pas encore saisi »
Autre (ODBC) La source de données ou le texte de connexion « Source de données pas encore saisie »

Un réglage que la carte ne peut pas prendre est signalé sous les cartes, et l'équipement n'est pas enregistré tant qu'il n'est pas corrigé :

Vous saisissez La carte dit
Un serveur avec un schéma, un chemin ou une espace, comme http://mes-sql « Le serveur est un nom d'hôte ou une adresse IP seul : sans schéma, sans chemin et sans espace. Une instance SQL Server et un port écrits avec lui vont dans leurs propres champs. »
Un nom d'instance avec une espace ou un signe autre que _ et $ « Le nom d'instance compte jusqu'à 16 lettres, chiffres, traits de soulignement et signes dollar. »
Un nom de base de données de plus de 128 caractères « Le nom de la base de données compte au plus 128 caractères, sans caractère de contrôle. »
Un fichier qui n'est pas un chemin complet, comme recipes.db « Le fichier de base de données est un chemin complet : un lecteur, un dossier et le fichier (C:\Data\recettes.db), ou un partage réseau (\server\data\recettes.db). »
Un dossier, ou un chemin contenant *, ?, <, > ou un guillemet « Saisissez le chemin du fichier de base de données lui-même, pas celui d'un dossier, sans *? | < > ni guillemets. »
Un nom de source de données contenant un crochet, une accolade, une parenthèse, une virgule, un point-virgule ou l'un de ? * ! @ \ La carte demande le nom qu'a la source dans les Sources de données ODBC, ou un texte de connexion.
Un texte de connexion qui n'est pas fait de paires key=value, comme une accolade restée ouverte « Un texte de connexion est une suite de paires key=value séparées par des points-virgules; une valeur qui contient un point-virgule va entre accolades. »
Un texte de connexion contenant PWD= ou Password= « Retirez le mot de passe du texte de connexion et saisissez-le dans le champ du mot de passe : le texte est affiché et écrit dans le journal technique, et ce champ le garde protégé. »

L'enregistrement applique les mêmes règles, et le fil le dit quand il en refuse une : « L'équipement 'MES' a un réglage de base de données que son pilote ne peut pas utiliser. Ouvrez-le et corrigez le champ que son panneau signale. »

La carte Connexion à la base

Toute base de données sauf SQLite porte la carte Connexion à la base, avec l'utilisateur sous lequel la station se connecte.

Champ Affiché Sens Par défaut
Se connecter avec le compte Windows de la station SQL Server Activé : « La station se connecte à SQL Server avec le compte Windows sous lequel elle roule; aucun utilisateur ni mot de passe n'est enregistré. » Désactivé : « La station se connecte à SQL Server avec un utilisateur de la base de données et son mot de passe. » désactivé
Nom d'utilisateur un serveur où l'on se connecte avec un utilisateur, et ODBC, où il est facultatif L'utilisateur de la base de données. vide
Mot de passe les mêmes Le mot de passe de l'utilisateur, gardé protégé comme tout identifiant d'un pilote : il n'est jamais réaffiché, jamais écrit dans l'adresse ni dans le journal technique, et jamais rendu à un agent. vide
Chiffrement SQL Server Chiffrée, certificat vérifié : « La connexion est chiffrée et le certificat du serveur est vérifié au regard des certificats auxquels cet ordinateur fait confiance. » Chiffrée, tout certificat accepté : « La connexion est chiffrée et tout certificat est accepté, comme l'exige un serveur d'usine qui a son propre certificat. L'identité du serveur n'est pas vérifiée. » Non chiffrée : « Les valeurs et les commandes circulent en clair. Seulement pour un ancien serveur qui n'offre aucun chiffrement. » Chiffrée, certificat vérifié

PostgreSQL et MySQL n'ont pas de champ Chiffrement : leur connexion est chiffrée dès que le serveur le propose. Un SQL Server dont le certificat est le sien, comme l'est souvent celui d'un serveur d'usine, refuse la connexion avec les mots de la base de données sur une chaîne de certificats émise par une autorité qui n'est pas approuvée : Chiffrée, tout certificat accepté est le choix que ce serveur demande.

Sous ses champs, la carte dit quel utilisateur demander : « Demandez à l'administrateur de la base de données un utilisateur qui n'a que les droits dont la station a besoin : la lecture, et l'écriture seulement dans les tables que ses tags modifient. » La station lit et écrit les données d'un autre système avec tout ce que son utilisateur peut faire : cet utilisateur est donc la vraie limite de ce que la station peut modifier. Chaque écriture est inscrite au journal technique, comme sous tout pilote.

Un serveur où l'on se connecte avec un utilisateur, sans utilisateur encore saisi, dit à la place « Saisissez l'utilisateur avec lequel la station se connecte. D'ici là, la station ne connecte pas cet équipement. » Ce n'est pas un refus : l'équipement est enregistré, et son erreur dit qu'aucun utilisateur de la base de données n'est encore saisi, jusqu'à ce que l'utilisateur soit là.

En ligne, en attente et hors ligne

Situation Ce que font l'équipement et ses tags
La carte Base de données ne dit pas où se trouve la base de données L'équipement attend, point gris, rien n'est lu et aucune erreur (voir plus haut).
Un serveur où l'on se connecte avec un utilisateur, et aucun n'est saisi La station ne connecte pas l'équipement; son erreur dit qu'aucun utilisateur de la base de données n'est encore saisi.
Le serveur ne répond pas, refuse la connexion, ou le fichier SQLite n'existe pas L'équipement est hors ligne avec la cause donnée par la base de données elle-même, et la station le connecte dès qu'elle le peut. Une connexion est attendue au plus 10 s.
La connexion est perdue (le serveur a redémarré, le réseau est coupé) L'équipement passe hors ligne et se connecte de nouveau.
Une instruction que la base de données refuse, ou qui roule encore après 10 s Une lecture en échec de ce tag, avec les mots de la base de données elle-même; l'équipement continue de lire ses autres tags.
Un tag lit la ligne la plus récente d'une table qui n'a encore aucune ligne Ce tag attend, sans erreur, et l'état de santé de son équipement ne le compte pas tant que la première ligne n'est pas écrite : les autres tags de l'équipement disent s'il est en ligne. Une table vidée après que le tag y a lu n'est pas cette attente : le tag garde sa dernière lecture, qui compte comme en échec une fois plus ancienne que son intervalle de scrutation plus 10 s, comme sous tout pilote.

Chaque équipement a sa propre connexion, ouverte quand il se connecte et jamais partagée ni gardée dans un pool : une connexion qu'un serveur a coupée n'est jamais réutilisée.

Préparer le serveur

Les trois bases de données réseau sont livrées fermées à un autre ordinateur dans les installations courantes. Chacun de ces réglages se fait sur le serveur, par celui qui l'administre; la station n'en change aucun.

Base de données Ce qui laisse la station dehors Où cela se change
SQL Server TCP/IP désactivé (SQL Server Express et Developer sont livrés ainsi) SQL Server Configuration Manager > SQL Server Network Configuration > Protocols for l'instance : activez TCP/IP, puis redémarrez SQL Server (l'instance) sous SQL Server Services
SQL Server Une instance nommée écoute sur un port qu'elle choisit elle-même TCP/IP > IP Addresses > IPAll : videz TCP Dynamic Ports et saisissez le port dans TCP Port, puis redémarrez; ou laissez vide le champ Port de l'équipement et donnez le nom de l'instance
SQL Server Une instance nommée sans port se trouve par le SQL Server Browser, arrêté ou bloqué (erreur 26) SQL Server Services : SQL Server Browser démarré, Start Mode Automatic; UDP 1434 autorisé dans le pare-feu du serveur
PostgreSQL listen_addresses vaut localhost, sa valeur par défaut postgresql.conf : listen_addresses = '*', puis redémarrez PostgreSQL
PostgreSQL Aucune ligne de pg_hba.conf ne laisse entrer l'adresse de cette station (SQLSTATE 28000) pg_hba.conf : une ligne host pour la base, l'utilisateur et l'adresse de cette station, avec scram-sha-256 (md5 pour un mot de passe enregistré en MD5), puis SELECT pg_reload_conf();
MySQL, MariaDB bind-address vaut 127.0.0.1, comme beaucoup de paquets le règlent, ou skip-networking est activé La section [mysqld] du fichier de configuration : bind-address = 0.0.0.0, skip-networking supprimé, puis redémarrez
MySQL, MariaDB Aucun compte pour l'adresse de cette station (erreur 1130) CREATE USER pour l'utilisateur à l'adresse de cette station, et GRANT de ce dont les tags ont besoin

Toutes demandent aussi le port de la base autorisé dans le pare-feu de l'ordinateur du serveur. Quand le serveur répond de l'une de ces façons, la page de l'équipement dit de quel réglage il s'agit, avec ces étapes et les valeurs de cet équipement (le port, l'instance, l'adresse de cette station telle que le serveur l'a vue, la ligne de pg_hba.conf et le compte MySQL, chacun avec un bouton de copie), à la place de l'erreur en anglais de la base. L'avis disparaît de lui-même dès que l'équipement se connecte, ou quand le serveur répond autrement. Le journal et l'agent lisent les mêmes étapes.

Adressage du tag

Comment un tag lit

Un tag de ce pilote n'a pas de case d'adresse à lui : sa carte Source de la valeur demande comment il lit.

Lit Ce que montre le tag Ses champs
Table et colonne Une cellule : la colonne de la valeur d'une ligne d'une table. Table de la valeur, Colonne de la valeur, Ligne à lire et les champs de la ligne
Requête propre La première colonne de la première ligne que renvoie un SELECT propre. Texte de la requête

Un nouveau tag lit Table et colonne, par sa clé, en Double. Les types proposés sont Boolean, Int32, Int64, Float, Double, String et DateTime. À la lecture d'une cellule, un tag de nombre entier refuse une valeur avec une partie décimale plutôt que de l'arrondir (l'écriture fait l'inverse, voir Écriture), et un texte ne se lit comme nombre que s'il en est un. Chaque tag naît en Lecture seule; ce que l'écriture ajoute se trouve dans Écriture.

Table et colonne

Champ Affiché Sens Par défaut
Table de la valeur Table et colonne « Un nom, ou un schéma et un nom (dbo.Orders). Un nom qui contient des espaces ou des majuscules va entre guillemets ou entre crochets, comme [Order Lines]. » vide
Colonne de la valeur Table et colonne La colonne dont la cellule est la valeur du tag. vide
Ligne à lire Table et colonne Par sa clé : « La ligne dont la colonne clé contient la valeur clé. Les tags d'une même table et d'une même ligne sont lus ensemble en une seule requête. » La plus récente : « La ligne qui a la valeur la plus haute de la colonne de date : une date et une heure, ou un nombre qui ne fait que croître. Les tags d'une même table et d'une même ligne sont lus ensemble en une seule requête. » Par sa clé
Colonne clé Par sa clé La colonne qui choisit la ligne, comme OrderNo. vide
Valeur clé Par sa clé Ce que contient la colonne clé dans la ligne à lire, comme 4711, saisi comme texte : la base de données le lit comme elle lit une valeur de cette colonne. vide
Colonne de date La plus récente La colonne dont la valeur la plus haute est la ligne la plus récente, comme updated_at. vide

Un nom se lit comme la base de données le lit :

Écrit Lu comme
Orders Un nom simple, lu comme la base de données lit tout nom simple : PostgreSQL en minuscules, Oracle en majuscules.
"Order Lines", [Order Lines] Le nom exact, quels que soient les guillemets que la base de données elle-même accepte.
dbo.Orders Un schéma et une table : un point hors des guillemets les sépare.

Le pilote met chaque partie d'un nom entre les guillemets que sa base de données accepte : un nom n'est donc jamais collé dans une instruction comme du texte. Un tag dont les champs ne peuvent pas fonctionner n'est pas enregistré, et sa page dit ce qui lui manque :

Vous laissez ou saisissez La page du tag dit
Aucune table « Saisissez la table où se trouve la valeur. »
Une table en trois parties, ou un guillemet non fermé « La table est un nom, ou un schéma et un nom (dbo.Orders); mettez un nom qui contient des espaces entre guillemets ou entre crochets. Chaque partie compte au plus 128 caractères. »
Aucune colonne de la valeur « Saisissez la colonne de la valeur. »
Une colonne de la valeur en deux parties « La colonne de la valeur est un seul nom; mettez un nom qui contient des espaces entre guillemets ou entre crochets. »
Par sa clé, sans colonne clé « Saisissez la colonne clé qui choisit la ligne. »
Par sa clé, sans valeur clé « Saisissez la valeur clé : ce que la colonne clé contient dans la ligne à lire. »
La plus récente, sans colonne de date « Saisissez la colonne de date dont la valeur la plus haute est la ligne la plus récente. »

La ligne en lecture seule Adresse source (bus) montre ce que reçoit le pilote : row?table=dbo.ProductionOrders&column=Quantity&key=OrderNo&equals=4711 pour une ligne par sa clé, newest?table=recipe_setpoints&column=oven_temperature&by=updated_at pour la ligne la plus récente.

Requête propre

Champ Sens Par défaut
Texte de la requête « Un SELECT qui ne fait que lire; la valeur est la première colonne de la première ligne. @now est la date et l'heure de la station. » Une requête qui commence par WITH et ne fait que lire est acceptée aussi. vide

La requête se lit comme la base de données la lit : ce qui se trouve dans un texte entre guillemets, un nom entre guillemets ou un commentaire n'est pas un mot de l'instruction. Une requête qui fait plus que lire est refusée là où elle est saisie :

Vous saisissez La page du tag dit
Rien « Saisissez la requête : un SELECT dont la première colonne de la première ligne est la valeur. »
Une instruction qui n'est pas un SELECT, comme UPDATE ou DELETE « La requête commence par SELECT ou WITH. Pour écrire, laissez l'accès du tag écrire et utilisez une commande d'écriture. »
Un SELECT qui modifie la base de données : SELECT ... INTO, FOR UPDATE, ou un SELECT qui contient INSERT, UPDATE, EXEC « La requête modifierait la base de données (INSERT, UPDATE, SELECT INTO, FOR UPDATE, EXEC et autres). Une requête ne fait que lire. »
Deux instructions « La requête contient plus d'une instruction. Gardez un seul SELECT. »
Un guillemet, un crochet ou un commentaire non fermé « Un guillemet, un crochet ou un commentaire de la requête n'est pas fermé. »
Une valeur autre que @now, comme @order « Une requête n'accepte que @now, la date et l'heure de la station. Écrivez toute autre valeur dans le texte. »

L'adresse de bus d'un tag de requête est query?sql= suivi de la requête, encodée en pourcentage.

Lecture

Un tag qui lit Comment il est lu
Par sa clé Sa colonne, dans la ligne dont la colonne clé est égale à la valeur clé; la valeur clé est remise à la base de données comme paramètre.
La ligne la plus récente Sa colonne, dans la ligne dont la colonne de date a la valeur la plus haute de cette colonne (WHERE ... = (SELECT MAX(...) FROM ...)), une forme que toute base de données et ODBC lisent de la même façon; quand deux lignes sont à égalité, la première est lue.
Plusieurs tags d'une même table et d'une même ligne Une requête par passe pour toutes leurs colonnes, pour ne pas interroger la base de données de l'usine une fois par tag. Si la base de données refuse cette requête (une colonne que la table n'a pas), la colonne du tag lui-même est lue seule et cette ligne est ensuite lue colonne par colonne : une colonne erronée ne coûte que son propre tag.
Sa requête propre La requête telle qu'elle est écrite, @now remis comme paramètre.
La base de données répond Le tag
Une valeur d'un type que le tag lit La lit.
Une cellule vide (NULL) Échoue sa lecture.
Aucune ligne qui contient la valeur clé, ou plusieurs Échoue sa lecture : un tag lit une seule ligne.
La ligne la plus récente d'une table qui n'a encore aucune ligne Attend, sans erreur.
Une requête qui ne renvoie aucune ligne Échoue sa lecture.
Une valeur que le type du tag ne lit pas (un texte dans un tag Int32, une partie décimale dans un tag de nombre entier) Échoue sa lecture, avec la raison.

Une lecture en échec garde la dernière lecture du tag, qui compte comme en échec une fois plus ancienne que son intervalle de scrutation plus 10 s, comme sous tout pilote. La base de données est interrogée à chaque lecture : un changement fait par un autre programme se voit à la lecture suivante, jamais à l'instant où il est fait.

Écriture

Un tag n'écrit qu'une fois que son Accès est Lecture et écriture ou Écriture seule. Sa carte Source de la valeur ajoute alors ce que fait une écriture :

Champ Affiché Sens Par défaut
Une écriture le tag écrit Modifie la cellule qu'il lit : « Modifie la cellule que lit ce tag, dans une seule ligne. Une valeur plus récente encore en attente remplace une plus ancienne. » Exécute sa commande d'écriture : « Exécute la commande d'écriture ci-dessous. Chaque écriture compte : aucune encore en attente n'est abandonnée pour une plus récente. » Un tag qui lit sa requête propre n'a pas de cellule à modifier, et ne se voit proposer que Exécute sa commande d'écriture. Modifie la cellule qu'il lit
Commande d'écriture Exécute sa commande d'écriture « Un UPDATE avec son WHERE, un INSERT, ou l'appel d'une procédure stockée. @value est la valeur écrite et @now la date et l'heure de la station; la valeur est toujours un paramètre, jamais collée dans le texte. » La case vide affiche INSERT INTO results (result, recorded_at) VALUES (@value, @now) comme indication. vide

Un tag en Écriture seule qui exécute sa commande d'écriture ne lit rien : sa carte Source de la valeur ne contient que l'écriture.

Une écriture Comment elle se passe
Modifie la cellule qu'il lit Un UPDATE qui met la colonne de la valeur à @value dans la ligne du tag, dans une transaction annulée sauf si exactement une ligne a changé : une valeur clé qu'aucune ligne ne contient, ou que deux lignes contiennent, n'écrit rien et le dit. Une valeur plus récente encore en attente remplace une plus ancienne, comme pour toute consigne.
Exécute sa commande d'écriture La commande s'exécute une fois par écriture, avec la valeur comme @value et la date et l'heure de la station comme @now. Chaque écriture compte : deux INSERT font deux lignes, et une écriture encore en attente n'est jamais abandonnée pour une plus récente. Une procédure stockée s'appelle avec EXEC, CALL ou le {call ...} d'ODBC.
Une valeur avec une partie décimale, dans un tag de nombre entier Arrondie, non refusée : une valeur avec une partie décimale écrite dans un tag de nombre entier (Int32 ou Int64) sans Mise à l'échelle ni Étalonnage est arrondie à l'entier le plus proche avant d'atteindre la base de données, les moitiés loin de zéro (2,5 écrit 3, -2,5 écrit -3). Refuser la partie décimale est la façon de lire une cellule, non d'écrire une valeur.
Réponse Faite, ou refusée avec les mots de la base de données elle-même : un droit qui manque à l'utilisateur, une contrainte que la ligne enfreint, une valeur que la colonne n'accepte pas.

Une commande que le pilote ne peut pas exécuter est refusée sur la page du tag :

Vous saisissez La page du tag dit
Rien « Saisissez la commande d'écriture : un UPDATE, un INSERT ou l'appel d'une procédure stockée contenant @value. »
Une commande qui commence par un autre mot, comme DELETE « La commande d'écriture commence par UPDATE, INSERT, EXEC ou CALL. »
Deux instructions « La commande d'écriture contient plus d'une instruction. Gardez-en une, ou appelez une procédure stockée. »
Un guillemet, un crochet ou un commentaire non fermé « Un guillemet, un crochet ou un commentaire de la commande d'écriture n'est pas fermé. »
Pas de @value « Placez @value là où va la valeur écrite : c'est toujours un paramètre, jamais collé dans le texte. »
Une valeur autre que @value et @now, comme @line « Une commande d'écriture n'accepte que @value, la valeur écrite, et @now, la date et l'heure de la station. »
Un UPDATE sans WHERE « Un UPDATE sans WHERE modifie toutes les lignes de la table. Ajoutez le WHERE qui choisit la ligne. »

Les noms en @@, les fonctions de SQL Server, et les noms d'argument d'un EXEC (@speed = @value) ne sont pas des valeurs et restent tels qu'ils sont écrits. L'enregistrement applique les mêmes règles, et le fil le dit quand il refuse un tag : « Le tag 'Order quantity' ne dit pas où se trouve sa valeur dans la base de données, ou a une requête ou une commande d'écriture que son pilote refuse. Ouvrez-le et corrigez le champ que le panneau du tag signale. »

L'adresse de bus ajoute l'écriture : row?table=recipes&column=setpoint&key=code&equals=R-100&write=cell pour une cellule, none?write=command&command= suivi de la commande pour un tag en Écriture seule qui exécute sa commande.

Découverte

La carte Portée du balayage

Pour Configurer le connector, la page du pilote porte sa carte Portée du balayage, sous la ligne « Se connecte comme le fait l'équipement et propose un tag pour chaque colonne de ses tables, à la ligne la plus récente ou à la ligne de la plus petite clé. »

Champ Sens Par défaut
Équipement à balayer Un équipement du pilote, par son nom. Une base de données ne se balaie qu'à travers un équipement, qui garde sa connexion; une modification de l'équipement qui attend encore d'être enregistrée est enregistrée d'abord. le premier équipement par nom
Tables à balayer « Vide pour toutes les tables, ou un nom ou un motif où * représente n'importe quels caractères, comme Recette*. » vide

Un pilote sans équipement ne contient que « Une base de données se balaie à travers un équipement, qui garde sa connexion. Ajoutez un équipement de ce pilote et dites où se trouve sa base de données. » Ce qui manque encore à la portée est dit en rouge sous la carte, et Découvrir reste grisé tant qu'elle n'est pas complète :

La portée La carte dit
Un équipement qui ne dit pas où se trouve sa base de données, ou qui a un réglage que son pilote ne peut pas utiliser « L'équipement 'Recipes' ne dit pas encore où se trouve sa base de données, ou a un réglage que son pilote ne peut pas utiliser. Complétez d'abord sa carte Base de données. »
Un motif avec un schéma, un guillemet, un crochet ou un point-virgule, comme dbo.Recipe* « 'dbo.Recipe*' n'est ni un nom ni un motif de table. Écrivez un nom, ou un motif où * représente n'importe quels caractères, sans schéma ni guillemets. »
Un équipement qui n'existe plus « L'équipement choisi pour le balayage n'existe plus. Choisissez un autre équipement à balayer. »

Quand l'équipement à balayer a une modification qui ne peut pas être enregistrée, le balayage ne démarre pas : « La découverte n'a pas démarré parce que la modification de l'équipement à balayer n'a pas pu être enregistrée. »

Ce que le balayage propose

Le balayage se connecte comme le fait l'équipement, lit la liste que la base de données elle-même tient de ses tables et de ses vues (celles du système exclues) et de leurs colonnes, et dit quelle table il lit, comme « Lecture des colonnes de recipes… ». Il propose un candidat, l'équipement lui-même, marqué Déjà configuré : sa carte liste, cochées, les colonnes qu'aucun tag de l'équipement ne lit encore, et Ajouter les tags, avant Ouvrir, ajoute celles qui sont cochées à l'équipement, en lecture seule.

La table Ses tags candidats
A une colonne de date et heure Un par colonne, qui lit la ligne la plus récente selon la première colonne de ce type.
N'en a pas Un par colonne sauf sa clé, qui lit la ligne de la plus petite valeur de sa clé primaire (ou de sa première colonne, dans une table qui n'en a pas) : changez la Valeur clé du tag pour lire une autre ligne.
N'en a pas, et n'a aucune ligne Laissée de côté.
Une colonne qu'aucun type de tag ne lit (des données binaires, une géométrie) Laissée de côté, et comptée dans la ligne qui clôt le balayage.

Les tags sont nommés d'après leur table et leur colonne (recipes.oven_temperature), typés d'après le type de la colonne, et chacun est en Lecture seule. Un balayage lit au plus 100 tables et 500 valeurs; un balayage coupé là dit « Le balayage de Recipes s'est arrêté tôt. Un balayage lit au plus 100 tables et 500 valeurs : donnez un nom de table ou un motif pour voir les autres. » Le reste du comportement du balayage se trouve dans Découverte.

La page d'un équipement fait la même chose sans la page de son pilote : Découvrir les tags, dans l'en-tête de sa carte des tags, se connecte comme l'équipement, balaie sa base de données tel qu'il est enregistré et ne propose que les colonnes pour lesquelles il n'a pas encore de tag (voir Découvrir les tags d'un équipement).

Exemple : un ordre de fabrication depuis SQL Server

Le MES garde ses ordres de fabrication dans SQL Server, dans la table dbo.ProductionOrders de la base de données MES, une ligne par numéro d'ordre :

  1. Sur la page du pilote, Ajouter un équipement; nommez-le MES. Sur la carte Base de données gardez SQL Server, saisissez Serveur mes-sql (ou mes-sql\SQLEXPRESS pour une instance nommée), laissez Port vide et saisissez Nom de la base de données MES.
  2. Sur la carte Connexion à la base saisissez Nom d'utilisateur station_reader et son Mot de passe, ou activez Se connecter avec le compte Windows de la station. Pour un serveur d'usine dont le certificat est le sien, choisissez Chiffrée, tout certificat accepté.
  3. Ajouter un tag Order quantity, Int32 : Table de la valeur dbo.ProductionOrders, Colonne de la valeur Quantity, Ligne à lire Par sa clé, Colonne clé OrderNo, Valeur clé 4711. Son adresse de bus est row?table=dbo.ProductionOrders&column=Quantity&key=OrderNo&equals=4711.
  4. Ajouter un tag Product, String, sur la même table et la même ligne, Colonne de la valeur ProductCode : les deux tags sont lus en une seule requête.

Avec les outils :

device_upsert name=MES driver=Database databaseKind=SqlServer host="mes-sql\SQLEXPRESS" databaseName=MES username=station_reader password=<password> databaseEncryption=TrustServerCertificate
tag_upsert device=MES name="Order quantity" opcUaType=Int32 databaseTable=dbo.ProductionOrders address=Quantity databaseRow=Key databaseKeyColumn=OrderNo databaseKeyValue=4711
tag_upsert device=MES name=Product opcUaType=String databaseTable=dbo.ProductionOrders address=ProductCode databaseRow=Key databaseKeyColumn=OrderNo databaseKeyValue=4711

Exemple : une consigne de recette depuis PostgreSQL

Le système de recettes ajoute une ligne à recipe_setpoints chaque fois qu'une consigne change, datée dans sa colonne updated_at :

  1. Ajouter un équipement; nommez-le Recipes, Type de base de données PostgreSQL, Serveur recipes-db, Port vide (le 5432 de PostgreSQL), Nom de la base de données recipes, puis Nom d'utilisateur et Mot de passe sur la carte Connexion à la base.
  2. Ajouter un tag Oven setpoint, Double : Table de la valeur recipe_setpoints, Colonne de la valeur oven_temperature, Ligne à lire La plus récente, Colonne de date updated_at.

Chaque nouvelle ligne est lue à la lecture suivante du tag. PostgreSQL lit un nom simple en minuscules : une colonne créée avec des majuscules, comme OvenTemp, s'écrit donc entre guillemets, "OvenTemp". Avec les outils :

device_upsert name=Recipes driver=Database databaseKind=PostgreSql host=recipes-db databaseName=recipes username=station password=<password>
tag_upsert device=Recipes name="Oven setpoint" opcUaType=Double databaseTable=recipe_setpoints address=oven_temperature databaseRow=Newest databaseDateColumn=updated_at

Exemple : une ligne de résultat écrite par un INSERT

Le système qualité veut une ligne par pièce mesurée dans sa table test_results :

  1. Sur l'équipement de cette base de données, Ajouter un tag Result, Double, Accès Écriture seule.
  2. Une écriture Exécute sa commande d'écriture, et dans Commande d'écriture saisissez INSERT INTO test_results (result, recorded_at) VALUES (@value, @now), qui ajoute la ligne.

Chaque valeur que Logic écrit dans Result devient une ligne à part, avec la date et l'heure de la station à côté; les écritures qui se suivent de près sont toutes gardées, dans l'ordre, aucune abandonnée pour une plus récente. Un tag en Lecture et écriture qui lit une cellule modifierait au contraire son unique ligne à chaque écriture. Avec les outils :

tag_upsert device=Quality name=Result opcUaType=Double accessType=WriteOnly databaseWriteMode=Command databaseCommand="INSERT INTO test_results (result, recorded_at) VALUES (@value, @now)"

Exemple : Access et Oracle par ODBC

Base de données Sur cet ordinateur Sur l'équipement
Microsoft Access L'Access Database Engine de Microsoft, en 64 bits Type de base de données Autre (ODBC), Source de données ou texte de connexion Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=C:\Data\plant.accdb, sans utilisateur
Oracle Le pilote ODBC 64 bits d'Oracle, et une source de données ERP créée pour lui dans les Sources de données ODBC (64 bits) Type de base de données Autre (ODBC), Source de données ou texte de connexion ERP, Nom d'utilisateur et Mot de passe sur la carte Connexion à la base

Quand la source de données ou le pilote qu'un équipement nomme n'existe que pour les programmes 32 bits (un Access d'un Office 32 bits, une source de données créée dans Sources de données ODBC (32 bits)), ou n'existe pas du tout sur cet ordinateur, le panneau de l'équipement dit lequel des deux cas c'est, avec le nom que l'équipement a donné, et donne l'instruction complète tant que l'équipement est activé et ne se connecte pas. L'erreur de l'équipement dit la même chose en anglais, et driver_capabilities aussi, dans le prerequisite du pilote Database (perDevice true) :

Partie Ce qu'elle dit
Ce qui manque Un pilote ODBC 64 bits pour cette source de données ou ce pilote : Ganter Lab est un programme 64 bits et ne voit que les pilotes ODBC 64 bits et les sources de données créées avec eux, et il ne peut pas inclure le pilote d'un autre éditeur
Où l'obtenir Auprès de l'éditeur de la base de données; pour Access, la page de Microsoft « Download and install Microsoft 365 Access Runtime », dont le runtime apporte l'Access Database Engine
Laquelle choisir La version 64 bits (pour Access, le bouton de téléchargement 64 bits de votre langue), jamais la version 32 bits
Comment l'installer En tant qu'administrateur; ensuite, pour un équipement qui nomme une source de données, la créer dans Sources de données ODBC (64 bits) avec le même nom et la même base de données
Écueil connu Pour Access sur un ordinateur qui a Office : la page de Microsoft dit que l'Access Runtime installé correspond à l'Office déjà installé et n'est pas compatible avec un Office installé par Windows Installer, et la page de Microsoft sur le choix entre la version 64 bits et la version 32 bits d'Office dit qu'une version est désinstallée avant que l'autre soit installée
Ensuite À sa prochaine tentative de connexion, l'équipement se connecte avec la configuration qu'il a, sans redémarrer Ganter Lab

L'avis se termine par les pilotes ODBC 64 bits de cet ordinateur, sous le nom que prend Driver={...}. Une source de données ou un pilote que le côté 64 bits a, et qui échoue quand même, montre l'erreur propre du gestionnaire de pilotes.

Par ODBC, un nom simple se lit comme la base de données le lit (en majuscules sous Oracle) et un nom entre guillemets exactement; les dates et les heures sont envoyées à la seconde entière, la précision la plus fine que tout pilote ODBC accepte. Avec les outils :

device_upsert name="Plant book" driver=Database databaseKind=Odbc databaseOdbc="Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=C:\Data\plant.accdb"
device_upsert name=ERP driver=Database databaseKind=Odbc databaseOdbc=ERP username=STATION password=<password>

Outils de l'agent

driver_capabilities décrit ce pilote sous database : le chemin simple, chaque base de données avec ses champs et son port propre, les choix de chiffrement, les deux façons dont un tag lit et les deux dont il écrit, la règle selon laquelle une valeur n'entre dans une instruction que comme @value ou @now, les types, les délais, le conseil sur l'utilisateur de la base de données, la découverte et quatre exemples complets. device_upsert driver=Database accepte databaseKind (SqlServer, la valeur par défaut, PostgreSql, MySql, Sqlite ou Odbc), et pour un serveur host (un server\INSTANCE ou server,port de SQL Server est réparti), port, databaseName, et sur SQL Server databaseInstance, databaseWindowsSignIn et databaseEncryption (Verified, TrustServerCertificate ou Off); databaseFile pour SQLite, databaseOdbc pour ODBC; username et password, qui n'est jamais rendu. Un équipement qu'il renvoie porte database, avec l'adresse et le fait que l'équipement attend encore ou non son utilisateur. tag_upsert accepte la colonne de la valeur comme address, databaseSource (Fields ou Query), databaseTable, databaseRow (Key ou Newest), databaseKeyColumn, databaseKeyValue, databaseDateColumn, databaseQuery, et une fois que l'accessType écrit, databaseWriteMode (Cell ou Command) et databaseCommand; un nouveau tag est en lecture seule et en Double sauf si opcUaType dit autre chose. device_discover driver=Database accepte databaseDevice, le nom d'un équipement configuré du pilote, et facultativement databaseTables, un nom de table ou un motif avec *; les tags qui manquent à l'équipement s'ajoutent avec tag_upsert. connector_browse renvoie le databaseKind de chaque équipement. Les autres outils se trouvent dans Outils de l'agent.

Limites à connaître

  • Le pilote lit et écrit les valeurs de ses tags, une valeur par tag. Il n'enregistre pas les essais de la station dans une base de données : une ligne par essai avec son numéro de série, son verdict et ses mesures n'est pas quelque chose que ce pilote écrit.
  • Aucun pilote ODBC n'est livré avec le produit. Oracle, Access, Firebird et toute base de données autre que les quatre atteintes directement ont besoin de leur propre pilote ODBC 64 bits installé sur l'ordinateur; un pilote 32 bits n'est pas vu.
  • L'équipement ne garde aucun mot de passe Windows : la connexion Windows à SQL Server, et un fichier SQLite sur un partage réseau, utilisent le compte sous lequel roule la station, et la base de données ou le partage doit donc laisser entrer ce compte.
  • Une requête ne fait que lire. Ce qui modifie la base de données est une écriture, et une écriture n'a lieu que sur un tag dont l'accès écrit.
  • Une valeur n'entre jamais dans le texte d'une instruction : la valeur écrite est toujours le paramètre @value, la date et l'heure de la station @now, et une valeur clé est aussi un paramètre. Une instruction qui nomme toute autre valeur est refusée.
  • Une écriture de cellule modifie exactement une ligne; une commande UPDATE a besoin de son WHERE.
  • La base de données est interrogée à chaque lecture : un changement fait par un autre programme se voit à la lecture suivante, et une base de données qui a beaucoup de tags d'une même ligne est interrogée une fois par passe pour tous.
  • Une colonne binaire n'est pas lue.