ЭСКО: чтение данных

Обмен

Содержание

Пакеты

Запрос — 14 байт:

00 BA CMD P0 P1 D0 D1 D2 D3 D4 D5 D6 D7 KS

Обычный ответ — 14 байт, CMD_response = CMD | 0x80.

KS = sum(packet[:-1]) & 0xFF

Проверяются длина, начальный 00, адрес, команда и сумма. Поля ответа: R/G/M/L — байты 3–4 совпадают с запросом; T/G — байт 3 равен 47; P/1/G — байты 3–5 совпадают с запросом; A — совпадает байт 3, байт 4 уже относится к записи. Приём потоковый: ответ может поступать частями. Точное эхо запроса перед ответом отбрасывается. Межбайтовый интервал при передаче запроса прибору — не более 0,5 с.

Параметры обмена: таймаут полного ответа 5 с, число попыток ≥1 задаётся вызывающей стороной. Нет ответа или неверный пакет → пауза, очистка приёмного буфера, повтор. После исчерпания попыток — ошибка. Отмена проверяется до запроса и после ответа, в том числе при сканировании FLASH.

Чтение памяти

CMD Hex Память
R 52 EEPROM
G 47 RAM
M 4D Состояние ЭСКО-Т
L 4C FLASH ЭСКО-Т
Запрос: 00 BA CMD AH AL 00 00 00 00 00 00 00 00 KS
Ответ:  00 BA RSP AH AL D0 D1 D2 D3 D4 D5 D6 D7 KS

Адрес — UInt16 BE. Для R/G/M адрес байтовый, для L — номер блока по 8 байт. Данные ответа: packet[5:13].

Заводской номер: R 0x0000, восемь ASCII-цифр. Пустой ответ и нецифровые символы отклоняются. При сравнении ведущие нули не учитываются (00000027 = 27). Несовпадение номера прекращает опрос до использования данных.

Часы: T/G

Запрос: 00 BA 54 47 00 00 00 00 00 00 00 00 00 KS
Ответ:  00 BA D4 47 00 ss mm hh wd DD MM YY 00 KS

Дата и время — BCD; год 2000 + YY (2000–2099). Проверяется календарная корректность. wd — день недели. Время локальное, часовой пояс не передаётся.

Архив по дате: A/4

Запрос: 00 BA 41 04 AT YY MM DD hh mm 00 00 00 KS
Ответ:  00 BA C1 04 [payload] KS
AT Архив Граница запроса
0 Часовой Начало часа
1 Суточный 00:00 суток
2 Месячный Первое число месяца, 00:00

Дата — BCD. Поддержка AT=2 зависит от версии прибора; альтернативное чтение — по адресам/страницам FLASH.

Прибор Размер payload Полный ответ Срез payload
ЭСКО-Т 64 69 packet[4:68]
МТР-06 256 261 packet[4:260]

Последний байт payload — внутренняя сумма:

KSI = (~sum(payload[:-1])) & 0xFF
sum(payload) & 0xFF == 0xFF

Внешняя KS и внутренняя KSI проверяются независимо.

Поиск возвращает запись с датой не меньше заданной либо последнюю запись. Фактическую дату ответа необходимо сверять. Запись другой календарной границы отклоняется. Запись внутри запрошенного часа/суток/месяца со сдвинутой отметкой считается частичной: накопленные значения помечаются недостоверными, приращение не вычисляется.

Форматы

Все многобайтовые целые — big-endian.

Поле Кодирование Масштаб
Q BCD, 7 байт /1e9, Гкал
M BCD, 7 байт /1e6, т
V BCD, 7 байт /1e6, м³
Архивное время работы BCD, 4 байта /100, ч
Архивная температура UInt16 /256, °C
Архивное давление UInt8 /100, МПа
Архивная дата BCD, 5 байт YY MM DD hh mm

BCD: каждая тетрада 0–9. Например, 12 34 → 1234. Тетрады A–F недопустимы.

24:00 нормализуется в 00:00 следующих суток. 24:xx при ненулевых минутах отклоняется.

Тип давления (абсолютное/избыточное) единицей МПа не определяется и требует проверки исполнения.

Обработка интервалов

Архивная дата — конец интервала. Для суток D нужны записи на D 00:00 и D+1 00:00:

consumption_date = start_boundary
dQ    = Q_end - Q_start
dM    = M_end - M_start
dV    = V_end - V_start
dTime = Time_end - Time_start

Температуры, давления и ошибки берутся из конечной записи. Для месяца конечная граница — первое число следующего месяца.

Без двух точных соседних записей приращение не вычисляется. Уменьшение счётчика проверяется на сброс/переполнение. Уменьшение времени нормальной работы без переполнения блокирует все приращения контура; средние температуры и давления этого интервала помечаются недостоверными. Сброс отдельного Q/M/V исключает его приращение и отмечает сброс накопленных значений.

Счётчик Модуль
Q 100 000 Гкал
M/V 100 000 000 т/м³
Время 1 000 000 ч

При подтверждённом переполнении: delta = modulus - previous + current. При сбросе приращение не определено. Критерий переполнения: previous > 0.9*modulus и current < 0.1*modulus.

Контроль длительности: час — до 1 ч, сутки — до 25 ч, месяц — до календарных часов плюс 1 ч. Это проверка правдоподобия с учётом перевода часов, не ограничение формата.

Расчётное время без питания:

NoPower = calendar_hours - sum(five_duration_deltas)

Расчёт выполняется, если определены все пять приращений и их сумма ≤ calendar_hours + 0.05. Результат ограничивается снизу нулём. При большей сумме значение отсутствует. Перевод часов способен сделать календарный расчёт неоднозначным.

Последовательность опроса

  1. Прочитать обязательную конфигурацию и проверить номер; определить используемые каналы/контуры.
  2. Прочитать часы: device_time, запомнить монотонное время приёма t0. Далее device_now = device_time + elapsed(t0).
  3. Для архива привести начало/конец периода к его границам. Шаг — 1 час, 1 сутки или 1 календарный месяц.
  4. Прочитать накопленные значения на начальную границу, затем на конец каждого интервала. Последний допустимый конец ≤ device_now; незавершённые интервалы пропускаются.
  5. Сохранить исправные накопленные значения. При точной паре вычислить приращения; отсутствие начала не препятствует чтению последующих интервалов.
  6. Ошибки точной конечной записи отнести к началу интервала, даже если начальный интегратор отсутствует. По частичной записи ошибки к полной строке не относятся.
  7. Для текущих показаний обновить часы; отдельно получить мгновенные величины и накопленные интеграторы. Между текущими интеграторами и последним архивом разность автоматически не вычислять.

Оценка доступного периода по ёмкости: B = floor(device_now), начальная граница B - depth шагов, последняя дата потребления B - 1 шаг. Начало ограничивается 01.01.2000. Это оценка, фактическое наличие проверяется ответами.

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

Примеры запросов, BA=0

Запрос Hex
R 0x0000 00 00 52 00 00 00 00 00 00 00 00 00 00 52
T/G 00 00 54 47 00 00 00 00 00 00 00 00 00 9B
A/4, сутки, 26.10.2026 00:00 00 00 41 04 01 26 10 26 00 00 00 00 00 A2