i need help for my project for my graduation conclusion.
I've set this program to controll the raspberry from the web, using node-red node MQTT. At first, the communication worked just fine, however, in some point the program start to receive the message more than one time after I inject it from the node-red flow and it makes the program crash as it gets the error: oserror: [errno 24] too many open files . I analysed the code and just can't find out why the mqtt broker receives more than one message per time, and I need help, I'm really desperate. In the images I show the flow from node-red and the output from the terminal on raspberry pi.
#! usr/bin/ env python
#Import librarys used#
import paho.mqtt.client as mqtt
import RPi.GPIO as GPIO
import sys
import time
import Adafruit_DHT
import MFRC522
#Definition of inputs#
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
pino_presenca = 11 #Set the input of the PIR sensor used in the project
GPIO.setup(pino_presenca, GPIO.IN)
pino_luminosidade = 15 #Set the input of the LDR module used in the project
GPIO.setup(pino_luminosidade, GPIO.IN)
pino_temperatura = 27 #Sets the input of the DHT11 sensor used in the project
#Set the LED used to demonstrate the mode select (Automatic or manual)#
GPIO.setup(12, GPIO.OUT)
GPIO.output(12, GPIO.LOW)
GPIO.setup(16, GPIO.OUT)
GPIO.output(16, GPIO.LOW)
#Set the outputs used in the project
GPIO.setup(36, GPIO.OUT)
GPIO.output(36, GPIO.HIGH)
GPIO.setup(38, GPIO.OUT)
GPIO.output(38, GPIO.HIGH)
GPIO.setup(40, GPIO.OUT)
GPIO.output(40, GPIO.HIGH)
#Set the cleared tags that will be read by RFID module
cartao = {"12:4F:90:34:F9":"Matheus Neri", "47:22:9D:60:98":"Matheus Neri"}
leitor = MFRC522.MFRC522()
auto = False #Declare the variable auto for using in the loop of the automatic mode
modo_auto = False #Declare the variable auto for using in the loop of the automatic mode
estado_lampada = 0 #Declare the variable that will monitor the state of the lamp
estado_ventilador = #Declare the variable that will monitor the state of the fan
#Function that will make the program runs in automatic mode
def automatico():
global estado_ventilador
global estado_lampada
global modo_auto
global estado_luminosidade
pino_luminosidade = 15
GPIO.setup(pino_luminosidade, GPIO.IN)
estado_luminosidade = GPIO.input(pino_luminosidade)
print ("Automatic mode activated")
GPIO.output(12, GPIO.HIGH)
GPIO.output(16,GPIO.LOW)
while auto == True:
estado_presenca = GPIO.input(pino_presenca)
if estado_presenca == 1:
modo_auto = True
while modo_auto == 1:
estado_luminosidade = GPIO.input(pino_luminosidade)
estado_presenca = GPIO.input(pino_presenca)
if estado_luminosidade == 1:
print ("Ambiente escuro")
GPIO.output(40, GPIO.LOW)
time.sleep(2)
if estado_luminosidade == 0:
print ("Luz acessa")
time.sleep(2)
temp_atual = temperatura()
if temp_atual > 21:
estado_ventilador = 1
ventilador_automatico()
if temp_atual < 21 and estado_ventilador == 1:
GPIO.output(38, GPIO.HIGH)
if estado_presenca == 0:
modo_auto = False
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("raspzerow.local", port = 1883, keepalive = 120)
client.username_pw_set("root","neri2143")
client.loop_start()
if estado_luminosidade == 0 and estado_presenca == 0:
GPIO.output(40, GPIO.HIGH)
if estado_presenca ==0 and estado_ventilador == 1:
GPIO.output(38, GPIO.HIGH)
print ("Sem presença")
time.sleep(3)
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("raspzerow.local", port = 1883, keepalive = 120)
client.username_pw_set("root", "neri2143")
client.loop_start()
def manual():
try:
print ("Manual mode activated")
GPIO.output(16,GPIO.HIGH)
GPIO.output(12, GPIO.LOW)
while modo_auto == False:
leitor = MFRC522.MFRC522()
status,tag_type = leitor.MFRC522_Request(leitor.PICC_REQIDL) #F$
if status == leitor.MI_OK:
status, uid = leitor.MFRC522_Anticoll()
if status == leitor.MI_OK:
uid = ':'.join(['%X'% x for x in uid])
print("UID do cartão: %s" %uid)
if uid in cartao:
print ("Acesso liberado")
print ("Olá %s." % cartao[uid])
GPIO.output(36, GPIO.LOW)
time.sleep(5)
GPIO.output(36, GPIO.HIGH)
else:
print ("Acesso negado")
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("raspzerow.local", port = 1883, keepalive =120)
client.username_pw_set("root", "neri2143")
client.loop_start()
except KeyboardInterrupt:
GPIO.cleanup()
print ("Simulação finalizada")
sys.exit(0)
def on_connect (client, userdata, flags, rc):
client.subscribe("iluminação")
client.subscribe("ventilação")
client.subscribe("modo")
def on_message(client, userdata, msg):
msg.payload = msg.payload.decode("utf-8")
mensagem = msg.payload
global estado_lampada
global estado_ventilador
global auto
global modo_auto
if mensagem == "ON":
auto = True
automatico()
if mensagem == "OFF":
auto = False
modo_auto= False
print (auto, modo_auto)
manual()
if mensagem == "ONL":
if estado_lampada == 1:
estado_lampada = 0
lampada()
if mensagem == "OFFL":
if estado_lampada == 0:
estado_lampada = 1
lampada()
if mensagem == "ONV":
if estado_ventilador == 1:
estado_ventilador = 0
ventilador()
if mensagem == "OFFV":
if estado_ventilador == 0:
estado_ventilador = 1
ventilador()
#Define the function that will change the state of the fan in automatic mode
def ventilador_automatico():
print("Ventilador ligado")
GPIO.output(38, GPIO.LOW)
estado_ventilador = 1
time.sleep(2)
#Define the function that will change the state of the fan in manual mode
def ventilador():
GPIO.setup (38, GPIO.OUT)
global estado_ventilador
if estado_ventilador == 0:
print ("Ventilador ligado")
GPIO.output(38,GPIO.LOW)
estado_ventilador = 1
time.sleep(2)
else:
print ("Ventilador desligado")
GPIO.output(38, GPIO.HIGH)
estado_ventilador = 0
#Define the function that will change the state of the lamp in manual mode
def lampada():
GPIO.setup(40, GPIO.OUT)
global estado_lampada
if estado_lampada == 0:
GPIO.output(40, GPIO.LOW)
print ("Lampada acessa")
estado_lampada = 1
else:
GPIO.output(40,GPIO.HIGH)
print ("Lampada apagada")
estado_lampada = 0
#Define the function that will make the reading of the DHT11 sensor
def temperatura():
sensor = Adafruit_DHT.DHT11
pino_sensor = 27
umid, temp = Adafruit_DHT.read_retry(sensor, pino_sensor)
if umid is not None and temp is not None:
print ("Temperatura = {0:0.1f}".format(temp))
#print ("Temperatura = {0:0.1f} Umidade = {1:0.1f}n".format(temp, umid))
if umid is None and temp is None:
print ("Falha ao ler dados do DHT11")
return temp
print ("Simulation start")
manual()
The following lines of code:
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("raspzerow.local", port = 1883, keepalive =120)
client.username_pw_set("root", "neri2143")
client.loop_start()
Should only be run once at the start of the program. You have them in a loop.
Each time this is called it will create a new connection to the MQTT broker, subscribe to your topics and create a new thread ( client.loop_start()
) to receive the subscriptions.
Very soon you'll run out of sockets to connect to the MQTT broker and get the too many open files error that you're seeing. You'll also appear to see multiple messages since each subscription will receive the same message.
Delete these lines of code everywhere they're used in the program (3 times) and move them to the start of the code before you call manual()
.
--- EDIT ---
Following the comments it appears there are more issues here. on_message()
function calls either manual()
or automatico()
which run a loop. This blocks the MQTT client thread from processing any more messages. Therefore this function should just set a flag or status to change whether automatico()
or manual()
are called in the main application thread.
Here's a suggested (untested) change to the code to enable this.
#! usr/bin/ env python
#Import librarys used#
import paho.mqtt.client as mqtt
import RPi.GPIO as GPIO
import sys
import time
import Adafruit_DHT
import MFRC522
#Definition of inputs#
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
pino_presenca = 11 #Set the input of the PIR sensor used in the project
GPIO.setup(pino_presenca, GPIO.IN)
pino_luminosidade = 15 #Set the input of the LDR module used in the project
GPIO.setup(pino_luminosidade, GPIO.IN)
pino_temperatura = 27 #Sets the input of the DHT11 sensor used in the project
#Set the LED used to demonstrate the mode select (Automatic or manual)#
GPIO.setup(12, GPIO.OUT)
GPIO.output(12, GPIO.LOW)
GPIO.setup(16, GPIO.OUT)
GPIO.output(16, GPIO.LOW)
#Set the outputs used in the project
GPIO.setup(36, GPIO.OUT)
GPIO.output(36, GPIO.HIGH)
GPIO.setup(38, GPIO.OUT)
GPIO.output(38, GPIO.HIGH)
GPIO.setup(40, GPIO.OUT)
GPIO.output(40, GPIO.HIGH)
#Set the cleared tags that will be read by RFID module
cartao = {"12:4F:90:34:F9":"Matheus Neri", "47:22:9D:60:98":"Matheus Neri"}
leitor = MFRC522.MFRC522()
modo_auto = False #Declare the variable modo_auto for using in the loop of the automatic mode
estado_lampada = 0 #Declare the variable that will monitor the state of the lamp
estado_ventilador = #Declare the variable that will monitor the state of the fan
#Function that will make the program runs in automatic mode
def automatico():
global estado_ventilador
global estado_lampada
global modo_auto
global estado_luminosidade
pino_luminosidade = 15
GPIO.setup(pino_luminosidade, GPIO.IN)
estado_luminosidade = GPIO.input(pino_luminosidade)
print ("Automatic mode activated")
GPIO.output(12, GPIO.HIGH)
GPIO.output(16,GPIO.LOW)
while modo_auto == True:
estado_presenca = GPIO.input(pino_presenca)
if estado_presenca == 1:
modo_auto = True
while modo_auto == 1:
estado_luminosidade = GPIO.input(pino_luminosidade)
estado_presenca = GPIO.input(pino_presenca)
if estado_luminosidade == 1:
print ("Ambiente escuro")
GPIO.output(40, GPIO.LOW)
time.sleep(2)
if estado_luminosidade == 0:
print ("Luz acessa")
time.sleep(2)
temp_atual = temperatura()
if temp_atual > 21:
estado_ventilador = 1
ventilador_automatico()
if temp_atual < 21 and estado_ventilador == 1:
GPIO.output(38, GPIO.HIGH)
if estado_presenca == 0:
modo_auto = False
if estado_luminosidade == 0 and estado_presenca == 0:
GPIO.output(40, GPIO.HIGH)
if estado_presenca ==0 and estado_ventilador == 1:
GPIO.output(38, GPIO.HIGH)
print ("Sem presença")
time.sleep(3)
def manual():
global modo_auto
try:
print ("Manual mode activated")
GPIO.output(16,GPIO.HIGH)
GPIO.output(12, GPIO.LOW)
while modo_auto == False:
leitor = MFRC522.MFRC522()
status,tag_type = leitor.MFRC522_Request(leitor.PICC_REQIDL) #F$
if status == leitor.MI_OK:
status, uid = leitor.MFRC522_Anticoll()
if status == leitor.MI_OK:
uid = ':'.join(['%X'% x for x in uid])
print("UID do cartão: %s" %uid)
if uid in cartao:
print ("Acesso liberado")
print ("Olá %s." % cartao[uid])
GPIO.output(36, GPIO.LOW)
time.sleep(5)
GPIO.output(36, GPIO.HIGH)
else:
print ("Acesso negado")
except KeyboardInterrupt:
GPIO.cleanup()
print ("Simulação finalizada")
sys.exit(0)
def on_connect (client, userdata, flags, rc):
client.subscribe("iluminação")
client.subscribe("ventilação")
client.subscribe("modo")
def on_message(client, userdata, msg):
msg.payload = msg.payload.decode("utf-8")
mensagem = msg.payload
global estado_lampada
global estado_ventilador
global modo_auto
if mensagem == "ON":
modo_auto = True
if mensagem == "OFF":
modo_auto= False
print (modo_auto)
if mensagem == "ONL":
if estado_lampada == 1:
estado_lampada = 0
lampada()
if mensagem == "OFFL":
if estado_lampada == 0:
estado_lampada = 1
lampada()
if mensagem == "ONV":
if estado_ventilador == 1:
estado_ventilador = 0
ventilador()
if mensagem == "OFFV":
if estado_ventilador == 0:
estado_ventilador = 1
ventilador()
#Define the function that will change the state of the fan in automatic mode
def ventilador_automatico():
print("Ventilador ligado")
GPIO.output(38, GPIO.LOW)
estado_ventilador = 1
time.sleep(2)
#Define the function that will change the state of the fan in manual mode
def ventilador():
GPIO.setup (38, GPIO.OUT)
global estado_ventilador
if estado_ventilador == 0:
print ("Ventilador ligado")
GPIO.output(38,GPIO.LOW)
estado_ventilador = 1
time.sleep(2)
else:
print ("Ventilador desligado")
GPIO.output(38, GPIO.HIGH)
estado_ventilador = 0
#Define the function that will change the state of the lamp in manual mode
def lampada():
GPIO.setup(40, GPIO.OUT)
global estado_lampada
if estado_lampada == 0:
GPIO.output(40, GPIO.LOW)
print ("Lampada acessa")
estado_lampada = 1
else:
GPIO.output(40,GPIO.HIGH)
print ("Lampada apagada")
estado_lampada = 0
#Define the function that will make the reading of the DHT11 sensor
def temperatura():
sensor = Adafruit_DHT.DHT11
pino_sensor = 27
umid, temp = Adafruit_DHT.read_retry(sensor, pino_sensor)
if umid is not None and temp is not None:
print ("Temperatura = {0:0.1f}".format(temp))
#print ("Temperatura = {0:0.1f} Umidade = {1:0.1f}n".format(temp, umid))
if umid is None and temp is None:
print ("Falha ao ler dados do DHT11")
return temp
print ("Simulation start")
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("raspzerow.local", port = 1883, keepalive = 120)
client.username_pw_set("root", "neri2143")
client.loop_start()
while True:
if modo_auto :
automatico()
else:
manual()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.