BatteryStats.cc

00001 /* -*- mode:c++ -*- ********************************************************
00002  * Energy Framework for Omnet++, version 0.9
00003  *
00004  * Author:  Laura Marie Feeney
00005  *
00006  * Copyright 2009 Swedish Institute of Computer Science.
00007  *
00008  * This software is provided `as is' and without any express or implied
00009  * warranties, including, but not limited to, the implied warranties of
00010  * merchantability and fitness for a particular purpose.
00011  *
00012  ***************************************************************************/
00013 
00014 /*
00015  * Battery Stats collects and formats times series and summary data
00016  * from the Battery.
00017  *
00018  * BatteryStats' summary() and detail() methods are called by
00019  * Battery's finish() to format its table of device battery
00020  * consumption. (Methods shoud manage their own resources, since own
00021  * finish() may be done).
00022  *
00023  * For time series data it subscribes to BatteryState published by the
00024  * Battery.  Note: only BatteryStats should do this, all other modules
00025  * should use the Battery's estimateResidual() method (Battery Stats
00026  * does this as well, but for now estimate just follows redisual
00027  * capacity.)
00028  */
00029 #include "BatteryStats.h"
00030 #include <iostream>
00031 
00032 Define_Module(BatteryStats);
00033 
00034 void BatteryStats::initialize(int stage)
00035 {
00036   BaseModule::initialize(stage);
00037 
00038   if (stage==0) {
00039     doDetail = 0;
00040     doDetail = par("detail").boolValue();
00041     debugEV << "show details = " << doDetail << endl;
00042 
00043     doTimeSeries = 0;
00044     doTimeSeries = par("timeSeries").boolValue();
00045     debugEV << "show timeSeries = " << doTimeSeries << endl;
00046 
00047     batteryCat = -1;
00048     if (doTimeSeries) {
00049       int scopeHost = (this->findHost())->getId();
00050       BatteryState bs;
00051       batteryCat = utility->subscribe(this, &bs, scopeHost);
00052 
00053       // suggest enabling only residualVec (omnetpp.ini), unless
00054       // others are of interest
00055 
00056       residualVec.setName("capacity");
00057       residualVec.setUnit("mW-s");
00058       relativeVec.setName("capacity(relative)");
00059 
00060       BaseBattery* batteryModule = FindModule<BaseBattery*>::findSubModule(getParentModule());
00061       if (batteryModule) {
00062         battery = batteryModule;
00063       }
00064       else {
00065         error("no battery module found, please check your Host.ned");
00066       }
00067       estimateVec.setName("estimate");
00068       estimateVec.setUnit("mW-s");
00069       estimateRelVec.setName("estimate(relative)");
00070     }
00071   }
00072 }
00073 
00074 void BatteryStats::handleMessage(cMessage *msg)
00075 {
00076   error("BatteryStats doesn't handle any messages");
00077 }
00078 
00079 // summary() and detail() are invoked by Battery's finish() method
00080 
00081 void BatteryStats::summary(double init, double final, simtime_t lifetime)
00082 {
00083   Enter_Method_Silent();
00084   recordScalar("nominal", init, "mW-s");
00085   recordScalar("total", init - final, "mW-s");
00086   recordScalar("lifetime", lifetime, "s");
00087   recordScalar("Mean power consumption", (init - final)/simTime().dbl(), "mW");
00088 }
00089 
00090 void BatteryStats::detail(DeviceEntry *devices, int numDevices)
00091 {
00092   Enter_Method_Silent();
00093   if (!doDetail)
00094     return;
00095 
00096   recordScalar("num devices", numDevices);
00097 
00098   for (int i = 0; i < numDevices; i++){
00099     double total = 0;
00100     for (int j = 0; j < devices[i].numAccts; j++) {
00101       total += devices[i].accts[j];
00102     }
00103     recordScalar(devices[i].name.c_str(), i);
00104     recordScalar("device total (mWs)", total);
00105     for (int j = 0; j < devices[i].numAccts; j++) {
00106       recordScalar("account", j);
00107       recordScalar("energy (mWs)", devices[i].accts[j]);
00108       recordScalar("time (s)", devices[i].times[j]);
00109     }
00110   }
00111 }
00112 
00113 void BatteryStats::receiveBBItem(int category, const BBItem *details, int scopeModuleId)
00114 {
00115     Enter_Method_Silent();
00116     BaseModule::receiveBBItem(category, details, scopeModuleId);
00117 
00118     if (category == batteryCat) {
00119       double residualCapacity;
00120       double relativeCapacity;
00121 
00122       // battery time series never publishes capacity < 0, just 0
00123       residualCapacity = ((BatteryState *)details)->getAbs();
00124       residualVec.record(residualCapacity);
00125       relativeCapacity = ((BatteryState *)details)->getRel();
00126       relativeVec.record(relativeCapacity);
00127 
00128       // for comparison, also get the estimated residual capacity
00129       double estimate = battery->estimateResidualAbs();
00130       estimateVec.record(estimate);
00131 
00132       double estimateRel = battery->estimateResidualRelative();
00133       estimateRelVec.record(estimateRel);
00134     }
00135 
00136 }
00137 
00138 void BatteryStats::finish() {
00139 }
00140 
00141