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
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 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).
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):
Ensuite ajout d’une commande info (l’auto actualisation ne fonctionne pas pour une commande action)
Voici à quoi cela ressemble avec la connexion en erreur:
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.