всем привет.
Удалённый объект. WB8 (Welcome to Wiren Board 8.5.3) с встроенным GSM модемом. По неустановленным причинам примерно раз в сутки модем отваливается от сети, и восстановить соединение можно только отправив миньона, который передёрнет автомат на питании, а с установленными supercup приходится ещё и ждать пару минут пока погаснет “лампочка“. Сначала написал скрипт, который тупо раз в сутки ребутит весь контроллер. Потом появилось немного времени, накатал rules которое проверяет пинг на 8.8.8.8 и если 10 минут нет ответа, то ребутит модем. Может кому то поможет.
После добавления правила, появляется новый девайс, где видно основные параметры
// Настройки Watchdog для Wiren Board 8 + ModemManager
var pingHost = "8.8.8.8";
var checkIntervalMs = 60 * 1000; // Проверка раз в минуту
var maxFailures = 10; // Перезагрузка после 10 минут (10 ошибок)
// Переменные
var failureCounter = 0;
var currentConnection = "wb-gsm-sim1"; // Соединение по умолчанию (на случай, если не удастся определить)
defineVirtualDevice("network_watchdog", {
title: "Network Watchdog",
cells: {
"status": { type: "text", value: "OK", readonly: true },
"errors_count": { type: "value", value: 0, readonly: true },
"last_restart": { type: "text", value: "Never", readonly: true },
"active_connection": { type: "text", value: currentConnection, readonly: true }
}
});
// Функция определения активного GSM-соединения
function updateActiveGsmConnection() {
// nmcli -t -f TYPE,NAME connection show --active
// Вывод будет в формате: тип:имя
// Ищем строку, начинающуюся с "gsm:"
runShellCommand("nmcli -t -f TYPE,NAME connection show --active", {
captureOutput: true,
exitCallback: function (exitCode, output) {
if (exitCode === 0 && output) {
var lines = output.split("\n");
for (var i = 0; i < lines.length; i++) {
var line = lines[i].trim();
if (line.indexOf("gsm:") === 0) {
// Нашли GSM соединение (формат gsm:имя)
var connName = line.substring(4); // Берем подстроку после "gsm:"
if (connName && connName.length > 0) {
if (currentConnection !== connName) {
log("Network Watchdog: Active connection detected: " + connName);
currentConnection = connName;
dev["network_watchdog"]["active_connection"] = currentConnection;
}
}
// Если нашли одно, выходим (предполагаем один активный модем в данный момент)
return;
}
}
}
}
});
}
function checkConnection() {
// Сначала обновляем информацию об активном соединении (если оно есть)
updateActiveGsmConnection();
// Пинг
runShellCommand("ping -c 1 -W 5 " + pingHost + " > /dev/null 2>&1", {
captureOutput: false,
exitCallback: function (exitCode, capturedOutput) {
if (exitCode === 0) {
// СВЯЗЬ ЕСТЬ
if (failureCounter > 0) {
log("Network Watchdog: Connection restored automatically.");
}
failureCounter = 0;
dev["network_watchdog"]["status"] = "OK";
} else {
// СВЯЗИ НЕТ
failureCounter++;
dev["network_watchdog"]["status"] = "ERROR";
log("Network Watchdog: Ping failed (" + failureCounter + "/" + maxFailures + ")");
}
// Обновляем счетчик
dev["network_watchdog"]["errors_count"] = failureCounter;
// ПОРА ПЕРЕЗАГРУЖАТЬ
if (failureCounter >= maxFailures) {
log("Network Watchdog: MAX failures reached. Restarting ModemManager and connection: " + currentConnection);
dev["network_watchdog"]["last_restart"] = new Date().toLocaleString();
dev["network_watchdog"]["status"] = "RESTARTING";
// Формируем команду восстановления динамически, используя текущее (или последнее известное) соединение
var restartCmd = "systemctl restart ModemManager; sleep 65; nmcli connection up \"" + currentConnection + "\" || true";
// Запуск команды восстановления
runShellCommand(restartCmd, {
exitCallback: function (code) {
// Код 0 значит, что скрипт отработал (даже если связь уже была)
log("Network Watchdog: Recovery sequence finished.");
}
});
// Сбрасываем счетчик на 0.
// Это дает системе "кредит доверия" еще на 10 минут.
failureCounter = 0;
}
}
});
}
// Запуск
setInterval(checkConnection, checkIntervalMs);
