RFID Gate Control with MQTT connectivity to Home Automation HUBs – 2nd part: HUB side SW and Final Product

In the previous blog post I described the device that can be installed at the gate to enable remote operation of the lock and an RFID reader feature.

In this post I am talking about the HUB side software (NodeRED and Home Assistant) and show the final PCB.

Software Overview

Highlevel software architecture and communications.
  • When the RFID Gate Opener read a new RFID Tag it is announced in the /RFID_reader topic
  • The flow running in NodeRED checks the Tag against a file database and determines if the Tag exists. Even if the Tag does not exist the RFID_code_approved Home Assistant Event is fired but the “granted” value is only true if the Tag is found. Also the “name” field only populates if the Tag is found, otherwise it is “none“.
  • The RFID_code_approved event is used as a trigger for two Home Assistant Automations
    • One of the automations updates the display fields for Tag, Name and Timestamp so all entries (or tries) will be logged
    • The other automation checks the “granted” value and calls the lock.unlock Service
    • The lock.unlock Service uses MQTT to send the unlock code (“9988” by default) to the RFID Gate Opener so it sets the opener relay closed
    • After 3 seconds (adjustable in the code) the RFID Gate Opener resets the relay to open and updates its state which is announced over the /state MQTT topic so that Home Assistant can update the Lock entity.

NodeRED

In NodeRED we need to define the code that checks the RFID Tag against a database. Simply the related MQTT topic read is connected to the SubFlow.

NodeRED code – High-level

The SubFlow that checks the database looks like this:

NodeRED SubFlow that checks the database

Its code is as follows (you can use Import in NodeRED):

[{"id":"99af359a.9cb6e8","type":"subflow","name":"RFID Check Tag in FileDB","info":"","category":"","in":[{"x":20,"y":80,"wires":[{"id":"123cd442.a1395c"}]}],"out":[],"env":[{"name":"HASS_EVENT","type":"str","value":"RFID_code_approved"}],"color":"#DDAA99"},{"id":"23661c6a.4f7cc4","type":"file in","z":"99af359a.9cb6e8","name":"","filename":"/filedb/users.txt","format":"utf8","chunk":false,"sendError":false,"encoding":"none","x":300,"y":140,"wires":[["11836a47.63df36"]]},{"id":"11836a47.63df36","type":"json","z":"99af359a.9cb6e8","name":"","property":"payload","action":"obj","pretty":false,"x":470,"y":140,"wires":[["46578695.244228"]]},{"id":"123cd442.a1395c","type":"json","z":"99af359a.9cb6e8","name":"","property":"payload","action":"obj","pretty":false,"x":110,"y":80,"wires":[["1e5e183c.a4f1a8","23661c6a.4f7cc4"]]},{"id":"1e5e183c.a4f1a8","type":"change","z":"99af359a.9cb6e8","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"tag","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":80,"wires":[["af4e07ee.e01c98"]]},{"id":"46578695.244228","type":"change","z":"99af359a.9cb6e8","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"file","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":630,"y":140,"wires":[["af4e07ee.e01c98"]]},{"id":"af4e07ee.e01c98","type":"join","z":"99af359a.9cb6e8","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":830,"y":80,"wires":[["6c5fbe0.b156044"]]},{"id":"6c5fbe0.b156044","type":"function","z":"99af359a.9cb6e8","name":"","func":"let result = {\"granted\":\"false\", \"user\":\"none\", \"tag\":\"NA\"};\nmsg.payload.file.users.forEach(function (user) {\n    if (user.RFID == msg.payload.tag.result) {\n        result.granted = \"true\";\n        result.user = user.name;\n    }\n    result.tag = msg.payload.tag.result;\n});\nmsg.payload.data = result;\nmsg.payload.event = env.get(\"HASS_EVENT\");\n\nreturn msg;","outputs":1,"noerr":0,"x":970,"y":80,"wires":[["6d97520a.27827c","8bc83b14.032ad8","fd560102.a45b1"]]},{"id":"6f98118c.b7dae","type":"debug","z":"99af359a.9cb6e8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1610,"y":240,"wires":[]},{"id":"6d97520a.27827c","type":"ha-fire-event","z":"99af359a.9cb6e8","name":"","server":"1f2c36f2.202329","event":"","data":"","dataType":"json","x":1490,"y":80,"wires":[[]]},{"id":"8bc83b14.032ad8","type":"function","z":"99af359a.9cb6e8","name":"","func":"let resultString;\nif (msg.payload.data.granted==\"true\") {\n    resultString = \"Succesful RFID tag scan by: \" + msg.payload.data.user;\n}\nelse {\n    resultString = \"Unauthorized RFID tag scan: by: \" + msg.payload.tag.result;\n}\nmsg.payload.text = resultString;\n\nreturn msg;","outputs":1,"noerr":0,"x":1150,"y":160,"wires":[["ca317886.cfa448"]]},{"id":"2b5edca.d339c24","type":"api-call-service","z":"99af359a.9cb6e8","name":"","server":"1f2c36f2.202329","version":1,"debugenabled":false,"service_domain":"logbook","service":"log","entityId":"","data":"{\"name\":\"RFID Gate Event - \",\"message\":\"{{payload}}\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1600,"y":160,"wires":[[]]},{"id":"ca317886.cfa448","type":"change","z":"99af359a.9cb6e8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.text","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1320,"y":160,"wires":[["2b5edca.d339c24","6f98118c.b7dae"]]},{"id":"fd560102.a45b1","type":"debug","z":"99af359a.9cb6e8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1520,"y":20,"wires":[]},{"id":"1f2c36f2.202329","type":"server","z":"","name":"MLHASS","legacy":false,"hassio":false,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]

Home Assistant

Let’s see what needs to be setup in Home Assistant.

First of all let’s add the lock entity in the configuration.yaml:

lock:
  - platform: mqtt
    name: RFID_Gate_Lock
    command_topic: "161d6e84-b6b8-4048-87a9-43c2565986d8/setRelay1"
    payload_unlock: "9988"
    state_unlocked: "UNLOCKED"
    state_topic: "161d6e84-b6b8-4048-87a9-43c2565986d8/state"

Then create the aforementioned two automations.

Updating the Displays

Opening the Lock

Leave a Reply