Nous recevons des données des compteurs Mercury 203.2T sur RS-485



Organiser une collecte à distance des relevés des compteurs d'électricité n'est pas une tâche difficile, les compteurs sont de plus en plus intelligents chaque année et doivent tout envoyer eux-mêmes, mais non, bien sûr, il y a des informations, mais elles sont dispersées. Les fabricants d'équipement veulent apparemment aussi gagner de l'argent en vendant leurs logiciels. J'écris cet article pour gagner du temps pour tous ceux qui ont des tâches similaires.

Commencer


L'entreprise devait automatiser la collecte des relevés des compteurs électriques, une vingtaine de pièces. Pour ce faire, il était nécessaire de le faire le plus rapidement et le moins cher possible. Par conséquent, ils ont décidé de collecter des données à l'aide du Zabbix déjà déployé, mais pour se connecter au compteur, il était nécessaire d'écrire un petit script, plus sur celui ci-dessous. Il s'est avéré que la collecte des lectures n'est qu'un des paramètres à collecter, le PC avec Debian à bord est responsable du reste, il n'a donc pas été difficile de se connecter au compteur via le port COM. Bien sûr, pour la plupart, il sera plus pratique d'utiliser un réseau local et d'obtenir des informations d'un commutateur industriel ou d'un convertisseur d'interface.

Parmi les options de connexion, vous pouvez également envisager un port optique, bien que vous deviez acheter un appareil supplémentaire, en revanche, vous n'avez pas besoin de retirer le sceau.



Les bornes de connexion au compteur sont situées sous le couvercle étanche.
Par conséquent, nous avons dû nous mettre d'accord sur une société de réseau dont nous avons besoin pour retirer les joints, effectuer des travaux, refermer les compteurs. Mais finalement, des accords ont été conclus et il a été possible de traiter calmement la solution du problème principal.



Résolution de problèmes


Comme suit de la documentation officielle.

Le compteur prend une chaîne d'entrée d'octets au format ADDR-CMD-CRC et donne ADDR-CMD-DATA-CRC, où:

  • ADDR - Nom du compteur (pour Mercury 203.2T - identique au numéro de série)
  • CMD - Commande de code
  • DONNÉES - Les données dépendent de la demande
  • CRC - Code de redondance cyclique à 2 octets calculé sur tous les octets précédents de ce paquet. D'après cette explication, il n'est pas clair ce qu'il faut écrire dans le champ de somme de contrôle.

Un tiret dans une séquence n'est pas utilisé; ici, il est utilisé pour séparer les blocs logiques.

Tout d'abord, connectez-vous au compteur à l'aide du programme konfigurator standard et, à l'aide d'un renifleur, regardez les paquets transmis, trouvez la somme de contrôle à ajouter à la fin. Ci-dessous, la ligne reçue du comptoir.



En utilisant le calculateur en ligne CRC , nous trouvons ce dont nous avons besoin pour calculer CRC-16 (Modbus) avec le polynôme 0xA001.

Un peu de python


Il y a suffisamment de liens vers l'algorithme de calcul, donc je ne m'y attarderai pas. Pour le développement, j'ai utilisé Python 3

def crc16(data): crc = 0xFFFF l = len(data) i = 0 while i < l: j = 0 crc = crc ^ data[i] while j < 8: if (crc & 0x1): mask = 0xA001 else: mask = 0x00 crc = ((crc >> 1) & 0x7FFF) ^ mask j += 1 i += 1 if crc < 0: crc -= 256 result = data + chr(crc % 256).encode() + chr(crc // 256).encode('latin-1') return result 

Essayons maintenant d'obtenir son numéro de série du compteur et vérifions le CRC. Vous devrez installer le module physique

 import serial import struct import time sn = 26222790 #   ser = serial.Serial('/dev/ttyUSB0', 9600, serial.EIGHTBITS, serial.PARITY_NONE, serial.STOPBITS_ONE) print ('Connected:', ser.isOpen()) # \x2f -      chunk = struct.pack('>L', int(sn)) chunk += b'\x2f' chunk = crc16(chunk) #          ser.write(chunk) time.sleep(1) out = ser.read_all() ser.close() print ('Check CRC:', out[-2:] == crc16(out[:-2])[-2:]) print ('Result string:', ':'.join('{:02x}'.format(c) for c in out)) 

Super! Maintenant, nous obtenons les valeurs de l'énergie consommée aux premier et deuxième tarifs, en fait, il nous suffit de changer le champ d'équipe et d'analyser le résultat.

 chunk += b'\x27' t1 = ''.join('{:02x}'.format(c) for c in out[5:9]) t2 = ''.join('{:02x}'.format(c) for c in out[9:13]) print ('T1 =', float(t1)*0.01, '(*)', 'T2 =', float(t2)*0.01, '(*)') 

Tout fonctionne. La version finale du script publiée sur git . À l'avenir, je prévois d'ajouter un support pour travailler sur le réseau local.

Pour le développement, l'adaptateur Mercury-221 USB -> COM a été utilisé, mais vous pouvez connecter directement le compteur au port COM.



Références:

Des informations utiles sur la connexion des compteurs sont disponibles ici.
Documentation sur le site officiel
Site Web d'assistance technique
À propos du CRC sur Wikipédia

Source: https://habr.com/ru/post/fr418209/


All Articles