Переписал функции подписки и создания виртуального устройства пока так
Спойлер
// Скрипт подписывается на топики ошибок связи и выводит в UI информацию о ошибках
var Device = "Check_serial_error";
var NameEN = "Check serial error";
var NameRU = "Обработка ошибок связи"
var nDevice = Device;
var sErrorTXT = "/Error_TXT";
var sWarningTXT = "/Warning_TXT";
var sResetError = "/pbReset";
//----------------СОЗДАНИЕ ВИРТУАЛЬНОГО УСТРОЙСТВА----------------------//
// Функция создание виртуального устройства
function Create_VDevice(vdDevice,vdNameEN,vdNameRU) {
try {
return defineVirtualDevice(vdDevice, {
// имя виджета в GUI
title: { en: vdNameEN, ru: vdNameRU},
cells: {
// Текущая ошибка WEB UI
Error_TXT: {
title: { en: "Current Error", ru: "Текущая ошибка" },
type: "text",
value: "Отсутствует",
readonly: true,
forceDefault: true,
order: 1,
},
// Текущая предупреждение WEB UI
Warning_TXT: {
title: { en: "Current warning", ru: "Предупреждение" },
type: "text",
value: "Отсутствует",
readonly: true,
forceDefault: true,
order: 2,
},
// Кнопка сброса ошибки.
pbReset: {
title: { en: "Reset error", ru: "Сброс ошибки" },
type: "pushbutton",
value: "false",
forceDefault: true,
order: 3,
},
},
});
} catch (error) {
log.error("try Error Create " + NameVD + " =" + error);
return undefined;
};
};
// Функция подписки на изменение топика кнопки "СБРОС ОШИБКИ" в WEB UI
function RuleResetError(RuleName) {
try {
return defineRule(RuleName, {
whenChanged: Device + sResetError, // подписка на событие нажатия на кнопку "Сброс ошибки" в WEB UI
then: function (newValue, devName, cellName) { // devName = Control cellName = pbResetFID
log("Произведен ручной сброс ошибки"); // логирование в консоли
//ResetCurrentError(); // Вызываем функцию сброса ошибок
dev[Device + sWarningTXT] = "Отсутствует"; // Очищаем поле предупреждений
dev[nDevice + sErrorTXT] = "Отсутствует"; // Выводим подсказку в WEB UI
},
});
} catch (error) {
log.error("try Error RuleResetError: '" + error + "'");
return undefined;
};
};
//----------------ФУНКЦИИ СОЗДАНИЯ ПОДПИСОК НА ТОПИКИ MQTT----------------------//
// Функция создания правила подписки на пропадании связи с устройствами
function CheckSerialDevices (){
try {
// Подписка на все устройства в которых есть топики /meta/error"
return trackMqtt("/devices/+/controls/+/meta/error", function(message){ // Подписка на все устройства в которых есть топики /meta/error"
// log.info("name: {}, value: {}".format(message.topic, message.value))
// Функция извлечения текста в виде "устройство/топик"
function GetDeviceName(string) {
var parts = string.split('/'); // Разделяем строку по символу '/'
return parts[2] + '/' + parts[4]; // Извлекаем нужные части и объединяем их
};
// Преобразовываем полученное значение для дальнейшего использования
var ShortDeviceString = GetDeviceName(message.topic);
// В зависимости от полученного значения ошибки (message.value) выполняем различные действия
switch (message.value) {
// Если текущая ошибка равна "r" нет ответа от устройства то
case "r":
dev[nDevice + sErrorTXT] = "Ошибка чтения из устройства"; // Выводим подсказку в WEB UI
dev[nDevice + sWarningTXT] = ShortDeviceString; // Выводим подсказку в WEB UI
log.error(
"Ошибка чтения из устройства: {}",
ShortDeviceString
);
break;
// Если текущая ошибка равна "w" запись в устройство не удалась
case "w":
dev[nDevice + sErrorTXT] = "Ошибка записи в устройство"; // Выводим подсказку в WEB UI
dev[nDevice + sWarningTXT] = ShortDeviceString; // Выводим подсказку в WEB UI
log.error(
"Ошибка записи в устройств {}",
ShortDeviceString
);
break;
// Если текущая ошибка равна "rp" попытка возобновить чтение после таймаута не удалась
case "rp":
dev[nDevice + sErrorTXT] = "Ошибка возобновления чтения"; // Выводим подсказку в WEB UI
dev[nDevice + sWarningTXT] = ShortDeviceString; // Выводим подсказку в WEB UI
log.error( // Выводим в лог
"Попытка возобновить чтение с устройства: {} не удалась",
ShortDeviceString
);
break;
// Если текущая ошибка равна "wp". Прим. (сюда не разу не попал наверно такого не бывает)
case "wp":
log.warning(
"Попытка возобновить запись в устройство?: {}, ", // Выводим в лог
ShortDeviceString
);
break;
// Если текущая ошибка равна (p)периодическая попытка чтения?
case "p":
dev[nDevice + sErrorTXT] = "Ошибка возобновления"; // Выводим подсказку в WEB UI
dev[nDevice + sWarningTXT] = ShortDeviceString; // Выводим подсказку в WEB UI
log.error( // Выводим в лог
"Попытка возобновить чтение с устройства: {} не удалась",
ShortDeviceString
);
break;
// Насколько понял сюда попадем в случае возобновления связи с устройством (чтение или запись которые раньше не читались или не записывались)
default:
dev[nDevice + sErrorTXT] = "Связь восстановлена"; // Выводим подсказку в WEB UI
dev[nDevice + sWarningTXT] = ShortDeviceString; // Выводим подсказку в WEB UI
log.warning(
"Возобновление связи c устройством: {}, код: ({})", // Выводим в лог
ShortDeviceString, message.value
);
break;
};
});
// При исключении выводим в MQTT и лог значение которое привело к этому
} catch (error) {
dev[nDevice + sErrorTXT] = " Try checkSerialDevices: " + error;
log.error("Try checkSerialDevices: " + error);
return null;
};
};
//----------------НЕПОСРЕДСТВЕННОЕ СОЗДАНИЕ ----------------------//
var vdCreateCheckSerialError = Create_VDevice (Device,NameEN,NameRU);
var ChangedCheck = CheckSerialDevices ();
var ChangedButton = RuleResetError ("RuleResetError");
вложение
TEST.zip (2,4 КБ)
в интерфейсе это выглядиn так
в логе
при восстановлении
Прим. Сохраняем последнюю ошибку в предупреждении.(после перенесу в журнал ошибок)
в логе так
да конечно можно сделать еще алармом, но все равно не так будет. У реального устройства видна в том числе попытка реанимировать связь (появляется еще значок)
Искал долго информацию что может быть в meta/error? нашел в https://github.com/wirenboard/conventions/blob/main/README.md#errors, где на мой взгляд не очень понятно написано topics can contain a combination of values
в переводе и их вариации ???
, какие???
.Можете перечислить? это же не трудно. Как именно я понял все возможные комбинации см. под спойлер или вложение. Даже пример в Wiki на который здесь ссылались отслеживает только чтение, а если есть и критичная запись в устройство? например (отключить реле). Почему сразу не привести пример на все возможные комбинации?
И не понятно почему это не описать и в https://github.com/wirenboard/wb-mqtt-serial раз оно более всего к нему относится например в главе Обработка ошибок связи и/или где то здесь https://github.com/wirenboard/wb-rules?tab=readme-ov-file#%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF-%D0%BA-%D1%82%D0%BE%D0%BF%D0%B8%D0%BA%D0%B0%D0%BC-meta
Но это так, лирическое отступления пока жду ответ на предыдущие вопросы. В любом случае спасибо Вам за поддержку!
P.S. Причина редактирования ошибки отображения и изменение кода примера