Files
mcp-wms-wiki/wiki/sources/archives/Documentation Module AGV.md
T
2026-05-20 09:41:27 +02:00

22 KiB

share_link, share_updated
share_link share_updated
https://share.note.sx/9sdwptyo#9+nZ1MSgcNReaNUIVOirxsvuDA6oWAyk4vuGxqP9C3g 2026-05-07T17:24:53+02:00

Résumé

Le WMS génère des mouvements et s'ils passent par des routes AGV (config easyS), les workflows du module AGV convertissent le mouvement en ordre de déplacement AGV. La gateway récupère cet ordre et met à jour une base de données postgres. Cette base de donnée postgres est lue par un middleware ou directement par le logiciel de flotte AGV (souvent non Mecalux). Ce dernier peut ensuite écrire à son tour en réponse dans la base de donnée et la gateway récupère les infos et tient au courant le WMS du statut de son ordre de mouvement AGV.

Vue d'ensemble de l'architecture

Le module AGV repose sur deux bases de données qui communiquent via un DBLink :

┌─────────────────┐ DBLink (ODBC/dg4odbc) ┌──────────────────┐ │ Oracle (WMS) │ ◄─────────────────────────────► │ PostgreSQL (AGV)│ │ Read Model DB │ synonyms → tables AGV │ Tables de comm.│ │ (db_read) │ │ agv_inputqueue │ └─────────────────┘ │ agv_outputqueue│ ▲ │ agv_age/ags/eag │ │ └──────────────────┘ │ ▲ Easy WMS │ (IIS App) Gateway AGV (Service Windows)

Le Gateway AGV est un service Windows qui fait le pont entre les tables PostgreSQL et le système AGV externe (MAP / Still iGo / etc.). Easy WMS lit et écrit dans les tables AGV via des synonyms Oracle pointant vers PostgreSQL à travers un DBLink ODBC utilisant le composant Oracle dg4odbc (Database Gateway for ODBC).


Prérequis

Élément Exigence
Easy WMS binaries Version minimum 18.10.22154.1
PostgreSQL Version >= 14 (attention au port si >= 18, voir section pièges)
Driver ODBC PostgreSQL psqlodbc x64
Oracle Connaître le chemin exact du ORACLE_HOME sur la VM
Droits Oracle L'utilisateur db_read doit pouvoir créer des database links
Firewall Port PostgreSQL ouvert (5432 par défaut, 5433 si PostgreSQL 18)

Pour connaître votre version Oracle et le chemin ORACLE_HOME :

dir C:\Mecalux\Motor\oracle\Product\

Dans la suite de ce guide, [ORACLE_HOME] désigne le chemin complet, par exemple C:\Mecalux\Motor\oracle\Product\19.27.0.0\dbhome_1. Remplacez systématiquement [ORACLE_HOME] par votre chemin réel — ne jamais laisser le placeholder, c'est une cause fréquente d'échec.


Étape 1 — Installer PostgreSQL

  1. Télécharger PostgreSQL >= 14 depuis https://www.enterprisedb.com/downloads/postgres-postgresql-downloads

  2. Installer avec les options par défaut

  3. Noter le port d'écoute — c'est critique pour la suite :

    • PostgreSQL <= 17 : port par défaut 5432

    • PostgreSQL 18+ : port par défaut 5433 (changement introduit en version 18)

Créer l'utilisateur et la base AGV

Dans PgAdmin4 :

  1. Clic droit sur Login/Group Roles > Create > Login/Group Role

    • Onglet General : Name = mecaluxAGV

    • Onglet Definition : Password = mecaluxAGV (ou selon votre convention)

    • Onglet Privileges : Can login = Yes

  2. Clic droit sur Databases > Create > Database

    • Database = AGV

    • Owner = mecaluxAGV

Autoriser les connexions externes

Éditer le fichier C:\Program Files\PostgreSQL[version]\data\pg_hba.conf et ajouter :

# Autoriser toutes les connexions IPv4 (environnement de dev uniquement) host all all 0.0.0.0/0 md5 # Alternative : filtrer par plage IP host all all 192.168.0.0/16 md5

Ouvrir le port dans le firewall Windows

# Adapter le port selon votre version de PostgreSQL netsh advfirewall firewall add rule name="PostgreSQL AGV" dir=in action=allow protocol=tcp localport=5432


Étape 2 — Installer le driver ODBC PostgreSQL

Attention : le lien de téléchargement dans la doc MSS officielle est mort.

Aller sur https://www.postgresql.org/ftp/odbc/releases/ — choisir la release la plus récente, puis télécharger psqlodbc_x64.msi (pas le wrapper setup.exe).

Installer le MSI.


Étape 3 — Configurer le System DSN (ODBC 64 bits)

  1. Ouvrir ODBC Data Sources (64-bit) (chercher odbcad32 dans le menu démarrer, ou lancer depuis C:\Windows\System32\odbcad32.exe)

  2. Aller sur l'onglet System DSN — pas User DSN !

  3. Cliquer Add

  4. Sélectionner le driver PostgreSQL Unicode(x64)

  5. Remplir :

Champ Valeur
Data Source PostgreSQL35W
Database AGV
Server localhost (ou IP du serveur PostgreSQL)
Port 5432 (ou 5433 si PostgreSQL 18+)
User Name mecaluxAGV
Password mecaluxAGV
  1. Aller dans l'onglet Datasource et décocher "Bools as Char"

  2. Cliquer Test pour vérifier la connexion

IMPORTANT — Casse du nom DSN : le nom PostgreSQL35W (avec le P et le W en majuscules) est utilisé tel quel dans 5 fichiers de configuration Oracle différents. Il faut être absolument cohérent sur la casse dans tous ces fichiers. POSTGRESQL35W (tout en majuscules) ou postgresql35w (tout en minuscules) provoqueront un échec silencieux de dg4odbc. Voir la section "Pièges connus" en fin de document pour le détail.


Étape 4 — Installer et démarrer le Gateway AGV

4.1 — Vérifier le fichier de configuration

Le fichier de config se trouve dans C:\ProgramData\Mecalux\EasyWMS GatewayAGV 2015\ (ou dans le dossier d'installation du service).

Point critique : le fichier XML ne doit contenir qu'une seule section . Si le fichier en contient deux (par exemple pour deux stations), le provider ne s'initialisera pas et le service crashera avec l'erreur Migration DataBase Provider No Initialized.

Vérifier que la connection string pointe vers la bonne base PostgreSQL avec les bons credentials :

<?xml version="1.0"?> <configuration> <configSections> <section name ="AGVConfig" type ="Mecalux.ITSW.AGVGateway.Config.ConfigSettings, Mecalux.ITSW.AGVGateway.Config" /> </configSections> <AGVConfig connectionString="Host=localhost;user id=mecaluxAGV;password=mecaluxAGV;database=AGV;MaxPoolSize=1000" inputCycleDelay ="1000" outputCycleDelay ="1000" timeoutCommand ="6000" providerName="Npgsql" stationType ="65" stationNumber ="1" warehouseNumber ="20000" commitLimit = "100" hoursToExecute = "24" daysToSave = "5"> </AGVConfig> </configuration>

Si PostgreSQL 18+ (port 5433), ajouter explicitement le port dans la connection string : connectionString="Host=localhost;Port=5433;user id=mecaluxAGV;password=mecaluxAGV;database=AGV;MaxPoolSize=1000"

4.2 — Premier démarrage (création des tables)

  1. Démarrer le service Gateway AGV (services.msc > EasyWMS GatewayAGV)

  2. Vérifier le log : C:\ProgramData\Mecalux\EasyWMS GatewayAGV 2015\Logs\AllLog.log

  3. Chercher les lignes de migration réussie :

[Info] [Migration] [Apply] End applying migration: Migration0 [Info] [Migration] [Apply] End applying migration: AgvMigration3

Si ces lignes apparaissent, les tables ont été créées avec succès. Les erreurs éventuelles après ces lignes sont normales (le Gateway essaie de communiquer avec le système AGV qui n'est pas encore connecté).

En cas d'erreur Migration DataBase Provider No Initialized : vérifier la connection string (user/password/port/nom de base) et s'assurer qu'il n'y a qu'une seule section dans le fichier XML.

  1. Stopper le service Gateway AGV

4.3 — Vérifier les tables créées

Dans PgAdmin4, sous la base AGV > Schemas > public > Tables, on doit voir 7 tables : agv_age, agv_ags, agv_eag, agv_inputqueue, agv_maintenance, agv_outputqueue, std_migrationinfo

Et 6 séquences : agv_age_id_seq, agv_ags_id_seq, agv_eag_id_seq, agv_inputqueue_id_seq, agv_maintenance_id_seq, agv_outputqueue_id_seq

4.4 — Exécuter les scripts PostgreSQL

Ouvrir le Query Tool dans PgAdmin4 sur la base AGV et exécuter les deux scripts suivants :

Script 1 — Fonction de notification (publie un événement à chaque modification de ligne) :

CREATE FUNCTION public."NotifyOnDataChange"() RETURNS trigger LANGUAGE 'plpgsql' AS $BODY$ DECLARE data JSON; notification JSON; BEGIN IF (TG_OP = 'DELETE') THEN data = row_to_json(OLD); ELSE data = row_to_json(NEW); END IF; notification = json_build_object( 'table', TG_TABLE_NAME, 'action', TG_OP, 'data', data); PERFORM pg_notify('datachange', notification::TEXT); RETURN NEW; END $BODY$;

Script 2 — Trigger sur la table inputqueue :

CREATE TRIGGER "OnDataChange" AFTER INSERT ON public.agv_inputqueue FOR EACH ROW EXECUTE PROCEDURE public."NotifyOnDataChange"();


Étape 5 — Configurer l'utilisateur externe PostgreSQL

Cet utilisateur sera utilisé par le DBLink Oracle pour accéder aux tables AGV depuis le WMS.

5.1 — Créer l'utilisateur

Dans PgAdmin4 : Login/Group Roles > Create > Login/Group Role

  • Name : externalAGV (ou autre nom de votre choix)

  • Password : définir un mot de passe

  • Can login : Yes

5.2 — Donner le droit CONNECT sur la base

Propriétés de la base AGV > onglet Security > ajouter externalAGV avec le privilège CONNECT.

5.3 — Donner les droits sur les tables et séquences

Option rapide (environnement de dev) — via le Query Tool sur la base AGV :

GRANT ALL ON ALL TABLES IN SCHEMA public TO "externalAGV"; GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO "externalAGV";

Option restrictive (production) — droits minimaux :

-- Tables GRANT SELECT, INSERT, UPDATE ON agv_inputqueue TO "externalAGV"; GRANT SELECT, INSERT, UPDATE ON agv_ags TO "externalAGV"; GRANT SELECT, INSERT, UPDATE ON agv_age TO "externalAGV"; GRANT SELECT, UPDATE ON agv_outputqueue TO "externalAGV"; GRANT SELECT ON agv_eag TO "externalAGV"; -- Séquences GRANT ALL ON agv_age_id_seq TO "externalAGV"; GRANT ALL ON agv_ags_id_seq TO "externalAGV"; GRANT ALL ON agv_inputqueue_id_seq TO "externalAGV";


C'est l'étape la plus délicate de toute l'installation. Oracle utilise le composant dg4odbc (Database Gateway for ODBC) pour se connecter à PostgreSQL via le DSN ODBC créé à l'étape 3. La configuration touche 3 fichiers Oracle et nécessite un redémarrage du Listener.

6.1 — Éditer tnsnames.ora

Fichier : [ORACLE_HOME]\network\admin\tnsnames.ora

Ajouter l'entrée suivante à la fin du fichier. L'identifiant PostgreSQL35W doit commencer en colonne 1 (pas d'espace en début de ligne), sinon Oracle ne le reconnaît pas comme une entrée TNS valide :

PostgreSQL35W = (DESCRIPTION= (ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521)) (CONNECT_DATA=(SID=PostgreSQL35W)) (HS=OK) )

Laisser une ligne vide entre l'entrée précédente et celle-ci.

(HS=OK) est obligatoire — il indique à Oracle qu'il s'agit d'un Heterogeneous Service (connexion vers un système non-Oracle).

Erreur fréquente : si l'identifiant est indenté (espace ou tabulation avant PostgreSQL35W =), Oracle retournera ORA-12154: TNS:could not resolve the connect identifier specified. C'est un piège subtil car le reste du fichier fonctionne avec des indentations.

Exemple de fichier tnsnames.ora complet :

# tnsnames.ora Network Configuration File # Generated by Oracle configuration tools. LISTENER_ORCL = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) ORACLR_CONNECTION_DATA = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521)) ) (CONNECT_DATA = (SID = CLRExtProc) (PRESENTATION = RO) ) ) ORCL = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = ORCL) ) ) PostgreSQL35W = (DESCRIPTION= (ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521)) (CONNECT_DATA=(SID=PostgreSQL35W)) (HS=OK) )

6.2 — Éditer listener.ora

Fichier : [ORACLE_HOME]\network\admin\listener.ora

Ajouter un bloc SID_DESC dans la section SID_LIST_LISTENER existante :

`(SID_DESC =       (SID_NAME = PostgreSQL35W)       (ORACLE_HOME = C:\Mecalux\Motor\oracle\Product\19.27.0.0\dbhome_1)       (PROGRAM = dg4odbc)     )`

ERREUR CRITIQUE FRÉQUENTE : le chemin ORACLE_HOME dans ce bloc doit être le chemin réel et complet de votre installation Oracle. Ne jamais laisser un placeholder comme [VERSION] — cela provoque l'erreur TNS-12518: TNS:listener could not hand off client connection et ORA-28545 côté client. C'est invisible au premier regard car le listener démarre sans erreur et le SID apparaît dans lsnrctl status, mais dg4odbc ne peut pas se lancer.

Vérification : après édition, le ORACLE_HOME du bloc PostgreSQL35W doit être identique à celui des autres blocs SID_DESC du même fichier.

Exemple de listener.ora complet :

# listener.ora Network Configuration File # Generated by Oracle configuration tools. SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (SID_NAME = ORCL) (ORACLE_HOME = C:\Mecalux\Motor\oracle\Product\19.27.0.0\dbhome_1) ) (SID_DESC = (SID_NAME = CLRExtProc) (ORACLE_HOME = C:\Mecalux\Motor\oracle\Product\19.27.0.0\dbhome_1) (PROGRAM = extproc) (ENVS = "EXTPROC_DLLS=ONLY:C:\Mecalux\Motor\oracle\Product\19.27.0.0\dbhome_1\bin\oraclr19.dll") ) (SID_DESC = (SID_NAME = PostgreSQL35W) (ORACLE_HOME = C:\Mecalux\Motor\oracle\Product\19.27.0.0\dbhome_1) (PROGRAM = dg4odbc) ) )

6.3 — Créer le fichier initPostgreSQL35W.ora

Aller dans : [ORACLE_HOME]\hs\admin\

  1. Dupliquer le fichier initdg4odbc.ora

  2. Renommer la copie en initPostgreSQL35W.ora (le nom doit correspondre exactement au SID_NAME — respect de la casse)

  3. Remplacer tout le contenu par :

HS_FDS_CONNECT_INFO = PostgreSQL35W HS_FDS_TRACE_LEVEL = 0

Ne pas laisser les lignes template du fichier original (, <trace_level>), les supprimer ou les commenter.

Pour le debug : passer temporairement HS_FDS_TRACE_LEVEL à 4 pour obtenir des traces détaillées de dg4odbc. Ne pas oublier de remettre à 0 une fois le problème résolu.

6.4 — Redémarrer le Listener Oracle

lsnrctl stop lsnrctl start

Vérifier que le SID PostgreSQL35W apparaît dans la liste des services :

lsnrctl status

On doit voir :

Service "PostgreSQL35W" has 1 instance(s). Instance "PostgreSQL35W", status UNKNOWN, has 1 handler(s) for this service...

Le status UNKNOWN est normal pour un Heterogeneous Service — c'est un processus lancé à la demande.

Se connecter en sysdba :

sqlplus sys/[password] as sysdba

GRANT CREATE DATABASE LINK TO db_read;

L'utilisateur cible est db_read (le schéma read model d'Easy WMS). C'est lui qui portera le database link et les synonyms. Ne pas créer le link sous SYS — il ne sera pas visible depuis db_read.

Se connecter en tant que db_read (pas en sysdba) :

sqlplus db_read/[password]

ou depuis une session sysdba :

CONNECT db_read/[password]

Puis créer le link :

CREATE DATABASE LINK AGV CONNECT TO "externalAGV" IDENTIFIED BY "mecalux" USING 'PostgreSQL35W';

Les guillemets doubles autour du user et du password sont obligatoires. Oracle convertit les identifiants en majuscules par défaut, mais PostgreSQL est case-sensitive. Sans guillemets, Oracle enverra EXTERNALAGV au lieu de externalAGV et l'authentification échouera.

SELECT * FROM "agv_inputqueue"@AGV;

Si la requête retourne no rows selected, le lien fonctionne. Les tables sont simplement vides à ce stade.

En cas d'erreur ORA-12154 : problème dans tnsnames.ora (casse, indentation, syntaxe). Voir section Pièges.

En cas d'erreur ORA-28545 / NCR message 65535 : dg4odbc ne se lance pas. Vérifier listener.ora (ORACLE_HOME correct ?) et que le listener est démarré. Activer le trace level à 4 dans initPostgreSQL35W.ora pour diagnostiquer.

6.8 — Créer les synonyms

Toujours connecté en db_read :

CREATE SYNONYM agv_age FOR "agv_age"@AGV; CREATE SYNONYM agv_ags FOR "agv_ags"@AGV; CREATE SYNONYM agv_eag FOR "agv_eag"@AGV; CREATE SYNONYM agv_inputqueue FOR "agv_inputqueue"@AGV; CREATE SYNONYM agv_outputqueue FOR "agv_outputqueue"@AGV;

Les noms de tables entre guillemets doubles sont en minuscules car PostgreSQL stocke les identifiants en minuscules par défaut.

6.9 — Vérifier les synonyms

SELECT * FROM agv_inputqueue; SELECT * FROM agv_outputqueue; SELECT * FROM agv_age; SELECT * FROM agv_ags; SELECT * FROM agv_eag;

Toutes les requêtes doivent passer sans erreur (no rows selected est le résultat attendu).


Étape 7 — Installer le module AGV dans Easy WMS

7.1 — Modifier le response.xml

Ajouter les lignes suivantes dans le fichier response.xml du déploiement :

<ExtraApps> [...] <Item Use="Yes" Name="AGV" Url="http://[host]/packages/Mecalux.ITSW.AGV.Application.zip" PackageUrl="http://[host]/packages/AGV.zip" /> [...] </ExtraApps> <Modules> [...] <Module Name="AGV" LicenseLevel="ENABLED" /> [...] </Modules>

Adapter les URLs selon votre serveur de packages.

7.2 — Lancer le deploy

Exécuter le deploy en choisissant l'option 16 — Install application.

7.3 — Redémarrer le Gateway AGV

Une fois le deploy terminé, redémarrer le service Gateway AGV dans services.msc.


Pièges connus et troubleshooting

1. Casse du nom ODBC : PostgreSQL35W vs POSTGRESQL35W

C'est la cause d'échec la plus fréquente. Oracle est case-insensitive par défaut pour les identifiants SQL, mais le DSN ODBC et les fichiers de configuration dg4odbc (HS) sont case-sensitive. Le nom doit être identique dans tous ces emplacements :

Fichier / Emplacement Valeur attendue
ODBC System DSN (nom du data source) PostgreSQL35W
tnsnames.ora (nom de l'entrée TNS + SID) PostgreSQL35W
listener.ora (SID_NAME) PostgreSQL35W
initPostgreSQL35W.ora (nom du fichier) initPostgreSQL35W.ora
initPostgreSQL35W.ora (contenu) HS_FDS_CONNECT_INFO = PostgreSQL35W
CREATE DATABASE LINK ... USING '...' 'PostgreSQL35W'

2. Indentation dans tnsnames.ora

L'identifiant de l'entrée TNS (ex: PostgreSQL35W =) doit commencer en colonne 1, sans espace ni tabulation en début de ligne. Une indentation accidentelle provoque ORA-12154: TNS:could not resolve the connect identifier specified.

3. Placeholder [VERSION] dans listener.ora

Le ORACLE_HOME dans le SID_DESC de PostgreSQL35W doit être le chemin réel de l'installation Oracle. Laisser un placeholder comme [VERSION] provoque TNS-12518 / ORA-28545. Le listener démarre sans erreur et le SID apparaît dans lsnrctl status, ce qui rend le problème difficile à diagnostiquer.

Commande de vérification :

dir C:\Mecalux\Motor\oracle\Product\

4. Port PostgreSQL 18+

PostgreSQL 18 utilise le port 5433 par défaut au lieu de 5432. Il faut mettre à jour deux endroits :

  • Le DSN ODBC (étape 3)

  • La connection string dans le fichier de config du Gateway AGV (étape 4)

5. Double section dans le fichier de config du Gateway

Le fichier XML du Gateway ne doit contenir qu'une seule section . Si le fichier en contient deux (même avec des stationNumber différents), le parser .NET ne sait pas laquelle utiliser et le service crashe avec : System.ArgumentNullException: Migration DataBase Provider No Initialized.

6. Guillemets doubles dans les commandes Oracle

Oracle convertit tous les identifiants en majuscules par défaut. PostgreSQL les stocke en minuscules. Lors de la création du database link et des synonyms :

  • Les noms de tables PostgreSQL doivent être entre guillemets doubles : "agv_inputqueue"

  • Les credentials PostgreSQL doivent aussi être entre guillemets doubles : "externalAGV", "mecalux"

Sans guillemets, Oracle enverra EXTERNALAGV et PostgreSQL refusera l'authentification.

Le database link et les synonyms doivent être créés en étant connecté en tant que db_read, pas en tant que SYS ou un autre schéma. Un link créé sous SYS ne sera pas visible depuis db_read, et les vues de monitoring AGV du WMS utilisent le schéma read model.

8. Diagnostic avec le trace dg4odbc

En cas de problème sur le DBLink (ORA-28545, ORA-12154, etc.), activer le trace dans [ORACLE_HOME]\hs\admin\initPostgreSQL35W.ora :

HS_FDS_TRACE_LEVEL = 4

Redémarrer le listener, retenter la requête, puis chercher le fichier de trace dans [ORACLE_HOME]\hs\admin\ ou le répertoire de diagnostic Oracle. Remettre à 0 après diagnostic.

Si le fichier de trace n'est pas créé, c'est que dg4odbc ne se lance pas du tout — le problème est dans listener.ora (ORACLE_HOME incorrect ou listener non redémarré).

9. Test de connectivité ODBC indépendant d'Oracle

Pour isoler un problème de connexion ODBC (sans passer par Oracle/dg4odbc) :

$conn = New-Object System.Data.Odbc.OdbcConnection $conn.ConnectionString = "DSN=PostgreSQL35W;Uid=externalAGV;Pwd=mecalux;" $conn.Open() $conn.State # Doit afficher "Open" $conn.Close()

Si ce test passe mais que le DBLink Oracle échoue, le problème est dans la configuration dg4odbc (fichiers Oracle), pas dans la connexion ODBC elle-même.