Added 5 min agrigator daemon
Former-commit-id: 5c8aa100b93911cee525a31ed090906752b2b3c6
This commit is contained in:
parent
b985776394
commit
adf49efc9a
8 changed files with 236 additions and 2 deletions
30
.classpath
Normal file
30
.classpath
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="src" path="src"/>
|
||||||
|
<classpathentry kind="src" path="test"/>
|
||||||
|
<classpathentry kind="src" path="lib/sphinx4-5prealpha-src/sphinx4-core/src/main/java"/>
|
||||||
|
<classpathentry kind="src" path="lib/java-speech-api-master/src"/>
|
||||||
|
<classpathentry kind="lib" path="external/marytts-5.1.2/lib/icu4j-54.1.1.jar"/>
|
||||||
|
<classpathentry kind="lib" path="external/marytts-5.1.2/lib/marytts-client-5.1.2-jar-with-dependencies.jar"/>
|
||||||
|
<classpathentry kind="lib" path="external/marytts-5.1.2/lib/marytts-lang-de-5.1.2.jar"/>
|
||||||
|
<classpathentry kind="lib" path="external/marytts-5.1.2/lib/marytts-lang-en-5.1.2.jar"/>
|
||||||
|
<classpathentry kind="lib" path="external/marytts-5.1.2/lib/marytts-lang-fr-5.1.2.jar"/>
|
||||||
|
<classpathentry kind="lib" path="external/marytts-5.1.2/lib/marytts-lang-it-5.1.2.jar"/>
|
||||||
|
<classpathentry kind="lib" path="external/marytts-5.1.2/lib/marytts-lang-ru-5.1.2.jar"/>
|
||||||
|
<classpathentry kind="lib" path="external/marytts-5.1.2/lib/marytts-lang-sv-5.1.2.jar"/>
|
||||||
|
<classpathentry kind="lib" path="external/marytts-5.1.2/lib/marytts-lang-te-5.1.2.jar"/>
|
||||||
|
<classpathentry kind="lib" path="external/marytts-5.1.2/lib/marytts-lang-tr-5.1.2.jar"/>
|
||||||
|
<classpathentry kind="lib" path="external/marytts-5.1.2/lib/marytts-runtime-5.1.2-jar-with-dependencies.jar"/>
|
||||||
|
<classpathentry kind="lib" path="external/marytts-5.1.2/lib/voice-cmu-slt-hsmm-5.1.2.jar"/>
|
||||||
|
<classpathentry kind="lib" path="lib/Ab.jar"/>
|
||||||
|
<classpathentry kind="lib" path="lib/commons-math3-3.5.jar"/>
|
||||||
|
<classpathentry kind="lib" path="lib/javaFlacEncoder-0.3.1.jar"/>
|
||||||
|
<classpathentry kind="lib" path="lib/jSerialComm-1.3.4.jar"/>
|
||||||
|
<classpathentry kind="lib" path="lib/marytts-client-5.1.2-jar-with-dependencies.jar"/>
|
||||||
|
<classpathentry kind="lib" path="lib/marytts-runtime-5.1.2-jar-with-dependencies.jar"/>
|
||||||
|
<classpathentry kind="lib" path="lib/pi4j-core-1.0.jar"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
|
<classpathentry combineaccessrules="false" kind="src" path="/zutil-java"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
||||||
|
<classpathentry kind="output" path="lib/java-speech-api-master/bin"/>
|
||||||
|
</classpath>
|
||||||
17
.project
Normal file
17
.project
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>hal</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
||||||
3
.settings/org.eclipse.core.resources.prefs
Normal file
3
.settings/org.eclipse.core.resources.prefs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
encoding//lib/sphinx4-5prealpha-src/sphinx4-core/src/main/java=UTF-8
|
||||||
|
encoding//lib/sphinx4-5prealpha-src/sphinx4-core/src/main/java/edu/cmu/sphinx/alignment/SimpleTokenizer.java=UTF-8
|
||||||
BIN
hal.db
BIN
hal.db
Binary file not shown.
BIN
lib/pi4j-core-1.0.jar
Normal file
BIN
lib/pi4j-core-1.0.jar
Normal file
Binary file not shown.
|
|
@ -4,21 +4,31 @@ package se.koc.hal;
|
||||||
import se.koc.hal.deamon.DataAggregatorDaemon;
|
import se.koc.hal.deamon.DataAggregatorDaemon;
|
||||||
import se.koc.hal.deamon.HalDaemon;
|
import se.koc.hal.deamon.HalDaemon;
|
||||||
import zutil.db.DBConnection;
|
import zutil.db.DBConnection;
|
||||||
|
import zutil.log.CompactLogFormatter;
|
||||||
|
import zutil.log.LogUtil;
|
||||||
|
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Ziver on 2015-12-03.
|
* Created by Ziver on 2015-12-03.
|
||||||
*/
|
*/
|
||||||
public class PowerChallenge {
|
public class PowerChallenge {
|
||||||
|
|
||||||
|
public static DBConnection db;
|
||||||
|
|
||||||
private static HalDaemon[] daemons = new HalDaemon[]{
|
private static HalDaemon[] daemons = new HalDaemon[]{
|
||||||
new DataAggregatorDaemon()
|
new DataAggregatorDaemon()
|
||||||
};
|
};
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
// init logging
|
||||||
|
LogUtil.setGlobalLevel(Level.ALL);
|
||||||
|
LogUtil.setGlobalFormatter(new CompactLogFormatter());
|
||||||
|
|
||||||
// init Database
|
// init Database
|
||||||
final DBConnection db = new DBConnection(DBConnection.DBMS.SQLite, "hal.db");
|
db = new DBConnection(DBConnection.DBMS.SQLite, "hal.db");
|
||||||
|
|
||||||
// init daemons
|
// init daemons
|
||||||
Timer daemonTimer = new Timer();
|
Timer daemonTimer = new Timer();
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,90 @@
|
||||||
package se.koc.hal.deamon;
|
package se.koc.hal.deamon;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import com.ibm.icu.util.Calendar;
|
||||||
|
|
||||||
|
import se.koc.hal.PowerChallenge;
|
||||||
|
import zutil.db.DBConnection;
|
||||||
|
import zutil.db.SQLResultHandler;
|
||||||
|
import zutil.db.handler.SimpleSQLHandler;
|
||||||
|
import zutil.log.LogUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Ziver on 2015-12-03.
|
* Created by Ziver on 2015-12-03.
|
||||||
*/
|
*/
|
||||||
public class DataAggregatorDaemon extends TimerTask implements HalDaemon {
|
public class DataAggregatorDaemon extends TimerTask implements HalDaemon {
|
||||||
|
private static final Logger logger = LogUtil.getLogger();
|
||||||
private static final int FIVE_MINUTES_IN_MS = 5 * 60 * 1000;
|
private static final int FIVE_MINUTES_IN_MS = 5 * 60 * 1000;
|
||||||
|
|
||||||
|
|
||||||
public void initiate(Timer timer){
|
public void initiate(Timer timer){
|
||||||
timer.schedule(this, FIVE_MINUTES_IN_MS);
|
timer.schedule(this, FIVE_MINUTES_IN_MS);
|
||||||
|
run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
DBConnection db = PowerChallenge.db;
|
||||||
|
try {
|
||||||
|
Long maxTimestampEnd = db.exec("SELECT MAX(timestamp_end) FROM sensor_data_aggr", new SimpleSQLHandler<Long>());
|
||||||
|
if(maxTimestampEnd == null)
|
||||||
|
maxTimestampEnd = 0l;
|
||||||
|
logger.fine("Calculating 5 min periods...");
|
||||||
|
long intervallTimestamp = getTimestampPeriodStart(5, System.currentTimeMillis());
|
||||||
|
db.exec("SELECT * FROM sensor_data_raw WHERE timestamp > " + maxTimestampEnd + " AND timestamp < " + intervallTimestamp + " ORDER BY timestamp ASC", new FiveMinuteAgrrigator());
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static long getTimestampPeriodStart(int min, long timestamp){
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.setTimeInMillis(System.currentTimeMillis());
|
||||||
|
int currentMinute = cal.get(Calendar.MINUTE);
|
||||||
|
cal.set(Calendar.MINUTE, (currentMinute/min) * min);
|
||||||
|
return cal.getTimeInMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FiveMinuteAgrrigator implements SQLResultHandler<Object>{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object handleQueryResult(Statement stmt, ResultSet result) throws SQLException {
|
||||||
|
long currentPeriodTimestamp = 0;
|
||||||
|
int sum = 0;
|
||||||
|
int count = 0;
|
||||||
|
while(result.next()){
|
||||||
|
long timestamp = result.getLong("timestamp");
|
||||||
|
long periodTimestamp = getTimestampPeriodStart(5, timestamp);
|
||||||
|
if(currentPeriodTimestamp != 0 && periodTimestamp != currentPeriodTimestamp){
|
||||||
|
float confidence = count / 5f;
|
||||||
|
logger.finer("Calculated period: "+ currentPeriodTimestamp +" sum: "+ sum +" confidence: "+ confidence);
|
||||||
|
PowerChallenge.db.exec(String.format("INSERT INTO sensor_data_aggr(sensor_id, sequence_id, timestamp_start, timestamp_end, data, confidence) VALUES(%d, %d, %d, %d, %d, %f)",
|
||||||
|
result.getInt("sensor_id"),
|
||||||
|
42,
|
||||||
|
currentPeriodTimestamp,
|
||||||
|
currentPeriodTimestamp + FIVE_MINUTES_IN_MS -1,
|
||||||
|
sum,
|
||||||
|
confidence));
|
||||||
|
|
||||||
|
// Reset variables
|
||||||
|
periodTimestamp = currentPeriodTimestamp;
|
||||||
|
sum = count = 0;
|
||||||
|
}
|
||||||
|
if(currentPeriodTimestamp == 0) currentPeriodTimestamp = periodTimestamp;
|
||||||
|
sum += result.getInt("data");
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
106
src/se/koc/hal/plugin/localsensor/ImpulseTracker.java
Normal file
106
src/se/koc/hal/plugin/localsensor/ImpulseTracker.java
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
package se.koc.hal.plugin.localsensor;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
import com.pi4j.io.gpio.GpioController;
|
||||||
|
import com.pi4j.io.gpio.GpioFactory;
|
||||||
|
import com.pi4j.io.gpio.GpioPinDigitalInput;
|
||||||
|
import com.pi4j.io.gpio.PinPullResistance;
|
||||||
|
import com.pi4j.io.gpio.PinState;
|
||||||
|
import com.pi4j.io.gpio.RaspiPin;
|
||||||
|
import com.pi4j.io.gpio.event.GpioPinDigitalStateChangeEvent;
|
||||||
|
import com.pi4j.io.gpio.event.GpioPinListenerDigital;
|
||||||
|
|
||||||
|
public class ImpulseTracker implements Runnable {
|
||||||
|
|
||||||
|
private static final int IMPULSE_REPORT_TIMEOUT = 60000; //one minute
|
||||||
|
private long nanoSecondsSleep = IMPULSE_REPORT_TIMEOUT * 1000000L;
|
||||||
|
private Integer impulseCount = 0;
|
||||||
|
private ExecutorService executorPool;
|
||||||
|
|
||||||
|
public static void main(String args[]) throws InterruptedException, IOException {
|
||||||
|
new ImpulseTracker();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImpulseTracker() throws InterruptedException, IOException{
|
||||||
|
|
||||||
|
// create gpio controller
|
||||||
|
final GpioController gpio = GpioFactory.getInstance();
|
||||||
|
|
||||||
|
// provision gpio pin #02 as an input pin with its internal pull up resistor enabled
|
||||||
|
final GpioPinDigitalInput irLightSensor = gpio.provisionDigitalInputPin(RaspiPin.GPIO_02, PinPullResistance.PULL_UP);
|
||||||
|
|
||||||
|
// create and register gpio pin listener
|
||||||
|
irLightSensor.addListener(new GpioPinListenerDigital() {
|
||||||
|
@Override
|
||||||
|
public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
|
||||||
|
if(event.getState() == PinState.LOW){ //low = light went on
|
||||||
|
//System.out.println("IR LED turned ON");
|
||||||
|
synchronized(impulseCount){
|
||||||
|
impulseCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
this.executorPool = Executors.newCachedThreadPool();
|
||||||
|
|
||||||
|
//start a daemon thread to save the impulse count every minute
|
||||||
|
Thread thread = new Thread(this);
|
||||||
|
thread.setDaemon(true);
|
||||||
|
thread.start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
long startTime = System.nanoTime();
|
||||||
|
synchronized(impulseCount){
|
||||||
|
impulseCount = 0; //reset the impulse count
|
||||||
|
}
|
||||||
|
while(true) {
|
||||||
|
sleepNano(nanoSecondsSleep);
|
||||||
|
int count = -1;
|
||||||
|
synchronized(impulseCount){
|
||||||
|
count = impulseCount;
|
||||||
|
impulseCount = 0;
|
||||||
|
}
|
||||||
|
save(System.currentTimeMillis(), count); //save the impulse count
|
||||||
|
long estimatedNanoTimeSpent = System.nanoTime() - startTime; //this is where the loop ends
|
||||||
|
startTime = System.nanoTime(); //this is where the loop starts from now on
|
||||||
|
if(estimatedNanoTimeSpent > 0){ //if no overflow
|
||||||
|
long nanoSecondsTooMany = estimatedNanoTimeSpent - (IMPULSE_REPORT_TIMEOUT*1000000L);
|
||||||
|
//System.out.println("the look took ~" + estimatedNanoTimeSpent + "ns. That is " + nanoSecondsTooMany/1000000L + "ms off");
|
||||||
|
nanoSecondsSleep -= nanoSecondsTooMany / 3; //divide by constant to take into account varaiations im loop time
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sleepNano(long ns){
|
||||||
|
//System.out.println("will go to sleep for " + ns + "ns");
|
||||||
|
try{
|
||||||
|
Thread.sleep(ns/1000000L, (int)(ns%1000000L));
|
||||||
|
}catch(InterruptedException e){
|
||||||
|
//ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void save(long timestamp_end, int data){
|
||||||
|
executorPool.execute(new Runnable(){
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
//this.listener.
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
public void setListener(Object listener){
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue