.. _connectors_guide: Коннекторы ========== Коннектор — программа, которая читает данные внешнего источника и записывает их в теги платформы. Источником может быть контроллер, прибор, промышленная шина, база или любой другой протокол. Один коннектор рассчитан на один источник и на один протокол: Modbus, OPC, собственный протокол прибора. Несколько одинаковых приборов — несколько запущенных копий одной программы, у каждой свой идентификатор в платформе и свой файл конфигурации. Платформа хранит описание коннектора и список привязанных тегов. Сам коннектор стоит рядом с источником и сам ходит к нему за значениями. Связь с платформой — по MQTT. Где запускать ------------- Коннектор ставят как можно ближе к источнику данных: на компьютер цеха, шлюз рядом с контроллером, ту же машину, где висит последовательный порт. Так короткий и капризный участок — опрос прибора — остаётся локальным. До платформы данные идут уже по MQTT, и этот участок может быть длиннее. Пока MQTT нет, коннектор копит значения в файле буфера на своей машине и отдаёт их после восстановления связи, с исходными метками времени. Как проходит работа ------------------- #. В конфигураторе в папке «Коннекторы» создаётся узел. В конфигурации узла лежат параметры источника (ключ ``source``) и параметры журнала (ключ ``log``). К коннектору привязываются теги: у каждой привязки свои адрес в источнике, выражение JSONata, значимое отклонение и период опроса. #. На машине коннектора лежит короткий файл: идентификатор узла в платформе и адрес MQTT. Полную конфигурацию коннектор получает от платформы и сохраняет у себя на диске. Правка в конфигураторе доходит до уже запущенного коннектора без переписывания этого файла. #. Коннектор открывает MQTT-сессию. Идентификатор сессии — UUID узла коннектора. При обрыве брокер публикует Last Will, и платформа пишет во все привязанные теги ``null`` с кодом качества 100. #. После соединения коннектор запрашивает конфигурацию. Платформа сначала пишет в теги ``null`` с кодом качества 101, затем отдаёт полную конфигурацию. Только после неё коннектор читает источник и присылает текущие значения. #. Прочитанное значение проходит JSONata, приводится к типу тега и сравнивается с последним отправленным. Если отклонение меньше порога ``maxDev``, точка не отправляется. Если связи с платформой нет, точка пишется в буфер. Коды качества 100 и 101 описаны в :ref:`qualityCodes`. Камера с ключом ``rtspUrl`` этой схемой не пользуется: её ведёт сервис подхвата, см. :ref:`video_cameras`. Журнал ------ Коннектор всегда пишет журнал в файл на своей машине. Имя файла, уровень, размер и число архивных копий задаются в блоке ``log`` конфигурации. Пока флажок **Лог в платформу** в конфигураторе выключен, строки остаются только в этом файле. Если флажок включён, те же строки уходят в платформу сообщением ``prsConnector.log_line`` и видны на вкладке **Лог коннектора**. Вывод удалённых команд на эту вкладку не попадает: он идёт отдельно, действием ``prsConnector.command_output``. Ниже — строки, по которым видно, что происходит с коннектором. В журнале перед текстом стоит уровень (``INFO``, ``WARNING``, ``ERROR``). .. list-table:: :header-rows: 1 :widths: 48 52 * - Сообщение - Что произошло * - ``Подключение к брокеру MQTT платформы ...`` - Начата попытка открыть сессию с платформой. * - ``Связь с платформой установлена.`` - Сессия открыта. Следом коннектор запрашивает конфигурацию. * - ``Разрыв связи с платформой: ...`` - Сессия оборвалась. Новые значения пишутся в буфер. * - ``Сообщение от платформы: prsConnector.full_configuration.`` - Пришла полная конфигурация. После первого такого сообщения в этой сессии коннектор читает все привязанные теги. * - ``Сообщение от платформы: prsConnector.connector_configuration.`` - Изменились параметры самого коннектора: источник, журнал, активность. * - ``Конфигурация коннектора изменена.`` - Новые параметры коннектора приняты. * - ``Сообщение от платформы: prsConnector.tags_configuration.`` - Добавлен тег или изменена привязка. * - ``Конфигурация тегов изменена.`` - Список тегов принят, чтение перезапущено с новыми параметрами. * - ``Тег удалён из списка.`` - Тег отвязан от коннектора. * - ``Конфигурация сохранена.`` - Конфигурация записана на диск коннектора. * - ``Коннектор активен, работа по чтению данных запущена.`` - Узел включён, опрос источника идёт. * - ``Коннектор неактивен, работа по чтению данных остановлена.`` - Узел выключен. Коннектор остаётся на связи и ждёт новую конфигурацию. * - ``Отправка данных в платформу.`` - Очередь значений ушла в платформу. * - ``Данные сохранены в буфер.`` - Связи не было, точка осталась в файле буфера. * - ``Ошибка передачи данных: сохраняем в буфер.`` - Отправка не удалась, точка ушла в буфер. * - ``Обработка буфера данных.`` - Связь есть, накопленные точки возвращаются в очередь отправки. * - ``Тег ''. Ошибка конвертации значения ...`` - Значение с источника не привелось к типу тега. * - ``Неверная конфигурация тега .`` - Привязка тега не разобралась, тег в опрос не попал. * - ``Очередь сообщений переполнена.`` - Отправка не успевает за чтением, часть буфера отложена. * - ``Получен сигнал завершения работы, сохраняем данные...`` - Коннектор останавливается и сбрасывает буфер на диск. * - ``Работа коннектора завершена.`` - Процесс закончил остановку. Свой коннектор -------------- Общая часть вынесена в проект `prs-connector-core `__. Это Python-пакет. Его главный класс — ``BaseConnector``. Базовый класс сам открывает MQTT, запрашивает и применяет конфигурацию, хранит её на диске, выполняет JSONata, приводит тип, сравнивает отклонение, ведёт буфер, настраивает Last Will и пишет журнал. В наследнике остаётся чтение источника: метод забирает значения и кладёт их в очередь. Дальше их обрабатывает базовый класс. В ``prsJsonConfigString`` коннектора ключ ``source`` описывает, как подключиться к прибору. Формат ключа задаёт конкретный коннектор. В привязке тега свой ключ ``source`` описывает, как прочитать именно этот тег. Порядок разработки и формат сообщений — в документации репозитория ``prs-connector-core``.