Изначально у меня в санузле использовался микроволновый датчик движения, но, увы, у меня тут сильно много помех, и он работал не корректно. Решил заменить его на два инфракрасных датчика, работающих по протоколу Zigbee.
А два, собственно, потому, что такие датчики движения не умеют «смотреть» за шторку в душе или через висящее, на перекладине от нее, полотенце, т.е. одним датчиком движения надежно перекрыть весь санузел невозможно. Поэтому два!
Но для корректной работы потока, управляющего освещением и вентиляцией, нужно, чтобы датчик был один! В итоге и появилась задача, чтобы «снаружи» всем казалось, что датчик только один.
К слову, по факту, потоку совершенно все равно, сколько к нему подключено датчиков – хоть один, хоть 5 – он будет одинаково исправно работать.
Поток получает и обрабатывает статус «occupancy». При получении «true», т.е. движение есть, оно записывается в потоковый контекст с указанием названия датчика и сразу предается на выход для публикации. При получении «false», оно записывается в ту же «ячейку» контекста, а далее проверяется, чтобы в контексте для всех датчиков было указано «false» – если это так, то это значение передается на выход, если не так, то блокируется. Т.е. публикация значения «false» возможна только, если в контексте нет ни одного значения «true». Далее отсекается дублирование статусов, т.к. значение «true» от каждого датчика, как сказано выше, проходит сюда без каких-либо препятствий.
Для корректной работы потока конец названия устройства в Zigbee2MQTT должен быть в форме «местоположение_зона»! К примеру, для одного датчика движения название должно быть «motionsensor_zoneA», а для другого – «motionsensor_zoneB». Поток разбирает тему MQTT именно по знаку «_».
[ { "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": "" } ]
Обсуждение