Monitorer batteries Pylontech

Avec 158

Superbe, ça fait plaisir de voir ça :wink:

Bravo pour ta persévérance :+1:

merci, mais j’ai toujours en décalage :face_with_peeking_eye:

Sinon tu peux essayer de modifier le code suivant:

else:
	requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&apikey='+cmdapi+'&type=virtual&id='+cmdidretour+'&value=')
	x = rep.find("1     ")-1 # cherche le 1er 
	for i in range(1): #remplacer range(4) par range(x) en fonction du nombre x de batteries installees
	  tension = str(float(rep[x+7+(156*i):x+12+(156*i)]) / 1000)      # tension 3 chiffres apres la virgule sinon prendre x+11 au lieu de x+12 et diviser par 100 au lieu de 1000
	  intens=str(float(rep[x+14+(156*i):x+19+(156*i)]) /1000)      # intensite
	  temper=str(float(rep[x+21+(156*i):x+26+(156*i)]) /1000)      # temperature
	  soc=rep[x+92+(156*i):x+94+(156*i)]      # soc
	  requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&apikey='+cmdapi+'&type=virtual&id='+cmdidbat[i*4]+'&value='+tension)
	  requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&apikey='+cmdapi+'&type=virtual&id='+cmdidbat[1+(i*4)]+'&value='+intens)
	  requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&apikey='+cmdapi+'&type=virtual&id='+cmdidbat[2+(i*4)]+'&value='+temper)
	  requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&apikey='+cmdapi+'&type=virtual&id='+cmdidbat[3+(i*4)]+'&value='+soc)
     except:
	  requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&apikey='+cmdapi+'&type=event&id='+cmdidretour+'&value=erreur')
#tte

Par :

else:
	requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&apikey='+cmdapi+'&type=virtual&id='+cmdidretour+'&value=')
	for i in range(1): #remplacer range(4) par range(x) en fonction du nombre x de batteries installees
		x = rep.find(str(i + 1) + "     ")-1 # cherche le 1er 
		tension = str(float(rep[x+7:x+12]) / 1000)      # tension 3 chiffres apres la virgule sinon prendre x+11 au lieu de x+12 et diviser par 100 au lieu de 1000
	  intens=str(float(rep[x+14:x+19]) /1000)      # intensite
	  temper=str(float(rep[x+21:x+26) /1000)      # temperature
	  soc=rep[x+92:x+94]      # soc
	  requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&apikey='+cmdapi+'&type=virtual&id='+cmdidbat[i*4]+'&value='+tension)
	  requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&apikey='+cmdapi+'&type=virtual&id='+cmdidbat[1+(i*4)]+'&value='+intens)
	  requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&apikey='+cmdapi+'&type=virtual&id='+cmdidbat[2+(i*4)]+'&value='+temper)
	  requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&apikey='+cmdapi+'&type=virtual&id='+cmdidbat[3+(i*4)]+'&value='+soc)
     except:
	  requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&apikey='+cmdapi+'&type=event&id='+cmdidretour+'&value=erreur')
#tte

Attention à l’identation, là j’ai dû faire n’importe quoi

Je viens de mettre le bout de code, si dans for i in range(1) je mets 1 j’ai l’affichage de la batterie 1 et si je mets 2 j’ai l’affichage de la batterie 2 (dans les bon champ).
Demain je regarde si cette base pour faire afficher les deux batteries en même temps.

Merci beaucoup

Ok, tiens moi au courant :+1:

Bonjour,

L’idée serait de faire une truc comme ça :
Mais je maitrise pas suffisamment python.

else:
	requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&apikey='+cmdapi+'&type=virtual&id='+cmdidretour+'&value=')
	x = rep.find("1     ")-1 # cherche le 1er 
	for i in range(1): #remplacer range(4) par range(x) en fonction du nombre x de batteries installees

		tension = str(float(rep[x+7:x+12]) / 1000)      # tension 3 chiffres apres la virgule sinon prendre x+11 au lieu de x+12 et diviser par 100 au lieu de 1000
        intens=str(float(rep[x+14:x+19]) /1000)      # intensite
        temper=str(float(rep[x+21:x+26]) /1000)      # temperature
        soc=rep[x+92:x+94]      # soc

		#tension=str(float(rep[x+7+(158*i):x+12+(158*i)]) /1000)      # tension 3 chiffres apres la virgule sinon prendre x+11 au lieu de x+12 et diviser par 100 au lieu de 1000
		#intens=str(float(rep[x+14+(158*i):x+19+(158*i)]) /1000)      # intensite
		#temper=str(float(rep[x+21+(158*i):x+26+(158*i)]) /1000)      # temperature
        #base=rep[x+55+(158*i):x+62+(158*i)]		# sans de charge/decharge
        #soc=rep[x+92+(158*i):x+94+(158*i)]		# soc
        
        #Batterie 1
        requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[i*4]+'&value='+tension)
        requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[1+(i*4)]+'&value='+intens)
        requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[2+(i*4)]+'&value='+temper)
        #requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[3+(i*4)]+'&value='+base)
        requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[3+(i*4)]+'&value='+soc)

	requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&apikey='+cmdapi+'&type=virtual&id='+cmdidretour+'&value=')
	x = rep.find("1     ")-1 # cherche le 1er 
	for i in range(2): #remplacer range(4) par range(x) en fonction du nombre x de batteries installees

		tension = str(float(rep[x+7:x+12]) / 1000)      # tension 3 chiffres apres la virgule sinon prendre x+11 au lieu de x+12 et diviser par 100 au lieu de 1000
        intens=str(float(rep[x+14:x+19]) /1000)      # intensite
        temper=str(float(rep[x+21:x+26]) /1000)      # temperature
        soc=rep[x+92:x+94]      # soc


        #Batterie 2
        requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[i*4]+'&value='+tension)
        requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[1+(i*4)]+'&value='+intens)
        requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[2+(i*4)]+'&value='+temper)
        #requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[3+(i*4)]+'&value='+base)
        requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[3+(i*4)]+'&value='+soc)
#tte

OU comme cela

else:
	requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&apikey='+cmdapi+'&type=virtual&id='+cmdidretour+'&value=')
	x = rep.find("1     ")-1 # cherche le 1er 
	for i in range(1): #remplacer range(4) par range(x) en fonction du nombre x de batteries installees

		tension = str(float(rep[x+7:x+12]) / 1000)      # tension 3 chiffres apres la virgule sinon prendre x+11 au lieu de x+12 et diviser par 100 au lieu de 1000
        intens=str(float(rep[x+14:x+19]) /1000)      # intensite
        temper=str(float(rep[x+21:x+26]) /1000)      # temperature
        soc=rep[x+92:x+94]      # soc

		#tension=str(float(rep[x+7+(158*i):x+12+(158*i)]) /1000)      # tension 3 chiffres apres la virgule sinon prendre x+11 au lieu de x+12 et diviser par 100 au lieu de 1000
		#intens=str(float(rep[x+14+(158*i):x+19+(158*i)]) /1000)      # intensite
		#temper=str(float(rep[x+21+(158*i):x+26+(158*i)]) /1000)      # temperature
        #base=rep[x+55+(158*i):x+62+(158*i)]		# sans de charge/decharge
        #soc=rep[x+92+(158*i):x+94+(158*i)]		# soc
        
        #Batterie 1
        requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[i*4]+'&value='+tension)
        requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[1+(i*4)]+'&value='+intens)
        requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[2+(i*4)]+'&value='+temper)
        #requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[3+(i*4)]+'&value='+base)
        requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[3+(i*4)]+'&value='+soc)


        
if (rep == 'erreur'):
	requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&apikey='+cmdapi+'&type=virtual&id='+cmdidretour+'&value=erreur')
else:
	requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&apikey='+cmdapi+'&type=virtual&id='+cmdidretour+'&value=')
	x = rep.find("1     ")-1 # cherche le 1er 
	for i in range(2): #remplacer range(4) par range(x) en fonction du nombre x de batteries installees

		tension = str(float(rep[x+7:x+12]) / 1000)      # tension 3 chiffres apres la virgule sinon prendre x+11 au lieu de x+12 et diviser par 100 au lieu de 1000
        intens=str(float(rep[x+14:x+19]) /1000)      # intensite
        temper=str(float(rep[x+21:x+26]) /1000)      # temperature
        soc=rep[x+92:x+94]      # soc



		#Batterie 2
        requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[i*4]+'&value='+tension)
        requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[1+(i*4)]+'&value='+intens)
        requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[2+(i*4)]+'&value='+temper)
        #requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[3+(i*4)]+'&value='+base)
        requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[3+(i*4)]+'&value='+soc)
#tte

C’est ce que je t’ai proposé là

Je ne peux pas tester car j’ai un souci chez moi et je ne suis pas sur place…

Oui c’est le même code, mais qui fonctionne sur une batterie a la fois.
Pas les deux en même temps.

Bonjour,

Voici le script pour du python V3 avec les corrections de lecture lié a la version de firmware :

#!/usr/bin/python3

import time
import os
import json
import requests
from requests.auth import HTTPDigestAuth
import pprint
import sys
import socket


def question_pylon(): # interroge le BMS Pylontech avec une commande pwr
	# Connect the socket to the port where the server is listening
	HOST = 'xxx.xxx.xxx.xxx' #adresse IP du HF2221
	PORT = 8888
	server_address = (HOST, PORT)
#	print(server_address)
	try:
#    print >>sys.stderr, 'connecting to %s port %s' % server_address
#		print("connecting to %s port %s" % server_address , file=sys.stderr)
		client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		client.connect(server_address)
#		print("connecting to %s port %s" % server_address , file=sys.stderr)
        #        print ("Connexion vers " + HOST + ":" + str(PORT) + " reussie.")
	except socket.error as e:
		return 'erreur'
		sys.exit(1)
	message = 'pwr'
	client.settimeout(3)
	n = client.send((message + chr(13)).encode())
	try:
		resp = client.recv(1024)
#		print(resp)
	except socket.timeout:
		return 'erreur'
		sys.exit(1)
	resp2 = client.recv(1024)
	resp3 = client.recv(1024)
	resp += resp2 + resp3
#	print 'Recu :', resp
#	print 'Recu2 :', resp2
#	reponse = str(resp.text)
	reponse = resp
#	print 'Deconnexion.'
	client.close()
#	print 'rep = ', resp
	return reponse

 
ipjeedom = 'xxx.xxx.xxx.xxx:port'
cmdapi = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' #cle API a prendre dans le virtuel que l on veut mettre a jour
cmdidbat = ['1557','1558','1559','1560'] #valeurs des cmdid pour la batterie 1 tension, intensite, temperature, SOC
cmdidbat += ['1562','1563','1564','1565'] #valeurs des cmdid pour la batterie 2 tension, intensite, temperature, SOC
#cmdidbat += ['1477','1478','1479','1480'] #valeurs des cmdid pour la batterie 3 tension, intensite, temperature, SOC
#cmdidbat += ['1481','1482','1483','1484'] #valeurs des cmdid pour la batterie 4 tension, intensite, temperature, SOC
#cmdidbat += ['1468','1470','1471','1472'] #valeurs des cmdid pour la batterie 5 tension, intensite, temperature, SOC
#cmdidbat += ['1468','1470','1471','1472'] #valeurs des cmdid pour la batterie 6 tension, intensite, temperature, SOC
#cmdidbat += ['1468','1470','1471','1472'] #valeurs des cmdid pour la batterie 7 tension, intensite, temperature, SOC
#cmdidbat += ['1468','1470','1471','1472'] #valeurs des cmdid pour la batterie 8 tension, intensite, temperature, SOC
cmdidretour = '1566' #valeur de la cmd retour d etat connexion
rep = question_pylon()
if (rep == 'erreur'):
	requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidretour+'&value=erreur')
else:
	requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidretour+'&value=')
	x = rep.find("1     ".encode()) - 1 # cherche le 1er 
#	print rep
#	print x

for i in range(2):  # Remplacer range(4) par range(x) en fonction du nombre x de batteries installées
    tension = str(float(rep[x + 7 + (158 * i):x + 12 + (158 * i)]) / 1000)  # Tension 3 chiffres après la virgule sinon prendre x+11 au lieu de x+12 et diviser par 100 au lieu de 1000
    print(tension)
    intens = str(float(rep[x + 14 + (158 * i):x + 19 + (158 * i)]) / 1000)  # Intensité
    print(intens)
    temper = str(float(rep[x + 21 + (158 * i):x + 26 + (158 * i)]) / 1000)  # Température
    print(temper)
    soc = rep[x + 92 + (158 * i):x + 95 + (158 * i)].decode()  # SOC
    print(soc)
    
    url_tension = 'http://{}/core/api/jeeApi.php?plugin=virtual&type=event&apikey={}&id={}&value={}'.format(ipjeedom, cmdapi, cmdidbat[i * 4], tension)
    requests.get(url_tension)
    
    url_intensite = 'http://{}/core/api/jeeApi.php?plugin=virtual&type=event&apikey={}&id={}&value={}'.format(ipjeedom, cmdapi, cmdidbat[1 + (i * 4)], intens)
    requests.get(url_intensite)
    
    url_temperature = 'http://{}/core/api/jeeApi.php?plugin=virtual&type=event&apikey={}&id={}&value={}'.format(ipjeedom, cmdapi, cmdidbat[2 + (i * 4)], temper)
    requests.get(url_temperature)
    
    url_soc = 'http://{}/core/api/jeeApi.php?plugin=virtual&type=event&apikey={}&id={}&value={}'.format(ipjeedom, cmdapi, cmdidbat[3 + (i * 4)], soc)
    requests.get(url_soc)

#	  requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[i*4]+'&value='+tension)
#	  requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[1+(i*4)]+'&value='+intens)
#requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[2+(i*4)]+'&value='+temper)
#requests.get('http://'+ipjeedom+'/core/api/jeeApi.php?plugin=virtual&type=event&apikey='+cmdapi+'&id='+cmdidbat[3+(i*4)]+'&value='+soc)

Merci @Looping49

Merci @Looping49

Voici le mien qui fonctionne a merveille depuis novembre :

#!/usr/bin/env python3

import socket
import requests

IP_PYLON = 'xxx.xxx.xxx.xxx'
IP_JEEDOM = 'xxx.xxx.xxx.xxx'
APIKEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXXX'
CMD_ID_RETOUR = 3590
JEEDOM_URL = f'http://{IP_JEEDOM}/core/api/jeeApi.php?plugin=virtual&apikey={APIKEY}&type=event&type=cmd&id={{0}}&value={{1}}'
VARIABLES = ['Volt', 'Curr', 'Tempr', 'Base.St', 'Coulomb']

# liste des ids de chaque batterie
BATTERIES = {
    1: [2853, 2854, 2855, 3601, 2856],
    2: [3602, 3603, 3604, 3606, 3605],
    3: [3626, 3627, 3628, 3630, 3629],
    # 4: [1481, 1482, 1483, 1484, 1485],
    # 5....
}


def decode_data(data):
    '''
    cette fonction decode le resultat de la commande pwr
    et retourne une liste de dictionnaire des valeurs disponible
    '''
    result = {}
    # on separe les lignes
    data = data.split('\n')
    # on filtre les lignes interessantes
    data = [row for row in data if row and (row.startswith('Power') or row[0].isdigit())]
    # on recupere le nom des colonnes
    columns = list(filter(None, data[0].split(' ')))
    # pour chaque ligne de valeur
    for row in data[1:]:
        # on separe les valeurs
        row = list(filter(None, row.split(' ')))
        row = [value.strip() for value in row]
        # on retablie la colonne Time
        if row[13][0].isdigit():
            row[13] = row[13] + ' ' + row[14]
            del row[14]
        # on rajoute des valeurs vides pour les colonnes qui ne sont pas disponibles
        row += ['-'] * (len(columns) - len(row))
        # on cree un dictionnaire avec le nom des colonnes et les valeurs
        values = dict(zip(columns, row))
        # mise en forme des valeurs
        values['Power'] = int(values['Power'])
        for col in ('Volt', 'Curr', 'Tempr', 'Tlow', 'Thigh', 'Vlow', 'Vhigh'):
            if values[col].replace('-', '').isdigit():
                values[col] = float(values[col]) / 1000
        result[values['Power']] = values
    return result


def question_pylon(): 
    # interroge le BMS Pylontech avec une commande pwr
    # Connect the socket to the port where the server is listening
    PORT = 8899
    server_address = (IP_PYLON, PORT)
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.settimeout(3)
    try:
        client.connect(server_address)    
    except socket.error as e:
        return 'erreur à la connexion'
    
    message = 'pwr\n'
    client.send(message.encode())
    try:
        resp = b''
        while True:
            data = client.recv(1024)
            resp += data
            if not data or b'Command completed' in data:
                break
    except socket.timeout:
        return 'erreur durant la lecture'
    finally:
        client.close()
    return resp.decode()


def update_jeedom_variable(values, cmd_ids):
    # argument on donne les ID des variables a mettre a jour
    # ainsi que les valeurs issues de pylon
    for cmd_id, col in zip(cmd_ids, VARIABLES):
        requests.get(JEEDOM_URL.format(cmd_id, values[col]))


def update_jeedom():
    etat = 'ok'
    resp = question_pylon()
    if 'erreur' in resp:
        etat = resp
    else:
        resp = decode_data(resp)
        for n_batterie, cmd_ids in BATTERIES.items():
            update_jeedom_variable(resp[n_batterie], cmd_ids)
    requests.get(JEEDOM_URL.format(CMD_ID_RETOUR, etat))


update_jeedom()

Bonsoir, pour info: