Это старая версия документа!
Самый важный, я бы даже сказал, что основоположный скрипт, т.к. без его загрузки при запуске устройства, другие скрипты не будут работать.
Используется для тестирования. Если его расскомментировать, скрипт отработает на 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 запросов.
Вывод предыдущей функции может быть передан этой функции для сохранения результатов проверки на диске устройства.
Пример лог-файла.
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
Для работы требуется политика 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 ];
}
}
:if ( [ :typeof $runLogCount ] = "nothing" ) do={ :set runLogCount [ :toarray "" ]; }
: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 );
}
}
: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"; }
}
# Example # # $ ispLogging outInt=(«InterfaceName»|$ether1) [receivedPing=($ping|integer)] [totalPing=($ping|integer)] [startMode=(script|sms|manual|«any-text»)] newFileAt=(day|month);
# # Initialization of SMS reception and test sending #
: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";
}
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."
Обсуждение