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
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