/*******************************************************************************
* Copyright (c) 2008, 2009 Bug Labs, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - Neither the name of Bug Labs, Inc. nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
package com.buglabs.bug.module.motion;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;
import org.osgi.service.log.LogService;
import com.buglabs.bug.dragonfly.module.IModuleLEDController;
import com.buglabs.bug.jni.motion.Motion;
import com.buglabs.bug.module.motion.pub.IMotionObserver;
import com.buglabs.bug.module.motion.pub.IMotionSubject;
/**
*
* @author kgilmer
*
*/
public class MotionSubject extends Thread implements IMotionSubject {
/**
* Default value for sleep interval between motion detector reads.
*/
private static final int DEFAULT_SLEEP_INTERVAL = 500;
/**
* System property to define sleep between motion detector reads.
*/
public static final String SLEEP_INTERVAL_PROPERTY_KEY = "bug.motion.sleep_interval";
InputStream motionIs;
ArrayList observers;
private final IModuleLEDController ledController;
private final Timer timer = new Timer();
private final LogService log;
private volatile boolean flashing;
private final int sleepInterval;
MotionSubject(InputStream gpsIs, IModuleLEDController ledController, LogService log) {
this.motionIs = gpsIs;
this.ledController = ledController;
this.log = log;
observers = new ArrayList();
sleepInterval = getSleepInterval();
}
private int getSleepInterval() {
String is = System.getProperty(SLEEP_INTERVAL_PROPERTY_KEY);
if (is != null) {
return Integer.parseInt(is);
}
return DEFAULT_SLEEP_INTERVAL;
}
public void run() {
byte read = 0;
byte expected = Motion.BMI_MOTION_DETECT_ENABLED | Motion.BMI_MOTION_DETECT_DELTA | Motion.BMI_MOTION_DETECT_LATCHED_STATUS | Motion.BMI_MOTION_DETECT_STATUS;
try {
while (motionIs != null && !isInterrupted() && (read = (byte) motionIs.read()) != -1) {
if (read == expected) {
notifyObservers();
flashLed();
}
Thread.sleep(sleepInterval);
}
} catch (IOException e) {
log.log(LogService.LOG_ERROR, "An IOException occured while reading from Motion module.", e);
} catch (InterruptedException e) {
// Shutdown
} finally {
if (motionIs != null) {
try {
motionIs.close();
} catch (IOException e) {
// Ignore exception
}
}
}
}
private void flashLed() {
if (!flashing) {
try {
flashing = true;
ledController.setLEDGreen(true);
TimerTask tt = new TimerTask() {
public void run() {
try {
ledController.setLEDGreen(false);
flashing = false;
} catch (IOException e) {
}
}
};
timer.schedule(tt, 400);
} catch (IOException e) {
//Ignore exception
}
}
}
public void notifyObservers() {
synchronized (observers) {
Iterator iter = observers.iterator();
while (iter.hasNext()) {
IMotionObserver obs = (IMotionObserver) iter.next();
obs.motionDetected();
}
}
}
public void register(IMotionObserver obs) {
synchronized (observers) {
observers.add(obs);
}
}
public void unregister(IMotionObserver obs) {
synchronized (observers) {
observers.remove(obs);
}
}
}