Эта цепочка узлов является частью потока «Сохранение телеметрии», но может использоваться отдельно.
В этой цепочке используются следующие узлы, которых нет в стандартной поставке:
Эти подпотоки входят в состав кода ниже и загружать отдельно их не надо!
Первые узлы вводят параметры резервного копирования и периодически выполняют его, используя SQL-запрос VACUUM INTO
. Далее происходит архивация резервной копии программой 7-Zip. Потом подготавливается запрос и архив отправляется на FTP-сервер. И, наконец, удаляются старые файлы – глубину архива можно настраивать в первом узле этой части цепочки.
Помимо этого есть три узла отлова ошибок и формирования писем с соответствующими уведомлениями.
[ { "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": "fc6cfd9b.b1327", "type": "inject", "z": "551f568e.e62c18", "name": "Ввод параметров и периодический запуск", "props": [ { "p": "localFilename", "v": "\"telemetry-\" & $now('[Y0001][M01][D01][H01][m01][s01]', '+1000')", "vt": "jsonata" }, { "p": "localPath", "v": "c:\\noderedDB\\backup\\", "vt": "str" }, { "p": "workingDir", "v": "backup", "vt": "str" }, { "p": "archiveType", "v": "zip", "vt": "str" }, { "p": "topic", "v": "\"VACUUM main INTO '\" & localPath & localFilename & \".db'\"", "vt": "jsonata" } ], "repeat": "", "crontab": "22 02 * * *", "once": false, "onceDelay": "1", "topic": "", "x": 230, "y": 760, "wires": [ [ "a59c7f34.c8a12" ] ] }, { "id": "a59c7f34.c8a12", "type": "sqlite", "z": "551f568e.e62c18", "mydb": "dbb6e10a.23844", "sqlquery": "msg.topic", "sql": "", "name": "Резервное копирование базы", "x": 670, "y": 760, "wires": [ [ "98715068.0464a" ] ] }, { "id": "fee8ef4e.31997", "type": "advanced-ftp", "z": "551f568e.e62c18", "ftp": "480cc2b7.0bafdc", "operation": "put", "dataType": "binary", "filename": "", "localFilename": "", "workingDir": "", "oldPath": "", "newPath": "", "command": "", "recursive": false, "useCompression": false, "throwError": false, "showError": true, "name": "Отправка на FTP", "x": 710, "y": 880, "wires": [ [ "94b4e8bb.1ccb68" ] ] }, { "id": "5557801c.f1244", "type": "exec", "z": "551f568e.e62c18", "command": "\"C:\\Program Files\\7-Zip\\7z.exe\"", "addpay": true, "append": "", "useSpawn": "false", "timer": "", "oldrc": false, "name": "Архивация базы", "x": 150, "y": 880, "wires": [ [], [], [ "f1cd7879.e5cfe8" ] ] }, { "id": "98715068.0464a", "type": "change", "z": "551f568e.e62c18", "name": "Установка параметров архивации", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "\"a -sdel -t\" & archiveType & \" \\\"\" & localPath & localFilename & \"\\\" \\\"\" & localPath & localFilename & \".db\\\"\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 200, "y": 820, "wires": [ [ "5557801c.f1244" ] ] }, { "id": "f1cd7879.e5cfe8", "type": "switch", "z": "551f568e.e62c18", "name": "Отлов ошибок 7-Zip", "property": "payload.code", "propertyType": "msg", "rules": [ { "t": "eq", "v": "0", "vt": "num" }, { "t": "else" } ], "checkall": "true", "repair": false, "outputs": 2, "x": 420, "y": 940, "wires": [ [ "32c328b7.cba568" ], [ "4d3bf90.b649d08" ] ], "outputLabels": [ "Успешно", "Ошибка" ] }, { "id": "32c328b7.cba568", "type": "change", "z": "551f568e.e62c18", "name": "Подготовка параметров", "rules": [ { "t": "set", "p": "filename", "pt": "msg", "to": "workingDir & \"/\" & localFilename & \".\" & archiveType", "tot": "jsonata" }, { "t": "set", "p": "localFilename", "pt": "msg", "to": "localPath & localFilename & \".\" & archiveType", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 690, "y": 820, "wires": [ [ "fee8ef4e.31997" ] ] }, { "id": "4d3bf90.b649d08", "type": "change", "z": "551f568e.e62c18", "name": "Подготовка тела письма", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "payload.message", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 430, "y": 1000, "wires": [ [ "43bd8ec0.e5f6a" ] ] }, { "id": "90f9cd4e.41892", "type": "subflow:38c9a069.18cd6", "z": "551f568e.e62c18", "name": "Отправка почты", "env": [], "x": 490, "y": 1120, "wires": [] }, { "id": "8b4fb23f.3fc5e", "type": "status", "z": "551f568e.e62c18", "name": "Отлов ошибок FTP", "scope": [ "fee8ef4e.31997", "a6b4d607.6539d8", "6bf6acce.13b1b4" ], "x": 150, "y": 1060, "wires": [ [ "fb766dc1.84c82" ] ] }, { "id": "fb766dc1.84c82", "type": "switch", "z": "551f568e.e62c18", "name": "Отлов ошибок", "property": "status.fill", "propertyType": "msg", "rules": [ { "t": "eq", "v": "red", "vt": "str" } ], "checkall": "false", "repair": false, "outputs": 1, "x": 140, "y": 1120, "wires": [ [ "2d4148bb.c41d78" ] ] }, { "id": "2d4148bb.c41d78", "type": "change", "z": "551f568e.e62c18", "name": "Подготовка тела письма", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "\"Модуль \\\"\" & status.source.name & \"\\\" выдал ошибку \\\"\" & status.text & \"\\\".\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 170, "y": 1180, "wires": [ [ "43bd8ec0.e5f6a" ] ] }, { "id": "ee80db2.af9fa28", "type": "catch", "z": "551f568e.e62c18", "name": "Отлов ошибок SQLite", "scope": [ "a59c7f34.c8a12" ], "uncaught": false, "x": 160, "y": 940, "wires": [ [ "d2f3bf3f.79422" ] ] }, { "id": "43bd8ec0.e5f6a", "type": "change", "z": "551f568e.e62c18", "name": "Установка темы письма", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "\"Ошибка резервного копирования телеметрии (\" & $now('[H01]:[m01]:[s01] [D01].[M01].[Y0001]', '+1000') & \")!\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 430, "y": 1060, "wires": [ [ "90f9cd4e.41892" ] ] }, { "id": "d2f3bf3f.79422", "type": "change", "z": "551f568e.e62c18", "name": "Подготовка тела письма", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "\"Модуль \\\"\" & error.source.name & \"\\\" выдал ошибку:\\n\\n\\\"\" & error.message & \"\\\"\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 170, "y": 1000, "wires": [ [ "43bd8ec0.e5f6a" ] ] }, { "id": "7c896fde.621af", "type": "link in", "z": "551f568e.e62c18", "name": "Примем почты", "links": [ "f1dd250e.d302b8", "63bb51cd.8a1fc" ], "x": 335, "y": 1120, "wires": [ [ "90f9cd4e.41892" ] ] }, { "id": "a6b4d607.6539d8", "type": "advanced-ftp", "z": "551f568e.e62c18", "ftp": "480cc2b7.0bafdc", "operation": "list", "dataType": "binary", "filename": "", "localFilename": "", "workingDir": "", "oldPath": "", "newPath": "", "command": "", "recursive": false, "useCompression": false, "throwError": false, "showError": true, "name": "Запрос списка файлов", "x": 690, "y": 1000, "wires": [ [ "6f589a7f.74a9c4" ] ] }, { "id": "6f589a7f.74a9c4", "type": "split", "z": "551f568e.e62c18", "name": "Разделение массива", "splt": "\\n", "spltType": "str", "arraySplt": 1, "arraySpltType": "len", "stream": false, "addname": "", "x": 700, "y": 1060, "wires": [ [ "99fd96c4.893608" ] ] }, { "id": "94b4e8bb.1ccb68", "type": "change", "z": "551f568e.e62c18", "name": "Установка срока давности", "rules": [ { "t": "set", "p": "delayDays", "pt": "msg", "to": "7", "tot": "num" }, { "t": "delete", "p": "localFilename", "pt": "msg" }, { "t": "delete", "p": "filename", "pt": "msg" }, { "t": "delete", "p": "operation", "pt": "msg" }, { "t": "delete", "p": "dataType", "pt": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 680, "y": 940, "wires": [ [ "a6b4d607.6539d8" ] ] }, { "id": "99fd96c4.893608", "type": "switch", "z": "551f568e.e62c18", "name": "Выбор файлов", "property": "payload", "propertyType": "msg", "rules": [ { "t": "jsonata_exp", "v": "payload.name = \".htaccess\"", "vt": "jsonata" }, { "t": "jsonata_exp", "v": "$toMillis( $replace( $string( payload.date ), \"\\\"\", \"\" ) ) < $millis() - 86400000 * delayDays", "vt": "jsonata" } ], "checkall": "false", "repair": false, "outputs": 2, "x": 720, "y": 1120, "wires": [ [], [ "84f29eee.6ec95" ] ], "outputLabels": [ ".htaccess", "Старые" ] }, { "id": "6bf6acce.13b1b4", "type": "advanced-ftp", "z": "551f568e.e62c18", "ftp": "480cc2b7.0bafdc", "operation": "delete", "dataType": "binary", "filename": "", "localFilename": "", "workingDir": "", "oldPath": "", "newPath": "", "command": "", "recursive": false, "useCompression": false, "throwError": false, "showError": true, "name": "Удаление старых файлов", "x": 680, "y": 1180, "wires": [ [] ] }, { "id": "84f29eee.6ec95", "type": "change", "z": "551f568e.e62c18", "name": "Подготовка", "rules": [ { "t": "set", "p": "filename", "pt": "msg", "to": "workingDir & \"/\" & payload.name", "tot": "jsonata" }, { "t": "set", "p": "payload", "pt": "msg", "to": "\"/Q \\\"\" & localPath & payload.name & \"\\\" > nul\"", "tot": "jsonata" }, { "t": "delete", "p": "operation", "pt": "msg" }, { "t": "delete", "p": "dataType", "pt": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 430, "y": 1180, "wires": [ [ "6bf6acce.13b1b4", "c42dcbd6.d4a5e8" ] ] }, { "id": "c42dcbd6.d4a5e8", "type": "exec", "z": "551f568e.e62c18", "command": "del", "addpay": true, "append": "", "useSpawn": "false", "timer": "", "oldrc": false, "name": "Удаление локальных файлов", "x": 670, "y": 1240, "wires": [ [], [], [] ] }, { "id": "dbb6e10a.23844", "type": "sqlitedb", "db": "c:\\noderedDB\\telemetry.db", "mode": "RWC" }, { "id": "480cc2b7.0bafdc", "type": "advanced-ftp-config", "host": "tigerc42.beget.tech", "port": "", "secure": false, "secureOptions": "", "user": "tigerc42_nodered", "connTimeout": "", "pasvTimeout": "", "keepalive": "", "name": "telemetry-backup" } ]
Предыдущая модификация без удаления локальных файлов.
[ { "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": "fc6cfd9b.b1327", "type": "inject", "z": "551f568e.e62c18", "name": "Ввод параметров и периодичиский запуск", "props": [ { "p": "localFilename", "v": "\"telemetry-\" & $now('[Y0001][M01][D01][H01][m01][s01]', '+1000')", "vt": "jsonata" }, { "p": "localPath", "v": "c:\\\\noderedDB\\\\backup\\\\", "vt": "str" }, { "p": "archiveType", "v": "zip", "vt": "str" }, { "p": "topic", "v": "\"VACUUM main INTO '\" & localPath & localFilename & \".db'\"", "vt": "jsonata" } ], "repeat": "", "crontab": "22 02 * * *", "once": false, "onceDelay": "1", "topic": "", "payloadType": "str", "x": 230, "y": 760, "wires": [ [ "a59c7f34.c8a12" ] ] }, { "id": "a59c7f34.c8a12", "type": "sqlite", "z": "551f568e.e62c18", "mydb": "dbb6e10a.23844", "sqlquery": "msg.topic", "sql": "", "name": "Резервное копирование базы", "x": 670, "y": 760, "wires": [ [ "98715068.0464a" ] ] }, { "id": "fee8ef4e.31997", "type": "advanced-ftp", "z": "551f568e.e62c18", "ftp": "480cc2b7.0bafdc", "operation": "put", "dataType": "binary", "filename": "", "localFilename": "", "workingDir": "", "oldPath": "", "newPath": "", "command": "", "recursive": false, "useCompression": false, "throwError": false, "showError": true, "name": "Отправка на FTP", "x": 710, "y": 880, "wires": [ [ "94b4e8bb.1ccb68" ] ] }, { "id": "5557801c.f1244", "type": "exec", "z": "551f568e.e62c18", "command": "\"C:\\Program Files\\7-Zip\\7z.exe\"", "addpay": true, "append": "", "useSpawn": "false", "timer": "", "oldrc": false, "name": "Архивация базы", "x": 150, "y": 880, "wires": [ [], [], [ "f1cd7879.e5cfe8" ] ] }, { "id": "98715068.0464a", "type": "change", "z": "551f568e.e62c18", "name": "Установка параметров архивации", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "\"a -sdel -t\" & archiveType & \" \\\"\" & localPath & localFilename & \"\\\" \\\"\" & localPath & localFilename & \".db\\\"\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 200, "y": 820, "wires": [ [ "5557801c.f1244" ] ] }, { "id": "f1cd7879.e5cfe8", "type": "switch", "z": "551f568e.e62c18", "name": "Отлов ошибок 7-Zip", "property": "payload.code", "propertyType": "msg", "rules": [ { "t": "eq", "v": "0", "vt": "num" }, { "t": "else" } ], "checkall": "true", "repair": false, "outputs": 2, "x": 420, "y": 940, "wires": [ [ "32c328b7.cba568" ], [ "4d3bf90.b649d08" ] ], "outputLabels": [ "Успешно", "Ошибка" ] }, { "id": "32c328b7.cba568", "type": "change", "z": "551f568e.e62c18", "name": "Подготовка параметров", "rules": [ { "t": "set", "p": "filename", "pt": "msg", "to": "localFilename & \".\" & archiveType", "tot": "jsonata" }, { "t": "set", "p": "localFilename", "pt": "msg", "to": "localPath & localFilename & \".\" & archiveType", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 690, "y": 820, "wires": [ [ "fee8ef4e.31997" ] ] }, { "id": "4d3bf90.b649d08", "type": "change", "z": "551f568e.e62c18", "name": "Подготовка тела письма", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "payload.message", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 430, "y": 1000, "wires": [ [ "43bd8ec0.e5f6a" ] ] }, { "id": "90f9cd4e.41892", "type": "subflow:38c9a069.18cd6", "z": "551f568e.e62c18", "name": "Отправка почты", "env": [], "x": 490, "y": 1120, "wires": [] }, { "id": "8b4fb23f.3fc5e", "type": "status", "z": "551f568e.e62c18", "name": "Отлов ошибок FTP", "scope": [ "fee8ef4e.31997", "a6b4d607.6539d8", "6bf6acce.13b1b4" ], "x": 150, "y": 1060, "wires": [ [ "fb766dc1.84c82" ] ] }, { "id": "fb766dc1.84c82", "type": "switch", "z": "551f568e.e62c18", "name": "Отлов ошибок", "property": "status.fill", "propertyType": "msg", "rules": [ { "t": "eq", "v": "red", "vt": "str" } ], "checkall": "false", "repair": false, "outputs": 1, "x": 140, "y": 1120, "wires": [ [ "2d4148bb.c41d78" ] ] }, { "id": "2d4148bb.c41d78", "type": "change", "z": "551f568e.e62c18", "name": "Подготовка тела письма", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "\"Модуль \\\"\" & status.source.name & \"\\\" выдал ошибку \\\"\" & status.text & \"\\\".\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 170, "y": 1180, "wires": [ [ "43bd8ec0.e5f6a" ] ] }, { "id": "ee80db2.af9fa28", "type": "catch", "z": "551f568e.e62c18", "name": "Отлов ошибок SQLite", "scope": [ "a59c7f34.c8a12" ], "uncaught": false, "x": 160, "y": 940, "wires": [ [ "d2f3bf3f.79422" ] ] }, { "id": "43bd8ec0.e5f6a", "type": "change", "z": "551f568e.e62c18", "name": "Установка темы письма", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "\"Ошибка резервного копирования телеметрии (\" & $now('[H01]:[m01]:[s01] [D01].[M01].[Y0001]', '+1000') & \")!\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 430, "y": 1060, "wires": [ [ "90f9cd4e.41892" ] ] }, { "id": "d2f3bf3f.79422", "type": "change", "z": "551f568e.e62c18", "name": "Подготовка тела письма", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "\"Модуль \\\"\" & error.source.name & \"\\\" выдал ошибку:\\n\\n\\\"\" & error.message & \"\\\"\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 170, "y": 1000, "wires": [ [ "43bd8ec0.e5f6a" ] ] }, { "id": "7c896fde.621af", "type": "link in", "z": "551f568e.e62c18", "name": "Примем почты", "links": [ "f1dd250e.d302b8", "63bb51cd.8a1fc" ], "x": 335, "y": 1120, "wires": [ [ "90f9cd4e.41892" ] ] }, { "id": "a6b4d607.6539d8", "type": "advanced-ftp", "z": "551f568e.e62c18", "ftp": "480cc2b7.0bafdc", "operation": "list", "dataType": "binary", "filename": "", "localFilename": "", "workingDir": "", "oldPath": "", "newPath": "", "command": "", "recursive": false, "useCompression": false, "throwError": false, "showError": true, "name": "Запрос списка файлов", "x": 690, "y": 1000, "wires": [ [ "6f589a7f.74a9c4" ] ] }, { "id": "6f589a7f.74a9c4", "type": "split", "z": "551f568e.e62c18", "name": "Разделение массива", "splt": "\\n", "spltType": "str", "arraySplt": 1, "arraySpltType": "len", "stream": false, "addname": "", "x": 700, "y": 1060, "wires": [ [ "99fd96c4.893608" ] ] }, { "id": "94b4e8bb.1ccb68", "type": "change", "z": "551f568e.e62c18", "name": "Установка срока давности", "rules": [ { "t": "set", "p": "delayDays", "pt": "msg", "to": "7", "tot": "num" }, { "t": "delete", "p": "localFilename", "pt": "msg" }, { "t": "delete", "p": "localPath", "pt": "msg" }, { "t": "delete", "p": "filename", "pt": "msg" }, { "t": "delete", "p": "operation", "pt": "msg" }, { "t": "delete", "p": "dataType", "pt": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 680, "y": 940, "wires": [ [ "a6b4d607.6539d8" ] ] }, { "id": "99fd96c4.893608", "type": "switch", "z": "551f568e.e62c18", "name": "Выбор файлов", "property": "payload", "propertyType": "msg", "rules": [ { "t": "jsonata_exp", "v": "payload.name = \".htaccess\"", "vt": "jsonata" }, { "t": "jsonata_exp", "v": "$toMillis( $replace( $string( payload.date ), \"\\\"\", \"\" ) ) < $millis() - 86400000 * delayDays", "vt": "jsonata" } ], "checkall": "false", "repair": false, "outputs": 2, "x": 720, "y": 1120, "wires": [ [], [ "84f29eee.6ec95" ] ], "outputLabels": [ ".htaccess", "Старые" ] }, { "id": "6bf6acce.13b1b4", "type": "advanced-ftp", "z": "551f568e.e62c18", "ftp": "480cc2b7.0bafdc", "operation": "delete", "dataType": "binary", "filename": "", "localFilename": "", "workingDir": "", "oldPath": "", "newPath": "", "command": "", "recursive": false, "useCompression": false, "throwError": false, "showError": true, "name": "Удаление старых файлов", "x": 680, "y": 1180, "wires": [ [] ] }, { "id": "84f29eee.6ec95", "type": "change", "z": "551f568e.e62c18", "name": "Подготовка", "rules": [ { "t": "set", "p": "filename", "pt": "msg", "to": "payload.name", "tot": "msg" }, { "t": "delete", "p": "operation", "pt": "msg" }, { "t": "delete", "p": "dataType", "pt": "msg" }, { "t": "delete", "p": "payload", "pt": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 430, "y": 1180, "wires": [ [ "6bf6acce.13b1b4" ] ] }, { "id": "dbb6e10a.23844", "type": "sqlitedb", "db": "c:\\noderedDB\\telemetry.db", "mode": "RWC" }, { "id": "480cc2b7.0bafdc", "type": "advanced-ftp-config", "host": "ftp.server.ru", "port": "", "secure": false, "secureOptions": "", "user": "nodered", "connTimeout": "", "pasvTimeout": "", "keepalive": "", "name": "telemetry-backup" } ]
Обсуждение