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

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


iot:software:node-red:flows:dual_motion_sensor

Спаренный датчик движения на Node-RED

Изначально у меня в санузле использовался микроволновый датчик движения, но, увы, у меня тут сильно много помех, и он работал не корректно. Решил заменить его на два инфракрасных датчика, работающих по протоколу Zigbee.

А два, собственно, потому, что такие датчики движения не умеют «смотреть» за шторку в душе или через висящее, на перекладине от нее, полотенце, т.е. одним датчиком движения надежно перекрыть весь санузел невозможно. Поэтому два!

Но для корректной работы потока, управляющего освещением и вентиляцией, нужно, чтобы датчик был один! В итоге и появилась задача, чтобы «снаружи» всем казалось, что датчик только один.

К слову, по факту, потоку совершенно все равно, сколько к нему подключено датчиков – хоть один, хоть 5 – он будет одинаково исправно работать.

Логика работы потока

Поток получает и обрабатывает статус «occupancy». При получении «true», т.е. движение есть, оно записывается в потоковый контекст с указанием названия датчика и сразу предается на выход для публикации. При получении «false», оно записывается в ту же «ячейку» контекста, а далее проверяется, чтобы в контексте для всех датчиков было указано «false» – если это так, то это значение передается на выход, если не так, то блокируется. Т.е. публикация значения «false» возможна только, если в контексте нет ни одного значения «true». Далее отсекается дублирование статусов, т.к. значение «true» от каждого датчика, как сказано выше, проходит сюда без каких-либо препятствий.

Скриншот потока

:!: Для корректной работы потока конец названия устройства в Zigbee2MQTT должен быть в форме «местоположение_зона»! К примеру, для одного датчика движения название должно быть «motionsensor_zoneA», а для другого – «motionsensor_zoneB». Поток разбирает тему MQTT именно по знаку «_».

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

dual-motion-sensor.json
[
    {
        "id": "0949550bf2a91149",
        "type": "group",
        "z": "b18e26a3.abdb68",
        "name": "Спаренный датчик движения в санузле",
        "style": {
            "label": true
        },
        "nodes": [
            "a5e567ed977a171d",
            "95e5c0e9ab1f2009",
            "e058f10c50dbbdb3",
            "077e89fafb27e2d1",
            "e627c9270803f188",
            "58e1ea9518aa151c",
            "f1ebface1a39f71c"
        ],
        "x": 14,
        "y": 219,
        "w": 932,
        "h": 142
    },
    {
        "id": "a5e567ed977a171d",
        "type": "mqtt in",
        "z": "b18e26a3.abdb68",
        "g": "0949550bf2a91149",
        "name": "Зона ванны",
        "topic": "zigbee2mqtt/motionsensor/bathroom_tub",
        "qos": "2",
        "datatype": "json",
        "broker": "1765f6372ba832dc",
        "nl": false,
        "rap": false,
        "inputs": 0,
        "x": 110,
        "y": 260,
        "wires": [
            [
                "e058f10c50dbbdb3"
            ]
        ]
    },
    {
        "id": "95e5c0e9ab1f2009",
        "type": "mqtt in",
        "z": "b18e26a3.abdb68",
        "g": "0949550bf2a91149",
        "name": "Зона туалета",
        "topic": "zigbee2mqtt/motionsensor/bathroom_toilet",
        "qos": "2",
        "datatype": "json",
        "broker": "1765f6372ba832dc",
        "nl": false,
        "rap": false,
        "inputs": 0,
        "x": 110,
        "y": 320,
        "wires": [
            [
                "e058f10c50dbbdb3"
            ]
        ]
    },
    {
        "id": "e058f10c50dbbdb3",
        "type": "change",
        "z": "b18e26a3.abdb68",
        "g": "0949550bf2a91149",
        "name": "Сохранение статусов",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "payload.occupancy ? 1 : 0",
                "tot": "jsonata"
            },
            {
                "t": "set",
                "p": "name",
                "pt": "msg",
                "to": "$split (topic, \"_\" )",
                "tot": "jsonata"
            },
            {
                "t": "set",
                "p": "status.bathroom[msg.name[1]]",
                "pt": "flow",
                "to": "payload",
                "tot": "msg"
            },
            {
                "t": "delete",
                "p": "name",
                "pt": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 340,
        "y": 260,
        "wires": [
            [
                "077e89fafb27e2d1"
            ]
        ]
    },
    {
        "id": "077e89fafb27e2d1",
        "type": "switch",
        "z": "b18e26a3.abdb68",
        "g": "0949550bf2a91149",
        "name": "Фильтр статусов",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "jsonata_exp",
                "v": "$sum( $flowContext( \"status.bathroom\" ).* ) = 0 or payload = 1",
                "vt": "jsonata"
            }
        ],
        "checkall": "false",
        "repair": false,
        "outputs": 1,
        "x": 590,
        "y": 260,
        "wires": [
            [
                "e627c9270803f188"
            ]
        ]
    },
    {
        "id": "e627c9270803f188",
        "type": "rbe",
        "z": "b18e26a3.abdb68",
        "g": "0949550bf2a91149",
        "name": "Фильтр повторов",
        "func": "rbe",
        "gap": "",
        "start": "",
        "inout": "out",
        "septopics": false,
        "property": "payload",
        "topi": "topic",
        "x": 830,
        "y": 260,
        "wires": [
            [
                "58e1ea9518aa151c",
                "f1ebface1a39f71c"
            ]
        ]
    },
    {
        "id": "58e1ea9518aa151c",
        "type": "mqtt out",
        "z": "b18e26a3.abdb68",
        "g": "0949550bf2a91149",
        "name": "Публикация сообщения",
        "topic": "nodered/motionsensor/bathroom",
        "qos": "",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "1765f6372ba832dc",
        "x": 810,
        "y": 320,
        "wires": []
    },
    {
        "id": "f1ebface1a39f71c",
        "type": "link out",
        "z": "b18e26a3.abdb68",
        "g": "0949550bf2a91149",
        "name": "На управление светом",
        "mode": "link",
        "links": [
            "34808cfc98d35c13"
        ],
        "x": 635,
        "y": 320,
        "wires": []
    },
    {
        "id": "1765f6372ba832dc",
        "type": "mqtt-broker",
        "name": "localhost",
        "broker": "localhost",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "autoUnsubscribe": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthRetain": "false",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closeRetain": "false",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willRetain": "false",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    }
]

Дисклеймер

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

Обсуждение

Ваш комментарий:
M P B W H N M S X D Q O O L P G
 
Последнее изменение: 2023/12/03 21:22 — Николай Солошин