Энергомера СЕ102М S7 145-AV
[flickr:id=40031050103]
Отсутствие N в названии модели говорит нам, что для работы интерфейса RS485 не требуется внешнее напряжение 12 вольт.
Протокол обмена
Счётчик работает по протоколу ГОСТ Р МЭК 61107 2001 (В AdminTools необходимо установить протокол ГОСТ IEC61107-2011).
[flickr:id=35448713934]
Очень долго подключал этот счётчик, пытался подавать питание на выводы 7,8 (импульсный вывод) и 11,12 (11-заземление, используется при длинном сигнальном проводе). Увеличивал таймаут и т.д. Все было безрезультатно, пока не увидел информацию про контроль чётности 7-E-1. Для того чтобы его включить необходимо в AdminTools в диалоговом окне настройки канала связи установить галочку "Программный контроль четности 7-E-1".
[flickr:id=35448714094]
Важно!
7+1 программно:
Анализируется каждый байт, если число единиц (в двоичном формате) нечетное, то старший бит устанавливается в 1, четное в 0.
Например, первая посылка к счетчику в режиме 7-1-Чет:
Символами: /?!\r\n
или HEX: 2F 3F 21 0D 0A
Теперь по порядку разбираем каждый байт:
2F = 0010 1111 (5 единиц ) => 1010 1111 = AF
3F = 0011 1111 (6 единиц ) => 3F
21 = 0010 0001 (2 единицы) => 21
0D = 0000 1101 (3 единицы) => 1000 1101 = 8D
0A = 0000 1010 (2 единицы) => 0A
В режиме 7-1-Чет программный(сам канал настроен как 8N1), отправляем: AF 3F 21 8D 0A На приеме можно старший бит сразу отбрасывать (&=7F)
Суть протокола (необходимо прочитать ГОСТ):
-
В начале идёт авторизация, выполняется команда:
/?!\r\n
или/?<address>!\r\n
, возвращается версия ПО. Нам необходимо записать четвёртый байт -, он потребуется для дальнейших команд. -
Выбор режима работы 0 (0x30 чтение) 6 (0x36 чтение ограниченного набора параметров) и 1 (0x31 режим записи). Команда в этом случае такого вида
<ACK>0<Z>6<CR><LF>
или<ACK>0<Z>1<CR><LF>
-
Далее мы отправляем мнемонику команды, в моем случае ET0PE(), обязательно в конце использовать проверочный байт. Символы
<CR><LF>
не нужны. Команда выглядит так:<SOH>R1<STH>ET0PE()<ETX><LRC>
(env) python counter.py
>> request 2F 3F 31 30 37 31 34 33 34 31 32 21 0D 0A /?107143412!
>> encoded AF 3F B1 30 B7 B1 B4 33 B4 B1 B2 21 8D 0A
<< response 2F 45 4B 54 35 43 45 31 30 32 4D 76 30 31 0D 0A
>> request 06 30 35 36 0D 0A *056
>> encoded 06 30 35 36 8D 0A
<< response 02 45 54 30 50 45 28 30 2E 31 30 29 0D 0A
>> request 01 52 31 02 45 54 30 50 45 28 29 03 37 *R*ET0PE()*7
>> encoded 81 D2 B1 82 C5 D4 30 50 C5 28 A9 03 B7
<< response 28 30 2E 31 30 29 0D 0A
0.1
Программа для расчёта
#!/usr/bin/python
# coding: utf-8
def get_lrc(message_byte_array):
message = str(bytearray(message_byte_array))
lrc = 0x00
lrc_add = False
for i in range(0, len(message)):
if message[i] == '\x01':
lrc_add = True
elif message[i] == '\x02':
if lrc_add:
lrc = (lrc + ord(message[i])) & 0x7f
else:
lrc_add = True
elif message[i] == '\x03':
lrc_add = False
lrc = (lrc + ord(message[i])) & 0x7f
else:
if lrc_add:
lrc = (lrc + ord(message[i])) & 0x7f
return [lrc]
В этом протоколе команды реализованы через мнемоники ET0PE()
, SNUMB()
, полный перечень команд представлен в инструкции к устройству в приложении Д. А общение с устройством происходит непрерывно. Если задержки между командами больше допустимых, устройство считает что произошла ошибка и возвращается в начальное состояние. Так же есть несколько типов команд отличающихся по структуре. Это лучше всего смотреть в протоколе, ссылки приведены ниже. Я бы сказал что это самый неудачный вариант для опроса через GSM модем, потому что есть жечткая привязка к временным рамкам.
Ссылки
ГОСТ Р МЭК 61107-200141 стр. 9-10
Полный исходный код для считывания показаний Энергомера 102 М S7 по TCP/IP
Чтение счетчика по rs485 на языке python