Python et lecture xml sur port série

Forum dédié aux problématiques concernant les scripts pour DomoticZ.
Entourez votre code et les logs avec les balises nommées code grâce au bouton <\>.
JC38
Messages : 286
Inscription : 29 déc. 2014, 20:47
Localisation : Lyon

Python et lecture xml sur port série

Message par JC38 »

Bonjour,

J'ai un équipement connecté à un serveur Windows qui envoie des données de conso électrique via un port COM dans un flux xml.
Je voudrais essayer de parser le flux xml mais je suis embêté par qq caractères qui me bloquent dans mon code.
Voici le code :

Code : Tout sélectionner

import serial
import os
import requests
from lxml import etree

#Constants

COMPORT = "COM4"
COMPORT_BAUD = 57600
DOMOTICZ_URL = "http://192.168.0.36:8080"  

# connect to the CurrentCost meter

ser = None
try:
    ser = serial.Serial(port=COMPORT, baudrate=COMPORT_BAUD, timeout=30)
except serial.SerialException:#, msg:
    print("Failed to connect to CurrentCost meter :: " + str(msg))
    exit(1)
print ("Connected to "+COMPORT+" at "+str(COMPORT_BAUD)+" Baud!")
print (ser.name)

print ("Trying to read lines now....")

while True:
   line = str(ser.readline())
   line = line.lstrip('b')
   line = line.replace('\n','').replace('\r','')
   print (line) # Uncomment out this row if you want to see the raw XML
   #line = '<msg><src>CC128-v0.11</src><dsb>01784</dsb><time>16:40:19</time><tmpr>10.6</tmpr><sensor>2</sensor><id>03711</id><type>1</type><ch1><watts>00116</watts></ch1></msg>'
   #node = etree.fromstring(line)
   #print (node.tag)
   #print (node.findtext('src'))
   
exit(0)
Et c'est là que ça coince, avec les fins de lignes, les \r\n que je n'arrive pas à enlever dans la variable line

Code : Tout sélectionner

'<msg><src>CC128-v0.11</src><dsb>01801</dsb><time>11:52:21</time><tmpr>13.3</tmpr><sensor>2</sensor><id>03711</id><type>1</type><ch1><watts>00043</watts></ch1></msg>\r\n'
'<msg><src>CC128-v0.11</src><dsb>01801</dsb><time>11:52:23</time><tmpr>13.3</tmpr><sensor>1</sensor><id>01912</id><type>1</type><ch1><watts>00057</watts></ch1></msg>\r\n'
Si des habitués du python peuvent me venir en aide, je leur en serai reconnaissant.
Raspberry Pi3 sous Jessie 8.3 + Domoticz latest beta + RFXComm Usb + Aeon Labs Z-Stick + Weather Underground
Windows Server 2012 R2 + Domoticz Windows (latest) + Open Hardware Monitor
Clients : ImperiHome avec Mdah / Domoticz for Android
patrice
Messages : 1720
Inscription : 22 sept. 2014, 21:51

Re: Python et lecture xml sur port série

Message par patrice »

Bonjour
comme ca d’après mon souvenir :
line.replace("\n", "")
line.replace("\r", "")
ou les cr lf sont replaces par ""
ou sinon

line.strip('\n\r')

a verifier quand même
Raspberry pi 3, Dongle RfxCom et Zigate +, plugin de pipiche, Volets Roulants profalux, contrôle d'éclairage, détecteurs de présence, alarme incendie, pilotage livebox ...
Objectif : WAF > 1
JC38
Messages : 286
Inscription : 29 déc. 2014, 20:47
Localisation : Lyon

Re: Python et lecture xml sur port série

Message par JC38 »

Oups, je croyais avoir donné la solution suite à la réponse de Patrice. Je m'en suis sorti comme cela :

Code : Tout sélectionner

   line = str(ser.readline())
   line = line.lstrip("b'")
   line = line[:-5]
Raspberry Pi3 sous Jessie 8.3 + Domoticz latest beta + RFXComm Usb + Aeon Labs Z-Stick + Weather Underground
Windows Server 2012 R2 + Domoticz Windows (latest) + Open Hardware Monitor
Clients : ImperiHome avec Mdah / Domoticz for Android
JC38
Messages : 286
Inscription : 29 déc. 2014, 20:47
Localisation : Lyon

Re: Python et lecture xml sur port série

Message par JC38 »

Je reviens donc sur mon problème de lecture.
Déjà, je ne sais pas quel "module" utiliser, lxml ou xml.etree.ElementTree, pour l'instant, j'ai opté un peu au hasard pour lxml

Pour ce genre de ligne :

Code : Tout sélectionner

<msg><src>CC128-v0.11</src><dsb>01784</dsb><time>16:40:19</time><tmpr>10.6</tmpr><sensor>2</sensor><id>03711</id><type>1</type><ch1><watts>00116</watts></ch1></msg>
J'arrive à lire l'heure, le capteur et la température.

Code : Tout sélectionner

 print (node.findtext('sensor') + ' - ' + node.findtext('time')+ ' - ' + node.findtext('tmpr'))
Par contre, je ne sais pas comment lire la valeur de watts entre les balises ch1. Quelqu'un peut me guider ?
Raspberry Pi3 sous Jessie 8.3 + Domoticz latest beta + RFXComm Usb + Aeon Labs Z-Stick + Weather Underground
Windows Server 2012 R2 + Domoticz Windows (latest) + Open Hardware Monitor
Clients : ImperiHome avec Mdah / Domoticz for Android
patrice
Messages : 1720
Inscription : 22 sept. 2014, 21:51

Re: Python et lecture xml sur port série

Message par patrice »

Bonsoir

La réponse est apportée par la librairie minidom

Code : Tout sélectionner

from xml.dom import minidom
Pour tester j'ai mis tes données dans un fichier nommé fichxml.txt, tu adaptera à tes besoins
Et puis on va chercher la valeur de la premiere fois ou on trouve le mot "watts"

Code : Tout sélectionner

xmldoc = minidom.parse('fichxml.txt')
reponse = xmldoc.getElementsByTagName('watts')
valeur= reponse[0].firstChild.nodeValue
print valeur

/code off
Raspberry pi 3, Dongle RfxCom et Zigate +, plugin de pipiche, Volets Roulants profalux, contrôle d'éclairage, détecteurs de présence, alarme incendie, pilotage livebox ...
Objectif : WAF > 1
Répondre