16 KiB
title, type, sources, related, last_compiled
| title | type | sources | related | last_compiled | ||||
|---|---|---|---|---|---|---|---|---|
| AGV Module — Installation Guide | operation |
|
|
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.
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
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. UsingPOSTGRESQL35W(all caps) orpostgresql35w(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 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):
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:
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):
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:
-- 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 returnsORA-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_HOMEpath in this block must be the real, complete path of your Oracle installation. Never leave a placeholder like[VERSION]- this causesTNS-12518/ORA-28545errors. The listener starts without error and the SID appears inlsnrctl status, making the problem hard to diagnose. Verify that theORACLE_HOMEin the PostgreSQL35W block is identical to the otherSID_DESCblocks 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:
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):
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
EXTERNALAGVinstead ofexternalAGVand authentication fails.
6.7 — Test the DBLink
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:
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:
<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):
$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 — Functional documentation: architecture, protocol, monitoring, errors
- Stations — Station types including AGV (type 65), equipment groups, routes