Инструменты пользователя

Инструменты сайта


iot:software:node-red:subflows:watchdog

Сторожевой таймер для Node-RED

Этот подпоток используется разными потоками для проверки непрерывности поступления произвольных данных и уведомлении, если данные перестали поступать.

Нестандартные узлы

В этом подпотоке используются следующие узлы, которых нет в стандартной поставке:

Дополнительные подпотоки

Эти подпотоки входят в состав кода ниже и загружать отдельно их не надо!

Описание работы цепочки

Первое сообщение проходит триггер, запуская счетчик и сразу направляется в узлы проверки наличия соответствующей записи в таблице. Если записи нет, она добавляется. Далее проверяется, отправлялось ли письмо об возобновлении поступления сообщений. Если нет, меняется флаг отправки и формируется письмо с уведомлением. Если да, то ничего не происходит.

Пока с потоком сообщений все хорошо, каждое новое сообщение продлевает таймер. Как только сообщения перестали поступать, срабатывает триггер, снимается флаг отправки и отправляется письмо с предупреждением.

Создание таблицы

:!: Для работы этого подпотока, необходимо вручную создать таблицу, выполнив 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 минутам.

Код для загрузки

watchdog.json
[
    {
        "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"
    }
]

Дисклеймер

  • Использование материалов данной базы знаний разрешено на условиях лицензии, указанной внизу каждой страницы! При использовании материалов активная гиперссылка на соответствующую страницу данной базы знаний обязательна!
  • Автор не несет и не может нести какую либо ответственность за последствия использования материалов, размещенных в данной базе знаний. Все материалы предоставляются по принципу «как есть». Используйте их исключительно на свой страх и риск.
  • Все высказывания, мысли или идеи автора, размещенные в материалах данной базе знаний, являются исключительно его личным субъективным мнением и могут не совпадать с мнением читателей!
  • При размещении ссылок в данной базе знаний на интернет-страницы третьих лиц автор не несет ответственности за их техническую функциональность (особенно отсутствие вирусов) и содержание! При обнаружении таких ссылок, можно и желательно сообщить о них в комментариях к соответствующей статье.

Обсуждение

Ваш комментарий:
Z E J X S L L Y I M N Y O E C​ S
 
Последнее изменение: 2022/02/16 21:20 — Николай Солошин