package tinygsn.model.vsensor; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.Serializable; import java.util.ArrayList; import org.apache.commons.math3.stat.regression.SimpleRegression; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.epfl.locationprivacy.util.Utils; import org.json.JSONArray; import org.json.JSONObject; 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 CalibrateOzoneVirtualSensor extends AbstractVirtualSensor { /** * */ private static final long serialVersionUID = -6312509806997497585L; private String modelUrl; private String modelName; //source: 0=local sensor, 1=remote model, 2=local calibrated private DataField[] outputStructure = new DataField[]{new DataField("o3", DataTypes.DOUBLE), new DataField("source", DataTypes.INTEGER)}; private double lastLatitude; private double lastLongitude; private long lastLocationTime = 0; private SimpleRegression sr = new SimpleRegression(); private String LOGTAG = "CalibrateOzoneVirtualSensor"; @Override public boolean initialize() { return true; } @Override public void dispose() { } @Override public void dataAvailable(String inputStreamName, StreamElement streamElement) { double ozone = 0; double model = 0; int source = 0; 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 (inputStreamName.endsWith("gps")) { lastLatitude = (Double) streamElement.getData("latitude"); lastLongitude = (Double) streamElement.getData("longitude"); lastLocationTime = streamElement.getTimeStamp(); } else { double measure = (Double) streamElement.getData("ozoneCalibrated"); if (System.currentTimeMillis() - lastLocationTime < 60000) { model = getModelValue(); if (model > -1) { sr.addData(measure, model); } } if (System.currentTimeMillis() - lastLocationTime < 15000) { ozone = model; source = 1; } else { double ozone_p = sr.predict(measure); if (!Double.isNaN(ozone_p)) { ozone = ozone_p; source = 2; } else { ozone = measure; } } 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[]{ozone, source}, streamElement.getTimeStamp())); if ((boolean) Utils.getBuildConfigValue(StaticData.globalContext, "PERFORMANCE") || (boolean) Utils.getBuildConfigValue(StaticData.globalContext, "GPSPERFORMANCE")) { stopMethodTracing(); } } } private double getModelValue() { try { double ozone = -1; HttpGet httpGet; DefaultHttpClient httpclient = new DefaultHttpClient(); httpGet = new HttpGet("http://" + modelUrl + "/modeldata?vs=" + modelName + "&models=0&format=json&latitude=" + lastLatitude + "&longitude=" + lastLongitude); HttpResponse response = httpclient.execute(httpGet); int statusCode = response.getStatusLine().getStatusCode(); InputStreamReader is = new InputStreamReader(response.getEntity().getContent(), "UTF-8"); if (statusCode == 200) { BufferedReader bufferedReader = new BufferedReader(is); String line = bufferedReader.readLine(); if (line != null) { JSONArray obj = new JSONArray(line); JSONArray f = obj.getJSONObject(0).getJSONArray("fields"); for (int i = 1; i < f.length(); i++) { JSONObject v = f.getJSONObject(i); if (v.getString("name").equalsIgnoreCase("O3_RES")) { ozone = v.getDouble("value"); break; } } } } is.close(); return ozone; } catch (Exception e) { e.printStackTrace(); return -1; } } @Override public ArrayList<Parameter> getParameters() { ArrayList<Parameter> list = new ArrayList<>(); list.add(new Parameter("server_url", ParameterType.EDITBOX)); list.add(new Parameter("model_name", ParameterType.EDITBOX)); return list; } @Override protected void initParameter(String key, String value) { if (key.endsWith("server_url")) { modelUrl = value; } else if (key.endsWith("model_name")) { modelName = value; } } @Override public DataField[] getOutputStructure(DataField[] in) { return outputStructure; } }