Mission Principale - IPXact Tool - Part 2

sascha salles project

Posted on July 18, 2020, 10:21 a.m.

Déroulement de la mission

Architecture des fichiers

J'ai organisé la version finale du projet la sorte : 

sascha salles project

- Helpers contient les fonctions externes, comme le exceller, le parser et le worder

- Models contient la structure de chaque donnée (Classe Registre, Classe Fields etc...)

- Views contient cette fois les fichiers .ui de QtDesigner, mais aussi les fichiers python générés à partir des fichiers .ui

- Build contient la version compilée grace à cx_Freeze

- Assets contient les images et la norme en pdf (au cas où)

- project1_env est l'environnement virtuel python avec les packages installés

- main.py est le fichier de base, et setup.py contient les informations de compilation pour cx_Freeze

Le parser

Modules utilisés : ElementTree, xml.dom 

Le parser de fichiers IPXACT.xml permet de générer un array nommé mapping contenant des objets. Il existe une hierarchie entre ces différents objets. L'array mapping contient soit des addressBlocks soit des addressSpaces, un addressBlock est une entité à part entière sans enfants, une addressSpace contient quand à elle un ou des registres, un registre contient un ou plusieurs fields et un field peux contenir une ou plusieurs EnumeratedValues.

Cette organisation empirique semble inconfortable à première vue, mais est assez simple à parcourir. Il suffit juste de faire des boucles for imbriquées. 

Le fichier parser contient deux fonctions parseIpxact et writeIpxact, leur rôle est dans leur prénom. La fonction parseIpxact reprend le code que Benjamin a crée pour parser l'XML, j'y ai rajouté la possibilité de lire et de parser des AddressBlocks. La fonction writeIpxact permet de faire l'inverse de la fonction parseIpxact, elle génére du XML conforme à la norme IPXACT en fonction des objets présents dans l'array Mapping.

Design de l'IHM

Pour la conception graphique de l'IHM, je me suis appuyé sur les idées de Benjamin, et sur un fichier excel qui "ressemblait" à ce que devait donner l'IHM. Nous avons fait quelques schémas sur papier puis je me suis lancé dans le code. Une fois QtDesigner installé j'ai pu gérer beaucoup plus facilement la partie graphique de l'IHM et diminuer de façon drastique la redondance de l'écriture des champs de formulaire. 

Qt Design

L'export Excel

L'export Excel fut pour moi une découverte, j'ai appris à utiliser un module python très complet et surtout très puissant openpyxl.

A ma demande Benjamin m'a livré un template Excel correspondant le mieux à son besoin, ce template servira de base à la création du mien en automatisé. Dans le cas de l'IHM, l'export Excel est très intérressant pour les ingénieurs Hardware à l'aise avec excel. Suite à la réception du template, j'ai appris grâce à la documentation officielle à créer des fiches, insérer des volets, masquer des valeurs, customiser le style et ajouter des liens hypertextes permettants d'aller de fiches en fiches. J'ai pu donc répondre à toutes les attentes de Benjamin.

Difficulté : l'inversion de sens 

L'affichage des bits dans le fichier Excel se fait dans l'ordre décroissant mais aussi de la droite vers la gauche. J'avoue avoir passé pas mal de temps à gérer l'affichage des bits comme il faut. L'algorithme n'est pas spécialement complexe mais demande de penser à l'envers ce qui place généralement en situation d'inconfort.

Voici mon code :

    for addressSpace in data:

        startRow = 4

        for register in sorted(addressSpace):

            startCol = 6

            for field in reversed(register.fields):

                size = int(field.posh) - int(field.posl) + 1

                if size == 1:

                    mappingSheet.cell(row=startRow, column=((startCol + int(addressSpace.width)) - int(field.posh) - 1)).value = field.name

                    mappingSheet.cell(row=startRow, column=((startCol + int(addressSpace.width)) - int(field.posh) - 1)).border = mediumBorder

                elif size > 1:

                    pos = startCol 

                    mappingSheet.merge_cells(start_row = startRow, 

                                                    start_column = (startCol + int(addressSpace.width)) - int(field.posh) - 1, 

                                                    end_row = startRow, 

                                                    end_column = (startCol + int(addressSpace.width)) - int(field.posl) - 1)

                    mappingSheet.cell(row=startRow, column=(startCol + int(addressSpace.width)) - int(field.posh) - 1).value = field.name

            startCol += size

            startRow += 1

Notez l'utilisation de reverse dans la boucle, et les différents calculs de position. 

La mission aujourd'hui

Je pense avoir fait le tour des fonctionnalités les plus intéressantes du projet, il est évident que la description de tout le projet n'aurait pas de sens et serait assez ennuyeuse à lire. Cependant la rédaction de se blog se doît d'être finalisée pour le 31 août et il me reste encore un mois entier de stage, ma mission principale n'est donc pas arrivée à son terme.

L'outil de gestion agile JIRA me permet de visualiser les travaux restants sur l'IHM, ils sont actuellement au nombre de 10.

Voici pour l'instant quelques images de l'IHM.