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

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


iot:software:node-red:flows:telemetry_saving:narodmon:mqtt

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
iot:software:node-red:flows:telemetry_saving:narodmon:mqtt [2021/05/01 12:06]
Николай Солошин
iot:software:node-red:flows:telemetry_saving:narodmon:mqtt [2022/03/02 23:23] (текущий)
Николай Солошин
Строка 6: Строка 6:
 Это нативный для Node-RED вариант передачи данных в проект "[[https://narodmon.ru/?invite=nikolays|Народный мониторинг]]", т.к. для его реализации не требуются дополнительные узлы. Однако, с виду он немного более туманный, ибо в [[https://narodmon.ru/?invite=nikolays#devdoc|официальной инструкции]] написано что-то не до конца понятное... Но это только так кажется... если разобраться, что к чему. :-\ Это нативный для Node-RED вариант передачи данных в проект "[[https://narodmon.ru/?invite=nikolays|Народный мониторинг]]", т.к. для его реализации не требуются дополнительные узлы. Однако, с виду он немного более туманный, ибо в [[https://narodmon.ru/?invite=nikolays#devdoc|официальной инструкции]] написано что-то не до конца понятное... Но это только так кажется... если разобраться, что к чему. :-\
  
-:!: Пример использования специального узла и более подробное описание цепочки узлов [[iot:node-red:flows:telemetry_saving:narodmon|тут]]. В этой же статье рассмотрены только изменения относительно первого варианта.+:!: Пример использования специального узла «node-red-narodmon» [[iot:software:node-red:flows:telemetry_saving:narodmon|опубликован тут]].
  
-===== Описание изменений в цепочке =====+===== Нестандартные узлы =====
  
-Относительно вышеуказанного варианта, изменились узлы "Подготовка данных" и "Отправка данных".+В этой цепочке используются следующие узлы, которых нет в стандартной поставке:
  
-{{:iot:node-red:flows:telemetry_saving:narodmon:narodmon-mqtt.png?nolink|}}+  * [[https://flows.nodered.org/node/node-red-node-sqlite|node-red-node-sqlite]] 0.6.0.
  
-==== Подготовка данных ====+===== История версий =====
  
-Теперь в поле "Шаблон" сообщение отформатировано в виде JSON-строки, тогда как раньше был простой текст, а параметр "Вывести как", соответственно, изменен на ''JSON''.+//Это вторая версия цепочки, полностью переосмысленная и переработанная. Первая доступна [[iot:software:node-red:flows:telemetry_saving:narodmon:mqtt?rev=1645010443|в архиве]].//
  
-==== Отправка данных ====+{{:iot:software:node-red:flows:telemetry_saving:narodmon:narodmon-mqtt-v2.0.0.png?nolink|}}
  
-Теперь, вместо "node-red-narodmon", используется родной узел "mqtt out" со следующими настройками:+В отличие от первой версии: 
 + 
 +  * цепочка не зависит от узлов "mqtt in" и для периодического запуска использует узел "inject"; 
 +  * для выборки данных использует уже имеющиеся записи в базе данных SQLite, добавленные потоком "[[iot:software:node-red:flows:telemetry_saving|Сохранение телеметрии]]"; 
 +  * может собирать произвольные данные из разных таблиц одной базы данных в одно сообщение. 
 + 
 +===== Описание работы цепочки ===== 
 + 
 +Цепочка запускается по таймеру раз в 5 минут((Требование "Народного мониторинга" для бесплатных пользователей.)), считывает конфигурацию, о которой ниже, и делает нужное количество запросов к базе данных. Далее, если есть новые данные, они компонуются и отправляются в "Народный мониторинг", если нет, то, как говорится, и суда нет -- ничего не происходит. 
 + 
 +Состав отправляемой JSON-строки зависит от наличия новых данных, которые автоматически определяются по колонке "_id" соответствующей таблицы, и может быть полным или частичным. 
 + 
 +==== Конфигурация ==== 
 + 
 +Настройка работы цепочки производится в узле "Ввод параметров", который имеет следующую структуру: 
 + 
 +<code javascript>[ 
 +    { 
 +        "table": "device_1", 
 +        "columns": "temperature_c AS temperature, humidity" 
 +    }, 
 +    { 
 +        "table": "device_2", 
 +        "columns": "pressure" 
 +    } 
 +]</code> 
 + 
 +Необходимые для отправки колонки указываются через запятую. При желании можно переименовать колонки в выводе, использовав конструкцию "AS alias", как в примере выше. 
 + 
 +==== Настройка MQTT ==== 
 + 
 +Для отправки данных используется родной узел "mqtt out" со следующими настройками:
  
 ^  Путь до параметра                               ^^^  Значение     ^ ^  Путь до параметра                               ^^^  Значение     ^
Строка 31: Строка 62:
 Никаких других //обязательных// данных указывать или менять не нужно! Не знаю, почему такое расхождение с инструкцией на сайте проекта... Никаких других //обязательных// данных указывать или менять не нужно! Не знаю, почему такое расхождение с инструкцией на сайте проекта...
  
-===== Изменение в настройках устройства =====+===== Изменение устройства =====
  
 Если до этого использовали какой-либо другой вариант передачи данных на сервер, то после внесения изменений в поток, необходимо на сайте в свойствах устройства изменить протокол на MQTT, иначе данные будут игнорироваться! Если до этого использовали какой-либо другой вариант передачи данных на сервер, то после внесения изменений в поток, необходимо на сайте в свойствах устройства изменить протокол на MQTT, иначе данные будут игнорироваться!
Строка 37: Строка 68:
 ===== Код для загрузки ===== ===== Код для загрузки =====
  
-<file javascript narodmon-mqtt.json>[+<file javascript narodmon-mqtt-2.0.0.json>[
     {     {
-        "id": "f279413e.d2c8e", +        "id": "87cf2c5.9c165d", 
-        "type": "delay",+        "type": "comment",
         "z": "551f568e.e62c18",         "z": "551f568e.e62c18",
-        "name": "Ограничение 5 минут", +        "name": "Отправка данных на narodmon", 
-        "pauseType": "rate", +        "info": "", 
-        "timeout": "5", +        "x": 190,
-        "timeoutUnits": "seconds", +
-        "rate": "1", +
-        "nbRateUnits": "5", +
-        "rateUnits": "minute", +
-        "randomFirst": "1", +
-        "randomLast": "5", +
-        "randomUnits": "seconds", +
-        "drop": true, +
-        "x": 160,+
         "y": 580,         "y": 580,
 +        "wires": []
 +    },
 +    {
 +        "id": "8332b0ad.531ea",
 +        "type": "mqtt out",
 +        "z": "551f568e.e62c18",
 +        "name": "Передача данных",
 +        "topic": "nikolays/VND 22/json",
 +        "qos": "",
 +        "retain": "",
 +        "broker": "72c3b2f6.2ae94c",
 +        "x": 710,
 +        "y": 760,
 +        "wires": []
 +    },
 +    {
 +        "id": "d88ac30a.42feb",
 +        "type": "inject",
 +        "z": "551f568e.e62c18",
 +        "name": "Периодический запуск",
 +        "props": [],
 +        "repeat": "305",
 +        "crontab": "",
 +        "once": true,
 +        "onceDelay": "1",
 +        "topic": "",
 +        "x": 170,
 +        "y": 640,
         "wires": [         "wires": [
             [             [
-                "ef5cb94a.abad08", +                "5d6eea0c.4d6d24"
-                "15515561.bf4ccb"+
             ]             ]
         ]         ]
     },     },
     {     {
-        "id": "ef5cb94a.abad08", +        "id": "dd2a836b.d64a4", 
-        "type": "template",+        "type": "sqlite",
         "z": "551f568e.e62c18",         "z": "551f568e.e62c18",
-        "name": "Подготовка данных", +        "mydb": "dbb6e10a.23844", 
-        "field": "payload", +        "sqlquery": "msg.topic", 
-        "fieldType": "msg", +        "sql": "", 
-        "format": "handlebars", +        "name": "Запрос к базе данных",
-        "syntax": "mustache", +
-        "template": "{ \"T1\": {{{payload.temperature}}}, \"H1\": {{{payload.humidity}}} }", +
-        "output": "json",+
         "x": 440,         "x": 440,
-        "y": 580,+        "y": 700,
         "wires": [         "wires": [
             [             [
-                "8332b0ad.531ea"+                "7f4584c6.2f61cc"
             ]             ]
         ]         ]
     },     },
     {     {
-        "id": "d8544fd0.c205f", +        "id": "c6b04d86.596db", 
-        "type": "link in",+        "type": "change",
         "z": "551f568e.e62c18",         "z": "551f568e.e62c18",
-        "name": "С MQTT", +        "name": "Подготовка запроса", 
-        "links": [ +        "rules": [ 
-            "c8c40256.0249b"+            { 
 +                "t": "set", 
 +                "p": "topic", 
 +                "pt": "msg", 
 +                "to": "\"SELECT _id, \" & datasets[0].columns & \" FROM \" & datasets[0].table & \" ORDER BY _id DESC LIMIT 1\"", 
 +                "tot": "jsonata" 
 +            }
         ],         ],
-        "x": 75, +        "action": "", 
-        "y": 640,+        "property": "", 
 +        "from": "", 
 +        "to": "", 
 +        "reg": false, 
 +        "x": 160, 
 +        "y": 700,
         "wires": [         "wires": [
             [             [
-                "f279413e.d2c8e"+                "dd2a836b.d64a4"
             ]             ]
         ]         ]
     },     },
     {     {
-        "id": "15515561.bf4ccb", +        "id": "5d6eea0c.4d6d24", 
-        "type": "trigger",+        "type": "change",
         "z": "551f568e.e62c18",         "z": "551f568e.e62c18",
-        "name": "Вброс последнего сообщения", +        "name": "Ввод параметров", 
-        "op1": "", +        "rules": [ 
-        "op2": "", +            { 
-        "op1type": "nul", +                "t": "set", 
-        "op2type": "payl", +                "p": "datasets", 
-        "duration": "28", +                "pt": "msg", 
-        "extend": true, +                "to": "[{\"table\":\"snzb-02\",\"columns\":\"temperature AS Te, humidity AS Hy\"},{\"table\":\"bme680\",\"columns\":\"pressureSt AS Pst, pressureSl AS Psl, pressureBt AS Pbl\"}]", 
-        "overrideDelay": false, +                "tot": "json" 
-        "units": "min", +            } 
-        "reset": "", +        ], 
-        "bytopic": "all", +        "action": "", 
-        "topic": "topic", +        "property": "", 
-        "outputs": 1, +        "from": "", 
-        "x": 290,+        "to": "", 
 +        "reg": false, 
 +        "x": 430,
         "y": 640,         "y": 640,
         "wires": [         "wires": [
             [             [
-                "ef5cb94a.abad08", +                "c6b04d86.596db"
-                "c54dc60b.a15a28"+
             ]             ]
-        ], +        ]
-        "info": "Народный мониторинг требует передачи данных не реже раза в 30 мин, иначе выставляет санкции!.. а Sonoff SNZB-02, почему-то, периодически не передает данные дольше... Тут, либо у меня косяк какой-то, либо реально данные не меняются и он молчит.\n\nПоэтому был добавлен этот триггер - если данные не отправляются больше установленной задержки (меньше 30 мин), он вбрасывает последнее поступившее сообщение.\n\nПока данные периодические передаются, он постоянно продлевает таймер."+
     },     },
     {     {
-        "id": "c54dc60b.a15a28",+        "id": "7f4584c6.2f61cc",
         "type": "change",         "type": "change",
         "z": "551f568e.e62c18",         "z": "551f568e.e62c18",
-        "name": "Подготовка письма",+        "name": "Обработка данных",
         "rules": [         "rules": [
 +            {
 +                "t": "move",
 +                "p": "payload[0]._id",
 +                "pt": "msg",
 +                "to": "current_id",
 +                "tot": "msg"
 +            },
             {             {
                 "t": "set",                 "t": "set",
-                "p": "topic",+                "p": "telemetry",
                 "pt": "msg",                 "pt": "msg",
-                "to": "\"Данные телеметрии были вброшены в \" & $now('[H01]:[m01]:[s01] [D01].[M01].[Y0001]', '+1000') & \"!\"",+                "to": "current_id > ( $type( $lookup( $flowContext( \"last_id\" ), datasets[0].table ) ) = \"number\" ? $lookup( $flowContext( \"last_id\" ), datasets[0].table ) : current_id ) = true ? $merge( $append( telemetry, payload ) ) : $merge( telemetry )",
                 "tot": "jsonata"                 "tot": "jsonata"
             },             },
             {             {
                 "t": "set",                 "t": "set",
-                "p": "payload", +                "p": "last_id", 
-                "pt": "msg", +                "pt": "flow", 
-                "to": "\"Для соответствия правилам портала \\\"Народный мониторинг\\\", были вброшены следующие данные из последнего сообщения:\\n\\n1) температура: \" & payload.temperature & \";\\n2) влажность: \" & payload.humidity & \".\"",+                "to": "$merge( [ $flowContext( \"last_id\" ), { $.datasets[0].table: current_id } ] )",
                 "tot": "jsonata"                 "tot": "jsonata"
 +            },
 +            {
 +                "t": "delete",
 +                "p": "datasets[0]",
 +                "pt": "msg"
             }             }
         ],         ],
Строка 150: Строка 219:
         "to": "",         "to": "",
         "reg": false,         "reg": false,
-        "x": 600, +        "x": 710, 
-        "y": 640,+        "y": 700,
         "wires": [         "wires": [
             [             [
-                "63bb51cd.8a1fc"+                "b887ba10.f4dd28"
             ]             ]
         ]         ]
     },     },
     {     {
-        "id": "63bb51cd.8a1fc", +        "id": "b887ba10.f4dd28", 
-        "type": "link out",+        "type": "switch",
         "z": "551f568e.e62c18",         "z": "551f568e.e62c18",
-        "name": "Отправка почты", +        "name": "Маршрутизация", 
-        "links": [ +        "property": "payload", 
-            "7c896fde.621af"+        "propertyType": "msg", 
 +        "rules": [ 
 +            { 
 +                "t": "jsonata_exp", 
 +                "v": "$exists( datasets[0] )", 
 +                "vt": "jsonata" 
 +            }, 
 +            { 
 +                "t": "jsonata_exp", 
 +                "v": "$exists( telemetry )", 
 +                "vt": "jsonata" 
 +            }
         ],         ],
-        "x": 775, +        "checkall": "false", 
-        "y": 640, +        "repair": false, 
-        "wires": []+        "outputs": 2, 
 +        "x": 150, 
 +        "y": 760, 
 +        "wires": [ 
 +            [ 
 +                "c6b04d86.596db" 
 +            ], 
 +            [ 
 +                "7812260c.cbdb68" 
 +            ] 
 +        ], 
 +        "outputLabels": [ 
 +            "Нужен еще цикл", 
 +            "Есть данные для публикации" 
 +        ], 
 +        "info": "Если массив \"datasets\" не пустой, значит не все таблицы были обработаны, уходим на следующий круг.\n\nЕсли сообщение \"telemetry\" отсутствует, значит нет данных для публикации, завершаем."
     },     },
     {     {
-        "id": "8332b0ad.531ea", +        "id": "7812260c.cbdb68", 
-        "type": "mqtt out",+        "type": "change",
         "z": "551f568e.e62c18",         "z": "551f568e.e62c18",
-        "name": "Передача данных", +        "name": "Перемещение нагрузки", 
-        "topic": "user/device/json", +        "rules": [ 
-        "qos": "", +            { 
-        "retain": "", +                "t": "move", 
-        "broker": "72c3b2f6.2ae94c", +                "p": "telemetry", 
-        "x": 710, +                "pt": "msg", 
-        "y": 580, +                "to": "payload", 
-        "wires": []+                "tot": "msg" 
 +            }, 
 +            { 
 +                "t": "delete", 
 +                "p": "datasets", 
 +                "pt": "msg" 
 +            }, 
 +            { 
 +                "t": "delete", 
 +                "p": "current_id", 
 +                "pt": "msg" 
 +            }, 
 +            { 
 +                "t": "set", 
 +                "p": "topic", 
 +                "pt": "msg", 
 +                "to": "Bye-Bye!", 
 +                "tot": "str" 
 +            } 
 +        ], 
 +        "action": "", 
 +        "property": "", 
 +        "from": "", 
 +        "to": "", 
 +        "reg": false, 
 +        "x": 430, 
 +        "y": 760, 
 +        "wires": [ 
 +            [ 
 +                "8332b0ad.531ea" 
 +            ] 
 +        ]
     },     },
     {     {
Строка 189: Строка 315:
         "broker": "narodmon.ru",         "broker": "narodmon.ru",
         "port": "1883",         "port": "1883",
-        "clientid": "XX:XX:XX:XX:XX:XX",+        "clientid": "E0:3F:49:13:58:61",
         "usetls": false,         "usetls": false,
         "compatmode": false,         "compatmode": false,
Строка 203: Строка 329:
         "willQos": "0",         "willQos": "0",
         "willPayload": ""         "willPayload": ""
 +    },
 +    {
 +        "id": "dbb6e10a.23844",
 +        "type": "sqlitedb",
 +        "db": "c:\\noderedDB\\telemetry.db",
 +        "mode": "RWC"
     }     }
 ]</file> ]</file>
Последнее изменение: 2022/02/12 11:40 (внешнее изменение)