.. _BaseConnector:

Класс BaseConnector
-------------------
Класс реализует значительную часть работы, общей для всех коннекторов платформы
Пересвет.

Атрибуты
~~~~~~~~
``_loop`` - петля событий.

``_config_from_platfrom`` - полная конфигурация, полученная от платформы.

``_mqtt_will_topic`` - топик Last Will: ``prsConnector/connection_lost/<connector_id>``.
Используется при подключении к MQTT-брокеру, чтобы при нештатном отключении платформа
записала в привязанные теги качество 100.

``_mqtt_will_payload`` - тело Last Will: JSON ``{"id": "<connector_id>"}``.

``_tag_cache`` - кэш тегов вида:

    .. code-block:: python

        {
            "<tag_id>": {
                "JSONataExpr": Jsonata(),
                "last_value": ...
            }
        }

Если коннектору нужно дополнить кэш своими данными, то необходимо
переопределить метод ``_create_tag_cache``.

``_logger`` - журнал сообщений.

``_data_queue`` - очередь данных для отправки в платформу.
Метод ``_read_tags`` сам должен помещать новые данные
в эту очередь.

Методы
~~~~~~

``async def _read_tags(self)`` - абстрактный метод в базовом классе,
который необходимо переопределить в классах-наследниках.

Реализует всю работу с источником данных.

Запускается как отдельная задача.

Каждый раз, когда коннектору приходит от платформы новая
конфигурация, в которой исправлены данные о подключении к источнику данных,
задача с методом ``_read_tags`` останавливается, изменения в конфигурации
сохраняются и задача запускается снова.

Метод должен помещать в очередь ``_data_queue`` данные, прочитанные из источника.
Формат сообщений:

.. code-block:: python

    {
        "data": [
            {
                "tagId": "<tag_id>",
                "data": [
                    [value, timestamp, quality_code]
                ]
            }
        ]
    }

где:

``value`` - прочитанное из источника значение тега, обязательный параметр;

``timestamp`` - метка времени, обязательный параметр;

``quality_code`` - код качества, необязательный параметр;

При разрыве связи с источником данных метод должен записать для каждого тега
значение ``None`` с текущей меткой времени и с кодом качества 102 -
разрыв связи с источником данных.

``async def _create_tag_cache(self, tag_id: str)`` - метод
создания кэша для тега. Метод вызывается в следующих случаях:

* при старте коннектора, когда для каждого тега из конфигурации создаётся кэш;
* когда от платформы приходит сообщение о том, что к коннектору привязан новый тег;
* при изменении конфигурации тега: в этом случае сначала вызывается метод
  ``_remove_tag_cache``.

.. warning::

    Если тег неактивен (атрибут ``prsActive = True``), то кэше тега не создаётся,
    хотя метод ``_create_tag_cache`` вызывается.

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

.. code-block:: python

    async def _create_tag_cache(self, tag_id: str):
        super()._create_tag_cache(tag_id)
        # дополнительная работа

В этом случае гарантируется, что тег ``tag_id`` уже находится в списке тегов в конфигурации:

.. code-block:: python

    self._config_from_platfrom.tags[tag_id]

``async def _remove_tag_cache(self, tag_id: str)`` - метод вызывается при удалении тега
из списка привязанных к коннектору тегов, либо при изменении конфигурации тега:
кэш тега удаляется, потом создаётся снова.

Если при удалении тега из списка необходимо сделать какую-либо дополнительную работу,
то переопределение метода должно иметь вид:

.. code-block:: python

    async def _remove_tag_cache(self, tag_id: str):
        # дополнительная работа

        super()._remove_tag_cache(tag_id)

В этом случае гарантируется, что тег ещё находится в списке и кэш его неудалён.