/*
* 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.models;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import org.joda.time.chrono.JulianChronology;
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.EnergyEventListener;
import de.tud.kom.p2psim.api.energy.EnergyInfo;
import de.tud.kom.p2psim.api.energy.EnergyModel;
import de.tud.kom.p2psim.api.energy.EnergyState;
import de.tud.kom.p2psim.api.network.SimNetInterface;
import de.tud.kom.p2psim.impl.energy.Battery;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Time;
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;
import de.tudarmstadt.maki.simonstrator.api.component.sis.SiSInfoProperties;
import de.tudarmstadt.maki.simonstrator.api.component.sis.SiSInformationProvider.SiSProviderHandle;
import de.tudarmstadt.maki.simonstrator.api.component.sis.exception.InformationNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.sis.type.SiSTypes;
/**
* The default energy model that is composed of different
* {@link EnergyComponent}s and configured via the factory. In contrast to the
* old EnergyModels these are Host components, ie. there is one instance
* for each host.
*
* @author Bjoern Richerzhagen, Julian Zobel
* @version 2.0, 07.09.2018
*/
public class ModularEnergyModel extends AbstractEnergyModel implements EnergyEventListener {
public ModularEnergyModel(SimHost host, Battery bat) {
super(host, bat);
}
@Override
public void initialize() {
//
try {
SiSComponent sis = host.getComponent(SiSComponent.class);
sis.provide().nodeState(SiSTypes.ENERGY_BATTERY_LEVEL,
new SiSDataCallback() {
Set localID = INodeID.getSingleIDSet(getHost()
.getId());
@Override
public Double getValue(INodeID nodeID,
SiSProviderHandle providerHandle)
throws InformationNotAvailableException {
if (nodeID.equals(getHost().getId())) {
return getCurrentPercentage();
} else {
throw new InformationNotAvailableException();
}
}
@Override
public Set getObservedNodes() {
return localID;
}
@Override
public SiSInfoProperties getInfoProperties() {
return new SiSInfoProperties();
}
});
sis.provide().nodeState(SiSTypes.ENERGY_BATTERY_CAPACITY,
new SiSDataCallback() {
Set localID = INodeID.getSingleIDSet(getHost()
.getId());
@Override
public Double getValue(INodeID nodeID,
SiSProviderHandle providerHandle)
throws InformationNotAvailableException {
if (nodeID.equals(getHost().getId())) {
return getCurrentEnergyLevel();
} else {
throw new InformationNotAvailableException();
}
}
@Override
public Set getObservedNodes() {
return localID;
}
@Override
public SiSInfoProperties getInfoProperties() {
return new SiSInfoProperties();
}
});
} catch (ComponentNotAvailableException e) {
// OK
}
}
@Override
public void registerComponent(EnergyComponent comp) {
comp.setEnergyEventListener(this);
energyComponents.add(comp);
}
@Override
public void switchedState(EnergyComponent component, EnergyState oldState,
EnergyState newState, long timeSpentInOldState) {
if (!bat.isEmpty()) {
double consumedEnergy = oldState.getEnergyConsumption()
* (timeSpentInOldState / (double) Time.SECOND);
bat.consumeEnergy(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) {
//
}
// log.debug(component.toString() + " consumed " + consumedEnergy
// + " uJ in State " + oldState.getName() + " after spending "
// + (timeSpentInOldState/Simulator.SECOND_UNIT) + " sec there.");
if (bat.isEmpty()) {
/*
* Battery is now empty. Go offline.
*/
try {
Monitor.get(EnergyAnalyzer.class).batteryIsEmpty(getHost());
} catch (AnalyzerNotAvailableException e) {
//
}
for (SimNetInterface net : getHost().getNetworkComponent()
.getSimNetworkInterfaces()) {
net.goOffline();
}
}
}
}
@Override
public boolean turnOn(EnergyComponent component) {
return !bat.isEmpty();
}
@Override
public void reset() {
bat.reset();
}
}