Небольшой поток для мониторинга произвольных устройств в локальной сети или Интернете версия 2.x, полностью переосмысленная и переписанная – меньше ложных срабатываний1), меньше обращений к базе данных, более компактная, линейная и логичная! В общем, конфетка, а не… то, что было2).
В этой цепочке используются следующие узлы, которых нет в стандартной поставке:
Этот подпоток входит в состав кода ниже и загружать отдельно его не надо!
Цепочка запускается автоматически каждую минуту3), при необходимости или каком-то сбое, можно запустить вручную. Далее из базы данных читаются все устройства, проверяются командой ping и записываются результаты в БД. Если есть устройства, которые не ответили, они попадают в цикл с заданным числом витков и временем между попытками4). Прочие устройства ожидают завершения всех циклов, после чего все сообщения собираются в одно, которое и передается дальше.
Далее подсчитывается количество тех или иных статусов5) и сообщение вновь разбивается на части для объединения по статусам и сортировки. В конце, если необходимо6), формируется и отправляется письмо.
Для работы этого потока, необходимо вручную создать таблицу, выполнив SQL-запрос:
CREATE TABLE nw_status (_id INTEGER PRIMARY KEY, name TEXT, host TEXT, timeout INTEGER, response INTEGER, sent INTEGER DEFAULT 0, cycles INTEGER)
Пример цепочки:
[ { "id": "28be5e5d.cb7442", "type": "inject", "z": "66d1b95c.cf90f8", "name": "Подготовка запроса", "props": [ { "p": "topic", "vt": "str" }, { "p": "payload" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "CREATE TABLE nw_status (_id INTEGER PRIMARY KEY, name TEXT, host TEXT, timeout INTEGER, response INTEGER, sent INTEGER DEFAULT 0, cycles INTEGER)", "payload": "", "payloadType": "date", "x": 350, "y": 240, "wires": [ [ "d089a31b.a5805" ] ] }, { "id": "758cd73a.9cf318", "type": "debug", "z": "66d1b95c.cf90f8", "name": "Вывод команды", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "true", "targetType": "full", "statusVal": "", "statusType": "auto", "x": 350, "y": 360, "wires": [] }, { "id": "d089a31b.a5805", "type": "sqlite", "z": "66d1b95c.cf90f8", "mydb": "2bc4c6d.cf1f03a", "sqlquery": "msg.topic", "sql": "", "name": "Создание таблицы", "x": 350, "y": 300, "wires": [ [ "758cd73a.9cf318" ] ] }, { "id": "2bc4c6d.cf1f03a", "type": "sqlitedb", "db": "c:\\noderedDB\\nw_status.db", "mode": "RWC" } ]
Все эти запросы можно вставлять в msg.topic узла «inject» из примера цепочки в предыдущем пункте.
INSERT INTO nw_status (name, host, timeout) VALUES ("Устройство 1", "192.168.0.5", 10000)
Если таймаут необходимо установить по умолчанию, вместо цифр указать NULL
8) или не использовать его в запросе:
INSERT INTO nw_status (name, host) VALUES ("Устройство 1", "192.168.0.5")
INSERT INTO nw_status (name, host, timeout) VALUES ("Устройство 1", "192.168.0.5", NULL), ("Устройство 2", "192.168.0.6", 7000), ("Устройство 3", "192.168.0.7", 2000)
SELECT * FROM nw_status
Запрос для удаления устройства с номером 2.
DELETE FROM nw_status WHERE _id = 2
Во второй версии потока есть ограничение – ряд _id
должен быть цельным, без пропусков9), т.е. нельзя просто так удалить устройство – его необходимо заменить другим или присвоить его номер последнему устройству в списке!
Для замены _id
в последней строке базы данных можно использовать такой запрос:
UPDATE nw_status SET _id = 2 WHERE _rowid_ = ( SELECT MAX( _rowid_ ) FROM nw_status )
[ { "id": "38c9a069.18cd6", "type": "subflow", "name": "sendmail", "info": "Отправляет почту по настроенным реквизитам.", "category": "", "in": [ { "x": 60, "y": 60, "wires": [ { "id": "be1032f6.e2b02" } ] } ], "out": [], "env": [], "color": "#C7E9C0", "icon": "node-red/envelope.svg" }, { "id": "be1032f6.e2b02", "type": "e-mail", "z": "38c9a069.18cd6", "server": "smtp.beget.com", "port": "465", "secure": true, "tls": true, "name": "nikolay@soloshin.su", "dname": "Отправка сообщения", "x": 240, "y": 60, "wires": [] }, { "id": "bf63e9a3.a5b928", "type": "tab", "label": "Мониторинг сети", "disabled": false, "info": "" }, { "id": "817060ef.2b843", "type": "inject", "z": "bf63e9a3.a5b928", "name": "Автозапуск", "props": [], "repeat": "60", "crontab": "", "once": true, "onceDelay": "1", "topic": "", "payloadType": "str", "x": 130, "y": 100, "wires": [ [ "ad444795.a7b668" ] ] }, { "id": "f27932db.06f1e", "type": "sqlite", "z": "bf63e9a3.a5b928", "mydb": "2bc4c6d.cf1f03a", "sqlquery": "msg.topic", "sql": "", "name": "Выборка всех устройств", "x": 690, "y": 40, "wires": [ [ "5ace9ea9.1497d" ] ] }, { "id": "f41fa10e.39756", "type": "ping", "z": "bf63e9a3.a5b928", "protocol": "Automatic", "mode": "triggered", "name": "Проверка связи", "host": "", "timer": "60", "inputs": 1, "x": 460, "y": 160, "wires": [ [ "425962de.576a5c" ] ] }, { "id": "cbb6faf8.027568", "type": "change", "z": "bf63e9a3.a5b928", "name": "Установка счетчика цикла", "rules": [ { "t": "set", "p": "ping.count", "pt": "msg", "to": "$exists( ping.count ) = true ? ( ping.count + 1 ) : 0", "tot": "jsonata" }, { "t": "set", "p": "delay", "pt": "msg", "to": "settings.delay", "tot": "flow" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 180, "y": 220, "wires": [ [ "25c3af02.51d2c" ] ] }, { "id": "25c3af02.51d2c", "type": "switch", "z": "bf63e9a3.a5b928", "name": "Проверка счетчика", "property": "ping.count", "propertyType": "msg", "rules": [ { "t": "neq", "v": "settings.cycles", "vt": "flow" }, { "t": "eq", "v": "settings.cycles", "vt": "flow" } ], "checkall": "false", "repair": false, "outputs": 2, "x": 460, "y": 220, "wires": [ [ "202cf843.0c54a8" ], [ "73733ff5.013f9" ] ], "outputLabels": [ "Повторить цикл", "Завершить цикл" ] }, { "id": "425962de.576a5c", "type": "switch", "z": "bf63e9a3.a5b928", "name": "Доступность устройства", "property": "payload", "propertyType": "msg", "rules": [ { "t": "false" }, { "t": "else" } ], "checkall": "false", "repair": false, "outputs": 2, "x": 690, "y": 160, "wires": [ [ "cbb6faf8.027568" ], [ "47244dcf.c20b34" ] ], "outputLabels": [ "Не отвечает", "Отвечает" ] }, { "id": "202cf843.0c54a8", "type": "template", "z": "bf63e9a3.a5b928", "name": "Восстановление структуры", "field": "payload", "fieldType": "msg", "format": "handlebars", "syntax": "mustache", "template": "[{\n\"_id\": {{{ping._id}}},\n\"name\": \"{{{ping.name}}}\",\n\"host\": \"{{{ping.host}}}\",\n\"timeout\": {{{ping.timeout}}},\n\"sent\": {{{ping.sent}}},\n\"count\": {{{ping.count}}}\n}]", "output": "json", "x": 680, "y": 280, "wires": [ [ "d2b39ab6.0c64f8" ] ] }, { "id": "73733ff5.013f9", "type": "change", "z": "bf63e9a3.a5b928", "name": "Установка св-в", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "\"UPDATE \\\"\" & $flowContext( \"settings.table\" ) & \"\\\" SET response = \" & payload & \", cycles = \" & ( $exists( ping.count ) = false ? 0 : ping.count ) & \" WHERE _id = \" & ping._id", "tot": "jsonata" }, { "t": "set", "p": "parts.index", "pt": "msg", "to": "ping._id - 1", "tot": "jsonata" }, { "t": "set", "p": "parts.count", "pt": "msg", "to": "parts.count", "tot": "flow" }, { "t": "set", "p": "parts.id", "pt": "msg", "to": "parts.id", "tot": "flow" }, { "t": "move", "p": "payload", "pt": "msg", "to": "ping.response", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 220, "y": 280, "wires": [ [ "5d114f5c.32a04" ] ] }, { "id": "5d114f5c.32a04", "type": "sqlite", "z": "bf63e9a3.a5b928", "mydb": "2bc4c6d.cf1f03a", "sqlquery": "msg.topic", "sql": "", "name": "Запись ответов", "x": 420, "y": 280, "wires": [ [ "8961f0c.35b121" ] ] }, { "id": "5ace9ea9.1497d", "type": "change", "z": "bf63e9a3.a5b928", "name": "Сохранение переменных", "rules": [ { "t": "set", "p": "parts.count", "pt": "flow", "to": "$count( payload )\t", "tot": "jsonata" }, { "t": "set", "p": "parts.id", "pt": "flow", "to": "", "tot": "date" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 680, "y": 100, "wires": [ [ "f41fa10e.39756" ] ] }, { "id": "93dadf2f.1e905", "type": "join", "z": "bf63e9a3.a5b928", "name": "Объединение", "mode": "auto", "build": "string", "property": "payload", "propertyType": "msg", "key": "topic", "joiner": "\\n", "joinerType": "str", "accumulate": false, "timeout": "", "count": "", "reduceRight": false, "reduceExp": "", "reduceInit": "", "reduceInitType": "num", "reduceFixup": "", "x": 480, "y": 340, "wires": [ [ "d763f5eb.4a1378" ] ], "info": "Восстанавливается и объединяется последовательность для того, чтобы достоверно узнать завершение операции тестирования связи." }, { "id": "8961f0c.35b121", "type": "change", "z": "bf63e9a3.a5b928", "name": "Установка статусов", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "$type( payload ) = \"array\" ? ping : payload", "tot": "jsonata" }, { "t": "set", "p": "payload.status", "pt": "msg", "to": "( payload.sent = 0 and payload.response = false ) ? \"died\" : ( payload.sent = 1 and payload.response = false ) ? \"dead\" : ( payload.sent = 1 and payload.response > 0 ) ? \"revived\" : ( payload.sent = 0 and payload.response > 0 ) ? \"alive\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 240, "y": 340, "wires": [ [ "93dadf2f.1e905" ] ] }, { "id": "51891d56.192d94", "type": "delay", "z": "bf63e9a3.a5b928", "name": "Задержка проверки", "pauseType": "delayv", "timeout": "1", "timeoutUnits": "seconds", "rate": "1", "nbRateUnits": "1", "rateUnits": "second", "randomFirst": "1", "randomLast": "5", "randomUnits": "seconds", "drop": false, "x": 220, "y": 160, "wires": [ [ "f41fa10e.39756" ] ] }, { "id": "6ccc324d.f380bc", "type": "change", "z": "bf63e9a3.a5b928", "name": "Ввод настроек", "rules": [ { "t": "set", "p": "settings.cycles", "pt": "flow", "to": "3", "tot": "num" }, { "t": "set", "p": "settings.delay", "pt": "flow", "to": "10000", "tot": "num" }, { "t": "set", "p": "settings.table", "pt": "flow", "to": "nw_status_test", "tot": "str" }, { "t": "set", "p": "topic", "pt": "msg", "to": "\"SELECT _id, name, host, timeout, sent FROM \\\"\" & $flowContext( \"settings.table\" ) & \"\\\"\"", "tot": "jsonata" }, { "t": "set", "p": "status.run", "pt": "flow", "to": "true", "tot": "bool" }, { "t": "set", "p": "status.sent", "pt": "flow", "to": "false", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 440, "y": 40, "wires": [ [ "f27932db.06f1e" ] ], "info": "**flow.settings.cycles** -- количество дополнительных попыток проверки связи (при установке \"0\" будет проведена 1 попытка; при установке \"1\", соответственно, 2, т.е. одна основная, и одна дополнительная);\n\n**flow.settings.delay** -- задержка между дополнительными попытками проверки;\n\n**flow.settings.table** -- название таблицы в базе данных." }, { "id": "dbabb4a5.093288", "type": "link in", "z": "bf63e9a3.a5b928", "name": "", "links": [ "d2b39ab6.0c64f8" ], "x": 75, "y": 160, "wires": [ [ "51891d56.192d94" ] ] }, { "id": "d2b39ab6.0c64f8", "type": "link out", "z": "bf63e9a3.a5b928", "name": "", "links": [ "dbabb4a5.093288" ], "x": 675, "y": 220, "wires": [] }, { "id": "721310f6.a461a", "type": "link in", "z": "bf63e9a3.a5b928", "name": "", "links": [ "47244dcf.c20b34" ], "x": 75, "y": 280, "wires": [ [ "73733ff5.013f9" ] ] }, { "id": "47244dcf.c20b34", "type": "link out", "z": "bf63e9a3.a5b928", "name": "", "links": [ "721310f6.a461a" ], "x": 775, "y": 220, "wires": [] }, { "id": "ad444795.a7b668", "type": "switch", "z": "bf63e9a3.a5b928", "name": "Проверка метки", "property": "status.run", "propertyType": "flow", "rules": [ { "t": "jsonata_exp", "v": "$exists( $flowContext( \"status.run\" ) ) = false or $flowContext( \"status.run\" ) = false", "vt": "jsonata" }, { "t": "jsonata_exp", "v": "( $exists( $flowContext( \"status.sent\" ) ) = false or $flowContext( \"status.sent\" ) = false) and $flowContext( \"status.run\" ) = true", "vt": "jsonata" } ], "checkall": "false", "repair": false, "outputs": 2, "x": 330, "y": 100, "wires": [ [ "6ccc324d.f380bc" ], [ "65cbf7fe.7357d8" ] ], "info": "Фильтр запуска цепочки до завершения предыдущей задачи." }, { "id": "d763f5eb.4a1378", "type": "change", "z": "bf63e9a3.a5b928", "name": "Подсчет статусов", "rules": [ { "t": "set", "p": "result.alive", "pt": "msg", "to": "payload.$sift( function( $v, $k ) { $k = \"status\" and $v = \"alive\" } ) ~> $count()", "tot": "jsonata" }, { "t": "set", "p": "result.dead", "pt": "msg", "to": "payload.$sift( function( $v, $k ) { $k = \"status\" and $v = \"dead\" } ) ~> $count()", "tot": "jsonata" }, { "t": "set", "p": "result.revived", "pt": "msg", "to": "payload.$sift( function( $v, $k ) { $k = \"status\" and $v = \"revived\" } ) ~> $count()", "tot": "jsonata" }, { "t": "set", "p": "result.died", "pt": "msg", "to": "payload.$sift( function( $v, $k ) { $k = \"status\" and $v = \"died\" } ) ~> $count()", "tot": "jsonata" }, { "t": "set", "p": "status.run", "pt": "flow", "to": "false", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 710, "y": 340, "wires": [ [ "71abee18.7fdf4" ] ] }, { "id": "2aa2153.fed7bea", "type": "subflow:38c9a069.18cd6", "z": "bf63e9a3.a5b928", "name": "Отправка писем", "env": [], "x": 710, "y": 640, "wires": [] }, { "id": "38565f85.6837e", "type": "change", "z": "bf63e9a3.a5b928", "name": "Наложение проверок", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "\"Уведомление системы мониторинга от \" & $now( '[H01]:[m01]:[s01] [D01].[M01].[Y0001]', '+1000' ) & \"!\"", "tot": "jsonata" }, { "t": "set", "p": "payload", "pt": "msg", "to": "Запущен новый цикл проверки, тогда как предыдущий еще не завершен! Текущая проверка отменена. Возможно, необходимо увеличить интервал запуска.", "tot": "str" }, { "t": "set", "p": "status.sent", "pt": "flow", "to": "true", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 700, "y": 700, "wires": [ [ "2aa2153.fed7bea" ] ] }, { "id": "49762568.343b6c", "type": "link in", "z": "bf63e9a3.a5b928", "name": "", "links": [ "65cbf7fe.7357d8" ], "x": 555, "y": 700, "wires": [ [ "38565f85.6837e" ] ] }, { "id": "65cbf7fe.7357d8", "type": "link out", "z": "bf63e9a3.a5b928", "name": "", "links": [ "49762568.343b6c" ], "x": 495, "y": 100, "wires": [] }, { "id": "924e62cc.f20bf", "type": "csv", "z": "bf63e9a3.a5b928", "name": "Преобразование в текст", "sep": ",", "hdrin": "", "hdrout": "none", "multi": "one", "ret": "\\r\\n", "temp": "string", "skip": "0", "strings": true, "include_empty_strings": "", "include_null_values": "", "x": 430, "y": 520, "wires": [ [ "6d923a0c.dfcda4" ] ] }, { "id": "dd59e694.b8b688", "type": "split", "z": "bf63e9a3.a5b928", "name": "Разделение пос-и", "splt": "\\n", "spltType": "str", "arraySplt": 1, "arraySpltType": "len", "stream": false, "addname": "", "x": 430, "y": 400, "wires": [ [ "15fa5ef7.8a6351", "5a977cdd.89d1a4" ] ] }, { "id": "5a977cdd.89d1a4", "type": "change", "z": "bf63e9a3.a5b928", "name": "Подготовка свойств", "rules": [ { "t": "set", "p": "parts.id", "pt": "msg", "to": "payload.status", "tot": "msg" }, { "t": "set", "p": "parts.count", "pt": "msg", "to": "parts.id = \"alive\" ? result.alive : parts.id = \"dead\" ? result.dead : parts.id = \"revived\" ? result.revived : parts.id = \"died\" ? result.died", "tot": "jsonata" }, { "t": "delete", "p": "parts.index", "pt": "msg" }, { "t": "set", "p": "payload.string", "pt": "msg", "to": "( payload.response = false ? \"∞\" : payload.response ) & \" мс (\" & ( $exists( payload.count ) = false ? 0 : payload.count ) & \") - \" & payload.name & \" (\" & payload.host & \")\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 160, "y": 460, "wires": [ [ "3e710520.472cea" ] ] }, { "id": "3e710520.472cea", "type": "join", "z": "bf63e9a3.a5b928", "name": "Группировка по статусу", "mode": "auto", "build": "string", "property": "payload", "propertyType": "msg", "key": "topic", "joiner": "\\n", "joinerType": "str", "accumulate": false, "timeout": "", "count": "", "reduceRight": false, "reduceExp": "", "reduceInit": "", "reduceInitType": "", "reduceFixup": "", "x": 410, "y": 460, "wires": [ [ "5f8d8b50.4b7204" ] ], "info": "Создает до двух отдельных сообщений в зависимости от статуса -- отвечает устройство или нет." }, { "id": "5f8d8b50.4b7204", "type": "change", "z": "bf63e9a3.a5b928", "name": "Подготовка нагрузки", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "$type( payload[0].response ) = \"number\" ? $sort( payload, function( $l, $r ) { $l.response < $r.response } ) : payload", "tot": "jsonata" }, { "t": "set", "p": "result.status", "pt": "msg", "to": "payload[0].status", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 160, "y": 520, "wires": [ [ "924e62cc.f20bf" ] ] }, { "id": "15fa5ef7.8a6351", "type": "switch", "z": "bf63e9a3.a5b928", "name": "Фильтрация статусов", "property": "payload", "propertyType": "msg", "rules": [ { "t": "jsonata_exp", "v": "payload.status = \"died\" or payload.status = \"revived\"", "vt": "jsonata" } ], "checkall": "false", "repair": false, "outputs": 1, "x": 700, "y": 400, "wires": [ [ "663cca43.d8dff4" ] ] }, { "id": "a07661e9.dc5b5", "type": "sqlite", "z": "bf63e9a3.a5b928", "mydb": "2bc4c6d.cf1f03a", "sqlquery": "msg.topic", "sql": "", "name": "Запись статусов", "x": 710, "y": 520, "wires": [ [] ] }, { "id": "663cca43.d8dff4", "type": "change", "z": "bf63e9a3.a5b928", "name": "Подготовка изменений", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "\"UPDATE \"& $flowContext( \"settings.table\" ) & \" SET sent = \" & ( ( payload.status = \"died\" and payload.sent = 0 ) ? 1 : ( payload.status = \"revived\" and payload.sent = 1 ) ? 0 ) & \" WHERE _id = \" & payload._id", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 690, "y": 460, "wires": [ [ "a07661e9.dc5b5" ] ] }, { "id": "71abee18.7fdf4", "type": "switch", "z": "bf63e9a3.a5b928", "name": "Фильтрация изменений", "property": "payload", "propertyType": "msg", "rules": [ { "t": "jsonata_exp", "v": "( result.revived > 0 or result.died > 0 ) or ( result.dead > 0 and periodical = true)", "vt": "jsonata" } ], "checkall": "false", "repair": false, "outputs": 1, "x": 170, "y": 400, "wires": [ [ "dd59e694.b8b688" ] ] }, { "id": "6d923a0c.dfcda4", "type": "change", "z": "bf63e9a3.a5b928", "name": "Сохранение текста", "rules": [ { "t": "set", "p": "status.texts", "pt": "flow", "to": "$merge( [ $flowContext( \"status.texts\" ), { $.result.status : payload } ] )", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 160, "y": 580, "wires": [ [ "2fb8a144.23e9ee" ] ] }, { "id": "2fb8a144.23e9ee", "type": "trigger", "z": "bf63e9a3.a5b928", "name": "Ожидание всех частей", "op1": "", "op2": "true", "op1type": "nul", "op2type": "bool", "duration": "2", "extend": true, "overrideDelay": false, "units": "s", "reset": "", "bytopic": "all", "topic": "topic", "outputs": 1, "x": 430, "y": 580, "wires": [ [ "13bfd89.8a76c27" ] ] }, { "id": "13bfd89.8a76c27", "type": "change", "z": "bf63e9a3.a5b928", "name": "Подготовка письма", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "( periodical = true ? \"Сводка системы мониторинга от \" : \"Уведомление системы мониторинга от \" ) & $now( '[H01]:[m01]:[s01] [D01].[M01].[Y0001]', '+1000' ) & \"!\"", "tot": "jsonata" }, { "t": "set", "p": "payload", "pt": "msg", "to": "( $exists( $flowContext( \"status.texts.revived\" ) ) = true ? \"Устройства начали отвечать:\\n\" ) & ( $exists( $flowContext( \"status.texts.revived\" ) ) = true ? ( $flowContext( \"status.texts.revived\" ) & \"\\n\" ) ) & ( $exists( $flowContext( \"status.texts.died\" ) ) = true ? \"Устройства перестали отвечать: \\n\" ) & ( $exists( $flowContext( \"status.texts.died\" ) ) = true ? ( $flowContext( \"status.texts.died\" ) & \"\\n\" ) ) & ( $exists( $flowContext( \"status.texts.dead\" ) ) = true ? \"Устройства не отвечают:\\n\" ) & ( $exists( $flowContext( \"status.texts.dead\" ) ) = true ? ( $flowContext( \"status.texts.dead\" ) & \"\\n\" ) ) & ( $exists( $flowContext( \"status.texts.alive\" ) ) = true ? \"Диагностические данные:\\n\" ) & ( $exists( $flowContext( \"status.texts.alive\" ) ) = true ? $flowContext( \"status.texts.alive\" ) )", "tot": "jsonata" }, { "t": "delete", "p": "status.texts", "pt": "flow" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 700, "y": 580, "wires": [ [ "2aa2153.fed7bea" ] ] }, { "id": "172accf.e425333", "type": "inject", "z": "bf63e9a3.a5b928", "name": "Запустить и сбросить метку", "props": [], "repeat": "", "crontab": "", "once": false, "onceDelay": "1", "topic": "", "payloadType": "str", "x": 180, "y": 40, "wires": [ [ "6ccc324d.f380bc" ] ], "info": "Сбросить метку `flow.status.run` и запустить поток. Полезно при сбоях, когда цепочка повисла в режиме ожидания." }, { "id": "d45c7cea.9b2c4", "type": "inject", "z": "bf63e9a3.a5b928", "name": "Периодическая сводка", "props": [ { "p": "topic", "v": "\"SELECT _id, name, host, response, sent, cycles FROM \\\"\" & $flowContext( \"settings.table\" ) & \"\\\"\"", "vt": "jsonata" }, { "p": "periodical", "v": "true", "vt": "bool" } ], "repeat": "21600", "crontab": "", "once": true, "onceDelay": "60", "topic": "", "payloadType": "str", "x": 170, "y": 640, "wires": [ [ "994ffc21.74839" ] ], "info": "Отправляется только, если есть \"мертвые\" устройства." }, { "id": "994ffc21.74839", "type": "sqlite", "z": "bf63e9a3.a5b928", "mydb": "2bc4c6d.cf1f03a", "sqlquery": "msg.topic", "sql": "", "name": "Выборка устройств", "x": 440, "y": 640, "wires": [ [ "f97471ca.36e7d" ] ] }, { "id": "f97471ca.36e7d", "type": "split", "z": "bf63e9a3.a5b928", "name": "Разделение пос-и", "splt": "\\n", "spltType": "str", "arraySplt": 1, "arraySpltType": "len", "stream": false, "addname": "", "x": 150, "y": 700, "wires": [ [ "a11064c5.7b4778" ] ] }, { "id": "f9033d4c.c67e1", "type": "link in", "z": "bf63e9a3.a5b928", "name": "", "links": [ "d76d9726.edb0b8" ], "x": 75, "y": 340, "wires": [ [ "8961f0c.35b121" ] ] }, { "id": "d76d9726.edb0b8", "type": "link out", "z": "bf63e9a3.a5b928", "name": "", "links": [ "f9033d4c.c67e1" ], "x": 495, "y": 700, "wires": [] }, { "id": "a11064c5.7b4778", "type": "change", "z": "bf63e9a3.a5b928", "name": "Подготовка св-в", "rules": [ { "t": "set", "p": "payload.response", "pt": "msg", "to": "payload.response = 0 ? false : payload.response", "tot": "jsonata" }, { "t": "move", "p": "payload.cycles", "pt": "msg", "to": "payload.count", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 350, "y": 700, "wires": [ [ "d76d9726.edb0b8" ] ] }, { "id": "2bc4c6d.cf1f03a", "type": "sqlitedb", "db": "c:\\noderedDB\\nw_status.db", "mode": "RWC" } ]
Обсуждение