/* * This file is part of the Remote Sensor Actuator Interface (ReSAI). * * Copyright(c) Andreas Kipp, Frederic Siepmann * http://opensource.cit-ec.de/projects/resai * * This file may be licensed under the terms of of the * GNU Lesser General Public License Version 3 (the ``LGPL''), * or (at your option) any later version. * * Software distributed under the License is distributed * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either * express or implied. See the LGPL for the specific language * governing rights and limitations. * * You should have received a copy of the LGPL along with this * program. If not, go to http://www.gnu.org/licenses/lgpl.html * or write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The development of this software was supported by the * Excellence Cluster EXC 277 Cognitive Interaction Technology. * The Excellence Cluster EXC 277 is a grant of the Deutsche * Forschungsgemeinschaft (DFG) in the context of the German * Excellence Initiative. * */ /** * Evaluation tab to measure exchange rates. * * @author akipp */ package de.unibi.airobots.resaidroid.tabactivities; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.text.DecimalFormat; import java.util.HashMap; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.widget.TextView; import de.unibi.airobots.resaidroid.R; import de.unibi.airobots.resaidroid.helper.TimeConverter; import de.unibi.airobots.resaidroid.tabactivities.template.TabTemplate; public class TabEvaComponent extends TabTemplate { private long servertime = 0; private long clientTime = 0; // private long timeDiff = 0; private long sendTime = 0; private long receiveTime = 0; private long workTime = 0; private long receiveLatency = 0; private long workLatency = 0; private long sumLatency = 0; private double meanlatency = 0.0; private long messageNo = 0; private TextView txtServerTime; private TextView txtClientTime; private TextView txtMeanLatency; private TextView txtWorkText; private TextView txtWorkTime; private TextView txtSendTime; private TextView txtReciveTime; private TextView txtMessageNo; private String filename = ""; final private String STAT_FILE = "/proc/stat"; private long mUser; private long mSystem; private long mTotal; private long lastResaiRuntime = 0; private String cpuText = ""; private double resaiCpu = 0.0; private double cpu = 0.0; private int batteryLevel = 0; private int battOld = 0; private int charsCounted = 0; final private DecimalFormat mPercentFmt = new DecimalFormat("#0.0"); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.evacomponent); txtServerTime = (TextView) findViewById(R.id.serverTime); txtClientTime = (TextView) findViewById(R.id.clientTime); txtMeanLatency = (TextView) findViewById(R.id.meanLatency); txtWorkText = (TextView) findViewById(R.id.worktext); txtWorkTime = (TextView) findViewById(R.id.workTime); txtReciveTime = (TextView) findViewById(R.id.receiveTime); txtSendTime = (TextView) findViewById(R.id.sendTime); txtMessageNo = (TextView) findViewById(R.id.msgNo); lastResaiRuntime = getResaiRuntime(); registerReceiver(this.mBatInfoReceiver, new IntentFilter( Intent.ACTION_BATTERY_CHANGED)); } @Override public void processProperties() { messageHandler.post(new Runnable() { public void run() { try { synchronized (receivedProperties) { if (receivedProperties.containsKey(cm.getComponent(TAG) + "_HANDSHAKE")) { servertime = Long.parseLong(receivedProperties.get( cm.getComponent(TAG) + "_HANDSHAKE") .toString()); clientTime = System.currentTimeMillis(); txtServerTime.setText(TimeConverter .toDateTime(servertime)); txtClientTime.setText(TimeConverter .toDateTime(clientTime)); // timeDiff = Math.abs(clientTime - servertime); // txtTimeDiff.setText(String.valueOf(timeDiff)); // CREATE DATA FILE sumLatency = 0; meanlatency = 0.0; messageNo = 0; filename = receivedProperties.get(cm .getComponent(TAG) + "_FILENAME"); createLogHead(); } if (receivedProperties.containsKey(cm.getComponent(TAG) + "_TIME")) { receiveTime = System.currentTimeMillis(); sendTime = Long.parseLong(receivedProperties.get( cm.getComponent(TAG) + "_TIME").toString()); receiveLatency = Math.abs(Math.abs(sendTime - receiveTime)); txtMessageNo.setText(receivedProperties.get( cm.getComponent(TAG) + "_MSGNO").toString()); messageNo = Long.parseLong(receivedProperties.get( cm.getComponent(TAG) + "_MSGNO").toString()); sumLatency +=receiveLatency; meanlatency = sumLatency / messageNo; txtMeanLatency.setText(String.valueOf(meanlatency)); // TODO - timeDiff); txtSendTime.setText(TimeConverter .toDateTime(sendTime)); txtReciveTime.setText(TimeConverter .toDateTime(receiveTime) + "(" + receiveLatency + ")"); // HERE WE CREATE WORK charsCounted = doWork(receivedProperties); workTime = System.currentTimeMillis(); workLatency = Math.abs(Math .abs(workTime - sendTime)); // TODO - // timeDiff); txtWorkTime.setText(TimeConverter .toDateTime(workTime) + "(" + workLatency + ")"); readCpuTime(); txtWorkText.setText("ReSAI: " + getRuntime() + " / CPU: " + cpuText + "\n"); txtWorkText.append("Battery: " + batteryLevel + "%\n"); txtWorkText.append("Chars worked: " + charsCounted); writeLogLine(); } } } catch (NullPointerException e) { Log.i(TAG, "NULL POINTER...ELEMENT NOT FOUND."); } } }); } /** * This method iterates over all properties and adds their value length to * the return value. * * @param receivedProperties */ private int doWork(HashMap receivedProperties) { int characters = 0; for (String prop : receivedProperties.keySet()) { for (int i = 0; i < receivedProperties.get(prop).length(); i++) { characters++; } } return characters; } private void createLogHead() { FileOutputStream fos; try { File root = Environment.getExternalStorageDirectory(); File file = new File(root.getAbsoluteFile(), filename); if (file.exists()) { file.delete(); } fos = new FileOutputStream(file, true); String text = // "timeDiff;" + "charsCounted;sendTime;receiveTime;receiveLat;workTime;worklat;resaiCpu;cpu;batteryLevel;battUsage\n"; fos.write(text.getBytes()); fos.close(); // txtWorkText.setText(getRuntime()); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void writeLogLine() { FileOutputStream fos; try { File root = Environment.getExternalStorageDirectory(); File file = new File(root.getAbsoluteFile(), filename); fos = new FileOutputStream(file, true); String text = // timeDiff + ";" + charsCounted + ";" + sendTime + ";" + receiveTime + ";" + receiveLatency + ";" + workTime + ";" + workLatency + ";" + resaiCpu + ";" + cpu + ";" + batteryLevel + ";" + (battOld - batteryLevel) + "\n"; fos.write(text.getBytes()); fos.close(); // txtWorkText.setText(getRuntime()); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private String getRuntime() { long thisResaiRuntime = getResaiRuntime(); long deltaResaiRuntime = Math.abs(lastResaiRuntime - thisResaiRuntime); String text = String.valueOf((deltaResaiRuntime / 10.0) + "% "); resaiCpu = (deltaResaiRuntime / 10.0); lastResaiRuntime = thisResaiRuntime; return text; } private long getResaiRuntime() { File proc_dir = new File("/proc/"); String files[] = proc_dir.list(); for (int i = 0; i < files.length; ++i) { if (files[i].matches("[0-9]+") == true) { String stat = readData("/proc/" + files[i] + "/stat"); if (stat == null) continue; String[] segs = stat.split("[ ]+"); long runtime = Long.parseLong(segs[13]) + Long.parseLong(segs[14]); String cmdline = segs[1]; if (cmdline.toLowerCase().contains("resai")) { return runtime; } } } return 0; } private String readData(String filename) { FileReader fstream; try { fstream = new FileReader(filename); } catch (FileNotFoundException e) { Log.i("NetMeter", "File access error " + filename); return null; } BufferedReader in = new BufferedReader(fstream, 500); try { return in.readLine(); } catch (IOException e) { Log.i("NetMeter", "read error on " + filename); return null; } } private void readCpuTime() { FileReader fstream; try { fstream = new FileReader(STAT_FILE); BufferedReader in = new BufferedReader(fstream, 500); String line; while ((line = in.readLine()) != null) { if (line.startsWith("cpu")) { updateStats(line.trim().split("[ ]+")); break; } } } catch (FileNotFoundException e) { Log.e(TAG, "Could not read " + STAT_FILE); } catch (IOException e) { Log.e(TAG, e.toString()); } } private void updateStats(String[] segs) { // user = user + nice long user = Long.parseLong(segs[1]) + Long.parseLong(segs[2]); // system = system + intr + soft_irq long system = Long.parseLong(segs[3]) + Long.parseLong(segs[6]) + Long.parseLong(segs[7]); // total = user + system + idle + io_wait long total = user + system + Long.parseLong(segs[4]) + Long.parseLong(segs[5]); if (mTotal != 0 || total >= mTotal) { long duser = user - mUser; long dsystem = system - mSystem; long dtotal = total - mTotal; cpu = (double) (duser + dsystem) * 100.0 / dtotal; cpuText = (mPercentFmt.format((double) (duser + dsystem) * 100.0 / dtotal) + "% (" + mPercentFmt.format((double) (duser) * 100.0 / dtotal) + "/" + mPercentFmt.format((double) (dsystem) * 100.0 / dtotal) + ")"); } mUser = user; mSystem = system; mTotal = total; } private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver() { @Override public void onReceive(Context arg0, Intent intent) { // TODO Auto-generated method stub batteryLevel = intent.getIntExtra("level", 0); if (battOld == 0) { battOld = batteryLevel; } } }; }