/* * Copyright (c) 2005-2010 KOM – Multimedia Communications Lab * * This file is part of PeerfactSim.KOM. * * PeerfactSim.KOM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * PeerfactSim.KOM is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with PeerfactSim.KOM. If not, see . * */ package de.tud.kom.p2psim.impl.energy.components; 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.EnergyState; import de.tud.kom.p2psim.api.linklayer.mac.PhyType; import de.tud.kom.p2psim.impl.energy.DefaultEnergyState; import de.tudarmstadt.maki.simonstrator.api.Message; import de.tudarmstadt.maki.simonstrator.api.Time; /** * This is the implementation of a communication component that does care about * a state - it just consumes energy as soon as something is being sent or * received. * * * @author Christoph Muenker * @version 1.0, 07.02.2013 */ public class StateEnergyCommunicationComponent implements EnergyCommunicationComponent { private PhyType phy; private EnergyEventListener energyModel; /** * States supported by this component */ private final EnergyState SEND, IDLE, RECV, OFF, SLEEP; private EnergyState currentState; private long lastStateChange; /* * Parameters from SWB-B23 Datasheet - Broadcom BCM4329 WLAN+BT Solution */ public static double volt = 3.3; // in volt public static double sendAmp = 0.2525; // in ampere public static double recvAmp = 0.07783; // in ampere public static double idleAmp = 0.0004909; // in ampere public static double sleepAmp = 0.000125; // in ampere /** * Create a stateless Component * * @param phy */ public StateEnergyCommunicationComponent(PhyType phy) { this.phy = phy; IDLE = new DefaultEnergyState("IDLE", (idleAmp * volt) * 1000000); SEND = new DefaultEnergyState("SEND", (sendAmp * volt) * 1000000); RECV = new DefaultEnergyState("RECV", (recvAmp * volt) * 1000000); OFF = new DefaultEnergyState("OFF", 0); SLEEP = new DefaultEnergyState("SLEEP", (sleepAmp * volt) * 1000000); this.currentState = IDLE; this.lastStateChange = Time.getCurrentTime(); } @Override public void turnOff() { if (!currentState.equals(OFF)) { doStateChange(OFF); } } @Override public boolean turnOn() { if (energyModel.turnOn(this)) { if (!currentState.equals(IDLE)) { doStateChange(IDLE); } return true; } return false; } @Override public boolean isOn() { return !currentState.equals(OFF); } private void doStateChange(EnergyState newState) { long timeSpentInState = Time.getCurrentTime() - lastStateChange; timeSpentInState = Math.max(0, timeSpentInState); energyModel.switchedState(this, currentState, newState, timeSpentInState); currentState = newState; lastStateChange = Time.getCurrentTime(); } /** * Just to ensure that the energy calculation is correct, once you rely on * the energy level in an analyzer you should call this method prior to * querying the battery. */ public void doFakeStateChange() { doStateChange(currentState); } @Override public void receive(long duration, Message msg, boolean isBroadcast, boolean isIntendedReceiver) { assert !currentState.equals(OFF); doStateChange(RECV); // we do this change manually, because we can save the event for the end // receive! energyModel.switchedState(this, RECV, IDLE, duration); currentState = IDLE; lastStateChange = Time.getCurrentTime() + duration; } @Override public void send(long duration, Message msg, boolean isBroadcast) { assert !currentState.equals(OFF); doStateChange(SEND); // we do this change manually, because we can save the event for the end // receive! energyModel.switchedState(this, SEND, IDLE, duration); currentState = IDLE; lastStateChange = Time.getCurrentTime() + duration; } @Override public ComponentType getType() { return ComponentType.COMMUNICATION; } @Override public PhyType getPhyType() { return phy; } @Override public void setEnergyEventListener(EnergyEventListener listener) { energyModel = listener; } @Override public void eventOccurred(Object content, int type) { // will not happen! } @Override public String toString() { return phy.toString(); } }