import machine
import time
import dht
from machine import Pin, I2C, PWM
from umqtt.simple import MQTTClient
from esp8266_i2c_lcd import I2cLcd

# MQTT Configuration
mqtt_server = 'broker.hivemq.com'
client_id = 'poultry_farm_001'
topic_pub = b'poultry_farm/sensor_data'

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

# PIR Motion Sensor Configuration
pir_pin = Pin(19, Pin.IN)

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

# I2C LCD Configuration
i2c = I2C(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(115)  # Adjust duty for 180 degrees (open)
    time.sleep(1)
    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}%")

# MQTT Connection Function
def connect_and_subscribe():
    client = MQTTClient(client_id, mqtt_server)
    client.connect()
    return client

def main():
    client = connect_and_subscribe()
    while True:
        if pir_pin.value():
            dispense_food()
            temperature, humidity = read_dht22()
            update_lcd(temperature, humidity)
            sensor_data = {
                'temperature': temperature,
                'humidity': humidity
            }
            client.publish(topic_pub, str(sensor_data))
            time.sleep(2)
        time.sleep(0.1)

if __name__ == '__main__':
    main()