from machine import Pin, SoftI2C
from machine import Pin, PWM
from lcd_api import LcdApi
from i2c_lcd import I2cLcd
from SSD1306 import SSD1306_I2C
from hcsr04 import HCSR04
from time import sleep

i2c_lcd = SoftI2C(scl=Pin(22), sda=Pin(21), freq=10000)

I2C_ADDR_LCD = 0x27
totalRows = 4
totalColumns = 16

lcd = I2cLcd(i2c_lcd, I2C_ADDR_LCD, totalRows, totalColumns)
sensor = HCSR04(trigger_pin=5, echo_pin=18, echo_timeout_us=100000)

trig_pins = [12, 14]  # Trig pins for ultrasonic sensors
echo_pins = [13, 15]  # Echo pins for ultrasonic sensors
ultrasonics = [HCSR04(trigger_pin=trig_pins[i], echo_pin=echo_pins[i]) for i in range(2)]

# Initialize Servo Motors
servo_pins = [32, 33]  # Pins for servo motors
servos = [PWM(Pin(pin)) for pin in servo_pins]

# Initialize IR Sensors
ir_pins = [25, 26]  # Pins for IR sensors
irs = [Pin(pin, Pin.IN) for pin in ir_pins]

# Initialize LED Indicators
led_pins = [27, 14]  # Pins for LED indicators
leds = [Pin(pin, Pin.OUT) for pin in led_pins]

# Function to measure distance using ultrasonic sensors
def measure_distance(sensor):
    return sensor.distance_cm()

# Function to control servo motor angle
def move_servo(servo, angle):
    duty = int((angle / 180) * 1023)
    servo.duty(duty)

# Function to check IR sensor status
def check_ir(sensor):
    return sensor.value()

# Function to control LED indicators
def control_led(led, state):
    led.value(state)

# Function to display message on LCD
def display_lcd(line1, line2):
    lcd.move_to(0, 0)
    lcd.putstr(line1)
    lcd.move_to(0, 1)
    lcd.putstr(line2)

while True:
    # Measure distances from ultrasonic sensors
    distances = [measure_distance(sensor) for sensor in ultrasonics]

    # Check IR sensors
    ir_states = [check_ir(sensor) for sensor in irs]

    # Implement parking logic
    for i in range(2):
        if ir_states[i] == 1:
            move_servo(servos[i], 60)
            control_led(leds[i], 1)
        else:
            move_servo(servos[i], 0)
            control_led(leds[i], 0)

    # Display status on LCD
    display_lcd("Slot 1: {} cm".format(distances[0]), "Slot 2: {} cm".format(distances[1]))

    sleep(0.1)  # Adjust delay as needed