Хабрахабр

[Из песочницы] Получаем данные со счетчиков Меркурий 203.2Т по RS-485

Производители оборудования видимо тоже хотят зарабатывать на продаже своего ПО. Организовать удаленный сбор показаний с электросчетчиков — задача вроде не сложная, счетчики с каждым годом все умнее и умнее и должны сами все отправлять, ан нет, информация конечно есть, но она разрозненная. Пишу эту статью чтобы сэкономить время всем, у кого есть похожие задачи.

Начало

На предприятии нужно было автоматизировать сбор показаний с электросчетчиков, порядка двадцати штук. Сделать это требовалось быстро и максимально дешево. Поэтому приняли решение собирать данные с помощью уже развернутого Zabbix, а вот для подключения к счетчику потребовалось написать небольшой скрипт, об этом ниже. Так вышло, что сбор показаний, это лишь один из параметров, который нужно собирать, за остальные отвечает ПК с Debian на борту, поэтому не было сложности подключиться к счетчику через COM-порт. Конечно, для большинства, будет удобнее использовать локальную сеть и получить информацию с промышленного коммутатора или конвертера интерфейсов.

Из вариантов подключения также можно рассматривать оптопорт, правда потребуется приобретать дополнительный девайс, с другой стороны — не нужно снимать пломбу.

Но в итоге, договоренности были достигнуты и можно было спокойно заниматься решением основной задачи. Клеммы для подключения к счетчику находятся под опломбированной крышкой.
Поэтому нам пришлось договариваться сетевой компанией о том что, нужно снимать пломбы, выполнять работы, заново пломбировать счетчики.

Решение задачи

Как следует из официальной документации.

Счетчик, принимает на вход строку байтов формата ADDR-CMD-CRC, а отдает ADDR-CMD-DATA-CRC, где:

  • ADDR — Имя счетчика (для меркурий 203.2Т — совпадает с серийным номером)
  • CMD — Код команда
  • DATA — Данные, зависят от запроса
  • CRC — 2х байтовый циклический избыточный код, вычисляемый по всем предшествующим байтам данного пакета. Из этого объяснения не понятно что записывать в поле контрольной суммы.

Дефис в последовательности не используется, здесь использован для разделения логических блоков.

Ниже, строка полученная от счетчика. Первым делом, подключимся к счетчику с помощью стандартной программы konfigurator и, с помощью сниффера, посмотрим на передаваемые пакеты, выясним какую контрольную сумму нужно добавлять в конец.

Воспользовавшись онлайн калькулятором CRC выясняем, что нужно вычислить CRC-16 (Modbus) с полиномом 0xA001.

Немного Python

Ссылок на алгоритм вычисления достаточно, поэтому не буду останавливаться на нем. Для разработки я использовал 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

Теперь попробуем получить от счетчика его серийный номер и проверить CRC. Понадобится установить модуль pyserial

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(''.format(c) for c in out))

Отлично! Теперь получим значения для израсходованной энергии по первому и второму тарифам, на самом деле нам нужно изменить только поле команды и распарсить результат.

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, '(кВт*ч)')

Все работает. Конечный вариант скрипта выложил на git. В перспективе, планирую добавить поддержку работы по локальной сети.

Для разработки использовался Адаптер USB -> COM «Меркурий-221», но можно напрямую подключать счетчик к COM-порту.

Ссылки:

Полезная информация по подключению счетчиков находится тут
Документация на официальном сайте
Сайт техподдержки
Про CRC на Википедии

Показать больше

Похожие публикации

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»