# jrbustcp

Плагин `jrbustcp` добавляет функции клиента и сервера для взаимодействия с внешними устройствами по протоколу jrbustcp.

Для проверки соединения и просмотра данных можно использовать `jrviewer` в качестве простого клиента. Скачать можно здесь: jrviewer_win-x32, jrviewer_linux-x64.

## Сервер

    plugin.jrbustcp:
      module.jrsvr:
        type:          server
        port:          30000
        hidden:        off
        idleTimeout_s: 180
        logging:       off
        compress:      gzip
        ssl:           off
        auth:          off
        ipfilter:
          - 192.168.1.101 deny
          - 192.168.1.0/24 accept
          - deny

Параметр | Умолчание | Описание
--- | --- | ---
type | `-` | Для работы в режиме сервера равно `server`
port | `-` | Номер tcp порта, доступный для прослушивания (см.также Правила выбора номера tcp-порта)
idleTimeout_s | `180` | Тайм-аут бездействия клиента в секундах, после чего соединение разрывается
logging | `off` | Логирование трафика и вывод отладочных сообщение netty
compress | `off` | Использование сжатия. `off` - не использовать, `gzip` - формат сжатия Gzip
ssl | `off` | Шифрование трафика
auth | `off` | Использование аутентификации
ipfilter | `` | Фильтр входящих подключений по ip адресу. Состоит из списка правил следующего формата:
    [ip_addr[/cidr]] type
ip_addr - адрес в формате xxx.xxx.xxx.xxx cidr - целое число (если не указано, то 32) type - accept или deny Правила сканируются сверху вниз по списку до первого попадания. Последнее в списке правило может не содержать ip-адрес и будет распространятся на всех остальных, не попадающих в предыдущие правила. По умолчанию - accept.
alarm.values
tag | `.*` | regex-шаблон имен тегов
value | - | аварийное значение в строковом виде

Примечания:

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

## Клиент

    plugin.jrbustcp:
      module.jrcl:
        type:        client
        host:        localhost
        port:        30000
        descr:       арм_оператора_N1
        tagdescr:    off
        filter:      .*
        recon_s:     5
        timeout_ms:  3000
        ssl:         off
        compress:    gzip
        logging:     off
        auth:        off

        alarm.values:
          - tag:     .*\.SYSTEM\.ErrorFlag
            value:   "on"

Параметр | Умолчание | Описание
--- | --- | ---
type | `-` | Для работы в режиме клиента равно `client`
host | `localhost` | Имя или адрес сервера, доступный для подключения по протоколу `jrbustcp`
port | `-` | Номер tcp порта, прослушиваемого сервером (см.также Правила выбора номера tcp-порта)
descr | `имя модуля` | Короткое описание клиента, которое можно будет увидеть на сервере при просмотре списка подключенных клиентов
recon_s | `5` | Время переподключения при разъединении, секунды
timeout_ms | `3000` | Тайм-аут ожидания ответа от сервера, мс
writeDelay_s | `0` | Задержка команды записи (передачи измененных значений на сервер) после подключения, секунды
logging | `off` | Логирование трафика и вывод отладочных сообщение netty
compress | `off` | Использование сжатия. `off` - не использовать, `gzip` - формат сжатия Gzip
setHidden | `off` | Установка флага `hidden` всем импортируемым тегам
ssl | `off` | Шифрование трафика
auth | `off` | Использование аутентификации. Если аутентификация включена на сервере, то на клиенте также необходимо включить
authKey | `` | Имя приватного ключа, наличие которого необходимо, если включена аутентификация. Также необходимо разместить на сервере публичный ключ. Если приватный ключ не указан явно, и в каталоге хранения ключей будет всего лишь один приватный ключ, то будет использоваться данный ключ. Создание пары ключей можно выполнить командой `keygen`. Каталог с ключами определяется глобальным параметром `keys.dir`
Параметры фильтрации
filter | `.*` | Regex-выражение для отбора тегов на стороне сервера
excludeExternal | `off` | Запрет импорта тегов, которые на стороне сервера имеют флаг `external`
includeHidden | `off` | Разрешение импорта тегов, которые на стороне сервера имеют флаг `hidden`
Channel Watchdog
chWdtEnable | `off` | Включение режима `Channel Watchdog`
chWdtDelay_s | `0` | Задержка выполнения обнуления тегов после потери связи с сервером
В разработке
tagdescr | `off` | Позволяет отключить передачу сервером описаний тегов, что может сократить сетевой трафик в процессе подключения

### Channel Watchdog

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

Первое приложение `jrobo1` только опрашивает один модуль ввода-вывода `pdio1` и раздает свои теги модулем `jrsvr`. Также импортируются теги при помощи модуля `jrcl1` с удаленного приложения `jrobo2` (об этом подробнее ниже).

    # jrobo1 - поставщик адресов

    plugin.jrbustcp:
      module.jrsvr:
        type:            server
        port:            30000

      module.jrcl1:
        type:            client
        port:            30001
        filter:          .*Ch.*  # нужны только каналы

        chWdtEnable:     on      # включаем Channel Watchdog
        chWdtDelay_s:    5       # с задержкой срабатывания в 5 секунд

        excludeExternal: on      # исключаем циклический
        setHidden:       on      #   кросс-импорт между jrobo1 и jrobo2

    plugin.peripherial:
      module.pdio1:
        portnum:         1
        netaddr:         3
        type:            promauto.pdio

Второе приложение `jrobo2` выполняет roboplant-логику в модуле `prj1` и импортирует модулем `jrcl2` теги приложения `jrobo1` для использования в качестве адресов в каналах `prj1`. Свои теги раздаются модулем `jrsvr` всем желающим (например, hmi-клиентам, архиваторам и т.д.), в том числе и приложению `jrobo1`.

    # jrobo2 - получатель адресов

    plugin.jrbustcp:
      module.jrsvr:
        type:            server
        port:            30001

      module.jrcl2:
        type:            client
        port:            30000
        filter:          .*

    plugin.roboplant:
      module.prj1:
        project: projects/prj1.rpp

Предположим, что модуль `prj1` содержит блок MCHB с именем тега канала управления `prj1.MCHB_001_Channel1`, имеющего строковое значение `pdio1.out00` в качестве адреса. Далее происходит следующее:

1. MCHB подается команда старт, и в тег `pdio1.out00` приложения `jrobo1` устанавливается значение 1. Происходит запуск физического оборудования.
2. Происходит сбой в локальной сети, и связь между приложениями `jrobo1` и `jrobo2` теряется.
3. Оборудование продолжает работать, т.к. в `pdio1.out00` осталось значение 1, но работает оборудование уже бесконтрольно.
4. Если связь не восстанавливается в течение 5 секунд, то в модуле `jrcl1` срабатывает `Channel Watchdog`. При этом выполняется следующее: модуль находит среди собственных импортированных тегов каналы, адресами которых являются теги приложения `jrobo1`, и устанавливает им значение 0.
5. Физическое оборудование останавливается.

### Теги

Имя тега | Тип | Описание
--- | --- | ---
client.connected | `boolean` | Состояние подключения к серверу
client.reconnect.cnt | `int` | Количество попыток переподключения после разрыва соединения
client.disconnect.cnt | `int` | Количество разрывов соединения
client.last.error | `string` | Описание последней произошедшей ошибки соединения