GPIOZero Pi Сигнализация: нужна альтернатива для задержки

Мне нужна помощь с кодом моей системы сигнализации, который я создаю с помощью библиотеки GPIOZero (моему боссу очень нравится эта библиотека). Система предназначена для тележки для ноутбука, поэтому люди не забывают закрыть дверь, потому что есть зуммер, который звонит, если люди оставляют его открытым слишком долго. Так что я хочу сделать это действительно просто, но всегда ждет завершения функции, прежде чем перейти к следующему:

Если дверь открывается: время регистрации, время задержки, зуммер включается

Если дверь закрыта / закрывается: зуммер выключен, время журнала

Есть ли способ не ждать окончания функции в библиотеке GPIOZero. Пожалуйста, дайте мне знать!

from gpiozero import Button
from signal import pause
from gpiozero import Buzzer
from gpiozero import LED
from time import sleep

##### VARIABLES DEF #######
button = Button(21, pull_up=True)
buzzer = Buzzer(4)

def door_opened():
    f = open("log" + '.txt', 'a')               
    f.write("Opened " + time.strftime("%m-%d-%Y %X"))
    f.close()
    print("Door Open")
    sleep(100)
    print("door held, alarm on")
    buzzer.on

def door_closed():
    f = open("log" + '.txt', 'a')               
    f.write(" " + time.strftime("%X"))
    f.write('\n')
    f.close()
    print("Door Closed")
    buzzer.off()
    print("Buzzer off")


button.when_pressed = door_closed
button.when_released = door_opened


pause()

1 ответ

Решение

Вам придется немного перестроить вещи, чтобы сделать это.

Идея в том, что у вас есть пара глобальных переменных, которые обновляются обработчиками событий GPIOZero:

  • door_is_open - правда, когда дверь открыта
  • door_open_counter - подсчитывает количество секунд, в течение которых дверь была открыта (на самом деле обработчики событий сбрасывают ее на ноль).

Есть также бесконечный основной цикл, который тикает один раз в секунду, который читает door_is_open переменная и увеличивает открытый счетчик... и, наконец, если открытый счетчик достигает желаемого порога (5 секунд здесь, потому что мы нетерпеливые люди), он поворачивает buzzer на.

door_closed Обработчик заботится о сбросе buzzer, но это также можно сделать в основном цикле.

Я также взял на себя смелость рефакторинга регистрации в свою собственную функцию, которая легко также печатает то же самое на консоли. (Кроме того, я бы предложил использовать форматирование даты ISO 8601, но я не хотел навязывать это здесь.)

Дальнейший рефакторинг может обернуть все это в аккуратный класс, чтобы избежать глобальных переменных.

(Это все в сухом коде, поэтому ваш пробег может отличаться, но идея должна работать.:))

import time
from gpiozero import Button, Buzzer


button = Button(21, pull_up=True)
buzzer = Buzzer(4)
door_is_open = False
door_open_counter = 0


def log_event(text):
    print(log_line)
    with open("log.txt", "a") as log_file:
        log_line = "%s | %s" % (time.strftime("%m-%d-%Y %X"), text)
        log_file.write(log_line + "\n")



def door_opened():
    global door_is_open
    global door_open_counter
    log_event("Opened")
    door_is_open = True
    door_open_counter = 0


def door_closed():
    global door_is_open
    global door_open_counter
    log_event("Closed")
    buzzer.off()
    door_is_open = False
    door_open_counter = 0


button.when_pressed = door_closed
button.when_released = door_opened

while True:
    time.sleep(1)
    if door_is_open:
        door_open_counter += 1
        if door_open_counter >= 5:
            buzzer.on()
Другие вопросы по тегам