import time
import ujson
import network
import json
from time import sleep
from pump import PUMP
from environment_sensor import ENVIRONMENT_SENSOR
from cistern import CISTERN
from machine import Pin, PWM
from oled import OLED
from ldr import LDR
from fan import FAN
from door import DOOR
from ground_sensor import GROUND_SENSOR
from mqtt_client import MQTT
"""PARAMETERS DEFINITION"""
#WI-FI params
WIFI_SSID = 'Simone'
WIFI_PASSWORD = 'simonefaraulo'
# MQTT Server parameters
MQTT_CLIENT_ID = "gruppo09"
MQTT_BROKER = "test.mosquitto.org"
MQTT_USER = ""
MQTT_PASSWORD = ""
#MQTT topic to witch the client must publish informations
MQTT_GROUND_HUMIDITY = "SmartGreenhouse/Ground/Humidity"
MQTT_ENVIRONMENT_TEMP = "SmartGreenhouse/Environment/Temp"
MQTT_ENVIRONMENT_HUMIDITY = "SmartGreenhouse/Environment/Humidity"
MQTT_CISTERN_LEVEL = "SmartGreenhouse/Irrigation/Cistern"
MQTT_OUTSIDE_LUX = "SmartGreenhouse/External/Lum"
MQTT_FAN_STATE = "SmartGreenhouse/Ventilation/Fan"
MQTT_PUMP_STATE = "SmartGreenhouse/Irrigation/Pump"
MQTT_LED_STATE = "SmartGreenhouse/Lights/LED"
MQTT_DOOR_STATE = "SmartGreenhouse/DoorState"
#MQTT topic to which the client must subscribe
MQTT_SUBSCRIBE_TOPIC = {
"MQTT_IRRIGATION_MANUALCONTROL" : b'SmartGreenhouse/Irrigation/ManualState',
"MQTT_IRRIGATION_MANUALPUMP" : b'SmartGreenhouse/Irrigation/ManualPump',
"MQTT_IRRIGATION_HUMIDITY" : b'SmartGreenhouse/Irrigation/Humidity',
"MQTT_FAN_MANUALSTATE" : b'SmartGreenhouse/Ventilation/ManualFan',
"MQTT_FAN_MANUALCONTROL" : b'SmartGreenhouse/Ventilation/ManualState',
"MQTT_FAN_ACTIVATIONTEMP" : b'SmartGreenhouse/Ventilation/Temp',
"MQTT_LIGHTS_MANUALCONTROL" : b'SmartGreenhouse/Lights/ManualState',
"MQTT_LIGHTS_MANUALLED" : b'SmartGreenhouse/Lights/ManualLED',
"MQTT_LIGHTS_LEVEL" : b'SmartGreenhouse/Lights/Lum',
"MQTT_RESET_SYSTEM" : b'SmartGreenhouse/Restart'
}
#dict of value that comes from sensors and actuators state to publish on the respective topic: k = topic, v = value to publish on the topic
MQTT_PUBLISH_VALUE = {
MQTT_GROUND_HUMIDITY : None,
MQTT_ENVIRONMENT_TEMP : None,
MQTT_ENVIRONMENT_HUMIDITY : None,
MQTT_CISTERN_LEVEL: None,
MQTT_OUTSIDE_LUX : None,
MQTT_FAN_STATE : None,
MQTT_PUMP_STATE : None,
MQTT_LED_STATE : None,
MQTT_DOOR_STATE : None
}
SENSORS_ACTUAL_VALUE = {
MQTT_GROUND_HUMIDITY : None,
MQTT_ENVIRONMENT_TEMP : None,
MQTT_ENVIRONMENT_HUMIDITY : None,
MQTT_CISTERN_LEVEL: None,
MQTT_OUTSIDE_LUX : None,
}
#dict of parameter that are setted based on the informations that comes from the broker and from the system computation
SYSTEM_PARAMS = {
"BOOT" : True,
"DOOR_OPEN": False,
"PRINT_SYS_STATE" : True,
"CRITICAL_CISTERN_LEVEL" : 10,
"HUMIDITY_CRITICAL_LEVEL" : 10,
"MANUAL_IRRIGATION_CONTROL" : False,
"MANUAL_IRRIGATION_PUMP": False,
"MANUAL_FAN_CONTROL" : False,
"MANUAL_FAN_STATE": False,
"MANUAL_LIGHTS_CONTROL" : False,
"MANUAL_LIGHTS_LEVEL": 0,
"LIGHTS_OFF_LEVEL": 20,
"BLOCK_IRRIGATION_FOR_CRITICAL_CISTERN_LEVEL": False,
"RESTART_SYSTEM": False,
"FAN_ACTIVATION_TEMP": 30,
"PUMP_CICLE": False
}
#irq_lock setted true when the system is restarted
IRQ_LOCK = False
#CISTERN parameters
CISTERN_TRIGGER_PIN = 26
CISTERN_ECHO_PIN = 25
CISTERN_HEIGHT = 30
#PUMP parameters
PUMP_PIN = 2
#ENVIRONMENT_SENSOR parameters
ENVIRONMENT_SENSOR_PIN = 4
#PHOTO_RESISTOR parameters
PHOTO_RESISTOR_PIN = 35
PHOTO_RESISTOR_MIN_VALUE = 0
PHOTO_RESISTOR_MAX_VALUE = 100
#LED_ZONE_1 parameters
LED1_PIN = 13
LED1_FREQ = 50
#LED_ZONE_2 parameters
LED2_PIN = 19
LED2_FREQ = 50
#FAN parameters
FAN_PIN = 14
#GROUND_SENSOR parameters
GROUND_SENSOR_PIN = 33
GROUND_SENSOR_MAX_READ = 2800
GROUND_SENSOR_MIN_READ = 500
GROUND_SENSOR_MIN_VALUE = 0
GROUND_SENSOR_MAX_VALUE = 100
#OLED_DISPLAY parameters
OLED_WIDTH = 128
OLED_HEIGHT = 64
OLED_SLC_PIN = 22
OLED_SDA_PIN = 32
OLED_FILL = 0
OLED_COLOR = 1
#DOOR parameters
DOOR_PIN = 23
DOOR_CLOSE_ANGLE = 180
DOOR_OPEN_ANGLE = 110
#RESET_BTN parameters
RESET_BTN_PIN = 15
#DOOR_BTN parameters
DOOR_BTN_PIN = 34
#BOUNCING BTNs VAR
LAST_RESET = 0
DELTA_MAX_RESET = 300
LAST_DOOR = 0
DELTA_MAX_DOOR = 1000
#DASHBOARD max and min value sent and recived on all topics
DASH_MAX_VAL = 100
DASH_MIN_VAL = 0
"""IMPLEMENTATION OF SYSTEM LOGIC"""
#INSTANTIATION OF THE SYSTEM OBJECTS
reset_btn = Pin(RESET_BTN_PIN, Pin.IN, Pin.PULL_DOWN)
door_btn = Pin(DOOR_BTN_PIN, Pin.IN, Pin.PULL_DOWN)
cistern = CISTERN(CISTERN_TRIGGER_PIN, CISTERN_ECHO_PIN, CISTERN_HEIGHT)
pump = PUMP(PUMP_PIN)
environment_sensor = ENVIRONMENT_SENSOR(ENVIRONMENT_SENSOR_PIN)
photo_resistor = LDR(PHOTO_RESISTOR_PIN, PHOTO_RESISTOR_MIN_VALUE, PHOTO_RESISTOR_MAX_VALUE)
ground_sensor = GROUND_SENSOR(GROUND_SENSOR_PIN, GROUND_SENSOR_MIN_VALUE, GROUND_SENSOR_MAX_VALUE, GROUND_SENSOR_MAX_READ, GROUND_SENSOR_MIN_READ)
client = MQTT(MQTT_CLIENT_ID, MQTT_BROKER)
oled = OLED(OLED_WIDTH, OLED_HEIGHT, OLED_SLC_PIN, OLED_SDA_PIN)
fan = FAN(FAN_PIN)
door = DOOR(DOOR_PIN, DOOR_CLOSE_ANGLE, DOOR_OPEN_ANGLE)
led1 = PWM(Pin(LED1_PIN, Pin.OUT), freq=LED1_FREQ)
led2 = PWM(Pin(LED2_PIN, Pin.OUT), freq=LED2_FREQ)
led1.duty(0)
led2.duty(0)
#START THE CONNECTIVITY PROCEDURE
oled.print_booting_info(OLED_FILL, OLED_COLOR)
#IMPORTED IN THE BOOT FILE FOR THE WI-FI CONNECTION
def wifi_connect():
global oled
global OLED_COLOR
try:
shift_point = 0
print("Connecting to WiFi", end="")
oled.print_line("Connecting", 0, 1, OLED_COLOR)
oled.print_line_no_fill("to Wifi", 0, 10, OLED_COLOR)
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="")
oled.print_line_no_fill(".", 53 + shift_point, 10, OLED_COLOR)
time.sleep(0.1)
shift_point = shift_point + 6
print(" Connected!")
oled.print_line_no_fill("Connected!", 0, 20, OLED_COLOR)
except OSError as ex:
print("Failure connecting to WiFi!!")
oled.print_line("Not Connected!", 0, 1, OLED_COLOR)
for i in range(10, 0, -1):
oled.fill_rect(60, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Retrying in " + str(i) + "s", 0, 10, OLED_COLOR)
time.sleep(1)
wifi_connect()
#DEFINING ALL THE PROCEDURES
def restart_procedure():
global MQTT_PUBLISH_VALUE, SYSTEM_PARAMS, SENSORS_ACTUAL_VALUE
global MQTT_GROUND_HUMIDITY
global MQTT_ENVIRONMENT_TEMP
global MQTT_ENVIRONMENT_HUMIDITY
global MQTT_CISTERN_LEVEL
global MQTT_OUTSIDE_LUX
global MQTT_FAN_STATE
global MQTT_DOOR_STATE
global MQTT_PUMP_STATE
global OLED_COLOR
global led, pump, fan, oled, client, door
oled.print_line("Restarting the", 0, 1, OLED_COLOR)
oled.print_line_no_fill("system", 0, 10, OLED_COLOR)
shift_point = 0
pump.stop_pump()
led.duty(0)
fan.stop_fan()
door.close_door()
try:
client.publish(MQTT_GROUND_HUMIDITY, ujson.dumps({"humidity" : 0}))
client.publish(MQTT_ENVIRONMENT_TEMP, ujson.dumps({"temp" : 0}))
client.publish(MQTT_ENVIRONMENT_HUMIDITY, ujson.dumps({"humidity" : 0}))
client.publish(MQTT_CISTERN_LEVEL, ujson.dumps({"cistern_level" : 0}))
client.publish(MQTT_OUTSIDE_LUX, ujson.dumps({"light" : 0}))
client.publish(MQTT_FAN_STATE, ujson.dumps({"fan" : 0}))
client.publish(MQTT_PUMP_STATE, ujson.dumps({"pump" : 0}))
client.publish(MQTT_LED_STATE, ujson.dumps({"light" : 0}))
client.publish(MQTT_DOOR_STATE, ujson.dumps({"door" : 0}))
except OSError as e:
print("Error during the sensors data pubblication: ", e)
while shift_point < 28:
oled.print_line_no_fill(".", 45 + shift_point, 10, OLED_COLOR)
time.sleep(0.1)
shift_point = shift_point + 6
SYSTEM_PARAMS = {
"BOOT" : True,
"DOOR_OPEN": False,
"PRINT_SYS_STATE" : True,
"CRITICAL_CISTERN_LEVEL" : 10,
"HUMIDITY_CRITICAL_LEVEL" : 10,
"MANUAL_IRRIGATION_CONTROL" : False,
"MANUAL_IRRIGATION_PUMP": False,
"MANUAL_FAN_CONTROL" : False,
"MANUAL_FAN_STATE": False,
"MANUAL_LIGHTS_CONTROL" : False,
"MANUAL_LIGHTS_LEVEL": 0,
"LIGHTS_OFF_LEVEL": 20,
"BLOCK_IRRIGATION_FOR_CRITICAL_CISTERN_LEVEL": False,
"RESTART_SYSTEM": False,
"FAN_ACTIVATION_TEMP": 30,
"PUMP_CICLE": False
}
MQTT_PUBLISH_VALUE = {
MQTT_GROUND_HUMIDITY : None,
MQTT_ENVIRONMENT_TEMP : None,
MQTT_ENVIRONMENT_HUMIDITY : None,
MQTT_CISTERN_LEVEL: None,
MQTT_OUTSIDE_LUX : None,
MQTT_FAN_STATE : None,
MQTT_PUMP_STATE : None,
MQTT_LED_STATE : None,
MQTT_DOOR_STATE : None
}
SENSORS_ACTUAL_VALUE = {
MQTT_GROUND_HUMIDITY : None,
MQTT_ENVIRONMENT_TEMP : None,
MQTT_ENVIRONMENT_HUMIDITY : None,
MQTT_CISTERN_LEVEL: None,
MQTT_OUTSIDE_LUX : None,
}
def auto_fan_control():
global SYSTEM_PARAMS, MQTT_PUBLISH_VALUE, MQTT_FAN_STATE
global OLED_COLOR, OLED_FILL
global fan, oled, client
oled.fill_rect(35, 20, 30, 10, OLED_FILL)
oled.print_line_no_fill("AUT=>", 35, 20, OLED_COLOR)
actual_temp = environment_sensor.get_last_temperature()
if SYSTEM_PARAMS["FAN_ACTIVATION_TEMP"] != None and actual_temp > SYSTEM_PARAMS["FAN_ACTIVATION_TEMP"]:
fan.start_fan()
oled.fill_rect(80, 20, 60, 10, OLED_FILL)
oled.print_line_no_fill("ON", 80, 20, OLED_COLOR)
MQTT_PUBLISH_VALUE[MQTT_FAN_STATE] = ujson.dumps({"fan" : 1})
try:
client.publish(MQTT_FAN_STATE, MQTT_PUBLISH_VALUE[MQTT_FAN_STATE])
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Published", 55, 10, OLED_COLOR)
except OSError as e:
print("Error during the sensors data pubblication: ", e)
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Error", 55, 10, OLED_COLOR)
else:
fan.stop_fan()
oled.fill_rect(80, 20, 60, 10, OLED_FILL)
oled.print_line_no_fill("OFF", 80, 20, OLED_COLOR)
MQTT_PUBLISH_VALUE[MQTT_FAN_STATE] = ujson.dumps({"fan": 0})
try:
client.publish(MQTT_FAN_STATE, MQTT_PUBLISH_VALUE[MQTT_FAN_STATE])
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Published", 55, 10, OLED_COLOR)
except OSError as e:
print("Error during the sensors data pubblication: ", e)
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Error", 55, 10, OLED_COLOR)
def auto_irrigation_control():
global SYSTEM_PARAMS, MQTT_PUBLISH_VALUE, MQTT_PUMP_STATE
global OLED_COLOR, OLED_FILL
global oled, pump
oled.fill_rect(40, 30, 30, 10, OLED_FILL)
oled.print_line_no_fill("AUT=>", 40, 30, OLED_COLOR)
actual_ground_humidity = ground_sensor.get_last_value()
if actual_ground_humidity < SYSTEM_PARAMS["HUMIDITY_CRITICAL_LEVEL"]:
print("Starting pump...", end="")
pump.start_pump()
oled.fill_rect(80, 30, 30, 10, OLED_FILL)
oled.print_line_no_fill("ON", 80, 30, OLED_COLOR)
MQTT_PUBLISH_VALUE[MQTT_PUMP_STATE] = ujson.dumps({"pump": 1})
try:
client.publish(MQTT_PUMP_STATE, MQTT_PUBLISH_VALUE[MQTT_PUMP_STATE])
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Published", 55, 10, OLED_COLOR)
except OSError as e:
print("Error during the sensors data pubblication: ", e)
ooled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Error", 55, 10, OLED_COLOR)
else:
pump.stop_pump()
oled.fill_rect(80, 30, 30, 10, OLED_FILL)
oled.print_line_no_fill("OFF", 80, 30, OLED_COLOR)
MQTT_PUBLISH_VALUE[MQTT_PUMP_STATE] = ujson.dumps({"pump": 0})
try:
client.publish(MQTT_PUMP_STATE, MQTT_PUBLISH_VALUE[MQTT_PUMP_STATE])
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Published", 55, 10, OLED_COLOR)
except OSError as e:
print("Error during the sensors data pubblication: ", e)
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Error", 55, 10, OLED_COLOR)
def auto_light_control():
global MQTT_PUBLISH_VALUE, MQTT_LED_STATE
global OLED_COLOR, OLED_FILL
global led, client
actual_external_lum = photo_resistor.get_last_value()
oled.fill_rect(49, 40, 41, 10, OLED_FILL)
oled.print_line_no_fill("AUT=>", 49, 40, OLED_COLOR)
if actual_external_lum < SYSTEM_PARAMS["LIGHTS_OFF_LEVEL"]:
actual_external_lum_converted = PHOTO_RESISTOR_MAX_VALUE - actual_external_lum
duty_value = int(1023 * actual_external_lum_converted / (PHOTO_RESISTOR_MAX_VALUE - PHOTO_RESISTOR_MIN_VALUE))
led1.duty(duty_value)
led2.duty(duty_value)
oled.fill_rect(90, 40, 60, 10, OLED_FILL)
oled.print_line_no_fill(str(int(actual_external_lum_converted)) + "%", 90, 40, OLED_COLOR)
MQTT_PUBLISH_VALUE[MQTT_LED_STATE] = ujson.dumps({"light" : 1})
try:
client.publish(MQTT_LED_STATE, MQTT_PUBLISH_VALUE[MQTT_LED_STATE])
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Published", 55, 10, OLED_COLOR)
except OSError as e:
print("Error during the sensors data pubblication: ", e)
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Error", 55, 10, OLED_COLOR)
else:
led1.duty(0)
led2.duty(0)
oled.fill_rect(90, 40, 60, 10, OLED_FILL)
oled.print_line_no_fill("0%", 90, 40, OLED_COLOR)
MQTT_PUBLISH_VALUE[MQTT_LED_STATE] = ujson.dumps({"light" : 0})
try:
client.publish(MQTT_LED_STATE, MQTT_PUBLISH_VALUE[MQTT_LED_STATE])
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Published", 55, 10, OLED_COLOR)
except OSError as e:
print("Error during the sensors data pubblication: ", e)
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Error", 55, 10, OLED_COLOR)
def read_sensor_value():
global SENSORS_ACTUAL_VALUE, MQTT_ENVIRONMENT_TEMP, MQTT_ENVIRONMENT_HUMIDITY, MQTT_OUTSIDE_LUX
global MQTT_CISTERN_LEVEL, MQTT_GROUND_HUMIDITY
global OLED_COLOR, OLED_FILL
global oled, environment_sensor, photo_resistor, cistern, ground_sensor
print("Reading sensors values...")
oled.fill_rect(70, 0, 60, 10, OLED_FILL)
oled.print_line_no_fill("Reading", 65, 1, OLED_COLOR)
environment_sensor.measure()
SENSORS_ACTUAL_VALUE[MQTT_ENVIRONMENT_TEMP] = environment_sensor.get_ujson_temp()
SENSORS_ACTUAL_VALUE[MQTT_OUTSIDE_LUX] = photo_resistor.get_ujson_value()
SENSORS_ACTUAL_VALUE[MQTT_CISTERN_LEVEL] = cistern.get_ujson_level()
SENSORS_ACTUAL_VALUE[MQTT_GROUND_HUMIDITY] = ground_sensor.get_ujson_value()
SENSORS_ACTUAL_VALUE[MQTT_ENVIRONMENT_HUMIDITY] = environment_sensor.get_ujson_humidity()
oled.fill_rect(70, 0, 60, 10, OLED_FILL)
oled.print_line_no_fill("Read", 65, 1, OLED_COLOR)
def check_cistern():
global SENSORS_ACTUAL_VALUE, SYSTEM_PARAMS, MQTT_PUMP_STATE, MQTT_CISTERN_LEVEL
global OLED_COLOR, OLED_FILL
global oled, pump, cistern
if cistern.get_last_level() < SYSTEM_PARAMS["CRITICAL_CISTERN_LEVEL"]:
print("Livello di cisterna critico, ricarica il serbatoio per proseguire l'irrigazione")
pump.stop_pump()
if SYSTEM_PARAMS["MANUAL_IRRIGATION_CONTROL"] == False:
oled.fill_rect(40, 30, 30, 10, OLED_FILL)
oled.print_line_no_fill("AUT=>", 40, 30, OLED_COLOR)
oled.fill_rect(80, 30, 30, 10, OLED_FILL)
oled.print_line_no_fill("OFF", 80, 30, OLED_COLOR)
oled.fill_rect(70, 50, 60, 10, OLED_FILL)
oled.print_line_no_fill("Critic!!", 70, 50, OLED_COLOR)
SYSTEM_PARAMS["BLOCK_IRRIGATION_FOR_CRITICAL_CISTERN_LEVEL"] = True
MQTT_PUBLISH_VALUE[MQTT_PUMP_STATE] = ujson.dumps({"pump": 0})
try:
client.publish(MQTT_PUMP_STATE, MQTT_PUBLISH_VALUE[MQTT_PUMP_STATE])
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Published", 55, 10, OLED_COLOR)
except OSError as e:
print("Error during the sensors data pubblication: ", e)
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Error", 55, 10, OLED_COLOR)
elif cistern.get_last_level() > SYSTEM_PARAMS["CRITICAL_CISTERN_LEVEL"] and SYSTEM_PARAMS["BLOCK_IRRIGATION_FOR_CRITICAL_CISTERN_LEVEL"]:
print("Sistema di irrigazione ripristinato")
SYSTEM_PARAMS["BLOCK_IRRIGATION_FOR_CRITICAL_CISTERN_LEVEL"] = False
oled.fill_rect(70, 50, 60, 10, OLED_FILL)
oled.print_line_no_fill("Filled!!", 70, 50, OLED_COLOR)
if SYSTEM_PARAMS["MANUAL_IRRIGATION_PUMP"] == True:
print("Starting pump...", end="")
pump.start_pump()
oled.fill_rect(80, 30, 30, 10, OLED_FILL)
oled.print_line_no_fill("ON", 80, 30, OLED_COLOR)
MQTT_PUBLISH_VALUE[MQTT_PUMP_STATE] = ujson.dumps({"pump": 1})
try:
client.publish(MQTT_PUMP_STATE, MQTT_PUBLISH_VALUE[MQTT_PUMP_STATE])
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Published", 55, 10, OLED_COLOR)
except OSError as e:
print("Error during the sensors data pubblication: ", e)
ooled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Error", 55, 10, OLED_COLOR)
else:
oled.fill_rect(70, 50, 60, 10, OLED_FILL)
oled.print_line_no_fill(str(int(cistern.get_last_level())) + "%", 70, 50, OLED_COLOR)
def manual_fan_control():
global MQTT_PUBLISH_VALUE, MQTT_FAN_STATE
global OLED_COLOR, OLED_FILL
global oled, fan, client
oled.fill_rect(35, 20, 30, 10, OLED_FILL)
oled.print_line_no_fill("MAN=>", 35, 20, OLED_COLOR)
fan.stop_fan()
oled.fill_rect(80, 20, 60, 10, OLED_FILL)
oled.print_line_no_fill("OFF", 80, 20, OLED_COLOR)
MQTT_PUBLISH_VALUE[MQTT_FAN_STATE] = ujson.dumps({"fan" : 0 })
try:
client.publish(MQTT_FAN_STATE, MQTT_PUBLISH_VALUE[MQTT_FAN_STATE])
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Published", 55, 10, OLED_COLOR)
except OSError as e:
print("Error during the sensors data pubblication: ", e)
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Error", 55, 10, OLED_COLOR)
def manual_fan_on():
global SYSTEM_PARAMS, MQTT_PUBLISH_VALUE, DASH_MAX_VAL, MQTT_FAN_STATE
global OLED_COLOR, OLED_FILL
global fan, oled, client
fan.start_fan()
oled.fill_rect(80, 20, 60, 10, OLED_FILL)
oled.print_line_no_fill("ON", 80, 20, OLED_COLOR)
MQTT_PUBLISH_VALUE[MQTT_FAN_STATE] = ujson.dumps({"fan" : 1})
try:
client.publish(MQTT_FAN_STATE, MQTT_PUBLISH_VALUE[MQTT_FAN_STATE])
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Published", 55, 10, OLED_COLOR)
except OSError as e:
print("Error during the sensors data pubblication: ", e)
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Error", 55, 10, OLED_COLOR)
def manual_fan_off():
global SYSTEM_PARAMS, MQTT_PUBLISH_VALUE, DASH_MAX_VAL, MQTT_FAN_STATE
global OLED_COLOR, OLED_FILL
global fan, oled, client
fan.stop_fan()
oled.fill_rect(80, 20, 60, 10, OLED_FILL)
oled.print_line_no_fill("OFF", 80, 20, OLED_COLOR)
MQTT_PUBLISH_VALUE[MQTT_FAN_STATE] = ujson.dumps({"fan" : 0})
try:
client.publish(MQTT_FAN_STATE, MQTT_PUBLISH_VALUE[MQTT_FAN_STATE])
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Published", 55, 10, OLED_COLOR)
except OSError as e:
print("Error during the sensors data pubblication: ", e)
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Error", 55, 10, OLED_COLOR)
def manual_irrigation_pump_on():
global SYSTEM_PARAMS, MQTT_PUBLISH_VALUE, MQTT_PUMP_STATE, MQTT_CISTERN_LEVEL
global OLED_COLOR, OLED_FILL
global oled, client, pump
if SYSTEM_PARAMS["BLOCK_IRRIGATION_FOR_CRITICAL_CISTERN_LEVEL"] == False:
print("Starting pump...", end="")
pump.start_pump()
oled.fill_rect(80, 30, 30, 10, OLED_FILL)
oled.print_line_no_fill("ON", 80, 30, OLED_COLOR)
MQTT_PUBLISH_VALUE[MQTT_PUMP_STATE] = ujson.dumps({"pump": 1})
try:
client.publish(MQTT_PUMP_STATE, MQTT_PUBLISH_VALUE[MQTT_PUMP_STATE])
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Published", 55, 10, OLED_COLOR)
except OSError as e:
print("Error during the sensors data pubblication: ", e)
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Error", 55, 10, OLED_COLOR)
else:
print("Livello di cisterna critico, ricarica il serbatoio per proseguire l'irrigazione")
pump.stop_pump()
oled.fill_rect(80, 30, 30, 10, OLED_FILL)
oled.print_line_no_fill("OFF", 80, 30, OLED_COLOR)
MQTT_PUBLISH_VALUE[MQTT_PUMP_STATE] = ujson.dumps({"pump": 0})
try:
client.publish(MQTT_PUMP_STATE, MQTT_PUBLISH_VALUE[MQTT_PUMP_STATE])
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Published", 55, 10, OLED_COLOR)
except OSError as e:
print("Error during the sensors data pubblication: ", e)
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Error", 55, 10, OLED_COLOR)
def manual_irrigation_pump_off():
global MQTT_PUBLISH_VALUE, MQTT_PUMP_STATE
global OLED_COLOR, OLED_FILL
global oled, client, pump
pump.stop_pump()
oled.fill_rect(80, 30, 30, 10, OLED_FILL)
oled.print_line_no_fill("OFF", 80, 30, OLED_COLOR)
MQTT_PUBLISH_VALUE[MQTT_PUMP_STATE] = ujson.dumps({"pump": 0})
try:
client.publish(MQTT_PUMP_STATE, MQTT_PUBLISH_VALUE[MQTT_PUMP_STATE])
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Published", 55, 10, OLED_COLOR)
except OSError as e:
print("Error during the sensors data pubblication: ", e)
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Error", 55, 10, OLED_COLOR)
#DA AGGIUSTARE IL DUTY VALUE
def manual_light_control():
global MQTT_PUBLISH_VALUE, MQTT_LED_STATE, SYSTEM_PARAMS
global OLED_COLOR, OLED_FILL
global client, led
led1.duty(0)
led2.duty(0)
oled.fill_rect(49, 40, 41, 10, OLED_FILL)
oled.print_line_no_fill("MAN=>", 49, 40, OLED_COLOR)
SYSTEM_PARAMS["MANUAL_LIGHTS_LEVEL"] = 0
oled.fill_rect(90, 40, 60, 10, OLED_FILL)
oled.print_line_no_fill(str(SYSTEM_PARAMS["MANUAL_LIGHTS_LEVEL"]) + "%", 90, 40, OLED_COLOR)
MQTT_PUBLISH_VALUE[MQTT_LED_STATE] = ujson.dumps({"light" : 0 })
try:
client.publish(MQTT_LED_STATE, MQTT_PUBLISH_VALUE[MQTT_LED_STATE])
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Published", 55, 10, OLED_COLOR)
except OSError as e:
print("Error during the sensors data pubblication: ", e)
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Error", 55, 10, OLED_COLOR)
def manual_light_level():
global SYSTEM_PARAMS, DASH_MAX_VAL, DASH_MIN_VAL, MQTT_LED_STATE, MQTT_PUBLISH_VALUE
global OLED_COLOR, OLED_FILL
global led, client
duty_value = 1023 * SYSTEM_PARAMS["MANUAL_LIGHTS_LEVEL"] / (DASH_MAX_VAL - DASH_MIN_VAL)
led1.duty(int(duty_value))
led2.duty(int(duty_value))
oled.fill_rect(90, 40, 60, 10, OLED_FILL)
oled.print_line_no_fill(str(SYSTEM_PARAMS["MANUAL_LIGHTS_LEVEL"]) + "%", 90, 40, OLED_COLOR)
MQTT_PUBLISH_VALUE[MQTT_LED_STATE] = ujson.dumps({"light" : 1})
try:
client.publish(MQTT_LED_STATE, MQTT_PUBLISH_VALUE[MQTT_LED_STATE])
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Published", 55, 10, OLED_COLOR)
except OSError as e:
print("Error during the sensors data pubblication: ", e)
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Error", 55, 10, OLED_COLOR)
#DEFINE THE CALLBACK PROCEDURE FOR THE RECIVED MSG FROM THE BROKER
def subCallback(topic, msg):
global SYSTEM_PARAMS, MQTT_SUBSCRIBE_TOPIC
global oled
print(topic, msg)
if topic == MQTT_SUBSCRIBE_TOPIC["MQTT_RESET_SYSTEM"]:
if msg == b'true':
SYSTEM_PARAMS["RESTART_SYSTEM"] = True
elif msg == b'false':
SYSTEM_PARAMS["RESTART_SYSTEM"] = False
if topic == MQTT_SUBSCRIBE_TOPIC["MQTT_IRRIGATION_MANUALCONTROL"]:
if msg == b'true':
oled.fill_rect(40, 30, 30, 10, OLED_FILL)
oled.print_line_no_fill("MAN=>", 40, 30, OLED_COLOR)
SYSTEM_PARAMS["MANUAL_IRRIGATION_CONTROL"] = True
elif msg == b'false':
oled.fill_rect(40, 30, 30, 10, OLED_FILL)
oled.print_line_no_fill("AUT=>", 40, 30, OLED_COLOR)
SYSTEM_PARAMS["MANUAL_IRRIGATION_CONTROL"] = False
if topic == MQTT_SUBSCRIBE_TOPIC["MQTT_IRRIGATION_MANUALPUMP"]:
if msg == b'true':
SYSTEM_PARAMS["MANUAL_IRRIGATION_PUMP"] = True
manual_irrigation_pump_on()
elif msg == b'false':
SYSTEM_PARAMS["MANUAL_IRRIGATION_PUMP"] = False
manual_irrigation_pump_off()
if topic == MQTT_SUBSCRIBE_TOPIC["MQTT_IRRIGATION_HUMIDITY"]:
SYSTEM_PARAMS["HUMIDITY_CRITICAL_LEVEL"] = int(msg)
if topic == MQTT_SUBSCRIBE_TOPIC["MQTT_FAN_MANUALCONTROL"]:
if msg == b'true':
SYSTEM_PARAMS["MANUAL_FAN_CONTROL"] = True
manual_fan_control()
elif msg == b'false':
SYSTEM_PARAMS["MANUAL_FAN_CONTROL"] = False
if topic == MQTT_SUBSCRIBE_TOPIC["MQTT_FAN_MANUALSTATE"]:
if msg == b'true':
SYSTEM_PARAMS["MANUAL_FAN_STATE"] = True
manual_fan_on()
elif msg == b'false':
SYSTEM_PARAMS["MANUAL_FAN_STATE"] = False
manual_fan_off()
if topic == MQTT_SUBSCRIBE_TOPIC["MQTT_FAN_ACTIVATIONTEMP"]:
SYSTEM_PARAMS["FAN_ACTIVATION_TEMP"] = int(msg)
if topic == MQTT_SUBSCRIBE_TOPIC["MQTT_LIGHTS_MANUALCONTROL"]:
if msg == b'true':
SYSTEM_PARAMS["MANUAL_LIGHTS_CONTROL"] = True
manual_light_control()
elif msg == b'false':
SYSTEM_PARAMS["MANUAL_LIGHTS_CONTROL"] = False
if topic == MQTT_SUBSCRIBE_TOPIC["MQTT_LIGHTS_MANUALLED"]:
SYSTEM_PARAMS["MANUAL_LIGHTS_LEVEL"] = int(msg)
manual_light_level()
if topic == MQTT_SUBSCRIBE_TOPIC["MQTT_LIGHTS_LEVEL"]:
SYSTEM_PARAMS["LIGHTS_OFF_LEVEL"] = int(msg)
# PROCEDURE OF CONNECTION TO THE MQTT SERVER
def mqtt_connection():
global client, oled
global OLED_COLOR
print("Connecting to MQTT server", end="")
shift_point = 0
oled.print_line("Connecting to", 0, 1, OLED_COLOR)
oled.print_line_no_fill("MQTT server", 0, 10, OLED_COLOR)
client.connect(MQTT_SUBSCRIBE_TOPIC, subCallback)
while shift_point < 28:
print(".", end="")
oled.print_line_no_fill(".", 85 + shift_point, 10, OLED_COLOR)
time.sleep(0.1)
shift_point = shift_point + 6
if client.get_conn_state():
print(" Connected")
oled.print_line_no_fill("Connected!", 0, 20, OLED_COLOR)
oled.fill_clr()
else:
print("Failure connecting to MQTT server!!")
oled.print_line_no_fill("Not Connected!", 0, 20, OLED_COLOR)
oled.fill_clr()
raise OSException
#UTILITIES FUNCTIONS USED FOR THE TESTS
def print_dict(dic):
for k, v in dic.items():
if v != None:
print(k, ": ", v)
#DEFINING THE IRQ PROCEDURE FOR THE RESET BTN
def hard_reset(btn_reset):
global LAST_RESET, SYSTEM_PARAMS, DELTA_MAX_RESET
current = time.ticks_ms()
delta = time.ticks_diff(current, LAST_RESET)
if delta < DELTA_MAX_RESET:
return
LAST_RESET = current
SYSTEM_PARAMS["RESTART_SYSTEM"] = True
reset_btn.irq(trigger=Pin.IRQ_RISING, handler=hard_reset)
#DEFINING THE IRQ PROCEDURE FOR THE DOOR BTN
def change_door_state_reprint():
global SYSTEM_PARAMS
global oled
if SYSTEM_PARAMS["MANUAL_IRRIGATION_CONTROL"] == True:
oled.fill_rect(40, 30, 30, 10, OLED_FILL)
oled.print_line_no_fill("MAN=>", 40, 30, OLED_COLOR)
if SYSTEM_PARAMS["MANUAL_IRRIGATION_PUMP"] == True:
oled.fill_rect(80, 30, 30, 10, OLED_FILL)
oled.print_line_no_fill("ON", 80, 30, OLED_COLOR)
else:
oled.fill_rect(80, 30, 30, 10, OLED_FILL)
oled.print_line_no_fill("OFF", 80, 30, OLED_COLOR)
if SYSTEM_PARAMS["MANUAL_FAN_CONTROL"] == True:
oled.fill_rect(35, 20, 30, 10, OLED_FILL)
oled.print_line_no_fill("MAN=>", 35, 20, OLED_COLOR)
if SYSTEM_PARAMS["MANUAL_FAN_STATE"] == True:
oled.fill_rect(80, 20, 60, 10, OLED_FILL)
oled.print_line_no_fill("ON", 80, 20, OLED_COLOR)
else:
oled.fill_rect(80, 20, 60, 10, OLED_FILL)
oled.print_line_no_fill("OFF", 80, 20, OLED_COLOR)
if SYSTEM_PARAMS["MANUAL_LIGHTS_CONTROL"] == True:
oled.fill_rect(49, 40, 41, 10, OLED_FILL)
oled.print_line_no_fill("MAN=>", 49, 40, OLED_COLOR)
oled.fill_rect(90, 40, 60, 10, OLED_FILL)
oled.print_line_no_fill(str(SYSTEM_PARAMS["MANUAL_LIGHTS_LEVEL"]) + "%", 90, 40, OLED_COLOR)
def change_door_state(btn_door):
global LAST_DOOR, SYSTEM_PARAMS, DELTA_MAX_DOOR, IRQ_LOCK, MQTT_DOOR_STATE
global door, oled, client
global OLED_FILL, OLED_COLOR
if IRQ_LOCK == False:
current = time.ticks_ms()
delta = time.ticks_diff(current, LAST_DOOR)
if delta < DELTA_MAX_DOOR:
return
LAST_DOOR = current
SYSTEM_PARAMS["DOOR_OPEN"] = not SYSTEM_PARAMS["DOOR_OPEN"]
if SYSTEM_PARAMS["DOOR_OPEN"] == True:
door.open_door()
oled.print_door_state(SYSTEM_PARAMS["DOOR_OPEN"], OLED_FILL, OLED_COLOR)
MQTT_PUBLISH_VALUE[MQTT_DOOR_STATE] = ujson.dumps({"door" : 1})
try:
client.publish(MQTT_DOOR_STATE, MQTT_PUBLISH_VALUE[MQTT_DOOR_STATE])
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Published", 55, 10, OLED_COLOR)
except OSError as e:
print("Error during the sensors data pubblication: ", e)
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Error", 55, 10, OLED_COLOR)
elif SYSTEM_PARAMS["DOOR_OPEN"] == False:
door.close_door()
oled.print_door_state(SYSTEM_PARAMS["DOOR_OPEN"], OLED_FILL, OLED_COLOR)
MQTT_PUBLISH_VALUE[MQTT_DOOR_STATE] = ujson.dumps({"door" : 0})
try:
client.publish(MQTT_DOOR_STATE, MQTT_PUBLISH_VALUE[MQTT_DOOR_STATE])
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Published", 55, 10, OLED_COLOR)
except OSError as e:
print("Error during the sensors data pubblication: ", e)
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Error", 55, 10, OLED_COLOR)
oled.print_system_state(OLED_FILL,OLED_COLOR)
change_door_state_reprint()
door_btn.irq(trigger=Pin.IRQ_RISING, handler=change_door_state)
#MAIN LOOP
while True:
if SYSTEM_PARAMS["BOOT"] == True:
IRQ_LOCK = True
wifi_connect()
mqtt_connection()
oled.print_system_state(OLED_FILL,OLED_COLOR)
SYSTEM_PARAMS["BOOT"] = False
IRQ_LOCK = False
if SYSTEM_PARAMS["PRINT_SYS_STATE"] == True:
oled.print_system_state(OLED_FILL,OLED_COLOR)
SYSTEM_PARAMS["PRINT_SYS_STATE"] = False
if SYSTEM_PARAMS["RESTART_SYSTEM"] == False:
try:
read_sensor_value()
except OSError as e:
print("Error while reading the sensors values:", e)
try:
MQTT_PUBLISH_VALUE = client.publish_new_sensor_value(MQTT_PUBLISH_VALUE, SENSORS_ACTUAL_VALUE)
except OSError as e:
print("Error during the sensors data pubblication: ", e)
check_cistern()
try:
print("Checking messages from the broker...")
client.check_msg()
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Checked", 55, 10, OLED_COLOR)
except OSError as e:
oled.fill_rect(55, 10, 80, 10, OLED_FILL)
oled.print_line_no_fill("Error", 55, 10, OLED_COLOR)
print("Checking masseges from the broker fail: ", e)
if SYSTEM_PARAMS["MANUAL_FAN_CONTROL"] == False:
auto_fan_control()
if SYSTEM_PARAMS["MANUAL_IRRIGATION_CONTROL"] == False and SYSTEM_PARAMS["BLOCK_IRRIGATION_FOR_CRITICAL_CISTERN_LEVEL"] == False:
auto_irrigation_control()
if SYSTEM_PARAMS["MANUAL_LIGHTS_CONTROL"] == False:
auto_light_control()
else:
IRQ_LOCK = True
restart_procedure()
IRQ_LOCK = False