import time
import utime
time.sleep(0.1) # Wait for USB to become ready

print("Hello, Pi Pico W!")

from machine import PWM, Pin

servo = PWM(Pin(22))
servo.freq(50)

code_override_btn = Pin(0, Pin.IN, Pin.PULL_UP)

green_led = Pin(4, Pin.OUT)
red_led = Pin(5, Pin.OUT)

def toggle_leds(val):
    if val == 'red':
        green_led.value(0)
        red_led.value(1)
    elif val == 'green':
        red_led.value(0)
        green_led.value(1)

red_led.value(1)

sensor_status_dictionary = {
    'system_ok': 1,
    'system_not_ok': 0
}

def set_servo_angle(angle):
    min_duty = 1000  # Adjust the minimum pulse width (may need to lower)
    max_duty = 8000  # Adjust the maximum pulse width (may need to lower)
    duty = int(min_duty + (angle / 180) * (max_duty - min_duty))
    servo.duty_u16(duty)

set_servo_angle(15)
time.sleep(1)
set_servo_angle(180)
time.sleep(1)
set_servo_angle(15)
time.sleep(1)

# Define the GPIO pins connected to the keypad rows and columns
rows = [Pin(14, Pin.IN, Pin.PULL_UP), 
        Pin(15, Pin.IN, Pin.PULL_UP), 
        Pin(16, Pin.IN, Pin.PULL_UP), 
        Pin(17, Pin.IN, Pin.PULL_UP)]
        
cols = [Pin(18, Pin.OUT), 
        Pin(19, Pin.OUT), 
        Pin(20, Pin.OUT), 
        Pin(21, Pin.OUT)]

# Define the keypad mapping
keypad_mapping = [
    ['1', '2', '3', 'A'],
    ['4', '5', '6', 'B'],
    ['7', '8', '9', 'C'],
    ['*', '0', '#', 'D']
]

# Predefined correct pin code
correct_pin = "1234"
entered_pin = ""

# Function to read keypad input
def read_keypad():
    for col_index in range(4):
        # Set the current column to LOW
        cols[col_index].value(0)

        for row_index in range(4):
            # If the button is pressed (LOW)
            if rows[row_index].value() == 0:
                # Wait for key release to prevent bouncing
                while rows[row_index].value() == 0:
                    pass
                return keypad_mapping[row_index][col_index]

        # Set the current column back to HIGH
        cols[col_index].value(1)
    
    return None

def red_strobe():
    duration = 5
    start_time = time.time()
    for i in range(100000):
        red_led.value(0)
        time.sleep(0.1)
        red_led.value(1)
        time.sleep(0.1)
        if time.time() - start_time >= duration:
            return None

# Function to check the entered pin
def check_pin():
    global entered_pin
    time.sleep(0.5)
    if entered_pin == correct_pin:
        toggle_leds('green')
        set_servo_angle(180)  # Adjust angle to unlock
        print("Access Granted!")
        time.sleep(5)
        set_servo_angle(15)  # Reset the servo to default position
        toggle_leds('red')
    else:
        red_strobe()
        print("Access Denied!")
        time.sleep(0.5)

go = True
system_secure = True

while go == True:
    key = read_keypad()
    if key:
        if key == '#':  # '#' to confirm the entered pin
            print("Checking pin:", entered_pin)
            check_pin()  # Call the function to check the pin
            entered_pin = ""  # Reset the entered pin after checking
        elif key == '*':  # '*' to reset the entered pin
            print("Pin reset.")
            entered_pin = ""
        else:
            entered_pin += key
            print("Entered pin so far:", entered_pin)