Example #1
0
class FermentControl:

    THREADS = 4 

    sensor_logger = None
    fridge_control = None
    logger = None
    control = None

    def __init__(self):
        print("OpenBrew - Ferment")

        # Setup the config parser
        self.config = ConfigParser()
        self.config.readfp(open('config.cfg'))

        # Make sure we have a connection to the database
        # http://initd.org/psycopg/docs/
        dsn = "host=" + self.config['database']['host'] + " dbname=" + self.config['database']['database'] + " user="******" password="******"Running...")

        self.sensor_logger = SensorLogger(self.config, self.dbconn)
        self.fridge_control = FridgeControl(self.config, self.dbconn)
        self.control = ControlInterface(self.logger, self.dbconn, self.config)

        children = []

        for process in range(self.THREADS):
            pid = os.fork()
            if pid:
                children.append(pid)
            else:
                self.runFermentThread(process)
                os._exit(0)

        for i, child in enumerate(children):
            os.waitpid(child, 0)

    def runFermentThread(self, process):
        print 'This is process thread {0} for fermenter tasks'.format(process)
        if process is 0:
            self.sensor_logger.actions()
        elif process is 1:
            self.fridge_control.actions(1)
        elif process is 2:
            self.fridge_control.actions(2)
        elif process is 3:
            self.control.interface()
Example #2
0
    def __init__(self, logger):
        #initialize
        super(MPU6050, self).__init__(logger)
        self.sensorlogger = SensorLogger('MPU6050',logger)
        self.mutex = threading.Semaphore(1)
        self.mpu = MPU6050BASE()
        self.mpu.dmpInitialize()
        self.mpu.setDMPEnabled(True)

        # get expected DMP packet size for later comparison
        self.packetSize = self.mpu.dmpGetFIFOPacketSize()
Example #3
0
 def __init__(self, logger, device):
     super(Serial, self).__init__(logger)
     #Logger for voltage sensor
     self.voltagelogger = SensorLogger('Voltage',logger)
     #Set serial with baudrate 9600 and a timeout of 3 seconds
     self.ser = serial.Serial(device, baudrate=9600, timeout=3.0)
     #Flushes the input. If we don't flush the input we will recieve old input.
     self.ser.flushInput()
     #Semaphores
     self.mutex1 = threading.Semaphore(1)
     self.mutex2 = threading.Semaphore(1)
     self.mutexVoltage = threading.Semaphore(1)
     self.mutexButton = threading.Semaphore(1)
Example #4
0
    def run(self):
        print("Running...")

        self.sensor_logger = SensorLogger(self.config, self.dbconn)
        self.fridge_control = FridgeControl(self.config, self.dbconn)
        self.control = ControlInterface(self.logger, self.dbconn, self.config)

        children = []

        for process in range(self.THREADS):
            pid = os.fork()
            if pid:
                children.append(pid)
            else:
                self.runFermentThread(process)
                os._exit(0)

        for i, child in enumerate(children):
            os.waitpid(child, 0)
Example #5
0
class Serial(Sensor):
    # Interval in seconds
    interval = 0.1

    sensor1 = 0
    sensor2 = 0
    button = False
    voltage = 0
    voltageCounter = 0

    def __init__(self, logger, device):
        super(Serial, self).__init__(logger)
        #Logger for voltage sensor
        self.voltagelogger = SensorLogger('Voltage',logger)
        #Set serial with baudrate 9600 and a timeout of 3 seconds
        self.ser = serial.Serial(device, baudrate=9600, timeout=3.0)
        #Flushes the input. If we don't flush the input we will recieve old input.
        self.ser.flushInput()
        #Semaphores
        self.mutex1 = threading.Semaphore(1)
        self.mutex2 = threading.Semaphore(1)
        self.mutexVoltage = threading.Semaphore(1)
        self.mutexButton = threading.Semaphore(1)

    def run(self):
        while self.alive:
            #Gets the sensor values
            self.getValues()
            #Sleep
            time.sleep(self.interval)

    def getValues(self):
        #Readline from serial
        responses = self.ser.readline()
        responses = responses.decode('ascii')
        #Remove characters that we don't need
        responses = responses.replace("\r\n","")
        responses = responses.replace("\x00","")
        responses = responses.replace("n'","")
        responses = responses.replace("'","")
        #split the line
        responses = responses.split(',')
        #loop through the responses
        for response in responses:
            #Checks if we need the response
            if len(response) > 2:
                #Convert to int
                response = int(response)
                #Voltage
                if(response < 2000):
                    voltage = float(response) / float(100)
                    self.setVoltage(voltage)
                #First glove sensor
                if(response >= 2000 and response < 2500):
                    sensor1 = response - 2000
                    self.setSensor1(sensor1)
                #Second glove sensor
                elif(response >= 2500 and response < 3000):
                    sensor2 = response - 2500
                    self.setSensor2(sensor2)
                #Light sensor off
                elif(response == 3001):
                    self.setButton(False)
                #Light sensor on
                elif(response == 3002):
                    self.setButton(True)


    def stop(self):
        #Stop loop
        self.alive = False

    def start(self):
        #Start loop
        self.thread.start()

    def getSensor1(self):
        #Mutex
        self.mutex1.acquire()
        value = self.sensor1
        self.mutex1.release()
        return value

    def setSensor1(self, value):
        #Mutex
        self.mutex1.acquire()
        self.sensor1 = value
        self.mutex1.release()

    def getSensor2(self):
        #Mutex
        self.mutex2.acquire()
        value = self.sensor2
        self.mutex2.release()
        return value

    def setSensor2(self, value):
        #Mutex
        self.mutex2.acquire()
        self.sensor2 = value
        self.mutex2.release()

    def getButton(self):
        #Mutex
        self.mutexButton.acquire()
        value = self.button
        self.mutexButton.release()
        return value

    def setButton(self, value):
        #Mutex
        self.mutexButton.acquire()
        self.button = value
        self.mutexButton.release()

    def getVoltage(self):
        #Mutex
        self.mutexVoltage.acquire()
        value = self.voltage
        self.mutexVoltage.release()
        return value

    def setVoltage(self, value):
        #Mutex
        self.mutexVoltage.acquire()
        self.voltage = value
        #Log every ten times
        if self.voltageCounter == 0 or self.voltageCounter == 10:
            self.voltageCounter = 0
            self.voltagelogger.log_waarde("{0:.2f}".format(self.voltage))
            if self.voltageCounter  <=9.2 and self.voltageCounter != 0 :
                import os
                os.system("sudo poweroff")

        self.mutexVoltage.release()
Example #6
0
    # Remove residual files from the previous run (removes all files in the current and processing dir)
    remove_residual_files()

    # Get a dictionary of sensors and their status
    sensors = get_sensors()

    # Join the LoRa network
    lora = False
    if (True in sensors.values()
            or gps_on) and config.get_config("LORA") == "ON":
        lora = LoRaWAN(status_logger)

    # Initialise temperature and humidity sensor thread with id: TEMP
    if sensors[s.TEMP]:
        TEMP_logger = SensorLogger(sensor_name=s.TEMP, terminal_out=True)
        if config.get_config(s.TEMP) == "SHT35":
            temp_sensor = TempSHT35(TEMP_logger, status_logger)
    status_logger.info("Temperature and humidity sensor initialised")

    # Initialise PM power circuitry
    PM_transistor = Pin('P20', mode=Pin.OUT)
    PM_transistor.value(0)
    if config.get_config(s.PM1) != "OFF" or config.get_config(s.PM2) != "OFF":
        PM_transistor.value(1)

    # Initialise PM sensor threads
    if sensors[s.PM1]:
        initialise_pm_sensor(sensor_name=s.PM1,
                             pins=('P3', 'P17'),
                             serial_id=1,
Example #7
0
def pm_thread(sensor_name, status_logger, pins, serial_id):
    """
    Method to run as a thread that reads, processes and logs readings form pm sensors according to their type
    :param sensor_name: PM1 or PM2
    :type sensor_name: str
    :param status_logger: status logger
    :type status_logger: LoggerFactory object
    :param pins: serial bus pins (TX, RX)
    :type pins: tuple(int, int)
    :param serial_id: serial bus id (0, 1 or 2)
    :type serial_id: int
    """

    status_logger.debug("Thread {} started".format(sensor_name))

    sensor_logger = SensorLogger(sensor_name=sensor_name, terminal_out=True)

    sensor_type = config.get_config(sensor_name)
    init_time = int(config.get_config(sensor_name + "_init"))

    init_count = 0

    if sensor_type == "PMS5003":

        # initialise sensor
        sensor = Plantower(pins=pins, id=serial_id)

        time.sleep(1)

        # warm up time  - readings are not logged
        while init_count < init_time:
            try:
                time.sleep(1)
                sensor.read()
                init_count += 1
            except PlantowerException as e:
                status_logger.exception("Failed to read from sensor PMS5003")
                blink_led((0x550000, 0.4, True))

    elif sensor_type == "SPS030":

        # initialise sensor
        while True:
            try:
                sensor = Sensirion(
                    retries=1, pins=pins,
                    id=serial_id)  # automatically starts measurement
                break
            except SensirionException as e:
                status_logger.exception("Failed to read from sensor SPS030")
                blink_led((0x550000, 0.4, True))
                time.sleep(1)

        # warm up time  - readings are not logged
        while init_count < init_time:
            try:
                time.sleep(1)
                sensor.read()
                init_count += 1
            except SensirionException as e:
                status_logger.exception("Failed to read from sensor SPS030")
                blink_led((0x550000, 0.4, True))

    # start a periodic timer interrupt to poll readings every second
    processing_alarm = Timer.Alarm(process_readings,
                                   arg=(sensor_type, sensor, sensor_logger,
                                        status_logger),
                                   s=1,
                                   periodic=True)
Example #8
0
 def run(self):
     print("Running..")
     
     brews = 1
     brewcount = 0
     
     # add the pumps
     hlt_recirc = Pump(Pump.PUMP_BROWN)
     mlt_recirc = Pump(Pump.PUMP_MARCH)
     transfer   = Pump(Pump.PUMP_MARCH)
     
     # This will run forever.
     while True:        
     
         # Initially this will just be doing a single batch at a time
         # but this could allow recipes to be stacked.
         try:
             # load the recipe xml
             recipe = Recipe('step_mash_recipe.xml')
     
             # parse the recipe xml
             recipe.parse()
         except Exception as e:
             error_str = "Recipe parsing failed!"
             self.logger.critical(error_str)
             print(error_str)
             
         print("Mash steps are:")
         mash_steps = recipe.get_mash_steps()
         
         for steps in mash_steps:
             print(steps.tag, steps.attrib)
             for step in steps:
                 print(step.tag, step.text)
         
         # setup the vessels 
         self.vessel_hlt = VesselHlt(self.logger, self.dbconn)
         self.vessel_hlt.strike_in_mlt(self.strike_in_mlt)
         self.vessel_hlt.set_target_strike_time() # UNIX timestamp
         self.vessel_hlt.add_steps(recipe.get_mash_steps())
         
         self.vessel_mlt = VesselMlt(self.logger, self.dbconn)
         self.vessel_mlt.strike_in_mlt(self.strike_in_mlt)
         self.vessel_mlt.add_steps(recipe.get_mash_steps())
         
         self.vessel_ktl = VesselKettle(self.logger, self.dbconn)
     
         self.sensor_logger = SensorLogger(self.logger, self.dbconn)
         
         self.control = ControlInterface(self.logger, self.dbconn)
     
         children = []
     
         # Create forks for each vessel.
         # from http://www.petercollingridge.co.uk/blog/running-multiple-processes-python
         start_time = time.time()
         processes = self.VESSEL_COUNT + 2 # number of vessels plus the logger and webservice threads
         for process in range(self.VESSEL_COUNT):
             pid = os.fork()
             if pid:
                 children.append(pid)
             else:
                 self.processLauncher(process)
                 os._exit(0)
         
         # Wait for all the vessels to complete.
         for i, child in enumerate(children):
             os.waitpid(child, 0)
         
         brewcount += 1
         
         if(brewcount == brews):
             print("All batches completed. Exiting.")
             os._exit(0) 
Example #9
0
class BreweryControl():

    vessel_hlt = None
    vessel_mlt = None
    vessel_ktl = None
    
    VESSEL_COUNT = 3

    config  = None
    sensors = None
    dbconn  = None
    logger  = None

    strike_in_mlt = True 

    def __init__(self):
        print("OpenBrew init.")

        # https://docs.python.org/3/library/logging.html
        logging.basicConfig(format='%(message)s', level=logging.DEBUG)
        self.logger = logging.getLogger('BreweryControl').setLevel(logging.WARNING) 

        # Setup the config parser
        self.config = ConfigParser()
        self.config.readfp(open('config.cfg'))
    
        #sensors = Sensors() 
        #sensors.load(self.config)
        
        # Make sure we have a connection to the database
        # http://initd.org/psycopg/docs/
        dsn = "dbname=" + self.config['database']['database'] + " user="******" password="******"Running..")
        
        brews = 1
        brewcount = 0
        
        # add the pumps
        hlt_recirc = Pump(Pump.PUMP_BROWN)
        mlt_recirc = Pump(Pump.PUMP_MARCH)
        transfer   = Pump(Pump.PUMP_MARCH)
        
        # This will run forever.
        while True:        
        
            # Initially this will just be doing a single batch at a time
            # but this could allow recipes to be stacked.
            try:
                # load the recipe xml
                recipe = Recipe('step_mash_recipe.xml')
        
                # parse the recipe xml
                recipe.parse()
            except Exception as e:
                error_str = "Recipe parsing failed!"
                self.logger.critical(error_str)
                print(error_str)
                
            print("Mash steps are:")
            mash_steps = recipe.get_mash_steps()
            
            for steps in mash_steps:
                print(steps.tag, steps.attrib)
                for step in steps:
                    print(step.tag, step.text)
            
            # setup the vessels 
            self.vessel_hlt = VesselHlt(self.logger, self.dbconn)
            self.vessel_hlt.strike_in_mlt(self.strike_in_mlt)
            self.vessel_hlt.set_target_strike_time() # UNIX timestamp
            self.vessel_hlt.add_steps(recipe.get_mash_steps())
            
            self.vessel_mlt = VesselMlt(self.logger, self.dbconn)
            self.vessel_mlt.strike_in_mlt(self.strike_in_mlt)
            self.vessel_mlt.add_steps(recipe.get_mash_steps())
            
            self.vessel_ktl = VesselKettle(self.logger, self.dbconn)
        
            self.sensor_logger = SensorLogger(self.logger, self.dbconn)
            
            self.control = ControlInterface(self.logger, self.dbconn)
        
            children = []
        
            # Create forks for each vessel.
            # from http://www.petercollingridge.co.uk/blog/running-multiple-processes-python
            start_time = time.time()
            processes = self.VESSEL_COUNT + 2 # number of vessels plus the logger and webservice threads
            for process in range(self.VESSEL_COUNT):
                pid = os.fork()
                if pid:
                    children.append(pid)
                else:
                    self.processLauncher(process)
                    os._exit(0)
            
            # Wait for all the vessels to complete.
            for i, child in enumerate(children):
                os.waitpid(child, 0)
            
            brewcount += 1
            
            if(brewcount == brews):
                print("All batches completed. Exiting.")
                os._exit(0) 
            # Program end.
        
    def processLauncher(self, process):
        if process is 0:
            self.sensor_logger.actions()
        elif process is 1:
            self.control.interface()
        elif process is 2:
            #self.logger.info("HLT Fork starting up")
            self.vessel_hlt.actions()
        elif process is 3:
            #self.logger.info("MLT Fork starting up")
            self.vessel_mlt.actions()
        elif process is 4:
            #self.logger.info("Kettle Fork starting up")
            self.vessel_ktl.actions()
Example #10
0
class MPU6050(Sensor):
    # Interval in seconds
    interval = 1

    # Default value
    current_value = {'yaw': 0, 'pitch': 0, 'roll': 0}

    def __init__(self, logger):
        #initialize
        super(MPU6050, self).__init__(logger)
        self.sensorlogger = SensorLogger('MPU6050',logger)
        self.mutex = threading.Semaphore(1)
        self.mpu = MPU6050BASE()
        self.mpu.dmpInitialize()
        self.mpu.setDMPEnabled(True)

        # get expected DMP packet size for later comparison
        self.packetSize = self.mpu.dmpGetFIFOPacketSize()

    #get Values
    def run(self):
        while self.alive:
            self.getValues()
            time.sleep(self.interval)

    def getValues(self):
        # Get INT_STATUS byte
        mpuIntStatus = self.mpu.getIntStatus()
        if mpuIntStatus >= 2: # check for DMP data ready interrupt (this should happen frequently)
            # get current FIFO count
            fifoCount = self.mpu.getFIFOCount()

            # check for overflow (this should never happen unless our code is too inefficient)
            if fifoCount == 1024:
                # reset so we can continue cleanly
                self.mpu.resetFIFO()
                # print('FIFO overflow!')


            # wait for correct available data length, should be a VERY short wait
            fifoCount = self.mpu.getFIFOCount()
            while fifoCount < self.packetSize:
                fifoCount = self.mpu.getFIFOCount()

            result = self.mpu.getFIFOBytes(self.packetSize)
            q = self.mpu.dmpGetQuaternion(result)
            g = self.mpu.dmpGetGravity(q)
            ypr = self.mpu.dmpGetYawPitchRoll(q, g)

            #save sensordata
            sensorData = {'yaw': ypr['yaw'] * 180 / math.pi, 'pitch': ypr['pitch'] * 180 / math.pi, 'roll': ypr['roll'] * 180 / math.pi}
            self.setValue(sensorData)
            fifoCount -= self.packetSize

            #log sensor
            self.sensorlogger.log_waarde("y:{0:.3f}, p:{1:.3f}, r:{2:.3f}".format(sensorData['yaw'], sensorData['pitch'], sensorData['roll']))
    #stop thread
    def stop(self):
        self.alive = False

    #start thread
    def start(self):
        self.thread.start()

    #get yaw, pith, roll
    def getValue(self):
        self.mutex.acquire()
        value = self.current_value
        self.mutex.release()
        return value

    #set sensorData
    def setValue(self, value):
        self.mutex.acquire()
        self.current_value = value
        self.mutex.release()