package holeg.model; import holeg.serialize.PostDeserialize; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; /** * The class HolonObject represents any Object on the system which capability of * injecting or consuming energy on the network, for instance a house or a power * plant. * * @author Gruppe14 */ public class HolonObject extends AbstractCanvasObject implements PostDeserialize { /* Array of all consumers */ private final Set elements = new HashSet<>(); //Calculated values private transient HolonObjectState state; private transient float actualEnergy; private transient float energyFromHolon; private transient float energyToHolon; private transient float minimumConsumingElementEnergy; private transient float energyNeededFromHolon; private transient float energyFromConsumingElements; private transient float energySelfSupplied; /** * Constructor Set by default the name of the object equals to the category * name, until the user changes it. * * @param objName name of the Object */ public HolonObject(String objName) { super(objName); } /** * Contructor of a copy of an Object. * * @param obj object to be copied */ public HolonObject(HolonObject obj) { super(obj); for (HolonElement ele : obj.elements) { this.add(new HolonElement(ele)); } } @Override public AbstractCanvasObject copy(){ return new HolonObject(this); } /** * Getter for all Elements in the HolonObject. * * @return the elements ArrayList */ public Stream elementsStream() { return elements.stream(); } public void clearElements() { elements.clear(); } /** * adds an Element to the Object. * * @param element the Element to add */ public void add(HolonElement element) { elements.add(element); element.parentObject = this; } public void add(Collection elements) { for (HolonElement hE : elements) { hE.parentObject = this; } this.elements.addAll(elements); } /** * remove an Element to the Object. * * @param element the Element to add */ public void remove(HolonElement element) { elements.remove(element); element.parentObject = null; } /** * This Method returns the smallest consuming HolonElement that is ACTIVE. If * the HolonObject has no Consumer its return null. * * @return The smallest consuming HolonElement or null. */ public Optional getMinimumConsumingElement() { return elements.stream().filter(element -> element.getActualEnergy() < 0).max((lhs, rhs) -> Float.compare(lhs.getActualEnergy(), rhs.getActualEnergy())); } /** * This Method returns the smallest consuming HolonElement'Energy that is * ACTIVE. If the HolonObject has no Consumer its return 0. * * @return The smallest consuming HolonElement or 0. */ public float getMinimumConsumingElementEnergy() { return minimumConsumingElementEnergy; } /** * This Method returns the biggest consuming HolonElement'Energy that is ACTIVE. * If the HolonObject has no Consumer its return 0. * * @return The biggest consuming HolonElement or 0. */ public float getMaximumConsumingElementEnergy() { return elements.stream().filter(element -> element.getActualEnergy() < 0).map(element -> -element.getActualEnergy()).max(Float::compare).orElse(0.0f); } public float getMaximumProductionPossible() { return elements.stream().map(HolonElement::getEnergy).filter(energy -> energy > 0).reduce(0.0f, Float::sum); } public float getMaximumConsumptionPossible() { return elements.stream().filter(element -> element.getEnergy() < 0).map(element -> -element.getEnergy()).reduce(0.0f, Float::sum); } /** * This Method returns the Energy of all HolonElements from the HolonObject that * are consuming. Its sums all Energies from the HolonElements of the * HolonObject that are ACTIVE and are Consumer. If the HolonObject have no * HolonElement its return 0; * * @return The Energy of the consuming HolonElements. */ public float getEnergyNeededFromConsumingElements() { return energyFromConsumingElements; } /** * This Method calculate the amount of HolonElements that are consuming Energy * and are ACTIVE. * * @return The amount of HolonElements that are consuming Energy. */ public int countConsumingElements() { return (int) elements.stream().filter(element -> element.getActualEnergy() < 0).count(); } /** * This Method calculate the amount of HolonElements that are producing Energy * and are ACTIVE. * * @return The amount of HolonElements that are producing Energy. */ public int countProducingElements() { return (int) elements.stream().filter(element -> element.getActualEnergy() > 0).count(); } public int getNumberOfActiveElements() { return (int) elements.stream().filter(ele -> ele.active).count(); } public int getNumberOfInActiveElements() { return (int) elements.stream().filter(ele -> !ele.active).count(); } public int getNumberOfElements() { return elements.size(); } /** * This Method returns the Energy of a HolonObject. Its sums all Energies from * the HolonElements of the HolonObject that are ACTIVE. If the HolonObject have * no HolonElement its return 0; Is the returned Energy negative then the * HolonObject need Energy because its consuming HolonElements need more Energy * then the producing HolonElements. Is the returned Energy positive its * reversed. * * @param timeStep is the TimeStep to compare the HolonElements. */ public void calculateEnergy(int timeStep) { elements.forEach(ele -> ele.calculateState(timeStep)); actualEnergy = elements.stream().map(HolonElement::getActualEnergy).reduce(0f, Float::sum); minimumConsumingElementEnergy = elements.stream().filter(element -> element.getActualEnergy() < 0).map(element -> -element.getActualEnergy()).min(Float::compare).orElse(0.0f); energyNeededFromHolon = (actualEnergy >= 0) ? 0 : -actualEnergy; energyFromConsumingElements = elements.stream().filter(element -> element.getActualEnergy() < 0).map(element -> -element.getActualEnergy()).reduce(0.0f, Float::sum); energySelfSupplied = elements.stream().map(HolonElement::getActualEnergy).filter(energy -> energy > 0).reduce(0.0f, Float::sum); energyToHolon = energyFromHolon = 0; } public float getActualEnergy() { return actualEnergy; } public HolonObjectState getState() { return state; } void setState(HolonObjectState state) { this.state = state; } public float getEnergyFromHolon() { return energyFromHolon; } void setEnergyFromHolon(float energyFromHolon) { this.energyFromHolon = energyFromHolon; } public float getEnergyNeededFromHolon() { return energyNeededFromHolon; } public float getEnergySelfSupplied() { return energySelfSupplied; } public float getCurrentEnergy() { return energyFromHolon - energyNeededFromHolon; } public float getSupplyBarPercentage() { return (energyFromConsumingElements > 0.001) ? (energyFromHolon + energySelfSupplied) / energyFromConsumingElements : 1.0f; } public String toString() { return "[HolonObject: " + "id=" + getId() + ", name=" + name + ", state=" + state + ", pos=" + position+ ", elements=[" + elementsStream().map(HolonElement::getName).collect(Collectors.joining(", ")) + "]]"; } public float getEnergyToHolon() { return energyToHolon; } void setEnergyToHolon(float energyToHolon) { this.energyToHolon = energyToHolon; } public void calculateState() { if(actualEnergy > 0){ state = HolonObjectState.PRODUCER; }else if(elements.isEmpty()){ state = HolonObjectState.NO_ENERGY; }else if(energySelfSupplied + energyFromHolon > energyFromConsumingElements) { state = (HolonObjectState.OVER_SUPPLIED); }else if(energySelfSupplied + energyFromHolon == energyFromConsumingElements) { state = (HolonObjectState.SUPPLIED); }else if(energySelfSupplied + energyFromHolon >= minimumConsumingElementEnergy) { state = (HolonObjectState.PARTIALLY_SUPPLIED); }else { state = (HolonObjectState.NOT_SUPPLIED); } } @Override public void postDeserialize() { elements.forEach(ele -> ele.parentObject = this); } public enum HolonObjectState { NO_ENERGY, NOT_SUPPLIED, SUPPLIED, PRODUCER, PARTIALLY_SUPPLIED, OVER_SUPPLIED } }