Макросы: Событийная система (Smart)

Макросы (или скрипты) — это мощнейший внутренний механизм автоматизации агрегаторов SIM Roulette. С помощью макросов могут быть реализованы абсолютно любые сценарии работы. При этом очень важно, что написание макросов доступно даже пользователям не знакомым с программированием, макросы не требуют компиляции (предварительного перевода в машинные коды), всегда готовы к исполнению и доступны для редактирования.

Устройство макроса
Синтаксис
Первые шаги
Полезные приемы
Примеры

Устройство макроса

Строки в макросе выполняются последовательно сверху вниз. Для изменения порядка выполнения применяются метки, операторы ветвления и безусловного перехода.

Метка - любое слово латиницей обрамленное квадратными скобками, ставится над строкой на которую должен быть осуществлен переход.
Пример метки: [next]

Текст макроса не должен содержать пустых строк. Каждая команда макроса может сопровождаться комментарием, отделенным от команды символами.

При запуске макроса через Терминал можно передать ему входные параметры m.my_macros:Текст_для_передачи_макросу Строка после : поступит в буфер, а дальше может быть разобрана стандартными методами работы с буфером.

Макросы размещаются в папке /m файловой системы.

Сложные макросы представляют собой комплексы файлов, в этом случае целесообразно хранить их в одной папке. При запуске макроса через терминал достаточно указать имя папки, SR найдет и запустит одноименный файл внутри указанной папки. При наличии макроса m/scanner/scanner его можно запустить как командой m.scanner/scanner так и m.scanner.

Также целесообразно снабжать сложные комплексы макросов файлом-руководством в формате макроса (среди примеров есть образец) с именем help и файлом-меню если предполагается запуск различных макросов из набора (пример также есть).

Синтаксис


Операторы ветвления

if — Проверяет результат выполнения предыдущей команды. Если результат равен 1 — осуществляется переход к указанной метке.

var:a<10
if next
...
[next]
...

unless — Проверяет результат выполнения предыдущей команды. Если результат равен 0 (NULL/Пустой) — осуществляется переход к указанной метке.

unless next


Оператор безусловного перехода

goto — Осуществляет переход к указанной метке.

goto next
...
[next]
...


Операторы завершения программы

stop — Завершение работы макроса.

stop

return — Производит досрочный возврат из вложенного макроса (по умолчанию возврат происходит после выполнения команды в последней строке вложенного макроса).

return

return:event — Производит досрочный возврат из макроса, вызванного событием.

return:event


Оператор ввода

input — Производит запрос действия сотрудника-оператора в разделе WEB-интерфейса Оператор. Параметры: максимальная длина вводимых данных;текст который будет выведен оператору над полем ввода).

input 1;Выберите действие:<br>1-первый вариант<br>2-второй вариант


Операторы выполнения команды из буфера

exec Выполняет команду из буфера (текст помещенный в буфер будет передан на выполнение как команда).

buffer>write=sound:beep
exec

exec2 Выполняет команду из копии буфера в стеке.

buffer>write=sound:beep
buffer>push
exec2


Оператор подключения вложенного макроса

include Подключает указанный макрос и передает ему управление (степень вложенности макросов неограничена), по окончании управление возвращается в текущий макрос.

include macrosname


Пауза

pause Пауза (приостановка программы) в миллисекундах (1/1000 секунды)

pause 1000


Первые шаги

Что же из себя представляет макрос или скрипт? Это набор команд агрегатору (все команды к вашему устройству подробно описаны в соответвующем разделе Документации). Например, вывести Hello world! в Терминал можно командой @echo:Hello world!. Но нас интересует другая команда: .ussd:{"number":"*102#","modem":"1"} — команда для осуществления USSD-запроса (в данном случае запроса баланса) для одной из СИМ-карт первого модема. Эта же команда может выглядеть так: .ussd:*102#,1, но в дальнейшем мы будем писать команды в JSON. Так нагляднее.

Давайте попробуем написать наш первый макрос. Для этого перейдем в раздел Макросы WEB-интерфейса вашего устройства и нажмем кнопку «Создать макрос». В поле «Название» введем my_macro. А в поле «Содержание»:

.ussd:{"number":"*102#","modem":"1"}

Макрос готов. Команда отправляет USSD-команду на 1 модем для запроса баланса. Вот так просто мы уже произвели небольшую автоматизацию. Теперь надо сохранить макрос нажав соответствующую кнопку.

Точку перед командой ussd необходимо ставить если мы хотим получить ответ о выполнении команды в выходной поток (в Терминал и на на управляющий сервер). Если мы не ставим точку, команда точно также выполняется, но без ответа.

Как запустить (выполнить) макрос. Через WEB-интерфейс макрос можно запустить двумя способами:

  1. В разделе Макросы, в списке найти строку с названием нужного макроса и нажать на иконку исполнения. Строка запущенного на исполнение макроса подсветится, к иконкам добавится новая — иконка остановки.
  2. В разделе Терминал ввести команду macro: и название вашего макроса — macro:my_macro. Существует также сокращенная команда m — m:my_macro. Запуск через терминал позволяет передать макросу входные данные. Делается это так m:my_macro:Текст_для_передачи_макросу.

Как остановить макрос. Для прерывания работы макроса также существуют 2 способа:

  1. В разделе Макросы, в списке найти строку с названием запущенного макроса и нажать на иконку остановки.
  2. В разделе Терминал ввести команду macro.stop. Существует также сокращенная команда m.stop.

Итак, выберите одну из установленных в устройство карт, дождитесь пока она станет активной и запустите любым способом ваш первый макрос. Получилось? Макрос должен был выполнить USSD-запрос. А результат выполнения вы можете увидеть в Терминале.

Давайте вернемся к редактированию (иконка редактирования в строке с названием макроса) и добавим дальнейший функционал. Мы ведь не собираемся вручную переключать карты и дожидаться пока они зарегиструются в сети. Здесь нам сразу же придет на помощь событийная система нашего агрегатора.

m.event:event=modemState,macro=my_macro:test,action=add
[test]
.ussd:{"number":"*102#","modem":"1"}

Добавилось 2 строки.
Команда в первой строке заставляет наш агрегатор постоянно отслеживать событие modemState (изменение состояния модемов) и при любом его изменении запускать указанный нами макрос my_macro с метки test [слово в квадратных скобках из второй строки]. После запятой action=add означает, что мы добавляем нового слушателя события modemState. Если мы передумаем и захотим перестать отслеживать событие — нужно будет подать команду m.event:event=modemState,macro=my_macro:test,action=delete.

Как же это работает? Выбирая карту из списка вы отключаете от модема текущую карту и подключаете к нему выбранную. В этот момент устройство перезапускает модем, чтобы он мог начать работу с новой СИМ-картой. Статус модема меняется на -1. Вот именно изменение этого статуса мы и просим наш агрегатор отслеживать.

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

m.event:event=modemState,macro=my_macro:test,action=add
[test]
buffer.test:-1
if end // Если статус -1 (СИМ-карта еще неактивна) - завершаем обработку события
buffer.test:1
if task // Если статус 1 (все в порядке, СИМ-карта в сети) - выполняем действие
buffer.test:3
if task // Если статус 3 (нет регистрации в сети) - предполагаем, что авторизация все-таки состоится и выполняем действие
buffer.test:5
if task // Если статус 5 - выполняем действие
buffer.test:6
unless end // Если статус (0,4), то есть не равен 6 (карта отсутствует) - завершаем обработку события
[end]
@echo: Подключение к сети...
return:event // Завершаем обработку события
[task] buffer.event.dev buffer.test:1 // Проверяем первый ли модем вернул статус
unless end // Это был не первый модем, поэтому завершаем обработку события .ussd:{"number":"*102#","modem":"1"}

Разберем новые строки:

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

Второе — это операторы ветвления if и unless. Как они работают?

Операторы ветвления обрабатывают ответ предыдущей команды. Если ответ положительный 1 или некий текст, то выполняется условие оператора if и действие передается на метку указанную после оператора, для оператора unless наоборот условие не выполняется и действие уходит на следующую после оператора строку. Если ответ отрицательный 0(NULL), то условие оператора if не выполняется и действие уходит на следующую после оператора строку, а действие unless выполняется и действие передается на указанную после оператора метку.

Теперь вы можете самостоятельно разобрать этот кусок кода и проследить при каких статусах действие макроса продолжится с метки task, а при каких остановится после метки end. Тут следует отметить, что выход из макроса запущенного обработчиком события осуществляется по команде return:event. В следующий раз наш макрос будет вызван на выполнение с метки test при новом изменении статуса.

И вот мы могли бы уже запустить команду получения баланса. Но! Мы ведь помним, что в нашем устройстве 3 активных модема. А по коду выше мы проверили статус, но не проверили какой из модемов вернул этот статус. Вот и проверим. Получаем устройство командой buffer.event.dev и с помощью оператора ветвления решаем дальнейший ход событий. Итак, при получении соответствующего нашей задачи статуса и номера модема мы, наконец, запускаем команду получения баланса return:event. Полдела сделано. Теперь надо установить слушателя ответов USSD. Что мы и сделаем командой m.event:event=ussd,macro=my_macro:ussd,action=add. Этот механизм нам уже должен быть понятен, поэтому сразу добавляем выход return:event, метку ussd и пишем следующую часть программы:

m.event:event=modemState,macro=my_macro:test,action=add
[test]
buffer.test:-1
if end // Если статус -1 (СИМ-карта еще неактивна) - завершаем обработку события
buffer.test:1
if task // Если статус 1 (все в порядке, СИМ-карта в сети) - выполняем действие
buffer.test:3
if task // Если статус 3 (нет регистрации в сети) - предполагаем, что авторизация все-таки состоится и выполняем действие
buffer.test:5
if task // Если статус 5 - выполняем действие
buffer.test:6
unless end // Если статус (0,4), то есть не равен 6 (карта отсутствует) - завершаем обработку события
[end]
@echo: Подключение к сети...
return:event // Завершаем обработку события
[task]
buffer.event.dev // Запрашиваем номер устройства, вернувшего результат
buffer.test:1 // Проверяем первый ли модем вернул статус
unless end // Это был не первый модем, поэтому завершаем обработку события
.ussd:{"number":"*102#","modem":"1"}
m.event:event=ussd,macro=my_macro:ussd,action=add
return:event
[ussd]
buffer.find: *руб
if next // Ишем в текcте ответа на USSD-запрос фрагмент, например: " 53 руб"
return:event
[next]
@buffer // Если фрагмент найден выводим на экран найденный баланс
m.event:event=ussd,macro=my_macro:ussd,action=delete // Убираем слушателя
return:event

Разберем новые строки:

Событие USSD вызывает наш макрос с метки ussd. Макрос ищет в буфере сумму нашего баланса. Если не находит, мы завершаем процесс и оставляем слушателя USSD, хотя он уже не актуален. Вот вам и домашнее задание по доработке макроса ;)

А если баланс получен, мы выводим его в выходной поток командой @buffer, убираем слушателя USSD, но оставляем слушателя modemState. В этом случае при переключении любой карты ряда A, опять запустится наш запрос баланса.

Ну вот и все, теперь вы умеете писать макросы для SIM Roulette. Ознакомьтесь с синтаксисом макросов, почитайте документацию для SR-OPrganizer-Smart, посмотрите примеры макросов. А когда напишите полезный макрос можете поделиться им с другими бесплатно либо выставить на продажу.


Полезные приемы


Оформление текста

В тексте выводящимся в выходной поток терминала можно использовать следующую мнемонику для трансформаций:
[br] — перевод строки
[b]жирный текст[/b]
[i]курсив[/i]


Таблицы

Данные в выходной поток Терминала можно выводить в виде таблицы для этого используется следующий синтаксис (для удобства воcприятия он разложен по строкам, но в макросе текст команды всегда вводится одной строкой):

[table]
     [tr]
          [th]Заголовок 1-го столбца[/th]
          [th]Заголовок 2-го столбца[/th]
     [/tr]
     [tr]
          [td]Содержимое 1-го столбца[/td]
          [td]Содержимое 2-го столбца[/td]
     [/tr]
[/table]


Переход на другую страницу WEB-интерфейса/Перезагрузка страницы

Для перехода на любой _URL_ в текст, выводящийся в выходной поток Терминала (командами echo или buffer), необходимо вставить команду sr>reload_URL_; Не забываете про "." и "@" в начале команды.

buffer.write:sr>reload/terminal;
@buffer
@echo:sr>reloadhttps://google.com;


Очистка выходного потока Терминала

Для очистки выходного потока Терминала в текст необходимо вставить команду sr>clear;

buffer.write:sr>clear;
@buffer
@echo:sr>clear;


Эмуляция ручного ввода команды и ее исполнение

Для исполнения любой команды (_COM_) в любое место текста, выводящегося в выходной поток Терминала (командами echo или buffer), необходимо вставить команду sr>com:_COM_; Команда будет выполнена и останется в логе команд.

buffer:sr>com:version;
@buffer
@echo:version;


Вывод текста в поле ввода команды Терминала

Для вывода произвольного текста (_TEXT_) в поле для ввода команды Терминала в любое место текста, выводящегося в выходной поток Терминала (командами echo или buffer), необходимо вставить команду sr>enter:_TEXT_; После вставки текста в поле для ввода команды туда же переместится фокус браузера.

buffer:sr>version;
@buffer
@echo:sr>text:version;


Гиперсылки

Для удобства навигации вместо или наряду со списком команд можно выводить готовые гиперссылки содержащие команды. Для этого в любое место текста, выводящегося в выходной поток Терминала (командами echo или buffer), вставляются конструкции [link]_КОМАНДА_[name]_НАЗВАНИЕ_[/name][/link]

buffer:sr>Команда [link]version[name]Версия[/name][/link]
@buffer
@echo>sr>Команда [link]version[name]Версия[/name][/link]


Примеры

autoexec
Автозапуск фонового получения номеров СИМ-карт.

m.event:event=modemState,macro=scanner:test,action=add // Добавлем слушателя события modemState

com_add
Макрос для добавления в Терминал кнопок быстрых ссылок.

buffer.swap // Меняем буфер и копию местами
buffer.file.load:/terminal.dat // Загружаем в буфер текущее содержание кнопок
buffer.merge: // Склеиваем буфер и копию буфера
buffer.postfix:; // Добавляем в конец буфера ;
buffer.file.save:/terminal.dat // Сохраняем отредактированный файл
buffer.write:Command added // Готовим уведомление о том, что кнопка добавлена
@buffer // Выводим уведомление
pause 1000 // Ждем секунду
@echo:sr>reload/terminal; // Обновляем окно Терминала


Больше примеров вы найдете в разделе Приложения и в нашем репозитории на вашем SIM Roulette.



Новости SIM Roulette

Анонсы новых девайсов и софта, информацию об акциях и скидках мы публикуем только в соцсетях: