import time
import board
import digitalio
import analogio
import pwmio

# === INPUTS =========================================================================

# Mode Buttons
button_mode1 = digitalio.DigitalInOut(board.GP18)  # Auto Mode
button_mode2 = digitalio.DigitalInOut(board.GP20)  # Manual Mode
button_party_mode = digitalio.DigitalInOut(board.GP19)  # Party Mode 

for btn in (button_mode1, button_mode2, button_party_mode):
    btn.direction = digitalio.Direction.INPUT
    btn.pull = digitalio.Pull.DOWN

# Manual Control Buttons
btn_relay_led = digitalio.DigitalInOut(board.GP21)
btn_blinds = digitalio.DigitalInOut(board.GP22)

for btn in (btn_relay_led, btn_blinds):
    btn.direction = digitalio.Direction.INPUT
    btn.pull = digitalio.Pull.DOWN

# Sensors
pir_sensor = digitalio.DigitalInOut(board.GP10)
pir_sensor.direction = digitalio.Direction.INPUT

ldr_inside = analogio.AnalogIn(board.GP27)
ldr_outside = analogio.AnalogIn(board.GP26)

# === OUTPUTS =========================================================================

# RGB LED
ledR = pwmio.PWMOut(board.GP3, frequency=5000, duty_cycle=0)
ledG = pwmio.PWMOut(board.GP4, frequency=5000, duty_cycle=0)
ledB = pwmio.PWMOut(board.GP5, frequency=5000, duty_cycle=0)

# Servo for blinds
servo_blinds = pwmio.PWMOut(board.GP12, frequency=50)

# Relay for Lamp
lamp_relay = digitalio.DigitalInOut(board.GP11)
lamp_relay.direction = digitalio.Direction.OUTPUT

# === FUNCTIONS ======================================================================

def set_rgb(r, g, b):
    # Convert 0-255 to 0-65535 for PWM
    ledR.duty_cycle = int(r * 257)
    ledG.duty_cycle = int(g * 257)
    ledB.duty_cycle = int(b * 257)

def get_voltage(raw):
    return (raw * 3.3) / 65536

def rtolux(rawval):
    vout = get_voltage(rawval)
    RLDR = (10000 * (3.3 - vout)) / vout
    lux = 500 / (RLDR / 1000)
    return lux

def set_servo(pwm, angle):
    min_duty = 1638
    max_duty = 8192
    pwm.duty_cycle = int(min_duty + (angle / 180) * (max_duty - min_duty))

def open_blinds():
    print("Blinds opened.")
    set_servo(servo_blinds, 90)
    time.sleep(0.5)

def close_blinds():
    print("Blinds closed.")
    set_servo(servo_blinds, 0)
    time.sleep(0.5)

# === MAIN LOOP =======================================================================

current_mode = None
pir_manual_active = False
pir_manual_start_time = 0
state = False
servo_blinds.duty_cycle = 1638

print("System ready. Waiting for mode selection...")

while True:
    # === Mode Selection ===
    if button_mode1.value:
        current_mode = "auto"
        set_rgb(255, 0, 0)  # Red
        print("Auto Mode Activated")
        time.sleep(1)

    elif button_mode2.value:
        current_mode = "manual"
        set_rgb(255, 0, 255)  # Magenta
        print("Manual Mode Activated")   
        time.sleep(1)

    elif button_party_mode.value:
        current_mode = "party"
        set_rgb(255, 165, 0)  # Orange for Party Mode
        close_blinds()  # Open blinds for an energetic atmosphere
        lamp_relay.value = True  # Turn on main lighting
        print("Party Mode Activated - Bright Lights & close Blinds")   
        time.sleep(1)

    # === AUTO MODE ===
    if current_mode == "auto":
        ldr1 = sum(rtolux(ldr_inside.value) for _ in range(10)) / 10
        ldr2 = sum(rtolux(ldr_outside.value) for _ in range(10)) / 10
        print(f"LDR Inside: {ldr1:.2f} Lux | Outside: {ldr2:.2f} Lux")

        if ldr1 < ldr2:
            open_blinds()
        elif ldr1 > ldr2:
            close_blinds()

        if pir_sensor.value:
            print("Motion detected! Turning lamp ON.")
            lamp_relay.value = True
            time.sleep(3)
        else:
            lamp_relay.value = False
            time.sleep(0.5)

    # === MANUAL MODE ===
    if current_mode == "manual":
        if btn_blinds.value:
            state = not state
            if state:
                open_blinds()
                print("Manual Mode: Blinds opened.")
            else:
                close_blinds()
                print("Manual Mode: Blinds closed.")
            while btn_blinds.value:
                pass  # Wait for button release
            time.sleep(0.5)

        if btn_relay_led.value:
            state = not state
            lamp_relay.value = state
            print(f"Manual Mode: Lamp {'ON' if state else 'OFF'}")
            while btn_relay_led.value:
                pass  # Wait for button release
            time.sleep(0.5)

    # === PARTY MODE ===
    if current_mode == "party":
        close_blinds()
        # Flashing RGB lights for party effect
        for _ in range(10):
            set_rgb(255, 0, 0)  # Red
            time.sleep(0.3)
            set_rgb(0, 255, 0)  # Green
            time.sleep(0.3)
            set_rgb(0, 0, 255)  # Blue
            time.sleep(0.3)

        if pir_sensor.value:
            print("Party Mode: Motion detected, LED blinking!")
            for _ in range(30):
                lamp_relay.value = True  # LED ON
                time.sleep(0.2)
                lamp_relay.value = False  # LED OFF
                time.sleep(0.2)
        else:
            set_rgb(255, 165, 0)  # Reset to orange (Party Mode default)
            lamp_relay.value = True  # Keep LED ON
            time.sleep(0.5)

    time.sleep(0.1)
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT
NOCOMNCVCCGNDINLED1PWRRelay Module