Skip to content

Commit 16a87e9

Browse files
Create main.py
1 parent 8f22daf commit 16a87e9

File tree

1 file changed

+330
-0
lines changed
  • RFID-Based Inventory Management System

1 file changed

+330
-0
lines changed

Diff for: RFID-Based Inventory Management System/main.py

+330
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,330 @@
1+
#IOT Mini Project- Shivani Bhat and Chetanarupa Jirgale
2+
from mfrc522 import MFRC522
3+
from machine import Pin, SPI
4+
import time
5+
import usocket as socket
6+
import network
7+
import _thread
8+
9+
# Define the SPI bus and pins
10+
spi = SPI(2, baudrate=2500000, polarity=0, phase=0)
11+
spi.init()
12+
13+
# Initialize the MFRC522 RFID reader with SPI and reset/cs pins
14+
rdr = MFRC522(spi=spi, gpioRst=4, gpioCs=5)
15+
16+
# Define the relay pin (to control a lock or door)
17+
relay = Pin(12, Pin.OUT)
18+
19+
# Define warehouse sections with authorized RFID tags, items, and statuses
20+
warehouse_access = {
21+
"0xbcb23202": {"section": "Section A", "items": "Resistors", "quantity": 100, "authorized": True, "status": "Not Scanned"},
22+
"0x533c11da": {"section": "Section B", "items": "Wooden Crates", "quantity": 75, "authorized": True, "status": "Not Scanned"},
23+
"0xa3e7dce1": {"section": "Section C", "items": "Electrical Cables", "quantity": 50, "authorized": False, "status": "Not Scanned"}, # Unauthorized
24+
"0x737505da": {"section": "Section D", "items": "Steel Beams", "quantity": 120, "authorized": True, "status": "Not Scanned"},
25+
"0x66033402": {"section": "Section E", "items": "Plastic Containers", "quantity": 60, "authorized": False, "status": "Not Scanned"} # Unauthorized
26+
}
27+
28+
# Global variable to store the latest RFID scan information
29+
access_log = "Waiting for RFID scan..."
30+
31+
# Function to check access to warehouse section and update status
32+
def check_access(uid):
33+
global access_log
34+
if uid in warehouse_access:
35+
section_info = warehouse_access[uid]
36+
section = section_info["section"]
37+
authorized = section_info["authorized"]
38+
39+
if authorized:
40+
section_info["status"] = "Granted"
41+
access_log = f"Access granted to {section}."
42+
print(access_log)
43+
# Simulate unlocking the door (activating relay)
44+
relay.on()
45+
time.sleep(3) # Keep the door open for 3 seconds
46+
relay.off() # Lock the door again
47+
else:
48+
section_info["status"] = "Denied"
49+
access_log = f"Access denied to {section}. Unauthorized RFID tag."
50+
print(access_log)
51+
else:
52+
access_log = "RFID tag not recognized."
53+
print(access_log)
54+
55+
# Function to generate the web page HTML with the status table
56+
def web_page():
57+
table_rows = ""
58+
for uid, section_info in warehouse_access.items():
59+
row = f"""
60+
<tr>
61+
<td>{section_info['section']}</td>
62+
<td>{section_info['items']}</td>
63+
<td>{section_info['quantity']}</td>
64+
<td>{section_info['status']}</td>
65+
</tr>
66+
"""
67+
table_rows += row
68+
69+
html = """<!DOCTYPE HTML><html>
70+
<head>
71+
<meta name="viewport" content="width=device-width, initial-scale=1">
72+
<style>
73+
:root {
74+
--primary-color: #007acc;
75+
--secondary-color: #f4f7fc;
76+
--text-color: #333;
77+
--bg-gradient: linear-gradient(to bottom, #d4ebf2, #f4f7fc);
78+
}
79+
80+
body {
81+
font-family: Arial, sans-serif;
82+
margin: 0;
83+
padding: 0;
84+
background: var(--bg-gradient);
85+
color: var(--text-color);
86+
transition: all 0.5s ease;
87+
}
88+
header {
89+
background-color: var(--primary-color);
90+
color: white;
91+
padding: 20px;
92+
text-align: center;
93+
font-size: 1.5rem;
94+
font-weight: bold;
95+
}
96+
.container {
97+
max-width: 1000px;
98+
margin: 30px auto;
99+
background: white;
100+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
101+
border-radius: 8px;
102+
overflow: hidden;
103+
transition: background 0.5s ease, color 0.5s ease;
104+
}
105+
h2 {
106+
color: var(--primary-color);
107+
text-align: center;
108+
padding: 20px;
109+
margin: 0;
110+
border-bottom: 2px solid #f2f2f2;
111+
}
112+
table {
113+
width: 100%;
114+
border-collapse: collapse;
115+
margin: 20px 0;
116+
}
117+
th, td {
118+
padding: 12px;
119+
text-align: center;
120+
border: 1px solid #ddd;
121+
}
122+
th {
123+
background-color: var(--primary-color);
124+
color: white;
125+
font-weight: bold;
126+
}
127+
tr:nth-child(even) {
128+
background-color: #f9f9f9;
129+
}
130+
tr:hover {
131+
background-color: #f1f1f1;
132+
}
133+
p {
134+
font-size: 1.2rem;
135+
margin: 20px;
136+
text-align: center;
137+
}
138+
.status-log {
139+
font-weight: bold;
140+
color: var(--primary-color);
141+
}
142+
footer {
143+
background-color: var(--primary-color);
144+
color: white;
145+
text-align: center;
146+
padding: 10px;
147+
position: fixed;
148+
width: 100%;
149+
bottom: 0;
150+
}
151+
.theme-toggle {
152+
background-color: var(--primary-color);
153+
color: white;
154+
border: none;
155+
padding: 10px 20px;
156+
cursor: pointer;
157+
font-size: 1rem;
158+
border-radius: 5px;
159+
margin: 20px;
160+
transition: background 0.5s ease;
161+
}
162+
.theme-toggle:hover {
163+
background-color: #005a99;
164+
}
165+
166+
/* Dark theme variables */
167+
body.dark-theme {
168+
--primary-color: #1a1a2e;
169+
--secondary-color: #16213e;
170+
--text-color: #eaeaea;
171+
--bg-gradient: linear-gradient(to bottom, #0f3460, #1a1a2e);
172+
}
173+
body.dark-theme .container {
174+
background: var(--secondary-color);
175+
}
176+
body.dark-theme table th {
177+
background-color: #0f3460;
178+
}
179+
body.dark-theme table tr:nth-child(even) {
180+
background-color: #16213e;
181+
}
182+
body.dark-theme table tr:hover {
183+
background-color: #1a1a2e;
184+
}
185+
</style>
186+
<script>
187+
// Function to toggle between light and dark themes
188+
function toggleTheme() {
189+
document.body.classList.toggle('dark-theme');
190+
const button = document.getElementById('theme-toggle');
191+
if (document.body.classList.contains('dark-theme')) {
192+
button.innerHTML = 'Switch to Light Theme';
193+
} else {
194+
button.innerHTML = 'Switch to Dark Theme';
195+
}
196+
}
197+
// Function to fetch RFID scan data and update the page
198+
function fetchAccessLog() {
199+
var xhr = new XMLHttpRequest();
200+
xhr.onreadystatechange = function() {
201+
if (this.readyState == 4 && this.status == 200) {
202+
document.getElementById("status_table").innerHTML = this.responseText;
203+
}
204+
};
205+
xhr.open("GET", "/log", true); // Fetch the log from the '/log' route
206+
xhr.send();
207+
}
208+
// Update every 2 seconds
209+
setInterval(fetchAccessLog, 2000);
210+
</script>
211+
</head>
212+
<body>
213+
<header>RFID Warehouse Management System</header>
214+
<div class="container">
215+
<button id="theme-toggle" class="theme-toggle" onclick="toggleTheme()">Switch to Dark Theme</button>
216+
<h2>Warehouse Inventory & RFID Access</h2>
217+
<table>
218+
<tr>
219+
<th>Section</th>
220+
<th>Item Description</th>
221+
<th>Quantity</th>
222+
<th>Status</th>
223+
</tr>
224+
<tbody id="status_table">
225+
""" + table_rows + """
226+
</tbody>
227+
</table>
228+
<p>Status: <span class="status-log" id="access_log">""" + access_log + """</span></p>
229+
</div>
230+
<footer>
231+
&copy; 2024 RFID Management | Designed for Efficiency
232+
</footer>
233+
</body></html>"""
234+
return html
235+
236+
# Function to return the latest access status table in plain text (for AJAX)
237+
def access_status_table():
238+
table_rows = ""
239+
for uid, section_info in warehouse_access.items():
240+
row = f"""
241+
<tr>
242+
<td>{section_info['section']}</td>
243+
<td>{section_info['items']}</td>
244+
<td>{section_info['quantity']}</td>
245+
<td>{section_info['status']}</td>
246+
</tr>
247+
"""
248+
table_rows += row
249+
return table_rows
250+
251+
# Setup ESP32 as Access Point
252+
def setup_ap():
253+
ap = network.WLAN(network.AP_IF) # Set as Access Point
254+
ap.active(True)
255+
ap.config(essid='ESP32-RFID-AccessPoint') # Network SSID
256+
ap.config(authmode=network.AUTH_WPA_WPA2_PSK, password='123456789') # Network password
257+
258+
while not ap.active():
259+
pass # Wait for the AP to activate
260+
print('Access Point Active')
261+
print('AP IP:', ap.ifconfig()[0]) # Display AP IP address
262+
263+
# Start the web server
264+
def start_web_server():
265+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
266+
s.bind(('', 80))
267+
s.listen(5)
268+
269+
while True:
270+
conn, addr = s.accept()
271+
print('Got a connection from %s' % str(addr))
272+
request = conn.recv(1024).decode()
273+
274+
# Log for request parsing
275+
print('Request:', request)
276+
277+
# Serve the main page
278+
if 'GET / ' in request or 'GET /favicon.ico' in request:
279+
response = web_page()
280+
conn.send('HTTP/1.1 200 OK\n')
281+
conn.send('Content-Type: text/html\n')
282+
conn.send('Connection: close\n\n')
283+
conn.sendall(response)
284+
285+
# Serve the access log data (only the table rows)
286+
elif 'GET /log' in request:
287+
response = access_status_table() # Update only the table rows
288+
conn.send('HTTP/1.1 200 OK\n')
289+
conn.send('Content-Type: text/html\n')
290+
conn.send('Connection: close\n\n')
291+
conn.sendall(response)
292+
293+
conn.close()
294+
295+
# Main function for RFID scanning
296+
def rfid_scanner():
297+
global access_log
298+
print("Place card to scan...")
299+
300+
while True:
301+
# Request tag in IDLE state
302+
(stat, tag_type) = rdr.request(rdr.REQIDL)
303+
304+
if stat == rdr.OK:
305+
# Read the UID of the card
306+
(stat, raw_uid) = rdr.anticoll()
307+
308+
if stat == rdr.OK:
309+
# Construct the card ID in a hex format
310+
card_id = "0x%02x%02x%02x%02x" % (raw_uid[0], raw_uid[1], raw_uid[2], raw_uid[3])
311+
print("UID:", card_id)
312+
313+
# Check if the UID has access
314+
check_access(card_id)
315+
316+
# Wait a short time before scanning again
317+
time.sleep(1)
318+
319+
# Run the web server and RFID scanner simultaneously
320+
try:
321+
setup_ap() # Set up the ESP32 as Access Point
322+
323+
# Start the web server in a separate thread
324+
_thread.start_new_thread(start_web_server, ())
325+
326+
# Continue scanning RFID tags infinitely
327+
rfid_scanner()
328+
329+
except KeyboardInterrupt:
330+
print("Program stopped")

0 commit comments

Comments
 (0)