Monitorer batteries Pylontech

Tags: #<Tag:0x00007fcb9ef8d100>

Edit du 05/01/2021: ajout gestion socket.timeout si HF est bien connecté mais pas les batteries
Edit du 04/01/2021: ajout gestion erreur socket.connect si HF non connecté

Bonjour à tous, juste un petit retour et partage d’expérience au cas où quelqu’un cherche à suivre ses batteries Pylontech associées à un onduleur solaire ou autre.

Pour l’instant je n’ai reçu que les batteries donc je n’ai travaillé que sur cette partie. Je suis nul en présentation et ne me donne pas la peine de faire qq chose de joli, l’important pour moi c’est que ça fonctionne alors si vous avez des idées à me soumettre pour améliorer les choses je n’ai aucun souci là dessus :wink:

Donc mon point de départ: je compte faire installer des panneaux solaires associé à un onduleur hybride Sofarsolar. Je rajouterai moi même les batteries Pylontech et je les ai donc déjà commandées. J’en aurai 4 dans un premier temps, à voir si extension plus tard. L’onduleur peut être interrogé via un port RS485 en ModBus et les batteries par un port COM en RS282.

Comme je n’ai pas de liaison physique entre le lieu d’installation et mon serveur jeedom j’ai donc acheté chez aliexpress un serveur accessible en wifi et/ou ethernet doté de 2 ports qui peuvent être soit en RS485 soit en RS232 ou mixte http://www.hi-flying.com/hf2221

En bricolant un câble DB9 vers RJ 11 (câblage respectivement de DB9 2, 3 et 5 vers RJ11 3, 2 et 1+4 et ponter sur DB9 1+4+6 et 7+8) j’ai donc réussi à faire se causer mon PC avec les batteries via un port com virtuel (le logiciel fourni avec le HF2221 le permet). Voici les infos que l’on peut récupérer avec la commande pwr envoyé vers les batteries:

pylon>pwr

@

Power Volt   Curr   Tempr  Tlow   Thigh  Vlow   Vhigh  Base.St  Volt.St  Curr.St  Temp.St  Coulomb  Time                 B.V.St   B.T.St  

1     49657  0      26000  23000  23000  3304   3316   Idle     Normal   Normal   Normal   65%      2020-12-21 22:22:39  Normal   Normal  

2     49675  0      26000  23000  23000  3295   3318   Idle     Normal   Normal   Normal   66%      2020-12-21 22:22:37  Normal   Normal  

3     49657  0      26000  23000  23000  3300   3315   Idle     Normal   Normal   Normal   65%      2020-12-21 22:22:37  Normal   Normal  

4     49659  0      25000  22000  22000  3303   3315   Idle     Normal   Normal   Normal   66%      2020-12-21 22:22:36  Normal   Normal  

5     -      -      -      -      -      -      -      Absent   -        -        -        -        -                    -        -       

6     -      -      -      -      -      -      -      Absent   -        -        -        -        -                    -        -       

7     -      -      -      -      -      -      -      Absent   -        -        -        -        -                    -        -       

8     -      -      -      -      -      -      -      Absent   -        -        -        -        -                    -        -       

Command completed successfully

$$


Une fois ceci fait je suis passé à Jeedom. J’ai donc créé un script en python que j’ai uploadé dans html/plugins/script/data/ via Jeexplorer.

Pour le script me suis au départ inspiré du script d’olive (merci à lui). La base était avec un arduino à la place du HF2221 que je voulais utiliser alors j’ai un peu adapté.

Il faut donc en premier lieu créer un virtuel qui affichera toutes les données souhaitées. Pour ma part j’ai voulu récupérer la tension, l’intensité, la température et le SOC de chaque batterie. Donc 4 infos * 4 batteries cela donne un virtuel avec 16 infos (1481, … dans le screen ci dessous). J’en ai ajouté une 17 ème pour la mise à jour commandée des infos (1469 dans le screen).

image

Voici donc le script:

#!/usr/bin/python

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 = '192.168.1.18' #adresse IP du HF2221
	PORT = 8899
	server_address = (HOST, PORT)
	try:
#	print >>sys.stderr, 'connecting to %s port %s' % server_address
		client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		client.connect(server_address)    
#	print 'Connexion vers ' + HOST + ':' + str(PORT) + ' reussie.'
	except socket.error, e:
		return 'erreur'
		sys.exit(1)
	message = 'pwr'
	client.settimeout(3)
	n = client.send(message + chr(13))
	try:
		resp = client.recv(1024)
	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 = 'mettre ici l'IP de votre JEEDOM'
cmdapi = 'mettre ici votre propre clé API' #cle API a prendre dans le virtuel que l on veut mettre a jour
cmdidbat = ['1468','1470','1471','1472'] #valeurs des cmdid pour la batterie 1 tension, intensite, temperature, SOC
cmdidbat += ['1473','1474','1475','1476'] #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 = '1499' #valeur de la cmd retour d etat connexion
rep = question_pylon()
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(4): #remplacer range(4) par range(x) en fonction du nombre x de batteries installees
	  tension = str(float(rep[x+7+(141*i):x+12+(141*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+(141*i):x+19+(141*i)]) /1000)      # intensite
	  temper=str(float(rep[x+21+(141*i):x+26+(141*i)]) /1000)      # temperature
	  soc=rep[x+92+(141*i):x+94+(141*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)

Ensuite il faut créer un objet script dans le plugin script que j’ai appelé « pylontech » avec une auto actualisation toutes les minutes (peut être trop, je verrai à l’usage):

image

Ensuite ajout d’une commande info (l’auto actualisation ne fonctionne pas pour une commande action)

image

Voici à quoi cela ressemble avec la connexion en erreur:

image

Voilà, il y a peut être plus simple mais comme je suis 100% autodidacte je suis assez content de moi. S’il y en a qui se sente de me corriger pour améliorer les choses je n’ai absolument aucun problème avec ça, bien au contraire.

J’espère que cela peut servir à d’autres, au moins pour la méthode.

2 J'aimes

Non c’est très bien ce que tu à fait, bravo.
Je suis content de t’avoir inspiré.

1 J'aime

mon problème c’est toujours le point de départ et pouvoir m’inspirer de qq1 d’autre est toujours une grande aide pour moi.

Merci à toi :wink:

par contre, sais tu comment on peut mettre à l’heure les batteries? J’ai essayé quelques commandes mais rien ne passe…

Non j’ai le même problème (c’est a l’heure chez moi mais pas dans le bon fuseau horaire …)

Bonjour,

Pour mettre à l’heure, je l’ai fait en port série avec la commande « time ».
(même style de commande que « getpwr x », « pwr », …)
Je n’ai plus la syntaxe en ligne, mais il me semble qu’en mettant juste time, on voit.

1 J'aime

j’ai trouvé aussi merci @LaurentP
en faite la syntaxe est dans la commande help …
on trouve :

time Time - time [year] [month] [day] [hour] [minute] [second]
il faut donc dans la case inscrire comme suit :
Capture d’écran du 2021-01-23 23-57-41
et faire Envoyer
notez que l’année est sur 2 chiffres

Merci @LaurentP, j’avais bien tenté cette commabde mais avec l’année sur 4 chiffres…

Top, merci