Одна из проблем здесь заключается в том, что у нас нет спецификации поведения системы complete (например, после каждого high photo_volt()
или moisture_read()
читая, есть ли минимальное время, в течение которого соответствующее реле должно оставаться HIGH
, как для LOW
...?). Но вот пример того, как это может работать. Я буду использовать независимые очереди событий для двух реле без потоков (я понятия не имею, будет ли библиотека GPIO
поточно-ориентированной).
import time
import functools # we'll use functools.partial to "pre-bake" our GPIO.output calls
def check_queue(queue, t):
while True:
if not queue:
return True # Return True to indicate "this queue is empty: feel free to take new readings and add more commands"
first = queue[0]
if isinstance(first, float): # A numeric entry in the queue means "do nothing until the clock reaches this number"
if t < first:
return False # Return False to indicate "commands are still pending in this queue: don't take any more readings yet"
else:
queue.pop(0) # Time's up: immediately proceed to the next item in the queue
else: # Any non-numeric queue entry is assumed to be a command for immediate execution
command = queue.pop(0)
command()
try:
relay1_commands = []
relay2_commands = []
while True:
t = time.time() # current time
if check_queue(relay1_commands, t):
if photo_volt() < 1.6:
relay1_commands += [
functools.partial(GPIO.output, RELAY_1, GPIO.LOW),
t + 5.0, # wait until 5 seconds from now (no more photo_volt readings or outputs on RELAY_1 till then)
functools.partial(GPIO.output, RELAY_1, GPIO.HIGH),
t + 6.0, # this is literally what the question asks for, but is it necessary?
# so, after a low photo_volt() reading, RELAY_1 should be constantly LOW for
# at least 5 seconds, then automatically HIGH (regardless of photo_volt state)
# for at least 1 second
]
else:
relay1_commands += [
functools.partial(GPIO.output, RELAY_1, GPIO.HIGH),
t + 1.0,
# after a high photo_volt() reading, RELAY_1 should be constantly HIGH for
# at least.... what? That's not specified in the question. Here I've arbitrarily
# said 1 second.
]
if check_queue(relay2_commands, t):
if ss.moisture_read() < 350:
relay2_commands += [
functools.partial(GPIO.output, RELAY_2, GPIO.LOW),
t + 5.0, # wait until then (no more photo_volt readings or outputs on RELAY_2)
# so, after a low ss.moisture() reading, RELAY_2 should be constantly LOW for
# at least 5 seconds, but unlike RELAY_1 there shouldn't be an automatic HIGH
# period after that (that's what the question appears to specify)
]
else:
relay2_commands += [
functools.partial(GPIO.output, RELAY_2, GPIO.HIGH),
t + 1.0,
# after a high ss.moisture() reading, RELAY_2 should be constantly HIGH for
# at least.... what? That's not specified in the question. Here I've arbitrarily
# said 1 second.
]
time.sleep(0.001) # or however long is appropriate between repeated checks
finally: # as chepner says: You probably want to do this no matter why the `try` statement exits.
GPIO.cleanup()