DIYAC
Raspberry Pi Python code & PCB design project to control door access (access control) via a wiegand card and/or keypad reader, handles a doorbell too
Install / Use
/learn @CuriousJames/DIYACREADME
DIYAC - Do-It-Yourself Access Control
Warning
This is a work in progress as a personal hobby, however it has been running without any problems for the project owners use 24/7 for over a year.
That said of course, use at your own risk.
Purpose
This python code allows a Raspberry Pi to be used to allow access to a door using a Wiegand keypad/ RFID reader, and a door strike It also rings a doorbell in a (possibly) nice fashion Also included in 'Extras' is the Fritzing pcb/breadboard design
Pre-requisits
- Hardware
- Raspberry Pi (ideally 2 or up)
- Software
- Install raspbian legacy 64bit lite (as you don't need a desktop env) with the raspberry pi imager
- Update your pi
sudo apt update && sudo apt dist-upgrade - This repository
sudo apt install git && git clone https://github.com/CuriousJames/DIYAC.git && cd DIYAC - Wiegand.py put in the project directory (as obtained from: Abyz.me.uk)
wget http://abyz.me.uk/rpi/pigpio/code/wiegand_py.zip && unzip wiegand_py.zip && rm -rf wiegand_py.zip && rm -rf wiegand_old.py - Enable PiGPIO on the Pi (just do this once and it will start automatically on boot)
sudo apt-get update && sudo apt-get install pigpio python-pigpio python3-pigpio && sudo systemctl enable pigpiod - SD Notify
- with pip3
sudo apt-get update && sudo apt-get install python3-pip && sudo pip3 install sdnotify - with apt
sudo apt install python3-sdnotify
- with pip3
- Config
- Create DIYAC user, diable login and add to sudoers group
sudo useradd -M diyac && sudo usermod -L diyac
- Create DIYAC user, diable login and add to sudoers group
Installing the service
The hard way (hopefully there will be a script to do this and more soon!)
- If '/home/pi/diyac' IS your diyac folder location:
cp /home/pi/DIYAC/diyac.service_example /home/pi/DIYAC/diyac.service && sudo systemctl link /home/pi/DIYAC/diyac.service && sudo systemctl enable diyac.service - If '/home/pi/diyac' is NOT your diyac folder location:
- change the 'ExecStart' line in 'diyac.service' to 'ExecStart=/usr/bin/python3 /your/diyac/folder/location/main.py'
sudo systemctl link /your/diyac/folder/location/diyac.service
sudo systemctl enable diyac.service
sudo reboot
- Done - The service will now run on startup of the Pi
Settings
Settings are stored in settings.json which must be made by the user - you may copy settings.json_example to get you started if you wish.
This is the structure of the settings.json file:
- root - str - optional, defaults to where main.py is - path to project root
- allowedTokens - obj
- path - str - optional, default will not allow any entry - path to allowedTokens.json file, can be absolute or relative
- wiegandLength - int - optional, default 34 - number of bits that the wiegand reader will spit out
- modules - not used anymore
- logging - obj
- redact - obj - optional, keys to redact (globally)
- keys to redact - str
- syslog - obj
- level - str - optional, default NOTE - log level for syslog
- display - obj
- level - str - optional, default INFO - log level for display output
- colour - bool - optional, default FALSE - whether display output should be in colour or not
- redact - obj - optional, keys to redact
- keys to redact - str
- file - obj
- level - str - optional, defalt NONE - log level for file output
- path - str - required for logging to file - path to log file
- redact - obj - optional, keys to redact
- keys to redact - str
- redact - obj - optional, keys to redact (globally)
- pinDef - obj
- pcbVersion - float - optional - pcb version being used, for pin assignments
- doorStrike - int - optional - gpio number
- doorbell12 - int - optional - gpio number
- doorbellCc - int - optional - gpio number
- readerLed - int - optional - gpio number
- readerBuzz - int - optional - gpio number
- doorbellButton - int - optional - gpio number
- doorSensor - int - optional - gpio number
- piActiveLed - int - optional - gpio number
- spareLed - int - optional - gpio number
- wiegand0 - int - optional - gpio number
- wiegand1 - int - optional - gpio number
- exitButton - int - optional - gpio number
- inputHandling - obj
- delimiter - str - optional, default "#" - start/stop character for keypad entry
- timeout - float - optional, default 5 - seconds between keypad button presses before timeout
- bruteforceThresholdTime - float - optional, default 20 - seconds for number of attempts before lockout
- bruteforceThresholdAttempts - int - optional, default 3 - number of bad (denied) token access attempts within threshold time that are allowed before lockout starts (so if it is 3 then the fourth attempt will be denied, and the lockout will start)
- overspeedThresholdTime - float - minimum number of seconds between ench key press or card read
- lockoutTime - float - optional, default 600 - seconds that a lockout will last (for both brute forces & overspeed inputs)
- doorSensorOpen - binary - set to 1 if level reads '1' when door is open, otherwise set to '0'
- outputHandling - obj
- doorOpenTime - float - optional, default 5 - seconds that the door strike will be open for on access granted
- doorbellCcTime - float - optional, default 0.1 - seconds that doorbell contact closure will be closed/opened for
AllowedTokens
Allowed (or authorised) tokens are stored in allowedTokens.json which must be made by the user - you may copy allowedTokens.json_example to get you started if you wish.
This file is how you store what tokens (be they cards or codes) are allowed to enter the door
Each entry in this list must contain 3 items:
- token - str - token number/keypad code
- type - str - "code", "card" - what the token is for, card or keypad code
- user - str - optional, but it would be silly to leave blank - name of user
The token handler takes hex tokens and changes them to lowercase and removes colons. This means hex tokens can be upper or lower case, and can include colons or not.
Logging
Log levels are as follows:
- DBUG - lots of debug messages (most verbose)
- INFO - informational level
- NOTE - notices, mainly start and stop execution
- WARN - non critical, but should be looked at
- ERRR - critical problem
- NONE - no output (least verbose)
All levels are equivalent to linux syslog levels.
Redacting
It is possible to redact values of a specified key, by key name, in the logged 'data' (it does NOT redact the message)
So if you want to redact all values of the key 'token' you can add 'token' to the global or destination (display or file) context in settings and then no token values will display -REDACTED- and nothing else, see settings.json_example for it's implementation
code notes
systemHandler
Because systemHandler is designed to be used by various things, it's a bit flexible. Importantly, the quit function and signal handlers can be set up with a callback, so that project specific instructions can be defined in the main body of code without having to change anything within systemHandler (hopefully)
Resources
Systemd integration - https://www.freedesktop.org/software/systemd/man/systemd.service.html
Related Skills
claude-opus-4-5-migration
84.6kMigrate prompts and code from Claude Sonnet 4.0, Sonnet 4.5, or Opus 4.1 to Opus 4.5
model-usage
341.8kUse CodexBar CLI local cost usage to summarize per-model usage for Codex or Claude, including the current (most recent) model or a full model breakdown. Trigger when asked for model-level usage/cost data from codexbar, or when you need a scriptable per-model summary from codexbar cost JSON.
diffs
341.8kUse the diffs tool to produce real, shareable diffs (viewer URL, file artifact, or both) instead of manual edit summaries.
TrendRadar
50.1k⭐AI-driven public opinion & trend monitor with multi-platform aggregation, RSS, and smart alerts.🎯 告别信息过载,你的 AI 舆情监控助手与热点筛选工具!聚合多平台热点 + RSS 订阅,支持关键词精准筛选。AI 智能筛选新闻 + AI 翻译 + AI 分析简报直推手机,也支持接入 MCP 架构,赋能 AI 自然语言对话分析、情感洞察与趋势预测等。支持 Docker ,数据本地/云端自持。集成微信/飞书/钉钉/Telegram/邮件/ntfy/bark/slack 等渠道智能推送。
