Energy Framework


The Energy Framework is a collection of new modules that provide a framework for modeling battery consumption of wireless devices. Several existing modules have also been extended to be battery-aware. The Energy Framework is intended to be flexible and extensible: a host can have multiple sources of energy consumption (e.g. nic, sensor, processor) and their energy consumption can be modeled in a variety of ways.

The Energy Framework was partly inspired by the Battery Module 2.0 of Anna Förster ( However, the Energy Framework is structured differently and provides a number of features not supported in Battery Module 2.0. A set of Energy Framework modules provide backward compatibility with the the Battery Module2.0

The Energy Framework is implemented in omnet++3 and the
mobility-fw2.0p3, although the functionality not strongly dependent on mobility-fw internals (except for HostState notifications). The presence of a fairly extensive collection of validation tests will make porting easier.

The Energy Framework was ported to MiXiM by Daniel Willkomm and Karl Wessel of the TKN Group at TU-Berlin and is part of all MiXiM versions 1.2 and later.


The key abstraction in the Energy Framework is a Battery module that provides a well-defined message interface to one or more energy consuming Device(s).

Each Device models its energy consumption by sending a sequence of messages to the Battery indicating the amount of continuous (CURRENT) or discrete (ENERGY) draw. For logging purposes, the energy consumed can also be assigned to a particular activity (e.g. Tx, Rx, sleep). The activities are specified on a per-device basis, so that Devices are independent. The Device functionality can be an independent module (e.g. DeviceAF) or it can be included in some other host module (e.g. in the NIC's SnrEval).

The Battery models both the residual capacity of the battery and the host's own state-of-charge estimation, which may differ from the actual residual capacity. Other host modules should use only the estimated value (e.g. for battery-aware routing). The Battery also announces Host State information via the blackboard to inform nodes of host failure due to battery depletion. A separate BatteryStats module is intended to make it easy to do simulation-specific data collection and visualization.


Separating the modeling of energy consuming operations from the modeling of the capacity of the battery enables some features that are not supported in BatteryModule2.0:


One Battery model, two Battery Stats modules and two network Devices have already been implemented in the Energy Framework. In addition, several abstract "test" Devices have also been implemented. These are also suitable as a basis for modeling e.g. simple sensors, etc.


The battery is the core of the Energy Framework, as it provides a well-defined message interface to any Device that consumes energy (i.e. any module that models energy consuming operations). The battery maintains an array of input Gates, whose size is specified by parameter numDevices, which is most easily specified in the Host.ned, where the Device's connection to the battery are also specified. (See tests/deviceTestMulti for an example).

Each Device sends DrawMsg's to the Battery to inform it of each change in its current draw (CURRENT). The Battery updates its residual capacity based on the total current being drawn by all devices. Since CURRENT represents continuous battery consumption, each Device must to ensure that the value is updated for each relevant state change in the Device (note 1).

A Device can also send a drawMsg that immediately deducts a certain amount of energy from the battery (ENERGY). The ENERGY message is used to represent the energy consumption of operations that are only modeled at high level of abstraction or would be difficult to represent as a fixed current draw. Examples include state changes, sensor readings, etc. An ENERGY deduction does not affect any ongoing CURRENT deductions.

The DrawMsg can also specify which of a Device's accounts should be "charged" for the battery consumption and the Battery keeps energy consumption statistics per-device and per-account within each Device. Before sending the first Draw message, each module must therefore send a Register message to the battery, providing a device name and number of activities to which the device will assign energy consumption.

The Battery also provides a public interface for other modules to get the host's remaining battery capacity: estimateResidualRelative() and estimateRedidualAbs(). The distinction between the modeled capacity of the battery and its state-of-charge estimate is necessary because there are limitations on hardware's ability to estimate own battery reserves. That means that modules should always use the
estimateResidual*() calls rather than obtaining battery statistics. Because s-o-c estimation is battery chemistry dependent, in the current implementation, the estimate is just the same as the modeled capacity.

The Battery also publishes a Host State notification to announce host failure when the battery is depleted. All modules, whether or not they use the Battery directly, should subscribe to this notification and should stop any pending events and correctly handle internal statistics when the host fails (note 2). This is important, because the NIC module can only shut down the interface, so that there are no frames transmitted or received. But if other layers keep generating traffic and recording statistics about it, the simulation results will be nonsense.

Finally, the Battery also provides real-time Battery State information and consumption statistics to the BatteryStats module (see below).

The only Battery model currently implemented is SimpleBattery, which provides a simple linear model of energy consumption, similar to BatteryModule2.0. The residual capacity consumed over an interval is the total current drawn by all devices * nominal battery voltage * the length of the interval. The capacity is updated with every new DrawMsg and at interval specified by the resolution parameter.

The internal unit of energy and the unit in ENERGY messages is mW-s. CURRENT is given in units of mA. Battery capacity is specified in mA-hr (both rated capacity and initial value) at V volts.

It should be possible to cleanly replace this model with more sophisticated battery chemistry models, or with models of alternative energy sources, such as solar charging. Because the ENERGY message is itself an approximation (an extremely useful one), it's probably not suitable for use with a very sophisticated battery module (note 3).


The Battery does not generate any statistics output by itself, this is done by the BatteryStats module. There are two interactions between the Battery and the BatteryStats module.

The first interaction is for summary data. At finish(), the Battery passes its record of battery consumption (per-device and per-activity) to summary()/detail() methods provided by the BatteryStats module, allowing the BatteryStats module to format data however it likes (note 4).

The second interaction is for time series data, which the BatteryStats module obtains throughout the simulation. The Battery publishes residual capacity (note 4) information on the blackboard, at intervals controlled by the parameters 'publishTime' and 'publishDelta'.

There is no particular requirement to use the mobility-fw blackboard interface - an omnetpp message or a direct method invocation could also be suitable. Host modules should not use residual capacity information published to the stats module; they should use the estimateResidual*() interface described above.

There are two implemented battery statistics modules. BatteryStatsAF generates output compatible with BatteryModule2.0 (time in each state for a single device). BatteryStats reports all per-device/activity information (see howto.txt for an example of output). Currently, both existing statistics modules use the omnetpp scalar and vector data collection.

There is also a Python script that converts simulation .vec files to per-host time series data files.

Usage: [options]

-h, --help show this help message and exit -i INFILE, --infile=INFILE

input .vec file -o OUTDIR, --outdir=OUTDIR

output directory -p PRECISION, --precision=PRECISION

precision in output (not generally used) -c COMMENT, --comment=COMMENT

comment char (for input to graphics or other program)

The -c option ensures that non-data lines have the appropriate comment header for the plotting program (use -c "#" for gnuplot).


In the Energy Framework, a Device is any module that sends Register and DrawMsg's to the Battery -- it can be a standalone module or the functionality can be incorporated into another module. Two communication Devices, NIC80211Battery and DeviceAF, and several simple abstract test Devices have been implemented.

Nic80211Battery, which extends the mobility-fw 80211Nic, is the best way to model battery consumption of IEEE 802.11 based systems. The parameters used for Nic80211Battery are based on the Marvell low power wi-fi chipset.

The SnrEval80211 module of Nic80211Battery has been replaced by SnrEval80211Battery, which sends DrawMsg to the battery when handling outbound frames from the upper layer and incoming frames from the channel. Unlike the DeviceAF, the SnrEval80211Battery distinguishes between receive and idle, as it can determine whether the NIC perceives the medium as busy, when the frame is received from the lower layer. There is placeholder code to support state change cost, but these lack good hardware data and are not tested. There is also placeholder code to support variable transmit power, but this is not useful, as there is currently no straightforward way for higher layers to specify transmit power.

The SnrEval80211Battery module also subscribes to the Host State notification published by the battery. It responds to host failure by blocking frames to and from the channel. This ensures that no other hosts interact with the failed host. However, other modules should also subscribe to the Host State notification and cancel pending messages and update statistics appropriately on host failure. The BurstApplLayerBattery, which extends the BurstApplLayer test module, has been updated to cancel a pending burst on host failure.

DeviceAF is a standalone device that models battery consumption by listening to blackboard messages announcing the state of the Radio and sending DrawMsg's accordingly. It is intended to mimic the operation of BatteryModule2.0 and also demonstrates the ability of the Energy Framework to support quite different battery consumption models.

There are also a number of abstract devices that implement various kinds of duty cycles and battery consumption patterns. For example, DeviceDutySimple implements a simple on/off duty cycle, with a fixed wakeup cost. They are primarily used for testing and as examples, but are also suitable as a basis for modeling simple sensors and so forth.


The Battery's resolution parameter determines the longest interval between updates of the battery state. It should therefore be much shorter than the expected host lifetime.

In general, the worst case lifetime error is the larger of:

To see this, consider a battery that should fail at time t. If floating point operation has left its capacity at epsilon > 0, it is not until the next resolution timeout (for CURRENT draw) or next ENERGY message, that the capacity will become negative. If the host is inactive (i.e. no ongoing battery consumption) neither of these will occur until the host becomes active.

The worst case error in the total energy consumption is the larger of:

If several devices are consuming energy at the time of battery depletion, it's arbitrary which device consumes last bit of energy

For meaningful simulation results, the resolution, initial capacity and sim-time-limit should be chosen so that these errors are much less than the total lifetime and/or energy. For a given simulation, it should be possible to estimate the relevant error for use in data analysis.

The BatteryStats module is informed of the actual total energy consumption, which can be larger than the initial capacity.

It should also be emphasized that any discussion of precision of the Energy Framework has to take into account that the linear battery model and device power consumptions models themselves are quite crude.


The Energy Framework was partly inspired by BatteryModule2.0 of Anna Förster ( As this document shows, the Energy Framework is structured quite differently and provides a lot of extra functionality.

BatteryModule2.0 combines all functionality into a single module, which listens to the radio state announcements on the blackboard, decrements the battery capacity, and generates statistics.

In the Energy Framework, the DeviceAF also listens to the radio state, but sends DrawMsg's to the Battery, while BatteryStatsAF gets battery state information from the Battery and generates Battery Module 2.0-compatible output. (There's no particular dependency between DeviceAF and BatteryStatsAF, since the statistics interface is shared.)

Note that while the *AF modules are intended to be compatible with the original BatteryModule, they are not "bug- compatible": There are some issues in the BatteryModule2.0. The input parameters are also slightly different, as the Energy Framework takes voltage into account. See tests/AFTest/README.txt for details.


The Energy Framework is intended to be flexible and extensible. That means that well-validated contributions of Battery and Device models is most welcome, as is hardware data for parameterizing existing devices.


This is version 0.9 of the Energy Framework for Omnet++, written by Laura Marie Feeney (

Comments may be directed to me at lmfeeney at, or (better) to the omnet++ mailing list at omnetpp at

Most of the Energy Framework is

Exceptions are the BatteryModule2.0 compability modules and the extensions to existing mobility-fw modules. See individual files for details.


(1) If two modules independently control current for a single logical device, then they'll both need to talk to a little switching module that has a single stream of CURRENT messages to the battery. It's hard to think of a sensible example of when this would be needed.

(2) It would be much better if OMNeT++ had a general way of enforcing that all modules supported START/STOP signals.

(3) So some common sense is required in designing simulations.

(4) Note that since there's no control over order of finish() invocation, summary()/detail() methods have to manage their own resources.

(5) The state-of-charge estimate is announced along with the residual capacity; it is currently ignored, since the two are identical.