La version 0.8 d'AnyBlok / WMS Base (AWB) a été mise en ligne sur PyPI il y a exactement une semaine, et comme la dernière fois, c'est une bonne occasion pour faire le point – en français.
Le grand sujet de ce cycle de développement aura été la fusion des Modèles des emplacements (Location) et des marchandises (Goods), il occupera fort logiquement la majeure partie de cet article, mais commençons par la vie du projet.
AWB en tournée !
J'ai eu la joie de parler pour la première fois d'Anyblok / WMS Base en public, le 6 octobre dernier lors du congrès pycon.fr 2018 à l'IMT Lille Douai, et tiens à en remercier une fois de plus les organisateurs.
La présentation elle-même est disponible en ligne: voir la vidéo et les écrans projetés. Même si finalement, la sortie effective de la nouvelle version aura encore pris presque deux semaines, c'est bien d'AWB 0.8 qu'il est question tout du long.
Note
à cette occasion j'ai soulevé la question de trouver un nouveau nom pour AWB. L'actuel « AnyBlok / WMS Base » est descriptif : il suit la nomenclature des projets standards du monde AnyBlok, indique que c'est du WMS et que ce n'est pas une application complète, mais au prix d'être lourd – et fatigant à prononcer ! Si vous avez des idées, faites m'en part.
J'aurai de nouveau l'occasion de présenter AWB, cette fois en anglais et sur un format un peu plus long, à PyParis 2018, qui aura lieu les 14 et 15 novembre prochains, à l'EPITA (Le Kremlin-Bicêtre).
Enfin, l'adaptation d'AnyBlok / Wms Examples à la version 0.8 est en cours – rappelons que c'est à la fois un ensemble d'exemples et un test de charge. Pour le moment les tests passent, mais je ne l'ai pas exécuté pour de bon, car il reste du travail de consolidation à faire sur le lanceur. Je vais essayer par la suite de maintenir un cycle de développement coordonné avec AWB.
Cas d'application
Depuis le billet précédent, j'ai assisté à la modélisation complète sur AWB d'une chaîne d'opérations pour de l'assemblage spécifique, avec matières premières disponibles en stock, ou commandées à la demande, voire en cours de processus.
Globalement, l'on peut dire que c'était un bon test pour le système de réservation et planification d'AWB, qui n'a quasiment pas évolué depuis la version 0.7. C'est peut-être l'occasion d'en rappeler les grands traits :
- les « requêtes de réservation » expriment le besoin en marchandises ou matières premières et font le lien avec le but recherché ; elles forment donc le point d'articulation principal pour l'applicatif métier ; elles peuvent être créées avant même qu'il soit prévu que les marchandises nécessaires soient présentes ;
- les « réservations » bloquent des objets présents ou à venir, en les liant au passage aux requêtes de réservation.
- la résolution des requêtes de réservation doit se faire de manière séquentielle et est peu coûteuse ; une fois faite, le partitionnement du problème ainsi obtenu permet une planification en parallèle sans concurrence en écriture. Il est donc utile pour passer à l'échelle d'utiliser le système de réservations, même s'il n'y a pas de besoin exprimé fonctionnellement en la matière.
Fusion des concepts d'emplacements et de marchandises
Jusqu'à la version précédente, nous avions deux modèles distincts : Wms.Goods (marchandises) pour les objets physiques suivis par le système, et Wms.Location (emplacements) pour les endroits où ils se trouvent.
C'ést là une distinction classique qui paraît bien naturelle, entre le « où ? » et le « quoi ? ». On la retrouve dans d'autres systèmes, et je l'avais reprise au début du projet sans la remettre en question, mais elle avait un côté légèrement arbitraire qui pouvait s'avérer gênant et un peu artificiel.
Les contenants intermédiaires
Dans beaucoup de scénarios logistiques que l'on voudrait modéliser avec un outil comme AWB, les marchandises sont regroupées pour être manipulées d'un coup dans des contenants : bacs, péniches (trays) ou chariots. Par exemple, il est courant de rassembler les éléments d'une commande client dans un bac, que l'on amène à une zone d'emballage pour faire un carton par bac. La distinction entre marchandises et emplacements nous force à un choix de modélisation sans solution satisfaisante :
Si l'on choisit de représenter ces contenants comme marchandises, on peut suivre leurs déplacements, mais il n'y a pas de moyen pratique d'indiquer que des choses sont dedans. On pourrait être tenté d'utiliser les opérations d'emballage et déballage (Assembly et Unpack) pour cela, mais cela ne correspond pas au ressenti utilisateur, et c'est très peu satisfaisant de devoir modéliser avec un déballage et un remballage le geste très simple d'ajouter quelque chose dans un bac.
Si l'on choisit de représenter les contenants comme emplacements, il est facile de placer des marchandises dedans, mais on n'a pas de moyen de représenter le déplacement de l'ensemble du contenant. Pourtant, c'est bien lui que l'on déplace comme un tout dans la réalité.
On pourrait choisir de ne pas représenter ces contenants, mais alors on s'éloigne de la réalité perçue par les opérateurs (qui déplacent des bacs), et en fait, on ne bénéficie pas sur le plan informatique de la simplification qu'ils procurent sur le plan matériel, et l'on serait amené par exemple à valider chaque étape sur les objets contenus plutôt que de le faire d'un coup sur le contenant.
Dans le cas d'utilisation pour le suivi de matériel scénique, on a même des appareils qui sont montés dans des flight-cases, conçus pour que l'on utilise le matériel sans l'en démonter. Suivant le cas d'application, l'utilisation peut amener le système informatique à enregistrer des dysfonctionnements, des temps d'utilisation etc. Pour le transport, c'est bien sûr le flight-case que l'on charge dans le camion. Il serait absurde de forcer les opérateurs à ouvrir les capots pour lire les code-barres des appareils qui sont à l'intérieur…
Une solution. que j'avais explorée dans ce dernier cas, était de définir le contenant intermédiaire à la fois comme emplacement et marchandise, mais c'était lourd à maintenir dans le code applicatif.
Autres limitations des emplacements
Je le notais dès le début du projet, le terme d'emplacement (location en anglais) laisse facilement à penser qu'il s'agit de quelque chose dont la position dans l'espace est fixe, et la question était ouverte de choisir une terminologie plus neutre à cet égard, pour qu'il soit clair qu'un camion, un navire peuvent être des emplacements.
De plus, il y avait ambiguïté sur la notion de sous-emplacement : devait-elle représenter un regroupement logique ou le fait que le sous-emplacement soit véritablement à l'intérieur de son parent ? Pour résoudre cela, on avait introduit dans la version 0.7 un système d'étiquettes dédié aux regroupements logiques, et l'on se préparait à expliquer à tous les consultants fonctionnels que la hiérarchie était bien à interpréter de manière spatiale.
D'une manière générale, la hiérarchie des emplacements avait le défaut d'être atemporelle, amenant donc à ce qu'une restructuration d'entrepôt donne des résultats de comptage difficiles à interpréter dès lors qu'ils portent sur une date où la structure était ou sera différente de celle du présent.
Pour finir, on avait prévu d'introduire par la suite un système de typage des emplacements – par exemple pour représenter une chambre froide et le fait qu'une denrée périssable doive être placée dedans – et je commençais à ressentir le besoin d'avoir des propriétés, notamment pour le cas d'utilisation du parc de matériel : un flight-case peut être distingué par sa couleur, ou nécessiter une réparation.
Un concept unique : les objets physiques
Finalement, n'est-il pas plus simple et cohérent de considérer simplement que les emplacements sont eux aussi des objets matériels ? C'est ce qui a été fait dans la version 0.8. Après tout, les insuffisances pointées plus haut peuvent se résumer au fait que les emplacements ne bénéficiaient pas de tout ce que nous avions prévu pour les marchandises. En poussant le raisonnement, il n'est pas non plus choquant de qualifier d'objet physique une étagère, un bâtiment, un pays ou même la Terre entière.
Comme la terminologie employée, les « marchandises (Goods) » paraissait dès lors inadaptée, on emploiera donc désormais le terme « objet physique », et le nom de modèle commun est Wms.PhysObj. C'est un peu plus lourd que simplement « objet », mais ceci aurait été source de confusion dans un contexte de programmation.
Pour le moment, un comportement (behaviour) sur le type d'objet physique indique s'il s'agit d'un contenant (container), permettant ainsi de placer d'autres objets à l'intérieur.
Par ce regroupement des concepts, on obtient directement les avantages suivants :
- comme tous objets physiques, les contenants ont un type et des propriétés ;
- comme tous objets physiques, la position d'un contenant à un moment donné est exprimé par un Avatar avec ses champs location, dt_from et dt_until ;
- en cas de restructuration des entrepôts, les requêtes de quantité dans le passé ou le futur tiennent compte du mouvement des emplacements ;
- la modélisation des contenants intermédiaires (bacs, péniches etc.) ne pose aucun problème particulier, on peut donc facilement être proche de la réalité de terrain ;
- toutes les Opérations prévues par le système sont directement possibles pour les contenants : on peut recevoir (Arrival) des étagères et des boîtes, ou même les construire (Assembly).
Avec tout cela, on a finalement considéré que le système d'étiquettes introduit pour AWB 0.7 n'était plus de très grande utilité et on l'a pour le moment supprimé, au profit d'un filtrage par type d'emplacements. Pour éviter de compter les articles à la poubelle comme disponibles à la vente, il suffira de donner un type précis à la poubelle, et de l'exclure des résultats.
Quels inconvénients ?
Ce choix conceptuel peut éventuellement surprendre des développeurs en aval, donc cela fait un effort de transmission, mais il n'y a pas de risque de confusion.
Il faut admettre que la représentation en base d'une chaîne de positions est un peu moins directe :
Par conséquent, cela fait des jointures en plus dans les requêtes hiérarchiques pour les quantités de stocks, avec la possibilité que cela s'avère trop coûteux dans certains cas, mais il restera possible de faire plus terre à terre en fonction du besoin.
Également à mentionner, le fait qu'un navigateur de stocks générique présenterait tous les contenants en plus des marchandises qui intéressent l'opérateur au premier chef : on imagine aisément que l'utilisateur d'une application destinée à la vente en ligne de vêtements aurait envie de ne voir quand il navigue que les articles destinés à la vente, et non les casiers de stockage – dans ce cas, un filtrage basé sur le Type dans l'interface utilisateur sera la bonne solution.
Conclusion
Il n'y a plus donc que deux catégories de concepts dans AWB : les objets physiques et les opérations.
C'est encore une grosse refonte que je suis content d'avoir mené à bien avant d'avoir des applications en production.
Il reste des endroits où le terme précédent (goods) est encore employé, comme par exemple dans les champs des Arrival, ce sera nettoyé dans les versions à venir, avec maintien de compatibilité.
Autres nouveautés de la version 0.8
On a eu quelques simplifications d'utilisation de l'API ; notamment, il n'est plus nécessaire de passer une date d'exécution à la création d'une Opération planifiée.
Les requêtes de quantité sont devenues plus puissantes et flexibles.
Des Opérations spécifiques ont été introduites pour le support des inventaires : Apparition, Disparition et Téléportation.
Le développement de l'Observation, une Opération pour changer les propriétés d'un objet physique, a commencé, mais elle n'a pas atteint la maturité à temps.
Diverses facilités pour manipuler les objets physiques et leurs avatars sont apparues.
Un nouveau cycle de développement
Le développement de la version 0.9 a commencé sur les chapeaux de roue ! D'abord l'Observation est quasiment prête, et devrait donc être rapidement intégrée.
Nous avons trois grands sujets pour 0.9 :
l'introduction de primitives pour manipuler – affiner ou réécrire – la planification. Cela fait partie de ce qui est proposé dans la page des améliorations sous le titre Superseding of planned Operations.
Elles permettront de mettre en œuvre un slogan du type « planifiez a minima, raffinez par la suite » et seront donc assez centrales dans l'utilisation concrète d'AWB. Nous avons d'ores et déjà assez d'entre elles pour le cas d'utilisation de réceptions complexes qui est mentionné dans la page des améliorations.
la gestion des inventaires. L'idée est que les Apparitions et autres Disparitions soient créés par des Modèles de plus haut niveau, qui représenteront le processus concret d'établissement de l'inventaire. Ce sera dans un Blok à part, pour ne pas forcer une manière de faire.
pour la planification encore, une meilleure représentation interne de l'indétermination temporelle. Pour le moment, le problème est juste posé dans la page des améliorations, et il est bien possible qu'on le reporte à plus tard.