2016-04-06 5 views
1

Ниже приведен код - http://pi4j.com/example/listener.html (слушать GPIO). Мне было интересно, есть ли способ отключить событие от увольнения за определенный временной интервал. Например, у меня есть детектор движения и вы хотите настроить его так, чтобы после обнаружения движения он включал свет. Однако, если в течение следующих 15 минут (после включения света) будет обнаружено движение, эти события (движение) должны быть отброшены.Отключение событий за определенное время

public class ListenGPIO { 

public static void main(String args[]) throws InterruptedException { 
    final GpioController gpio = GpioFactory.getInstance(); 
    final GpioPinDigitalInput myButton = gpio.provisionDigitalInputPin(RaspiPin.GPIO_02, PinPullResistance.PULL_DOWN); 

    myButton.addListener(new GpioPinListenerDigital() { 
     @Override 
     public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) { 
      System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = " + event.getState()); 
     } 

    }); 

    System.out.println(" ... complete the GPIO #02 circuit and see the listener feedback here in the console."); 
    for (;;) { 
     Thread.sleep(500); 
    } 
} 
} 

Я попытался добавить Thread.sleep внутри handleGpioPinDigitalStateChangeEvent но помещает событие-нить спать, но как только поток просыпается он начинает обработку событий от лица т.е. события сохраняются в какой-то очереди и они обрабатываются, которых я хочу избежать.

ответ

3

Вместо того, чтобы спать, вы могли бы просто игнорировать это событие в течение промежутка времени

long waitUntilTime = -1L; 
    public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) { 
     System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = " + event.getState()); 
     long time = System.currentTimeMillis(); 
     if (time >= waitUntilTime) { 
      waitUntilTime = time + TIME_TO_IGNORE_EVENTS; 
      processEvent(event); 
     } 
    } 
+0

как бы отключить прослушиватель событий каждые 15 минут после его запуска. System.currentTimeMillis() возвращает разность, измеренную в миллисекундах, между текущим временем и полночью, 1 января 1970 г. UTC (время для linux). В первый раз, когда событие должно срабатывать, а затем даже если событие срабатывает, действие не должно выполняться в течение 15 минут с момента запуска события. – srock

+0

В течение 15 минут в примере выше вы устанавливаете TIME_TO_IGNORE_EVENTS на «1000/* ms */* 60/* s */* 15/* 15 минут * /' – ControlAltDel

0

Есть 3 способа справиться с этим, 2 с таймером, один без, это также зависит от API вы используя:

1) добавьте переменную, которая будет храниться при последнем запуске события. В случае нового события сравните время. Если 15 минут прошло, обрабатывать событие, иначе игнорировать его

public class ListenGPIO { 
private long lastFiredMillis = -1; 

public static void main(String args[]) throws InterruptedException { 
    final GpioController gpio = GpioFactory.getInstance(); 
    final GpioPinDigitalInput myButton = gpio.provisionDigitalInputPin(RaspiPin.GPIO_02, PinPullResistance.PULL_DOWN); 

    myButton.addListener(new GpioPinListenerDigital() { 
     @Override 
     public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) { 
       if(lastFiredMillis == -1 || (System.currentTimeMillis() - lastFiredMillis) > 15 * 60 * 1000) { 
        lastFiredMillis = System.currentTimeMillis();   
        System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = " + event.getState()); 
       } 

     } 
    }); 
}} 

2) удалить слушателя и повторно добавить его после того, как 15 минут старше Это, конечно, будет работать, только если ваш API имеет метод для удаления слушателя

3) держите слушателя, но игнорируйте события, вы можете установить для него глобальный логический флаг.

public class ListenGPIO { 
private boolean mHandleEvents = true; 

public static void main(String args[]) throws InterruptedException { 
    final GpioController gpio = GpioFactory.getInstance(); 
    final GpioPinDigitalInput myButton = gpio.provisionDigitalInputPin(RaspiPin.GPIO_02, PinPullResistance.PULL_DOWN); 

    myButton.addListener(new GpioPinListenerDigital() { 
     @Override 
     public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) { 
      if(mHandleEvents) { 
       System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = " + event.getState()); 
       mHandleEvents = false; //prevent 
       Timer t = new Timer(); 
       t.schedule(new TimerTask() { 
        public void run() { 
         mHandleEvents = true 
        } 
       }, 15 * 60 * 1000); 
      } 
     } 
    }); 
}}