Учебник по flexible драйверу (Входящие данные)
В текущей статье мы рассмотрим возможности flexible драйвера и то, как его можно использовать для обработки произвольных входящих данных из TCP соединения.
SberMobile включает в себя драйверы для множества различных устройств, что упрощает их интеграцию в систему. В случаях, когда в SberMobile нет драйвера для определенного устройства (например, для устройства, использующего проприетарный протокол), существует несколько вариантов интеграции устройства. Первый вариант - написать плагин для SberMobile на Java, и хотя это просто, но трудоемко. Другой вариант - настроить один или несколько экземпляров flexible драйвера для обработки входящих данных в виде переменных или событий.
Введение в операцию с драйвером
В данном руководстве приведено множество выражений, использующих команду
переменной окружения. В различных выражениях на эту переменную ссылается {env/command}
. В SberMobile, использующем flexible драйвер, настроенный на получение входящих данных, эта переменная содержит данные, которые были получены и обрабатываются драйвером.
Настроить flexible плагин
Первым шагом будет настройка плагина драйвера Flexible для корректной маршрутизации входящих данных на определенное устройство Flexible драйвер. В корневом контексте откройте контекст Драйверы/расширения и выберите Редактировать свойства драйвера/расширения flexible драйвера.
В окне редактора свойств добавьте новую строку для каждого устройства, которое будет заниматься обработкой входящих данных. Изначально добавьте одну строку с указанными ниже данными.
Имя свойства | Значение | Заметки |
---|---|---|
Описание |
| Удобное для пользователя имя для конфигурации устройства. |
Протокол |
| Тип данных, которые будет обрабатывать устройство flexible драйвера. |
Порт |
| Укажите порт, на котором SberMobile должен прослушивать входящие TCP-соединения. 3010 - типичный порт для TCP-соединений, но вы можете выбрать любой доступный порт. |
Защищенный |
| Укажите, зашифровано ли соединение с помощью SSL/TLS. |
Выражение разделитель входного потока |
| Определяет количество байт, которые будут взяты из входного потока данных. Необработанная команда доступна в переменной окружения |
Режим разделителя входного потока |
| Указывает, когда запускать Выражение расширенного поиска разделителя входного потока; в текущем случае оно будет запущено один раз, в конце сообщения. Если выбрана опция Попытка разделить на каждом байте, Выражение разделителя входного потока сработает один раз для каждого байта в блоке, где |
Выражение расширенного поиска |
| Используется, когда драйвер отправляет сведенья. Один из примеров использования - вычисление контрольной суммы и добавление ее перед отправкой. В текущем примере мы просто отправляем точную команду. |
Выражение раскодирования |
| Используется при получении пакета данных. Текущее выражение предварительно обрабатывает пакет данных перед дальнейшей обработкой. Текущее выражение может использоваться для простой обрезки терминальных символов из пакета или для полного преобразования данных, например, путем их расшифровки/декомпрессии. |
Выражение метода обнаружения ID устройства |
| Выражение, определяющее метод вычисления идентификатора, который возврат:
В текущем примере используется значение 1, так как мы будем отправлять произвольные данные. |
Выражение чтения ID устройства | Не используется в данном примере. Если Выражение метода обнаружения ID устройства равно Ответ на команду запроса ID устройства затем отправляется в Выражение результата чтения ID устройства для определения ID устройства. | |
Выражение результата чтения ID устройства |
| Результат выполнения этой команды определяет идентификатор устройства. Мы установили значение Если бы мы ожидали, что на одном порту будут взаимодействовать разные устройства, мы могли бы установить это значение динамически, основываясь на входящем сообщении или ответе на Выражение чтения ID устройства. Как и в случае с предыдущими |
Закодированный |
| Существует несколько различных кодировок, для данного примера мы используем ASCII. |
На следующем скриншоте показана строка глобальных настроек flexible драйвера, настроенная в соответствии с предыдущей таблицей.
Вы настроили глобальные конфигурации flexible драйвера на прием TCP-пакетов на порт 5040, интерпретацию каждой полезной нагрузки как кодированной в ASCII и пересылку полезной нагрузки на устройство flexible драйвера с идентификатором "1"
. В следующем разделе необходимо настроить устройство с идентификатором "1"
, которое будет далее обрабатывать входящие полезные нагрузки TCP.
Создание устройства
Чтобы создать flexible устройство, нажмите Добавить устройство из контекста Устройства в корневом контексте. Настройте устройство с помощью следующих параметров:
Имя свойства | Значение | Заметки |
---|---|---|
Драйвер устройства |
| Текущее руководство предназначено для драйвера Flexible |
Имя устройства |
| Это будет частью контекстного пути для ссылки на устройство в SberMobile. |
Описание устройства |
| Удобное для пользователя имя устройства. |
Подключение |
| Указывает, что данное устройство будет обрабатывать входящие соединения. |
Идентификатор устройства |
| Текущее значение принимает строковое значение и должно соответствовать значению, указанному в Выражении результата чтения ID устройства на предыдущем шаге. |
На следующем скриншоте показаны приведенные выше конфигурации, введенные в окно "Добавить устройство". Нажмите OK, чтобы сохранить и открыть страницу Свойства аккаунта устройства .
После создания устройства окно Свойства аккаунта устройства должно открыться автоматически. Окно также можно открыть, нажав Редактировать свойства аккаунта устройства из контекстного меню вновь созданного устройства.
Добавление переменной в устройство
Для того чтобы связать поступающие данные с устройством, создайте хотя бы одну переменную. Перейдите на вкладку Статические переменные и добавьте строку со следующими данными:
Поле | Значение | Заметки |
---|---|---|
Имя |
| Текущий будет частью контекстного пути для ссылки на переменную в языке выражений SberMobile. |
Описание |
| Удобное для пользователя имя переменной |
Формат |
| Описание полей таблицы данных переменной. Мы описываем таблицу с одним полем с именем |
Читаемая |
| Позволяет читать переменную |
Writable |
| Позволяет записывать переменную |
Настроив строку на вкладке Статические переменные , вы получите следующее:
Теперь у устройства есть переменная данных
, в которую могут быть записаны входящие данные.
Конфигурирование события для устройства
Еще одним способом взаимодействия с устройством является инициирование определенных событий. Откройте вкладку Статические события в Свойствах аккаунта устройства и добавьте строку с указанными данными, оставив неупомянутые поля пустыми:
Поле Имя | Значение | Заметки |
---|---|---|
Имя |
| Текущий будет частью контекстного пути для ссылки на событие в языке выражений SberMobile. |
Описание |
| Удобное для пользователя имя события. |
Формат |
| Описание полей таблицы данных для события. Мы описываем таблицу с одним полем с именем |
Уровень |
| Установка уровня события в качестве информационного. |
Настроив статическое событие с указанными выше значениями, вы получите следующее:
Это позволит устройству инициировать события при получении определенных пакетов данных.
Настроить свойства Операции
Свойства вкладки Операции определяют, как устройство будет реагировать на входящие данные в случае входящего соединения, а также как обрабатываются исходящие соединения. Следующие конфигурации предназначены для устройств, принимающих входящие соединения.
Операции с данными
Имя свойства | Значение | Заметки |
Выражение детектор асинхронных команд |
| Это выражение может обращаться к
|
Выражение классификатора события/обновления переменной | contains({env/command}, "переменная") ? 1 : (contains({env/command}, "event") ? 0 : 1) | Вычислено только в том случае, если Выражение детектора асинхронных команд выполнено в
В текущем случае, если входящая командная строка содержит подстроку |
Выражение ID команды |
| Поле Выражение ID команды и поле Выражение ID ответа принимаются в операцию только в том случае, если Выражение детектора асинхронных команд возвращает |
Выражение расширенного поиска ответа ID |
|
Асинхронная обработка переменных
Имя свойства | Значение | Заметки |
Выражение имени переменной |
| Указывает имя переменной, которая будет обновлена, если Выражение классификатора события/обновления переменной возвращает |
Выражение временной метки переменной |
| Временная метка для применения к обновлению переменной. |
Выражение качества переменной |
| Качество данных, применяемое к обновлению переменной |
Выражение значения переменной |
| Таблица данных, с помощью которой обновляется переменная. Соответствует формату, определенному для переменной. |
Обработка асинхронных событий
Имя свойства | Значение | Заметки |
Выражение имени события |
| Указывает имя события, которое будет создано, если Выражение классификатора события/обновления переменной возвращает |
Выражение временной метки события |
| Дата/время события для применения к обновлению события. |
Выражение уровня события |
| Уровень, на котором будет создано событие |
Выражение расширенного поиска значения события |
| Таблица данных для события. Соответствует формату, определенному для таблицы данных события. |
Остальные разделы можно оставить пустыми. Настроив свойства вкладки Операции, вы должны получить нечто подобное приведенному ниже скриншоту
Сейчас, когда устройство SberMobile настроено на обработку входящих сообщений с помощью flexible драйвера, его можно протестировать, отправив несколько сообщений.
Отправка данных на устройство SberMobile
Существует несколько способов отправки произвольных TCP-данных. Один из них заключается в использовании специализированного инструмента, такого как Пакет Отправитель, другой - в написании простой программы, которая создает TCP-соединение и отправляет нужные данные.
Использование программы Пакет Отправитель для отправки пакетов
Загрузите и установите пакетный отправитель в той же операционной системе, в которой запущен сервер SberMobile.
Создайте пакет со следующими конфигурациями:
Свойства | Значение | Описание |
---|---|---|
Имя |
| Если вы хотите сохранить пакет для повторного использования |
ASCII |
| Текст ASCII для отправки. |
HEX |
| Автоматически закодированное HEX-значение указанного ASCII-текста. |
Адрес |
| Хост или IP-адрес, на который следует отправить пакет. |
Порт |
| Порт, на который нужно отправить пакет |
Задержка повторной отправки |
| Задержка перед повторной отправкой пакета |
Тип связи |
| Тип соединения с сервером. |
Настроенное окно Отправитель пакетов будет выглядеть следующим образом.
Кликните Отправить, чтобы отправить пакет на устройство с flexible драйвером SberMobile.
Использование Python для отправки пакета
Установите Python 3 на ту же машину, на которой запущен сервер SberMobile.
Сохраните приведенный ниже пример сценария в файле с именем sendpacket.py:
import socket
# Set up the socket connection
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Hostname or IP address where server is running
host = 'localhost'
# Port where Flexible Driver is configured to listen to incoming data
port = 5040
# Start connection
s.connect((host, port))
# Send data
data = b'var: Update data with some arbitrary TCP data.'
s.sendall(data)
# Close the connection
s.close()
Запустите сценарий из командной строки командой
python3 sendpacket.py
Подтвердите, что пакет был принят устройством с flexible драйвером
Откройте контекстное меню устройства из корневого контекста и нажмите Управление устройством...
Текущий откроет окно со всеми переменными устройства, в данном случае переменной data, с данными, которые мы отправили как пакет
var: Обновить переменную "data" произвольными данными TCP.
Доступ к переменной можно получить на языке выражений с помощью контекстного пути
{users.admin.devices.incoming_flexible:data}
.
Триггер события в flexible устройстве
Мы можем вызвать событие updateData, которое мы настроили выше, вместо обновления переменной, просто изменив данные, отправляемые на устройство.
Напомним, что Выражение классификатора события/обновления переменной определяет, будут ли входящие данные обрабатываться как событие или как операция обновления переменной. Мы использовали следующее выражение:
contains({env/command}, "variable") ? 1 : (contains({env/command}, "event") ? 0 : 1)
Текущее выражение сначала проверяет, содержит ли команда строку "переменная". Если да, то оно принимает значение 1
, и команда обрабатывается как обновление переменной. Если команда не содержит строку "переменная", выполняется проверка, содержит ли команда строку "событие". Если команда содержит строку "событие", выражение оценивается в 0
, и команда обрабатывается как событие. Если ни "переменная", ни "событие" не присутствуют, по умолчанию устанавливается значение 1
и обновляется переменная.
Чтобы вызвать событие, просто измените содержимое тестового пакета так, чтобы оно содержало строку "event" и удалите строку "variable". Например: event: Текущее событие!
Используяотправитель пакетов , обновите данные в формате ASCII и HEX, как указано ниже:
Свойство | Значение | Описание |
---|---|---|
Имя |
| Если вы хотите сохранить пакет для повторного использования |
ASCII |
| Текст ASCII для отправки. |
HEX |
| Автоматически закодированное HEX-значение указанного ASCII-текста. |
Адрес |
| Хост или IP-адрес, на который следует отправить пакет. |
Порт |
| Порт, на который нужно отправить пакет |
Задержка повторной отправки |
| Задержка перед повторной отправкой пакета |
Тип связи |
| Тип соединения с сервером. |
При использовании сценария Python обновите переменную данных
, как указано ниже:
...
# Send data
data = b'event: Текущее событие!'
...
В Контекстном дереве SberMobile откройте контекстное меню Входящего flexible устройства и выберите Просмотр событий.
Появится окно, в котором отображаются все текущие события Входящего flexible устройства. В нашем случае активных событий нет, поэтому таблица данных пуста.
Отправьте пакет из программы Пакет Отправитель или запустите сценарий Python и убедитесь, что событие сработало:
После создания большего количества событий для устройства, Выражение имени события и Выражение данных события можно настроить с помощью более сложных функций, чтобы вызвать различные события, основанные на содержимом команды.