fixed issue with Timestamp sorting

added new RAM-only logger
fixed issue with WiFi timestamps
This commit is contained in:
2019-08-22 12:39:00 +02:00
parent a0d46c9aae
commit e344fbbfef
9 changed files with 248 additions and 48 deletions

View File

@@ -1,15 +1,16 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion '26.0.3'
compileSdkVersion 29
buildToolsVersion '29.0.2'
defaultConfig {
applicationId "de.fhws.indoor.sensorreadout"
minSdkVersion 21
minSdkVersion 19
targetSdkVersion 23
versionCode 1
versionName "1.0"
multiDexEnabled true
}
buildTypes {
release {

View File

@@ -35,12 +35,12 @@ import java.util.Set;
import de.fhws.indoor.sensorreadout.sensors.GpsNew;
import de.fhws.indoor.sensorreadout.sensors.GroundTruth;
import de.fhws.indoor.sensorreadout.sensors.Logger;
import de.fhws.indoor.sensorreadout.sensors.LoggerRAM;
import de.fhws.indoor.sensorreadout.sensors.PedestrianActivity;
import de.fhws.indoor.sensorreadout.sensors.PedestrianActivityButton;
import de.fhws.indoor.sensorreadout.sensors.PhoneSensors;
import de.fhws.indoor.sensorreadout.sensors.WiFi;
import de.fhws.indoor.sensorreadout.sensors.iBeacon;
import de.fhws.indoor.sensorreadout.sensors.iBeaconOld;
import de.fhws.indoor.sensorreadout.sensors.mySensor;
import de.fhws.indoor.sensorreadout.sensors.SensorType;
@@ -53,7 +53,8 @@ public class MainActivity extends Activity {
MediaPlayer mpFailure;
private final ArrayList<mySensor> sensors = new ArrayList<mySensor>();
private final Logger logger = new Logger(this);
//private final Logger logger = new Logger(this);
private final LoggerRAM logger = new LoggerRAM(this);
private Button btnStart;
private Button btnStop;
private Button btnGround;
@@ -250,29 +251,39 @@ public class MainActivity extends Activity {
logger.addCSV(id, timestamp, csv);
runOnUiThread(new Runnable() {
@Override public void run() {
if (id == SensorType.WIFI) {
final TextView txt = (TextView) findViewById(R.id.txtWifi);
txt.setText( ((++loadCounterWifi % 2) == 0) ? "wi" : "WI");
} else if (id == SensorType.IBEACON){
final TextView txt = (TextView) findViewById(R.id.txtBeacon);
txt.setText( ((++loadCounterBeacon % 2) == 0) ? "ib" : "IB");
} else if (id == SensorType.GPS){
final TextView txt = (TextView) findViewById(R.id.txtGPS);
txt.setText( ((++loadCounterGPS % 2) == 0) ? "gps" : "GPS");}
// update UI for WIFI/BEACON/GPS
if (id == SensorType.WIFI || id == SensorType.IBEACON || id == SensorType.GPS) {
runOnUiThread(new Runnable() {
@Override
public void run() {
// dump buffer stats every x entries
if (++loadCounterAny % 250 == 0) {
if (id == SensorType.WIFI) {
final TextView txt = (TextView) findViewById(R.id.txtWifi);
txt.setText(((++loadCounterWifi % 2) == 0) ? "wi" : "WI");
} else if (id == SensorType.IBEACON) {
final TextView txt = (TextView) findViewById(R.id.txtBeacon);
txt.setText(((++loadCounterBeacon % 2) == 0) ? "ib" : "IB");
} else if (id == SensorType.GPS) {
final TextView txt = (TextView) findViewById(R.id.txtGPS);
txt.setText(((++loadCounterGPS % 2) == 0) ? "gps" : "GPS");
}
}
});
}
// dump buffer stats every x entries
if (++loadCounterAny % 250 == 0) {
runOnUiThread(new Runnable() {
@Override
public void run() {
final TextView txt = (TextView) findViewById(R.id.txtBuffer);
final float elapsedMinutes = (timestamp - logger.getStartTS()) / 1000.0f / 1000.0f / 1000.0f / 60.0f;
final int kBPerMin = (int) (logger.getTotalSize() / 1024.0f / elapsedMinutes);
txt.setText( (logger.getCurrentBufferSize() / 1024) + "k, " + logger.getNumEntries() + ", " + kBPerMin + "kB/m");
txt.setText((logger.getCurrentBufferSize() / 1024) + "k, " + logger.getNumEntries() + ", " + kBPerMin + "kB/m");
}
}
});
});
}
}
@@ -439,7 +450,7 @@ public class MainActivity extends Activity {
});
}
if(activeSensors.contains("WIFI")) {
// logo wifi using sensor number 8
// log wifi using sensor number 8
final WiFi wifi = new WiFi(this);
sensors.add(wifi);
wifi.setListener(new mySensor.SensorListener() {
@@ -461,15 +472,18 @@ public class MainActivity extends Activity {
final mySensor beacon;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
beacon = new iBeacon(this);
} else{
beacon = new iBeaconOld(this);
} else {
beacon = null;
//beacon = new iBeaconOld(this);
}
sensors.add(beacon);
beacon.setListener(new mySensor.SensorListener() {
@Override public void onData(final long timestamp, final String csv) { add(SensorType.IBEACON, csv, timestamp); }
@Override public void onData(final SensorType id, final long timestamp, final String csv) {return; }
});
if (beacon != null) {
sensors.add(beacon);
beacon.setListener(new mySensor.SensorListener() {
@Override public void onData(final long timestamp, final String csv) { add(SensorType.IBEACON, csv, timestamp); }
@Override public void onData(final SensorType id, final long timestamp, final String csv) {return; }
});
}
}
}

View File

@@ -166,7 +166,7 @@ public final class Logger {
@Override
public int compareTo(@NonNull LogEntry another) {
return (int)(timestamp - another.timestamp);
return (timestamp < another.timestamp) ? (-1) : (+1);
}
}

View File

@@ -0,0 +1,171 @@
package de.fhws.indoor.sensorreadout.sensors;
import android.content.Context;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Collections;
/**
* log sensor data to RAM
* only flush to file when finished
*/
public final class LoggerRAM {
public static final long BEGINNING_TS = -1;
private StringBuilder stringBuilder = new StringBuilder();
private File file;
private FileOutputStream fos;
private Context context;
private boolean addingStopped = false;
private int entries = 0;
private int sizeTotal = 0;
private int currentSize = 0;
private ArrayList<LogEntry> buffer = new ArrayList<>();
/** timestamp of logging start. all entries are relative to this one */
private long startTS = 0;
public LoggerRAM(Context context) {
this.context = context;
}
/** start logging (into RAM) */
public final void start() {
// start empty
stringBuilder.setLength(0);
entries = 0;
sizeTotal = 0;
currentSize = 0;
buffer.clear();
addingStopped = false;
// starting timestamp
startTS = SystemClock.elapsedRealtimeNanos();
// open the output-file immeditaly (to get permission errors)
// but do NOT yet write anything to the file
final DataFolder folder = new DataFolder(context, "sensorOutFiles");
file = new File(folder.getFolder(), startTS + ".csv");
try {
fos = new FileOutputStream(file);
Log.d("logger", "will write to: " + file.toString());
} catch (final Exception e) {
throw new MyException("error while opening log-file", e);
}
}
/** stop logging and flush RAM-data to the flash-chip */
public final void stop() {
addingStopped = true;
synchronized (buffer) {
// sort by TS (ensure strict ordering)
Collections.sort(buffer);
// export each entry
for (LogEntry e : buffer) {
try {
fos.write(e.csv.getBytes());
} catch (final Exception ex) {
ex.printStackTrace();;
}
}
// done
buffer.clear();
}
// done
close();
}
public File getFile() {
return file;
}
public int getCurrentBufferSize() {return currentSize;}
public int getTotalSize() {return sizeTotal;}
public int getNumEntries() {return entries;}
/** add a new CSV entry for the given sensor number to the internal buffer */
public final void addCSV(final SensorType sensorNr, final long timestamp, final String csv) {
if (addingStopped) {return;}
final long relTS = (timestamp == BEGINNING_TS) ? 0 : (timestamp - startTS);
if(relTS >= 0) { // drop pre startTS logs (at the beginning, sensors sometimes deliver old values)
stringBuilder.setLength(0);
stringBuilder.append(relTS); // relative timestamp (uses less space)
stringBuilder.append(';');
stringBuilder.append(sensorNr.id());
stringBuilder.append(';');
stringBuilder.append(csv);
stringBuilder.append('\n');
++entries;
LogEntry logEntry = new LogEntry(relTS, stringBuilder.toString());
sizeTotal += logEntry.csv.length();
currentSize += logEntry.csv.length();
synchronized (buffer) {
buffer.add(logEntry);
}
}
}
private final void close() {
try {
fos.close();
} catch (final Exception e) {
throw new MyException("error while writing log-file", e);
}
}
public final long getStartTS() {
return startTS;
}
int cnt = 0;
private final void debug(boolean force) {
if (++cnt % 1000 == 0 || force) {
Log.d("buffer", "size: " + buffer.size() + " lines");
}
}
private static class LogEntry implements Comparable<LogEntry> {
public long timestamp;
public String csv;
public LogEntry(long timestamp, String csv) {
this.timestamp = timestamp;
this.csv = csv;
}
@Override
public int compareTo(@NonNull LogEntry another) {
return (timestamp < another.timestamp) ? (-1) : (+1);
}
}
}

View File

@@ -23,6 +23,7 @@ public class WiFi extends mySensor {
private final WifiManager wifi;
private BroadcastReceiver receiver;
private boolean isReceiverRegistered;
private boolean isFirstMeasurement = true;
public WiFi(final Activity act) {
@@ -40,17 +41,29 @@ public class WiFi extends mySensor {
this.receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final StringBuilder sb = new StringBuilder(1024);
final List<ScanResult> res = wifi.getScanResults();
long timestamp = System.currentTimeMillis();
for (final ScanResult sr : res) {
sb.append(Helper.stripMAC(sr.BSSID)).append(';');
sb.append(sr.frequency).append(';');
sb.append(sr.level).append(';');
timestamp = sr.timestamp;
}
if (listener != null && isReceiverRegistered) {
listener.onData(timestamp, sb.toString());
// ignore the first measurement
if (isFirstMeasurement) {
isFirstMeasurement = false;
} else {
final StringBuilder sb = new StringBuilder(1024);
final List<ScanResult> res = wifi.getScanResults();
long timestamp = 0;
for (final ScanResult sr : res) {
sb.append(Helper.stripMAC(sr.BSSID)).append(';');
sb.append(sr.frequency).append(';');
sb.append(sr.level).append(';');
// export with oldest timestamp among all contained measurements
final long nanos = sr.timestamp * 1000;
if (nanos > timestamp) {
timestamp = nanos;
}
}
if (listener != null && isReceiverRegistered) {
listener.onData(timestamp, sb.toString());
}
}
startScan();
//Log.d("wifi", sb.toString());

View File

@@ -20,7 +20,7 @@ public class iBeacon extends mySensor {
private static final int REQUEST_ENABLE_BT = 1;
private ScanCallback mLeScanCallback;
/** ctor */
// ctor
public iBeacon(final Activity act) {
// sanity check

View File

@@ -14,14 +14,14 @@ import android.widget.Toast;
/**
* Created by toni on 02/06/16.
*/
/*
public class iBeaconOld extends mySensor {
private BluetoothAdapter bt = null;
private static final int REQUEST_ENABLE_BT = 1;
private BluetoothAdapter.LeScanCallback mLeScanCallback;
/** ctor */
// ctor
public iBeaconOld(final Activity act) {
// sanity check
@@ -70,3 +70,4 @@ public class iBeaconOld extends mySensor {
}
}
*/