Commit 3c2239a0 authored by Julian Zobel's avatar Julian Zobel
Browse files

Refactored the way that energy consumation is calculated for the energy...

Refactored the way that energy consumation is calculated for the energy models. Now the consumation is calculated on every energy component for itself, since the state change is of no interest to the energy model. Makes the process easier.
Monitor logging can now be added to the respective energy components, if that is wished again (was removed from the energy model anyways!).
parent 548eb15e
......@@ -21,6 +21,7 @@
package de.tud.kom.p2psim.api.energy;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Time;
/**
* A component that consumes energy (ie. a radio or a GPS-receiver).
......@@ -72,5 +73,9 @@ public interface EnergyComponent extends EventHandler {
* @param listener
*/
public void setEnergyEventListener(EnergyEventListener listener);
default double calculateEnergyConsumation(EnergyState state, long timeInState) {
return state.getEnergyConsumption() * ( (double) timeInState / (double) Time.SECOND);
}
}
......@@ -28,7 +28,7 @@ import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.energy.EnergyConfiguration;
import de.tud.kom.p2psim.api.energy.EnergyModel;
import de.tud.kom.p2psim.api.scenario.ConfigurationException;
import de.tud.kom.p2psim.impl.energy.models.ModularEnergyModel;
import de.tud.kom.p2psim.impl.energy.models.ComponentBasedEnergyModel;
import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
......@@ -61,6 +61,10 @@ public class EnergyModelFactory implements HostComponentFactory {
*/
private boolean configurationsUsed = false;
private boolean useRandomBatteryStartConfiguration = false;
private double minimumStartEnergyLevel = 0.3;
private Battery batteryModel = new SimpleBattery(186480000, 186480000);
/**
......@@ -80,16 +84,24 @@ public class EnergyModelFactory implements HostComponentFactory {
+ "Add at least one child element <Component class=\"...\" /> pointing to an EnergyConfiguration.");
}
configurationsUsed = true;
Battery bat;
if(useRandomBatteryStartConfiguration)
{
// clone the battery from the provided model
// FIXME Different Capacities for different nodes.
double percentageOfFullBattery = (1 - random.nextDouble());
if(percentageOfFullBattery < minimumStartEnergyLevel)
percentageOfFullBattery = minimumStartEnergyLevel;
double initialEnergy = batteryModel.getMaximumEnergyLevel() * percentageOfFullBattery;
bat = new SimpleBattery(batteryModel.getMaximumEnergyLevel(), initialEnergy);
}
else {
bat = batteryModel.clone();
}
// clone the battery from the provided model
// FIXME Different Capacities for different nodes.
double percentageOfFullBattery = (1 - random.nextDouble());
if(percentageOfFullBattery < 0.3)
percentageOfFullBattery = 0.3;
double initialEnergy = 186480000 * percentageOfFullBattery;
Battery bat = new SimpleBattery(186480000, initialEnergy);
// Battery bat = batteryModel.clone();
EnergyModel em = new ModularEnergyModel(host, bat);
EnergyModel em = new ComponentBasedEnergyModel(host, bat);
for (EnergyConfiguration config : energyConfigurations) {
em.registerComponent(config.getConfiguredEnergyComponent(host));
......@@ -129,5 +141,19 @@ public class EnergyModelFactory implements HostComponentFactory {
energyConfigurations.add(energyConfig);
}
private void setMinimumStartEnergyLevel(double level) {
if(level > 1.0) {
this.minimumStartEnergyLevel = 1.0;
}
else if(level < 0.0) {
this.minimumStartEnergyLevel = 0.0;
}
else {
this.minimumStartEnergyLevel = level;
}
}
private void setUseRandomBatteryStartConfiguration(boolean randomStart) {
this.useRandomBatteryStartConfiguration = randomStart;
}
}
......@@ -20,12 +20,15 @@
package de.tud.kom.p2psim.impl.energy.components;
import de.tud.kom.p2psim.api.analyzer.EnergyAnalyzer;
import de.tud.kom.p2psim.api.energy.ComponentType;
import de.tud.kom.p2psim.api.energy.EnergyComponent;
import de.tud.kom.p2psim.api.energy.EnergyEventListener;
import de.tud.kom.p2psim.api.energy.EnergyState;
import de.tud.kom.p2psim.impl.energy.DefaultEnergyState;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.core.MonitorComponent.AnalyzerNotAvailableException;
public class ActuatorEnergyComponent implements EnergyComponent {
......@@ -54,11 +57,10 @@ public class ActuatorEnergyComponent implements EnergyComponent {
public void doStateChange(EnergyState newState) {
// FIXME TODO
long timeSpentInState = Time.getCurrentTime() - lastStateChange;
energyModel.switchedState(this, currentState, newState,
timeSpentInState);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(currentState, timeSpentInState));
currentState = newState;
lastStateChange = Time.getCurrentTime();
......@@ -107,4 +109,6 @@ public class ActuatorEnergyComponent implements EnergyComponent {
public EnergyState getCurrentState() {
return currentState;
}
}
......@@ -67,8 +67,10 @@ public class OneStateEnergyComponent implements EnergyComponent {
@Override
public void eventOccurred(Object content, int type) {
if (isOn()) {
energyModel.switchedState(this, state, state, Time.SECOND);
if (energyModel.turnOn(this)) {
double consumedEnergy = state.getEnergyConsumption() * Time.SECOND;
energyModel.componentConsumedEnergy(this, consumedEnergy);
if (energyModel.componentCanBeActivated(this)) {
Event.scheduleWithDelay(Time.SECOND, this, null, 0);
} else {
this.turnOff();
......
......@@ -30,6 +30,7 @@ import de.tud.kom.p2psim.impl.energy.DefaultEnergyState;
import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tudarmstadt.maki.simonstrator.api.Message;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
public class SmartphoneCellularCommunicationEnergyComponent implements
......@@ -102,7 +103,7 @@ EnergyCommunicationComponent {
@Override
public boolean isOn() {
if (energyModel.turnOn(this)) {
if (energyModel.componentCanBeActivated(this)) {
doFakeStateChange();
return true;
}
......@@ -139,8 +140,8 @@ EnergyCommunicationComponent {
+ " after spending "
+ (timeInTailState / (double) Simulator.SECOND_UNIT)
+ " sec there.");
energyModel
.switchedState(this, currentState, null, timeInTailState);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(currentState, timeInTailState));
tailCounter++;
currentState = IDLE;
lastStateChange = Simulator.getCurrentTime();
......@@ -161,7 +162,7 @@ EnergyCommunicationComponent {
* message. However, the energy for the ramp state before sending is
* consumed.
*/
energyModel.switchedState(this, RAMP_TX, null, RAMP_TX_DURATION);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(RAMP_TX, RAMP_TX_DURATION));
} else {
assert currentState.equals(TAIL_RX) || currentState.equals(TAIL_TX);
......@@ -176,15 +177,16 @@ EnergyCommunicationComponent {
+ " after spending "
+ (timeInTailState / (double) Simulator.SECOND_UNIT)
+ " sec there before starting a transmission.");
energyModel
.switchedState(this, currentState, null, timeInTailState);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(currentState, timeInTailState));
tailCounter++;
}
/*
* Consume the energy for the transmission of data.
*/
energyModel.switchedState(this, TX, null, duration);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(TX, duration));
Monitor.log(SmartphoneCellularCommunicationEnergyComponent.class, Level.DEBUG, Simulator.getFormattedTime(Simulator.getCurrentTime())
+ " "
+ ((EnergyModel) energyModel).getHost().getHostId()
......@@ -214,7 +216,8 @@ EnergyCommunicationComponent {
* message. However, the energy for the ramp state before receiving
* is consumed.
*/
energyModel.switchedState(this, RAMP_RX, null, RAMP_RX_DURATION);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(RAMP_RX, RAMP_RX_DURATION));
} else {
assert currentState.equals(TAIL_RX) || currentState.equals(TAIL_TX);
......@@ -229,14 +232,16 @@ EnergyCommunicationComponent {
+ " after spending "
+ (timeInTailState / (double) Simulator.SECOND_UNIT)
+ " sec there before receiving a message.");
energyModel
.switchedState(this, currentState, null, timeInTailState);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(currentState, timeInTailState));
tailCounter++;
}
/*
* Consume the energy for the receiption of data.
*/
energyModel.switchedState(this, RX, null, duration);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(RX, duration));
Monitor.log(SmartphoneCellularCommunicationEnergyComponent.class, Level.DEBUG,Simulator.getCurrentTime()
+ " "
+ ((EnergyModel) energyModel).getHost().getHostId()
......@@ -266,8 +271,9 @@ EnergyCommunicationComponent {
+ " uJ in State " + currentState.getName() + " after spending "
+ (timeSpentInState / (double) Simulator.SECOND_UNIT)
+ " sec there.");
energyModel.switchedState(this, currentState, newState,
timeSpentInState);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(currentState, timeSpentInState));
currentState = newState;
if(!currentState.equals(TAIL_RX) && !currentState.equals(TAIL_TX))
lastStateChange = Simulator.getCurrentTime();
......
......@@ -97,7 +97,7 @@ public class SmartphoneCommunicationEnergyComponent implements
@Override
public boolean turnOn() {
if (energyModel.turnOn(this)) {
if (energyModel.componentCanBeActivated(this)) {
if (!currentState.equals(IDLE)) {
doStateChange(IDLE);
}
......@@ -139,8 +139,9 @@ public class SmartphoneCommunicationEnergyComponent implements
+ (SEND.getEnergyConsumption() * (duration/ (double) Simulator.SECOND_UNIT))
+ " uJ in State " + SEND.getName() + " after spending "
+ (duration / (double) Simulator.SECOND_UNIT) + " sec there.");
energyModel.switchedState(this, SEND, null,
duration);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(SEND, duration));
}
@Override
......@@ -159,8 +160,9 @@ public class SmartphoneCommunicationEnergyComponent implements
+ " after spending "
+ (duration / (double) Simulator.SECOND_UNIT)
+ " sec there.");
energyModel.switchedState(this, RECEIVE, null,
duration);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(RECEIVE, duration));
}
public void doFakeStateChange() {
......@@ -181,8 +183,8 @@ public class SmartphoneCommunicationEnergyComponent implements
+ " after spending "
+ (timeSpentInState / (double) Simulator.SECOND_UNIT)
+ " sec there.");
energyModel.switchedState(this, currentState, newState,
timeSpentInState);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(currentState, timeSpentInState));
currentState = newState;
lastStateChange = Simulator.getCurrentTime();
}
......
......@@ -95,7 +95,7 @@ public class StateEnergyCommunicationComponent implements
@Override
public boolean turnOn() {
if (energyModel.turnOn(this)) {
if (energyModel.componentCanBeActivated(this)) {
if (!currentState.equals(IDLE)) {
doStateChange(IDLE);
}
......@@ -112,8 +112,7 @@ public class StateEnergyCommunicationComponent implements
private void doStateChange(EnergyState newState) {
long timeSpentInState = Time.getCurrentTime() - lastStateChange;
timeSpentInState = Math.max(0, timeSpentInState);
energyModel.switchedState(this, currentState, newState,
timeSpentInState);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(currentState, timeSpentInState));
currentState = newState;
lastStateChange = Time.getCurrentTime();
}
......@@ -135,7 +134,7 @@ public class StateEnergyCommunicationComponent implements
doStateChange(RECV);
// we do this change manually, because we can save the event for the end
// receive!
energyModel.switchedState(this, RECV, IDLE, duration);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(RECV, duration));
currentState = IDLE;
lastStateChange = Time.getCurrentTime() + duration;
}
......@@ -147,7 +146,7 @@ public class StateEnergyCommunicationComponent implements
doStateChange(SEND);
// we do this change manually, because we can save the event for the end
// receive!
energyModel.switchedState(this, SEND, IDLE, duration);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(SEND, duration));
currentState = IDLE;
lastStateChange = Time.getCurrentTime() + duration;
}
......
......@@ -26,14 +26,13 @@ import de.tud.kom.p2psim.api.energy.EnergyEventListener;
import de.tud.kom.p2psim.api.energy.EnergyState;
import de.tud.kom.p2psim.api.linklayer.mac.PhyType;
import de.tud.kom.p2psim.impl.energy.DefaultEnergyState;
import de.tud.kom.p2psim.impl.energy.models.ModularEnergyModel;
import de.tudarmstadt.maki.simonstrator.api.Message;
import de.tudarmstadt.maki.simonstrator.api.Time;
/**
* This is the implementation of a communication component that does not care
* about a state - it just consumes energy as soon as something is being sent.
* In the context of the {@link ModularEnergyModel} we mimic a state-aware
* In the context of the {@link StateSwitchingEnergyModel} we mimic a state-aware
* behavior. Please take a look at the comment in the Constructor if your
* analyzers seem to return odd results with this component...
*
......@@ -120,7 +119,7 @@ public class StatelessCommunicationComponent implements
@Override
public boolean turnOn() {
if (energyModel.turnOn(this)) {
if (energyModel.componentCanBeActivated(this)) {
if (!currentState.equals(IDLE)) {
doStateChange(IDLE);
}
......@@ -136,8 +135,7 @@ public class StatelessCommunicationComponent implements
private void doStateChange(EnergyState newState) {
long timeSpentInState = Time.getCurrentTime() - lastStateChange;
energyModel.switchedState(this, currentState, newState,
timeSpentInState);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(currentState, timeSpentInState));
currentState = newState;
lastStateChange = Time.getCurrentTime();
}
......@@ -167,7 +165,7 @@ public class StatelessCommunicationComponent implements
doStateChange(ON);
// switch back to IDLE with fake timeHP
energyModel.switchedState(this, ON, IDLE, timeHP);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(ON, timeHP));
currentState = IDLE;
lastStateChange = Time.getCurrentTime();
}
......
......@@ -24,14 +24,17 @@ import java.util.List;
import java.util.Set;
import java.util.Vector;
import de.tud.kom.p2psim.api.analyzer.EnergyAnalyzer;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.energy.ComponentType;
import de.tud.kom.p2psim.api.energy.EnergyComponent;
import de.tud.kom.p2psim.api.energy.EnergyInfo;
import de.tud.kom.p2psim.api.energy.EnergyModel;
import de.tud.kom.p2psim.impl.energy.Battery;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.common.graph.INodeID;
import de.tudarmstadt.maki.simonstrator.api.component.ComponentNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.core.MonitorComponent.AnalyzerNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.battery.BatterySensor;
import de.tudarmstadt.maki.simonstrator.api.component.sis.SiSComponent;
import de.tudarmstadt.maki.simonstrator.api.component.sis.SiSDataCallback;
......@@ -40,6 +43,13 @@ import de.tudarmstadt.maki.simonstrator.api.component.sis.SiSInformationProvider
import de.tudarmstadt.maki.simonstrator.api.component.sis.exception.InformationNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.sis.type.SiSTypes;
/**
* The default functionalities for energy models, composed of different
* {@link EnergyComponent}s and configured via the factory.
*
* @author Julian Zobel
* @version 1.0, 07.09.2018
*/
public abstract class AbstractEnergyModel implements EnergyModel, BatterySensor, EnergyInfo {
protected SimHost host;
......@@ -183,5 +193,27 @@ public abstract class AbstractEnergyModel implements EnergyModel, BatterySensor,
"You are not supposed to reset this component.");
}
protected void monitorEnergyConsumation(EnergyComponent component, double consumedEnergy) {
/*
* TODO Refactor the Energy-Analyzer to support EnergyComponents
* directly, rather than strings.
*/
try {
Monitor.get(EnergyAnalyzer.class).consumeEnergy(getHost(),
consumedEnergy, component);
} catch (AnalyzerNotAvailableException e1) {
//
}
}
protected void monitorEmptyBattery() {
/*
* Battery is now empty.
*/
try {
Monitor.get(EnergyAnalyzer.class).batteryIsEmpty(getHost());
} catch (AnalyzerNotAvailableException e) {
//
}
}
}
......@@ -31,7 +31,7 @@ import de.tud.kom.p2psim.api.analyzer.MessageAnalyzer.Reason;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.energy.ComponentType;
import de.tud.kom.p2psim.api.energy.EnergyCommunicationComponent;
import de.tud.kom.p2psim.api.energy.EnergyEventListener;
import de.tud.kom.p2psim.api.energy.OldEnergyEventListener;
import de.tud.kom.p2psim.api.linklayer.LinkLayerMessage;
import de.tud.kom.p2psim.api.linklayer.LinkMessageEvent;
import de.tud.kom.p2psim.api.linklayer.LinkMessageListener;
......@@ -985,7 +985,7 @@ public abstract class AbstractMacLayer implements MacLayer {
}
@Override
public void setEnergyEventListener(EnergyEventListener listener) {
public void setEnergyEventListener(OldEnergyEventListener listener) {
// not interested
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment