TamTap is a locally hosted attendance system designed for FEU Roosevelt Marikina. Students tap their NFC cards on an RC522 reader connected to a Raspberry Pi 4B. The system captures a photo via Pi Camera v2 for face detection verification (Haar Cascade β detection only, no recognition ), records the attendance in MongoDB, and broadcasts the event to a real-time LAN dashboard via Socket.IO.
All processing happens on-premise β no cloud, no internet dependency.
Category
Feature
Attendance
NFC tap β Camera capture β Face detection β Record
Dashboard
Real-time attendance feed via Socket.IO
Roles
Admin, Adviser, Teacher β role-based access
Schedules
Per-section weekly schedules with grace period/absent thresholds
Calendar
Academic calendar with suspensions and no-class declarations
Notifications
Pending absence tracking, excused marking
Export
XLSX and PDF attendance reports
Offline Mode
JSON fallback when MongoDB is unreachable
Logs
Live systemd log streaming in admin panel
Buttons
Physical GPIO buttons to start/restart/stop services
Photo Storage
External SD card with internal fallback
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β RASPBERRY PI 4B β
β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β RC522 NFC β β Pi Camera β β I2C LCD β β
β β Reader β β v2 (5MP) β β 16x2 β β
β β (SPI) β β (CSI) β β (0x27) β β
β ββββββββ¬ββββββββ ββββββββ¬ββββββββ ββββββββ¬ββββββββ β
β β β β β
β ββββββββΌββββββββββββββββββββΌββββββββββββββββββββΌβββββββββββ β
β β tamtap.py (Python 3.11) β β
β β State Machine + Face Detection (Haar) β β
β β GPIO: Green LED (17) | Red LED (27) | Buzzer(18) β β
β ββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββ β
β β HTTP POST /api/hardware/* β
β ββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββ β
β β server.js (Node.js 20 / Express) β β
β β REST API + Socket.IO + Session Auth β β
β ββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββ β
β β MongoDB (Local Instance) β β
β β Collections: students, teachers, attendance, β β
β β admins, calendar, schedules, settings β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ
β LAN (port 3000)
βββββββββββββΌββββββββββββ
β Browser Dashboard β
β (HTML/CSS/Vanilla JS)β
β Tailwind + Chart.js β
βββββββββββββββββββββββββ
Student taps NFC card
β
βΌ
βββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β RC522 reads βββββΆβ Lookup student βββββΆβ Validate β
β NFC UID β β in DB (Mongo/JSON)β β schedule/time β
βββββββββββββββ ββββββββββββββββββββ ββββββββββ¬βββββββββ
β
ββββββββββΌβββββββββ
β Capture photo β
β (rpicam-still) β
ββββββββββ¬βββββββββ
β
ββββββββββΌβββββββββ
β Haar cascade β
β face detection β
ββββββββββ¬βββββββββ
β
ββββββββββββββββββββ΄βββββββββββββββββββ
β β
Face detected? No face
β β
βββββββΌββββββ βββββββββΌββββββββ
β Save to DB β β Red LED + β
β Green LED β β Buzzer fail β
β Buzzer OK β β LCD: FAIL β
βββββββ¬ββββββ βββββββββββββββββ
β
βββββββΌβββββββββββββββ
β POST /api/hardware/ β
β attendance β
βββββββ¬βββββββββββββββ
β
βββββββΌβββββββββββββββ
β Socket.IO broadcast β
β attendance:new β
ββββββββββββββββββββββ
π§ Hardware Specifications
Component
Model
Interface
Details
SBC
Raspberry Pi 4B
β
4GB RAM, Bookworm OS
NFC Reader
RC522
SPI
GPIO 8, 9, 10, 11, 25
LCD
I2C 16x2
I2C
Address 0x27
Camera
Pi Camera v2
CSI
5MP, snapshot only
Green LED
β
GPIO 17
Success indicator
Red LED
β
GPIO 27
Failure indicator
Buzzer
β
GPIO 18
Via relay module
Start Button
β
GPIO 5
Active LOW, pull-up
Restart Button
β
GPIO 6
Active LOW, pull-up
Stop Button
β
GPIO 13
Hold 2.5s, Active LOW
GPIO 5 βββ START button (to GND)
GPIO 6 βββ RESTART button (to GND)
GPIO 8 βββ RC522 SDA/CS
GPIO 9 βββ RC522 MISO
GPIO 10 βββ RC522 MOSI
GPIO 11 βββ RC522 SCK
GPIO 13 βββ STOP button (to GND, hold 2.5s)
GPIO 17 βββ Green LED (success)
GPIO 18 βββ Buzzer (via relay)
GPIO 25 βββ RC522 RST
GPIO 27 βββ Red LED (fail)
I2C SDA βββ LCD SDA
I2C SCL βββ LCD SCL
Hardware Layer (Python 3.11)
Library
Purpose
RPi.GPIO
GPIO pin control (LEDs, buzzer)
mfrc522
RC522 NFC reader driver (SPI)
smbus
I2C communication (LCD 16x2)
opencv-python-headless
Face detection (Haar Cascade)
pymongo
MongoDB driver (with JSON fallback)
python-dotenv
Environment variable loading
pyserial
Arduino serial communication
Library
Purpose
express
HTTP server & REST API
mongodb
MongoDB native driver
socket.io
Real-time WebSocket events
express-session
Session-based authentication
connect-mongo
MongoDB-backed session store
express-rate-limit
Rate limiting (login, API)
bcryptjs
Password hashing
cors
Cross-origin requests (LAN)
multer
File upload handling (XLSX import)
exceljs
XLSX report generation
pdfkit
PDF report generation
xlsx
XLSX parsing (schedule import)
signale
Structured console logging
dotenv
Environment variable loading
Frontend (Multi-Page HTML)
Technology
Purpose
HTML5
Page structure
CSS3
Styling
Vanilla JavaScript (ES6+)
Client logic β no frameworks
Tailwind CSS
Utility-first styling (CDN)
Chart.js
Attendance analytics charts
SweetAlert2
Modal dialogs and alerts
Socket.IO Client
Real-time attendance feed
Fetch API
HTTP requests β no Axios
TamTap/
βββ .env # Environment variables (gitignored)
βββ .gitignore
βββ LICENSE # MIT License
βββ README.md # This file
βββ startup.sh # Systemd startup script for tamtap.py
βββ update.sh # Git pull + dependency update + restart
β
βββ assets/
β βββ attendance_photos/ # Captured attendance photos (by date)
β βββ backgrounds/ # UI background images
β βββ icons/ # Favicon and UI icons
β βββ logos/ # FEU x TamTap branding logos
β βββ templates/ # Schedule import templates
β βββ formats/ # Export format assets
β
βββ buttons/
β βββ button_listener.py # GPIO button controller (start/restart/stop)
β βββ tamtap-buttons.service # Systemd unit: button listener
β βββ tamtap-server.service # Systemd unit: Node.js server
β βββ README.md # Button wiring & setup guide
β
βββ database/
β βββ tamtap_users.json # JSON fallback database
β
βββ hardware/
β βββ tamtap.py # Main NFC attendance loop (state machine)
β βββ database.py # Unified DB module (MongoDB + JSON sync)
β βββ register.py # Student registration CLI
β βββ tamtap_admin.py # Admin CLI (archive, manage, export)
β βββ archive_attendance.py # Attendance archival utility
β βββ requirements.txt # Python dependencies
β βββ arduino/
β βββ rfid_reader.ino # Arduino RFID reader firmware
β βββ register_arduino.py # Arduino-based NFC registration
β
βββ software/
β βββ server.js # Express.js API server (main entry)
β βββ config.js # Server configuration
β βββ package.json # Node.js dependencies
β βββ middleware/
β β βββ auth.js # Session auth middleware (requireAuth, requireAdmin)
β β βββ hardwareAuth.js # Hardware API key auth (Pi β Server)
β βββ routes/
β β βββ admin.js # Teacher/student CRUD (admin only)
β β βββ archive.js # Attendance archival management
β β βββ attendance.js # Attendance queries (today, by date, range)
β β βββ auth.js # Login/logout/session
β β βββ calendar.js # Academic calendar management
β β βββ export.js # XLSX/PDF report generation
β β βββ logs.js # Live systemd log streaming
β β βββ notifications.js # Pending absences & excused marking
β β βββ schedules.js # Section schedule management
β β βββ stats.js # Dashboard statistics & analytics
β β βββ students.js # Student/teacher data queries
β βββ scripts/
β β βββ bootstrap-admin.js # Initial admin account creation
β βββ utils/
β β βββ Logger.js # Signale-based structured logging
β β βββ dateUtils.js # Philippine timezone date utilities
β β βββ filenameSanitizer.js # Photo filename sanitization
β β βββ sanitize.js # Input sanitization (NoSQL injection guard)
β βββ public/
β βββ index.html # Landing page
β βββ login.html # Login page
β βββ dashboard.html # Main dashboard
β βββ admin.html # Admin panel
β βββ 404.html # Custom 404 error page
β βββ privacy.html # Privacy policy page
β βββ terms.html # Terms of use page
β βββ researchers.html # Research team page
β βββ css/
β β βββ fonts.css # Shared @font-face definitions
β β βββ preloader.css # Loading animation styles
β β βββ dashboard.css # Dashboard page styles
β β βββ admin.css # Admin panel styles
β β βββ login.css # Login page styles
β β βββ researchers.css # Researchers page styles
β β βββ 404.css # 404 page styles
β βββ js/
β βββ preloader.js # Loading animation logic
β βββ tailwind-config.js # Shared Tailwind CSS configuration
β βββ utils.js # Shared utilities (XSS escape, etc.)
β βββ dashboard.js # Dashboard page logic
β βββ admin.js # Admin panel logic
β βββ login.js # Login page logic
β
βββ test/
βββ test_rfid.py # RFID reader test
βββ test_lcd.py # LCD display test
βββ test_lcd_debug.py # LCD debug utility
βββ test_leds.py # LED test
βββ test_buzzer.py # Buzzer test
βββ test_dry_run.py # Full system dry run (no hardware)
βββ excel_id.py # Excel ID utility
Raspberry Pi 4B (4GB RAM) with Raspberry Pi OS Bookworm
RC522 NFC Reader module
I2C LCD 16x2 display
Pi Camera v2
2x LEDs (green, red), 1x buzzer with relay
3x push buttons (start, restart, stop)
NFC cards/tags (MIFARE)
Python 3.11+
Node.js 20+
MongoDB 7+ (local instance)
Git
Enable Interfaces (on Raspberry Pi)
sudo raspi-config
# Enable: SPI, I2C, Camera (Legacy Camera if needed)
π Installation & Setup
cd /home/charles
git clone https://github.com/CharlesNaig/TamTap.git
cd TamTap
2. Create Environment File
cp .env.example .env
# Edit .env with your MongoDB URI and settings
Required .env variables:
# MongoDB
MONGODB_URI = mongodb://localhost:27017/
MONGODB_NAME = tamtap
# Server
API_SERVER_PORT = 3000
API_SERVER_HOST = 0.0.0.0
# Session
SESSION_SECRET = your-random-secret-here
# Hardware β Server communication
TAMTAP_API_URL = http://localhost:3000
# Hardware API Key (shared secret between Pi and server, prevents forged attendance)
HARDWARE_SECRET = your-hardware-secret-here
3. Setup Python Virtual Environment
python3 -m venv .venv
source .venv/bin/activate
pip install -r hardware/requirements.txt
4. Install Node.js Dependencies
sudo systemctl start mongod
sudo systemctl enable mongod
6. Bootstrap Admin Account
cd software
npm run bootstrap
# Default: admin / tamtap2026 (change immediately)
7. Install Systemd Services
# Copy service files
sudo cp buttons/tamtap-buttons.service /etc/systemd/system/
sudo cp buttons/tamtap-server.service /etc/systemd/system/
# Create tamtap.service for the hardware script
sudo systemctl daemon-reload
sudo systemctl enable tamtap-buttons.service
sudo systemctl enable tamtap-server.service
sudo systemctl enable tamtap.service
Server Config (software/config.js)
Setting
Default
Description
server.port
3000
HTTP server port
server.host
0.0.0.0
Bind address (all interfaces)
mongodb.maxPoolSize
10
Max MongoDB connections
session.maxAge
8 hours
Session cookie lifetime
photos.baseDir
../assets/attendance_photos
Internal photo storage
photos.externalDir
/mnt/tamtap_photos
External SD card (preferred)
socketio.pingTimeout
60000
Socket.IO ping timeout (ms)
Timing Constants (hardware/tamtap.py)
Constant
Value
Description
CAMERA_CAPTURE_TIME
1200 ms
Camera shutter time
CAMERA_TIMEOUT
2.5 s
subprocess timeout
NFC_POLL_INTERVAL
0.1 s
NFC read poll interval
FACE_DETECTION_TIMEOUT
1.0 s
Haar cascade timeout
MIN_FACE_SIZE
(80, 80)
Minimum face pixel size
# Terminal 1: Start MongoDB
sudo systemctl start mongod
# Terminal 2: Start Node.js server (with auto-reload)
cd software
npm run dev
# Terminal 3: Start hardware script (on Raspberry Pi only)
source .venv/bin/activate
cd hardware
python tamtap.py
Production Mode (Systemd)
# Start all services
sudo systemctl start tamtap.service
sudo systemctl start tamtap-server.service
sudo systemctl start tamtap-buttons.service
# Or use physical START button (GPIO 5)
Open a browser on any device on the same LAN:
http://<raspberry-pi-ip>:3000
Base URL: http://<host>:3000/api
Method
Endpoint
Auth
Description
POST
/api/auth/login
Public
Login (returns session cookie)
POST
/api/auth/logout
Session
Destroy session
GET
/api/auth/me
Session
Get current user info
Method
Endpoint
Auth
Description
GET
/api/students
Session
List all students
GET
/api/students/:nfc_id
Session
Get student by NFC ID
GET
/api/teachers
Session
List all teachers
GET
/api/teachers/:nfc_id
Session
Get teacher by NFC ID
Method
Endpoint
Auth
Description
Teachers
GET
/api/admin/teachers
Admin
List teachers with sections
GET
/api/admin/teachers/:id
Admin
Get teacher by ID
POST
/api/admin/teachers
Admin
Register new teacher
PUT
/api/admin/teachers/:id
Admin
Update teacher
DELETE
/api/admin/teachers/:id
Admin
Delete teacher
POST
/api/admin/teachers/:id/reset-password
Admin
Reset teacher password
Students
GET
/api/admin/students
Admin
List students (paginated, filterable)
POST
/api/admin/students
Admin
Register new student
POST
/api/admin/students/bulk
Admin
Bulk register (CSV)
PUT
/api/admin/students/:nfc_id
Admin
Update student
DELETE
/api/admin/students/:nfc_id
Admin
Delete student
POST
/api/admin/students/archive-batch
Admin
Archive multiple students
GET
/api/admin/students/archived
Admin
List archived students
POST
/api/admin/students/restore
Admin
Restore archived student
DELETE
/api/admin/students/archived/:nfc_id
Admin
Permanently delete archived
POST
/api/admin/students/delete-batch
Admin
Permanently delete batch
Sections & Settings
GET
/api/admin/sections
Admin
List all sections
GET
/api/admin/settings
Admin
Get all settings
GET
/api/admin/settings/:key
Admin
Get setting by key
PUT
/api/admin/settings/:key
Admin
Update setting value
POST
/api/admin/settings/saturday-toggle
Admin
Toggle Saturday classes
Method
Endpoint
Auth
Description
GET
/api/attendance
Session
Today's records (?section=11-A)
GET
/api/attendance/:date
Session
Records by date (YYYY-MM-DD)
GET
/api/attendance/range
Session
Records by date range (?from=&to=)
Method
Endpoint
Auth
Description
GET
/api/stats
Session
Dashboard statistics
GET
/api/stats/summary
Session
Present/late/absent counts
GET
/api/stats/daily
Session
Daily summary
GET
/api/stats/weekly
Session
Weekly summary
Method
Endpoint
Auth
Description
GET
/api/schedules
Session
All section schedules
GET
/api/schedules/:section
Session
Specific section schedule
POST
/api/schedules
Admin
Create schedule
PUT
/api/schedules/:section
Admin/Adviser
Update schedule
DELETE
/api/schedules/:section
Admin
Delete schedule
POST
/api/schedules/import
Admin
Import from XLSX
GET
/api/schedules/template
Session
Download XLSX template
Method
Endpoint
Auth
Description
GET
/api/calendar
Session
Calendar events
POST
/api/calendar
Admin
Add suspension/no-class
DELETE
/api/calendar/:id
Admin
Remove event
Method
Endpoint
Auth
Description
GET
/api/export/xlsx
Session
Download XLSX report
GET
/api/export/pdf
Session
Download PDF report
Method
Endpoint
Auth
Description
GET
/api/notifications/pending
Session
Students who haven't tapped
GET
/api/notifications/count
Session
Pending absence count
POST
/api/notifications/mark-excused
Session
Mark student excused
POST
/api/notifications/mark-absent
Session
Confirm absent
POST
/api/notifications/bulk-absent
Session
Mark all pending as absent
Method
Endpoint
Auth
Description
GET
/api/logs
Admin
All service logs
GET
/api/logs/:service
Admin
Logs by service (buttons, server, hardware)
Hardware Bridge (API Key Protected)
Method
Endpoint
Auth
Description
POST
/api/hardware/attendance
Hardware Key
Record from tamtap.py
POST
/api/hardware/fail
Hardware Key
Failure from tamtap.py
POST
/api/hardware/status
Hardware Key
Status update from tamtap.py
Method
Endpoint
Auth
Description
GET
/api/health
Public
Server health + uptime
{
nfc_id : String , // Unique NFC card UID (required, indexed)
tamtap_id : String , // Human-readable TamTap ID
name : String , // Full name
first_name : String ,
last_name : String ,
email : String ,
grade : String , // e.g., "12"
section : String , // e.g., "12-ICT-A"
registered : String // ISO date string
}
{
username : String , // Unique login username (indexed)
password : String , // bcrypt hash
name : String ,
email : String ,
nfc_id : String , // Optional (sparse unique index)
tamtap_id : String ,
role_type : String , // "admin" | "adviser" | "teacher"
advised_section : String , // For advisers only
sections_handled : [ String ] , // Sections this teacher manages
forcePasswordChange : Boolean ,
created : String
}
{
username : String , // Unique
password : String , // bcrypt hash
name : String
}
{
nfc_id : String , // Student/teacher NFC UID
tamtap_id : String ,
name : String ,
role : String , // "student" | "teacher"
date : String , // "YYYY-MM-DD HH:MM:SS"
time : String , // "HH:MM:SS"
session : String , // "AM" | "PM"
status : String , // "present" | "late" | "absent" | "excused"
photo : String , // Filename of captured photo
grade : String ,
section : String
}
{
section : String , // Unique (e.g., "12-ICT-A")
adviser_id : String , // Teacher _id (indexed)
weekly_schedule : {
monday : { start : "07:00" , end : "17:00" } ,
tuesday : { start : "07:00" , end : "17:00" } ,
wednesday : { start : "07:00" , end : "17:00" } ,
thursday : { start : "07:00" , end : "17:00" } ,
friday : { start : "07:00" , end : "17:00" } ,
saturday : { start : null , end : null }
} ,
grace_period_minutes : Number , // Default: 20
absent_threshold_minutes : Number // Default: 60
}
{
type : String , // "suspension" | "no-class" | "saturday-makeup"
date : String , // Single date (YYYY-MM-DD)
startDate : String , // Range start (for multi-day suspensions)
endDate : String , // Range end
section : String , // For section-specific no-class
reason : String
}
{
key : String , // Unique setting key
value : Mixed // Setting value
}
1. School-wide suspension (Admin) β Highest
2. Section no-class declaration (Teacher)
3. Weekend rules (Sat disabled, Sun always off)
4. Normal instructional day (Mon-Fri) β Lowest
// Students
students . createIndex ( { nfc_id : 1 } , { unique : true } ) ;
students . createIndex ( { tamtap_id : 1 } ) ;
// Teachers
teachers . createIndex ( { nfc_id : 1 } , { unique : true , sparse : true } ) ;
teachers . createIndex ( { tamtap_id : 1 } ) ;
teachers . createIndex ( { username : 1 } , { unique : true } ) ;
// Attendance
attendance . createIndex ( { nfc_id : 1 , date : 1 } ) ;
attendance . createIndex ( { date : - 1 } ) ;
// Calendar
calendar . createIndex ( { type : 1 , date : 1 } ) ;
calendar . createIndex ( { type : 1 , startDate : 1 , endDate : 1 } ) ;
calendar . createIndex ( { type : 1 , section : 1 , date : 1 } ) ;
// Settings
settings . createIndex ( { key : 1 } , { unique : true } ) ;
// Schedules
schedules . createIndex ( { section : 1 } , { unique : true } ) ;
schedules . createIndex ( { adviser_id : 1 } ) ;
Only these events are emitted (contract-enforced):
Attendance Events (hardware β dashboard)
Event
Direction
Payload
Description
attendance:new
Server β Client
{ nfc_id, name, role, date, time, session, photo, section }
New attendance recorded
attendance:fail
Server β Client
{ nfc_id, name, reason, decline_code }
Attendance failed
camera:snapshot
Server β Client
{ photo_url }
Camera snapshot taken
system:status
Server β Client
{ status, mongodb, clients, hardware }
System health update
Log Streaming Events (admin panel β server)
Event
Direction
Payload
Description
logs:subscribe
Client β Server
{ service }
Client requests real-time log stream
logs:entry
Server β Client
{ timestamp, message, service }
Server pushes a log entry
logs:error
Server β Client
{ error }
Server reports log stream error
logs:unsubscribe
Client β Server
{ service }
Client stops log stream
β οΈ No custom events may be added without updating the contract.
All hardware modules must follow this state flow:
βββββββββββββββββββββββββββββββββββββββββββ
β β
βΌ β
ββββββββ Card read βββββββββββββββββ β
β IDLE β βββββββββββββββββΆβ CARD_DETECTED β β
ββββββββ βββββββββ¬ββββββββ β
β β
βΌ β
ββββββββββββββββββ β
β CAMERA_ACTIVE β β
βββββββββ¬βββββββββ β
β β
βββββββββββ΄ββββββββββ β
β β β
βΌ βΌ β
βββββββββββ βββββββββ
β SUCCESS β β FAIL ββ
ββββββ¬βββββ ββββ¬βββββ
β β β
ββββββββββββββββββββββββ
Rules:
No state skipping β every transition is sequential
No parallel state transitions
Every cycle must return to IDLE
SHUTDOWN state only on SIGINT/SIGTERM
Each attendance cycle must complete within β€ 3.5 seconds :
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β TOTAL BUDGET: β€ 3.5s β
ββββββββββββ¬βββββββββββ¬βββββββββββββββ¬βββββββββββ¬ββββββββββββββ€
β NFC Read β Schedule β Camera Wake β Face β LCD + LED β
β β€ 100ms β Validate β + Capture β Detect β Update β
β β ~50ms β β€ 1500ms β β€ 1200ms β β€ 100ms β
ββββββββββββ΄βββββββββββ΄βββββββββββββββ΄βββββββββββ΄ββββββββββββββ
All code must be non-blocking. No sleep() calls that violate this budget.
Page
Path
Description
Landing
/index.html
Public landing page with hero slideshow
Login
/login.html
Username/password login (session)
Dashboard
/dashboard.html
Real-time attendance feed + charts
Admin
/admin.html
Student/teacher management, schedules, calendar, logs
Privacy
/privacy.html
Privacy policy (Data Privacy Act compliance)
Terms
/terms.html
Terms of use
Researchers
/researchers.html
Research team profiles
404
/404.html
Custom error page
Multi-page HTML β no SPA frameworks
One JS file per page β extracted to public/js/ (no inline <script> blocks)
Shared utilities β utils.js (XSS escape), tailwind-config.js, fonts.css
Fetch API only β no Axios
WebSocket only for live updates β not for data fetching
Tailwind CSS via CDN with shared config (tailwind-config.js)
Role-based UI via JS logic: admin / adviser / teacher
Service
File
Description
User
tamtap.service
(created during setup)
Hardware NFC/camera loop
charles
tamtap-server.service
buttons/tamtap-server.service
Node.js backend
charles
tamtap-buttons.service
buttons/tamtap-buttons.service
GPIO button controller
root
# Check status
sudo systemctl status tamtap.service
sudo systemctl status tamtap-server.service
sudo systemctl status tamtap-buttons.service
# View logs
sudo journalctl -u tamtap -f
sudo journalctl -u tamtap-server -f
sudo journalctl -u tamtap-buttons -f
# Restart
sudo systemctl restart tamtap.service
sudo systemctl restart tamtap-server.service
Script
Location
Description
startup.sh
Root
Activates venv + starts tamtap.py (used by systemd)
update.sh
Root
Git pull + update deps + restart services
bootstrap-admin.js
software/scripts/
Create initial admin account
register.py
hardware/
CLI student registration via NFC
tamtap_admin.py
hardware/
Admin CLI: archive, manage, export
archive_attendance.py
hardware/
Archive/clear attendance records
CLI Registration (register.py)
source .venv/bin/activate
cd hardware
python register.py
# Menu: 1. Register Student (NFC) | 2. List | 3. Delete | 4. Exit
Update System (update.sh)
./update.sh
# Pulls from GitHub, updates pip deps if changed, restarts services
# Aborts if local uncommitted changes exist
β οΈ Error Handling & Logging
All functions use try/except with specific exception types
Timeouts on NFC reads, camera subprocess, and face detection
No print() debugging β use logging module only
Levels: INFO (normal), WARNING (recoverable), ERROR (hardware/data failure)
All routes use try/catch
Structured logging via signale (Logger.js)
Custom log types: info, success, warn, error, debug, database, socket, api, hardware, server
Live log streaming to admin panel via Socket.IO
Level
Use Case
Example
INFO
Normal operations
"Student tapped: John Doe"
WARN
Recoverable issues
"MongoDB reconnecting..."
ERROR
Hardware or data failure
"NFC reader init failed"
No cloud services β Firebase, AWS, Supabase, etc. are forbidden
No frontend frameworks β React, Angular, Vue are not allowed
No GUI apps on Pi β No Tkinter, PyQT
No facial recognition β Face detection (Haar) only, no face matching
No hardcoded credentials β Use .env for all secrets
No blocking infinite loops β All code must be non-blocking
No features outside research scope β Only implement what's in the capstone spec
Fork the repository
Create a feature branch: git checkout -b feature/your-feature
Commit changes: git commit -m "feat: description"
Push: git push origin feature/your-feature
Open a Pull Request
feat: New feature
fix: Bug fix
docs: Documentation only
style: Formatting (no logic change)
refactor: Code restructuring
test: Adding tests
chore: Build/tooling changes
Python 3.11+ syntax
logging module β never print()
Type hints encouraged but not required
snake_case for functions and variables
PascalCase for classes
UPPER_SNAKE_CASE for constants
Defensive programming: validate all inputs
Prefer clarity over cleverness
All code must be explainable to panelists
ES6+ syntax (const, let, arrow functions, async/await)
camelCase for functions and variables
PascalCase for classes
UPPER_SNAKE_CASE for constants
Always use try/catch in async routes
Return early on errors
Use structured logger, not console.log
Vanilla ES6+ β no frameworks, no transpilers
One JS file per HTML page
Fetch API for HTTP requests β no Axios
Socket.IO client for real-time only
Use const by default, let when mutation needed
Never use var
4-space indentation (Python), 4-space or 2-space (JS β match existing)
Modular, testable functions
Meaningful variable/function names
Comments for non-obvious logic
TODO comments are mandatory edge cases β never ignore them
Layer
Language
Hardware control
Python 3.11
Backend API
JavaScript (Node.js 20)
Frontend UI
HTML5, CSS3, JavaScript (ES6+)
Arduino firmware
C++ (Arduino IDE)
Shell scripts
Bash
Database
MongoDB query language
Charles Giann Marcelo β Lead Developer
et al. β FEU Roosevelt Marikina, Grade 12 ICT
This project is licensed under the MIT License β see the LICENSE file for details.
MIT License
Copyright (c) 2025 Charles Giann Marcelo
Built with π at FEU Roosevelt Marikina
TamTap β Tap. Verify. Present.