Этот подпоток используется разными потоками для проверки непрерывности поступления произвольных данных и уведомлении, если данные перестали поступать.
В этом подпотоке используются следующие узлы, которых нет в стандартной поставке:
Эти подпотоки входят в состав кода ниже и загружать отдельно их не надо!
Первое сообщение проходит триггер, запуская счетчик и сразу направляется в узлы проверки наличия соответствующей записи в таблице. Если записи нет, она добавляется. Далее проверяется, отправлялось ли письмо об возобновлении поступления сообщений. Если нет, меняется флаг отправки и формируется письмо с уведомлением. Если да, то ничего не происходит.
Пока с потоком сообщений все хорошо, каждое новое сообщение продлевает таймер. Как только сообщения перестали поступать, срабатывает триггер, снимается флаг отправки и отправляется письмо с предупреждением.
Для работы этого подпотока, необходимо вручную создать таблицу, выполнив SQL-запрос:
CREATE TABLE watchdog (topic TEXT PRIMARY KEY, name TEXT, sent INTEGER DEFAULT 0)
Пример цепочки:
[ { "id": "28be5e5d.cb7442", "type": "inject", "z": "98ba2d02.5ee68", "name": "Подготовка запроса", "props": [ { "p": "topic", "vt": "str" }, { "p": "payload" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "CREATE TABLE watchdog (topic TEXT PRIMARY KEY, name TEXT, sent INTEGER DEFAULT 0)", "payload": "", "payloadType": "date", "x": 150, "y": 680, "wires": [ [ "d089a31b.a5805" ] ] }, { "id": "758cd73a.9cf318", "type": "debug", "z": "98ba2d02.5ee68", "name": "Вывод команды", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "true", "targetType": "full", "statusVal": "", "statusType": "auto", "x": 150, "y": 800, "wires": [] }, { "id": "d089a31b.a5805", "type": "sqlite", "z": "98ba2d02.5ee68", "mydb": "abf4792e.cd5078", "sqlquery": "msg.topic", "sql": "", "name": "Создание таблицы", "x": 150, "y": 740, "wires": [ [ "758cd73a.9cf318" ] ] }, { "id": "abf4792e.cd5078", "type": "sqlitedb", "z": "98ba2d02.5ee68", "db": "c:\\noderedDB\\watchdog.db", "mode": "RWC" } ]
После добавления подпотока на рабочую область, нужно настроить его взаимодействие с существующей цепочкой узлов. Этот подпоток принимает msg.topic в качестве ID устройства и msg.payload в качестве названия, которое будет указано в теле письма. Для установки этих параметров удобнее всего использовать перед ним узел «change».
Помимо этого, в свойствах узла, которые открываются при двойном клике на узел в рабочей области, можно изменить задержку срабатывания таймера. По умолчанию установлено 3600000 миллисекунд, что равняется 60 минутам.
[ { "id": "38c9a069.18cd6", "type": "subflow", "name": "sendmail", "info": "Отправляет почту по настроенным реквизитам.", "category": "", "in": [ { "x": 80, "y": 40, "wires": [ { "id": "be1032f6.e2b02" } ] } ], "out": [], "env": [], "color": "#C7E9C0", "icon": "node-red/envelope.svg" }, { "id": "be1032f6.e2b02", "type": "e-mail", "z": "38c9a069.18cd6", "server": "smtp.mail.com", "port": "465", "secure": true, "tls": true, "name": "nikolay@soloshin.su", "dname": "Отправка сообщения", "x": 260, "y": 40, "wires": [] }, { "id": "98ba2d02.5ee68", "type": "subflow", "name": "watchdog", "info": "Ожидает поступление сообщений в установленный интервал, если сообщения нет, генерирует письмо с предупреждением.\n\nПринимает **msg.topic** в качестве ID датчика и **msg.payload** в качестве названия, которые будут указаны в теле письма.", "category": "", "in": [ { "x": 80, "y": 40, "wires": [ { "id": "fee5d855.a15048" } ] } ], "out": [], "env": [ { "name": "msgnote35634", "type": "str", "value": "", "ui": { "label": { "en-US": "Укажите задержку срабатывания таймера в миллисекундах." }, "type": "none" } }, { "name": "msgdelay", "type": "num", "value": "3600000", "ui": { "icon": "font-awesome/fa-clock-o", "label": { "en-US": "Задержка (мс)" }, "type": "input", "opts": { "types": [ "num" ] } } } ], "color": "#FFAAAA", "icon": "font-awesome/fa-clock-o" }, { "id": "7cada431.44b94c", "type": "trigger", "z": "98ba2d02.5ee68", "name": "Таймер", "op1": "", "op2": "", "op1type": "pay", "op2type": "date", "duration": "10", "extend": true, "overrideDelay": true, "units": "s", "reset": "", "bytopic": "topic", "topic": "topic", "outputs": 2, "x": 540, "y": 40, "wires": [ [ "536fe262.24fb2c" ], [ "27141a53.5a2246" ] ], "outputLabels": [ "Первое", "Ошибка" ] }, { "id": "3cfc87ed.72e3d8", "type": "subflow:38c9a069.18cd6", "z": "98ba2d02.5ee68", "name": "Отправка почты", "env": [], "x": 710, "y": 580, "wires": [] }, { "id": "ca1cc7d1.c86308", "type": "change", "z": "98ba2d02.5ee68", "name": "Установка текстовых полей письма", "rules": [ { "t": "move", "p": "firstline", "pt": "msg", "to": "payload", "tot": "msg" }, { "t": "set", "p": "topic", "pt": "msg", "to": "\"Изменился статус датчика (\" & $now('[H01]:[m01]:[s01] [D01].[M01].[Y0001]', '+1000') & \")\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 210, "y": 580, "wires": [ [ "3cfc87ed.72e3d8" ] ] }, { "id": "fee5d855.a15048", "type": "change", "z": "98ba2d02.5ee68", "name": "Установка задержки таймера", "rules": [ { "t": "set", "p": "delay", "pt": "msg", "to": "msgdelay", "tot": "env" }, { "t": "set", "p": "savedtopic", "pt": "msg", "to": "topic", "tot": "msg" }, { "t": "set", "p": "savedpayload", "pt": "msg", "to": "payload", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 290, "y": 40, "wires": [ [ "7cada431.44b94c" ] ] }, { "id": "536fe262.24fb2c", "type": "change", "z": "98ba2d02.5ee68", "name": "Подготовка запроса", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "\"SELECT * FROM watchdog WHERE topic = \\\"\" & savedtopic & \"\\\"\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 160, "y": 100, "wires": [ [ "25c0b13d.61990e" ] ] }, { "id": "25c0b13d.61990e", "type": "sqlite", "z": "98ba2d02.5ee68", "mydb": "abf4792e.cd5078", "sqlquery": "msg.topic", "sql": "", "name": "Запрос на наличие записи в БД", "x": 200, "y": 160, "wires": [ [ "43ffca62.b3b554" ] ] }, { "id": "43ffca62.b3b554", "type": "switch", "z": "98ba2d02.5ee68", "name": "Маршрутизация", "property": "payload", "propertyType": "msg", "rules": [ { "t": "nempty" }, { "t": "else" } ], "checkall": "false", "repair": false, "outputs": 2, "x": 650, "y": 160, "wires": [ [ "2557a088.c4251" ], [ "90a4953e.e690a8" ] ] }, { "id": "90a4953e.e690a8", "type": "change", "z": "98ba2d02.5ee68", "name": "Подготовка запроса", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "\"INSERT INTO watchdog (topic, name) VALUES (\\\"\" & savedtopic & \"\\\", \\\"\" & savedpayload & \"\\\")\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 160, "y": 220, "wires": [ [ "235c7484.7cd52c" ] ] }, { "id": "235c7484.7cd52c", "type": "sqlite", "z": "98ba2d02.5ee68", "mydb": "abf4792e.cd5078", "sqlquery": "msg.topic", "sql": "", "name": "Добавление отсутствующей записи", "x": 210, "y": 280, "wires": [ [ "2557a088.c4251" ] ] }, { "id": "2557a088.c4251", "type": "change", "z": "98ba2d02.5ee68", "name": "Подготовка запроса", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "\"SELECT * FROM watchdog WHERE topic = \\\"\" & savedtopic & \"\\\" AND sent = false\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 540, "y": 280, "wires": [ [ "b903c102.384fe" ] ] }, { "id": "b903c102.384fe", "type": "sqlite", "z": "98ba2d02.5ee68", "mydb": "abf4792e.cd5078", "sqlquery": "msg.topic", "sql": "", "name": "Выборка записей, которые не отправлялись", "x": 240, "y": 340, "wires": [ [ "2d7a7c9c.c9c0a4" ] ] }, { "id": "2d7a7c9c.c9c0a4", "type": "switch", "z": "98ba2d02.5ee68", "name": "Отсечка пустых сообщений", "property": "payload", "propertyType": "msg", "rules": [ { "t": "nempty" } ], "checkall": "false", "repair": false, "outputs": 1, "x": 180, "y": 400, "wires": [ [ "29c18b99.2c4044" ] ] }, { "id": "27141a53.5a2246", "type": "change", "z": "98ba2d02.5ee68", "name": "Настройка текста письма (false)", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "false", "tot": "bool" }, { "t": "set", "p": "firstline", "pt": "msg", "to": "\"Датчик \\\"\" & savedpayload & \"\\\" не передает показания уже \" & $ceil(delay/1000/60) & \" мин!\\n\\nИдентификатор устройства \\\"\" & savedtopic & \"\\\".\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 660, "y": 100, "wires": [ [ "b13655cc.bdf9d8" ] ] }, { "id": "b13655cc.bdf9d8", "type": "change", "z": "98ba2d02.5ee68", "name": "Подготовка запроса", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "\"UPDATE watchdog SET sent = \" & topic & \" WHERE topic = \\\"\" & savedtopic & \"\\\"\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 700, "y": 460, "wires": [ [ "b4d28c09.f2007" ] ] }, { "id": "b4d28c09.f2007", "type": "sqlite", "z": "98ba2d02.5ee68", "mydb": "abf4792e.cd5078", "sqlquery": "msg.topic", "sql": "", "name": "Установка флага отправки", "x": 180, "y": 520, "wires": [ [ "ca1cc7d1.c86308" ] ] }, { "id": "29c18b99.2c4044", "type": "change", "z": "98ba2d02.5ee68", "name": "Настройка текста письма (true)", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "true", "tot": "bool" }, { "t": "set", "p": "firstline", "pt": "msg", "to": "\"Датчик \\\"\" & savedpayload & \"\\\" передал показания! Интервал проверки \" & $ceil(delay/1000/60) & \" мин.\\n\\nИдентификатор устройства \\\"\" & savedtopic & \"\\\".\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 190, "y": 460, "wires": [ [ "b13655cc.bdf9d8" ] ] }, { "id": "abf4792e.cd5078", "type": "sqlitedb", "z": "98ba2d02.5ee68", "db": "c:\\noderedDB\\watchdog.db", "mode": "RWC" } ]
Обсуждение