Коллеги, добрый день!
Возникла у нас проблема: поменяли несколько приборов ТЭМ-104. Прошивка у приборов не изменилась — S10X v3.07 и осталась как и на старых версиях. ТЭМ-104 — это прибор учёта теплоносителя. При опросе использовали следующие адреса регистров:
8704 — температура ПТР
8708 — температура ОТР
8768 — объёмный расход теплоносителя ПТР
8772 — объёмный расход теплоносителя ОТР
⚠️ Проблема
В регистрах нуль. Посмотрели логи, data → 00 00, то есть буквально прибор отвечает нормально, но в кадре данных нуль (00 00). Нас интересовали мгновенные (real-time) параметры для отображения на мнемосхеме:
-
температура
-
давление (при наличии датчика)
-
объемный расход
Очевидно, что данные куда-то переехали, в другую область памяти (любия фишка производителя).
🔍 Проверка гипотезы
Встал вопрос, а что делать, как достать данные из прибора? Первая мысль, проверить, а шлет ли прибор вообще real-time данные. Подключились через Tesmastat (заводское ПО), прочитали мгновенные и архивные показания, проблем нет (скриншот прилагаю). Значит проблема не в приборах, а в адресах регистров.

🧠 Решение
Решили, что надо подсмотреть, какие запроса отправляет Tesmastat и какие ответы получает, то есть проверить логику работы request/response. Wireshark отпал сразу, так как отдел защиты информации запрещает перехватывать трафик ЛВС. Решили локально перехватить трафик при общении между Tesmastat и TЭМ-104 и написать свой скрипт — sniffer.
Sniffer (подключение через rs-485/232)
Sniffer № 1 $max_len_request=1024$max_len_response=1024$sleep = 1000$out=New-Object System.IO.Ports.SerialPort COM4, 9600, None,8,one$in=New-Object System.IO.Ports.SerialPort COM14, 9600, None,8,one$latin1 = [System.Text.Encoding]::GetEncoding("ISO-8859-1")$in.Encoding = $latin1$out.Encoding = $latin1try { $in.Open() $out.Open() while ($true) { if ($out.BytesToRead -gt 0) { [byte[]]$data = New-Object byte[] $max_len_response $count_byte_response = $out.Read($data, 0, $max_len_response) $in.Write($data, 0, $count_byte_response) Write-Host ("Ответ:") -ForegroundColor Red Write-Host ($data[0..($count_byte_response - 1)] | ForEach-Object { "{0:X2}" -f $_}) -ForegroundColor Red Write-Host ("Длина: $count_byte_response" ) -ForegroundColor Red Write-Host "`n" -NoNewLine } [System.Threading.Thread]::Sleep($sleep) if ($in.BytesToRead -gt 0) { [byte[]]$data = New-Object byte[] $max_len_request $count_byte_request = $in.Read($data, 0, $max_len_request) $out.Write($data, 0, $count_byte_request) Write-Host ("Запрос:" ) -ForegroundColor Green Write-Host ($data[0..($count_byte_request - 1)] | ForEach-Object { "{0:X2}" -f $_}) -ForegroundColor Green Write-Host ("Длина: $count_byte_request" ) -ForegroundColor Green Write-Host "`n" -NoNewLine } }} finally { $in.Close() $out.Close()}
Можно было выполнить подключение через Moxa NPort, но суть не меняется.
🛠️ Реализация
-
Запускаем Tesmastat
-
Запрашиваем мгновенные значения
-
Перехватываем весь трафик
-
Анализируем перехваченный трафик
Получаем сырой request/response.. Приступаем к реализации.
📦 Чтение текущих данных

📦 Пример перехвата

🔎 Поиск значений
Для поиска нужных значений, взяли в Tesmastat мгновенные показания, для температуры: 65 градусов по трубопроводу ОТР –> переводим в HEX и ищем в перехвате совпадение. Таким образом находим нужный блок данных, понимаем, на какой адрес он пришел и определяем адрес регистра.
🎯 Результат
В итоге нашли следующие регистры:
-
ПТР расход теплоносителя —
57992 -
ОТР расход теплоносителя —
57996 -
ПТР температура теплоносителя —
57856 -
ОТП температура теплоносителя —
57860
Для работы нашей мнемосхемы этого достаточно.

Заключение
Для работы приходится выдвигаться в место непосредственной локации прибора. Если у вас нет проблем с информационной безопасностью, то всё это можно делать непосредственно с рабочего места (не забудт остановить опрос со стороны автоматизированной системы).
Теперь сразу отвечу тем, кто скажет: а почему вы не взяли описание протокола опроса прибора. Потому что там внятно не описано, где искать real-time показания, плюс к тому же есть смещение. Мы искали информацию, звонили поставщикам. Были варианты, но они не сработали.
Кстати, сейчас также встаёт вопрос с выгрузкой архивов, но там всё сложнее, возможно, некорректно настроена логика опроса на уровне самой системы учёта, что лечится только корректировкой последней.
Спасибо всем, кто дочитал!
Надеюсь, этот опыт будет полезен.
ссылка на оригинал статьи https://habr.com/ru/articles/1030430/