def programloop(self):
        try:       
            self.master.after(5000)
            
            #make temp copy of self.ll
            self.li=copy.deepcopy(self.ll)          #deepcopy kann eigentlich keine tkinter objects kopieren, deshalb sind in der self.ll liste nur indexe fuer die self.l5 liste, die die objekte enthaelt
                                                    #honestly I don't remember why a copy of self.ll is needed. Seems to work without it, however further investigation needed
            #modify memory
            self.resetmemory('realtime',None)      
                
            

            for idx,element in enumerate(self.li):
                print(l3)

                #set hour for the whole time of correcting this device
                self.hour=int(datetime.now().strftime('%H'))       #get string with current hour
                #set self.memory[4] as True, to register the use of devices
                self.memory[idx][4]=True

            #checks if device shouldn't be turned on in certain time frame
                if element[5] is not None:           #checks if measurand correction should be affected by time
                    if element[5][3] is not None:
                        if self.hour >=element[5][3][0] or self.hour <= element[5][3][1]:
                            print('Currently in the forbidden hours!')
                            continue                                        #jumps to next iteration in for loop
                        else:
                            print('Measurand is not in the forbidden hours rn.')
                            pass
                        

                while values.checkintervall(element[0])!=True:
                    
                    self.direction=element[2][values.checkintervall(element[0])]        #long expression just returns high/low dictionary, as to not have millions of loops 
                    self.changecolor(element[1],None)                                  #color measurand as None/red           
                    self.changecolor(self.direction[0],True)                            #color devices, both changecolor and changeconnection, have a way of ignoring the argument when its None

                    self.changeconnections(self.direction[1])                           #change connection-->point to 'used' devices

                    if element[4]==None and self.direction[0]!= None:                 #this guarantees that certain measurands don't get corrected at all, or only partially(like only raising the value)
                        self.useddevice=self.direction[0]                               #placing the used device variable here, guarantees, only really the last 'used' devices gets marked
                        self.memory[idx][3]=datetime.now()
                        self.timelog(element,idx,'x/h')                              #register general use of device one time

                        values.simulation('',element[0],self.direction[2])   
                    else:                                                   #goes into this when the measurand can't be changed in one or even two directions
                        self.timelog(element,idx,'normallogging')           #NEEDS to be outside if None, as to also add the running time of light, if lightintenisty now exceeds the upper limit
                        if self.direction[0]!= None:                        #it enters this loop, if it actually got a device to power up, in case of i.e lightintenistity too high, it doesn't
                            self.timelog(element,idx,'x/h')                      #register general use of device one time
                            self.memory[idx][3]=datetime.now()              #startingtime always needs to be after timelog, otherwise you measure the wrong way around
                        else:                                               #measurand hasn't got a device to power up
                            self.resetmemory('atthetime',idx)

                        self.changeconnections(self.l1[9])                  #set to no connection
                        if values.checkintervall(element[0])=='high':       #turn off low device because measurand is too high, and you can't change it, i.e. lightintensity 
                            self.changecolor(element[2]['low'][0],None)     #note to self: this is all very convoluted-->Think carefully before changing sth
                        break
                    
                    #correcting intervall
                    self.master.after(1000)                         

                    #add small increments of 'normally' used device, basically adds the 1000 ms from above
                    self.timelog(element,idx,'normallogging')
                    
                    #exit if t/atthetime is exceeded    (contains bascially most code from the else below)
                    if element[5] is not None:              #only for the time sensitive
                        if self.memory[idx][2]>=element[5][2]:                          #NOTE: Measurands with simulation-correction:None, never need to enter the followinng code, because the devices are intended to run in the background. Checking t/atthetime doesn't make sense for them
                            print('The',element[5][2],'seconds of allowed uptime, has been reached here.')
                            #set device time of powered up device to 0
                            self.resetmemory('atthetime',idx)
                            #set to no connection
                            self.changeconnections(self.l1[9])
                            #turning off used device
                            self.changecolor(self.useddevice,None)        
                            self.useddevice=None
                            break
                    
                    
                else:
                    #timelogging
                    self.timelog(element,idx,'normallogging')
                    
                    print(self.memory[idx],'\n')
                    #set device time of powered up device to 0
                    self.resetmemory('atthetime',idx)


                    #set to no connection
                    self.changeconnections(self.l1[9])          
                
                    #coloring/turning off devices...
                    self.changecolor(element[1],True)               #color measurand as correct/green
                    self.changecolor(self.useddevice,None)         #Turn off just used device
                    self.useddevice=None                           #Forget last used device
                    
                    if element[4]==True:                            #turn off measurand devices with no simulation, in case they are in the right intervall
                        self.changecolor(element[2]['high'][0],None)
                        self.changecolor(element[2]['low'][0],None)

                                
            #simulation
            print('Starting with simulation!')
            for p in range(30):
                values.simulation('simulation',None,None)
                for u in self.ll:
                    if values.checkintervall(u[0])==True:
                        self.changecolor(u[1],True)
                    else:
                        self.changecolor(u[1],None)
                self.master.after(300)

            print('Das ist l3 nach der Simulation: '+str(l3))
                    
        
        
            self.master.after(1, self.programloop)  #trick is to call function again, at end of function
        except:
            cleanclose()
            print('Did you cleanup?')
    def programloop(self):
        try:

            time.sleep(5)
            #make temp copy of self.ll
            self.li = copy.deepcopy(
                self.ll
            )  #deepcopy kann eigentlich keine tkinter objects kopieren, deshalb sind in der self.ll liste nur indexe fuer die self.l5 liste, die die objekte enthaelt
            #honestly I don't remember why a copy of self.ll is needed. Seems to work without it, however further investigation needed

            for idx, element in enumerate(self.li):

                #set hour for the whole time of correcting this device
                self.hour = int(datetime.now().strftime(
                    '%H'))  #get string with current hour
                #set self.memory[4] as True, to register the use of devices
                self.memory[idx][4] = True
                #checks if device shouldn't be turned on in certain time frame
                if self.checktime(element, idx, 'timeframe') == 'continue':
                    continue

                for self.data in self.onecheckintervallinstance(
                        element, idx
                ):  #this replaces while values.checkintervall(element[0],idx,element)!=True loop,necessary to get stable a variable of condition
                    #just for testing

                    print(l3)
                    ###du willst hier was einbauen dass bei True kein error vorkommt
                    self.direction = element[2][
                        self.
                        data]  #long expression just returns high/low dictionary, as to not have millions of loops
                    self.relay(
                        self.direction[0], True
                    )  #color devices, both relay and changeconnection, have a way of ignoring the argument when its None

                    if element[4][0] == None and self.direction[
                            0] != None:  #this guarantees that certain measurands don't get corrected at all, or only partially(like only raising the value)
                        self.useddevice = self.direction[
                            0]  #placing the used device variable here, guarantees, only really the last 'used' devices gets marked
                        self.memory[idx][3] = datetime.now()
                        self.timelog(
                            element, idx,
                            'x/h')  #register general use of device one time
                        values.simulation('', element[0], self.direction[2],
                                          element)
                        if idx == 3:  #turn off heating element, similar to growlight this has to be done once here in while loop and then one time in else down below
                            self.relay(element[2]['low'][0], None)
                    else:  #goes into this when the measurand can't be changed in one or even two directions
                        self.timelog(
                            element, idx, 'normallogging'
                        )  #NEEDS to be outside if None, as to also add the running time of light, if lightintenisty now exceeds the upper limit
                        if self.direction[
                                0] != None:  #it enters this loop, if it actually got a device to power up, in case of i.e lightintenistity too high, it doesn't
                            self.timelog(
                                element, idx, 'x/h'
                            )  #register general use of device one time
                            self.memory[idx][3] = datetime.now(
                            )  #startingtime always needs to be after timelog, otherwise you measure the wrong way around
                        else:  #measurand hasn't got a device to power up
                            self.resetmemory('atthetime', idx, element)

                        if self.data == 'high':  #turn off low device because measurand is too high, and you can't change it, i.e. lightintensity
                            self.relay(
                                element[2]['low'][0], None
                            )  #note to self: this is all very convoluted-->Think carefully before changing sth
                        break

                    #correcting intervall
                    time.sleep(1)

                    #add small increments of 'normally' used device, basically adds the 1000 ms from above
                    self.timelog(element, idx, 'normallogging')

                    #exit if t/atthetime is exceeded    (contains bascially most code from the else below)
                    if element[5] is not None:  #only for the time sensitive
                        if self.memory[idx][2] and element[5][
                                2] is not None:  #needed to not cause errors when there is no atthetime function needed for measurand
                            if self.memory[idx][2] >= element[5][
                                    2]:  #NOTE: Measurands with simulation-correction:None, never need to enter the followinng code, because the devices are intended to run in the background. Checking t/atthetime doesn't make sense for them
                                print(
                                    'The', element[5][2],
                                    'seconds of allowed uptime, has been reached here.'
                                )
                                #set device time of powered up device to 0
                                self.resetmemory('atthetime', idx, element)
                                #set to no connection
                                #turning off used device
                                self.relay(self.useddevice, None)
                                self.useddevice = None
                                break

                    #testing
                    print(l3)
                else:
                    #timelogging
                    self.timelog(element, idx, 'normallogging')

                    #set device time of powered up device to 0
                    self.resetmemory('atthetime', idx, element)

                    #turning off devices...
                    self.relay(self.useddevice,
                               None)  #Turn off just used device
                    self.useddevice = None  #Forget last used device

                    if element[4][
                            0] == True:  #turn off measurand devices with no simulation, in case they are in the right intervall
                        self.relay(element[2]['high'][0], None)
                        self.relay(element[2]['low'][0], None)
                    if idx == 3:  #turn off heating element, similar to growlight above
                        self.relay(element[2]['low'][0], None)
            '''    
            modify memory
            also turn on devices that have'nt been turned on enough the last hour
            the device function is called in the resetmemory function, because it needs to be checked before the memory is deleted
            '''
            self.resetmemory(
                'realtime', idx, element
            )  #this is here, because it needs acces to the element, to be able to call the checktime function in it

            file1.write(
                'Das ist l3 nach der Correction und vor der Simulation: ' +
                str(l3) + '\n')
            file1.write('Das ist das gesamte MEMORY nach der Korrektion: ' +
                        str(self.memory) + '\n')

            print('MEMORY:', self.memory, '\n')
            #simulation
            print('Starting with simulation!')
            for p in range(5):
                values.simulation('simulation', None, None, None)
                time.sleep(5)

            file1.write('\nStart einer neuen Runde um ' +
                        datetime.now().strftime("%H:%M:%S") + '\n')
            print('Das ist l3 nach der Simulation: ' + str(l3) + '\n')
            print('Start einer neuen Runde um ',
                  datetime.now().strftime("%H:%M:%S"))
            file1.write('Das ist l3 nach der Simulation: ' + str(l3) + '\n')

            self.programloop()
        except:  #apparently Exception is the base class of all exceptions

            file1.close()
            cleanclose()
            print('Did you cleanup?')
            print(traceback.format_exc())  #seems to print good traceback
예제 #3
0
    def programloop(self):
        try:  

            time.sleep(5)            
            #make temp copy of self.ll
            self.li=copy.deepcopy(self.ll)          #deepcopy kann eigentlich keine tkinter objects kopieren, deshalb sind in der self.ll liste nur indexe fuer die self.l5 liste, die die objekte enthaelt
                                                    #honestly I don't remember why a copy of self.ll is needed. Seems to work without it, however further investigation needed
                 
            for idx,element in enumerate(self.li):
                
                
                #set hour for the whole time of correcting this device
                self.hour=int(datetime.now().strftime('%H'))       #get string with current hour
                #set self.memory[4] as True, to register the use of devices
                self.memory[idx][4]=True
                #set self.memory[idx][5] as True, to register use of device for ecxcel counting
                self.memory[idx][5]=True
                #set self.memory[idx][6] as True, to get a correct DB entry, by only entering 'start' once
                self.memory[idx][6]=True
                #checks if device shouldn't be turned on in certain time frame, also turns off devices of measurand if currently in use(e.g light)                        
                if self.checktime(element,idx,'timeframe')=='continue':
                    continue

               
                for self.data in self.onecheckintervallinstance(element,idx):           #this replaces while values.checkintervall(element[0],idx,element)!=True loop,necessary to get stable a variable of condition                  
                    
                    print(l3)
                    self.direction=element[2][self.data]        #long expression just returns high/low dictionary, as to not have millions of loops 
                    self.relay(self.direction[0],True)                            #color devices, both relay and changeconnection, have a way of ignoring the argument when its None
                    #write to excel file
                    excel.devicestable(idx,self.direction[0],self.data,'apparently keyboardinterrupt',element)
                    



                    if element[4][0]==None and self.direction[0]!= None:                 #this guarantees that certain measurands don't get corrected at all, or only partially(like only raising the value)
                        #DB
                        DB.devices('start',[idx],self.direction[0],excel.measurandnames[element[0]]+' '+str(self.data),None,element,None)
                        
                        
                        self.useddevice=self.direction[0]                               #placing the used device variable here, guarantees, only really the last 'used' devices gets marked
                        self.memory[idx][3]=datetime.now()                       
                        self.timelog(element,idx,'x/h')                              #register general use of device one time
                        values.simulation('',element[0],self.direction[2],element)      #at this point, it only simulates co2 correction
                        #turning off heating element now happens in the onecheckinintervallinstance function, where it sets the opposite device to None.

                    else:                                                   #goes into this when the measurand can't be changed in one or even two directions
                        self.useddevice=self.direction[0]
                        self.timelog(element,idx,'normallogging')           #NEEDS to be outside if None, as to also add the running time of light, if lightintenisty now exceeds the upper limit
                        if self.direction[0]!= None:                        #it enters this loop, if it actually got a device to power up, in case of i.e lightintenistity too high, it doesn't
                            #write into DB
                            DB.devices('start',[idx],self.useddevice,excel.measurandnames[element[0]]+' '+str(self.data),None,element,None)
                            '''timelog needs to be in between "start" and "end" of DB.devices because DB.messages is called for logging x/h inside of self.timelog
                            . DB.messages is the reason why timelog needs to be placed in between here"'''
                            self.timelog(element,idx,'x/h')                      #register general use of device one time
                            self.memory[idx][3]=datetime.now()              #startingtime always needs to be after timelog, otherwise you measure the wrong way around
                            
                            DB.devices('end',[idx],self.useddevice,None,'no poweroff',element,'running in BG')
                        else:                                               #measurand hasn't got a device to power up
                            self.resetmemory('atthetime',idx,element)

                        #if self.data=='high':       #turn off low device because measurand is too high, and you can't change it, i.e. lightintensity 
                         #   self.relay(element[2]['low'][0],None)     #note to self: this is all very convoluted-->Think carefully before changing sth
                        #xlsx logging
                        excel.xlsxstartingtime=None           #set startingtime to none, because device is running in bg from here on, so ther cant be any duration at this point, if xlsxstartingtime is none, no duration is written
                        excel.devicestable(idx,self.useddevice,None,'no poweroff',element)
                        
                        self.useddevice=None
                        break
                    
                    #correcting intervall
                    time.sleep(1)

                    #add small increments of 'normally' used device, basically adds the 1000 ms from above
                    self.timelog(element,idx,'normallogging')
                    
                    #exit if t/atthetime is exceeded    (contains bascially most code from the else below)
                    if element[5] is not None:              #only for the time sensitive
                        if self.memory[idx][2] and element[5][2] is not None:               #needed to not cause errors when there is no atthetime function needed for measurand
                            if self.memory[idx][2]>=element[5][2]:                          #NOTE: Measurands with simulation-correction:None, never need to enter the followinng code, because the devices are intended to run in the background. Checking t/atthetime doesn't make sense for them
                                print('The',element[5][2],'seconds of allowed uptime, have been reached here.')
                                #xlsx filelog
                                excel.specialmessages(idx,'atthetime exceeded',None)

                                #set device time of powered up device to 0
                                self.resetmemory('atthetime',idx,element)
                                #turning off used device
                                self.relay(self.useddevice,None)
                            
                                #write duration and reason for poweroff into xlsx file
                                excel.devicestable(idx,self.useddevice,None,'athetime exceeded',element) 
                                #actual mysql(mariad DB) entry
                                DB.messages(idx,'atthetime exceeded','device gets turned off')
                                DB.devices('end',[idx],self.useddevice,None,'atthetime exceeded',element,None)
                                self.useddevice=None
                                break
                    
                    #testing
                    print(l3)
                else:
                    #actual mysql(mariad DB) entry
                    DB.devices('end',[idx],self.useddevice,None,'measurand corrected',element,None)
                    #write duration and reason for poweroff into xlsx file
                    excel.devicestable(idx,self.useddevice,None,'measurand corrected',element)  
                    #timelogging
                    self.timelog(element,idx,'normallogging')

                    #set device time of powered up device to 0
                    self.resetmemory('atthetime',idx,element)
                
                    #turning off devices...
                    self.relay(self.useddevice,None)         #Turn off just used device
                    self.useddevice=None                           #Forget last used device
                    
                    if element[4][0]==True:                            #turn off measurand devices with no simulation, in case they are in the right intervall
                        self.relay(element[2]['high'][0],None)
                        self.relay(element[2]['low'][0],None)
                    if idx==3:                                          #turn off heating element, similar to growlight above
                            self.relay(element[2]['low'][0],None)
                            


            '''    
            modify memory
            also turn on devices that have'nt been turned on enough the last hour
            the device function is called in the resetmemory function, because it needs to be checked before the memory is deleted
            '''
            self.resetmemory('realtime',idx,element)       #this is here, because it needs acces to the element, to be able to call the checktime function in it   

                    
            print('MEMORY:',self.memory,'\n')
            #simulation
            print('Starting with simulation!')
            for p in range(5):
                values.simulation('simulation',None,None,None)
                time.sleep(5)

            
            print('Das ist l3 nach der Simulation: '+str(l3)+'\n')
            print('Start einer neuen Runde um ',datetime.now().strftime("%H:%M:%S"))
        
        
            self.programloop()
        except BaseException as e:                           #apparently BaseException also includes Keyboardinterrupt and all normal Exceptions
            cleanclose()    
            excel.specialmessages(idx,type(e).__name__,traceback.format_exc())        #type gives name of Exception
            excel.workbook.close()
            DB.messages(idx,'Exception: '+traceback.format_exc(),'exit program')      #'Exception: '+type(e).__name__  for only name of exception                
            print(traceback.format_exc())           #seems to print good traceback