IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Problème lecture de fichier / décalage et masquage binaire


Sujet :

Python

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Problème lecture de fichier / décalage et masquage binaire
    Bonjour à toutes et à tous,

    N'étant pas un profesionnel de python (et de la programmation en général) je me tourne vers vous pour quelque conseil !

    Tout d'abord, laissez moi vous expliquer un peu le contexte.

    La 1ere partie du script, que je ne vous détaillerez pas pour la simple raison qu'elle fonctionne correctement, envoie une commande sous forme d'une chaîne de caractère hexadécimal à un boitier physique, ce boitier répond à son tour. cette réponse est sous cette forme : "ACK0p08000200F060010000"
    Ces caractères hexadécimal correspondent chacun à une information contenu dans un fichier de mapping(mapfile.txt) dont voici la forme:
    bit 0-15 | Project_id | RMC
    bit 53 | SSPA-A | RMC
    bitnumber | information | type de boitier

    Chaque information est enregistrée sur 1 ou plusieurs bit, ici en l'occurence, l'information project_id est enregistrée sur 16 bit et SSPA-A est enregistrée seulement sur le bit numéro 53.
    A noté que la conversation de l'hexa au binaire est ici un peu particulière, car ce sont seulement des demi octets, c'est à dire que par exemple, l'information présente au "demi"octet numéro 13 est 13* 4 = 52 > 52eme bit !
    Dans l'exemple d'au dessus, dans le demi octet numéro 13, il y a donc 4 bit avec chacun une information différente, le bit 52 correpond par exemple à la température, le 53 au status du boitier, le 54 ...

    Le code qui suit à des variables défini en dur pour éviter toute la 1ere partie.

    Voici donc le code, ça sera surement plus compréhensible

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    # On ouvre le fichier de mapping passé en paramètre
    msg = 'ACK0p08000200F060010000'
    # la variable "data" enlève la 1ere partie de la chaine qui nous sera inutile et prend donc  seulement 08000200F060010000, je la transforme ensuite en nombre entier hexadécimal
    data = int(msg[5:],16)
    print ('\nNombre entier hexadécimal, on le traduit en binaire en isolant le numéro de bit :\n ' + str(data))
    #ici se
    zabbix = [line.strip() for line in open('mapfileRMC.txt','r')]
    # On extrait ligne par ligne, le numéro de bit, la clé d'item, et le type de statut
    for line in zabbix:
        # J'essaie de récupérer les chiffres / lettres contenu dans le fichier avec une expression régulière
        result = re.search('bit\s([0-9]+)|([0-9]+)-([0-9]+)\s\|\s([a-zA-Z]*)\s\|\s([a-zA-Z]*)', line)
        if result:
          # On extrait le contenu de chaque ligne  
          bitnumber = result.group(1)
          itemZabbix = result.group(2)
          typeboitier = result.group(3)
     
          # On génere le masque binaire associé au numéro de bit 
          # ici on essaie d'isoler le numéro de bit, et masquer pour pourvoir ressortir seulement l'information dont on a besoin
          mask = "1"
          for i in range(0,int(bitnumber)):
            mask += "0"   
     
          binarymask = int(mask,2)
          print ('\nMasque binaire : ' + str(binarymask))
          # On masque la valeur et on décale pour obtenir la valeur du bit
          bitvalue = (data & binarymask)>>int(bitnumber)
     
          print('\nValeur du bit' + str(bitvalue))
          print('Item zabbix' + str(itemZabbix))
          print('typeboitier ' + str(typeBoitier))
    En tous les cas, voici ce que donne l'exécution du script :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    Nombre entier hexadécimal, on le traduit en binaire en isolant le numéro de bit :
     147574516572032663552
     
    Masque binaire : 1
     
    Valeur du bit0
    Item zabbixNone
    typeboitierNone
     
    Masque binaire : 65536
     
    Valeur du bit1
    Item zabbixNone
    typeboitierNone
     
    Masque binaire : 4294967296
     
    Valeur du bit0
    Item zabbixNone
    typeboitierNone
     
    Masque binaire : 8589934592
     
    Valeur du bit0
    Item zabbixNone
    typeboitierNone
    j'ai coupé car ça descend encore plus bas.

    Pour résumé, je n'arrive pas à voir si le code que j'ai fais, prend en compte n'importe quel informations > bitnumber = n et ressort la bonne information associé à ce numéro de bit.

    Si vous avez des remarques quant au python en lui même, je suis également preneur.

    Je ne pense pas que ça soit très clair, je répondrai aux éventuelles questions du mieux possible.

    Merci pour vos réponses.

    Cordialement,

    Lysan

  2. #2
    Membre éprouvé

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Points : 1 273
    Points
    1 273
    Par défaut
    Le premier gros problème vient de ta regex. Je ne vais pas tout détailler, mais d’une part, il faut utiliser les chaînes “raw” de python quand on utilise les séquences d’échappement dans une regex (sous peine de devoir les échapper doublement, soit on écrit r"\s", soit on écrit "\\s", le choix est vite fait, en général ). D’autre part, la clause “or” (le |) des regex est un peu délicat, il faut utiliser des parenthèses (de préférence non-capturantes) pour en délimiter les limites, et il n’intervient pas dans la numérotation des groupes capturants (ce qui fait que dans ta regex, group(2) correspond au deuxième groupe capturant défini, le second '([0-9]+)').

    De toute façon, tu n’as pas besoin de ce “or” ici, rendre le contenu du second groupe capturant le bit de fin optionnel est suffisant. Au fait, il vaut mieux “compiler” une seule fois une regex, plutôt que de la re-définir à chaque fois…

    Par ailleurs, tu t’es compliqué la vie pour la définition de ton masque, il suffit d’utiliser les opérations binaires sur un entier, là aussi*!

    Enfin, tu “oublies” de fermer ton fichier de mapping… Mieux vaut utiliser “with” (context manager) pour ce genre de chose, comme ça le fichier est automatiquement fermer quand on sort du contexte.

    Ce qui nous donne quelque chose comme ça*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    msg = 'ACK0p08000200F060010000'
    # la variable "data" enlève la 1ere partie de la chaine qui nous sera inutile et prend donc
    # seulement 08000200F060010000, je la transforme ensuite en nombre entier hexadécimal
    data = int(msg[5:], 16)
    print ('\nNombre entier hexadécimal, on le traduit en binaire en isolant le numéro de bit :\n {}'.format(data))
     
    # Définition de la regex parsant les "coordonnées" des données.
    regex = re.compile(r"bit\s([0-9]+)-?([0-9]*)\s\|\s(\w+)\s\|\s(\w+)")
    # On ouvre le fichier de mapping passé en paramètre
    with open('mapfileRMC.txt','r') as zabbix:
        # On extrait ligne par ligne, le numéro de bit, la clé d'item, et le type de statut
        for line in zabbix:
            # J'essaie de récupérer les chiffres / lettres contenu dans le fichier avec une expression régulière
            result = regex.search(line.strip())
            if result:
                # On extrait le contenu de chaque ligne  
                bitstart = result.group(1)
                bitend = result.group(2) or bitstart  # un seul bit si pas de seconde "coordonnées"
                itemZabbix = result.group(3)
                typeboitier = result.group(4)
     
                # On génere le masque binaire associé au numéro de bit 
                # ici on essaie d'isoler le numéro de bit, et masquer pour pourvoir ressortir seulement l'information
                # dont on a besoin
                mask = 0
                for i in range(bitstart, bitend + 1):
                    mask += 1 << i
     
                print ('\nMasque binaire: {}'.format(mask))
                # On masque la valeur et on décale pour obtenir la valeur du bit
                bitvalue = (data & binarymask) >> int(bitstart)
     
                print('\nValeur des bits {} à {}: {}'.format(bitstart, bitend, bitvalue))
                print('Item zabbix: {}'.format(itemZabbix))
                print('typeboitier: {}'.format(typeBoitier))
    Code non testé, hein*!

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    Merci infiniment pour ta réponse !

    je vais prendre en compte tout ça et essayer ça dans les prochains jours.

    Cordialement,

    Lysan

Discussions similaires

  1. Problème lecture de fichier binaire
    Par -N4w4k- dans le forum C#
    Réponses: 3
    Dernier message: 16/02/2013, 22h16
  2. probléme lecture de fichier binaire octer par octet
    Par ousmanesidibe dans le forum C++
    Réponses: 2
    Dernier message: 12/12/2009, 21h34
  3. [XPATH] problème lecture dans fichier XML
    Par DiamonDonald dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 26/02/2008, 09h57
  4. problème lecture seule fichier image
    Par Damien69 dans le forum Langage
    Réponses: 1
    Dernier message: 23/03/2007, 16h53
  5. problème lecture de fichier
    Par nico33410 dans le forum Langage
    Réponses: 2
    Dernier message: 29/10/2006, 20h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo