from machine import I2C, Pin, ADC #importing LIBRARIES
from umqtt.simple import MQTTClient #
import network #
import utime as time #
from time import sleep #
from i2c_lcd import I2cLcd #
import math #
import ujson # importing libraries
global new_load # TIMH KATHE KAINOYRGIOY FORTIOY
new_load = 1 # 1KW
AddressOfLcd = 0x27
global loadscounter # metriths synolikoy fortiou
loadscounter = 0
i2c = I2C(scl=Pin(22), sda=Pin(21), freq=400000) # connect scl to GPIO 22, sda to GPIO 21
lcd = I2cLcd(i2c, AddressOfLcd, 2, 16)
# Device Setup
DEVICE_ID = "user1"
# WiFi Setup
WIFI_SSID = "Wokwi-GUEST"
WIFI_PASSWORD = ""
# MQTT Setup
MQTT_BROKER = "broker.mqttdashboard.com" #broker
MQTT_CLIENT = DEVICE_ID #
MQTT_TELEMETRY_TOPIC = "iot/telemetry" #iot topics
MQTT_CONTROL_TOPIC = "iot/control" #iot topics
MQTT_REQUEST_TOPIC = "iot/request" #iot topics
#slide switch
right_position =Pin(25, Pin.IN) #slide switch pin
global sw_state
sw_state = right_position.value() #katastash diakopth
# LED/LAMP & pushbuttons Setup
RED_LED = Pin(19, Pin.OUT)
YELLOW_LED = Pin(18, Pin.OUT)
GREEN_LED = Pin(5, Pin.OUT)
BLUE_LED = Pin(4, Pin.OUT)
red_button_pin = Pin(34, Pin.IN)
yellow_button_pin = Pin(35, Pin.IN)
green_button_pin = Pin(32, Pin.IN)
blue_button_pin = Pin(33, Pin.IN)
global red_led_state #apothikebw tis katastaseis twn led
red_led_state = 0
global yellow_led_state
yellow_led_state = 0
global green_led_state
green_led_state = 0
global blue_led_state
blue_led_state = 0
last_red_button_state = 0 # prohgoymenes katastaseis led
last_yellow_button_state = 0 # (tha mporoyse na xrisimopoihthei
last_green_button_state = 0 # h entoli "toggle" ant aytoy)
last_blue_button_state = 0 # p.x. if button_state != old button state:
# led.toggle()
red_led_que = 0 # apothikebw poia fortia exoyn kanei request ston aggregator
yellow_led_que = 0
green_led_que = 0
blue_led_que = 0
# Methods
def did_receive_callback(topic, message):
print('\n\nData Received! \ntopic = {0}, message = {1}'.format(topic, message))
if topic == MQTT_CONTROL_TOPIC.encode():
if message == ('{0}/load/led1/on'.format(DEVICE_ID)).encode(): #red led on control message
global red_led_state
if red_led_state == 0: # check if the load is alreaddy on
RED_LED.on() #turn led1/red led on
red_led_state = 1
global loadscounter
loadscounter = loadscounter + 1
global telemetry_data_new
mqtt_client_publish(MQTT_TELEMETRY_TOPIC, telemetry_data_new) # publish the status of the loads and total power consumption
elif red_led_state == 1: # an to fortio einai idi energopoihmeno emfanizw sto lcd oti to fortio einai energopoihmeno
lcd.clear()
lcd.move_to(0,0)
lcd.putstr('mqtt led1 -> on')
lcd.move_to(02,1)
lcd.putstr('ALREADY ON')
sleep(1)
lcd.clear()
elif message == ('{0}/load/led1/off'.format(DEVICE_ID)).encode(): #red led off control message
global red_led_state
if red_led_state == 1: #an einai energopoihmeno to led
red_led_state = 0 # apothikebw oti einai sbhsto (den xrhsimopoiw thn entolh RED_LED.value() giati moy dimioyrgoyse problhmata)
RED_LED.off() # kai to sbhnw
global loadscounter
loadscounter = loadscounter - 1 #synypologizw thn meiwsh toy sylolikoy fortioy
mqtt_client_publish(MQTT_TELEMETRY_TOPIC, telemetry_data_new)
elif red_led_state ==0:
lcd.clear()
lcd.move_to(0,0)
lcd.putstr('mqtt led1 -> on')
lcd.move_to(02,1)
lcd.putstr('ALREADY OFF')
sleep(1)
lcd.clear()
elif message == ('{0}/load/led2/on'.format(DEVICE_ID)).encode():
global yellow_led_state
if yellow_led_state == 0:
YELLOW_LED.on()
yellow_led_state = 1
global loadscounter
yellow_led_state = 1
loadscounter = loadscounter + 1
mqtt_client_publish(MQTT_TELEMETRY_TOPIC, telemetry_data_new)
elif yellow_led_state == 1:
lcd.clear()
lcd.move_to(0,0)
lcd.putstr('mqtt led2 -> on')
lcd.move_to(02,1)
lcd.putstr('ALREADY ON')
sleep(1)
lcd.clear()
elif message == ('{0}/load/led2/off'.format(DEVICE_ID)).encode():
global yellow_led_state
if yellow_led_state == 1:
YELLOW_LED.off()
yellow_led_state = 0
global loadscounter
loadscounter = loadscounter - 1
mqtt_client_publish(MQTT_TELEMETRY_TOPIC, telemetry_data_new)
elif yellow_led_state ==0:
lcd.clear()
lcd.move_to(0,0)
lcd.putstr('mqtt led2 -> on')
lcd.move_to(02,1)
lcd.putstr('ALREADY OFF')
sleep(1)
lcd.clear()
elif message == ('{0}/load/led3/on'.format(DEVICE_ID)).encode():
global green_led_state
if green_led_state == 0:
GREEN_LED.on()
green_led_state = 1
global loadscounter
loadscounter = loadscounter + 1
mqtt_client_publish(MQTT_TELEMETRY_TOPIC, telemetry_data_new)
elif green_led_state == 1:
lcd.clear()
lcd.move_to(0,0)
lcd.putstr('mqtt led3 -> on')
lcd.move_to(02,1)
lcd.putstr('ALREADY ON')
sleep(1)
lcd.clear()
elif message == ('{0}/load/led3/off'.format(DEVICE_ID)).encode():
global green_led_state
if green_led_state == 1:
GREEN_LED.off()
green_led_state = 0
global loadscounter
loadscounter = loadscounter - 1
mqtt_client_publish(MQTT_TELEMETRY_TOPIC, telemetry_data_new)
elif green_led_state == 0:
lcd.clear()
lcd.move_to(0,0)
lcd.putstr('mqtt led3 -> on')
lcd.move_to(02,1)
lcd.putstr('ALREADY OFF')
sleep(1)
lcd.clear()
elif message == ('{0}/load/led4/on'.format(DEVICE_ID)).encode():
global blue_led_state
if blue_led_state == 0:
BLUE_LED.on()
blue_led_state = 1
global loadscounter
loadscounter = loadscounter + 1
mqtt_client_publish(MQTT_TELEMETRY_TOPIC, telemetry_data_new)
elif blue_led_state == 1:
lcd.clear()
lcd.move_to(0,0)
lcd.putstr('mqtt led3 -> on')
lcd.move_to(02,1)
lcd.putstr('ALREADY ON')
sleep(1)
lcd.clear()
elif message == ('{0}/load/led4/off'.format(DEVICE_ID)).encode():
global blue_led_state
if blue_led_state == 1:
BLUE_LED.off()
blue_led_state = 0
global loadscounter
loadscounter = loadscounter - 1
mqtt_client_publish(MQTT_TELEMETRY_TOPIC, telemetry_data_new)
elif blue_led_state == 0:
lcd.clear()
lcd.move_to(0,0)
lcd.putstr('mqtt led3 -> on')
lcd.move_to(02,1)
lcd.putstr('ALREADY OFF')
sleep(1)
lcd.clear()
elif message == ('{0}/load/on'.format(DEVICE_ID)).encode(): # entolh energopoihseis olwn twn fortiwn
if red_led_state == 0: # check if the load is already on for a better count of the total loads
RED_LED.on()
red_led_state = 1
global loadscounter
loadscounter = loadscounter + 1
if yellow_led_state == 0:
YELLOW_LED.on()
yellow_led_state = 1
global loadscounter
loadscounter = loadscounter + 1
if green_led_state == 0:
GREEN_LED.on()
green_led_state = 1
global loadscounter
loadscounter = loadscounter + 1
if blue_led_state == 0:
BLUE_LED.on()
blue_led_state = 1
loadscounter = loadscounter + 1
mqtt_client_publish(MQTT_TELEMETRY_TOPIC, telemetry_data_new)
elif message == ('{0}/load/off'.format(DEVICE_ID)).encode(): # turn all loads of
if red_led_state != 0: # check the state of the load to not mess up the total loads count
RED_LED.off()
red_led_state = 0
global loadscounter
loadscounter = loadscounter - 1
if yellow_led_state != 0:
YELLOW_LED.off()
yellow_led_state = 0
loadscounter = loadscounter - 1
if green_led_state != 0:
GREEN_LED.off()
green_led_state = 0
loadscounter = loadscounter - 1
if blue_led_state != 0:
BLUE_LED.off()
blue_led_state = 0
loadscounter = loadscounter - 1
mqtt_client_publish(MQTT_TELEMETRY_TOPIC, telemetry_data_new)
elif message == ('{0}/load_enable/on'.format(DEVICE_ID)).encode(): # if a load request has been sent the xxx_led_que stores the loads that have been requested so that the agreggator can enable them with a more general message
global red_led_que
global yellow_led_que
global green_led_que
global blue_led_que
if red_led_que == 1 and red_led_state == 0:
RED_LED.on()
red_led_state = 1
loadscounter = loadscounter + 1
if yellow_led_que == 1 and yellow_led_state == 0:
YELLOW_LED.on()
yellow_led_state =1
loadscounter = loadscounter + 1
if green_led_que == 1 and green_led_state == 0:
GREEN_LED.on()
green_led_state = 1
loadscounter = loadscounter + 1
if blue_led_que == 1 and blue_led_state == 0:
BLUE_LED.on()
blue_led_state = 1
loadscounter = loadscounter + 1
red_led_que = 0
yellow_led_que = 0
green_led_que = 0
blue_led_que = 0
elif message == ('{0}/load_enable/off'.format(DEVICE_ID)).encode():
global red_led_que
global yellow_led_que
global green_led_que
global blue_led_que
red_led_que = 0
yellow_led_que = 0
green_led_que = 0
blue_led_que = 0
elif message == ('{0}/status'.format(DEVICE_ID)).encode() or message == ('status').encode(): # after status request the controller publishes every load state and the over all power consumption
global telemetry_data_old
mqtt_client_publish(MQTT_TELEMETRY_TOPIC, telemetry_data_old)
else:
return
def mqtt_connect(): # connecting to mqtt broker
print("Connecting to MQTT broker ...", end="")
mqtt_client = MQTTClient(MQTT_CLIENT, MQTT_BROKER, user="", password="")
mqtt_client.set_callback(did_receive_callback)
mqtt_client.connect()
print("Connected.")
mqtt_client.subscribe(MQTT_CONTROL_TOPIC)
# mqtt_client.subscribe(MQTT_TELEMETRY_TOPIC)
return mqtt_client
def mqtt_client_publish_to_Aggregator(MQTT_REQUEST_TOPIC, request_data): #request loads to be enabled
print("\nUpdating MQTT Broker...")
mqtt_client.publish(MQTT_REQUEST_TOPIC, request_data)
print(request_data)
def mqtt_client_publish(topic, data):
print("\nUpdating MQTT Broker...")
mqtt_client.publish(topic, data)
print(data)
def create_json_data(loadscounter,red_led_state,yellow_led_state,green_led_state,blue_led_state):
data = ujson.dumps({
"device_id": DEVICE_ID,
"power": loadscounter,
"red led": red_led_state,
"yellow led": yellow_led_state,
"green led": green_led_state,
"blue led": blue_led_state,
"type": "lamps"
})
return data
def telemetry_msg(loadscounter,DEVICE_ID): # synolikh timh fortioy msg
telem_msg = ujson.dumps({
"power": loadscounter, # mhnyma meta apo energ/apenerg. fortiou
"type": "sensor",
"user_id": DEVICE_ID
})
return telem_msg
def msg_to_Aggregator(loadscounter,new_load): # request msg to agr
request_data = ujson.dumps({ # tha mporoyse na einai to idio me to apo panw an to "type" htan idio
"device_id": DEVICE_ID,
"power_request": new_load,
"type": "lamps"
})
return request_data
# Connect to WiFi
wifi_client = network.WLAN(network.STA_IF)
wifi_client.active(True)
print("Connecting device to WiFi")
wifi_client.connect(WIFI_SSID, WIFI_PASSWORD)
# Wait until WiFi is Connected
while not wifi_client.isconnected():
print("Connecting")
time.sleep(0.1)
print("WiFi Connected!")
print(wifi_client.ifconfig())
# Connect to WiFi
wifi_client = network.WLAN(network.STA_IF)
wifi_client.active(True)
print("Connecting device to WiFi")
wifi_client.connect(WIFI_SSID, WIFI_PASSWORD)
# Wait until WiFi is Connected
while not wifi_client.isconnected():
print("Connecting")
time.sleep(0.1)
print("WiFi Connected!")
print(wifi_client.ifconfig())
# Connect to MQTT
mqtt_client = mqtt_connect()
telemetry_data_old = ""
request_status = ""
telemetry_msg_ar_old = ""
while True:
current_red_button_state = red_button_pin.value() #checking if a button has been pressed
if current_red_button_state != last_red_button_state:
if red_led_state == 0 and current_red_button_state == 1:
if sw_state == 0: # checking the mode
RED_LED.on()
loadscounter = loadscounter + 1
elif sw_state == 1: # demand mode (send request to agr.)
mqtt_client_publish_to_Aggregator(MQTT_REQUEST_TOPIC,request_status)
red_led_que = 1 # the response of the agr. does not specifie the loads seperatly so we store what has been requested
elif red_led_state == 1 and current_red_button_state == 1: # for turning on a load we do not need to request permition, just enform the agreggator about the changes
RED_LED.off()
loadscounter = loadscounter - 1
red_led_state = RED_LED.value()
last_red_button_state = current_red_button_state
current_red_button_state = red_button_pin.value()
current_yellow_button_state = yellow_button_pin.value()
if current_yellow_button_state != last_yellow_button_state:
if yellow_led_state == 0 and current_yellow_button_state == 1:
if sw_state == 0:
YELLOW_LED.on()
loadscounter = loadscounter + 1
elif sw_state == 1:
mqtt_client_publish_to_Aggregator(MQTT_REQUEST_TOPIC,request_status)
yellow_led_que = 1
elif yellow_led_state == 1 and current_yellow_button_state == 1:
YELLOW_LED.off()
loadscounter = loadscounter - 1
yellow_led_state = YELLOW_LED.value()
last_yellow_button_state = current_yellow_button_state
current_yellow_button_state = yellow_button_pin.value()
current_green_button_state = green_button_pin.value()
if current_green_button_state != last_green_button_state:
if green_led_state == 0 and current_green_button_state == 1:
if sw_state == 0:
GREEN_LED.on()
loadscounter = loadscounter + 1
elif sw_state == 1:
mqtt_client_publish_to_Aggregator(MQTT_REQUEST_TOPIC,request_status)
green_led_que = 1
elif green_led_state == 1 and current_green_button_state == 1:
GREEN_LED.off()
loadscounter = loadscounter - 1
green_led_state = GREEN_LED.value()
last_green_button_state = current_green_button_state
current_green_button_state = green_button_pin.value()
current_blue_button_state = blue_button_pin.value()
if current_blue_button_state != last_blue_button_state:
if blue_led_state == 0 and current_blue_button_state == 1:
if sw_state == 0:
BLUE_LED.on()
loadscounter = loadscounter + 1
elif sw_state == 1:
mqtt_client_publish_to_Aggregator(MQTT_REQUEST_TOPIC,request_status)
blue_led_que = 1
elif blue_led_state == 1 and current_blue_button_state == 1:
BLUE_LED.off()
loadscounter = loadscounter - 1
blue_led_state = BLUE_LED.value()
last_blue_button_state = current_blue_button_state
current_blue_button_state = blue_button_pin.value()
mqtt_client.check_msg()
# print(". ", end="")
sw_state = right_position.value() # checking the sw state inside the loop or else the modes will not change while the program is running
telemetry_data_new = create_json_data(loadscounter,red_led_state,yellow_led_state,green_led_state,blue_led_state)
request_status = msg_to_Aggregator(loadscounter,new_load)
telemetry_msg_ar = telemetry_msg(loadscounter,DEVICE_ID) # messege to agreggator after changes in loads
if telemetry_data_new != telemetry_data_old:
# mqtt_client_publish(MQTT_TELEMETRY_TOPIC, telemetry_data_new)
telemetry_data_old = telemetry_data_new
if telemetry_msg_ar != telemetry_msg_ar_old: #mhnyma sto agreggator meta apo ka8e alagh fortioy
mqtt_client_publish(MQTT_TELEMETRY_TOPIC, telemetry_msg_ar)
telemetry_msg_ar_old = telemetry_msg_ar
lcd.move_to(01,0) # lcd showing the overall power consumption
lcd.putstr(' Total load : ')
lcd.move_to(0,1)
lcd.putstr(" "+str(loadscounter) + "KW ")