<commit_before>from  PySide import QtCore
from model import *

from time import sleep
from threading import Thread
import serial
import serial.tools.list_ports
import pickle

class Controller(Thread):
    
    def __init__(self, exp=[], incubator=None):
        Thread.__init__(self)
        self.experiment = exp
        self.pastLightHistory=[]
        self.futureLightHistory=[]
        self.incubator = incubator
        self.ser = None
        self.previousLightState = None
    
    def run(self):
  
        self.isExperimentRunning = None
        
        try:
            time = QtCore.QDateTime.currentDateTime()
            #self.debugTime = time
            actualDate = time.date()
            
            timer = QtCore.QElapsedTimer()
        
            isSerialOpen=self.openSerial(self.incubator)
            print (isSerialOpen)
            
            if isSerialOpen:
                self.mainController()
                ##timer to only call the function every minute.
                #self.timer.timeout.connect(self.mainController)
                self.simulateExperiment(time)
                self.isExperimentRunning = True
                self.previousLightState = None
                timer.start()
                while self.isExperimentRunning==True:
                    if timer.elapsed() > 60000:
                        self.mainController()
                        timer.restart()
                        #self.isExperimentRunning = True
                    sleep(0.2)
                
                self.closeSerial()
                print ("serial closed")
            else:
                self.isExperimentRunning = False
               
        except Exception as e:
            self.closeSerial()
            print(e)
            self.isExperimentRunning = False

        
    
    def mainController(self):
        ##Get the actual period
        actualTime = QtCore.QDateTime.currentDateTime()
        currentDate = actualTime.date()
        self.currentPeriod = self.periodActive(actualTime)
        #actualTime = self.debugTime
        #currentDate = actualTime.date()
        #self.currentPeriod = self.periodActive(actualTime)
        try:
            
            if self.currentPeriod is None:
                self.isExperimentRunning = False
                
            else:
                period = self.experiment[self.currentPeriod]
                #check if it is the last period.
                colour = period.lightColour
                isRampingOn = period.isRampingOn
                rampPercent = 1
                ##Decide if the lights needs to be on or off
                if period.isLL:
                        #ramping on first day:
                        endsRamping = period.switchOnTime.addSecs(period.rampingTime*3600)
                        
                        if (period.dateStartTime.__eq__(actualTime.date()) 
                            and period.switchOnTime.__gt__(actualTime.time())):
                            self.writeDataToArduino(False, colour)
                            self.pastLightHistory.append([0,colour[0], 
                                                        colour[1],colour[2],colour[3],rampPercent])
                        elif (period.dateStartTime.__eq__(actualTime.date())
                            and endsRamping.__gt__(actualTime.time())):
                            
                            colour, rampPercent = self.rampingProccesing(actualTime.time(), isRampingOn, period)
                            self.writeDataToArduino(True, colour)
                            self.pastLightHistory.append([1,colour[0], 
                                                        colour[1],colour[2],colour[3],rampPercent])
                        else:
                            colour, rampPercent = self.rampingProccesing(actualTime.time(), False, period)
                            self.writeDataToArduino(True, colour)
                            self.pastLightHistory.append([1,colour[0], 
                                                        colour[1],colour[2],colour[3],rampPercent])
                            
     
                elif period.isDD:
                    if (period.dateStartTime.__eq__(actualTime.date()) 
                        and period.switchOnTime.__gt__(actualTime.time())):
                        self.writeDataToArduino(False, colour)
                        self.pastLightHistory.append([0,colour[0], 
                                                        colour[1],colour[2],colour[3],rampPercent])
                    else:
                        self.writeDataToArduino(False, colour)
                        self.pastLightHistory.append([0,colour[0], 
                                                        colour[1],colour[2],colour[3], rampPercent])
                

                elif self.isHourInIntervalSim(self.currentPeriod,
                                            period.switchOnTime,
                                            period.switchOffTime,
                                            actualTime):
                    colour, rampPercent = self.rampingProccesing(actualTime.time(), isRampingOn, period)
                    self.writeDataToArduino(True, colour)
                    self.pastLightHistory.append([1,colour[0], 
                                                        colour[1],colour[2],colour[3], rampPercent])
                    #print("on")
                else:
                    if period.isLM:
                        #white soft colour, minimum intensity
                        colour = [0,0,0,2]
                        self.writeDataToArduino(True, colour)
                        self.pastLightHistory.append([0,colour[0], 
                                                    colour[1],colour[2],colour[3],rampPercent])
                    else:
                        self.writeDataToArduino(False,colour)
                        self.pastLightHistory.append([0,colour[0], 
                                                        colour[1],colour[2],colour[3], rampPercent])
                    #print("off")
            #self.debugTime = self.debugTime.addMSecs(60000) #add 1min
            ##Simulate the full experiment ahead
            #self.simulateExperiment(time)
        except Exception as e:
            print (e)
            self.isExperimentRunning = False     

    ##Gets the period that is active
    def periodActive(self, actualTime):
        currentDate = actualTime.date()
        NextItem = 1
        last = False
        first = True
        for period in self.experiment:
            ##ADD the hour of starting for the next period, por si coinciden en un periodo el dia de
            ## acabar y empezar es decir para periodos de menos de 24 horas
            currentPeriod = None 
            try:
                index = self.experiment.index(period)+1
                nextPeriod = self.experiment[index]
            except:
                last = True
            
            #check if logic inverted
            if period.switchOffTime.__le__(period.switchOnTime):
                #logich inverted
                if (period.dateStartTime.__le__(currentDate) 
                    and period.dateEndTime.__ge__(currentDate)):
                    if (last == False
                        and period.dateEndTime.__eq__(nextPeriod.dateStartTime) 
                        and period.dateEndTime.__eq__(actualTime.date())
                        #and period.switchOffTime.__le__(nextPeriod.switchOnTime)
                        and nextPeriod.switchOnTime.__le__(actualTime.time())):
                        #and period.switchOnTime.__lt__(actualTime.time())):
                        if last == True:
                            currentPeriod = None
                        else:
                            currentPeriod =  self.experiment.index(period)+1
                    else:    
                        #if the last, return None
                        currentPeriod =  self.experiment.index(period)
                        break
            else:
                    #normal logic
                if (period.dateStartTime.__le__(currentDate) 
                    and period.dateEndTime.__ge__(currentDate)):
                    if (last == False
                        and period.dateEndTime.__eq__(nextPeriod.dateStartTime) 
                        and period.dateEndTime.__eq__(actualTime.date())
                        #and period.switchOffTime.__le__(nextPeriod.switchOnTime)
                        and nextPeriod.switchOnTime.__le__(actualTime.time())):
                        #and period.switchOffTime.__lt__(actualTime.time())):
                        if last == True:
                            currentPeriod = None
                        else:
                            currentPeriod =  self.experiment.index(period)+1
                    else:
                        currentPeriod =  self.experiment.index(period)
                        break ##catch only the first ocurrence
                        
            NextItem += 1
            first=False
        return currentPeriod
            
    ##Decide if the lights needs to be on or off               
    def isHourInInterval(self):
        period = self.currentPeriod
        on = self.experiment[period].switchOnTime
        off = self.experiment[period].switchOffTime
        currentTime = QtCore.QTime.currentTime()

        
        if  off.__le__(on):
            #logic inverted
            if on.__ge__(currentTime) and off.__le__(currentTime):
                #inverted logic, lights off!
                actualLightState = self.previousLightState 
            else:
                #lights on!
                actualLightState = True 
        elif off.__ge__(on):
            #standart logic
            if  on.__le__(currentTime) and off.__ge__(currentTime):
                #lights on!
                actualLightState = self.previousLightState 
            else:
                #lights Off!
                actualLightState = False
        
        return actualLightState
        
        
    def isHourInIntervalSim(self, period,on,off,actualTime):     
        p = self.experiment[period]
        hour = actualTime.time()
        date = actualTime.date()
        
        if  off.__le__(on):
            #logic inverted
            if p.dateStartTime.__eq__(date) and on.__ge__(hour):
                #inverted logic, lights off!
                actualLightState = self.previousLightState  
            elif on.__ge__(hour) and off.__le__(hour):
                #check if it is the first day of the period to avoid extrange behaviour
                 actualLightState = False
            else:
                #lights on!
                 actualLightState = True
                
        elif off.__ge__(on):
            #standart logic
            if p.dateStartTime.__eq__(date) and on.__ge__(hour):
                #inverted logic, lights off!
                actualLightState = self.previousLightState 
            elif  on.__le__(hour) and off.__ge__(hour):
                #lights on!
                 actualLightState = True 
            else:
                #lights Off!
                 actualLightState = False 
                 
        self.previousLightState = actualLightState
                 
        return actualLightState
    
    def simulateExperiment(self, startTime, hours = None):
        if hours is None:
            hours = 1200 #45 days of simulation if nothing given!
            
        timeToSimulate = hours*60*60*1000
        futureTime = startTime
        self.futureLightHistory = []
        timeSimulationEnds=startTime.addMSecs(timeToSimulate)
        while futureTime < timeSimulationEnds:
            
            futureDate = futureTime.date()
            
            futurePeriod = self.periodActive(futureTime)
            
            if futurePeriod is None:
                self.futureLightHistory.append([-1,0,0,0,0,0])
                self.endExperimentTime = futureTime
                #print(self.futureLightHistory)
                break
            else:
                ## Get the active colour lights
                period = self.experiment[futurePeriod]
                colour = period.lightColour
                isRampingOn = period.isRampingOn
                rampPercent = 1
                ##Decide if the lights needs to be on or off
                if self.experiment[futurePeriod].isLL:
                    #ramping on first day:
                    endsRamping = period.switchOnTime.addSecs(period.rampingTime*3600)
                    
                    if (period.dateStartTime.__eq__(futureTime.date()) 
                        and period.switchOnTime.__gt__(futureTime.time())):
                        self.futureLightHistory.append([0,colour[0], 
                                                    colour[1],colour[2],colour[3],rampPercent])
                    elif (period.dateStartTime.__eq__(futureTime.date())
                        and endsRamping.__gt__(futureTime.time())):
                        colour, rampPercent = self.rampingProccesing(futureTime.time(), isRampingOn, period)
                        self.futureLightHistory.append([1,colour[0], 
                                                    colour[1],colour[2],colour[3],rampPercent])
                    else:
                        colour, rampPercent = self.rampingProccesing(futureTime.time(), False, period)
                        self.futureLightHistory.append([1,colour[0], 
                                                    colour[1],colour[2],colour[3],rampPercent])

                elif self.experiment[futurePeriod].isDD:
                    if (period.dateStartTime.__eq__(futureTime.date()) 
                        and period.switchOnTime.__gt__(futureTime.time())):
                        self.futureLightHistory.append([0,colour[0], 
                                                    colour[1],colour[2],colour[3],rampPercent])
                    else:
                        self.futureLightHistory.append([0,colour[0], 
                                                    colour[1],colour[2],colour[3], rampPercent])

                elif self.isHourInIntervalSim(futurePeriod,
                                              period.switchOnTime,
                                              period.switchOffTime,
                                              futureTime):
                    colour, rampPercent = self.rampingProccesing(futureTime.time(), isRampingOn, period)
                    self.futureLightHistory.append([1,colour[0], 
                                                    colour[1],colour[2],colour[3], rampPercent])

                else:
                    self.futureLightHistory.append([0,colour[0], 
                                                    colour[1],colour[2],colour[3], rampPercent])

            futureTime = futureTime.addMSecs(60000) #add 1min
            
            #print("Sim ended")
            
    def openSerial(self, incubator):
        SNR = 0
        for port in serial.tools.list_ports.comports():
            if port[2].find('SNR=')>0:
                SNR = port[2][port[2].find('SNR=')+4:]
            elif port[2].find('PID'):
                SNR = port[2][port[2].find('PID'):]
            else:
                SNR = None     
            
            if SNR != None: 
                if incubator['SN'] == SNR:
                    print (port[0])
                    self.ser = serial.Serial(port[0], 9600)
                    self.ser.write(b'C\r')
                    sleep(1)
                    res = self.ser.readline()
                    print (res.find(b'Led controller'))
                    if res.find(b'Led controller')>=0 :
                        print("Arduino connected")
                        #block the arduino during experimnent to prevent errors
                        f = open('config.cfg','rb')
                        incubators= pickle.load(f)
                        for i in incubators:
                            if i['SN'] == incubator['SN']:
                                i.update(isRunning=True)
                        #print (incubators)
                        f.close()
                        with open('config.cfg', 'wb') as f:
                            pickle.dump(incubators,f, pickle.HIGHEST_PROTOCOL)
                    
                        return True
                    
                    else:
                        print("error, Not a Led controller")
                        self.ser.__del__()
                        self.isExperimentRunning=False
                        return False
                        
                        
    
    def closeSerial(self):
        if self.ser._isOpen:
            self.writeDataToArduino(False,[0,0,0,0])
            self.ser.__del__()
        f = open('config.cfg','rb')
        incubators= pickle.load(f)
        for i in incubators:
            if i['SN'] == self.incubator['SN']:
                i.update(isRunning=False)
        #print (incubators)
        f.close()
        with open('config.cfg', 'wb') as f:
            pickle.dump(incubators,f, pickle.HIGHEST_PROTOCOL)
    
    def serialPorts():
        """
        Returns a generator for all available serial ports
        """
        if os.name == 'nt':
            # windows
            for i in range(256):
                try:
                    s = serial.Serial(i)
                    s.close()
                    yield 'COM' + str(i + 1)
                except serial.SerialException:<commit_msg>update line for pyserial is_open<commit_after>from  PySide import QtCore
from model import *

from time import sleep
from threading import Thread
import serial
import serial.tools.list_ports
import pickle

class Controller(Thread):
    
    def __init__(self, exp=[], incubator=None):
        Thread.__init__(self)
        self.experiment = exp
        self.pastLightHistory=[]
        self.futureLightHistory=[]
        self.incubator = incubator
        self.ser = None
        self.previousLightState = None
    
    def run(self):
  
        self.isExperimentRunning = None
        
        try:
            time = QtCore.QDateTime.currentDateTime()
            #self.debugTime = time
            actualDate = time.date()
            
            timer = QtCore.QElapsedTimer()
        
            isSerialOpen=self.openSerial(self.incubator)
            print (isSerialOpen)
            
            if isSerialOpen:
                self.mainController()
                ##timer to only call the function every minute.
                #self.timer.timeout.connect(self.mainController)
                self.simulateExperiment(time)
                self.isExperimentRunning = True
                self.previousLightState = None
                timer.start()
                while self.isExperimentRunning==True:
                    if timer.elapsed() > 60000:
                        self.mainController()
                        timer.restart()
                        #self.isExperimentRunning = True
                    sleep(0.2)
                
                self.closeSerial()
                print ("serial closed")
            else:
                self.isExperimentRunning = False
               
        except Exception as e:
            self.closeSerial()
            print(e)
            self.isExperimentRunning = False

        
    
    def mainController(self):
        ##Get the actual period
        actualTime = QtCore.QDateTime.currentDateTime()
        currentDate = actualTime.date()
        self.currentPeriod = self.periodActive(actualTime)
        #actualTime = self.debugTime
        #currentDate = actualTime.date()
        #self.currentPeriod = self.periodActive(actualTime)
        try:
            
            if self.currentPeriod is None:
                self.isExperimentRunning = False
                
            else:
                period = self.experiment[self.currentPeriod]
                #check if it is the last period.
                colour = period.lightColour
                isRampingOn = period.isRampingOn
                rampPercent = 1
                ##Decide if the lights needs to be on or off
                if period.isLL:
                        #ramping on first day:
                        endsRamping = period.switchOnTime.addSecs(period.rampingTime*3600)
                        
                        if (period.dateStartTime.__eq__(actualTime.date()) 
                            and period.switchOnTime.__gt__(actualTime.time())):
                            self.writeDataToArduino(False, colour)
                            self.pastLightHistory.append([0,colour[0], 
                                                        colour[1],colour[2],colour[3],rampPercent])
                        elif (period.dateStartTime.__eq__(actualTime.date())
                            and endsRamping.__gt__(actualTime.time())):
                            
                            colour, rampPercent = self.rampingProccesing(actualTime.time(), isRampingOn, period)
                            self.writeDataToArduino(True, colour)
                            self.pastLightHistory.append([1,colour[0], 
                                                        colour[1],colour[2],colour[3],rampPercent])
                        else:
                            colour, rampPercent = self.rampingProccesing(actualTime.time(), False, period)
                            self.writeDataToArduino(True, colour)
                            self.pastLightHistory.append([1,colour[0], 
                                                        colour[1],colour[2],colour[3],rampPercent])
                            
     
                elif period.isDD:
                    if (period.dateStartTime.__eq__(actualTime.date()) 
                        and period.switchOnTime.__gt__(actualTime.time())):
                        self.writeDataToArduino(False, colour)
                        self.pastLightHistory.append([0,colour[0], 
                                                        colour[1],colour[2],colour[3],rampPercent])
                    else:
                        self.writeDataToArduino(False, colour)
                        self.pastLightHistory.append([0,colour[0], 
                                                        colour[1],colour[2],colour[3], rampPercent])
                

                elif self.isHourInIntervalSim(self.currentPeriod,
                                            period.switchOnTime,
                                            period.switchOffTime,
                                            actualTime):
                    colour, rampPercent = self.rampingProccesing(actualTime.time(), isRampingOn, period)
                    self.writeDataToArduino(True, colour)
                    self.pastLightHistory.append([1,colour[0], 
                                                        colour[1],colour[2],colour[3], rampPercent])
                    #print("on")
                else:
                    if period.isLM:
                        #white soft colour, minimum intensity
                        colour = [0,0,0,2]
                        self.writeDataToArduino(True, colour)
                        self.pastLightHistory.append([0,colour[0], 
                                                    colour[1],colour[2],colour[3],rampPercent])
                    else:
                        self.writeDataToArduino(False,colour)
                        self.pastLightHistory.append([0,colour[0], 
                                                        colour[1],colour[2],colour[3], rampPercent])
                    #print("off")
            #self.debugTime = self.debugTime.addMSecs(60000) #add 1min
            ##Simulate the full experiment ahead
            #self.simulateExperiment(time)
        except Exception as e:
            print (e)
            self.isExperimentRunning = False     

    ##Gets the period that is active
    def periodActive(self, actualTime):
        currentDate = actualTime.date()
        NextItem = 1
        last = False
        first = True
        for period in self.experiment:
            ##ADD the hour of starting for the next period, por si coinciden en un periodo el dia de
            ## acabar y empezar es decir para periodos de menos de 24 horas
            currentPeriod = None 
            try:
                index = self.experiment.index(period)+1
                nextPeriod = self.experiment[index]
            except:
                last = True
            
            #check if logic inverted
            if period.switchOffTime.__le__(period.switchOnTime):
                #logich inverted
                if (period.dateStartTime.__le__(currentDate) 
                    and period.dateEndTime.__ge__(currentDate)):
                    if (last == False
                        and period.dateEndTime.__eq__(nextPeriod.dateStartTime) 
                        and period.dateEndTime.__eq__(actualTime.date())
                        #and period.switchOffTime.__le__(nextPeriod.switchOnTime)
                        and nextPeriod.switchOnTime.__le__(actualTime.time())):
                        #and period.switchOnTime.__lt__(actualTime.time())):
                        if last == True:
                            currentPeriod = None
                        else:
                            currentPeriod =  self.experiment.index(period)+1
                    else:    
                        #if the last, return None
                        currentPeriod =  self.experiment.index(period)
                        break
            else:
                    #normal logic
                if (period.dateStartTime.__le__(currentDate) 
                    and period.dateEndTime.__ge__(currentDate)):
                    if (last == False
                        and period.dateEndTime.__eq__(nextPeriod.dateStartTime) 
                        and period.dateEndTime.__eq__(actualTime.date())
                        #and period.switchOffTime.__le__(nextPeriod.switchOnTime)
                        and nextPeriod.switchOnTime.__le__(actualTime.time())):
                        #and period.switchOffTime.__lt__(actualTime.time())):
                        if last == True:
                            currentPeriod = None
                        else:
                            currentPeriod =  self.experiment.index(period)+1
                    else:
                        currentPeriod =  self.experiment.index(period)
                        break ##catch only the first ocurrence
                        
            NextItem += 1
            first=False
        return currentPeriod
            
    ##Decide if the lights needs to be on or off               
    def isHourInInterval(self):
        period = self.currentPeriod
        on = self.experiment[period].switchOnTime
        off = self.experiment[period].switchOffTime
        currentTime = QtCore.QTime.currentTime()

        
        if  off.__le__(on):
            #logic inverted
            if on.__ge__(currentTime) and off.__le__(currentTime):
                #inverted logic, lights off!
                actualLightState = self.previousLightState 
            else:
                #lights on!
                actualLightState = True 
        elif off.__ge__(on):
            #standart logic
            if  on.__le__(currentTime) and off.__ge__(currentTime):
                #lights on!
                actualLightState = self.previousLightState 
            else:
                #lights Off!
                actualLightState = False
        
        return actualLightState
        
        
    def isHourInIntervalSim(self, period,on,off,actualTime):     
        p = self.experiment[period]
        hour = actualTime.time()
        date = actualTime.date()
        
        if  off.__le__(on):
            #logic inverted
            if p.dateStartTime.__eq__(date) and on.__ge__(hour):
                #inverted logic, lights off!
                actualLightState = self.previousLightState  
            elif on.__ge__(hour) and off.__le__(hour):
                #check if it is the first day of the period to avoid extrange behaviour
                 actualLightState = False
            else:
                #lights on!
                 actualLightState = True
                
        elif off.__ge__(on):
            #standart logic
            if p.dateStartTime.__eq__(date) and on.__ge__(hour):
                #inverted logic, lights off!
                actualLightState = self.previousLightState 
            elif  on.__le__(hour) and off.__ge__(hour):
                #lights on!
                 actualLightState = True 
            else:
                #lights Off!
                 actualLightState = False 
                 
        self.previousLightState = actualLightState
                 
        return actualLightState
    
    def simulateExperiment(self, startTime, hours = None):
        if hours is None:
            hours = 1200 #45 days of simulation if nothing given!
            
        timeToSimulate = hours*60*60*1000
        futureTime = startTime
        self.futureLightHistory = []
        timeSimulationEnds=startTime.addMSecs(timeToSimulate)
        while futureTime < timeSimulationEnds:
            
            futureDate = futureTime.date()
            
            futurePeriod = self.periodActive(futureTime)
            
            if futurePeriod is None:
                self.futureLightHistory.append([-1,0,0,0,0,0])
                self.endExperimentTime = futureTime
                #print(self.futureLightHistory)
                break
            else:
                ## Get the active colour lights
                period = self.experiment[futurePeriod]
                colour = period.lightColour
                isRampingOn = period.isRampingOn
                rampPercent = 1
                ##Decide if the lights needs to be on or off
                if self.experiment[futurePeriod].isLL:
                    #ramping on first day:
                    endsRamping = period.switchOnTime.addSecs(period.rampingTime*3600)
                    
                    if (period.dateStartTime.__eq__(futureTime.date()) 
                        and period.switchOnTime.__gt__(futureTime.time())):
                        self.futureLightHistory.append([0,colour[0], 
                                                    colour[1],colour[2],colour[3],rampPercent])
                    elif (period.dateStartTime.__eq__(futureTime.date())
                        and endsRamping.__gt__(futureTime.time())):
                        colour, rampPercent = self.rampingProccesing(futureTime.time(), isRampingOn, period)
                        self.futureLightHistory.append([1,colour[0], 
                                                    colour[1],colour[2],colour[3],rampPercent])
                    else:
                        colour, rampPercent = self.rampingProccesing(futureTime.time(), False, period)
                        self.futureLightHistory.append([1,colour[0], 
                                                    colour[1],colour[2],colour[3],rampPercent])

                elif self.experiment[futurePeriod].isDD:
                    if (period.dateStartTime.__eq__(futureTime.date()) 
                        and period.switchOnTime.__gt__(futureTime.time())):
                        self.futureLightHistory.append([0,colour[0], 
                                                    colour[1],colour[2],colour[3],rampPercent])
                    else:
                        self.futureLightHistory.append([0,colour[0], 
                                                    colour[1],colour[2],colour[3], rampPercent])

                elif self.isHourInIntervalSim(futurePeriod,
                                              period.switchOnTime,
                                              period.switchOffTime,
                                              futureTime):
                    colour, rampPercent = self.rampingProccesing(futureTime.time(), isRampingOn, period)
                    self.futureLightHistory.append([1,colour[0], 
                                                    colour[1],colour[2],colour[3], rampPercent])

                else:
                    self.futureLightHistory.append([0,colour[0], 
                                                    colour[1],colour[2],colour[3], rampPercent])

            futureTime = futureTime.addMSecs(60000) #add 1min
            
            #print("Sim ended")
            
    def openSerial(self, incubator):
        SNR = 0
        for port in serial.tools.list_ports.comports():
            if port[2].find('SNR=')>0:
                SNR = port[2][port[2].find('SNR=')+4:]
            elif port[2].find('PID'):
                SNR = port[2][port[2].find('PID'):]
            else:
                SNR = None     
            
            if SNR != None: 
                if incubator['SN'] == SNR:
                    print (port[0])
                    self.ser = serial.Serial(port[0], 9600)
                    self.ser.write(b'C\r')
                    sleep(1)
                    res = self.ser.readline()
                    print (res.find(b'Led controller'))
                    if res.find(b'Led controller')>=0 :
                        print("Arduino connected")
                        #block the arduino during experimnent to prevent errors
                        f = open('config.cfg','rb')
                        incubators= pickle.load(f)
                        for i in incubators:
                            if i['SN'] == incubator['SN']:
                                i.update(isRunning=True)
                        #print (incubators)
                        f.close()
                        with open('config.cfg', 'wb') as f:
                            pickle.dump(incubators,f, pickle.HIGHEST_PROTOCOL)
                    
                        return True
                    
                    else:
                        print("error, Not a Led controller")
                        self.ser.__del__()
                        self.isExperimentRunning=False
                        return False
                        
                        
    
    def closeSerial(self):
        if self.ser.is_open:
            self.writeDataToArduino(False,[0,0,0,0])
            self.ser.__del__()
        f = open('config.cfg','rb')
        incubators= pickle.load(f)
        for i in incubators:
            if i['SN'] == self.incubator['SN']:
                i.update(isRunning=False)
        #print (incubators)
        f.close()
        with open('config.cfg', 'wb') as f:
            pickle.dump(incubators,f, pickle.HIGHEST_PROTOCOL)
    
    def serialPorts():
        """
        Returns a generator for all available serial ports
        """
        if os.name == 'nt':
            # windows
            for i in range(256):
                try:
                    s = serial.Serial(i)
                    s.close()
                    yield 'COM' + str(i + 1)
                except serial.SerialException:
{'fraction_non_alphanumeric': 0.08186572438162544, 'fraction_numerical': 0.009045936395759718, 'mean_word_length': 1.196039481035446, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 84, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1308931', 'n_tokens_mistral': 8717, 'n_tokens_neox': 7999, 'n_words': 1627}