package tinygsn.model.vsensor; import org.epfl.locationprivacy.util.Utils; import java.io.Serializable; import java.util.ArrayList; import tinygsn.beans.DataField; import tinygsn.beans.DataTypes; import tinygsn.beans.StaticData; import tinygsn.beans.StreamElement; import tinygsn.model.utils.ParameterType; import tinygsn.model.utils.Parameter; import static android.os.Debug.startMethodTracing; import static android.os.Debug.stopMethodTracing; public class METVirtualSensor extends AbstractVirtualSensor { private static final long serialVersionUID = -5276247717926554522L; double weight = 60.0; double age = 30; String gender = "m"; private DataField[] outputStructure = new DataField[]{new DataField("MET", DataTypes.DOUBLE), new DataField("VA", DataTypes.DOUBLE), new DataField("start", DataTypes.BIGINT), new DataField("end", DataTypes.BIGINT)}; double[] MET_Table = new double[]{3, 1.8, 10, 7.5, 5, 1.3}; StreamElement lastActivity = null; private String LOGTAG = "METVirtualSensor"; //3.bike : 7.5 //5.sitting : 1.3 //1.standing : 1.8 //2.running : 10 //4.stairs : 5 //0.walking : 3 private double getRMR() { if (gender.equals("m")) { if (age < 30) { return 2.896 + weight * 0.063; } else if (age < 60) { return 3.653 + weight * 0.048; } else { return 2.459 + weight * 0.049; } } else { if (age < 30) { return 2.036 + weight * 0.062; } else if (age < 60) { return 3.538 + weight * 0.034; } else { return 2.755 + weight * 0.038; } } } private double getNVO2max() { double n = 0; if (gender.equals("m")) { n = 44 / 2.0; } else { n = 33.8 / 2.0; } if (age < 30) { n += 45.3 / 2.0; } else if (age < 40) { n += 43.8 / 2.0; } else if (age < 50) { n += 42.9 / 2.0; } else if (age < 60) { n += 36.8 / 2.0; } else if (age < 70) { n += 30.7 / 2.0; } else { n += 27.2 / 2.0; } return n; } @Override public boolean initialize() { return true; } @Override public void dispose() { } @Override public void dataAvailable(String inputStreamName, StreamElement streamElement) { if ((boolean) Utils.getBuildConfigValue(StaticData.globalContext, "PERFORMANCE")) { startMethodTracing("Android/data/tinygsn.gui.android/" + LOGTAG + "_" + inputStreamName + "_" + System.currentTimeMillis()); } log("dataAvailable_" + LOGTAG + "_" + inputStreamName, "==========================================="); log("dataAvailable_" + LOGTAG + "_" + inputStreamName, "Starting to process data in dataAvailable"); long startLogTime = System.currentTimeMillis(); streamElement = super.anonymizeData(inputStreamName, streamElement); if (lastActivity == null) { lastActivity = streamElement; } if (lastActivity.getData("activity") != streamElement.getData("activity")) { double MET = MET_Table[((Double) lastActivity.getData("activity")).intValue()]; double ECF = 0.21; double RMR = getRMR(); double NVO2max = getNVO2max(); double VAmax = NVO2max * weight * (1.212 - 0.14 * Math.log((streamElement.getTimeStamp() - lastActivity.getTimeStamp()) / 60000.0)); double VA = 19.63 * ECF * MET * RMR; if (VAmax != Double.NaN) { VA = 19.63 * Math.min(ECF * MET * RMR, VAmax); } long endLogTime = System.currentTimeMillis(); log("dataAvailable_" + LOGTAG + "_" + inputStreamName, "Total Time to process data in dataAvailable() (without dataProduced()) : " + (endLogTime - startLogTime) + " ms."); dataProduced(new StreamElement(outputStructure, new Serializable[]{MET, VA, lastActivity.getTimeStamp(), streamElement.getTimeStamp()}, streamElement.getTimeStamp())); lastActivity = streamElement; if ((boolean) Utils.getBuildConfigValue(StaticData.globalContext, "PERFORMANCE") || (boolean) Utils.getBuildConfigValue(StaticData.globalContext, "GPSPERFORMANCE")) { stopMethodTracing(); } } } @Override public ArrayList<Parameter> getParameters() { ArrayList<Parameter> list = new ArrayList<>(); list.add(new Parameter("weight", ParameterType.EDITBOX)); list.add(new Parameter("age", ParameterType.EDITBOX)); list.add(new Parameter("gender(m/f)", ParameterType.EDITBOX)); return list; } @Override protected void initParameter(String key, String value) { if (key.endsWith("weight")) { weight = Double.parseDouble(value); } else if (key.endsWith("age")) { age = Integer.parseInt(value); } else if (key.endsWith("gender(m/f)")) { gender = value; } } @Override public DataField[] getOutputStructure(DataField[] in) { return outputStructure; } }