Python : Communiquer avec un onduleur WKS EVO Circle via le port série¶
🧰 Matériel¶
un onduleur WKS EVO Circle et le câble série fourni
un adaptateur USB vers série DB9 RS232 - Mâle / Mâle (ICUSB232V2)
une machine pour exécuter le code Python (PC portable, Raspberry Pi, etc.)
Installation¶
raccorder le câble série fourni avec l’adaptateur USB/série
brancher le câble dans le port COM de l’onduleur, puis l’autre côté dans un port USB de la machine
Code¶
Nous aurons besoin du module pyserial :
python -m pip install pyserial
Et très certainement des droits d’accès au port TTY émulé :
sudo gpasswd -a $USER dialout && exit
# or
# sudo chmod a+rw /dev/ttyUSB0
Cette fonction établit la connexion avec l’onduleur :
import serial
def init_serial(port: str) -> serial.Serial:
return serial.Serial(
port=port,
baudrate=2400,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
)
Celle-ci permet d’envoyer une commande à l’onduleur (comme vu dans le PDF partagé plus haut, une commande est une succession de 3 blocs : COMMANDE+CRC+CR
, où COMMANDE
est un mot clé comme « QID », CRC
est la somme de contrôle de la commande envoyée, et CR
est le caractère permettant de dire à l’onduleur que c’est la fin de l’instruction) :
def send_command(conn: serial.Serial, command: str) -> bool:
full_command = f"{command}{compute_crc(command)}\r"
return conn.write(serial.to_bytes(ord(c) for c in full_command)) == len(full_command)
Pour calculer la somme de contrôle :
def compute_crc(value: str) -> str:
"""
>>> compute_crc("96332309100452")
'?xf3'
"""
crc = 0
for ch in value:
if not ch:
break
crc ^= ord(ch) << 8
for _ in range(8):
crc = crc << 1 if (crc & 0x8000) == 0 else (crc << 1) ^ 0x1021
crc &= 0xFFFF
return crc.to_bytes(2, "big").decode(encoding="latin1")
Enfin, nous pouvons récupérer la réponse de l’onduleur via cette dernière fonction :
def get_response(conn: serial.Serial) -> str:
response = conn.read_until(expected=b"\r")
# Remove leading parenthesis, and trailing CRC + CR
response = response[1:-3]
return response.decode(encoding="latin1")
Exemple¶
Exemple d’utilisation avec la récupération du n° de série de l’onduleur :
>>> conn = init_serial("/dev/ttyUSB0")
>>> send_command(conn, "QID")
True
>>> get_response(conn)
'96332309100452'
Module Spécifique¶
J’ai rendu publique le code pour lire les métriques de l’onduleur, car le n° de série est facile à récupérer en comparaison des informations techniques envoyées en bloc, et ça se passe par là : BoboTiG/python-wks-com. Un aperçu :
python -m pip install -U wks-com
>>> from inverter_com import Inverter
>>> inverter = Inverter("/dev/ttyUSB0")
>>> inverter.send("QID")
'96332309100452'
Et il y a même un exécutable mis à disposition, une fois le module installé :
wks-read --help
wks-read serial-no
Toutes les informations utiles se trouvent dans le dépôt GitHub ☺
📜 Historique¶
- 2024-11-02
Le module Python WKS COM étant maintenant disponible sur PyPI, mise à jour du code d’installation.
- 2024-10-26
Mise à jour du module Python WKS COM (
1.0.1
→1.2.0
).- 2024-01-27
Déplacement de l’article depuis le blog.
- 2023-12-07
Premier jet.