from machine import Pin, PWM, SoftI2C, time_pulse_us
from time import sleep_ms
import ssd1306, framebuf
import machine
import time
import network
import dht
import ujson
from umqtt.simple import MQTTClient
import umqtt.simple
import buzzer
import HCSR04, SG90
#finisci servo motore
#risolvi problema storico
#risolvi problema dei 10s al bottone
prev_erog= "0"
prev_erogMax= 4
i2c = SoftI2C(sda=Pin(21), scl=Pin(22))
display = ssd1306.SSD1306_I2C(128, 64, i2c)
b = buzzer.BUZZER(23)
servo=SG90.SERVO(4)
def current_time():
time_tuple = time.localtime()
time_dict = {
'anno': time_tuple[0],
'mese': time_tuple[1],
'giorno': time_tuple[2],
'ora': time_tuple[3],
'minuto': time_tuple[4],
'secondo': time_tuple[5]
}
return time_dict
def next_time(tot_ore):
time_tuple = time.localtime()
time_dict = {
'anno': time_tuple[0],
'mese': time_tuple[1],
'giorno': time_tuple[2],
'ora': time_tuple[3],
'minuto': time_tuple[4],
'secondo': time_tuple[5]
}
time_dict['ora'] += tot_ore
if(time_dict['ora'] >=24):
time_dict['ora'] = time_dict['ora'] -24
time_dict['giorno'] += 1
#time_dict['minuto'] += 1
return time_dict
def next_reset():
def next_time(tot_ore):
time_tuple = time.localtime()
time_dict = {
'anno': time_tuple[0],
'mese': time_tuple[1],
'giorno': time_tuple[2],
'ora': time_tuple[3],
'minuto': time_tuple[4],
'secondo': time_tuple[5]
}
if (time_dict['giorno'] == 31 and (time_dict['mese'] == 1 or time_dict['mese'] == 3 or time_dict['mese'] == 5 or time_dict['mese'] == 7 or time_dict['mese'] == 8 or time_dict['mese'] == 10 ) ):
time_dict['giorno'] = 1
time_dict['mese'] +=1
elif(time_dict['giorno'] == 30 and (time_dict['mese'] == 4 or time_dict['mese'] == 6 or time_dict['mese'] == 9 or time_dict['mese'] == 11) ):
time_dict['giorno'] = 1
time_dict['mese'] +=1
elif(time_dict['mese'] == 2 and time_dict['giorno']==28):
time_dict['giorno'] = 1
time_dict['mese'] +=1
elif (time_dict['mese'] == 12 and time_dict['giorno'] == 31 ):
time_dict['anno']+=1
time_dict['mese']=1
time_dict['giorno']=1
time_dict['giorno'] += 1
return time_dict
def on_message(topic, msg):
global erogazione_ogni, erogazioni_effettuate, erogazioni_massime, ora_prossimaErogazione
if topic == MQTT_TOPIC:
erogazione_ogni = float(msg.decode('utf-8'))
#print(erogazione_ogni)
erogazioni_massime=int(24/erogazione_ogni)
#print(erogazioni_massime)
ora_prossimaErogazione=next_time(erogazione_ogni)
#imposta il programma
elif topic == MQTT_EROGA:
if msg == b'1':
if erogazioni_effettuate >= erogazioni_massime:
#invia notifica alla dashboard
msg = ujson.dumps({
"erogMax": "Erogazioni giornaliere terminate"
})
client.publish(MQTT_ALLERT, msg)
return
eroga()
MQTT_CLIENT_ID = "myAppLogger1"
MQTT_BROKER = "test.mosquitto.org"
MQTT_USER = ""
MQTT_PASSWORD = ""
MQTT_TOPIC = b'unisa_iot/project/09/routine'
MQTT_EROGA = b'unisa_iot/project/09/erogaOra'
MQTT_ALLERT = b'unisa_iot/project/09/allert'
MQTT_STORICO = b'unisa_iot/project/09/routine/storico'
MQTT_CROCC = b'unisa_iot/project/09/crocc'
print("Connecting to WiFi", end="")
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect('Wokwi-GUEST', '')
while not sta_if.isconnected():
print(".", end="")
time.sleep(0.1)
print(" Connected!")
print("Connecting to MQTT server... ", end="")
client = MQTTClient(MQTT_CLIENT_ID, MQTT_BROKER)
client.set_callback(on_message)
client.connect()
client.subscribe(MQTT_TOPIC)
client.subscribe(MQTT_EROGA)
print("Connected!")
ultrasonic = HCSR04.HCSR04(trigger_pin=26, echo_pin=27, echo_timeout_us=1000000)
duty = 512
wait = 150
start=0
erogazione_ogni = 6
erogazioni_effettuate = 0
erogazioni_massime=4
def erogabtn(self):
global start, erogazioni_massime
current=time.ticks_ms()
#occorre un metodo per fare la differenza perchè potrebbe verificarsi un rollover
delta = time.ticks_diff(current, start)
if delta < 300:
return
start = current
eroga()
def eroga():
global wait, duty, song, erogazioni_effettuate, erogazione_ogni, prev_erog, servo, ora_prossimaErogazione
if erogazioni_effettuate >= erogazioni_massime :
display.opTerminate()
return
elif erogazioni_effettuate != prev_erog:
return
while(ultrasonic.distance_cm()>20):
display.text("Aspetto il cane",5,32)
display.show()
#print(ultrasonic.distance_cm())
time.sleep(1)
display.erogIncorso()
servo.set_angle(180) #apro la valvola
b.play(song,wait,duty) #attivo il buzzer
servo.set_angle(0) #chiudo la valvola
#modifico ora prossima erogazione
ora_ultimaErogazione=current_time()
ora_prossimaErogazione=next_time(erogazione_ogni)
#print(ora_prossimaErogazione, ora_ultimaErogazione)
display.fill(0)
display.show()
erogazioni_effettuate=erogazioni_effettuate+1
#servo=PWM(Pin(4),freq=50,duty=26)
btn = Pin(2, Pin.IN, Pin.PULL_DOWN)
btn.irq(handler=erogabtn, trigger=Pin.IRQ_RISING)
red=Pin(33, Pin.OUT)
green=Pin(32, Pin.OUT)
red.off()
green.off()
song = buzzer.mario
data_reset = next_reset()
ora_prossimaErogazione=next_time(erogazione_ogni)
ora_lastProssimaErogazione=ora_prossimaErogazione
pre_level = 0
# Avvia il loop di gestione degli eventi MQTT
while True:
client.check_msg()
#controllo cambio di valore di erogazioni effettuate e delle erogazioi
if (erogazioni_effettuate != prev_erog or erogazioni_massime != prev_erogMax or ora_lastProssimaErogazione != ora_prossimaErogazione ):
message = ujson.dumps({
"erogEffettuate": "{}/{}".format(erogazioni_effettuate,erogazioni_massime),
"ora_nextErog": "il giorno {:02}/{:02} alle {:02}:{:02}:{:02}".format(ora_prossimaErogazione['giorno'],ora_prossimaErogazione['mese'],ora_prossimaErogazione['ora'], ora_prossimaErogazione['minuto'], ora_prossimaErogazione['secondo'])
})
client.publish(MQTT_EROGA, message)
prev_erog = erogazioni_effettuate
prev_erogMax=erogazioni_massime
ora_lastProssimaErogazione=ora_prossimaErogazione
if(erogazioni_effettuate<erogazioni_massime):
green.on()
red.off()
elif(erogazioni_effettuate==erogazioni_massime):
green.off()
red.on()
# Ottieni l'ora corrente
ora_corrente = current_time()
if(current_time() == data_reset ):
erogazioni_effettuate = 0 #resetto a 0 le erogazioni alla mezzanotte
data_reset=next_reset()
print("reset")
elif (current_time() == ora_prossimaErogazione):
eroga()
level= 80 - ultrasonic.distance_cm()
if(level != pre_level):
pre_level=level
livelloCroccantini= (100 * level )/80
message = ujson.dumps({
"Crocc": livelloCroccantini})
client.publish(MQTT_CROCC, message)
#inserire codice per rilevamento livello croccantini
#codice per vedere se il cane ha mangiato
time.sleep(0.1)