Вам придется немного перестроить вещи, чтобы сделать это.
Идея заключается в том, что у вас есть пара глобальных переменных, которые обновляются обработчиками событий GPIOZero:
door_is_open
- true, когда дверь открыта Существует также бесконечный основной цикл, который тикает один раз в секунду, который читает переменную door_is_open
и увеличивает счетчик открытия ... и, наконец, если счетчик открытия достигает желаемого порога (5 секунд здесь, потому что мы ' нетерпеливые люди), он включает buzzer
.
Обработчик door_closed
заботится о сбросе buzzer
, но это также может быть сделано в основном цикле.
Я также взял на себя смелость рефакторинга регистрации в свою собственную функцию, которая легко также печатает то же самое на консоли. (Кроме того, я бы предложил использовать форматирование даты ISO 8601, но я не хотел навязывать это здесь.)
Дальнейший рефакторинг может обернуть все это в аккуратный класс, чтобы избежать глобальных переменных. [ 1114]
(Это все в сухом коде, поэтому ваш пробег может отличаться, но идея должна работать. :))
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()
Количество разрешенных одновременных подключений по умолчанию равно 10.
Скорее всего, ваш клиент не закрывает соединения.
Чтобы увеличить количество одновременных вызовов, вам придется добавить свое поведение в конфигурацию службы, а не клиента.
Можете ли вы настроить трассировку и запустить цикл? Может случиться так, что канал выйдет из строя и заставит клиента тайм-аут.
Нет, это неплохая идея, за исключением того, что вы все испортили.
Во-первых, вы пишете в строковый литерал. Это неопределенное поведение. (Он вылетает в Windows.) Если бы вы написали const char * str = "Hello!"
, компилятор рявкнул бы на вас. К сожалению, существует (в C ++ устаревшее, но все же разрешенное) преобразование строкового литерала в неконстантный char *
, что позволяет компилировать ваш код. Однако вам нужен массив, в который вы можете записывать (и который предварительно инициализирован). Для этого используйте char str [] = "Hello!"
.
Другая, незначительная ошибка заключается в том, что вы дважды перебираете строку: strlen
пробегает символы, пока не находит '\ 0'
, а затем вы выполняете опять то же самое.
Я действительно изменил свой вызов моей службы на Dispose ()
клиент службы, но, похоже, это не дало никакого эффекта. Очевидно, где-то скрывается еще один служебный вызов.
Что может быть интересно отметить, так это то, что заставило меня решить, что это , а не проблема: этот предел не связан с фактическим количеством сокетов, подключенных к веб-сервис. Когда вы достигнете предела maxConcurrentSessions
, останется только одно фактическое соединение с сокетом . Я проверял это с помощью netstat
, что привело меня к неправильному выводу. Итак, не путайте сеансы с сокетами .
У нас есть интерфейсы, определенные для всех наших сервисов WCF, поэтому я планирую адаптировать этот шаблон в своем коде сейчас:
IMyService service = new MyServiceClient();
using (service as IDisposable)
{
service.MyServiceMethod();
}
Что также интересно, в том, что проблема не возникла у меня, когда службы (и веб-сайт) размещались на IIS. Конфигурация (почти) идентична, но мне не удалось воспроизвести такое поведение на этой машине. Думаю, это хорошо :)
с использованием
): Я обычно помещаю присвоение переменных в с использованием оператора
. Но созданный IMyService не может быть неявно преобразован в IDisposable
. Если бы вы действительно хотели, чтобы это присваивание было там, я полагаю, альтернативой будет:
IService service;
using ((service = new ServiceClient()) as IDisposable)
{
}
Тем не менее, остается проблема с неправильной областью видимости переменной. Ссылка на службу IService
непригодна для использования, но все еще остается в силе. Так что в этом отношении было бы лучше:
using (IDisposable serviceDisposable = new ServiceClient())
{
IService service = (IService)serviceDisposable;
}
Это требует, чтобы я ввел дополнительное имя переменной. * Meh *
Это можно решить, создав класс singleton в качестве интерфейса между ссылкой на веб-сервис и приложением. Тогда будет создан только один экземпляр ссылки сервиса.
class ServiceInterface
{
private static ServiceInterface _instance;
private ServiceClient _service = new ServiceClient ;
private ServiceInterface()
{
//Prevent accessing default constructor
}
public static ServiceInterface GetInstance()
{
if(_instance == null)
{
_instance = new ServiceInterface();
}
return _instance;
}
// You can add your functions to access web service here
Public int PerformTask()
{
return _service.PerformTask();
}
}