Files
mcp-wms-wiki/wiki/limagrain/05-agv/still-igo-integration.md
T
arthur 7496aafe64 lint(limagrain): corrections completes Phase 1+2
- Bloquants: mermaid 03-picking/_index reconstitue (archive 11-05), 13 liens vers pages squelette retires, 2 liens recibles (anoxie, application-dictionary)
- Conventions: 910 em dashes -> tirets simples, 145 checklists -> puces question, 13 questions resolues barrees
- Liens: 9 ancres reparees (slugs GitHub)
- Delta: 12 standard_ref remappes, blocs Standard EasyWMS + sections References ajoutes, front matter complete
- Glossaire: 15 termes standard deplaces en section rappel avec renvoi
- Rapport: limagrain/_lint_report.md (Phase 1 + Phase 2 + re-scan final)
- Inclut les pages des sessions precedentes non commitees + CLAUDE.md et consume.log en l'etat
2026-07-20 12:56:42 +02:00

33 KiB

title, tags, status, standard_ref, jira_refs, confluence_refs, sources, last_updated, author
title tags status standard_ref jira_refs confluence_refs sources last_updated author
Intégration Still iGo - API PACS et architecture
agv
still
igo
pacs
api
integration
architecture
draft modules/agv.md
LIM-103
LIM-104
CR technique - iGO STILL - fonctionnement et flux API + correspondance avec le module AGV EasyWMS Opus 4.7 v1.md
Jira LIM-103 (lecture directe 2026-07-20)
Jira LIM-104 (lecture directe 2026-07-20)
2026-07-20 Arthur

Intégration Still iGo - API PACS et architecture

Résumé : documentation complète de l'intégration du fleet manager iGO easy (STILL / KION Group) avec EasyWMS chez Limagrain. Couvre l'API REST PACS 2.3, le cycle de vie des transports, le mapping avec le module AGV standard, l'architecture cible à 4 composants et les réponses FAQ STILL contractuelles.

Standard EasyWMS : → voir AGV - Automated Guided Vehicles Le standard communique par tables d'échange DB (EAG/AGE/AGS). Chez Limagrain, iGO easy remplace le protocole historique par une API REST HTTPS - un middleware (pool IIS C#) assure la traduction.

Contexte projet

Limagrain utilise des AGV Still EXV CB iGo (gerbeurs électriques automatisés) pour les transports internes entre images de quai, PIE, postes de picking et zones de stockage. Le fleet manager est iGO easy (variante simplifiée de PACS - Productized Automated Concept Solutions), motorisé par le moteur interne E'tricc.

La communication est 100 % REST HTTPS (port 7002, TLS 1.2) - pas de PLC ni de tables d'échange SQL directes entre WMS et iGO. Le modèle est pull + push : le WMS pousse les ordres (POST /transports), iGO pousse les changements d'état via webhook (callback POST vers une URL exposée par le WMS).

Vue d'ensemble iGO / PACS

flowchart LR
    subgraph WMS["Hôte (EasyWMS)"]
      EasyWMS["EasyWMS + CstAGV"]
    end

    subgraph FleetMgr["iGO easy / PACS Fleet Manager"]
      Etricc["Moteur E'tricc"]
      MyMA["MyMA admin UI"]
      Etricc <--> MyMA
    end

    subgraph Fleet["Flotte AGV"]
      EXV["EXV CB iGo<br/>(gerbeur ~3.4m)"]
    end

    EasyWMS <-->|"HTTPS REST<br/>port 7002<br/>TLS 1.2 + X-API-Key"| Etricc
    Etricc -.->|"callback POST<br/>vers WMS"| EasyWMS
    Etricc <--> Fleet

Concepts clés :

  • Pas de notion de routes/segments côté WMS : iGO ne demande qu'une sourceLocation et une destinationLocation - la trajectoire physique est gérée par iGO en interne.
  • Décision tardive (Group / decision point) : si la destination exacte est inconnue à la création, on donne un destinationGroupId. iGO place le transport en RequestDestination et interroge le WMS quand l'AGV arrive au point de décision.
  • Load = container EasyWMS - passé directement dans le payload de création du transport (pas de POST /api/loads préalable - FAQ #5).

Stack technique iGO (MyMA)

Composant Détail
Backend .NET 8.0 (C#)
Frontend Vue 3.2
Base de données Postgres 12+ (défaut), SQL Server 2019 ou MySQL 8.0
OS serveur Windows 11/Server 2016-2022, Ubuntu 18.04
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

Ports réseau

Service Port
Front-end admin MyMA 82
Backend REST interne 50005
API Host (HTTPS REST) 7002
Postgres 5432

Véhicule - Still EXV CB iGo

Gerbeur électrique automatisé (EXV = Elektro-Vertikal) - se déplace sur ses propres roues et lève la charge avec le mât. Pas de couloir mécanique ni de canal compact.

Caractéristique Valeur
Longueur totale (l1) 3 383 mm
Longueur jusqu'au dosseret (l2) 2 083 mm
Largeur tablier fourche 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

Modèle de ressources API

L'API PACS 2.3 expose 8 ressources :

Ressource iGO Équivalent EasyWMS Description
Transport AgvTask L'ordre de transport (le cœur)
Vehicle AGV station (type 65) Le véhicule physique
Load Container / LPN La charge physique
LoadType ContainerType Catalogue de types de charge
Location Location (IRealLocation) Point physique du warehouse
Group WorkingZone Ensemble de locations (décision tardive)
System - État global + abonnements

Champs clés du Transport

Champ iGO Type Équivalent EasyWMS
id string (généré par iGO)
transportHostId string OrderExtId (= Task.TaskNumber)
sourceLocationId / sourceGroupId string LoadLocation
destinationLocationId / destinationGroupId string UnloadLocation
load Load Container (PalletId, type, dimensions)
priority int 0-10 Priority 0-4 (conversion inversée)
suspended bool (pas d'équivalent - false par défaut)
customMetaData dict HasTopper, PalletType, etc.
status enum AgvStatus (mapping § ci-dessous)

Champs clés du Vehicle

Champ Type Description
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 temps réel
batteryLevel int % batterie
errors array Codes/labels d'erreur

Inventaire des endpoints API

Tous sur https://[IP]:7002/api/... avec header X-API-Key.

Transports

Verbe URL Effet
GET /api/transports Liste des transports en mémoire
POST /api/transports Créer un transport
GET /api/transports/{id} Détail d'un transport
POST /api/transports/{id}/final-destination Fixer destination finale (group → location)
POST /api/transports/{id}/final-source Fixer 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 priorité
POST /api/transports/subscription?callbackUrl=… S'abonner aux events transport
DELETE /api/transports/subscription?callbackUrl=… Se désabonner

Vehicles

Verbe URL Effet
GET /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
POST /api/vehicles/restart Redémarrer la flotte
POST /api/vehicles/subscription?callbackUrl=… S'abonner aux events vehicle

Autres

Verbe URL Effet
GET /api/system Status global + subscriptions
GET /api/groups / /{id} Lecture des groupes
GET /api/loads / /{id} Lecture des loads
POST /api/loads Créer une load (non recommandé - FAQ #5)
GET /api/locations / /{id} Lecture des locations
GET /api/load-types Catalogue des types

Endpoints callback côté WMS (webhook receiver)

URL côté WMS Body reçu Déclenchement
POST /agv/transport-event Objet Transport complet Changement d'état transport
POST /agv/vehicle-event Objet Vehicle complet Changement d'état véhicule

Cycle de vie d'un Transport

flowchart TD
    Req[Requested] --> Pen[Pending]
    Pen --> Asg[Assigned]
    Asg -->|source = Group| RS[RequestSource]
    Asg -->|source = Location| Ret[Retrieving]
    RS -->|final source set| Ret
    RS -->|AGV arrivé sans réponse| WS[WaitSource]
    WS -->|final source set| Ret
    Ret --> Rtd[Retrieved]
    Rtd -->|dest = Group| RD[RequestDestination]
    Rtd -->|dest = Location| Sto[Storing]
    RD -->|final dest set| Sto
    RD -->|AGV arrivé sans réponse| WD[WaitDestination]
    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

États terminaux : Finished, Cancelled, Aborted.

⚠️ Le statut New est un état interne instantané d'iGO - il n'apparaît jamais dans les callbacks. Le premier état observable est Requested (FAQ #4).

Mapping états iGO → phases EasyWMS

iGO Transport.status Phase AGV EasyWMS AgvStatus Notes
Requested - (après POST) Premier état observable
Pending 100 (Order accepted) Sent En file d'attente iGO
Assigned 103 (Vehicle assigned) (Sent) ⚠️ Pas de Vehicle.id dans le payload (FAQ #1)
RequestSource 104 (Load permission) PendingToBeLoad Uniquement en mode Group
Retrieving - (Sent) AGV en route / chargement
Retrieved 106 (Load confirmed) (Sent) Vehicle.id disponible ici (FAQ #1)
RequestDestination 108 (Unload permission) PendingToBeUnload Uniquement en mode Group
Storing - - AGV en dépose
Stored / Finished 110 (Unload confirmed) (purge) Transport terminé
Cancelled 255 (Cancelled) Annulé
Aborted 255 (Cancelled) Erreur irrécupérable - aucun code d'erreur dans le payload (FAQ #2)

Différence sémantique majeure : CanPick / CanDrop

Le standard EasyWMS attend une demande explicite d'autorisation (phases 104 / 108) quand CanPick / CanDrop sont à false. iGO ne demande l'autorisation qu'au point de décision d'un Group. Si la source/destination est une Location connue dès la création, iGO exécute directement sans demander d'autorisation.

Pour reproduire le comportement EasyWMS dans iGO, il faut forcer l'usage de Groups (même mono-location) là où EasyWMS aurait CanPick = false.

Conversion de priorité

EasyWMS iGO Suggestion
0 - Urgent 10 - Highest mapping direct
1 - High 8
2 - Normal 5
3 - Low 3
4 - VeryLow 1

Flux nominal - création et exécution

sequenceDiagram
    autonumber
    participant WMS as EasyWMS
    participant iGO as iGO easy
    participant V as Vehicle

    WMS->>iGO: POST /api/transports
    iGO-->>WMS: 200 OK (status=Requested)
    iGO->>WMS: callback (Pending)
    iGO->>V: assigne véhicule
    iGO->>WMS: callback (Assigned)
    V->>iGO: arrivé source
    iGO->>WMS: callback (Retrieving)
    V->>iGO: chargé
    iGO->>WMS: callback (Retrieved)
    V->>iGO: arrivé destination
    iGO->>WMS: callback (Storing)
    V->>iGO: déchargé
    iGO->>WMS: callback (Stored → Finished)

Flux avec décision tardive (Group)

sequenceDiagram
    autonumber
    participant WMS
    participant iGO
    participant V as Vehicle

    WMS->>iGO: POST /api/transports {destinationGroupId}
    iGO-->>WMS: 200 OK (Requested)
    iGO->>WMS: callback (Assigned → Retrieving → Retrieved)
    V->>iGO: arrivé au decision point
    iGO->>WMS: callback (RequestDestination)
    WMS->>iGO: POST /final-destination {destinationId}
    iGO-->>WMS: 200 OK
    iGO->>WMS: callback (Storing → Stored → Finished)

⚠️ Si le WMS ne répond pas assez vite, iGO bascule de RequestDestination vers WaitDestination (AGV arrivé et en attente). Symétrique côté source : RequestSourceWaitSource.

Annulation

Un transport ne peut pas être annulé après l'état Retrieved (FAQ #6). Si un cancel arrive côté WMS après Retrieved, deux options : attendre Finished puis créer une tâche retour, ou intervenir manuellement.

Sécurité et abonnements

Authentification

X-API-Key (confirmé par STILL - FAQ #8). Le header Authorization: Bearer mentionné dans certaines parties de la doc PACS est obsolète. La clé est fixe, fournie par le PM STILL, stockée chiffrée dans la config du middleware.

TLS

HTTPS avec TLS 1.2. Certificats auto-signés côté iGO - le WMS doit les truster explicitement (import dans le keystore).

Modèle d'abonnement

Au démarrage du WMS :

  1. POST /api/transports/subscription?callbackUrl=https://wms/agv/events/transport
  2. POST /api/vehicles/subscription?callbackUrl=https://wms/agv/events/vehicle

À l'arrêt : DELETE sur les mêmes URLs. Le endpoint callback doit être en HTTPS, retourner 200 OK rapidement (< 1s), traitement asynchrone derrière. Le listener doit être idempotent : clé de déduplication = transport.id + status (FAQ #9).

Mapping erreurs iGO → EasyWMS

Code EasyWMS Famille Équivalent iGO
1001-1014 Configuration HTTP 400 BadRequest à la création
2003 Extraction error Transport.status = Aborted + Vehicle.errors[]
2004 Putaway error idem
2005 Manual cancel Transport.status = Cancelled en callback
2500-2503 Communication Erreurs HTTP 5xx / timeouts
2700 Wrong container Vehicle.errors[] + status = Faulted

⚠️ Le payload Aborted ne contient aucun code d'erreur (FAQ #2). Pour enrichir le Flags AGE, il faut faire un GET /api/vehicles/{id} complémentaire pour récupérer errors[].errorCode.

Mapping verbes / opérations

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 POST /priority, /final-source, /final-destination
Annuler un ordre Operation = Delete + ligne EAG POST /api/transports/{id}/cancel
Suspendre un ordre (pas d'équivalent) POST /suspend
Reprendre un ordre (pas d'équivalent) POST /release
Suspendre la flotte (pas d'équivalent) POST /api/vehicles/suspend
Auth load EAG Update (CanPick=true) POST /final-source
Auth unload EAG Update (CanDrop=true) POST /final-destination

Architecture cible - Pattern à 4 composants

Principe directeur

EasyWMS communique avec les fleet managers externes via une base intermédiaire (5 tables). Côté Mecalux, la Gateway AGV (existante) mediate entre les workflows et les tables. Côté flotte, un middleware à développer (pool IIS C# .NET 8) traduit les tables vers/depuis l'API REST PACS.

Le custom CstAGV n'est pas modifié. L'intégration iGO consiste uniquement à fournir le middleware.

flowchart LR
    subgraph EasyWMS["EasyWMS (existant)"]
      Process[Process<br/>Putaway/Picking/Shipping]
      AgvCore[Module AGV core<br/>+ CstAGV]
      GwMec[Gateway AGV Mecalux<br/>workflows ↔ tables]
    end

    subgraph DB["Base intermédiaire"]
      OQ[(AGV_OUTPUTQUEUE)]
      EAG[(AGV_EAG)]
      IQ[(AGV_INPUTQUEUE)]
      AGE[(AGV_AGE)]
      AGS[(AGV_AGS)]
    end

    subgraph Pool["Pool IIS C# .NET 8 - À DÉVELOPPER"]
      Pump[Pompe sortante<br/>poll OUTPUTQUEUE → API iGO]
      Hook[Webhook receiver<br/>callbacks iGO → tables]
    end

    subgraph KION["iGO / PACS (STILL)"]
      iGO[API REST port 7002]
    end

    Process --> AgvCore --> GwMec
    GwMec --> OQ & EAG
    GwMec -.poll.-> IQ & AGE & AGS
    Pump -.poll.-> OQ
    Pump -.lit.-> EAG
    Pump -->|HTTPS X-API-Key| iGO
    iGO -.webhook.-> Hook
    Hook --> IQ & AGE & AGS

Composants existants - RIEN à modifier

Composant Rôle Statut
CstAGV (workflows) Logique métier AGV Existant
Gateway AGV Mecalux Mediator workflows ↔ tables Existant
Tables AGV_* (5) Base intermédiaire Existantes
Vues SmartUI AGV Monitoring opérateur Existantes

Middleware pool IIS - seul livrable nouveau

Aspect Description
Forme Pool IIS C# ASP.NET Core (.NET 8.0)
Hébergement Serveur Mecalux (co-localisé ou VM séparée)
Rôle Pompe sortante + webhook receiver dans un service unique
Accès BDD Connection vers les 5 tables AGV_*
Sécurité X-API-Key sortant + HTTPS entrant (TLS 1.2)

Pompe sortante (OUTPUTQUEUE → API iGO)

Polling régulier (1-5 s) sur AGV_OUTPUTQUEUE WHERE processedDate IS NULL ORDER BY creationDate ASC. Pour chaque ligne : récupère batchId → lit AGV_EAG → interprète l'Operation (C/U/D) → appel REST iGO. Après ack synchrone (200 OK) : marque processedDate.

Webhook receiver (callbacks → tables)

Controller ASP.NET Core exposant deux endpoints HTTPS. À réception : insert dans AGV_INPUTQUEUE → insert dans AGV_AGE ou AGV_AGS avec le mapping Status → EventType/Flags (cf. tableau ci-dessous). Horodatage DateTime.UtcNow à la réception (iGO ne fournit pas de timestamp - FAQ #3).

Mapping Status iGO → (EventType, Flags) AGE

iGO Transport.status EventType Flags Notes
Pending 100 0 Order accepted
Assigned 103 0 Vehicle assigned - StationNumber=null (FAQ #1)
Retrieved 106 0 Load confirmed - Vehicle.id disponible ici
Stored / Finished 110 0 Unload confirmed
Cancelled 255 0 Annulé
Aborted - 2003/2004 À enrichir via GET /api/vehicles/{id} (FAQ #2)

Pattern de boot du middleware

À chaque démarrage :

  1. Vérifier la base intermédiaire accessible
  2. Vérifier l'API iGO : GET /api/system
  3. Vérifier les subscriptions actives - (re)créer si absentes
  4. Réconcilier les transports : GET /api/transports vs AGV_OUTPUTQUEUE non acquittées → générer les lignes AGE manquantes
  5. Démarrer le polling sortant

Logique d'annulation côté middleware

À la lecture d'un EAG Operation=Delete, le middleware doit vérifier le status iGO courant :

  • Requested / Pending / Assigned / RetrievingPOST /cancel
  • Retrieved / Storing / Stored Cancel impossible (FAQ #6) → écrire un Flags d'erreur dans AGE → notification opérateur → fallback (attendre Finished + tâche retour, ou RFT)
  • Cancelled / Aborted / Finished → no-op (déjà terminal)

Refus WMS de l'annulation quand le support est sur un AGV (LIM-104)

Statut : préprod ; revue de code validée le 23/06/2026 (Vincent Charvet).

Problème (découvert aux tests STILL) : si on annule / supprime une Task AGV alors que le support est déjà pris par l'AGV (transport iGO >= Retrieved), iGO refuse l'annulation et termine physiquement la mission - mais le WMS a déjà supprimé la Task au moment de la demande. ProcessEvents_PR s'arrête alors sur sa garde CST Get Task (« CST Task exists » = false) pour toutes les AGE suivantes :

  • l'AGE 255/1009 ne déclenche jamais ProcessError1009notification opérateur du refus perdue ;
  • l'AGE 110 (Unload confirmed) ne déclenche jamais ContainerMovesupport figé sur l'AGV.

Solution : souscription preview sur la commande de suppression / annulation de Task. Avant exécution :

  1. récupérer le support (container) associé à la Task ;
  2. vérifier s'il est sur un AGV - critère retenu Container.StationType == Agv (équivalent métier de « palette physiquement sur l'AGV » = iGO >= Retrieved ; repli possible : LocationCode commençant par AGV_) ;
  3. si sur AGVrefuser la commande (exception) avec message opérateur explicite. La Task reste vivante, l'AGV termine sa mission, le support est livré à destination ;
  4. sinon (support encore à la source ou déjà déposé) → laisser la commande s'exécuter normalement.
Élément AD Type Rôle
CST_TaskCancel_CheckAgv Subscription Appelle le WF à l'annulation d'une tâche
CST_TaskDelete_CheckAgv Subscription Appelle le WF à la suppression d'une tâche
CST_CancelTask_CheckForAgv Workflow Récupère la tâche annulée / supprimée ; si le conteneur est sur un emplacement AGV, lève une erreur (numéro de tâche + code conteneur)
CST_CancelTask_NotPossible_2 Ressource FR « Impossible de supprimer la tâche {0} car le conteneur {1} est sur un AGV » / EN « Cannot delete task {0} because container {1} is on AGV »

Cas de test : (1) annulation après pickup (>= Retrieved) → refusée, support livré, Task Finished ; (2) annulation avant pickup (< Retrieved) → acceptée, EAG D, middleware POST cancel iGO 204.

Comparaison avec les Gateways historiques

Aspect EasyWMSGateway2015 (Galileo) GatewayRocla2015 Pool IIS iGO
Communication aval TCP socket (port 3000) TCP socket (port 50011) HTTPS REST (port 7002)
Format messages Frames GALILEO bas niveau Frames Rocla propriétaires JSON REST
Auth TokenUser dans config Intégrée au protocole X-API-Key
Architecture Monolithique Monolithique (Gateway + middleware fusionnés) Découplée via tables AGV_*
Liaison Mecalux (autre architecture) Abonnement direct WF (héritage EasyB) Tables AGV_* (archi moderne)

La pool IIS iGO ne doit pas être un fork de GatewayRocla2015 (ancienne architecture monolithique). Développement from scratch sur ASP.NET Core .NET 8 recommandé.

Workflows EasyWMS - impact iGO

Avec le pattern Gateway iGO + tables AGV_*, 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 middleware.

⚠️ Réserve (LIM-103, préprod) : ce tableau reflète l'hypothèse de conception. À l'implémentation, plusieurs bugs du module AGV standard Mecalux ont dû être corrigés (dispatch d'events cassé par la transformation Gateway phase + 100, attributs canPick/canDrop jamais assignés, events 106/110 non gérés, refus de mission iGo). Détail : Corrections des bugs du module AGV standard (LIM-103).

Workflow Comportement avec Gateway iGO
MovementCreatedEventHandler_PR Inchangé - déclencheur
AgvTask_CreateTaskFromMovement_PR Inchangé
SerializeAgvTasks_PR Inchangé - écrit EAG, le middleware lit et POST
ProcessEvents_PR + ProcessEvent_*_PR ⚠️ Modifié (LIM-103) - patch dispatch phase+100, gestion events 106/110, refus mission, fix canPick/canDrop
ProcessErrors_PR Inchangé - réagit aux Flags dans AGE
Agvtask_CanPick/CanDrop_PendingToBeSent_PR Inchangé - écrit EAG, le middleware appelle /final-source ou /final-destination
TaskCanceledEventHandler_PR Inchangé - écrit EAG Delete, le middleware gère
Workflows RFT Inchangés - fallback préservé

Corrections des bugs du module AGV standard (LIM-103)

Statut : préprod ; revue de code à faire (@Vincent, 30/06/2026), assignée Vincent Charvet. Ticket regroupant les corrections nécessaires pour faire fonctionner le module AGV standard sur ce projet.

Queries standard corrigées

  • Equipment_AgvTask_GetTask_ByWorkingZone_UI : correction d'une null exception sur query standard.
  • Equipment_AgvTask_LoadEquipment_UI : correction d'un paramètre erroné sur query standard.

Dispatch d'events cassé par la transformation Gateway phase + 100

Bug de cohérence Mecalux entre la Gateway et le module AGV. Le record agvEvent reçu par ProcessEvents_PR est un GalileoEventCreatedWF dont le champ EventType (Integer) porte la valeur SIMO de la Gateway, alors que la DecisionActivity « Event type » de ProcessEvents_PR dispatche sur les valeurs natives 100 / 103 / 104 / 108.

Chaîne du bug :

  • le middleware écrit phase = 104 dans agv_age.phase ;
  • la Gateway lit la ligne et pose EventType = phase + 100 = 204 (avec Extension[PHASE] = 104) ;
  • ProcessEvents_PR reçoit EventType = 204 ≠ 100/103/104/108 → default silencieux → workflow Completed sans side-effect (silent fail).

Fix : patch de l'activité « Check parameters » de ProcessEvents_PR (soustraction de 100 pour retrouver la valeur native).

canPick / canDrop jamais assignés (LoadPermission / UnloadPermission)

Bug majeur du standard : dans ProcessEvent_LoadPermission_PR, l'attribut interne canPick (InitialValue vide) n'est jamais assigné. La DecisionActivity « Can pick? » prend donc toujours la branche Otherwise No → End, et le sous-workflow Agvtask_CanPick_PendingToBeSent_PR (qui pose CanPick = true) n'est jamais appelé. Même défaut dans ProcessEvent_UnloadPermission_PR (attribut canDrop).

Workflow État Logique
ProcessEvents_PR OK (après patch -100) Dispatch sur EventType == 100/103/104/108
Agvtask_CanPick_PendingToBeSent_PR OK CanPick = true hardcodé, fait le flip
SetAgvStatus_PR OK if CanPick && CanDrop → Sent ; elif CanPick → PendingToBeUnload ; else → PendingToBeLoad
ProcessEvent_LoadPermission_PR / ProcessEvent_UnloadPermission_PR BUGGÉ canPick / canDrop jamais assigné → branche No systématique

Fix : remplacer l'expression de la condition Yes de la DecisionActivity par !agvTask.CanPick (resp. !agvTask.CanDrop), qui teste directement la propriété de l'AgvTask récupérée par « Get AGV task ». En l'état, le standard Mecalux est inutilisable pour le flow LoadPermission / UnloadPermission.

Events 106 / 110 non gérés (fix temporaire)

Le standard ne gère pas les events 106 (déplacer le support sur l'AGV) et 110 (déplacer le support de l'AGV vers son emplacement de destination). Fix temporaire (Michael Chaudier, 29/05) : ProcessEvents_PR gère désormais les events 106 (confirmation load) et 110 (confirmation unload), avec ajout des commandes de déplacement du support - chargement sur l'AGV à l'event 106, déchargement à la destination de la tâche à l'event 110.

Refus de mission iGo

Ajout (Arthur, 01/06) d'une condition dans ProcessEvents_PR pour gérer le refus de mission par iGo → annulation de la tâche AGV ; la transition « sequence 0 » est modifiée pour ne pas catcher cette erreur (non gérée par le sous-workflow) tant qu'aucun flag d'erreur n'est levé.

Génération du mouvement PS → position PK

Container_MovedEventHandler_PS_PR modifié (Vincent, 02/06, commit 9fa84a83e2) pour générer le mouvement des PS vers la bonne position du PK (première position libre). Logique conservée pour la recertification et l'échantillonnage.

Ce même handler est ensuite spécialisé : redirection selon le type de tâche au picking (voir Placement PS → PK, LIM-82) et placement à la position X max de l'image de quai à l'expédition (voir Assignation automatique de l'image de quai, LIM-94). LIM-103 en pose la base (première position libre).

FAQ STILL - réponses contractuelles

Réponses obtenues de STILL en avril 2026. Valeur contractuelle.

# Question Réponse Impact
1 Vehicle.id dès Assigned ? Non, seulement à partir de Retrieved Insérer StationNumber dans AGE uniquement à partir de Retrieved
2 Code d'erreur dans payload Aborted ? Non, juste le statut Enrichir via GET /api/vehicles/{id} (errors[])
3 Timestamp dans callbacks ? Non Horodater à la réception (DateTime.UtcNow)
4 Statut New vs Requested ? New = interne instantané, traiter Requested comme premier état Ignorer New
5 Créer la Load avant le Transport ? Non, passer les infos dans le transport Ne PAS appeler POST /api/loads
6 Annulation après Retrieved ? Non Vérifier status iGO avant cancel
7 Cas d'usage de suspended ? Pré-création transport avant dispo palette suspended = false par défaut
8 X-API-Key vs Bearer ? X-API-Key Jamais Bearer
9 Retry webhook en cas d'indispo ? Oui, mais fréquence inconnue Listener idempotent (transport.id + status)
10 Persistance après reboot iGO ? Oui Boot : vérifier subscriptions + réconcilier via GET /transports
11 Communication directe ou via iGo Flow ? Directe avec l'API PACS Pas de couche iGo Flow

Points encore ouverts avec STILL

# Sujet Statut
3b Fréquence des vehicle/event (pose updates) Ouvert
5b customMetaData (taille, caractères, ré-émis ?) Ouvert
6b Création/modification de Location via API Ouvert (API GET only)
7b Pallet Shuttle (LoadType = 1) Ouvert
8b Multi-warehouse Ouvert
9b HasTopper (attribut véhicule) Ouvert

Points d'attention

⚠️ CanPick/CanDrop : pour reproduire le standard EasyWMS, forcer l'usage de Groups même mono-location.

⚠️ Priorité inversée : EasyWMS 0=Urgent, iGO 10=Max - conversion à coder dans le middleware.

⚠️ Pas de routing exposé : iGO gère ses routes en interne - pas d'équivalent à "Routes between stations" en EasyS, pas d'erreur "Disabled route" côté iGO.

⚠️ Annulation après chargement impossible : la logique AgvTask_SetCancelledTask_PR qui déclenche la recherche de relocation après chargement n'a plus de sens dans le mapping iGO. Le WMS refuse désormais l'annulation en amont via la souscription preview LIM-104 (voir Refus WMS de l'annulation…).

⚠️ Tests de charge webhook à mener : simuler Gateway iGO down pendant 30s / 1min / 5min pour observer le comportement réel d'iGO (retries, intervalles, abandon).

Capacités nouvelles iGO (hors standard EasyWMS)

  • Suspend / Resume / Restart d'une flotte ou d'un véhicule individuel
  • Pose temps réel (x, y, orientation) → dashboard live possible
  • Battery level → seuils de notification possibles

Questions ouvertes

  • Fréquence des callbacks vehicle/event pour les mises à jour de position - risque de flood (@Nicolas)
  • Taille max et caractères autorisés dans customMetaData (@STILL)
  • Les customMetaData sont-elles ré-émises dans les callbacks transport ? (@STILL)
  • Création/modification de Location via API iGO - limité à GET pour l'instant (@STILL)
  • Gestion Pallet Shuttle via iGO (LoadType = 1) - hors scope actuel ? (@Théo)
  • Multi-warehouse : iGO suppose un seul site - impact si extension future ? (@Michael)

Historique des modifications

Date Auteur Modification
2026-05-12 Arthur Création initiale depuis CR technique iGO STILL
2026-07-20 Arthur Intégration LIM-103 (corrections bugs module AGV standard, préprod, revue de code à faire) : nouvelle section (2 queries standard corrigées, dispatch d'events cassé par phase+100, canPick/canDrop jamais assignés dans LoadPermission/UnloadPermission, events 106/110 non gérés, refus de mission iGo, Container_MovedEventHandler_PS_PR première position libre) ; réserve ajoutée sur le tableau « workflows inchangés » (ligne ProcessEvents_PR = Modifié) ; front matter jira_refs/sources/last_updated
2026-07-20 Arthur Intégration LIM-104 (refus WMS annulation/suppression Task si support sur AGV, préprod, revue validée 23/06) : sous-section sous « Logique d'annulation » (désync task supprimée avant refus iGo, souscription preview, critère Container.StationType == Agv, table AD CST_TaskCancel_CheckAgv/CST_TaskDelete_CheckAgv/CST_CancelTask_CheckForAgv/CST_CancelTask_NotPossible_2, cas de test) ; cross-ref depuis le point d'attention « Annulation après chargement impossible » ; jira_refs +LIM-104

Références

Source Type Date
CR technique iGO STILL - fonctionnement et flux API v1 CR technique 2026-04-28
LIM-103 Ticket Jira (corrections bugs module AGV standard - préprod, revue à faire, commit 9fa84a83e2) 2026
LIM-104 Ticket Jira (refus annulation Task si support sur AGV - préprod, revue validée 23/06) 2026
2510_PACS-2.3-Host-Interface-Technical-Specifications Spec API STILL 2025-10
iGo easy 2.3 - Host Interface Specifications Spec API STILL 2025
IT requirements R1 20250929 Spec infra STILL 2025-09-29
Technical specification EXV CB iGo Datasheet véhicule 2025