Изначально я планировал реализовать только сохранение телеметрии с модуля Peacefair PZEM-004T-100A и двух датчиков температуры Maxim Integrated/Dallas Semiconductor DS18B20, подключенных к TOMZN TOB15-63 WIFI, в базу SQLite, но… пошло-поехало и получился этот многофункциональный поток, который:
В этой цепочке используются следующие узлы, которых нет в стандартной поставке:
Этот подпоток входит в состав кода ниже и загружать отдельно его не надо!
Поток логически разбит на четыре зависящих друг от друга цепочки:
[ { "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": "2024bfa3.ee2a4", "type": "tab", "label": "Мониторинг электроснабжения", "disabled": false, "info": "" }, { "id": "9f58fb72.63bd18", "type": "mqtt in", "z": "2024bfa3.ee2a4", "name": "Энерготелеметрия", "topic": "circuitbreaker_0B6A01/tele/SENSOR", "qos": "2", "datatype": "json", "broker": "8745b931.133868", "x": 150, "y": 280, "wires": [ [ "5ff6c1dd.8ae" ] ] }, { "id": "e3b00957.24e2e8", "type": "sqlite", "z": "2024bfa3.ee2a4", "mydb": "ba734886.beb808", "sqlquery": "msg.topic", "sql": "", "name": "Запись в базу данных", "x": 700, "y": 280, "wires": [ [] ] }, { "id": "1a1cb94e.a99977", "type": "change", "z": "2024bfa3.ee2a4", "name": "Подготовка запроса", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "\"INSERT INTO \\\"telemetry\\\" (Warning, Timestamp, Voltage, VoltageThresholdHigh, VoltageThresholdLow, VoltageThresholdNormalMin, VoltageThresholdNormalMax, Current, Power, Frequency, PowerApparent, PowerReactive, Factor, EnergyTotalStartTime, EnergyTotal, EnergyYesterday, EnergyToday, TemperatureRelay, TemperatureBreaker, TemperatureThresholdHigh, TemperatureThresholdNormal) VALUES (\" & (payload.Warning = true ? true : false) & \", \\\"\" & $now('[Y0001].[M01].[D01] [H01]:[m01]:[s01]', '+1000') & \"\\\", \" & payload.ENERGY.Voltage & \", \" & $flowContext(\"settings.thresholds.voltageHigh\") & \", \" & $flowContext(\"settings.thresholds.voltageLow\") & \", \" & $flowContext(\"settings.thresholds.voltageNormalMin\") & \", \" & $flowContext(\"settings.thresholds.voltageNormalMax\") & \", \" & payload.ENERGY.Current & \", \" & payload.ENERGY.Power & \", \" & payload.ENERGY.Frequency & \", \" & payload.ENERGY.ApparentPower & \", \" & payload.ENERGY.ReactivePower & \", \" & payload.ENERGY.Factor & \", \\\"\" & ($replace(payload.ENERGY.TotalStartTime, '-', '.') ~> $replace('T', ' ')) & \"\\\", \" & payload.ENERGY.Total & \", \" & payload.ENERGY.Yesterday & \", \" & payload.ENERGY.Today & \", \" & ( $type(payload.'DS18B20-1'.Temperature) = \"number\" ? payload.'DS18B20-1'.Temperature : null ) & \", \" & ( $type(payload.'DS18B20-2'.Temperature) = \"number\" ? payload.'DS18B20-2'.Temperature : null ) & \", \" & $flowContext(\"settings.thresholds.temperatureHigh\") & \", \" & $flowContext(\"settings.thresholds.temperatureNormal\") & \")\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 440, "y": 280, "wires": [ [ "e3b00957.24e2e8" ] ] }, { "id": "7d006e78.b822d", "type": "mqtt in", "z": "2024bfa3.ee2a4", "name": "Пересечение порогов", "topic": "circuitbreaker_0B6A01/stat/STATUS10", "qos": "2", "datatype": "json", "broker": "8745b931.133868", "x": 160, "y": 340, "wires": [ [ "25cf29b.c40dcd6" ] ] }, { "id": "25cf29b.c40dcd6", "type": "change", "z": "2024bfa3.ee2a4", "name": "Подготовка нагрузки", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "payload.StatusSNS", "tot": "msg" }, { "t": "set", "p": "payload.Warning", "pt": "msg", "to": "true", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 160, "y": 400, "wires": [ [ "5ff6c1dd.8ae" ] ] }, { "id": "8b7e27a0.b891a8", "type": "subflow:38c9a069.18cd6", "z": "2024bfa3.ee2a4", "name": "Отправка писем", "env": [], "x": 590, "y": 640, "wires": [] }, { "id": "48c2326d.305c5c", "type": "change", "z": "2024bfa3.ee2a4", "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": "\"Время: \" & $now('[Y0001].[M01].[D01] [H01]:[m01]:[s01]', '+1000') & \".\\nНапряжение: \" & payload.ENERGY.Voltage & \" В (\" & payload.ENERGY.Frequency & \" Гц).\\nПороги низкого/высокого напряжения: \" & $flowContext(\"settings.thresholds.voltageLow\") & \"/\" & $flowContext(\"settings.thresholds.voltageHigh\") & \" В.\\n\\nНагрузка: \" & payload.ENERGY.Power & \" Вт (\" & payload.ENERGY.Current & \" А).\"", "tot": "jsonata" }, { "t": "set", "p": "marks.warningSent", "pt": "flow", "to": "true", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 660, "y": 700, "wires": [ [ "8b7e27a0.b891a8" ] ] }, { "id": "93f701f7.421b2", "type": "mqtt out", "z": "2024bfa3.ee2a4", "name": "Отправка сообщения", "topic": "", "qos": "", "retain": "", "broker": "8745b931.133868", "x": 440, "y": 1300, "wires": [] }, { "id": "30e47596.618a3a", "type": "mqtt in", "z": "2024bfa3.ee2a4", "name": "Получение результата", "topic": "circuitbreaker_0B6A01/stat/RESULT", "qos": "2", "datatype": "json", "broker": "8745b931.133868", "x": 160, "y": 1180, "wires": [ [ "e32f6f55.306" ] ] }, { "id": "ecb3fe37.3f07f", "type": "inject", "z": "2024bfa3.ee2a4", "name": "Инициализация потока", "props": [], "repeat": "", "crontab": "", "once": true, "onceDelay": 0.1, "topic": "", "payloadType": "str", "x": 170, "y": 100, "wires": [ [ "fd528111.05d7f" ] ] }, { "id": "fd528111.05d7f", "type": "change", "z": "2024bfa3.ee2a4", "name": "Ввод настроек", "rules": [ { "t": "set", "p": "settings.deviceName", "pt": "flow", "to": "circuitbreaker_0B6A01", "tot": "str" }, { "t": "set", "p": "settings.sensorsNames.DS18B20-1", "pt": "flow", "to": "Реле", "tot": "str" }, { "t": "set", "p": "settings.sensorsNames.DS18B20-2", "pt": "flow", "to": "Выключатель", "tot": "str" }, { "t": "set", "p": "settings.thresholds.voltageHigh", "pt": "flow", "to": "242", "tot": "num" }, { "t": "set", "p": "settings.thresholds.voltageNormalMax", "pt": "flow", "to": "235", "tot": "num" }, { "t": "set", "p": "settings.thresholds.voltageNormalMin", "pt": "flow", "to": "215", "tot": "num" }, { "t": "set", "p": "settings.thresholds.voltageLow", "pt": "flow", "to": "209", "tot": "num" }, { "t": "set", "p": "settings.teleperiod.normal", "pt": "flow", "to": "30", "tot": "num" }, { "t": "set", "p": "settings.teleperiod.warning", "pt": "flow", "to": "10", "tot": "num" }, { "t": "set", "p": "settings.thresholds.temperatureHigh", "pt": "flow", "to": "35", "tot": "num" }, { "t": "set", "p": "settings.thresholds.temperatureNormal", "pt": "flow", "to": "32", "tot": "num" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 140, "y": 160, "wires": [ [ "e2bbdbf7.e8da38" ] ], "info": "Описание настроек:\n\n * **settings.deviceName** - имя устройства в MQTT;\n * **settings.sensorsNames.\\*** - благозвучные названия датчиков для писем;\n * **settings.thresholds.voltage\\*** - верхний и нижний (опасный) порог напряжения;\n * **settings.thresholds.voltageNormal\\*** - верхний и нижний порог нормального напряжения;\n * **settings.teleperiod.normal** - штатная частота отправки телеметрии с модуля;\n * **settings.teleperiod.warning** - частота отправки телеметрии во время действия опасных порогов;\n * **settings.thresholds.temperature\\*** - пороги высокой и нормальной температуры." }, { "id": "e32f6f55.306", "type": "switch", "z": "2024bfa3.ee2a4", "name": "Фильтрация сообщений", "property": "payload", "propertyType": "msg", "rules": [ { "t": "hask", "v": "Rule1", "vt": "str" }, { "t": "hask", "v": "TelePeriod", "vt": "str" } ], "checkall": "false", "repair": false, "outputs": 2, "x": 390, "y": 1180, "wires": [ [ "d3cdbc36.1eb46" ], [ "7dbf780c.ac7e98" ] ], "outputLabels": [ "Получено правило 1", null ] }, { "id": "d3e4abfe.5df318", "type": "switch", "z": "2024bfa3.ee2a4", "name": "Проверка наличия изменений", "property": "payload", "propertyType": "msg", "rules": [ { "t": "jsonata_exp", "v": "payload.threshold.high != $flowContext(\"settings.thresholds.voltageHigh\") or payload.threshold.low != $flowContext(\"settings.thresholds.voltageLow\")", "vt": "jsonata" } ], "checkall": "false", "repair": false, "outputs": 1, "x": 670, "y": 1240, "wires": [ [ "e8eb8da5.5aebf" ] ], "outputLabels": [ "Есть изменений" ] }, { "id": "d3cdbc36.1eb46", "type": "change", "z": "2024bfa3.ee2a4", "name": "Получение порогов из правила", "rules": [ { "t": "set", "p": "payload.threshold.high", "pt": "msg", "to": "$substringAfter(payload.Rule1.Rules, \"Voltage>=\") ~> $substring(0, 3) ~> $number()", "tot": "jsonata" }, { "t": "set", "p": "payload.threshold.low", "pt": "msg", "to": "$substringAfter(payload.Rule1.Rules, \"Voltage<=\") ~> $substring(0, 3) ~> $number()", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 670, "y": 1180, "wires": [ [ "d3e4abfe.5df318" ] ] }, { "id": "e8eb8da5.5aebf", "type": "change", "z": "2024bfa3.ee2a4", "name": "Подготовка сообщения", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "$flowContext(\"settings.deviceName\") & \"/cmnd/Rule1\"", "tot": "jsonata" }, { "t": "set", "p": "payload", "pt": "msg", "to": "payload.Rule1.Rules ~> $replace($string(payload.threshold.high), $string( $flowContext(\"settings.thresholds.voltageHigh\") )) ~> $replace($string(payload.threshold.low), $string( $flowContext(\"settings.thresholds.voltageLow\") ))", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 690, "y": 1300, "wires": [ [ "93f701f7.421b2" ] ] }, { "id": "5ff6c1dd.8ae", "type": "switch", "z": "2024bfa3.ee2a4", "name": "Маршрутизация данных", "property": "payload.ENERGY.Power", "propertyType": "msg", "rules": [ { "t": "istype", "v": "number", "vt": "number" }, { "t": "jsonata_exp", "v": "payload.Warning = true and payload.ENERGY.Voltage > 0", "vt": "jsonata" }, { "t": "jsonata_exp", "v": "payload.ENERGY.Frequency = 0 and payload.ENERGY.Voltage = 0", "vt": "jsonata" }, { "t": "jsonata_exp", "v": "payload.ENERGY.Voltage > 0 and payload.ENERGY.ApparentPower = 0 and ( $flowContext(\"marks.relayStatus\") = \"ON\" or $exists($flowContext(\"marks.relayStatus\")) = false )", "vt": "jsonata" }, { "t": "jsonata_exp", "v": "$exists(payload.'DS18B20-1') = false or $exists(payload.'DS18B20-2') = false", "vt": "jsonata" } ], "checkall": "true", "repair": false, "outputs": 5, "x": 450, "y": 360, "wires": [ [ "1a1cb94e.a99977", "e8f85797.7464d8" ], [ "ffa8a4c3.42c328" ], [ "5b6b4800.8fadb8" ], [ "eb8db7d7.b60e28" ], [ "c3e4540.ec3abb" ] ], "outputLabels": [ "Корректные данные", "Пересечен порог напряжения", "Не подключен модуль", "Не подключен токосъемник", "Не подключены термодатчики" ], "info": "При загрузке устройства первые 2 сообщения - массивы, что вызывает ошибку записи в БД и ложную отправку письма с превышением порога." }, { "id": "f1580409.2cff88", "type": "comment", "z": "2024bfa3.ee2a4", "name": "Корректировка настроек на устройстве", "info": "Автоматически производится при запуске устройства.", "x": 220, "y": 1120, "wires": [] }, { "id": "d1ba081d.326e68", "type": "comment", "z": "2024bfa3.ee2a4", "name": "Сохранение телеметрии", "info": "", "x": 170, "y": 220, "wires": [] }, { "id": "48eb1a43.503494", "type": "change", "z": "2024bfa3.ee2a4", "name": "Именование порогов", "rules": [ { "t": "set", "p": "threshold", "pt": "msg", "to": "( payload.ENERGY.Voltage >= $flowContext(\"settings.thresholds.voltageHigh\") or payload.ENERGY.Voltage <= $flowContext(\"settings.thresholds.voltageLow\") ) ? \"abnormal\" : ( ( payload.ENERGY.Voltage >= $flowContext(\"settings.thresholds.voltageNormalMin\") and payload.ENERGY.Voltage <= $flowContext(\"settings.thresholds.voltageNormalMax\") ) ? \"normal\" : \"borderline\" )", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 220, "y": 1360, "wires": [ [ "104913d2.abbf1c" ] ] }, { "id": "104913d2.abbf1c", "type": "switch", "z": "2024bfa3.ee2a4", "name": "Фильтрация изменений", "property": "payload", "propertyType": "msg", "rules": [ { "t": "jsonata_exp", "v": "( threshold != $flowContext(\"marks.threshold\") or $exists( $flowContext(\"marks.threshold\") ) = false ) and threshold != \"borderline\"", "vt": "jsonata" }, { "t": "jsonata_exp", "v": "threshold = \"normal\" and $flowContext(\"marks.warningSent\") = true", "vt": "jsonata" } ], "checkall": "true", "repair": false, "outputs": 2, "x": 470, "y": 1360, "wires": [ [ "6f86e534.fa71cc" ], [ "efb5bd3c.3ea97" ] ], "outputLabels": [ "Есть изменения", "Отправляем письмо" ] }, { "id": "6f86e534.fa71cc", "type": "change", "z": "2024bfa3.ee2a4", "name": "Подготовка сообщения", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "$flowContext(\"settings.deviceName\") & \"/cmnd/TelePeriod\"", "tot": "jsonata" }, { "t": "set", "p": "payload", "pt": "msg", "to": "threshold = \"normal\" ? $number($flowContext(\"settings.teleperiod.normal\")) : ( threshold = \"abnormal\" ? $number($flowContext(\"settings.teleperiod.warning\")))", "tot": "jsonata" }, { "t": "set", "p": "marks.threshold", "pt": "flow", "to": "threshold", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 690, "y": 1420, "wires": [ [ "99c37f52.0d552" ] ] }, { "id": "e2bbdbf7.e8da38", "type": "change", "z": "2024bfa3.ee2a4", "name": "Запрос правила порогов", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "$flowContext(\"settings.deviceName\") & \"/cmnd/Rule1\"", "tot": "jsonata" }, { "t": "set", "p": "payload", "pt": "msg", "to": "", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 470, "y": 160, "wires": [ [ "7fd65357.9f39ec", "6ba68741.54ecd8" ] ] }, { "id": "f443f690.205de8", "type": "change", "z": "2024bfa3.ee2a4", "name": "Запрос телепериода", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "$flowContext(\"settings.deviceName\") & \"/cmnd/TelePeriod\"", "tot": "jsonata" }, { "t": "set", "p": "payload", "pt": "msg", "to": "", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 700, "y": 100, "wires": [ [ "6ba68741.54ecd8" ] ] }, { "id": "7fd65357.9f39ec", "type": "delay", "z": "2024bfa3.ee2a4", "name": "Задержка", "pauseType": "delay", "timeout": "2", "timeoutUnits": "seconds", "rate": "1", "nbRateUnits": "2", "rateUnits": "second", "randomFirst": "1", "randomLast": "5", "randomUnits": "seconds", "drop": true, "x": 440, "y": 100, "wires": [ [ "f443f690.205de8" ] ] }, { "id": "7dbf780c.ac7e98", "type": "switch", "z": "2024bfa3.ee2a4", "name": "Проверка изменения периода", "property": "payload", "propertyType": "msg", "rules": [ { "t": "jsonata_exp", "v": "$flowContext(\"marks.threshold\") = \"normal\" and payload.TelePeriod != $flowContext(\"settings.teleperiod.normal\")", "vt": "jsonata" } ], "checkall": "true", "repair": false, "outputs": 1, "x": 190, "y": 1240, "wires": [ [ "3054f284.e0cb8e" ] ] }, { "id": "3054f284.e0cb8e", "type": "change", "z": "2024bfa3.ee2a4", "name": "Подготовка сообщения", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "$flowContext(\"settings.deviceName\") & \"/cmnd/TelePeriod\"", "tot": "jsonata" }, { "t": "set", "p": "payload", "pt": "msg", "to": "settings.teleperiod.normal", "tot": "flow" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 170, "y": 1300, "wires": [ [ "93f701f7.421b2" ] ] }, { "id": "8dec4e10.be3b5", "type": "change", "z": "2024bfa3.ee2a4", "name": "Очистка нагрузки", "rules": [ { "t": "delete", "p": "payload.Time", "pt": "msg" }, { "t": "delete", "p": "payload.ENERGY", "pt": "msg" }, { "t": "delete", "p": "payload.TempUnit", "pt": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 330, "y": 520, "wires": [ [ "76e9ea68.d9bf04" ] ] }, { "id": "76e9ea68.d9bf04", "type": "split", "z": "2024bfa3.ee2a4", "name": "Разделение нагрузки", "splt": "\\n", "spltType": "str", "arraySplt": 1, "arraySpltType": "len", "stream": false, "addname": "sensorNumber", "x": 700, "y": 520, "wires": [ [ "b90d31a.b84ddd" ] ] }, { "id": "b90d31a.b84ddd", "type": "switch", "z": "2024bfa3.ee2a4", "name": "Фильтрация по порогу и статусу", "property": "payload", "propertyType": "msg", "rules": [ { "t": "jsonata_exp", "v": "payload.Temperature >= $flowContext(\"settings.thresholds.temperatureHigh\") and ( ( \"marks.temperature.\" & parts.key ~> $flowContext() ) != \"high\" or ( \"marks.temperature.\" & parts.key ~> $flowContext() ~> $exists() ) = false )", "vt": "jsonata" }, { "t": "jsonata_exp", "v": "payload.Temperature <= $flowContext(\"settings.thresholds.temperatureNormal\") and ( \"marks.temperature.\" & parts.key ~> $flowContext() ) = \"high\"", "vt": "jsonata" } ], "checkall": "false", "repair": false, "outputs": 2, "x": 200, "y": 580, "wires": [ [ "f0d3b6f7.0799d8" ], [ "87fc2a28.6aa838" ] ], "outputLabels": [ "Превышен порог", "Температура снизилась" ] }, { "id": "f0d3b6f7.0799d8", "type": "change", "z": "2024bfa3.ee2a4", "name": "Письмо о превышении температуры", "rules": [ { "t": "set", "p": "marks.temperature", "pt": "flow", "to": "$merge( [ $flowContext(\"marks.temperature\"), {$.sensorNumber:\"high\"} ] )", "tot": "jsonata" }, { "t": "set", "p": "topic", "pt": "msg", "to": "\"Превышен порог по температуре в \" & $now('[H01]:[m01]:[s01] [D01].[M01].[Y0001]', '+1000') & \"!\"", "tot": "jsonata" }, { "t": "set", "p": "payload", "pt": "msg", "to": "\"Время: \" & $now('[Y0001].[M01].[D01] [H01]:[m01]:[s01]', '+1000') & \".\\nНазвание датчика: \" & ( ( \"settings.sensorsNames.\" & sensorNumber ) ~> $flowContext() ) & \".\\nТемпература: \" & payload.Temperature & \"°C (порог: \" & $flowContext(\"settings.thresholds.temperatureHigh\") & \"°C).\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 650, "y": 580, "wires": [ [ "8b7e27a0.b891a8" ] ] }, { "id": "87fc2a28.6aa838", "type": "change", "z": "2024bfa3.ee2a4", "name": "Письмо о снижении температуры", "rules": [ { "t": "set", "p": "marks.temperature", "pt": "flow", "to": "$merge( [ $flowContext(\"marks.temperature\"), {$.sensorNumber:\"normal\"} ] )", "tot": "jsonata" }, { "t": "set", "p": "topic", "pt": "msg", "to": "\"Температура нормализовалась в \" & $now('[H01]:[m01]:[s01] [D01].[M01].[Y0001]', '+1000') & \"!\"", "tot": "jsonata" }, { "t": "set", "p": "payload", "pt": "msg", "to": "\"Время: \" & $now('[Y0001].[M01].[D01] [H01]:[m01]:[s01]', '+1000') & \".\\nНазвание датчика: \" & ( ( \"settings.sensorsNames.\" & sensorNumber ) ~> $flowContext() ) & \".\\nТемпература: \" & payload.Temperature & \"°C (порог: \" & $flowContext(\"settings.thresholds.temperatureNormal\") & \"°C).\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 200, "y": 640, "wires": [ [ "8b7e27a0.b891a8" ] ] }, { "id": "8f2f4d10.f4222", "type": "trigger", "z": "2024bfa3.ee2a4", "name": "Триггер энергомонитора", "op1": "false", "op2": "true", "op1type": "bool", "op2type": "bool", "duration": "1", "extend": true, "overrideDelay": true, "units": "min", "reset": "", "bytopic": "all", "topic": "topic", "outputs": 1, "x": 450, "y": 820, "wires": [ [ "f5094224.6bd3" ] ] }, { "id": "335988c2.9b8ed8", "type": "change", "z": "2024bfa3.ee2a4", "name": "Задержка триггера", "rules": [ { "t": "set", "p": "delay", "pt": "msg", "to": "($flowContext(\"settings.teleperiod.warning\") + 5) * 1000", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 210, "y": 820, "wires": [ [ "8f2f4d10.f4222" ] ] }, { "id": "f5094224.6bd3", "type": "change", "z": "2024bfa3.ee2a4", "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": "\"Вероятно, энергомонитор \" & ( payload = true ? \"ПЕРЕДАЕТ\" : \"НЕ ПЕРЕДАЕТ\" ) & \" данные с \" & $now('[H01]:[m01]:[s01] [D01].[M01].[Y0001]', '+1000') & \".\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 700, "y": 820, "wires": [ [ "341e2ed3.f408f2" ] ] }, { "id": "5f806e54.aa6cd", "type": "change", "z": "2024bfa3.ee2a4", "name": "Задержка триггера", "rules": [ { "t": "set", "p": "delay", "pt": "msg", "to": "($flowContext(\"settings.teleperiod.normal\") + 5) * 1000", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 210, "y": 940, "wires": [ [ "c7f29d7b.a6f08" ] ] }, { "id": "c7f29d7b.a6f08", "type": "trigger", "z": "2024bfa3.ee2a4", "name": "Триггер токосъемника", "op1": "false", "op2": "true", "op1type": "bool", "op2type": "bool", "duration": "1", "extend": true, "overrideDelay": true, "units": "min", "reset": "", "bytopic": "all", "topic": "topic", "outputs": 1, "x": 450, "y": 940, "wires": [ [ "bf08624f.36b27" ] ] }, { "id": "bf08624f.36b27", "type": "change", "z": "2024bfa3.ee2a4", "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": "\"Вероятно, токосъемник \" & ( payload = true ? \"ПЕРЕДАЕТ\" : \"НЕ ПЕРЕДАЕТ\" ) & \" данные с \" & $now('[H01]:[m01]:[s01] [D01].[M01].[Y0001]', '+1000') & \".\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 700, "y": 940, "wires": [ [ "341e2ed3.f408f2" ] ] }, { "id": "291326ae.6f6a1a", "type": "trigger", "z": "2024bfa3.ee2a4", "name": "Триггер термодатчика", "op1": "false", "op2": "true", "op1type": "bool", "op2type": "bool", "duration": "1", "extend": true, "overrideDelay": false, "units": "min", "reset": "", "bytopic": "all", "topic": "topic", "outputs": 1, "x": 220, "y": 880, "wires": [ [ "23e59bcc.6fa514" ] ] }, { "id": "ee9c1c35.019c2", "type": "change", "z": "2024bfa3.ee2a4", "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": "\"Время: \" & $now('[Y0001].[M01].[D01] [H01]:[m01]:[s01]', '+1000') & \".\\nНапряжение: \" & payload.ENERGY.Voltage & \" В (\" & payload.ENERGY.Frequency & \" Гц).\\nПороги нормального напряжения (мин/макс): \" & $flowContext(\"settings.thresholds.voltageNormalMin\") & \"/\" & $flowContext(\"settings.thresholds.voltageNormalMax\") & \" В.\\n\\nНагрузка: \" & payload.ENERGY.Power & \" Вт (\" & payload.ENERGY.Current & \" А).\"", "tot": "jsonata" }, { "t": "set", "p": "marks.warningSent", "pt": "flow", "to": "false", "tot": "bool" }, { "t": "set", "p": "reset", "pt": "msg", "to": "true", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 270, "y": 700, "wires": [ [ "8b7e27a0.b891a8", "b6d17636.a318a8" ] ] }, { "id": "500fc081.83a8b", "type": "catch", "z": "2024bfa3.ee2a4", "name": "Отлов ошибок", "scope": null, "uncaught": false, "x": 140, "y": 1000, "wires": [ [ "6b52c12f.1d08a" ] ] }, { "id": "fbb23ad0.4062d8", "type": "change", "z": "2024bfa3.ee2a4", "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": "\"Ошибка: \\\"\" & error.message & \"\\\".\\nУзел: \\\"\" & error.source.name & \"\\\" (\" & error.source.type & \").\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 680, "y": 1000, "wires": [ [ "d438ca1f.522f88" ] ] }, { "id": "804ad46f.265ab8", "type": "trigger", "z": "2024bfa3.ee2a4", "name": "Ограничение потока", "op1": "", "op2": "", "op1type": "pay", "op2type": "nul", "duration": "1", "extend": true, "overrideDelay": true, "units": "min", "reset": "", "bytopic": "topic", "topic": "error.message", "outputs": 1, "x": 400, "y": 1000, "wires": [ [ "fbb23ad0.4062d8" ] ] }, { "id": "6b52c12f.1d08a", "type": "change", "z": "2024bfa3.ee2a4", "name": "Задержка триггера", "rules": [ { "t": "set", "p": "delay", "pt": "msg", "to": "($flowContext(\"settings.teleperiod.normal\") + 5) * 1000", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 150, "y": 1060, "wires": [ [ "804ad46f.265ab8" ] ] }, { "id": "da8fd867.bda6b8", "type": "link in", "z": "2024bfa3.ee2a4", "name": "", "links": [ "6ba68741.54ecd8", "99c37f52.0d552" ], "x": 435, "y": 1240, "wires": [ [ "93f701f7.421b2" ] ] }, { "id": "6ba68741.54ecd8", "type": "link out", "z": "2024bfa3.ee2a4", "name": "", "links": [ "da8fd867.bda6b8" ], "x": 775, "y": 160, "wires": [] }, { "id": "48f06ff4.69e04", "type": "link in", "z": "2024bfa3.ee2a4", "name": "", "links": [ "e8f85797.7464d8" ], "x": 75, "y": 1360, "wires": [ [ "48eb1a43.503494" ] ] }, { "id": "e8f85797.7464d8", "type": "link out", "z": "2024bfa3.ee2a4", "name": "", "links": [ "48f06ff4.69e04", "cb4e32d6.c166e" ], "x": 775, "y": 340, "wires": [] }, { "id": "cb4e32d6.c166e", "type": "link in", "z": "2024bfa3.ee2a4", "name": "", "links": [ "e8f85797.7464d8" ], "x": 75, "y": 520, "wires": [ [ "8dec4e10.be3b5" ] ] }, { "id": "5547ecee.8de894", "type": "link in", "z": "2024bfa3.ee2a4", "name": "", "links": [ "ffa8a4c3.42c328" ], "x": 75, "y": 760, "wires": [ [ "b6d17636.a318a8" ] ] }, { "id": "ffa8a4c3.42c328", "type": "link out", "z": "2024bfa3.ee2a4", "name": "", "links": [ "5547ecee.8de894" ], "x": 695, "y": 340, "wires": [] }, { "id": "5b363de4.570ac4", "type": "link in", "z": "2024bfa3.ee2a4", "name": "", "links": [ "5b6b4800.8fadb8" ], "x": 75, "y": 820, "wires": [ [ "335988c2.9b8ed8" ] ] }, { "id": "5b6b4800.8fadb8", "type": "link out", "z": "2024bfa3.ee2a4", "name": "", "links": [ "5b363de4.570ac4" ], "x": 775, "y": 400, "wires": [] }, { "id": "eb8db7d7.b60e28", "type": "link out", "z": "2024bfa3.ee2a4", "name": "", "links": [ "784f8791.da1058" ], "x": 695, "y": 400, "wires": [] }, { "id": "784f8791.da1058", "type": "link in", "z": "2024bfa3.ee2a4", "name": "", "links": [ "eb8db7d7.b60e28" ], "x": 75, "y": 940, "wires": [ [ "5f806e54.aa6cd" ] ] }, { "id": "c3e4540.ec3abb", "type": "link out", "z": "2024bfa3.ee2a4", "name": "", "links": [ "7d588612.d5a478" ], "x": 615, "y": 400, "wires": [] }, { "id": "7d588612.d5a478", "type": "link in", "z": "2024bfa3.ee2a4", "name": "", "links": [ "c3e4540.ec3abb" ], "x": 75, "y": 880, "wires": [ [ "291326ae.6f6a1a" ] ] }, { "id": "e0380922.ddad38", "type": "link in", "z": "2024bfa3.ee2a4", "name": "", "links": [ "d128e298.bf1d6", "341e2ed3.f408f2", "d438ca1f.522f88", "4eee56fc.c319b8" ], "x": 775, "y": 640, "wires": [ [ "8b7e27a0.b891a8" ] ] }, { "id": "99c37f52.0d552", "type": "link out", "z": "2024bfa3.ee2a4", "name": "", "links": [ "da8fd867.bda6b8" ], "x": 775, "y": 1360, "wires": [] }, { "id": "17e74152.03380f", "type": "comment", "z": "2024bfa3.ee2a4", "name": "Инициализация и запрос настроек", "info": "", "x": 200, "y": 40, "wires": [] }, { "id": "3e2eff3.54a6", "type": "comment", "z": "2024bfa3.ee2a4", "name": "Отправка оповещений", "info": "", "x": 160, "y": 460, "wires": [] }, { "id": "b23fae81.8776f", "type": "link in", "z": "2024bfa3.ee2a4", "name": "", "links": [ "efb5bd3c.3ea97" ], "x": 75, "y": 700, "wires": [ [ "ee9c1c35.019c2" ] ] }, { "id": "efb5bd3c.3ea97", "type": "link out", "z": "2024bfa3.ee2a4", "name": "", "links": [ "b23fae81.8776f" ], "x": 675, "y": 1360, "wires": [] }, { "id": "341e2ed3.f408f2", "type": "link out", "z": "2024bfa3.ee2a4", "name": "", "links": [ "e0380922.ddad38" ], "x": 775, "y": 880, "wires": [] }, { "id": "d438ca1f.522f88", "type": "link out", "z": "2024bfa3.ee2a4", "name": "", "links": [ "e0380922.ddad38" ], "x": 775, "y": 1060, "wires": [] }, { "id": "1b2d48ad.d03cf7", "type": "mqtt in", "z": "2024bfa3.ee2a4", "name": "Статус реле", "topic": "circuitbreaker_0B6A01/stat/POWER1", "qos": "2", "datatype": "utf8", "broker": "8745b931.133868", "x": 370, "y": 1060, "wires": [ [ "6af9f78c.624f08" ] ] }, { "id": "6af9f78c.624f08", "type": "change", "z": "2024bfa3.ee2a4", "name": "Подготовка письма", "rules": [ { "t": "set", "p": "marks.relayStatus", "pt": "flow", "to": "payload", "tot": "msg" }, { "t": "set", "p": "topic", "pt": "msg", "to": "\"Изменился статус реле в \" & $now('[H01]:[m01]:[s01] [D01].[M01].[Y0001]', '+1000') & \"!\"", "tot": "jsonata" }, { "t": "set", "p": "payload", "pt": "msg", "to": "\"Реле контроля напряжения \" & ( payload = \"OFF\" ? \"СРАБОТАЛО\" : \"ВОССТАНОВИЛОСЬ\" ) & \" в \" & $now('[H01]:[m01]:[s01] [D01].[M01].[Y0001]', '+1000') & \".\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 600, "y": 1060, "wires": [ [ "d438ca1f.522f88" ] ] }, { "id": "23e59bcc.6fa514", "type": "change", "z": "2024bfa3.ee2a4", "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": "\"Вероятно, термодатчики \" & ( payload = true ? \"ПОДКЛЮЧЕНЫ\" : \"НЕ ПОДКЛЮЧЕНЫ\" ) & \" данные с \" & $now('[H01]:[m01]:[s01] [D01].[M01].[Y0001]', '+1000') & \".\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 520, "y": 880, "wires": [ [ "341e2ed3.f408f2" ] ] }, { "id": "b6d17636.a318a8", "type": "trigger", "z": "2024bfa3.ee2a4", "name": "Ограничение потока", "op1": "", "op2": "", "op1type": "pay", "op2type": "nul", "duration": "5", "extend": true, "overrideDelay": false, "units": "min", "reset": "", "bytopic": "all", "topic": "topic", "outputs": 1, "x": 280, "y": 760, "wires": [ [ "48c2326d.305c5c" ] ] }, { "id": "8745b931.133868", "type": "mqtt-broker", "name": "localhost", "broker": "localhost", "port": "1883", "clientid": "", "usetls": false, "compatmode": false, "keepalive": "60", "cleansession": true, "birthTopic": "", "birthQos": "0", "birthPayload": "", "closeTopic": "", "closeQos": "0", "closePayload": "", "willTopic": "", "willQos": "0", "willPayload": "" }, { "id": "ba734886.beb808", "type": "sqlitedb", "db": "c:\\noderedDB\\energy_telemetry.db", "mode": "RWC" } ]
Для работы потока необходимо создать таблицу, используя узел «inject», подключенный к узлу «sqlite».
[ { "id": "984a7e3c.16348", "type": "inject", "z": "2024bfa3.ee2a4", "name": "Создание таблицы", "props": [ { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "CREATE TABLE telemetry (_id INTEGER PRIMARY KEY AUTOINCREMENT, Timestamp TEXT, Voltage INTEGER, VoltageThresholdHigh INTEGER, VoltageThresholdLow INTEGER, VoltageThresholdNormalMin INTEGER, VoltageThresholdNormalMax INTEGER, Current REAL, Power INTEGER, Frequency INTEGER, PowerApparent INTEGER, PowerReactive INTEGER, Factor REAL, EnergyTotalStartTime TEXT, EnergyTotal REAL, EnergyYesterday REAL, EnergyToday REAL, TemperatureRelay REAL, TemperatureBreaker REAL, TemperatureThresholdHigh INTEGER, TemperatureThresholdNormal INTEGER)", "x": 710, "y": 220, "wires": [ [ "e3b00957.24e2e8" ] ] } ]
Обсуждение