Телеметрия: факт против модели
Телеметрия: датчики давления, температуры и расхода — показания против расчёта, графики, выгрузки ОДПУ, датчики на карте.
Возможности
- Сравнить показания датчиков давления, температуры и расхода с последним расчётом фрагмента: факт, модель и расхождение в одной строке, оценка «норма», «внимание», «расхождение», «молчит».
- Тревоги: датчик разошёлся с моделью или замолчал. Последние пять видны сверху окна, остальные — числом «и ещё N». «Принято» снимает тревогу из списка.
- График показаний выбранного датчика за сутки, неделю или месяц с линией расчётного значения.
- Завести датчик: код в SCADA или ОДПУ, название, что измеряет, труба (подача, обратка), единица и место — узел для давления и температуры, участок для расходомера. Изменить и удалить датчик вместе с показаниями.
- «Загрузить выгрузку ОДПУ» — показания из файла CSV, TXT или XLSX.
- «Шкала времени на карте» — датчики точками цвета оценки за сутки, 3 суток или неделю; ползунок и «Проиграть» листают моменты.
- «Калибровка» — потери напора между соседними датчиками давления одной трубы: модель против факта и подсказка шероховатости.
- «Режим» — напоры и температура источников и подкачек по датчикам против расчёта; «Рассчитать по факту» — расчёт фрагмента с напорами из показаний.
- «Баланс» — зоны между расходомерами: приток против модели и ночной расход за прошлые ночи; контур зоны — на карте.
- «Прогноз» — нагрузка источников на сутки по прогнозу погоды (отдельная страница «Прогноз нагрузки по погоде»).
Как это работает
Датчики и показания. Датчики хранятся в tgid_sensor, показания — в tgid_sensor_reading. Показания приходят файлом ОДПУ из окна или от шлюза SCADA через API v2. Время без часового пояса считается местным временем сервера города. Будущее время принимается с запасом не больше 24 часов, остальное отбрасывается с пометкой.
Файл — до 20 МБ и 200 000 строк, кодировка UTF-8 или Windows-1251. Два вида таблицы: «время, код, значение» (строка — одно показание) или «время, <код датчика>, <код датчика>…» (строка — момент, колонки — датчики). Коды, которых нет среди датчиков, перечисляются в итоге загрузки.
С чем сравнивается. Модель — последний расчёт фрагмента, в котором стоит датчик, любой: плановый, по факту, на другую температуру воздуха. Давление сравнивается как напор над отметкой узла (us_out.pih, м вод. ст.), поэтому кгс/см², бар, МПа и кПа пересчитываются в метры: 1 кгс/см² = 10 м, 1 бар = 10,197 м, 1 МПа = 101,97 м. Температура — с us_out.t, расход — с модулем расхода участка (ut_out.a13, т/ч; м³/ч × 0,975).
Пороги: давление и расход — «норма» до 5 %, «внимание» до 10 %, дальше «расхождение»; температура — до 2 °C и до 5 °C. Датчик «молчит», если последнему показанию больше 60 минут. Расхождение по давлению и расходу показывается в процентах, по температуре — в градусах.
Тревоги. Раз в минуту фоновый проход API сверяет оценку каждого действующего датчика с прошлой и записывает переход в tgid_sensor_alert: «расхождение с моделью», «датчик молчит», «вернулся в норму». «Внимание» тревоги не даёт. Первая оценка нового датчика только запоминается. Тревога открыта, пока её не приняли и пока у датчика нет более новой — вернувшийся в норму датчик снимает свою тревогу сам. Те же переходы уходят подписчикам вебхуков: sensor.deviation, sensor.silent, sensor.recovered.
График. Показания сводятся в интервалы так, чтобы точек было не больше 500: сутки — по 5 мин, неделя — по 30 мин, месяц — по 3 ч. Окно обновляет список раз в минуту, пока открыто.
Шкала времени. Средние показания действующих датчиков с местом на карте — не больше 144 кадров за период: сутки по 15 мин, 3 суток по 30 мин, неделя по 3 ч. Модель для всех кадров одна — последний расчёт. Период — не больше 31 суток. Шкала видна, пока в списке не выбран датчик.
Калибровка. Для пары соседних датчиков давления на одной трубе берётся среднее за 30 минут до последнего показания каждого датчика и путь по сети между узлами (до 20 км, без насосных станций). Отношение потерь «факт / модель» в пределах ±10 % — «согласовано». Погрешность отношения — √2 × 0,5 м, делённое на потерю по модели; отклонение не больше двух погрешностей — «в погрешности». Отношение больше 1,5 — «местное сопротивление» (прикрытая задвижка, засор), меньше 0,5 — «проверить датчики». Между 0,5 и 1,5 — «шероховатость»: предлагается эквивалентная шероховатость, прежняя × отношение⁴, в пределах 0,05–5 мм. Пары с потерей по модели меньше 1 м не сравниваются и перечислены под таблицей. Модель здесь не меняется.
Режим. Узлы заданного напора (источники, подкачки) с датчиками: уставки, напоры и температура подачи из последнего расчёта и среднее показаний за 15 минут. «Режим изменился» — отличие больше 2 м или 2 °C. «Рассчитать по факту» ставит в очередь расчёт фрагмента: напоры источника из показаний, температура воздуха — из поля «Tн, °C»; пустое поле — погода текущего часа (округлённая, в пределах графика), без погоды — Tн последнего расчёта. Кнопка неактивна, пока у источника нет свежих показаний.
Баланс. Расходомеры делят сеть на зоны: «зона между расходомерами», «источник — подпитка», «с питающей точкой без расходомера» (такая зона «не закрыта» и не сводится). Приток зоны — средний за 60 минут — сравнивается с моделью. Погрешность расходомера — 2 %. «Небаланс» — приток больше модели сверх двойной погрешности; меньше модели на столько же — «проверить»; иначе «сходится». Ночной расход — с 2 до 5 ч местного времени за 7 ночей, нужны хотя бы 3 прошлые ночи; рост считается тревожным, если он больше трёх отклонений прошлых ночей и не меньше 5 т/ч. Тревоги баланса записываются в tgid_balance_alert не чаще раза в 15 минут и уходят вебхуками balance.imbalance, balance.night_growth, balance.recovered.
На карте. «На карте», шкала времени, пара калибровки и контур зоны рисуются поверх сети. Окно телеметрии большое и с затемнением, поэтому рисунок виден по краям окна; при закрытии окна он снимается.
Что нужно для работы
- Расчёт фрагмента, в котором стоят датчики, — иначе в строке «нет расчёта». Для «Режима» — узлы заданного напора с датчиками давления или температуры. Для «Баланса» — расходомеры на участках.
- Просмотр — всем, кто вошёл.
- «Датчик», изменить и удалить — право «Справочники и шаблоны карточек» и включённая запись на сервере.
- «Загрузить выгрузку ОДПУ» и «Принято» у тревог — право «Журналы: ремонты, ПТС, акты, ТУ, привязки».
- «Рассчитать по факту» — право «Запуск расчётов».
- Любая запись — правка данных включена на сервере.
Шаги
Откройте «Инструменты» и наберите в поиске «Телеметрия: факт против модели» — пункт выделен рамкой.

Нажмите пункт — откроется окно.

«Загрузить» в «Шкале времени на карте» — датчики точками цвета оценки на последний момент; ползунок и «Проиграть» листают моменты. Шкала видна, пока датчик не выбран; крестик у выбранного датчика возвращает к ней.

Выберите датчик — справа график его показаний за период и линия расчётного значения модели: видно, когда и насколько факт ушёл от расчёта.

«Калибровка» — потери напора между соседними датчиками одной трубы: по модели и по факту, их отношение и эквивалентная шероховатость, которая объяснила бы разницу. Модель здесь не меняется — это подсказка, что проверить (датчики, диаметры, расход) и какие значения внести групповыми установщиками или в сценарии.

«Режим» — напоры и температура в узлах заданного напора (источники, подкачки) в последнем расчёте и по датчикам; «режим изменился» — отличие больше 2 м или 2 °C. «Рассчитать по факту» (право «Запуск расчётов») ставит в очередь расчёт фрагмента с напорами источника из показаний; пустое поле «Tн, °C» — температура текущего часа по погоде. Расчёт станет последним расчётом фрагмента. Без свежих показаний источника кнопка неактивна.

«Баланс» — сеть делится расходомерами на зоны; приток в зону сравнивается с моделью и ночным расходом прошлых ночей. «Небаланс» — приток больше модели сверх двойной погрешности расходомеров (2 %): утечка или неучтённый водоразбор; кнопка в строке рисует зону на карте (у зоны из одного узла кнопки нет).

Примеры
Учебные датчики на копии Алматы. 14 датчиков пилота «Н-ТЕСТ»: давление в узлах 2-20, 2-40А, 7-10, 7-31 и ТЭЦ-1, температура и расходомеры на выходе ТЭЦ-1. Модель — расчёт №3 фрагмента «Маг. сети для расчета НС» при −25 °C. Последние показания — в ночь на 6 ноября, поэтому плитки: «Датчиков» 14, «Молчат» 14, сверху 14 тревог «датчик молчит». Оценка расхождения по последнему показанию при этом видна: датчик ALM-N220-P2 (обратка в узле 2-20) — 5,859 кгс/см² против 5,903 по модели, −0,8 %; ALM-N731-P1 (подача в 7-31) — 6,914 против 7,887, −12,3 %, «расхождение»; температура подачи ТЭЦ-1 — 62,4 °C против 132 °C, потому что модель посчитана на −25 °C, а не на фактическую погоду.
Калибровка той же копии. Пять пар. Подача 7-10 → 7-31: 3,03 км, 24 участка, Ду 704–996 мм, потери 13,29 м по модели и 19,69 м по факту, отношение 1,48 ±5 % — «шероховатость», подсказка 0,5 → 2,41 мм. Обратка 7-31 → 7-10: 12,37 / 13,49 м, 1,09 — «согласовано». Не сравниваются: 2-40А → 7-31 (потеря по модели 0,7 м меньше 1 м) и 2-20 → ТЭЦ-1 (на пути насосная станция).
Баланс. Две зоны: источник ТЭЦ-1 (граница — участок с расходомерами ALM-TEC1-G1 и G2, «нет свежих показаний расходомеров») и открытая зона на 1672 узла, 964 потребителя, 188,46 км.
Если не получается
- «Узла N нет», «Участка N нет» — в поле места указан id, которого нет в базе города.
- «Датчик с кодом «…» уже есть» — код в SCADA должен быть единственным.
- «Не найдены колонки: «время, код, значение» или «время, <код датчика>…»» — в файле нет строки заголовков или колонки названы иначе.
- «Кодировка файла не распознана (нужна UTF-8 или Windows-1251)», «Файл Excel не открывается», «Файл больше 20 МБ — разбейте выгрузку», «Строк больше 200000 — разбейте файл».
- «Принято показаний: 0» и список кодов — коды из файла не заведены как датчики.
- Строка «нет расчёта» — у фрагмента датчика нет ни одного расчёта.
- «Нет годных показаний для расчёта — …» при «Рассчитать по факту» — показания источника несвежие или неполные. «В узлах заданного напора фрагмента нет датчиков давления или температуры» — по факту считать нечем.
- «Пар для сравнения нет…» в «Калибровке» — на одной трубе нет двух соседних датчиков давления с показаниями и расчётом.
- «Зона не найдена — расходомеры или сеть изменились» — расходомеры или сеть поменялись, откройте вкладку «Баланс» заново. У зоны «источник — подпитка» из одного узла кнопки карты нет: участков внутри такой зоны нет, рисовать нечего.
- «Тревога N не найдена или уже принята» — тревогу приняли в другом окне.
- «Шкала времени на карте» пропала — в списке выбран датчик: крестик справа от его названия снимает выбор и возвращает шкалу.
- Датчиков «На карте» не видно — они под окном; после закрытия окна рисунок снимается.
Для администратора
- Пороги и окна:
TELEMETRY_STALE_MIN(молчит),TELEMETRY_CAL_WINDOW_MIN,TELEMETRY_PRESSURE_ACCURACY_M(калибровка),TELEMETRY_REGIME_WINDOW_MIN,TELEMETRY_REGIME_AUTO,TELEMETRY_REGIME_AUTO_MIN(перерасчёт по факту сам при смене режима),TELEMETRY_FLOW_ACCURACY_PCT,TELEMETRY_BALANCE_WINDOW_MIN,TELEMETRY_NIGHT_GROWTH_TH,TELEMETRY_BALANCE_EVERY_S(баланс). - Тревоги проверяет цикл вебхуков API (
WEBHOOK_POLL_S); без него тревоги не появляются. - Таблицы
tgid_sensor,tgid_sensor_reading,tgid_sensor_alert,tgid_balance_alertAPI создаёт сам. Удаление датчика удаляет его показания и тревоги. - Шлюз SCADA:
scripts/telemetry/opcua_gateway.py(OPC UA →/api/v2/telemetry/readingsс ключом API пользователя с правом «Журналы»), имитатор —scripts/telemetry/scada_emulator.py, настройки —gateway.example.json,emulator.example.json. - «Рассчитать по факту» идёт в общую очередь расчётов города и становится последним расчётом фрагмента — от него считают и окна, и карта по умолчанию.
Для разработчика
- API:
GET /api/v1/telemetry/units,/sensors,/sensors.geojson,/sensors/{id}/series,/timeline,/alerts?open=true,/calibration,/regime,/balance,/balance/zones/{key}/geometry,/balance/alerts;POST /api/v1/telemetry/sensors,PUT|DELETE /sensors/{id},POST /import,POST /alerts/{id}/ack,POST /balance/alerts/{id}/ack,POST /regime/run; шлюз —POST /api/v2/telemetry/readings(до 10 000 показаний за запрос). - API, код:
routers/telemetry.py,database/telemetry.py,database/calibration.py,database/telemetry_regime.py,database/flow_balance.py, проверка тревог —database/webhooks.py, события —database/api_events.py. - Веб:
components/TelemetryDialog.vue,components/TelemetryTimelinePanel.vue,components/FlowBalancePanel.vue,components/LoadForecastPanel.vue;utils/telemetry.ts,utils/flowBalance.ts. - Тесты:
tests/utils/telemetry.spec.ts,tests/utils/flowBalance.spec.ts; API —test_telemetry.py,test_telemetry_regime.py,test_regime_queries.py,test_flow_balance.py,test_telemetry_gateway.py; e2e —e2e/functions/other-networks.spec.ts.
