#! /usr/bin/env python3 import RPi.GPIO import Adafruit_DHT # Adafruit python module for DHT11 and DHT22 import Adafruit_SHT31 # Adafruit python module for SHT31 import Adafruit_BME280 # Adafruit python module for BMP/BME280 import smbus import smtplib import time import sys import socket # socket module doesn't accept URLs for connection, just hostname and port. It is a low-level library def setup(): global bus, BMP280_I2CADDR, BMP280_REGISTER_STATUS, serverHOSTNAME, serverPORT, serverMailhost, serverMailport, Tc, pinDHT22, pinLED, sensorBMP280, sensorSHT31, sensorDHT22 bus = smbus.SMBus(1) # Rev 2 Pi, Pi 2 & Pi 3 uses bus 1 # VAR per il BMP-280 BMP280_I2CADDR = 0x77 # Device I2C address BMP280_REGISTER_STATUS = 0xF3 # server GAUChO (beelzeboss.lart) serverHOSTNAME = 'beelzeboss' serverPORT = 61000 Tc = 300 # 5 minuti di tempo di wait tra un campione e l'altro pinDHT22 = 23 # PIN DATA del DHT22. GPIO23, PIN number 16 pinLED = 24 # PIN LED. GPIO24, PIN number 18 RPi.GPIO.setmode(RPi.GPIO.BCM) # uso la nomenclatura GPIO per i PIN RPi.GPIO.setwarnings(False) # disabilito warning RPi.GPIO.setup(pinLED, RPi.GPIO.OUT) # il PIN del LED è solo pi3->led RPi.GPIO.output(pinLED, RPi.GPIO.LOW) # pongo basso il GPIO24, quindi non ho tensione. Il LED è spento # dichiarazione dei sensori sensorBMP280 = Adafruit_BME280.BME280(t_mode=Adafruit_BME280.BME280_OSAMPLE_8, p_mode=Adafruit_BME280.BME280_OSAMPLE_8, h_mode=Adafruit_BME280.BME280_OSAMPLE_8) # per il BMP280 posso usare la libreria Adafruit BME280, il chipset è lo stesso, solo che il BME ha in più l'umidità, cosa che il nostro non ha. sensorSHT31 = Adafruit_SHT31.SHT31() sensorDHT22 = Adafruit_DHT.DHT22 def main(): setup() try: GAUChOsystem() except KeyboardInterrupt as err: closeAll(err) def checkError(): # ogni qual volta nascono nuovi errori sui sensori, aggiungerli quì try: # vedo se il Pi3 riesce a leggere il BMP-280 (val1, val2) = bus.read_i2c_block_data(BMP280_I2CADDR, BMP280_REGISTER_STATUS, 2) # vedo se il Pi3 riesce a leggere l'SHT-31 val3 = sensorSHT31.read_status() # se val1, val2, val3 sono valori i sensori funzionano. except OSError as err: sendEmail(serverMailhost, serverMailport, err) # system exit closeAll(err) def GAUChOsystem(): while True: timeStart = time.time() timeStamp = time.ctime() # check for some system error checkError() # BMP280 tempBMP280 = sensorBMP280.read_temperature() presP = sensorBMP280.read_pressure() presBMP280 = presP / 100 print('\nBMP-280:') print('Time: %s' % timeStamp) print('Temperature: {:f} °C'.format(tempBMP280)) print('Pressure: {:f} hPa'.format(presBMP280)) # SHT31-D tempSHT31 = sensorSHT31.read_temperature() humSHT31 = sensorSHT31.read_humidity() print('\nSHT-31D:') print('Time: %s' % timeStamp) print('Temperature = {:f} °C'.format(tempSHT31)) print('Humidity = {:f} %'.format(humSHT31)) # DHT22 humDHT22 = None tempDHT22 = None # Il DHT 22 ha problemi nel leggere il dato, ogni tanto può fornire dei valori nulli while humDHT22 is None and tempDHT22 is None: humDHT22, tempDHT22 = Adafruit_DHT.read(sensorDHT22, pinDHT22) print('\nDHT-22:') print('Time: %s ' % timeStamp) print('Temperature = {:ff} °C'.format(tempDHT22)) print('Humidity = {:f} %'.format(humDHT22)) msgTosend = [] messageBMP280 = 'BMP-280: ' + str(timeStart) + ' Temperature = {:f} °C Pressure = {:f} hPa'.format(tempBMP280, presBMP280) messageSHT31 = 'SHT-31: ' + str(timeStart) + ' Temperature = {:f} °C Humidity = {:f} %'.format(tempSHT31, humSHT31) messageDHT22 = 'DHT-22: ' + str(timeStart) + ' Temperature = {:f} °C Humidity = {:f} %'.format(tempDHT22, humDHT22) msgTosend.append(messageBMP280) msgTosend.append(messageSHT31) msgTosend.append(messageDHT22) socketgaucho(msgTosend) del messageBMP280, messageSHT31, messageDHT22, msgTosend time.sleep(Tc - (time.time() - timeStart)) # sleep for 2' - time execute def socketgaucho(msgTosend): try: # UDP socket socketGaucho = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) except socket.error as err: # system exit closeAll(err) try: # NB invio il tempo espresso come secondi trascorsi dall'epoch (January 1, 1970, 00:00:00 (UTC)) index = 0 while index != len(msgTosend): socketGaucho.sendto(str.encode(msgTosend[index]), (serverHOSTNAME, serverPORT)) index += 1 except socket.error as err: # system exit closeAll(err) nACKB = False nACKS = False nACKD = False RPi.GPIO.output(pinLED, RPi.GPIO.HIGH) print() while nACKB is False or nACKS is False or nACKD is False: # todo: gestione nel caso in cui non arrivi l'ack # wait ACK ack, addrServer = socketGaucho.recvfrom(1024) # aspetto gli ACK per tutti e tre i messaggi if bytes.decode(ack) == 'BMP-280 - ACK': nACKB = True print(bytes.decode(ack)) time.sleep(1) elif bytes.decode(ack) == 'SHT-31 - ACK': nACKS = True print(bytes.decode(ack)) time.sleep(1) elif bytes.decode(ack) == 'DHT-22 - ACK': nACKD = True print(bytes.decode(ack)) time.sleep(1) else: # todo gestione del ri-invio del messaggio. Pensare se introdurre un ID univoco (magari sequenziale) del messaggio per non inserire n volte lo stesso dato. Adesso ri-invio tutto if bytes.decode(ack) == 'Unknown message': nACKB = False nACKS = False nACKD = False index = 0 while index != len(msgTosend): socketGaucho.sendto(str.encode(msgTosend[index]), (serverHOSTNAME, serverPORT)) index += 1 del msgTosend socketGaucho.close() print('All right! Socket closed') RPi.GPIO.output(pinLED, RPi.GPIO.LOW) def closeAll(err): RPi.GPIO.cleanup() print('\n\************/') print(err) sys.exit(0) if __name__ == '__main__': main()