Skip to content
This repository has been archived by the owner on Dec 14, 2021. It is now read-only.

Compatibilité avec TIC Standard, Linky #5

Open
JBoisseau opened this issue Dec 22, 2020 · 5 comments
Open

Compatibilité avec TIC Standard, Linky #5

JBoisseau opened this issue Dec 22, 2020 · 5 comments

Comments

@JBoisseau
Copy link

Bonjour,

le TIC standard de Linky n'a pas exactement le même formatage que le TIC historique:
https://www.enedis.fr/sites/default/files/Enedis-NOI-CPT_54E.pdf

dans les grandes lignes : séparateur n'est plus un espace mais un tab, certaines valeur sont horodatées, et le calcul du checksum est aussi légèrement différent, dû au séparateur.

j'ai du faire des modifications dans le parser pour le supporter. (modif non compatible avec le mode historique)

def get_frame(self):
    raw = self._get_raw_frame().strip(self.MARKER_END_LINE)
    frame = {}
    for line in raw.split(self.MARKER_END_LINE):
       els = line.split("\t")
       k = els[0]
       if len(els) == 3:
           v = els[1].strip()
       elif len(els) == 4:
           v = (els[1].strip(),els[2].strip())
       else:
           logger.error('TIC is badly formated for line:' + str(line))
           continue
       data = line[:-1]
       chksum = line[-1]
       computedchksum = self._checksum(data)
       if chksum == computedchksum:
            frame[k] = v
       else:
            logger.debug(str(line) + ':' + str(chksum) + ':' + str(computedchksum))
    if len(frame) != len(raw.split(self.MARKER_END_LINE)):
        logger.error("Discarded fields because of bad checksum")
    return frame

def _checksum(self, data):
    chksum = sum([ord(c) for c in data])
    chksum = (chksum & 63) + 32
    return chr(chksum)

il y a surement moyen de faire une fonction compatible avec les 2 modes, en passant juste un "standard = True or False" en argument

SI tu veux je peux le faire, mais je n'ai pas de linky en mode historique pour tester.

@demikl
Copy link
Owner

demikl commented Dec 22, 2020

Bonjour.

J'ai un Linky en mode historique, je pourrais donc valider l'évolution de mon côté. Je te remercie d'avance pour ta contribution. En terme d'architecture, je verrais bien un type ou une classe qui porterait le dialecte (à la façon du module parseur CSV), dans lequel seraient spécifiés ces éléments qui changent : tabulation vs. espace, fonction de checksum, etc. . Et deux instances de ce dialecte préconfigurés : linky standard et linky historique. Ensuite on passe un instance en paramètre, avec rétrocompatibilité en étant de base sur le mode historique.

Ca te va ?

@JBoisseau
Copy link
Author

Bonjour,

Je pense que la fonction checksum peut rester comme je l'ai faite, pour couvrir les 2 modes.

Je verrais juste la fonction get_frame avec un argument : standardMode = False.

Et ensuite :
If standardMode:
els = line.split("\t")
data = line[:-1]
else:
els = line.split(" ")
data = line[:-2]

La suite serait identique aux 2 modes.

Qu'en penses tu ?

@JBoisseau
Copy link
Author

voici la fonction get_frame, compatible avec les 2 modes, je pense. Testé sur mon linky standard.

def get_frame(self,standardMode = False):
    raw = self._get_raw_frame().strip(self.MARKER_END_LINE)
    frame = {}
    lines = raw.split(self.MARKER_END_LINE)
    for line in lines:
       if standardMode:
           els = line.split("\t")
           data = line[:-1] #data should include last separator
       else:
           els = line.split(" ")
           data = line[:-2] #data should not include last separator

       k = els[0]
       if len(els) == 3:
           v = els[1].strip()
       elif len(els) == 4: #standardMode has some fields with date before the value.
           v = (els[1].strip(),els[2].strip())
       else:
           logger.error('TIC is badly formated for line:' + str(line))
           continue

       chksum = line[-1]
       computedchksum = self._checksum(data)
       if chksum == computedchksum:
            frame[k] = v
       else:
            logger.error('Discarded line because of bad checksum:' + str(line) + '| checksum:' + str(chksum) + ', vs:' + str(computedchksum))

    if len(frame) != len(lines):
        logger.error("Discarded fields because of bad checksum")
    return frame

et aussi le checksum générique

def _checksum(self, data):
    chksum = sum([ord(c) for c in data])
    chksum = (chksum & 63) + 32
    return chr(chksum)

@JBoisseau
Copy link
Author

par contre le code
#!/usr/bin/env python
from teleinfo import Parser
from teleinfo.hw_vendors import PITInfo
ti = Parser(PITInfo(baudrate=9600))
print ti.get_frame()

ne fonctionne pas.
TypeError: init() got an unexpected keyword argument 'baudrate'

j'ai dû modifier le baudrate dans le code directement.

@demikl
Copy link
Owner

demikl commented Dec 24, 2020

Bonsoir.

Effectivement si la différence se limite à ces faibles différences, inutile de se compliquer. Ta proposition me convient.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants