Update 34 files
- /nfc/README.md - /nfc/clean_old_logs.sh - /nfc/clockin.py - /nfc/emptycards.py - /nfc/sync_clocks.sh - /piservices/Dockerfile - /piservices/Portainer-lamp-stack.env - /piservices/Portainer-lamp-stack.yaml - /piservices/README.md - /piservices/avahi-alias.service - /piservices/clockpy.service - /piservices/emptycards.service - /piservices/nfc-sync.service - /piservices/test.sh - /www/404 - /www/get-table-data.php - /www/habiwan copy.png - /www/habiwan.png - /www/index.php - /www/log_swipe.php - /www/manage_data.php - /www/manifest.json - /www/names.csv - /www/network_audit.csv - /www/network-tracker.html - /www/nfc_debug.log - /www/scanner.html - /www/staff_names.php - /www/times.csv - /www/check_update.php - /www/dev.php - /www/favicon.png - /www/JsBarcode.all.min.js - /www/README.md
This commit is contained in:
1 parent
10824ab851
commit
a201d5d7ac
34 files changed
+9453
No files matched your search
+134
@@ -0,0 +1,134 @@
|
||||
"""
|
||||
This example shows connecting to the PN532 with I2C (requires clock
|
||||
stretching support), SPI, or UART. SPI is best, it uses the most pins but
|
||||
is the most reliable and universally supported.
|
||||
After initialization, try waving various 13.56MHz RFID cards over it!
|
||||
Modified and enhanced by F.Javier "habiwan" Puig Diaz in May/June 2025
|
||||
Remember to adjust the paths!
|
||||
It writes the raw times.csv file which is then used with names.csv later during processing.
|
||||
This example is production ready and has been working since June 2025.
|
||||
We were using an excel file that lists the date swiped and name of employee,
|
||||
but now I developed a php webapp with the same functionality and nicer look.
|
||||
Copyleft by F.Javier Puig Diaz, July 2026
|
||||
UPDATE: mysql for lamp usage (pip3 install mysql-connector-python first of course...)
|
||||
"""
|
||||
import RPi.GPIO as GPIO
|
||||
import vcgencmd
|
||||
import mysql.connector
|
||||
from datetime import datetime
|
||||
import time # Imported time module directly for our debounce math
|
||||
from pn532 import *
|
||||
|
||||
# --- DATABASE CONFIGURATION ---
|
||||
db_config = {
|
||||
'host': 'db', # Or your Pi's IP/localhost
|
||||
'user': 'root',
|
||||
'password': 'rootpassword',
|
||||
'database': 'lampapp'
|
||||
}
|
||||
|
||||
# --- DEBOUNCE CONFIGURATION ---
|
||||
last_swipe_times = {}
|
||||
DEBOUNCE_SECONDS = 60
|
||||
|
||||
def get_cpu_temp():
|
||||
"""Fetches the CPU temperature using vcgencmd."""
|
||||
try:
|
||||
# Standard approach for vcgencmd on Raspberry Pi
|
||||
temp = vcgencmd.measure_temp()
|
||||
# Returns a string like "temp=56.0'C", we need to extract the float
|
||||
temp_value = float(temp.replace("temp=", "").replace("'C", ""))
|
||||
return temp_value
|
||||
except:
|
||||
return 0.0 # Fallback if reading fails
|
||||
|
||||
def ensure_tables_exist(cursor):
|
||||
"""Creates tables if they are missing."""
|
||||
# Create 'names' table
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS names (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
CardID VARCHAR(12) NOT NULL UNIQUE,
|
||||
name VARCHAR(100) DEFAULT NULL
|
||||
)
|
||||
""")
|
||||
# Create 'times' table
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS times (
|
||||
UID VARCHAR(12) NOT NULL,
|
||||
temp FLOAT,
|
||||
timestamp DATETIME
|
||||
)
|
||||
""")
|
||||
|
||||
def log_to_db(uid_str, timestamp):
|
||||
try:
|
||||
conn = mysql.connector.connect(**db_config)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# --- NEW: Ensure structure exists before inserting ---
|
||||
ensure_tables_exist(cursor)
|
||||
|
||||
cpu_temp = get_cpu_temp()
|
||||
|
||||
sql = "INSERT INTO times (UID, temp, timestamp) VALUES (%s, %s, %s)"
|
||||
cursor.execute(sql, (uid_str, cpu_temp, timestamp))
|
||||
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
conn.close()
|
||||
except mysql.connector.Error as err:
|
||||
print(f"Database error: {err}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
pn532 = PN532_I2C(debug=False, reset=20, req=16)
|
||||
ic, ver, rev, support = pn532.get_firmware_version()
|
||||
print('Found PN532 with firmware version: {0}.{1}'.format(ver, rev))
|
||||
pn532.SAM_configuration()
|
||||
|
||||
GPIO.setwarnings(False)
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
buzzer = 23
|
||||
GPIO.setup(buzzer, GPIO.OUT)
|
||||
|
||||
# Boot beep
|
||||
GPIO.output(buzzer, GPIO.HIGH)
|
||||
time.sleep(0.1)
|
||||
GPIO.output(buzzer, GPIO.LOW)
|
||||
|
||||
print('Waiting for RFID/NFC card...')
|
||||
|
||||
while True:
|
||||
uid = pn532.read_passive_target(timeout=0.5)
|
||||
if uid is None:
|
||||
continue
|
||||
|
||||
# Convert list of hex to a clean string immediately
|
||||
uid_str = " ".join([hex(i) for i in uid])
|
||||
current_epoch = time.time()
|
||||
|
||||
# --- Per-Card Debounce Logic ---
|
||||
if uid_str in last_swipe_times:
|
||||
time_since_last = current_epoch - last_swipe_times[uid_str]
|
||||
if time_since_last < DEBOUNCE_SECONDS:
|
||||
# Ignore the card if it was swiped less than 60 seconds ago
|
||||
continue
|
||||
|
||||
# Record the new swipe time for this specific card
|
||||
last_swipe_times[uid_str] = current_epoch
|
||||
# -------------------------------
|
||||
|
||||
# Log to DB
|
||||
current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||
log_to_db(uid_str, current_time)
|
||||
|
||||
# Buzzer feedback
|
||||
GPIO.output(buzzer, GPIO.HIGH)
|
||||
time.sleep(0.1)
|
||||
GPIO.output(buzzer, GPIO.LOW)
|
||||
|
||||
except Exception as e:
|
||||
print(f"System error: {e}")
|
||||
finally:
|
||||
GPIO.cleanup()
|
||||
Reference in new issue
Block a user