Самый важный, я бы даже сказал, что основополагающий скрипт, т.к. без его загрузки при запуске устройства, другие скрипты не будут работать.
Им инициализируются:
Используется для тестирования. Если его раскомментировать, скрипт отработает на 50 секунд быстрее, но не будут инициализированы SMS и не будет проиграна музыка запуска.
# :local varOnly "yes";
Необходимо, чтобы скрипт не глючил при загрузке устройства, а устройство в свою очередь могло спокойно прогрузиться.
:if ( $varOnly != "yes" ) do={ :log info ("script will be executed after 50 seconds"); :delay 50s; }
Настройки для работы SMS. Предварительно, конечно, нужно настроить.
:global modemPort [/tool sms get port]; :global smsChannel [/tool sms get channel]; :global smsNumber [/tool sms get allowed-number];
Устанавливаем номер PPP подключения модема. Обычно 0
, но у всех по своему. Узнать можно введя в терминале /interface ppp-client print where name~«NAME»
, заменив NAME
на название подключения.
:global pppNumber 0;
Находим названия для наших Интернет-каналов. Будут использоваться для логирования, SMS и E-mail в других скриптах. Можно указать вручную, но… зачем? Смотрите номер физического интерфейса и пишете его вместо ether1
или ether2
.
:global ether1Name [/interface ethernet get [find default-name="ether1"] name]; :global ether2Name [/interface ethernet get [find default-name="ether2"] name];
Электронный адрес администратора для уведомлений.
:global adminEmail "name@domain.zone";
Список рассылки для уведомления сотрудников о состоянии Интернет-канала.
:global eventEmail "list@domain.zone";
Адреса для тестирования наличия Интернета на каналах. Шлюзы указывать нельзя! Лучшее решение, это DNS от Google.
:global pingTo1 "8.8.8.8"; :global pingTo2 "77.88.8.8";
Количество эхо-запросов по умолчанию.
:global pingCount 4;
Минимальное количество эхо-ответов, чтобы считать канал рабочим. Должно быть меньше, чем pingCount * 2.
В оригинальном фэйловер-скрипте использовались проценты, но в актуальной версии RouterOS нет дробей, увы. И на поиски этой ошибки я потратил огромное количество времени, пока не догадался поиграться в консоли с математическими операторами…
:global stableConnectFrom 6;
Частота отправки сообщения о неработающем резервном канале.
К примеру, чтобы оповещение отправлялось не чаще одного раза в 6 часов, при запуске задачи каждые 3 минуты, нужно указать 120.
:global setFailCounter 60;
Сброс состояния выполнения скрипта фэйловера, которое остается, к примеру, при сбросе питания во время выполения.
:global failoverRun false;
:global sendEvent do={
Чтобы проверить надежный режим, закомментируйте глобальную функцию modemPort и раскомментируйте локальную.
:global modemPort; # :local modemPort fake;
Инициализация переменных. errorTxt
, это текст сообщения об ошибке, выводимого в лог, если не удалось отправить сообщение в режиме $mode
(о них ниже).
:global smsChannel; :global smsNumber; :global adminEmail; :local errorTxt "Function \"sendEvent\" could not send $mode message!"; :local localTo; :local localSubj;
Выбор режима работы в зависимости от переданных функции переменных.
:if ( [ :typeof $to ] = "nothing" ) do={ :set localTo $adminEmail; } else={ :set localTo $to; } :if ( [ :typeof $subj ] = "nothing" ) do={ :local dateTime ([/system clock get date]."@".[/system clock get time]); :set localSubj "SMS transmission failed $dateTime!"; } else={ :set localSubj $subj; }
Надежный режим заключается в попытке сперва отправить SMS, а если не удалось (к примеру, модем повис), то отправить электронное письмо.
:if ( [ :typeof $mode ] = "nothing" || $mode = "safe" ) do={ :do { /tool sms send $modemPort channel=$smsChannel "$smsNumber" message=$msg; } on-error={ /tool e-mail send to=$localTo subject=$localSubj body=$msg; } }
Отправляем только SMS, если ошибка, то пишем в лог и больше ничего не делаем.
:if ( $mode = "sms" ) do={ :do { /tool sms send $modemPort channel=$smsChannel "$smsNumber" message=$msg; } on-error={ :log error ("$errorTxt"); } }
Отправляем только Email, если ошибка, то пишем в лог и больше ничего не делаем.
:if ( $mode = "mail" ) do={ :do { /tool e-mail send to=$localTo subject=$localSubj body=$msg; } on-error={ :log error ("$errorTxt"); } } }
Квадратные скобки указывают на необязательность соответствующих переменных или значений, а круглые скобки указывают на выбор одного из вариантов.
# [:(local|global) $anyVarMail "address@domain.zone";] # [:(local|global) $anyVarSubj "Any subject";] # [:(local|global) $anyVarMsg "Any message";] # $sendEvent [mode=(sms|mail|safe)] [to=(address@domain.zone|$anyVarMail)] [subj=("any subj"|$anyVarSubj)] msg=("any msg"|$anyVarMsg);
Обязательной является только одна переменная, msg
, - в этом случае будет использован надежный режим, адрес и тема по умолчанию.
mode
может принимать одно из трех значений - sms
, mail
или safe
.to
может быть взято из другой переменной или указано явно «address@domain.zone
».subj
так же может быть передано другой переменной или быть указано простым текстом в кавычках.:global pingSession do={
Инициализация переменных.
:global pingTo1; :global pingTo2; :global pingCount; :local localCount; :local localPingStatus;
Выбор режима работы в зависимости от переданных функции переменных.
:if ( [ :typeof $myPingCount ] = "nothing" ) do={ :set localCount $pingCount; } else={ :set localCount $myPingCount; }
Собственно, ядро функции - пигнует, запоминает, складывает. Все.
:do { :set localPingStatus \ ( [/ping $pingTo1 interface=$pingFrom count=$localCount] + \ [/ping $pingTo2 interface=$pingFrom count=$localCount] ); } on-error={}
Возвращает скрипту, вызвавшему эту функцию, результат.
:return $localPingStatus; }
Инициализируем обязательные переменные.
$intName
- название интерфейса с которого будем пинговать.pingStatus
- переменная в которую запишем результат.# :local $intName "Any-Interface-Name"; # :local pingStatus;
Вызываем функцию в стандартном режиме.
# :set pingStatus [ $pingSession pingFrom=$intName; ];
Или с указанием через переменную myPingCount
своего значения количества отправляемых эхо-запросов.
# :set pingStatus [ $pingSession pingFrom=$intName myPingCount=8; ];
При возвращении всех пакетов результат будет 16, т.к. производятся две попытки по 8 запросов.
Вывод предыдущей функции может быть передан этой функции для сохранения результатов проверки на диске устройства.
Для работы требуется политика ftp!
:global ispLogging do={
Инициализация переменных.
:global stableConnectFrom; :global runLogCount; :global logFileNum; :local contentsFile; :local fileName; :local monthToNum; :local dateToPick; :local dateToLog; :local timeToLog; :local warnLevel;
Проверка указания обязательной переменной outInt
. Если ее нет, то выходим с ошибкой.
:if ( [ :typeof $outInt ] = "nil" || [ :typeof $outInt ] = "nothing" ) do={ :local noInt "The variable \"outInt\" is missing, the function ends."; :log error ("$noInt"); :error "$noInt"; }
Получаем, преобразуем и записываем в переменные текущую дату и время.
:set monthToNum {jan="01";feb="02";mar="03";apr="04";may="05";jun="06";jul="07";aug="08";sep="09";oct="10";nov="11";dec="12";}; :set dateToPick [/system clock get date]; :set dateToLog ( [:pick $dateToPick 4 6] . "." . ( $monthToNum -> [:pick $dateToPick 0 3] ) . "." . [:pick $dateToPick 7 11] ); :set timeToLog [/system clock get time];
Если переменная с указанием текущего номера файла имеет тип nothing
, что нормально после перезагрузки, преобразуем ее в массив.
:if ( [ :typeof $logFileNum ] = "nothing" ) do={ :set logFileNum [ :toarray "" ]; }
Заполняем эту переменную из файла. Если файла нет, создаем его и устанавливаем счетчик в 0
.
/file { :if ( [ :typeof ( $logFileNum -> "$outInt" ) ] = "nothing" ) do={ :do { :set ( $logFileNum -> "$outInt" ) [ get "isp-stat/counters/$outInt.txt" contents ]; } on-error={ /system routerboard print file="isp-stat/counters/$outInt"; :delay 2s; set "isp-stat/counters/$outInt.txt" contents="0"; :set ( $logFileNum -> "$outInt" ) [ get "isp-stat/counters/$outInt.txt" contents ]; } }
Если переменная с указанием текущего количества запусков имеет тип nothing
, что нормально после перезагрузки, преобразуем ее в массив.
:if ( [ :typeof $runLogCount ] = "nothing" ) do={ :set runLogCount [ :toarray "" ]; }
Накручиваем счетчик количества запуска функции. Если он больше 66
(65 строк в файле, потом файл становится сильно большим и система начинает глючить) обнуляем этот счетчик, накручиваем logFileNum
и пишем в соответствующий файл.
:if ( ( $runLogCount -> "$outInt" ) = "66" || [ :typeof ( $runLogCount -> "$outInt" ) ] = "nothing" ) do={ :set ( $runLogCount -> "$outInt" ) 0; :set ( $logFileNum -> "$outInt" ) ( ( $logFileNum -> "$outInt" ) + 1 ); :do { set "isp-stat/counters/$outInt.txt" contents=( $logFileNum -> "$outInt" ); } on-error={ /system routerboard print file="isp-stat/counters/$outInt"; :delay 2s; set "isp-stat/counters/$outInt.txt" contents=( $logFileNum -> "$outInt" ); } } else={ :set ( $runLogCount -> "$outInt" ) (( $runLogCount -> "$outInt" ) + 1 ); } }
Проверяем частоту создания нового файла (ежедневно или ежемесячно) и пишем в переменную название текущего файла. Если переменная newFileAt
не была передана выходим с ошибкой.
:if ( $newFileAt = "month" ) do={ :set fileName ( $outInt . "-" . [:pick $dateToPick 7 11] . "." . \ ( $monthToNum -> [:pick $dateToPick 0 3] ) . "-" . ( $logFileNum -> "$outInt" ) ); } else={ :if ( $newFileAt = "day" ) do={ :set fileName ( $outInt . "-" . [:pick $dateToPick 7 11] . "." . \ ( $monthToNum -> [:pick $dateToPick 0 3] ) . "." . [:pick $dateToPick 4 6] . "-" . \ ( $logFileNum -> "$outInt" ) ); } else={ :local noFile "The variable \"newFileAt\" is missing, the function ends."; :log error ("$noFile"); :error "$noFile"; } }
Проверяем насколько удачным было тестирование канала, если плохо, ставим пометку.
:if ( $receivedPing < $stableConnectFrom ) do={ :set warnLevel "!"; }
Читаем из файла данные, добавляем с новой строки новые и пишем все обратно. Если ошибка, создаем файл.
/file { :do { :set contentsFile [ get "isp-stat/$fileName.txt" contents ]; } on-error={ /system routerboard print file="isp-stat/$fileName"; :delay 2s; set "isp-stat/$fileName.txt" contents="Interface;Warning;Date;Time;Received;Total;Level;Mode"; :set contentsFile [ get "isp-stat/$fileName.txt" contents ]; } set "isp-stat/$fileName.txt" \ contents="$contentsFile\r\n$outInt;$warnLevel;$dateToLog;$timeToLog;$receivedPing;$totalPing;$stableConnectFrom;$startMode"; } }
Квадратные скобки указывают на необязательность соответствующих переменных или значений, а круглые скобки указывают на выбор одного из вариантов.
# $ ispLogging outInt=("InterfaceName"|$ether1) [receivedPing=($rPing|integer)] [totalPing=($tPing|integer)] [startMode=(script|sms|manual|"any-text")] newFileAt=(day|month);
Переменные outInt
и newFileAt
являются обязательными.
Interface;Warning;Date;Time;Received;Total;Level;Mode In-MTS-0;;01.09.2020;09:09:28;8;8;6;test-modem-scheduler In-MTS-0;;01.09.2020;21:09:29;6;8;6;test-modem-scheduler In-MTS-0;;02.09.2020;09:09:28;8;8;6;test-modem-scheduler In-MTS-0;;02.09.2020;21:09:28;8;8;6;test-modem-scheduler In-MTS-0;;03.09.2020;09:09:28;8;8;6;test-modem-scheduler
Если переменная в начале скрипта раскомментирована, просто пишем в лог об этом и отправляем Email. В противном случае включаем прием SMS и сразу отправляем тестовую. Если ошибка, то пишем об этом Email.
:if ( $varOnly = "yes" ) do={ :local varOnlySubj "SMS reception is off!"; :local varOnlyMsg "Initialization script has been executed, but the SMS reception enable section is off!"; $sendEvent mode=mail subj=$varOnlySubj msg=$varOnlyMsg; :log warning ("$varOnlyMsg"); } else={ /tool sms set receive-enabled=yes; :delay 10s; :local smsOn "MikroTik rebooted! (send \":cmd 31337 script help\" for help)"; :local smsOnLog "SMS reception enabled!"; :local smsErrSubj "SMS transmission failed!"; :local smsErr "The device is rebooted, but the SMS notification could not be sent."; :local smsErrLog "Failed to enable SMS reception after reboot!"; :do { /tool sms send $modemPort channel=$smsChannel "$smsNumber" message=$smsOn; :log info ("$smsOnLog"); } on-error={ /tool e-mail send to=$localTo subject=$smsErrSubj body=$smsErr; :log warning ("$smsErrLog"); } :execute "startup-music"; }
Последней строчкой включаем победную музыку, оповещающую серверную об удачном старте.
/system script
add comment="\C8\ED\E8\F6\E8\E0\EB\E8\E7\E0\F6\E8\FF \E3\EB\EE\E1\E0\EB\FC\ED\
\FB\F5 \EF\E5\F0\E5\EC\E5\ED\ED\FB\F5 \E8 SMS \EF\EE\F1\EB\E5 \EF\E5\F0\E5\
\E7\E0\E3\F0\F3\E7\EA\E8" dont-require-permissions=no name=\
variables-initialization owner=petya policy=\
read,write,policy,test,sensitive source="# Written by Nikolay Soloshin (ni\
kolay@soloshin.su) for RouterOS v6.46.3 on RB3011UiAS (arm) @ 2020.03\r\
\n\r\
\n# Uncomment to update variables without initializing and sending SMS\r\
\n# :local varOnly \"yes\";\r\
\n\r\
\n# Delay execution when the device boots.\r\
\n:if ( \$varOnly != \"yes\" ) do={\r\
\n :log info (\"script will be executed after 50 seconds\");\r\
\n :delay 50s;\r\
\n}\r\
\n\r\
\n#\r\
\n# Variables\r\
\n#\r\
\n\r\
\n# All values are taken from \"Tools\" -> \"SMS\"\r\
\n:global modemPort [/tool sms get port];\r\
\n:global smsChannel [/tool sms get channel];\r\
\n:global smsNumber [/tool sms get allowed-number];\r\
\n\r\
\n# Number PPP connection of modem (/interface ppp-client print where name\
~\"MTS\")\r\
\n:global pppNumber 0;\r\
\n\r\
\n# Names of interfaces with Internet channels\r\
\n:global ether1Name [/interface ethernet get [find default-name=\"ether1\
\"] name];\r\
\n:global ether2Name [/interface ethernet get [find default-name=\"ether2\
\"] name];\r\
\n\r\
\n# Administrative email address for notification from scripts\r\
\n:global adminEmail \"csadmin@csdv.ru\";\r\
\n\r\
\n# Group email address for channel status notification from a script\r\
\n:global eventEmail \"internet-status@csdv.ru\";\r\
\n\r\
\n# Addresses for testing channels\r\
\n:global pingTo1 \"8.8.8.8\";\r\
\n:global pingTo2 \"77.88.8.8\";\r\
\n\r\
\n# The default number of echo requests to send.\r\
\n:global pingCount 4;\r\
\n\r\
\n# Minimum number of returned queries to consider the channel operational\
\_(should be less than pingCount * 2)\r\
\n:global stableConnectFrom 6;\r\
\n\r\
\n# The frequency of sending messages about the failure of the backup chan\
nel.\r\
\n# To send an alert no more than once every 6 hours when starting a task \
every 3 minutes, you need to specify 120.\r\
\n:global setFailCounter 60;\r\
\n\r\
\n# Reset script and function launch labels\r\
\n:global failoverRun false;\r\
\n\r\
\n#\r\
\n# Function for sending SMS and (or) letters from scripts (example below)\
\r\
\n#\r\
\n\r\
\n:global sendEvent do={\r\
\n\r\
\n# To check reliable mode, comment out the global function modemPort and \
uncomment the local\r\
\n :global modemPort;\r\
\n# :local modemPort ttt;\r\
\n\r\
\n :global smsChannel;\r\
\n :global smsNumber;\r\
\n :global adminEmail;\r\
\n\r\
\n :local errorTxt \"Function \\\"sendEvent\\\" could not send \$mode mes\
sage!\";\r\
\n\r\
\n :local localTo;\r\
\n :local localSubj;\r\
\n\r\
\n# Set the required variables if they are not passed to the function at s\
tartup\r\
\n :if ( [ :typeof \$to ] = \"nothing\" ) do={ :set localTo \$adminEmail;\
\_} else={ :set localTo \$to; }\r\
\n :if ( [ :typeof \$subj ] = \"nothing\" ) do={\r\
\n :local dateTime ([/system clock get date].\"@\".[/system clock get t\
ime]);\r\
\n :set localSubj \"SMS transmission failed \$dateTime!\";\r\
\n } else={ :set localSubj \$subj; }\r\
\n\r\
\n# Reliable mode - we try to send SMS, if it fails, we send mail\r\
\n :if ( [ :typeof \$mode ] = \"nothing\" || \$mode = \"safe\" ) do={\r\
\n :do {\r\
\n /tool sms send \$modemPort channel=\$smsChannel \"\$smsNumber\" me\
ssage=\$msg;\r\
\n } on-error={ /tool e-mail send to=\$localTo subject=\$localSubj bo\
dy=\$msg; }\r\
\n }\r\
\n\r\
\n# Mode - only SMS, if an error, do nothing else\r\
\n :if ( \$mode = \"sms\" ) do={\r\
\n :do { /tool sms send \$modemPort channel=\$smsChannel \"\$smsNumber\
\" message=\$msg; } on-error={ :log error (\"\$errorTxt\"); }\r\
\n }\r\
\n\r\
\n# Mode - only mail, if an error, do nothing else\r\
\n :if ( \$mode = \"mail\" ) do={\r\
\n :do { /tool e-mail send to=\$localTo subject=\$localSubj body=\$msg;\
\_} on-error={ :log error (\"\$errorTxt\"); }\r\
\n }\r\
\n}\r\
\n\r\
\n# Example (square brackets indicate the optionalness of the correspondin\
g variables or values, and round brackets indicate the choice of one of th\
e options)\r\
\n#\r\
\n# [:(local|global) \$anyVarMail \"address@domain.zone\";]\r\
\n# [:(local|global) \$anyVarSubj \"Any subject\";]\r\
\n# [:(local|global) \$anyVarMsg \"Any message\";]\r\
\n#\r\
\n# \$sendEvent [mode=(sms|mail|safe)] [to=(address@domain.zone|\$anyVarMa\
il)] [subj=(\"any subj\"|\$anyVarSubj)] msg=(\"any msg\"|\$anyVarMsg);\r\
\n\r\
\n#\r\
\n# Communication check function (example below)\r\
\n#\r\
\n\r\
\n:global pingSession do={\r\
\n\r\
\n :global pingTo1;\r\
\n :global pingTo2;\r\
\n :global pingCount;\r\
\n\r\
\n :local localCount;\r\
\n :local localPingStatus;\r\
\n\r\
\n :if ( [ :typeof \$myPingCount ] = \"nothing\" ) do={ :set localCount \
\$pingCount; } else={ :set localCount \$myPingCount; }\r\
\n\r\
\n :do {\r\
\n :set localPingStatus \\\r\
\n ( [/ping \$pingTo1 interface=\$pingFrom count=\$localCount] + \\\r\
\n [/ping \$pingTo2 interface=\$pingFrom count=\$localCount] );\r\
\n } on-error={}\r\
\n\r\
\n:return \$localPingStatus;\r\
\n}\r\
\n\r\
\n# Example\r\
\n#\r\
\n# :local \$intName \"Any-Interface-Name\";\r\
\n# :local pingStatus;\r\
\n#\r\
\n# :set pingStatus [ \$pingSession pingFrom=\$intName; ];\r\
\n# or\r\
\n# :set pingStatus [ \$pingSession pingFrom=\$intName myPingCount=8; ];\r\
\n\r\
\n#\r\
\n# Function of logging the results of checking channels\r\
\n# Requires ftp policy to work!\r\
\n#\r\
\n\r\
\n:global ispLogging do={\r\
\n\r\
\n :global stableConnectFrom;\r\
\n :global runLogCount;\r\
\n :global logFileNum;\r\
\n \r\
\n :local contentsFile;\r\
\n :local fileName;\r\
\n :local monthToNum;\r\
\n :local dateToPick;\r\
\n :local dateToLog;\r\
\n :local timeToLog;\r\
\n :local warnLevel;\r\
\n \r\
\n :if ( [ :typeof \$outInt ] = \"nil\" || [ :typeof \$outInt ] = \"nothi\
ng\" ) do={\r\
\n :local noInt \"The variable \\\"outInt\\\" is missing, the function \
ends.\";\r\
\n :log error (\"\$noInt\");\r\
\n :error \"\$noInt\"; }\r\
\n\r\
\n :set monthToNum {jan=\"01\";feb=\"02\";mar=\"03\";apr=\"04\";may=\"05\
\";jun=\"06\";jul=\"07\";aug=\"08\";sep=\"09\";oct=\"10\";nov=\"11\";dec=\
\"12\";};\r\
\n :set dateToPick [/system clock get date];\r\
\n :set dateToLog ( [:pick \$dateToPick 4 6] . \".\" . ( \$monthToNum -> \
[:pick \$dateToPick 0 3] ) . \".\" . [:pick \$dateToPick 7 11] );\r\
\n :set timeToLog [/system clock get time];\r\
\n\r\
\n :if ( [ :typeof \$logFileNum ] = \"nothing\" ) do={ :set logFileNum [ \
:toarray \"\" ]; }\r\
\n\r\
\n /file {\r\
\n :if ( [ :typeof ( \$logFileNum -> \"\$outInt\" ) ] = \"nothing\" ) d\
o={\r\
\n :do { :set ( \$logFileNum -> \"\$outInt\" ) [ get \"isp-stat/count\
ers/\$outInt.txt\" contents ];\r\
\n } on-error={\r\
\n /system routerboard print file=\"isp-stat/counters/\$outInt\";\r\
\n :delay 2s;\r\
\n set \"isp-stat/counters/\$outInt.txt\" contents=\"0\";\r\
\n :set ( \$logFileNum -> \"\$outInt\" ) [ get \"isp-stat/counters/\
\$outInt.txt\" contents ];\r\
\n }\r\
\n }\r\
\n\r\
\n :if ( [ :typeof \$runLogCount ] = \"nothing\" ) do={ :set runLogCoun\
t [ :toarray \"\" ]; }\r\
\n\r\
\n :if ( ( \$runLogCount -> \"\$outInt\" ) = \"66\" || [ :typeof ( \$ru\
nLogCount -> \"\$outInt\" ) ] = \"nothing\" ) do={\r\
\n :set ( \$runLogCount -> \"\$outInt\" ) 0;\r\
\n :set ( \$logFileNum -> \"\$outInt\" ) ( ( \$logFileNum -> \"\$outI\
nt\" ) + 1 );\r\
\n :do { set \"isp-stat/counters/\$outInt.txt\" contents=( \$logFileN\
um -> \"\$outInt\" );\r\
\n } on-error={\r\
\n /system routerboard print file=\"isp-stat/counters/\$outInt\";\r\
\n :delay 2s;\r\
\n set \"isp-stat/counters/\$outInt.txt\" contents=( \$logFileNum -\
> \"\$outInt\" );\r\
\n }\r\
\n } else={\r\
\n :set ( \$runLogCount -> \"\$outInt\" ) (( \$runLogCount -> \"\$o\
utInt\" ) + 1 );\r\
\n }\r\
\n }\r\
\n\r\
\n :if ( \$newFileAt = \"month\" ) do={\r\
\n :set fileName ( \$outInt . \"-\" . [:pick \$dateToPick 7 11] . \".\"\
\_. \\\r\
\n ( \$monthToNum -> [:pick \$dateToPick 0 3] ) . \"-\" . ( \$logFileNu\
m -> \"\$outInt\" ) );\r\
\n } else={\r\
\n :if ( \$newFileAt = \"day\" ) do={\r\
\n :set fileName ( \$outInt . \"-\" . [:pick \$dateToPick 7 11] . \
\".\" . \\\r\
\n ( \$monthToNum -> [:pick \$dateToPick 0 3] ) . \".\" . [:pick \$\
dateToPick 4 6] . \"-\" . \\\r\
\n ( \$logFileNum -> \"\$outInt\" ) );\r\
\n } else={\r\
\n :local noFile \"The variable \\\"newFileAt\\\" is missing, the\
\_function ends.\";\r\
\n :log error (\"\$noFile\");\r\
\n :error \"\$noFile\"; }\r\
\n }\r\
\n\r\
\n :if ( \$receivedPing < \$stableConnectFrom ) do={ :set warnLevel \"!\"\
; }\r\
\n\r\
\n /file {\r\
\n :do { :set contentsFile [ get \"isp-stat/\$fileName.txt\" contents ]\
; } on-error={\r\
\n /system routerboard print file=\"isp-stat/\$fileName\";\r\
\n :delay 2s;\r\
\n set \"isp-stat/\$fileName.txt\" contents=\"Interface;Warning;Date;\
Time;Received;Total;Level;Mode\"; \r\
\n :set contentsFile [ get \"isp-stat/\$fileName.txt\" contents ]; \r\
\n}\r\
\n set \"isp-stat/\$fileName.txt\" \\\r\
\n contents=\"\$contentsFile\\r\\n\$outInt;\$warnLevel;\$dateToLog;\$ti\
meToLog;\$receivedPing;\$totalPing;\$stableConnectFrom;\$startMode\";\r\
\n }\r\
\n}\r\
\n\r\
\n# Example\r\
\n#\r\
\n# \$ ispLogging outInt=(\"InterfaceName|\$ether1) [receivedPing=(\$ping|\
integer)] [totalPing=(\$ping|integer)] [startMode=(script|sms|manual|\"any\
-text\")] newFileAt=(day|month);\r\
\n\r\
\n#\r\
\n# Initialization of SMS reception and test sending\r\
\n#\r\
\n\r\
\n:if ( \$varOnly = \"yes\" ) do={\r\
\n :local varOnlySubj \"SMS reception is off!\";\r\
\n :local varOnlyMsg \"Initialization script has been executed, but the S\
MS reception enable section is off!\";\r\
\n\r\
\n \$sendEvent mode=mail subj=\$varOnlySubj msg=\$varOnlyMsg;\r\
\n :log warning (\"\$varOnlyMsg\");\r\
\n } else={\r\
\n /tool sms set receive-enabled=yes;\r\
\n :delay 10s;\r\
\n\r\
\n :local smsOn \"MikroTik rebooted! (send \\\":cmd 31337 script help\\\
\" for help)\";\r\
\n :local smsOnLog \"SMS reception enabled!\";\r\
\n :local smsErrSubj \"SMS transmission failed!\";\r\
\n :local smsErr \"The device is rebooted, but the SMS notification cou\
ld not be sent.\";\r\
\n :local smsErrLog \"Failed to enable SMS reception after reboot!\";\r\
\n\r\
\n :do { /tool sms send \$modemPort channel=\$smsChannel \"\$smsNumber\
\" message=\$smsOn;\r\
\n :log info (\"\$smsOnLog\");\r\
\n } on-error={\r\
\n /tool e-mail send to=\$localTo subject=\$smsErrSubj body=\$smsEr\
r;\r\
\n :log warning (\"\$smsErrLog\"); }\r\
\n\r\
\n :execute \"startup-music\";\r\
\n}\r\
\n\r\
\n# With love from Vladivostok."
Скрипт должен выполняться при запуске устройства и при внесении в него изменений. Параметры запуска смотрите в соответствующем разделе.
Это минимально необходимый набор для работы скрипта.
Обсуждение