← Все материалы

Программная часть городской системы мониторинга воздуха

31 мая 2026 · Услуги: Данные · Legacy Perl

В середине 2010-х я работал над программной частью проекта, связанного с городской системой мониторинга атмосферного воздуха Санкт-Петербурга. Это была не обычная веб-разработка, а часть городской инфраструктуры: автоматические станции по районам города, газоанализаторы, регулярные измерения, передача данных в центр сбора и обработки, хранение показаний и публикация информации.

По сути, это была промышленная система с приборами и удалённым сбором данных до того, как термин «интернет вещей» стал массовым. В системе были реальные приборы, COM-порты, модемная связь, промежуточные файлы измерений, центральная обработка, отчётность и требования к надёжности. Моя работа относилась к одному из программных слоёв уже существующей городской инфраструктуры: не вся система создавалась с нуля, но станционную часть нужно было привести в более сопровождаемое состояние.

Отправить бриф

Офлайн-карта Санкт-Петербурга с точками станций мониторинга воздуха

Рисунок 1. Офлайн-карта с точками станций мониторинга воздуха. Такие физические точки наблюдения были главным источником данных для программной части.

Контекст системы

Городская система использовалась для экологического мониторинга атмосферного воздуха. Автоматические станции непрерывно измеряли загрязняющие вещества, а результаты с регулярным интервалом попадали в центральную базу и дальше использовались для обработки, отчётности и информирования.

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

Система работала автоматизированно с измерением оксида углерода, оксида азота, диоксида азота, взвешенных частиц PM10 и диоксида серы. Неавтоматизированно наблюдались бензол, толуол, этилбензол, ксилолы, фенол. Часть таких измерений могла делаться через полуавтоматический отбор проб с последующим лабораторным анализом.

Исходное состояние

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

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

Что нужно было сделать

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

Репозиторий, документация и поставка

Первый слой работы был организационно-инженерным: привести код и документацию в состояние, с которым можно жить. Для изменений был зафиксирован процесс через задачи и отдельные ветки. Коммиты привязывались к задачам, перед слиянием изменения тестировались, а ветка master рассматривалась как версия для продакшена, которую можно взять для установки на рабочую станцию.

Это не был современный облачный CI/CD в смысле контейнеров, staging-кластеров и автоматического деплоя на каждую станцию. У станций могли быть ограничения по связи, часть обновлений выполнялась на месте. Но это был важный для проекта шаг к управляемой поставке: код перестал быть набором файлов "где-то в проде", появилась история изменений, появились правила попадания в продакшен, появилась тестовая станция и появился понятный способ обновлять рабочие станции из репозитория.

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

Схема работы программного обеспечения станции мониторинга атмосферного воздуха

Рисунок 2. Схема работы программного обеспечения станции мониторинга из рабочих материалов проекта.

Станционная часть

Станция была не абстрактным "клиентом API", а компьютером рядом с измерительным оборудованием. К нему подключались газоанализаторы, метеодатчики, радиационные датчики и служебное оборудование. Значительная часть обмена шла через последовательные порты, поэтому в документации отдельно описывались MOXA-платы для расширения количества COM-портов и привязка конкретных приборов к конкретным устройствам вроде /dev/ttyM0, /dev/ttyM3 или /dev/ttyS0.

В рабочих материалах были описаны разные классы приборов: ThermoElectron, Environnement, Horiba, Automet, WXT520, DKGRAD, FDS. Для них фиксировались измеряемые параметры и единицы: NO, NO2, SO2, CO, O3, PM10/PM2.5, температура, влажность, давление, скорость и направление ветра, радиационный фон. Это хорошо показывает природу задачи: программный слой должен был быть устойчивым посредником между физическими приборами и дальнейшей обработкой данных.

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

Экран газоанализатора с показаниями NO, NO2 и NOx

Рисунок 3. Показания прибора на станции: NO, NO2 и NOx в мг/м³.

Внутри станционной части были отдельные процессы для сбора и контроля данных. Результаты измерений складывались в рабочие каталоги, а центр мог забирать подготовленные файлы. Для инженера на станции важны были воспроизводимые команды: что запустить, где посмотреть живые показания, как проверить порт, как не потерять данные после перезагрузки.

Tiny Core Linux

Отдельной частью проекта была станционная операционная система на Tiny Core Linux. Это был прагматичный выбор для полевых условий: система загружалась с флешки, работала в оперативной памяти и позволяла сохранять нужную конфигурацию обратно на носитель. Такой подход упрощал обслуживание станции и снижал зависимость от состояния локального диска.

Рабочее окружение станции включало Perl, git, minicom, pppd, inetutils, Log::Log4perl, JSON и дополнительные пакеты для работы с последовательными портами. Часть зависимостей приходилось собирать и упаковывать отдельно в формат Tiny Core, например модули Perl для SerialPort и BufferedSelect, драйверы MOXA, mgetty и редактор Vim. Это была низкоуровневая эксплуатационная работа: не просто написать скрипт, а сделать так, чтобы он поднимался после перезагрузки станции и продолжал работать рядом с приборами.

Работа с командой

Ещё одна часть результата — подключение людей к проекту. Когда система существует только как код в продакшене и устные знания, стажёра или младшего разработчика невозможно безопасно включить в работу. Сначала нужно описать границы: где документация, где репозиторий, как создаются задачи, что можно менять, что проверяется на тестовой станции, как выглядит рабочее обновление.

После этого стажёры могли брать ограниченные задачи: приводить инструкции в порядок, проверять развёртывание, фиксировать шаги настройки, уточнять конфиги, помогать с переносом знаний в README. Для промышленной системы с унаследованным кодом это не второстепенная работа, а способ снизить зависимость от одного человека и сделать сопровождение более устойчивым.

Результат

  • Код станционной части был собран в репозиторий и стал управляемым артефактом, а не набором файлов в продакшене.
  • Был описан процесс изменений: задачи, ветки, коммиты, тестирование и попадание в продакшен-ветку.
  • Появилась эксплуатационная документация по Tiny Core Linux, пакетам, автозагрузке, ssh, cron, backup и связи станции с центром.
  • Были зафиксированы конфигурационные принципы для приборов, портов, исключения измерений и запуска станционных процессов.
  • Проект стало проще передавать инженерам и младшим специалистам: часть знаний перестала быть устной.
  • Система сохранила прикладной фокус: не переписывание ради переписывания, а повышение сопровождаемости работающей городской инфраструктуры.

Если нужен похожий результат: помогаю разбирать унаследованные системы вокруг данных, восстанавливать документацию, выстраивать репозиторий и процесс поставки, упаковывать эксплуатационные знания и снижать риски сопровождения.

Отправить бриф