Validador de rango de tiempo de Python

Tengo 2 parámetros en DB: iniciar y detener. el valor para ellos puede ser, por ejemplo, 07: 00-23: 00 o 23: 00-07: 00 (inicio después de 07, parada después de 23 o inicio después de 23, parada después de 07)

En ese momento, un estado debe ser 0 o 1, digamos que es LED

¿Cómo crear un controlador lógico unificado que no ensucie después de la medianoche?

Mi implementación deficiente (no funciona) está abajo. En realidad, he intentado muchas, muchas variaciones y aún terminé donde estoy actualmente.

if curtime >= vv_time_trig1 and curtime <= vv_time_trig2: logger.info("turning socket on") logger.debug("#1") #check current status #if current is 0 #turn socket on if vvstatus == 0: logger.debug("current status off, turning socket on") GPIO.output(25, GPIO.HIGH) #check current status #if current is already 1 #do nothing elif vvstatus == 1: logger.info("skiping. already on") #unhandeled current status else: logger.critical("unhandeled vvstatus!") logger.critical("turning socket off") GPIO.output(25, GPIO.LOW) #if current time is before start #turn off elif curtime = vv_time_trig2: logger.info("turning socket off") logger.debug("#2") #check current status #if current is 1 #turn socket off if vvstatus == 1: logger.debug("current status on, turning socket off") GPIO.output(25, GPIO.LOW) #check current status #if current is already 0 #do nothing elif vvstatus == 0: logger.info("skiping. already off") #unhandeled current status else: logger.critical("unhandeled vvstatus!") logger.critical("turning socket off") GPIO.output(25, GPIO.LOW) #if current time is after stop #turn off elif curtime >= vv_time_trig2: logger.info("turning socket off") logger.debug("#3") #check current status #if current is 1 #turn socket off if vvstatus == 1: logger.debug("current status: %s, turning socket off", vvstatus) GPIO.output(25, GPIO.LOW) #check current status #if current is already 0 #do nothing elif vvstatus == 0: logger.info("skiping. already on") #unhandeled current status else: logger.critical("unhandeled vvstatus!") logger.critical("turning socket off") GPIO.output(25, GPIO.LOW) #if current time is before stop #turn off elif curtime <= vv_time_trig2 and curtime <= vv_time_trig1: logger.info("turning socket on") logger.debug("#4") #check current status #if current is 0 #turn socket on if vvstatus == 0: logger.debug("current status off, turning socket on") GPIO.output(25, GPIO.HIGH) #check current status #if current is already 1 #do nothing elif vvstatus == 1: logger.info("skiping. already on") #unhandeled current status else: logger.critical("unhandeled vvstatus!") logger.critical("turning socket off") GPIO.output(25, GPIO.LOW) 

Versión actualizada. Determine la posición actual en el tiempo en relación con el final. el final está configurado para mañana si pasa la medianoche

  n1 = datetime.now() startTrig = datetime(n1.year, n1.month, n1.day, 23, 00, 0) logger.debug("start: %s",startTrig) n = datetime.now() endTrig = datetime(n.year, n.month, n.day, 07, 00, 0) logger.debug("end: %s",endTrig) if startTrig > endTrig: logger.debug("start > stop") endTrig += timedelta(days=1) logger.debug("new stop trig: %s",endTrig) if datetime.now() < endTrig: if curStatus == 1: logger.debug("socket %s already on. doing nothing.") elif curStatus == 0: logger.debug("socket %s sould be on. flipping switch") flipSocketStatus(bcmNo,bcmDir) else: logger.critical("unhandeled socket %s current status %s",socName,curStatus) if curStatus == 1: logger.critical("shutting socket %s down",socName) GPIO.output(bcmNo, GPIO.LOW) elif curStatus == 0: logger.warn("socket %s already off",socName) else: logger.critical("unhandeled current status for pin: %s",bcmNo) logger.critical("forcing socket %s down",socName) GPIO.output(bcmNo, GPIO.LOW) else: logger.critical("unhandeled start-stop rules") 

Hay dos casos: el tiempo actual es entre los tiempos dados (en el sentido de las agujas del reloj) o fuera (imagina el círculo del reloj):

 #!/usr/bin/env python from datetime import datetime def in_between(now, start, end): if start < end: # eg, "07:00-23:00" return start <= now < end elif end < start: # eg, "23:00-07:00" return start <= now or now < end else: # start == end return True # consider it 24 hour interval now = datetime.now().time() for date_range in ["07:00-23:00", "23:00-07:00"]: start, end = [datetime.strptime(s, "%H:%M").time() for s in date_range.split("-")] not_ = '' if in_between(now, start, end) else 'not ' print("{now:%H:%M} is {not_}in between {date_range}".format(**vars())) 

Salida

 02:26 is not in between 07:00-23:00 02:26 is in between 23:00-07:00 

ACTUALIZACIÓN: Basado en su actualización

Esto se ve mejor, lo único que me confunde es su if datetime.now() < endTrig condicional.

Corríjame si aún lo estoy entendiendo mal, pero su condicional actual parece que se lee:

 if now() is before endTrigger: - if status is 1, we are good, stay on - if status is 0, turn on - if status is anything else (but cant it only be 1 or 0?): * if status is 1 ... (but wait, we already checked for this above!) * if status is 0 ... (ditto, these two checks will never trigger) * otherwise, force off if now() is after endTime: - some logging (shouldnt this be where we turn off?) 

Usted mencionó que el estado debe ser 0 o 1. En base a eso, espero que su condicional se vea algo así como:

 . . [start/end setup stuff] . # If we haven't reached end time yet if datetime.now() < endTrig: # If status is 1, we're already on if curStatus == 1: log('Already on') # If status isn't 1, it must be 0 and we should turn on else: log('Turn on') flipSwitchOn() # If we have passed the end time else: # If we're on, time to turn off if curStatus == 1: log('Turning off') flipSwitchOff() # If its not 1 it must be 0, we're off, stay off else: log('Already off')