57 KiB
share_link, share_updated, cssclasses
| share_link | share_updated | cssclasses | |
|---|---|---|---|
| https://share.note.sx/ziuyd353#P//B0nvVix4HFcZp0NAOVtbR3EXhPIYEtuv1VDkKkV4 | 2026-04-30T09:33:12+02:00 |
|
CR technique — iGO STILL : fonctionnement et flux API + correspondance avec le module AGV EasyWMS
Compte-rendu technique simplifié du fleet manager iGO easy (alias PACS Host API côté KION/STILL) à partir des documents fournis dans le dossier STILL, suivi d'une table de correspondance complète avec le module AGV EasyWMS (cf.
CR_ModuleAGV.md).Public : développeurs EasyWMS / intégration robotique. Date : 2026-04-28. Sources :
2510_PACS-2.3-Host-Interface-Technical-Specifications_en-US--STILL-.pdf(référence API la plus récente, 10/2025)iGo easy 2.3 - Host Interface Specifications.pdf(variante iGO easy — API identique au PACS 2.3)IT requirements R1 20250929.pdf(environnement MyMA — frontend Vue3 + backend .NET 8 + Postgres)Technical specification EXV CB iGo.pdf(datasheet véhicule — gerbeur EXV CB iGo)Limagrain-LWM_Std_Interface_Compliance.xlsx(matrice de compliance — non lu automatiquement, format binaire ; sera abordé manuellement avec l'équipe Limagrain)
Sommaire
- Vue d'ensemble iGO / PACS
- Stack technique et déploiement
- Modèle de ressources
- Flux API principaux
- Cycle de vie d'un Transport
- Sécurité et abonnements aux events
- Table de correspondance EasyWMS AGV ↔ iGO
- Points d'attention pour l'intégration
- FAQ STILL — réponses officielles
1. Vue d'ensemble iGO / PACS
iGO easy (et son grand frère PACS — Productized Automated Concept Solutions) est le fleet manager AGV de KION Group / STILL. Le moteur sous-jacent s'appelle E'tricc (visible dans la phrase de la doc PACS « all transports that are still in the memory of E'tricc »). Les deux versions exposent strictement la même API REST en version 2.3 — le PACS est l'offre commerciale large, iGO easy est la déclinaison « easy » destinée à des installations plus simples.
flowchart LR
subgraph WMS["Hôte (WMS / WES / ERP)"]
direction TB
EasyWMS["EasyWMS"]
end
subgraph FleetMgr["iGO easy / PACS Fleet Manager"]
direction TB
Etricc["Moteur E'tricc"]
MyMA["MyMA - admin UI<br/>Vue3 + .NET8 + Postgres"]
Etricc <--> MyMA
end
subgraph Fleet["Flotte AGV"]
EXV["EXV CB iGo<br/>(gerbeur ~3.4m)"]
Other["...autres modèles STILL"]
end
EasyWMS <-->|"HTTPS REST<br/>port 7002<br/>TLS 1.2 + Bearer"| Etricc
Etricc -.->|"callback POST<br/>vers WMS"| EasyWMS
Etricc <--> Fleet
Concepts clés à retenir :
- Pas de PLC, pas de tables d'échange SQL côté hôte. Tout passe par REST sur HTTPS.
- Modèle pull + push : le WMS pousse les ordres (POST /transports) ; iGO pousse les changements d'état via webhook (callback vers une URL exposée par le WMS).
- Pas de notion de routes/segments côté WMS : iGO ne demande qu'une
sourceLocationet unedestinationLocation. La trajectoire physique entre les deux est entièrement gérée par iGO. - Décision tardive (group / decision point) : si on ne sait pas encore où exactement charger ou décharger au moment de la création du transport, on peut donner un
sourceGroupId/destinationGroupId. iGO place alors le transport enRequestSource/RequestDestinationet interroge le WMS au moment où l'AGV arrive au point de décision. - Charge utile (Load) = container EasyWMS. Existe comme ressource indépendante (catalogue) avec dimensions et type.
2. Stack technique et déploiement
2.1 Environnement (MyMA)
D'après IT requirements R1 :
| Composant | Détail |
|---|---|
| Backend | .NET 8.0 (C#) |
| Frontend | Vue 3.2 |
| Base de données | Postgres 12+ par défaut, SQL Server 2019 ou MySQL 8.0 supportés |
| OS serveur | Windows 11 Pro/Ent, Windows Server 2016/2019/2022, Ubuntu 18.04 |
| Navigateurs admin | Edge, Chrome, Firefox |
| Hardware (low) | 4 cores @2.26 GHz, 8 Go RAM, 500 Go RAID5, dual PSU |
| Hardware (high) | 8 cores, 16 Go RAM, 1 To, dual PSU |
2.2 Ports réseau
| Service | Port |
|---|---|
| Front-end web (admin MyMA) | 82 |
| Backend (REST interne) | 50005 |
| API Host vers WMS (HTTPS REST) | 7002 |
| Postgres | 5432 |
2.3 Wifi (pour terminaux opérateur si présents)
Signal min -70 dBm, SNR min 20 dB, débit min 24 Mbps, ping moyen ≤ 50 ms.
2.4 Véhicule type — STILL EXV CB iGo
| Caractéristique | Valeur |
|---|---|
| Longueur totale (l1) | 3 383 mm |
| Longueur jusqu'au dosseret (l2) | 2 083 mm |
| Largeur tablier fourche (b3 / b1 / b2) | 1 000 / 920 / 1 109 mm |
| Fourche (s / e / l) | 50 / 100 / 1 300 mm |
| Hauteur véhicule (arche / mât) | 2 447 / 2 015 mm |
Le véhicule est un gerbeur électrique automatisé (EXV = Elektro-Vertikal) — il se déplace sur ses propres roues et lève la charge avec le mât. Il n'a pas de notion de couloir mécanique ni de canal compact à l'instar d'un Pallet Shuttle.
3. Modèle de ressources
L'API expose 8 ressources (chapitres 1-8 du PACS) :
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ System │ │ Transport │ ─────▶│ Vehicle │
│ (état global + │ │ (l'ordre du │ │ (AGV physique) │
│ abonnements) │ │ WMS) │ └──────────────────┘
└──────────────────┘ └────────┬─────────┘ ▲
│ │ assignation
▼ │
┌──────────────────┐ ┌──────────────────┐
│ Load │◀──────│ Location │
│ (charge physique │ │ (point géo + │
│ = container) │ │ actions) │
└────────┬─────────┘ └────────┬─────────┘
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ LoadType │ │ Group │
│ (catalogue de │ │ (ensemble de │
│ types) │ │ locations) │
└──────────────────┘ └──────────────────┘
3.1 Transport (l'ordre)
C'est l'équivalent direct de l'AgvTask côté EasyWMS.
| Champ | Type | Rôle |
|---|---|---|
id |
string | Id généré par iGO |
transportHostId |
string | Id hôte (= OrderExtId côté EasyWMS) |
sourceLocationId ou sourceGroupId |
string | Source (un des deux requis) |
destinationLocationId ou destinationGroupId |
string | Destination (un des deux requis) |
load |
Load | Charge embarquée |
priority |
int 0-10 | 10 = max, 0 = min |
suspended |
bool | Crée le transport mais sans l'exécuter |
customMetaData |
dict (Key/Val) | Métadonnées libres |
status |
enum | Voir § 5 |
3.2 Vehicle (l'AGV)
| Champ | Type | Rôle |
|---|---|---|
id |
string | Identifiant véhicule |
mode |
enum | Manual / Automatic / SemiAutomatic / Removed / Disabled |
status |
enum | Idle / Executing / Charging / Faulted / Manual |
pose |
object (x, y, orientation) | Position physique en temps réel |
batteryLevel |
int | % batterie |
loadId / loadHostId |
string | Charge embarquée |
locationStationId |
string | Station courante |
errors |
array | Codes/labels d'erreur |
3.3 Load et LoadType
Load = instance physique d'une charge (un container, une palette). Possède loadHostId (id côté WMS), loadTypeId, locationId, dimensions (W/D/H/Weight) et customMetaData.
LoadType = catalogue (id + dimensions par défaut). Endpoint en lecture seule (GET /api/load-types).
3.4 Location & Group
- Location : un point physique sur lequel un AGV peut faire des actions (
possibleActions), avec types de véhicules et de charges autorisés etactualLoadscourantes. - Group : un ensemble de Locations. Sert quand on veut différer le choix de la location finale jusqu'au point de décision (cas typique : zone de déchargement avec plusieurs alvéoles). Le WMS appelle alors
POST /api/transports/{id}/final-sourceou/final-destinationpour fixer le choix.
3.5 System
État global : projet courant, isRunning, abonnements actifs, timestamp de démarrage.
4. Flux API principaux
4.1 Inventaire des endpoints
Tous sur https://[IP]:7002/api/... avec X-API-Key (header) et Authorization: Bearer <token> (header).
| Verbe | URL | Effet |
|---|---|---|
| GET | /api/system |
Status global + liste des subscriptions |
| GET | /api/transports |
Liste de tous les transports en mémoire |
| POST | /api/transports |
Créer un nouveau transport |
| GET | /api/transports/{id} |
Détail d'un transport |
| POST | /api/transports/{id}/final-destination |
Fixer la destination finale (group → location) |
| POST | /api/transports/{id}/final-source |
Fixer la source finale (group → location) |
| POST | /api/transports/{id}/suspend |
Mettre en pause |
| POST | /api/transports/{id}/release |
Relancer après suspend |
| POST | /api/transports/{id}/cancel |
Annuler |
| POST | /api/transports/{id}/priority?priority={0-10} |
Changer la priorité |
| POST | /api/transports/subscription?callbackUrl=… |
S'abonner aux events transport |
| DELETE | /api/transports/subscription?callbackUrl=… |
Se désabonner |
| GET | /api/groups / /api/groups/{id} |
Lecture des groupes |
| GET | /api/loads / /api/loads/{id} |
Lecture des loads |
| POST | /api/loads |
Créer une load à une location |
| POST | /api/loads/{id}/location |
Déplacer une load (manuellement) |
| DELETE | /api/loads/{id} |
Supprimer une load |
| GET | /api/load-types |
Catalogue des types |
| GET | /api/locations / /api/locations/{id} |
Lecture des locations |
| GET | /api/vehicles / /api/vehicles/{id} |
Lecture véhicules |
| POST | /api/vehicles/suspend |
Suspendre toute la flotte |
| POST | /api/vehicles/resume |
Relancer toute la flotte |
| POST | /api/vehicles/{id}/suspend / .../resume |
Suspend/resume un AGV donné |
| POST | /api/vehicles/restart |
Redémarrer toute la flotte |
| POST | /api/vehicles/subscription?callbackUrl=… |
S'abonner aux events vehicle |
| DELETE | /api/vehicles/subscription?callbackUrl=… |
Se désabonner |
4.2 Endpoints à implémenter côté WMS (callbacks)
Spécifiés par le client (l'URL est passée à l'inscription).
| URL (côté WMS) | Body reçu | Quand iGO l'appelle |
|---|---|---|
POST /api/transport/event |
objet Transport complet |
À chaque changement d'état d'un transport |
POST /api/vehicles/event |
objet Vehicle complet |
À chaque changement d'état d'un véhicule |
ℹ️ Le contrat ne définit pas la fréquence ni le rate-limiting. À tester en charge — un transport qui passe par tous les états émet ~7 callbacks ; un véhicule qui se déplace peut en émettre beaucoup plus (pose updates).
4.3 Flux nominal — création et exécution d'un transport
sequenceDiagram
autonumber
participant WMS as EasyWMS
participant iGO as iGO easy
participant V as Vehicle
WMS->>iGO: POST /api/transports {sourceLocationId, destinationLocationId, load, priority, transportHostId}
iGO-->>WMS: 200 OK Transport(id, status=Requested)
iGO->>WMS: callback transport/event (status=Pending)
iGO->>V: assigne le véhicule
iGO->>WMS: callback transport/event (status=Assigned)
Note over V: AGV se déplace<br/>vers source
V->>iGO: arrivé source
iGO->>WMS: callback (status=Retrieving)
Note over V: AGV charge
V->>iGO: chargé
iGO->>WMS: callback (status=Retrieved)
Note over V: AGV se déplace<br/>vers destination
V->>iGO: arrivé destination
iGO->>WMS: callback (status=Storing)
Note over V: AGV décharge
V->>iGO: déchargé
iGO->>WMS: callback (status=Stored)
iGO->>WMS: callback (status=Finished)
4.4 Flux avec décision tardive (Group)
C'est le cas où le WMS ne sait pas, à la création, quelle alvéole exacte utiliser :
sequenceDiagram
autonumber
participant WMS
participant iGO
participant V as Vehicle
WMS->>iGO: POST /api/transports {destinationGroupId="DOCK_OUT", ...}
iGO-->>WMS: 200 OK (status=Requested)
iGO->>WMS: callback (status=Pending)
iGO->>WMS: callback (status=Assigned)
iGO->>WMS: callback (status=Retrieving → Retrieved)
Note over V: AGV se déplace<br/>vers le decision point<br/>du groupe DOCK_OUT
V->>iGO: arrivé au decision point
iGO->>WMS: callback (status=RequestDestination)
Note over WMS: WMS choisit une<br/>alvéole précise dans<br/>le groupe DOCK_OUT
WMS->>iGO: POST /api/transports/{id}/final-destination<br/>{destinationId: "DOCK_OUT_03"}
iGO-->>WMS: 200 OK
Note over V: AGV poursuit<br/>vers DOCK_OUT_03
iGO->>WMS: callback (status=Storing → Stored → Finished)
⚠️ Si le WMS ne répond pas assez vite, iGO bascule de
RequestDestinationversWaitDestination(l'AGV est arrivé physiquement et attend). Symétrique côté source :RequestSource→WaitSource.
4.5 Annulation et suspension
Action Endpoint Effet
─────────────────────────────────────────────────────────────────────────────────────
Annuler POST /api/transports/{id}/cancel status=Cancelled (terminal)
Suspendre POST /api/transports/{id}/suspend gel temporaire (peut être levé)
Relancer POST /api/transports/{id}/release inverse de suspend
Re-prioriser POST /api/transports/{id}/priority?p=N 0..10
Suspendre flotte POST /api/vehicles/suspend tous les AGV s'arrêtent
Reprendre flotte POST /api/vehicles/resume
Redémarrer flotte POST /api/vehicles/restart reset hard
⚠️ Limite d'annulation confirmée par STILL : un transport ne peut pas être annulé après l'état
Retrieved(= AGV a déjà pris la palette) — cf. FAQ #6.Conséquence côté EasyWMS : la branche du
AgvTask_SetCancelledTask_PRqui gérait l'annulation après chargement (et déclenchait la recherche de relocation) n'a plus de sens dans le mapping iGO. Si un cancel arrive côté WMS aprèsRetrieved, il faut soit :
- attendre la fin du transport (
Stored) et faire alors une nouvelle tâche AGV de retour ;- ou intervenir physiquement (intervention manuelle / fallback RFT) avant de cancel.
💤 Le champ
suspended(paramètre du POST de création) n'a pas d'usage métier identifié par STILL côté WMS classique (cf. FAQ #7). À utiliser uniquement si on veut pré-créer un transport avant que la palette soit physiquement disponible.
5. Cycle de vie d'un Transport
État final possible : Finished, Cancelled, Aborted.
flowchart TD
New[New] --> Req[Requested]
Req --> Pen[Pending]
Pen --> Asg[Assigned]
Asg -->|source = Group| RS[Request Source]
Asg -->|source = Location| Ret[Retrieving]
RS -->|final source set| Ret
RS -->|AGV arrivé sans réponse| WS[Wait Source]
WS -->|final source set| Ret
Ret --> Rtd[Retrieved]
Rtd -->|dest = Group| RD[Request Destination]
Rtd -->|dest = Location| Sto[Storing]
RD -->|final dest set| Sto
RD -->|AGV arrivé sans réponse| WD[Wait Destination]
WD -->|final dest set| Sto
Sto --> Std[Stored]
Std --> Fin[Finished]
Asg -.cancel.-> Can[Cancelled]
Pen -.cancel.-> Can
Ret -.error.-> Abo[Aborted]
Sto -.error.-> Abo
| État | Sens fonctionnel |
|---|---|
New |
État interne instantané — n'apparaît jamais dans les callbacks. À ignorer côté WMS. (cf. FAQ #4) |
Requested |
Premier état réellement observable côté WMS, juste après le POST |
Pending |
En file d'attente, en attente d'un AGV libre |
Assigned |
Un AGV a été désigné |
RequestSource / WaitSource |
Source = group ; iGO attend la décision finale du WMS |
Retrieving |
AGV en route vers la source / en cours de chargement |
Retrieved |
Charge prise |
RequestDestination / WaitDestination |
Destination = group ; iGO attend la décision finale |
Storing |
AGV en route vers destination / en cours de dépose |
Stored |
Charge déposée |
Finished |
Transport terminé proprement (état terminal) |
Cancelled |
Annulé via /cancel (état terminal) |
Aborted |
Erreur d'exécution irrécupérable (état terminal). ⚠ Aucun code ni message d'erreur dans le payload — seul le statut est transmis (cf. FAQ #2) |
🔑 Identifiant véhicule : il n'apparaît dans le payload qu'à partir de l'état
Retrieved(et plus, après donc). À l'étatAssigned, le payload ne contient pas encore leVehicle.id(cf. FAQ #1). Les workflows EasyWMS (typiquementProcessEvent_TaskAssigned_PRqui faisait le lien Equipment ↔ Task) doivent donc être recalés surRetrievedpour le mapping iGO.
⏱️ Pas de timestamp dans le payload des callbacks (cf. FAQ #3). Si le WMS a besoin d'horodater, il doit le faire à réception (
DateTime.UtcNow).
6. Sécurité et abonnements aux events
6.1 Sécurité
- Transport : HTTPS avec TLS 1.2 ; certificats auto-signés → le WMS doit les truster explicitement (import dans le keystore).
- Authentification : ✅ C'est
X-API-Keyqui est utilisé (confirmé par STILL — cf. FAQ #8). Le headerAuthorization: Bearer <token>mentionné dans certaines parties de la doc est obsolète / à ignorer. - La clé est fixe (pas de refresh automatique) → fournie par le PM STILL.
6.2 Modèle d'abonnement
sequenceDiagram
participant WMS
participant iGO
Note over WMS: au démarrage du WMS
WMS->>iGO: POST /api/transports/subscription?callbackUrl=https://wms/agv/events/transport
iGO-->>WMS: 204 No Content
WMS->>iGO: POST /api/vehicles/subscription?callbackUrl=https://wms/agv/events/vehicle
iGO-->>WMS: 204 No Content
Note over iGO: en exploitation
iGO->>WMS: POST https://wms/agv/events/transport (Transport JSON)
WMS-->>iGO: 200 OK
iGO->>WMS: POST https://wms/agv/events/vehicle (Vehicle JSON)
WMS-->>iGO: 200 OK
Note over WMS: à l'arrêt du WMS
WMS->>iGO: DELETE /api/transports/subscription?callbackUrl=…
WMS->>iGO: DELETE /api/vehicles/subscription?callbackUrl=…
6.3 Bonnes pratiques côté EasyWMS
- Idempotence : iGO peut retransmettre un event en cas de timeout côté WMS. Le handler côté EasyWMS doit gérer le doublon (par exemple via
transport.id+status). - Re-souscription au boot : si iGO redémarre, les abonnements en mémoire peuvent être perdus. Le WMS doit toujours appeler
GET /api/systemau démarrage et vérifier la présence de la subscription, et la recréer sinon. - Endpoint callback : doit être en HTTPS (sinon iGO refuse), retourner 200 OK rapidement (idéalement < 1s), traitement asynchrone derrière.
7. Table de correspondance EasyWMS AGV ↔ iGO
7.1 Concepts métier
| EasyWMS (module AGV) | iGO easy / PACS | Commentaire |
|---|---|---|
AgvTask (entité) |
Transport (resource) |
Cœur fonctionnel — l'ordre de transport |
Container / LPN |
Load |
La charge physique |
ContainerType |
LoadType |
Catalogue de types |
Location (IRealLocation) |
Location |
Point physique du warehouse |
WorkingZone |
Group |
Ensemble de locations à décision tardive |
| AGV station (type 65) | Vehicle |
Le véhicule lui-même |
AgvLockType (AGV_Lock) |
Location.isEnabled = false |
iGO n'a pas de typage de lock — juste un flag |
ManualEquipment (RFT fallback) |
(aucun équivalent) | Concept WMS-uniquement |
EagMessages (table SQL) |
API REST POST /api/transports/... |
Tables ↔ HTTP |
AgeMessages (table SQL) |
Webhook callback POST /transport/event |
Tables ↔ HTTP |
AgsMessages (table SQL) |
Webhook callback POST /vehicles/event |
Status AGV |
7.2 Champs de l'ordre
EasyWMS AgvTask |
iGO Transport |
Conversion |
|---|---|---|
OrderExtId (long, = Task.TaskNumber) |
transportHostId (string) |
OrderExtId.ToString() |
Id (Guid) |
id (string) |
iGO génère son propre id |
LoadLocation |
sourceLocationId |
mapping direct par code location |
UnloadLocation |
destinationLocationId |
id direct |
| (groupe de couloirs / décision tardive) | sourceGroupId / destinationGroupId |
Pour WorkingZones |
LoadType (0=Container, 1=PalletShuttle) |
Load.loadTypeId |
iGO ne gère pas nativement le PS |
PalletId |
Load.loadHostId |
id côté WMS |
PalletType |
Load.loadTypeId |
référence au catalogue LoadType |
Priority (0=Urgent ... 4=VeryLow) |
priority (10=max, 0=min) |
Conversion inversée — voir ci-dessous |
HasTopper |
customMetaData["HASTOPPER"] |
passe en metadata |
CanPick, CanDrop |
(pas d'équivalent natif) | Voir § 8 |
UnloadAisleNumber/Side/X/Y/Depth |
(porté par la Location) |
iGO gère la géométrie en interne |
StationNumber (AGV courant) |
Vehicle.id (vu en callback) |
id du véhicule assigné |
PreviousOrderId (chaînage) |
(pas d'équivalent natif) | À encoder en customMetaData |
Status (enum AgvStatus) |
status (enum Transport) |
Voir § 7.3 |
Operation (Create/Update/Delete) |
endpoints REST distincts | POST / final-* / cancel |
WarehouseNumber / WarehouseCode |
(pas exposé) | iGO suppose un seul site |
Conversion de priorité :
| EasyWMS | iGO | Suggestion |
|---|---|---|
| 0 — Urgent | 10 — Highest | mapping direct |
| 1 — High | 8 | |
| 2 — Normal | 5 | |
| 3 — Low | 3 | |
| 4 — VeryLow | 1 |
7.3 États / phases
| Phase AGV (EasyWMS) | EasyWMS AgvStatus |
iGO Transport.status |
Notes |
|---|---|---|---|
| (création) | PendingToBeSend |
(pas encore envoyé) | côté WMS uniquement |
| Envoi EAG | — | New → Requested |
après POST /api/transports |
| Phase 100 (Order accepted) | Sent |
Pending |
en file d'attente iGO |
| Phase 103 (Vehicle assigned) | (Sent) | Assigned |
véhicule affecté |
| Phase 104 (Load permission) | PendingToBeLoad |
RequestSource (group only) |
iGO n'a ce comportement qu'en mode group |
| (autorisation WMS load) | (Sent / re-export EAG) | POST /final-source |
mais pas un renvoi du même ordre — c'est un endpoint dédié |
| Phase 106 (Load confirmed) | (Sent) | Retrieving → Retrieved |
charge prise |
| Phase 108 (Unload permission) | PendingToBeUnload |
RequestDestination (group only) |
idem auth load |
| (autorisation WMS unload) | (Sent / re-export EAG) | POST /final-destination |
endpoint dédié |
| Phase 110 (Unload confirmed) | (Sent → purge) | Storing → Stored → Finished |
terminé |
| Phase 255 (Cancel by AGV) | (Cancelled) |
Cancelled ou Aborted |
aborted = erreur, cancelled = ordre annulé |
🎯 Différence sémantique majeure : EasyWMS attend une demande explicite d'autorisation (phases 104 / 108) à chaque ordre quand
CanPick/CanDropsont àfalse. iGO ne demande l'autorisation qu'au point de décision d'un Group. Si lasourceLocationest connue dès la création, iGO ne demande aucune autorisation — elle exécute directement.Pour reproduire le comportement EasyWMS dans iGO, il faut forcer l'usage de Groups, même mono-location, là où EasyWMS aurait CanPick = false.
7.4 Erreurs
| Code EasyWMS | Famille | Équivalent iGO | Remarque |
|---|---|---|---|
| 1001-1014 | Configuration (mauvaise station, ordre dupliqué…) | HTTP 400 BadRequest à la création |
iGO refuse à la requête |
| 1003 (duplicate) | HTTP 400 sur POST /transports si transportHostId déjà utilisé (à valider) |
||
| 1009 (cancellation error) | HTTP 400/404 sur POST /cancel |
||
| 2003 (extraction error) | Exécution | Transport.status = Aborted + Vehicle.errors[] |
erreur runtime |
| 2004 (putaway error) | Exécution | idem | |
| 2005 (manual cancel from AGV UI) | Exécution | Transport.status = Cancelled reçu en callback |
|
| 2500-2503 | Communication | erreurs HTTP 5xx / timeouts | au niveau réseau |
| 2700 (wrong/missing container) | Exécution | Vehicle.errors[] + status = Faulted |
côté véhicule |
💡 Côté EasyWMS, les codes 1001-2700 sont stockés dans
agvEvent.Flagset routés parProcessErrors_PR. La logique côté EasyWMS doit donc être étendue pour transformer une réponse HTTP / un callback iGO en unagvEvent.Flagsnumérique, qui ensuite ré-utilise toute la machinerie standard de notification (ProcessError1001_PR, etc.).
7.5 Verbe / opération
| Action métier | EasyWMS (Operation + EAG) | iGO (REST) |
|---|---|---|
| Créer un ordre | Operation = Create + ligne EAG |
POST /api/transports |
| Modifier un ordre | Operation = Update + ligne EAG |
(selon le cas) POST /priority, POST /final-source, POST /final-destination |
| Annuler un ordre | Operation = Delete + ligne EAG |
POST /api/transports/{id}/cancel |
| Modifier priorité | AgvTaskEditCommand + Operation = Update |
POST /api/transports/{id}/priority?priority=N |
| Suspendre un ordre | (pas d'équivalent) | POST /api/transports/{id}/suspend ➕ |
| Reprendre un ordre | (pas d'équivalent) | POST /api/transports/{id}/release ➕ |
| Suspendre la flotte | (pas d'équivalent) | POST /api/vehicles/suspend ➕ |
| Demande d'auth load | EAG Operation = Update (CanPick=true) |
POST /api/transports/{id}/final-source |
| Demande d'auth unload | EAG Operation = Update (CanDrop=true) |
POST /api/transports/{id}/final-destination |
➕ = capacité nouvelle offerte par iGO, sans contrepartie WMS — utile pour la maintenance.
7.6 Topologie / configuration
| EasyWMS | iGO |
|---|---|
| AGV créé en EasyS dans un AGV equipment group (type 65) | Vehicle configuré dans MyMA |
Routes configurées en EasyS entre stations |
Layout iGO, géré dans MyMA / iGO designer |
LoadAisle / UnloadAisle (couloirs manuels) |
Location.possibleActions |
Allow loading / Allow unloading per location |
Location.isEnabled + possibleActions |
Manual loading aisle |
(pas d'équivalent — iGO calcule la trajectoire) |
LocationLockType "For AGV" |
Location.isEnabled = false (binaire) |
| Fault notification group AGV | callback POST /vehicles/event (errors[]) |
7.7 Workflows EasyWMS impactés par l'intégration iGO
📖 Vocabulaire : dans la suite, l'expression « Gateway iGO » est utilisée comme raccourci pour désigner le middleware côté flotte à développer pour iGO (cf. § 8.4) — concrètement, une pool IIS C# .NET 8 développée par Mecalux qui regroupe la pompe sortante (poll
AGV_OUTPUTQUEUE→ API iGO) et le webhook receiver (callbacks iGO → écritAGV_INPUTQUEUE+AGE/AGS). Il ne doit pas être confondu avec la Gateway AGV Mecalux, qui elle existe déjà dans le module AGV core et joue un rôle différent (mediator côté Mecalux entre workflows et tables).
✅ Avec le pattern Gateway iGO + Gateway AGV Mecalux + tables EAG/AGE/AGS (cf. § 8.4) : aucun workflow EasyWMS, ni la Gateway AGV Mecalux, n'a besoin d'être modifié. La spécificité iGO est entièrement encapsulée dans le Gateway iGO, qui se contente de traduire le contenu des tables vers/depuis l'API REST PACS.
| Workflow EasyWMS | Comportement avec Gateway iGO |
|---|---|
MovementCreatedEventHandler_PR |
✅ Inchangé — toujours le déclencheur |
AgvTask_CreateTaskFromMovement_PR |
✅ Inchangé — produit un AgvTaskWF |
AgvTask_SetCreatedTask_PR |
✅ Inchangé — Status = PendingToBeSend |
SerializeAgvTasks_PR + CreateMovTrackings_PR |
✅ Inchangé — écrit en table EAG. Le Gateway iGO lit cette ligne et exécute le POST /api/transports. |
ProcessEvents_PR + ProcessEvent_*_PR |
✅ Inchangé — poll AGE comme d'habitude. Le Gateway iGO alimente AGE en traduisant les callbacks REST. |
ProcessErrors_PR + ProcessError*_PR |
✅ Inchangé — réagit aux Flags dans AGE. Le Gateway est responsable d'inscrire un Flags cohérent (2003, 2004, etc.) à partir du status=Aborted + GET vehicles errors. |
Agvtask_CanPick/CanDrop_PendingToBeSent_PR |
✅ Inchangé — réécrit une ligne EAG avec CanPick=true/CanDrop=true. Le Gateway reconnaît ce pattern et appelle POST /transports/{id}/final-source ou /final-destination. |
TaskCanceledEventHandler_PR + AgvTask_SetCancelledTask_PR |
✅ Inchangé — écrit une ligne EAG Operation=Delete. Le Gateway appelle POST /transports/{id}/cancel (et signale impossibilité si statut iGO ≥ Retrieved). |
MovementDestinationChanged_PR |
✅ Inchangé — émet un Operation=Delete puis Operation=Create. Le Gateway chaîne cancel puis nouveau POST /transports. |
Workflows RFT (Equipment_AgvTask_*_UI) |
✅ Inchangés — fallback opérateur préservé si iGO indisponible |
AGV_LocationLockType_Create_PR |
✅ Inchangé — init du LockType AGV_Lock côté EasyWMS. La pose effective du verrou n'a pas d'écho direct vers iGO (les locations iGO ne sont gérées que par MyMA). |
Galileo_EventCreatedEventHandler_PR (partial) |
✅ Inchangé — non concerné par iGO (côté Galileo seulement) |
📌 Conséquence projet : la livraison du custom
CstAGVn'a rien à voir avec l'intégration iGO. Le custom AGV reste tel qu'il est, et c'est le Gateway iGO (livrable séparé, service Windows à part) qui porte toute la couche d'adaptation. C'est la bonne séparation des responsabilités.
8. Points d'attention pour l'intégration
8.1 Différences structurelles
- Pas de tables d'échange : il faut un service HTTP listener côté EasyWMS pour recevoir les callbacks. Exposé typiquement sur le serveur WMS, sécurisé en HTTPS, avec un certificat trusté par MyMA.
- Pas de phases distinctes 100/103/104/106/108/110 dans iGO — tout est état du Transport. Le mapping en phases EasyWMS est un travail de traduction côté custom.
- Pas de
CanPick/CanDropnatifs : pour reproduire la demande d'autorisation, il faut passer par les Groups. Conséquence : le layout iGO doit déclarer un Group pour chaque location qui doit demander auth. - Priorité 0-10 vs 0-4 : conversion bijective à fixer (cf. § 7.2).
- Pas de routing exposé : iGO gère ses routes en interne. Donc pas d'équivalent à
Routes between stationsen EasyS, et pas d'erreurDisabled routecôté iGO.
8.2 Capacités nouvelles
iGO offre des capacités que l'AGV core EasyWMS n'expose pas :
- Suspend / Resume / Restart d'une flotte ou d'un véhicule individuel sur demande WMS.
- Pose temps réel de chaque véhicule (
x, y, orientation) → utilisable pour un dashboard live côté EasyWMS. - Battery level → permet de déclencher des événements ERP/notifs à seuils.
8.3 Sujets levés avec STILL — état au 28/04/2026
Le retour FAQ STILL a clos plusieurs questions (cf. § 9). Récapitulatif :
| # | Sujet | Statut |
|---|---|---|
| 1 | X-API-Key vs Bearer token |
✅ Résolu : c'est X-API-Key (FAQ #8) |
| 2 | Re-livraison des callbacks | 🟡 Partiel : iGO retente, mais fréquence inconnue → à tester en charge (FAQ #9) |
| 3 | Fréquence des vehicle/event (pose updates) |
❌ Toujours ouvert |
| 4 | Comportement queue saturée (transport Pending sans véhicule) |
🟡 Partiel : on sait au moins que les transports survivent à un redémarrage iGO (FAQ #10) |
| 5 | customMetaData (taille, caractères, ré-émis ?) |
❌ Toujours ouvert |
| 6 | Création/modification de Location via API |
❌ Toujours ouvert (l'API n'expose que GET) |
| 7 | Pallet Shuttle (LoadType = 1) | ❌ Toujours ouvert |
| 8 | Multi-warehouse | ❌ Toujours ouvert |
| 9 | HasTopper (attribut véhicule) | ❌ Toujours ouvert |
| 10 | New vs Requested |
✅ Résolu : New est interne et instantané, traiter Requested comme premier état (FAQ #4) |
| 11 | Vehicle.id disponible dès Assigned ? |
✅ Résolu : non, seulement à partir de Retrieved (FAQ #1) |
| 12 | Code/message d'erreur dans payload Aborted |
✅ Résolu : aucun — juste le statut (FAQ #2) |
| 13 | Timestamp dans les callbacks | ✅ Résolu : aucun — le WMS doit horodater à réception (FAQ #3) |
| 14 | Workflow Load : créer la palette avant ou avec le transport ? |
✅ Résolu : ne pas créer — passer les infos directement dans le transport (FAQ #5) |
| 15 | Annulation après chargement | ✅ Résolu : non, impossible après Retrieved (FAQ #6) |
| 16 | Cas d'usage du suspended |
✅ Résolu : utile uniquement si pré-création d'un transport avant disponibilité de la palette (FAQ #7) |
| 17 | Persistance après redémarrage iGO | ✅ Résolu : oui, les données survivent (FAQ #10) |
| 18 | Communication directe vs via iGo Flow |
✅ Résolu : directement avec l'API PACS (FAQ #11) |
8.4 Architecture cible — Pattern à 4 composants (Gateway Mecalux + middleware pool IIS C#)
🔑 Principe directeur (vérifié dans la doc Mecalux
Interface_Communications_AGVs_EN.pdfet le contrat techniqueRT_AGVs_EN.pdf) : EasyWMS communique avec les fleet managers externes via une base intermédiaire dédiée aux communications (5 tables réelles). Côté Mecalux, un service Gateway AGV (existant) mediate entre les workflows EasyWMS et les tables. Côté flotte, un middleware à fournir (à développer par Mecalux pour iGO, sous forme de pool IIS C# .NET 8) mediate entre ces tables et l'API REST PACS.Le
EasyWMSGateway2015que l'on connaît pour Galileo ne joue PAS le rôle de la Gateway AGV Mecalux — il joue le rôle du middleware côté flotte (médiateur entre tables et TCP frames). Pour iGO, il faut son équivalent fonctionnel mais en REST/HTTPS, sous forme de pool IIS C#.Le custom
CstAGVn'est pas modifié. L'intégration iGO consiste uniquement à fournir le middleware pool IIS.
8.4.1 Schéma cible — 4 composants
flowchart LR
subgraph EasyWMS["Côté Mecalux EasyWMS (existant)"]
Process[Process<br/>Putaway/Picking/Shipping]
Task[Task & Movement]
AgvCore[Module AGV core<br/>workflows CstAGV]
GwMec[Gateway AGV Mecalux<br/>service mediator<br/>workflows ↔ tables]
MonitorView[Vues SmartUI<br/>AGV Tasks/Stations/<br/>Messages]
end
subgraph DB["Intermediate database for communications"]
direction TB
OQ[(AGV_OUTPUTQUEUE<br/>FIFO sortante)]
EAG[(AGV_EAG<br/>data ordres)]
IQ[(AGV_INPUTQUEUE<br/>FIFO entrante)]
AGE[(AGV_AGE<br/>data phases)]
AGS[(AGV_AGS<br/>data statuts AGV)]
end
subgraph FleetSide["Pool IIS C# .NET 8 — À DÉVELOPPER PAR MECALUX pour iGO"]
direction TB
Pump[Pompe sortante :<br/>poll OUTPUTQUEUE<br/>lit EAG via batchId<br/>+ POST API iGO]
Hook[Webhook receiver :<br/>HTTPS endpoint<br/>écrit INPUTQUEUE+AGE/AGS]
end
subgraph KION["iGO / PACS (existant chez STILL)"]
iGO[API REST<br/>port 7002]
end
Process --> Task --> AgvCore
AgvCore -->|events workflow| GwMec
GwMec -->|écrit OUTPUTQUEUE+EAG| OQ
GwMec -->|écrit OUTPUTQUEUE+EAG| EAG
GwMec -->|poll INPUTQUEUE+AGE/AGS| IQ
GwMec -->|poll INPUTQUEUE+AGE/AGS| AGE
GwMec -->|alimente| MonitorView
Pump -->|poll| OQ
Pump -->|lit data via batchId| EAG
Pump -->|HTTPS REST<br/>X-API-Key| iGO
iGO -.webhook callback.-> Hook
Hook -->|écrit| IQ
Hook -->|écrit| AGE
Hook -->|écrit| AGS
8.4.2 Composants existants côté Mecalux — RIEN à développer
| Composant | Rôle | Statut |
|---|---|---|
CstAGV (workflows) |
Logique métier AGV — création de tâches, gestion d'erreurs, fallback RFT, etc. | ✅ Existant — non touché |
| Gateway AGV Mecalux | Service mediator côté Mecalux : écoute events workflow → écrit AGV_OUTPUTQUEUE + AGV_EAG ; poll AGV_INPUTQUEUE → lit AGV_AGE/AGV_AGS → alimente vues SmartUI ; gère le processedDate |
✅ Existant dans le module AGV — non touché |
Tables AGV_INPUTQUEUE, AGV_OUTPUTQUEUE, AGV_EAG, AGV_AGE, AGV_AGS |
Intermediate database for communications | ✅ Existantes |
| Vues SmartUI (AGV Tasks/Stations/Messages) | Monitoring opérateur | ✅ Existantes |
8.4.3 Middleware côté flotte — pool IIS C# à développer par Mecalux
C'est le seul livrable nouveau de l'intégration. Mecalux (et non STILL) prend en charge ce développement, car le contrat avec les tables AGV_* est propriétaire Mecalux. Architecture cible :
| Aspect | Description |
|---|---|
| Forme | Pool IIS dédiée hébergeant un service ASP.NET Core (C#, .NET 8.0) |
| Hébergement | Serveur Mecalux — peut être co-localisé avec EasyWMS ou sur une VM séparée selon la topologie projet |
| Rôle | Service unique multi-thread combinant pompe sortante ET webhook receiver |
| Accès BDD | Connection chaîne vers la base intermédiaire (les 5 tables AGV_*) — typiquement la même base que le WMS, ou une base dédiée si l'architecture projet le décide |
| Sécurité | Header X-API-Key sortant + endpoint HTTPS entrant (TLS 1.2, certificat trusté ou auto-signé selon politique) |
A. Pompe sortante (poll AGV_OUTPUTQUEUE → API iGO)
| Aspect | Description |
|---|---|
| Mode | Background worker / hosted service ASP.NET Core — polling régulier (par ex. toutes les 1-5s) sur AGV_OUTPUTQUEUE WHERE processedDate IS NULL ORDER BY creationDate ASC |
| Action | Pour chaque ligne queue : récupère le id (= batchId) → SELECT data correspondante dans AGV_EAG WHERE batchId = <id> → interprète l'Operation (C/U/D) → fait l'appel REST iGO adéquat |
| Endpoints iGO appelés | POST /api/transports (Create), POST /transports/{id}/cancel (Delete), POST /transports/{id}/priority, POST /transports/{id}/final-source, POST /transports/{id}/final-destination (Update selon le pattern CanPick/CanDrop) |
| Marquage | Après ack synchrone d'iGO (200 OK) : UPDATE AGV_OUTPUTQUEUE SET processedDate = NOW() WHERE id = <id> |
B. Webhook receiver (callbacks iGO → écrit AGV_INPUTQUEUE + AGV_AGE/AGS)
| Aspect | Description |
|---|---|
| Mode | Controller ASP.NET Core exposant deux endpoints HTTPS : POST /agv/transport-event et POST /agv/vehicle-event (URL configurable). Souscriptions iGO créées au boot via POST /api/transports/subscription?callbackUrl=... et POST /api/vehicles/subscription?callbackUrl=... |
| Action | Pour chaque callback reçu : (1) INSERT INTO AGV_INPUTQUEUE (message, creationDate) VALUES ('AGE'/'AGS', NOW()) → récupère le id généré → (2) INSERT INTO AGV_AGE (ou AGV_AGS) avec batchId = <id>, Phase (selon mapping iGO status → 100/103/106/110/255), ErrorType (0 ou code 2003/2004/2700 selon contexte), et tous les autres champs du payload Transport/Vehicle iGO |
| Idempotence | Déduplication sur transport.id + status pour éviter les doubles inserts en cas de retry iGO (cf. FAQ #9). Implémentée via cache local distribué (par ex. table de dedupe interne avec TTL) |
| Horodatage | creationDate = NOW() UTC à la réception, car iGO ne fournit pas de timestamp (cf. FAQ #3) |
| Réponse | 200 OK rapidement (< 1s) après insertion en base — le traitement métier est différé à la Gateway AGV Mecalux qui poll AGV_INPUTQUEUE |
Pattern de boot du middleware
À chaque démarrage de la pool IIS :
- Vérifier la base intermédiaire accessible (connection string + ping
SELECT 1) - Vérifier l'API iGO accessible :
GET /api/system - Récupérer la liste des subscriptions actives via
GET /api/system(champsubscriptions) → comparer avec ce qui est attendu → (re)créer les manquantes viaPOST /api/transports/subscriptionetPOST /api/vehicles/subscription - Réconcilier les transports :
GET /api/transports→ comparer avec lesAGV_OUTPUTQUEUEnon encore acquittées → générer les lignesAGV_INPUTQUEUE+AGV_AGEmanquantes pour les events perdus pendant la coupure - Démarrer le hosted service de polling sortant
💡 Une seule pool IIS héberge les deux fonctions (pompe + webhook). C'est plus simple à exploiter (un seul service à monitorer, un seul recycling, un seul fichier de logs) et c'est le pattern recommandé pour iGO.
8.4.4 Mapping Status iGO → couple (EventType, Flags) AGE
C'est le cœur de la traduction entrante côté webhook receiver :
iGO Transport.status |
Inséré dans AGE comme |
|---|---|
Pending |
EventType=100, Flags=0 (Order accepted) |
Assigned |
EventType=103, Flags=0 (Vehicle assigned) — mais cf. FAQ #1 : pas de Vehicle.id à ce moment, donc StationNumber=null |
Retrieving |
(selon le mode group) EventType=104, Flags=0 ou rien |
Retrieved |
(selon le mode group) EventType=106, Flags=0 (Load confirmed) — c'est ici que le Vehicle.id arrive |
Storing |
EventType=108, Flags=0 (Unload permission) si group, sinon avancement standard |
Stored / Finished |
EventType=110, Flags=0 (Unload confirmed) |
Cancelled |
EventType=255, Flags=0 |
Aborted |
Flags=2003 ou 2004 selon contexte (cf. FAQ #2 : à enrichir via GET /api/vehicles/{id} pour récupérer errors[]) |
8.4.5 Avantages du pattern
✅ CstAGV livré tel quel, Gateway AGV Mecalux non modifiée. L'intégration iGO ne touche à aucun code EasyWMS — toute la spécificité iGO est encapsulée dans le composant côté flotte.
✅ RFT fallback préservé, notifications préservées, recherche de relocation préservée — toute la machinerie AGV continue à fonctionner.
✅ Découplage temporel : si iGO est down, EAG s'accumule et sera pompé à la reprise. Si la pompe sortante crashe, EasyWMS n'est pas impacté. Si le webhook receiver est down, iGO retransmet (FAQ #9).
✅ Pattern symétrique avec Galileo : Galileo a son EasyWMSGateway2015 côté flotte ; iGO aura son équivalent REST/HTTPS — même rôle, protocole différent.
8.4.6 Points de vigilance
⚠️ Pas d'équivalent natif EAG du final-source / final-destination : ces endpoints iGO sont consommés en réponse à un statut RequestSource / RequestDestination. Côté EAG, ils correspondent aux ré-exports Operation=Update avec CanPick=true / CanDrop=true → la pompe sortante doit reconnaître ce pattern et router vers le bon endpoint REST.
⚠️ Annulation après Retrieved (FAQ #6) : la pompe sortante doit, à la lecture d'un EAG Operation=Delete, vérifier le status iGO actuel (GET /api/transports/{id}). Si ≥ Retrieved → ne pas appeler /cancel et écrire un Flags d'erreur dans AGE pour notifier le WMS.
⚠️ Persistance : les tables EAG/AGE/AGS persistent dans la base EasyWMS — pas de risque de perte si le composant côté flotte crashe. Le BatchId permet de reprendre proprement.
8.4.7 Comparaison avec les services Gateway côté flotte historiques
Le middleware iGO à développer joue le même rôle que les services Gateway côté flotte que Mecalux a déjà développés pour d'autres protocoles. Comparaison côte à côte :
| Aspect | EasyWMSGateway2015 (Galileo TMS) |
EasyWMSGatewayRocla2015 (Rocla AGV) |
Pool IIS iGO (à développer) |
|---|---|---|---|
| Côté logique | Flotte (TCP frames ↔ hardware) | Flotte (TCP frames ↔ AGV Rocla) | Flotte (REST ↔ iGO PACS) |
| Forme | Service Windows | Service Windows | Pool IIS C# .NET 8 |
| Mode de communication aval | TCP socket binaire (port 3000) | TCP socket binaire (port 50011) | HTTPS REST (port 7002) |
| Pattern d'échange | Long-polling Search/Event/End | Messages q/m/n/s/b | POST + webhook callback |
| Format des messages | Frames GALILEO bas niveau | Frames Rocla propriétaires | JSON REST |
| Authentification | TokenUser dans MainObject.config |
(intégrée au protocole Rocla) | X-API-Key |
| Tables/storage côté flotte | (Galileo a son propre stockage) | SQLite locale (WCSROCLATASK) pour mapping interne |
(BDD partagée Mecalux uniquement) |
| Liaison côté Mecalux | (autre architecture) | Abonnement direct aux workflows (Galileo_SearchCreatedEventHandler_PR, etc.) — héritage EasyB |
Tables AGV_* (architecture moderne) |
| Configuration | MainObject.config |
Communications.config + JSON (Stations/Addresses/ContainerTypes/HeightTypes) |
appsettings.json ASP.NET Core |
| Logs | C:\ProgramData\Mecalux\EasyWMS Gateway 2015\Logs\AllLog.log |
C:\ProgramData\Mecalux\EasyWMS GatewayRocla 2015\Logs\ |
Logging ASP.NET (Serilog/log4net selon standard projet) |
| Architecture | Monolithique | Monolithique (Gateway Mecalux + middleware fusionnés) | Découplée via tables AGV_* |
| Statut | Existant | Existant (historique) | À développer par Mecalux |
💡 Architecture moderne vs historique : le pattern Rocla (
EasyWMSGatewayRocla2015) fusionnait la Gateway Mecalux et le middleware côté flotte en un seul service Windows monolithique qui s'abonnait directement aux workflows EasyWMS et écrivait sa propre base SQLite locale. Le pattern iGO respecte la séparation moderne : la Gateway AGV Mecalux (existant côté Mecalux) et la pool IIS C# (côté flotte) communiquent uniquement via les tablesAGV_*. C'est plus propre, plus testable, et permet de changer le fleet manager sans toucher à la Gateway Mecalux.💡 Recommandation projet : ne PAS partir d'un fork de
EasyWMSGatewayRocla2015(qui est dans l'ancienne architecture monolithique), mais bâtir la pool IIS iGO from scratch sur ASP.NET Core .NET 8, avec une dépendance unique vers la base intermédiaire (côté Mecalux) et une dépendance HTTP/REST vers iGO PACS (côté flotte). Cela donne un livrable plus simple, plus testable, et conforme aux standards Mecalux actuels.
9. FAQ STILL — réponses officielles
Réponses obtenues de STILL en avril 2026 sur les points clés d'intégration. Ces éléments ont valeur contractuelle et sont à intégrer aux workflows EasyWMS adaptés iGO.
FAQ #1 — Identifiant véhicule au passage à Assigned
Q. Lors du passage en état Assigned, le payload webhook contient-il l'identifiant du véhicule (sens iGO → EasyWMS) ?
R. STILL. Non, l'identifiant du véhicule n'est pas disponible au passage à Assigned. L'identifiant du véhicule fait partie du payload à partir du passage à l'état Retrieved.
Impact EasyWMS. Côté Gateway iGO : ne pas insérer la ligne AGE EventType=103 avec un StationNumber au passage à Assigned. Insérer uniquement EventType=103, Flags=0, StationNumber=null (vehicle assigned mais inconnu), puis attendre le passage à Retrieved pour insérer EventType=106 avec le Vehicle.id cette fois — ce qui déclenchera correctement ProcessEvent_TaskAssigned_PR côté core EasyWMS.
FAQ #2 — Erreurs en cas d'Aborted
Q. En cas d'Aborted, reçoit-on un code ou message d'erreur dans le payload ?
R. STILL. Non, nous recevons uniquement un POST avec l'état.
Impact EasyWMS. Le mapping vers les codes EasyWMS 2003 (extraction error) / 2004 (putaway error) / 2700 (wrong container) n'est pas dérivable du callback iGO seul. Côté Gateway iGO, à réception d'un Aborted :
- soit faire un
GET /api/vehicles/{id}complémentaire pour récupérererrors[].errorCode/errorLabeldu véhicule, et traduire dansFlagsde la ligne AGE ; - soit insérer un
Flagsgénérique (à définir, par ex.2003) et laisser une notification AGV « Aborted — investigation nécessaire » se déclencher.
FAQ #3 — Timestamp des événements
Q. Les événements webhook contiennent-ils un horodatage (timestamp) ?
R. STILL. Non.
Impact EasyWMS. Le Gateway iGO doit horodater à la réception (DateTime.UtcNow au moment du POST entrant) avant l'insertion en table AgeMessages (champ CreationDate). Sinon perte d'information pour le LMS / les KPI / l'audit.
FAQ #4 — Statut New
Q. Le statut New : quand apparaît-il et quelle est la différence avec Requested ?
R. STILL. Le statut New est un statut interne qui n'existe qu'un instant. Vous pouvez considérer que le premier statut est Requested.
Impact EasyWMS. Pas de gestion à prévoir pour New. Le mapping commence directement à Requested (= phase EasyWMS 100 / AgvStatus.Sent).
FAQ #5 — Création préalable des palettes (Load)
Q. Faut-il créer les palettes dans iGO (POST /api/loads) avant de créer un transport, ou peut-on inclure les infos palette directement dans la création du transport ?
R. STILL. Ce n'est pas nécessaire. Ni même souhaitable. Cela augmenterait la complexité de votre côté. Le seul cas d'usage que nous connaissons pour l'utilisation des Loads, ce serait dans le cas où le système qui reçoit les palettes est différent de celui qui crée le transport.
Impact EasyWMS. Le Gateway iGO ne doit PAS appeler POST /api/loads en amont du transport. Toutes les informations utiles de la palette (loadHostId = PalletId, dimensions, customMetaData reprenant HasTopper, PalletType, PalletSide etc.) sont passées directement dans l'objet load du payload POST /api/transports. Cela simplifie le Gateway et évite un point de défaillance supplémentaire.
FAQ #6 — Annulation après chargement
Q. Peut-on annuler un transport après que l'AGV a déjà pris la palette (état Retrieved) ?
R. STILL. Non.
Impact EasyWMS. Pas de modification du workflow EasyWMS AgvTask_SetCancelledTask_PR lui-même — il continue à écrire une ligne EAG Operation=Delete comme d'habitude. C'est le Gateway iGO qui, à la lecture de cette ligne, doit :
Status iGO courant du transport ?
├ Requested / Pending / Assigned / Retrieving
│ → POST /api/transports/{id}/cancel ✅
│ → Insère AGE EventType=255 quand iGO confirme l'annulation
│
├ Retrieved / Storing / Stored
│ → ❌ Cancel impossible côté iGO (limite STILL)
│ → Le Gateway répond NotifyError dans AGE (Flags spécifique)
│ → Le module AGV core notifie l'utilisateur via le notification group AGV
│ → Workflow alternatif côté process (attendre Finished + tâche retour, ou RFT)
│
└ Cancelled / Aborted / Finished → no-op (déjà terminal)
Cette logique est interne au Gateway iGO et n'impacte pas le custom EasyWMS.
FAQ #7 — Cas d'usage du suspended
Q. Le champ suspended : quel est son cas d'usage typique ?
R. STILL. Cela pourrait être utile si besoin de créer le transport avant que la palette ne soit disponible. Dans notre cas, je ne vois pas à quoi cela pourrait servir.
Impact EasyWMS. Champ à mettre à false par défaut dans tous les POST /api/transports. Pas de cas d'usage immédiat dans le mapping standard EasyWMS — pourrait éventuellement servir pour de la pré-réservation dans des scénarios spéciaux (e-commerce wave preparation, etc.) mais hors scope du custom AGV générique.
FAQ #8 — Authentification
Q. Authentification : faut-il utiliser X-API-Key ou Bearer token ?
R. STILL. X-API-Key.
Impact EasyWMS. Le Gateway iGO envoie systématiquement le header :
X-API-Key: <clé fournie par STILL>
Le Authorization: Bearer <token> mentionné dans certaines parties de la doc PACS est à ignorer. La clé est stockée chiffrée dans la config locale du Gateway (analogie : PasswordEncrypt.exe côté EasyWMSGateway2015).
FAQ #9 — Politique de retry des webhooks
Q. En cas d'indisponibilité de notre serveur webhook, iGO retente-t-il l'envoi des événements ? Si oui, selon quelle politique ?
R. STILL. iGO retente l'envoi mais nous ne savons pas à quelle fréquence. À tester.
Impact EasyWMS. Le Listener du Gateway iGO doit être idempotent : si iGO renvoie le même event 2 fois, ne pas insérer deux lignes dans AGE. Idempotency-key suggérée :
transport.id + transport.statuspour les events de transport ;vehicle.id + vehicle.statuspour les events véhicule (sans timestamp natif — cf. FAQ #3).
À implémenter via une table de déduplication interne au Gateway (cache rolling de quelques minutes), ou un index unique sur (OrderExtId, Phase) côté AgeMessages.
⚠️ Action de test à mener : pendant la phase d'intégration, simuler un Gateway iGO en panne pendant 30 s / 1 min / 5 min et observer le comportement réel d'iGO (nombre de retries, intervalles, abandon).
FAQ #10 — Persistance après redémarrage iGO
Q. Les données de transport survivent-elles à un redémarrage iGO, ou sont-elles uniquement en mémoire vive ?
R. STILL. Oui, les données survivent à un redémarrage du système.
Impact EasyWMS.
- Bonne nouvelle : pas besoin de re-pousser tous les transports en cours après un reboot iGO.
- Cependant : les subscriptions webhook étaient marquées « all transports that are still in the memory of E'tricc » dans la doc PACS § 2.2.1. Donc à clarifier : les abonnements survivent-ils aussi ? Si non, le Gateway doit ré-appeler
POST /api/transports/subscriptionau redémarrage. - Recommandation : au boot du Gateway iGO, toujours :
- Appeler
GET /api/systempour voir si la subscription existe. - La (re)créer si absente.
- Faire un
GET /api/transportspour réconcilier — comparer l'état iGO avec les transports en cours côté tables EAG/AGE et générer les lignes AGE manquantes si nécessaire.
- Appeler
FAQ #11 — Communication directe ou via iGo Flow
Q. Communique-t-on directement avec l'API PACS ou via iGo Flow ?
R. STILL. Directement avec l'API PACS.
Impact EasyWMS. Pas de couche d'orchestration intermédiaire « iGo Flow » à intégrer. Le Gateway iGO appelle directement https://[IP]:7002/api/... en HTTPS. Architecture simplifiée :
EAG/AGE/AGS ──▶ Gateway iGO ──HTTPS REST──▶ PACS Host API ──▶ iGo / E'tricc ──▶ AGV
▲
│
(pas d'iGo Flow intermédiaire)
Synthèse FAQ — points-clés à intégrer dans le Gateway iGO
| # | Règle dérivée |
|---|---|
| 1 | N'insérer le StationNumber (= Vehicle.id) dans AGE qu'à partir de Retrieved (pas dès Assigned) |
| 2 | Pour les Aborted, enrichir via GET /api/vehicles/{id} (errors[]) avant d'insérer la ligne AGE |
| 3 | Horodater (CreationDate) chaque insertion AGE à la réception du callback |
| 4 | Ignorer New |
| 5 | Ne PAS appeler POST /api/loads en amont — passer les infos palette dans le transport |
| 6 | À la lecture d'un EAG Operation=Delete, vérifier le status iGO courant : refuser si ≥ Retrieved et générer un Flags d'erreur dans AGE |
| 7 | suspended = false par défaut dans POST /transports |
| 8 | Header X-API-Key (jamais Bearer) |
| 9 | Listener idempotent (transport.id + status comme clé de déduplication) |
| 10 | À chaque boot du Gateway : vérifier subscriptions + réconcilier transports via GET /transports |
| 11 | Pas de couche iGo Flow — appel direct port 7002 |
Annexes
A. Glossaire rapide
| Sigle | Signification |
|---|---|
| iGO easy | Fleet manager AGV STILL (KION Group) — variante simple |
| PACS | Productized Automated Concept Solutions — offre KION large couvrant iGO et au-delà |
| E'tricc | Moteur interne du fleet manager (apparaît dans la doc PACS) |
| MyMA | Suite logicielle KION : Vue3 + .NET8 + Postgres — héberge iGO côté admin |
| EXV CB iGo | Modèle physique — gerbeur électrique automatisé STILL |
| TLS 1.2 | Niveau de chiffrement requis sur le port 7002 |
| X-API-Key | Authentification API officielle (FAQ #8) |
| iGo Flow | Couche d'orchestration STILL — non utilisée dans l'intégration directe (FAQ #11) |
B. Pointeurs sources
| Document | Section utile |
|---|---|
2510_PACS-2.3-Host-Interface-Technical-Specifications_en-US--STILL-.pdf |
Toute l'API REST (chap. 1-8) |
iGo easy 2.3 - Host Interface Specifications.pdf |
Identique à PACS — confirmant que iGO easy = produit dérivé du même moteur |
IT requirements R1 20250929.pdf |
Stack, ports, hardware |
Technical specification EXV CB iGo.pdf |
Datasheet véhicule |
Limagrain-LWM_Std_Interface_Compliance.xlsx |
Matrice de compliance projet — à exploiter manuellement (binaire non lu) |
C. Cross-référence avec le module AGV EasyWMS
Pour le détail du module AGV EasyWMS qui sert de point de comparaison ici, voir le document compagnon CR_ModuleAGV.md dans le dossier CstAGV/.