Недавно, я случайно познакомился с программой RadioBoss компании DJSoft.Net, одной из программ автоматизации радиовещания.



Возможности программы весьма обширны, меня же больше прельстило то, что она поддерживает API управление, что позволяет удаленно полностью управлять проигрыванием музыки на компьютере с установленным RadioBoss. У меня давно была мечта иметь возможность удаленного воспроизведения медиа без подключения к рабочему столу удаленного ПК и вообще без компьютера. Пусть за меня это делает, например, … мой роутер Микротик!

Как известно, Роутер ОС Микротик имеет встроенный мощнейший скриптовый язык, позволяющий писать любые сценарии и программы по автоматизации работы роутера. Но не только роутера! Скриптовая команда /tool fetch позволяет организовать внешние GET и POST запросы на указанный URL и таким образом, обращаться к любому оборудованию или программам с открытыми API. Например, реализованы скрипты и библиотеки команд по управлению из Микротик модулями интернет реле и мониторинга среды (можно посмотреть и скачать здесь), получения сведений о погоде, оповещениях о событиях в Телеграмм и управления роутером через Телеграмм, определения времени восхода/заката солнца c организацией астрономического реле и т.д…

За чем же у нас дело стало? Пользуясь руководством к API RadioBoss пишем несколько простых функций для Роутер ОС Микротик, которые позволят роутеру выполнять действия на RаdioBoss по совершению каких-либо событий на роутере:

#---------------------------------------------------------#
# Функции управления RadioBoss                                
#          by Sertik 18/12/2020                                       
#---------------------------------------------------------#

# - FuncRadioBossInit
# установить адрес устройства, порт и пароль для функий RadioBoss и проверить доступность устройства
# обязательно указывать все три параметра

:global FuncRadioBossInit do={
:if ([:len $0]!=0) do={
:if ([:len $1]!=0) do={
:if ([:len $2]!=0) do={
:if ([:len $3]!=0) do={
:global FuncPing
:if ([$FuncPing PingAdr=$1]="OK") do={
:global RBaddr $1
:global RBport $2
:global RBpass $3
:return "OK";
             } else={:return "ERROR PC RadioBoss not responded"}
          } else={:return "ERROR parametr password"}
     } else={:return "ERROR parametr port"}
   } else={:return "ERROR parametr address"}
  }
}


# - FuncRadioBossPlay
# играть трек с указанным номером, если не указан, но первый в плейлисте
# если указан "next"/"prev" переходит к следующему/предыдущему треку

:global FuncRadioBossPlay do={
:if ([:len $0]!=0) do={
:global RBaddr
:global RBport
:global RBpass
:if (([:len $RBaddr]!=0) and ([:len $RBport]!=0) and ([:len $RBpass]!=0)) do={
:local StrFetchRB;
:if (($1="next") or ($1="prev")) do={:set StrFetchRB ("http://"."$RBaddr".":"."$RBport"."/\?pass="."$RBpass"."&cmd="."$1");} else={ 
:set StrFetchRB ("http://"."$RBaddr".":"."$RBport"."/\?pass="."$RBpass"."&cmd=play%20"."$1");} 
do {
:global RBanswer [/tool fetch url=$StrFetchRB mode=http as-value output=user];
} on-error={:return "ERROR"}
:global RBanswer; 
:if (($RBanswer->"status")!="finished") do={:return "ERROR"}
:return ($RBanswer->"data");
   } else={:return "ERROR no define address, port or password"}
 }
}

# - FuncRadioBossStop
# остановить воспроизведение

:global FuncRadioBossStop do={
:if ([:len $0]!=0) do={
:global RBaddr
:global RBport
:global RBpass
:if (([:len $RBaddr]!=0) and ([:len $RBport]!=0) and ([:len $RBpass]!=0)) do={
:local StrFetchRB; :set StrFetchRB ("http://"."$RBaddr".":"."$RBport"."/\?pass="."$RBpass"."&cmd=stop"); 
do {
:global RBanswer [/tool fetch url=$StrFetchRB mode=http as-value output=user];
} on-error={:return "ERROR"}
:global RBanswer; 
:if (($RBanswer->"status")!="finished") do={:return "ERROR"}
:return ($RBanswer->"data");
   } else={:return "ERROR no define address, port or password"}
 }
}


# - FuncRadioBossBreak
# остановка воспроизведения после конца текущего трека

:global FuncRadioBossBreak do={
:if ([:len $0]!=0) do={
:global RBaddr
:global RBport
:global RBpass
:if (([:len $RBaddr]!=0) and ([:len $RBport]!=0) and ([:len $RBpass]!=0)) do={
:local StrFetchRB; :set StrFetchRB ("http://"."$RBaddr".":"."$RBport"."/\?pass="."$RBpass"."&cmd=set%20break");
do {
:global RBanswer [/tool fetch url=$StrFetchRB mode=http as-value output=user];
} on-error={:return "ERROR"}
:global RBanswer; 
:if (($RBanswer->"status")!="finished") do={:return "ERROR"}
:return ($RBanswer->"data");
   } else={:return "ERROR no define address, port or password"}
 }
}


# - FuncRadioBossVolume
# установка громкости 0-100

:global FuncRadioBossVolume do={
:if ([:len $0]!=0) do={
:global RBaddr
:global RBport
:global RBpass
:if (([:len $RBaddr]!=0) and ([:len $RBport]!=0) and ([:len $RBpass]!=0)) do={
:local StrFetchRB; :set StrFetchRB ("http://"."$RBaddr".":"."$RBport"."/\?pass="."$RBpass"."&cmd=setvol%20"."$1"); 
do {
:global RBanswer [/tool fetch url=$StrFetchRB mode=http as-value output=user];
} on-error={:return "ERROR"}
:global RBanswer; 
:if (($RBanswer->"status")!="finished") do={:return "ERROR"}
:return ($RBanswer->"data");
   } else={:return "ERROR no define address, port or password"}
 }
}

# - FuncRadioBossShuffle
# включить/выключить случайное воспроизведение
# использование [$FuncRadioBossShuffle "on/off"]


:global FuncRadioBossShuffle do={
:if ([:len $0]!=0) do={
:global RBaddr
:global RBport
:global RBpass
:if (([:len $RBaddr]!=0) and ([:len $RBport]!=0) and ([:len $RBpass]!=0)) do={
:local StrFetchRB; :set StrFetchRB ("http://"."$RBaddr".":"."$RBport"."/\?pass="."$RBpass"."&cmd=set%20shuffle%20"."$1"); 
do {
:global RBanswer [/tool fetch url=$StrFetchRB mode=http as-value output=user];
} on-error={:return "ERROR"}
:global RBanswer; 
:if (($RBanswer->"status")!="finished") do={:return "ERROR"}
:return ($RBanswer->"data");
   } else={:return "ERROR no define address, port or password"}
 }
}


# - FuncRadioBossReset
# сброс статуса проигранных треков в плейлисте

:global FuncRadioBossReset do={
:if ([:len $0]!=0) do={
:global RBaddr
:global RBport
:global RBpass
:if (([:len $RBaddr]!=0) and ([:len $RBport]!=0) and ([:len $RBpass]!=0)) do={
:local StrFetchRB; :set StrFetchRB ("http://"."$RBaddr".":"."$RBport"."/\?pass="."$RBpass"."&cmd=resetplayedstate"); 
do {
:global RBanswer [/tool fetch url=$StrFetchRB mode=http as-value output=user];
} on-error={:return "ERROR"}
:global RBanswer; 
:if (($RBanswer->"status")!="finished") do={:return "ERROR"}
:return ($RBanswer->"data");
   } else={:return "ERROR no define address, port or password"}
 }
}

:global FuncPing do={
:local PingCount 3; # количество пингов;
:local Hadr;
:if ([:find $PingAdr ":"]>0) do={:set Hadr [:pick $PingAdr 0 [:find $PingAdr ":"]];} else={
:set Hadr $PingAdr}
:local Result [/ping $Hadr count=$PingCount];
:local PingAnswer "";
:local MainIfInetOk false;
:set MainIfInetOk ((3*$Result) >= (2 * $PingCount))
:put "MainIfInetOk=$MainIfInetOk"
if (!$MainIfInetOk) do={
:set PingAnswer "ERROR"
}
if ($MainIfInetOk) do={
:set PingAnswer "OK"
}
:return $PingAnswer;
}


Вставляем скриптовый код, приведенный выше в реппозиторий роутера, не забываем вызвать его при старте железки (или когда нужно) для «определения» написанных функций в окружении переменных. Затем функции управления RadioBoss будут доступны из всех Ваших скриптов, вызвать их можно, например так:

# Использование (примеры):
:global FuncRadioBossInit; :global FuncRadioBossVolume; :global FuncRadioBossPlay;
:global FuncRadioBossReset; :global FuncRadioBossShuffle; :global FuncRadioBossBreak;
# Инициализируем доступ к ПК с RadioBoss
[$FuncRadioBossInit "192.168.0.2" "9001" "your password"]
# Устанавливаем громкость
[$FuncRadioBossVolume "30"]
# Сбрасываем метки проигранных треков
[$FuncRadioBossReset]
# Включаем воспроизведение в случайном порядке
[$FuncRadioBossShuffle "on"]
# Играем следующий трек
:log info [$FuncRadioBossPlay "next"]
# Останавливаем воспроизведение после текущего трека
[$FuncRadioBossBreak]

Приведенный в скрипте минимальный набор функций позволяет запускать воспроизведение указанного трека из главного плейлиста, воспроизводить треки в случайном порядке, останавливать воспроизведение, играть следующий, предыдущий треки, устанавливать громкость воспроизведения. API RadioBoss намного обширнее и позволяют управлять практически всеми функциями программы, в том числе добавлять, удалять треки и потоки в плейлист, вставлять джинглы и т д…

Я, естественно, не собирался открывать свою интернет-радиостанцию, а вот использование программы в утилитарных целях, для меня было даже более привлекательно. В частности возможности роутеров Микротик для озвучки скриптов через встроенный динамик, весьма скромны. А тут появляется возможность записать голосовые сообщения, вставить их в плейлист вместо треков и запускать из Роутер ОС Микротик по мере необходимости, причём это же делаю не я а сам роутер!

На ПК с установленным RadioBoss включаем удаленный доступ и настраиваем для него порт и пароль доступа:



Дома при включенном ПК, свернутая в трей Виндовс программа RadioBoss теперь сообщает мне голосом о нужных событиях в локальной сети (подключении домочадцев по wifi, превышениях лимита трафика сыном, доступности новой версии ПО, попытках несанкционированного доступа на роутер и т.д…)

На даче, с которой естественно давно организована многоканальная MESH VPN-сеть, можно, например, при определении движения видеокамерой, автоматически через усилитель и уличные колонки предупредить хулиганов и воришек о том, что их видят, записывают и скоро накостыляют по шее.

У системного администратора появляется возможность установить RadioBoss на офисные ПК и автоматически голосом предупреждать нарушителей дисциплины о том, что на работе необходимо работать, а не серфить Интернет или играть в «танчики» и т.д… Также можно теперь без покупки дорогостоящих аппаратных систем радиотрансляции запускать сообщения о собраниях, конференциях и т д…

Вот так, например, можно поприветствовать начальника, (а заодно и предупредить сотрудников!) при появлении его утром в офисе (в переменную MAC добавляем MAC-адрес смартфона начальника (идея взята отсюда).

:local MAC CC:CC:CC:CC:CC:CC;
:local MACdetect [interface wireless registration-table find mac-address=$MAC];
:if ([:len $MACdetect]>0) do {:do {:local nameADR [/ip firewall address-list get value-name=list [find address=123.123.123.123]];
:global FuncRadioBossInit; :[$FuncRadioBossInit «192.168.0.3» «9001» «PASSWORD»]
:global FuncRadioBossPlay
[$FuncRadioBossPlay «1»]
} on-error={/ip firewall address-list add dynamic=yes address=123.123.123.123 list=timer timeout=23:59:59; }}

Исполнение скрипта ставим в Планировщик Микротика с исполнением, скажем 1 раз в 15 секунд.

При появлении начальника в офисе (отслеживается именно первое появление за день) на ПК с адресом, переданным в функции $FuncRadioInit будет запущен первый трек из Плейлиста программы.

Возможно по API можно управлять обычным Media Player Windows, но я нигде не нашёл инструкций к управлению Медиа Плайером через http запросы.

Кстати, API RadioBoss позволяет запускать любые bat файлы и приложения Windows, а также перезагружать и выключать компьютер. Таким образом, если сетевая карта Вашего персонального компьютера или ноутбука оснащена функцией Wake on Lan, Микротик может запускать ПК с RadioBoss, а та в свою очередь, отработав нужное время, выключать компьютер.

Приятных экспериментов!