import soundcard as sc
from picamerax import PiCamera
import RPi.GPIO as GPIO
import yaml
from attrd import AttrDict
from colorama import Fore
import smbus2
import bme280
import board
import busio
from adafruit_pm25.i2c import PM25_I2C
import adafruit_bh1750
from adafruit_as7341 import AS7341
[docs]class InitDevices:
"""Initializes the audio device, the PiCamera and checks for connected light barriers and
their corresponding GPIO pins.
"""
instance = None
def __init__(self, config):
if self.instance is None:
InitDevices.instance = self
self.config = config
self.config.audio_devices = self.get_audio_devices()
self.config.camera = self.get_camera()
self.config.bme280_sensor = self.get_bme280_sensor()
self.config.bh1750_sensor = self.get_bh1750_sensor()
self.config.as7341_sensor = self.get_as7341_sensor()
self.config.pmsa003i_sensor = self.get_pmsa003i_sensor()
self.config.connected_GPIO_IR_pins = self.get_GPIO_IR_pins()
[docs] @staticmethod
def get_audio_devices():
"""Get speaker and microphone devices from the USB dongle.
:return: soundcard objects if connected else None
:rtype: object, None
"""
speakers = sc.all_speakers()
mics = sc.all_microphones()
sensor_microphone = sensor_speaker = None
for mic in mics:
if 'C-Media' in mic.id:
sensor_microphone = mic
for speaker in speakers:
if 'C-Media' in speaker.id:
sensor_speaker = speaker
if sensor_microphone is None or sensor_speaker is None:
print(Fore.RED + 'No suitable audio device found!' + Fore.WHITE)
return sensor_speaker, sensor_microphone
[docs] @staticmethod
def get_camera():
"""Initialize PiCamera if connected.
:return: picamera object if connected else None
:rtype: object, None
"""
try:
camera = PiCamera()
print(Fore.GREEN + 'PiCamera ' + camera.revision + ' detected!' + Fore.WHITE)
except Exception as e:
camera = None
print(Fore.RED + 'No PiCamera detected!' + Fore.WHITE)
return camera
[docs] @staticmethod
def get_bme280_sensor():
"""Initialize bme280 sensor for relative humidity, barometric pressure and ambient temperature if connected.
:return: sensor objects else None
:rtype: object, None
"""
port = 1
address = 0x77
bus = smbus2.SMBus(port)
try:
calibration_params = bme280.load_calibration_params(bus, address)
print('BME280 humidity sensor ' + Fore.GREEN + 'detected!' + Fore.WHITE)
except Exception as e:
calibration_params = None
print('BME280 humidity sensor ' + Fore.RED + 'not detected!' + Fore.WHITE)
return bus, address, calibration_params
[docs] @staticmethod
def get_bh1750_sensor():
"""Initialize bh1750 sensor for ambient light if connected.
:return: sensor object if connected else None
:rtype: object, None
"""
try:
i2c = board.I2C()
bh1750_sensor = adafruit_bh1750.BH1750(i2c)
print('BH1750 ambient light sensor ' + Fore.GREEN + 'detected!' + Fore.WHITE)
except Exception as e:
bh1750_sensor = None
print('BH1750 ambient light sensor ' + Fore.RED + 'not detected!' + Fore.WHITE)
return bh1750_sensor
[docs] @staticmethod
def get_as7341_sensor():
"""Initialize AS7341 10-channel spectral color sensor if connected.
:return: sensor object if connected else None
:rtype: object, None
"""
try:
i2c = board.I2C()
as7341_sensor = AS7341(i2c)
print('AS7341 spectral color sensor ' + Fore.GREEN + 'detected!' + Fore.WHITE)
except Exception as e:
as7341_sensor = None
print('AS7341 spectral color sensor ' + Fore.RED + 'not detected!' + Fore.WHITE)
return as7341_sensor
[docs] @staticmethod
def get_pmsa003i_sensor():
"""Initialize PMSA003I particulate matter (air quality) sensor if connected.
:return: sensor object if connected else None
:rtype: object, None
"""
try:
reset_pin = None
i2c = busio.I2C(board.SCL, board.SDA, frequency=100000)
pmsa003i_sensor = PM25_I2C(i2c, reset_pin)
print('PMSA003I air quality sensor ' + Fore.GREEN + 'detected!' + Fore.WHITE)
except Exception as e:
pmsa003i_sensor = None
print('PMSA003I air quality sensor ' + Fore.RED + 'not detected!' + Fore.WHITE)
return pmsa003i_sensor
[docs] def get_GPIO_IR_pins(self):
"""Get information about the GPIO pins with connected IR light barriers and sets GPIO switch for
LED flash light to low.
:return: list
:rtype: integers
"""
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
connected_GPIO_IR_list = []
GPIO_IR_pins = [self.config.GPIO_IR_1, self.config.GPIO_IR_2,
self.config.GPIO_IR_3, self.config.GPIO_IR_4]
GPIO_Switch = self.config.GPIO_Switch
GPIO.setup(GPIO_Switch, GPIO.OUT)
GPIO.output(GPIO_Switch, GPIO.LOW)
for pin in GPIO_IR_pins:
GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
if GPIO.input(pin) == GPIO.HIGH:
print('{}{} {} {} {}'.format('IR light barrier #', str(GPIO_IR_pins.index(pin)+1),
'@ GPIO pin', str(pin), Fore.RED + 'not connected!' + Fore.WHITE))
else:
print('{}{} {} {} {}'.format('IR light barrier #', str(GPIO_IR_pins.index(pin)+1),
'@ GPIO pin', str(pin), Fore.GREEN + 'connected!' + Fore.WHITE))
connected_GPIO_IR_list.append(pin)
if len(connected_GPIO_IR_list) == 0:
print(Fore.RED + 'No light barriers connected!' + Fore.WHITE)
return connected_GPIO_IR_list