import machine
import time
import dht
import network
from machine import Pin, SoftI2C, PWM
from hcsr04 import HCSR04
from umqtt.simple import MQTTClient
from lcd_api import LcdApi
from i2c_lcd import I2cLcd

# WiFi configuration
WIFI_SSID = "Wokwi-GUEST"
WIFI_PASSWORD = ""

# MQTT configuration
MQTT_CLIENT_ID = ""
MQTT_BROKER = "broker.mqttdashboard.com"
MQTT_PORT = 1883  # Default MQTT port
MQTT_USER = ""
MQTT_PASSWORD = ""
MQTT_TOPIC = "chickenFarm"
MQTT_TOPIC_TEMPT ="Temperature"
MQTT_TOPIC_HUMIDITY ="Humidity"

# Connect to WiFi
print("Connecting to WiFi", end="")
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect(WIFI_SSID, WIFI_PASSWORD)
while not sta_if.isconnected():
    print(".", end="")
    time.sleep(0.1)
print(" Connected!")

# Connect to MQTT Broker server
print("Connecting to MQTT server... ", end="")
client = MQTTClient(MQTT_CLIENT_ID, MQTT_BROKER, port=MQTT_PORT, user=MQTT_USER, password=MQTT_PASSWORD)
client.connect()
print("Connected")

# DHT22 Sensor Configuration
dht_pin = Pin(4)
dht_sensor = dht.DHT22(dht_pin)

# Ultrasonic Sensor Configuration
ultrasonic = HCSR04(trigger_pin=5, echo_pin=18)

# Servo Motor Configuration
servo_pin = Pin(19, Pin.OUT)
servo = PWM(servo_pin, freq=50)

# I2C LCD Configuration
i2c = SoftI2C(scl=Pin(22), sda=Pin(21), freq=100000)
lcd = I2cLcd(i2c, 0x27, 2, 16)

# Function to move servo motor to dispense food
def dispense_food():
    servo.duty(40)  # Adjust duty for 0 degrees (closed)
    time.sleep(1)
    servo.duty(77)  # Adjust duty for 90 degrees
    time.sleep(5)   # Wait for 5 seconds
    servo.duty(40)  # Close again
    time.sleep(1)

# Function to read DHT22 sensor data
def read_dht22():
    dht_sensor.measure()
    temperature = dht_sensor.temperature()
    humidity = dht_sensor.humidity()
    return temperature, humidity

# Function to update LCD display
def update_lcd(temperature, humidity):
    lcd.clear()
    lcd.putstr(f"Temp: {temperature:.1f}C")
    lcd.move_to(0, 1)
    lcd.putstr(f"Hum: {humidity:.1f}%")

def main():
    while True:
        distance = ultrasonic.distance_cm()
        temperature, humidity = read_dht22()
        update_lcd(temperature, humidity)
        if distance <= 15:  # Check if the distance is 15 cm or less
            dispense_food()
            temperature, humidity = read_dht22()
            update_lcd(temperature, humidity)
            sensor_data = {
                'temperature': temperature,
                'humidity': humidity
            }
        update_lcd(temperature, humidity)
        client.publish(MQTT_TOPIC, str(sensor_data))
        time.sleep(2)
        time.sleep(0.1)

if __name__ == '__main__':
    main()