Files
mcp-wms-wiki/wiki/operations/agv-installation.md
T
arthur 9ce6ae37be lint(standard): corrections completes mode standard
- Em dashes: 1712 remplaces par tirets simples (86 fichiers + _index.md,
  en-tete section Limagrain conserve)
- Checklists: 24 '- [ ]' -> '- ☐' (3 pages operations, plus de todos Obsidian)
- Ancres: 33 reparees (slugs GitHub + ancres HTML <a id> reconnues),
  1 reciblee (manuel de reten)
- related: tenseflow -> tense-flow, pie -> mechanical-elements,
  group.md retire (doublon shipping)
- Registre: compteur global 122 -> 131 pages
- Rapport racine _lint_report.md mis a jour (scan v2 + re-scan final: 0 anomalie)
- Aucun fichier limagrain/ modifie (cloisonnement)
2026-07-20 13:01:21 +02:00

418 lines
16 KiB
Markdown

---
title: "AGV Module - Installation Guide"
type: operation
sources:
- sources/archives/Documentation Module AGV.md
- sources/archives/Présentation Module AGV.md
related:
- modules/agv.md
- concepts/stations.md
last_compiled: "2026-05-15"
---
# AGV Module - Installation Guide
## Overview
This guide covers the end-to-end installation of the AGV module for Easy WMS. The module relies on a PostgreSQL intermediary database, an ODBC driver, an Oracle DBLink (dg4odbc), the Gateway AGV Windows service, and the AGV application package deployed into Easy WMS. For the functional description of the module, see [AGV - Automated Guided Vehicles](../modules/agv.md).
## Prerequisites
| Element | Requirement |
|---------|-------------|
| Easy WMS binaries | Version **18.10.22154.1** minimum |
| PostgreSQL | Version >= 14 (note: PostgreSQL 18+ defaults to port 5433) |
| PostgreSQL ODBC driver | **psqlodbc x64** |
| Oracle | Know the exact `ORACLE_HOME` path on the VM |
| Oracle permissions | The `db_read` user must be able to create database links |
| Firewall | PostgreSQL port open (5432 default, 5433 if PostgreSQL 18+) |
To find the Oracle version and `ORACLE_HOME` path:
```
dir C:\Mecalux\Motor\oracle\Product\
```
> Throughout this guide, `[ORACLE_HOME]` refers to the full path, e.g. `C:\Mecalux\Motor\oracle\Product\19.27.0.0\dbhome_1`. **Always replace** `[ORACLE_HOME]` **with your actual path** - leaving the placeholder is a frequent cause of failure.
## Step 1 - Install PostgreSQL
Download PostgreSQL >= 14 from the official EDB site and install with default options. Note the listening port - this is critical: PostgreSQL <= 17 uses port **5432**, while **PostgreSQL 18+ defaults to port 5433**.
### Create the AGV user and database
In PgAdmin4, create a login role `mecaluxAGV` (password: `mecaluxAGV` or per your convention, with login privilege), then create a database named `AGV` owned by `mecaluxAGV`.
### Allow external connections
Edit `C:\Program Files\PostgreSQL\[version]\data\pg_hba.conf` and add:
```
# Allow all IPv4 connections (dev environment only)
host all all 0.0.0.0/0 md5
# Alternative: filter by IP range
host all all 192.168.0.0/16 md5
```
### Open the firewall port
```powershell
netsh advfirewall firewall add rule name="PostgreSQL AGV" dir=in action=allow protocol=tcp localport=5432
```
Adjust the port number if using PostgreSQL 18+ (5433).
## Step 2 - Install the PostgreSQL ODBC driver
> The download link in the official MSS documentation is dead. Go to the PostgreSQL ODBC releases page and download the latest `psqlodbc_x64.msi` (not the wrapper setup.exe).
Install the MSI with default options.
## Step 3 - Configure the System DSN (64-bit ODBC)
Open **ODBC Data Sources (64-bit)** (`C:\Windows\System32\odbcad32.exe`), go to the **System DSN** tab (not User DSN), click **Add**, and select the **PostgreSQL Unicode(x64)** driver.
| Field | Value |
|-------|-------|
| Data Source | `PostgreSQL35W` |
| Database | `AGV` |
| Server | `localhost` (or PostgreSQL server IP) |
| Port | `5432` (or `5433` if PostgreSQL 18+) |
| User Name | `mecaluxAGV` |
| Password | `mecaluxAGV` |
In the **Datasource** tab, **uncheck "Bools as Char"**. Click **Test** to verify the connection.
> **Critical - DSN name case**: the name `PostgreSQL35W` (capital P and W) is used verbatim in **5 different Oracle configuration files**. The case must be **absolutely consistent** across all files. Using `POSTGRESQL35W` (all caps) or `postgresql35w` (all lowercase) will cause a silent dg4odbc failure. See the Troubleshooting section for details.
## Step 4 - Install and start the Gateway AGV
### 4.1 - Verify the configuration file
The config file is located at `C:\ProgramData\Mecalux\EasyWMS GatewayAGV 2015\`. The XML file must contain exactly **one** `<AGVConfig>` section. If it contains two (e.g., for two stations), the provider will not initialize and the service will crash with `Migration DataBase Provider No Initialized`.
Verify that the connection string points to the correct PostgreSQL database:
```xml
<?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>
```
> If using **PostgreSQL 18+** (port 5433), add the port explicitly: `Host=localhost;Port=5433;user id=mecaluxAGV;...`
### 4.2 - First startup (table creation)
Start the Gateway AGV service (`services.msc` > EasyWMS GatewayAGV). Check the log at `C:\ProgramData\Mecalux\EasyWMS GatewayAGV 2015\Logs\AllLog.log` for successful migration lines:
```
[Info] [Migration] [Apply] End applying migration: Migration0
[Info] [Migration] [Apply] End applying migration: AgvMigration3
```
If these lines appear, the tables were created successfully. Errors after these lines are normal (the Gateway tries to communicate with the fleet manager which is not yet connected). **Stop the service** after verification.
### 4.3 - Verify created tables
In PgAdmin4, under the AGV database > Schemas > public > Tables, there should be 7 tables: `agv_age`, `agv_ags`, `agv_eag`, `agv_inputqueue`, `agv_maintenance`, `agv_outputqueue`, `std_migrationinfo`. And 6 sequences: `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 - Execute PostgreSQL scripts
Open the Query Tool in PgAdmin4 on the AGV database and execute:
**Script 1 - Notification function** (publishes an event on every row change):
```sql
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 on the inputqueue table**:
```sql
CREATE TRIGGER "OnDataChange"
AFTER INSERT ON public.agv_inputqueue
FOR EACH ROW
EXECUTE PROCEDURE public."NotifyOnDataChange"();
```
## Step 5 - Configure the external PostgreSQL user
This user will be used by the Oracle DBLink to access the AGV tables from the WMS.
### 5.1 - Create the user
In PgAdmin4: create a login role `externalAGV` with a password and login privilege.
### 5.2 - Grant CONNECT on the database
In the AGV database properties > Security tab, add `externalAGV` with the **CONNECT** privilege.
### 5.3 - Grant permissions on tables and sequences
**Quick option (dev environment)**:
```sql
GRANT ALL ON ALL TABLES IN SCHEMA public TO "externalAGV";
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO "externalAGV";
```
**Restrictive option (production)** - minimum required permissions:
```sql
-- 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";
-- Sequences
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";
```
## Step 6 - Configure the Oracle DBLink to PostgreSQL
This is the most delicate step. Oracle uses the **dg4odbc** component (Database Gateway for ODBC) to connect to PostgreSQL via the ODBC DSN created in Step 3. The configuration touches 3 Oracle files and requires a Listener restart.
### 6.1 - Edit tnsnames.ora
File: `[ORACLE_HOME]\network\admin\tnsnames.ora`
Add the following entry **at the end of the file**. The identifier `PostgreSQL35W` **must start at column 1** (no leading space or tab), otherwise Oracle will not recognize it as a valid TNS entry:
```
PostgreSQL35W =
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521))
(CONNECT_DATA=(SID=PostgreSQL35W))
(HS=OK)
)
```
Leave a blank line between the previous entry and this one. `(HS=OK)` is mandatory - it tells Oracle this is a Heterogeneous Service (connection to a non-Oracle system).
> **Common error**: if the identifier is indented (space or tab before `PostgreSQL35W =`), Oracle returns `ORA-12154: TNS:could not resolve the connect identifier specified`. This is a subtle trap because the rest of the file works fine with indentation.
### 6.2 - Edit listener.ora
File: `[ORACLE_HOME]\network\admin\listener.ora`
Add a `SID_DESC` block in the existing `SID_LIST_LISTENER` section:
```
(SID_DESC =
(SID_NAME = PostgreSQL35W)
(ORACLE_HOME = C:\Mecalux\Motor\oracle\Product\19.27.0.0\dbhome_1)
(PROGRAM = dg4odbc)
)
```
> **Critical**: the `ORACLE_HOME` path in this block must be the **real, complete path** of your Oracle installation. Never leave a placeholder like `[VERSION]` - this causes `TNS-12518` / `ORA-28545` errors. The listener starts without error and the SID appears in `lsnrctl status`, making the problem hard to diagnose. **Verify** that the `ORACLE_HOME` in the PostgreSQL35W block is **identical** to the other `SID_DESC` blocks in the file.
### 6.3 - Create initPostgreSQL35W.ora
Go to `[ORACLE_HOME]\hs\admin\`, duplicate the file `initdg4odbc.ora`, rename the copy to `initPostgreSQL35W.ora` (name must match the SID_NAME exactly, case-sensitive), and replace all content with:
```
HS_FDS_CONNECT_INFO = PostgreSQL35W
HS_FDS_TRACE_LEVEL = 0
```
Do not leave the template lines from the original file. For debugging, temporarily set `HS_FDS_TRACE_LEVEL = 4` for detailed dg4odbc traces. Reset to 0 after diagnosis.
### 6.4 - Restart the Oracle Listener
```
lsnrctl stop
lsnrctl start
```
Verify that the SID `PostgreSQL35W` appears in the service list:
```
lsnrctl status
```
Expected output: `Service "PostgreSQL35W" has 1 instance(s). Instance "PostgreSQL35W", status UNKNOWN, has 1 handler(s) for this service...` The UNKNOWN status is normal for a Heterogeneous Service - the process is launched on demand.
### 6.5 - Grant CREATE DATABASE LINK to db_read
Connect as **sysdba** and grant:
```sql
GRANT CREATE DATABASE LINK TO db_read;
```
> The target user is **db_read** (the Easy WMS read model schema). The database link and synonyms must be owned by db_read. Do not create the link under SYS - it will not be visible from db_read.
### 6.6 - Create the Database Link
Connect as **db_read** (not sysdba):
```sql
CREATE DATABASE LINK AGV
CONNECT TO "externalAGV" IDENTIFIED BY "mecalux"
USING 'PostgreSQL35W';
```
> **Double quotes** around the user and password are **mandatory**. Oracle converts identifiers to uppercase by default, but PostgreSQL is case-sensitive. Without quotes, Oracle sends `EXTERNALAGV` instead of `externalAGV` and authentication fails.
### 6.7 - Test the DBLink
```sql
SELECT * FROM "agv_inputqueue"@AGV;
```
If the query returns `no rows selected`, the link works. The tables are simply empty at this stage.
### 6.8 - Create Oracle synonyms
Still connected as **db_read**:
```sql
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;
```
> Table names in double quotes are lowercase because PostgreSQL stores identifiers in lowercase by default.
Verify all synonyms: `SELECT * FROM agv_inputqueue;` (repeat for each). All queries must pass without error (`no rows selected` is expected).
## Step 7 - Install the AGV module in Easy WMS
### 7.1 - Modify response.xml
Add the AGV entries in the deployment `response.xml`:
```xml
<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>
```
### 7.2 - Run the deploy
Execute the deploy using **option 16 - Install application**.
### 7.3 - Restart the Gateway AGV
After the deploy completes, restart the Gateway AGV service in `services.msc`.
## Troubleshooting
### DSN name case: PostgreSQL35W
The most frequent cause of failure. The DSN name must be **identical** (case-sensitive) across all 6 locations:
| File / Location | Expected value |
|-----------------|----------------|
| ODBC System DSN (data source name) | `PostgreSQL35W` |
| tnsnames.ora (TNS entry name + SID) | `PostgreSQL35W` |
| listener.ora (SID_NAME) | `PostgreSQL35W` |
| initPostgreSQL35W.ora (filename) | `initPostgreSQL35W.ora` |
| initPostgreSQL35W.ora (content) | `HS_FDS_CONNECT_INFO = PostgreSQL35W` |
| CREATE DATABASE LINK ... USING '...' | `'PostgreSQL35W'` |
### Indentation in tnsnames.ora
The TNS entry identifier (e.g., `PostgreSQL35W =`) must start at **column 1**, with no leading space or tab. Accidental indentation causes `ORA-12154: TNS:could not resolve the connect identifier specified`.
### Placeholder in listener.ora
The `ORACLE_HOME` in the PostgreSQL35W `SID_DESC` must be the **real path**. Leaving a placeholder like `[VERSION]` causes `TNS-12518` / `ORA-28545`. The listener starts without error and the SID appears in `lsnrctl status`, which makes the problem difficult to spot. Verify with: `dir C:\Mecalux\Motor\oracle\Product\`
### PostgreSQL 18+ port
PostgreSQL 18 defaults to port **5433** instead of 5432. Update **two locations**: the ODBC System DSN (Step 3) and the Gateway AGV connection string (Step 4).
### Double AGVConfig section
The Gateway XML config must contain exactly **one** `<AGVConfig>` section. Two sections (even with different `stationNumber` values) cause: `System.ArgumentNullException: Migration DataBase Provider No Initialized`.
### Double quotes in Oracle commands
Oracle converts identifiers to uppercase; PostgreSQL stores them in lowercase. When creating the database link and synonyms, PostgreSQL table names must be in double quotes (`"agv_inputqueue"`), and PostgreSQL credentials must also be in double quotes (`"externalAGV"`, `"mecalux"`).
### Database link and synonyms must be created under db_read
The database link and synonyms must be created while connected as **db_read**, not SYS. A link created under SYS is not visible from db_read, and the AGV monitoring views in the WMS use the read model schema.
### dg4odbc trace for diagnosis
If the DBLink fails (`ORA-28545`, `ORA-12154`, etc.), enable tracing in `[ORACLE_HOME]\hs\admin\initPostgreSQL35W.ora`:
```
HS_FDS_TRACE_LEVEL = 4
```
Restart the listener, retry the query, then look for the trace file in `[ORACLE_HOME]\hs\admin\` or the Oracle diagnostic directory. **Reset to 0 after diagnosis.** If no trace file is created, dg4odbc is not launching at all - the problem is in listener.ora (incorrect ORACLE_HOME or listener not restarted).
### Standalone ODBC connectivity test
To isolate an ODBC connection problem (bypassing Oracle/dg4odbc):
```powershell
$conn = New-Object System.Data.Odbc.OdbcConnection
$conn.ConnectionString = "DSN=PostgreSQL35W;Uid=externalAGV;Pwd=mecalux;"
$conn.Open()
$conn.State # Should display "Open"
$conn.Close()
```
If this test passes but the Oracle DBLink fails, the problem is in the dg4odbc configuration (Oracle files), not the ODBC connection itself.
## Related
- [AGV - Automated Guided Vehicles](../modules/agv.md) - Functional documentation: architecture, protocol, monitoring, errors
- [Stations](../concepts/stations.md) - Station types including AGV (type 65), equipment groups, routes