from machine import Pin, PWM, RTC
from time import sleep
import network
import urequests
import ntptime
import time
# --- Keypad Setup ---
keypad_rows = [Pin(i, Pin.OUT) for i in [19, 18, 5, 17]]
keypad_cols = [Pin(i, Pin.IN, Pin.PULL_UP) for i in [16, 4, 0, 2]]
keypad_keys = [
['1', '2', '3', 'A'],
['4', '5', '6', 'B'],
['7', '8', '9', 'C'],
['*', '0', '#', 'D']
]
# Passcodes
passcodes = {
"1234": "Elli",
"4321": "Alex",
"2468": "Chris"
}
# Door and motion
door = Pin(23, Pin.OUT)
pir = Pin(26, Pin.IN)
# Servo Motor
servo = PWM(Pin(32), freq=50)
servo.duty(0) # off by default
# Relay Module (controls door lock)
relay = Pin(33, Pin.OUT)
relay.value(0) # off by default
# Network and Telegram
WIFI_NAME = 'Wokwi-GUEST'
WIFI_PASSWORD = ''
TELEGRAM_USERNAME = "@abchhhhu"
TELEGRAM_TEXT_TEMPLATE = "https://api.callmebot.com/text.php?user={user}&text={text}&lang=en"
wifi = network.WLAN(network.STA_IF)
wifi.active(True)
wifi.connect(WIFI_NAME, WIFI_PASSWORD)
while not wifi.isconnected():
print("Connecting to WiFi...")
sleep(1)
print("✅ Connected to WiFi!")
# Sync RTC with NTP
try:
ntptime.settime()
except:
print("⚠️ Failed to sync time with NTP")
# --- RTC for timestamp ---
rtc = RTC()
weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
def get_time_string():
t = time.localtime(time.time() + 10 * 3600) # UTC+10 for Sydney
weekday = weekdays[t[6]]
month = months[t[1]-1]
hour = t[3] % 12
hour = 12 if hour == 0 else hour
ampm = "am" if t[3] < 12 else "pm"
return "{:02d}:{:02d} {} on {}, {} {:02d}".format(hour, t[4], ampm, weekday, month, t[2])
def send_telegram_alert(msg):
encoded = msg.replace(" ", "%20").replace(",", "%2C").replace("?", "%3F")
try:
urequests.get(TELEGRAM_TEXT_TEMPLATE.format(user=TELEGRAM_USERNAME, text=encoded)).close()
print("✅ Sent via Telegram: ", msg)
except:
print("❌ Failed to send via Telegram: ", msg)
def read_keypad():
for r in range(4):
for row in keypad_rows:
row.value(1)
keypad_rows[r].value(0)
for c in range(4):
if keypad_cols[c].value() == 0:
key = keypad_keys[r][c]
print("🔘 Keypad pressed:", key)
while keypad_cols[c].value() == 0:
sleep(0.01)
sleep(0.1)
return key
return None
# --- Main Loop ---
entered_code = ""
fail_attempts = 0
while True:
key = read_keypad()
if key:
if key == '#':
if entered_code in passcodes:
name = passcodes[entered_code]
open_time = get_time_string()
send_telegram_alert(f"🔓 My Home: The front door was unlocked by {name} at {open_time}.")
print("✅ Door unlocked for:", name)
door.value(1)
servo.duty(35) # open position
relay.value(1) # activate relay
sleep(3) # wait before re-lock
door.value(0)
servo.duty(0) # close position
relay.value(0) # deactivate relay
fail_attempts = 0 # reset counter on success
else:
fail_attempts += 1
print("❌ Invalid passcode entered")
if fail_attempts > 2:
open_time = get_time_string()
send_telegram_alert(f"🚨 EMERGENCY: Multiple failed unlock attempts detected at the front door at {open_time}! 🚨 Alarm triggered")
print("🚨 Alarm triggered!")
relay.value(1)
sleep(5)
relay.value(0)
else:
open_time = get_time_string()
send_telegram_alert(f"🚨 My Home: Someone attempted to unlock the front door with an incorrect passcode at {open_time}.")
entered_code = ""
elif key == '*':
entered_code = ""
print("🔄 Code entry reset")
else:
entered_code += key
print("🔢 Code so far:", entered_code)
sleep(0.05)
*1234#: Elli
*4321#: Alex
*2468#: Chris