package classes; import com.google.gson.annotations.Expose; import java.awt.*; import java.util.ArrayList; //import javafx.util.converter.PercentageStringConverter; /** * 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 AbstractCpsObject { /* * the constants showing a HolonObject's current state * (whether it needs no energy, whether it is not supplied, fully supplied, * a producer, partially supplied or over-supplied) */ public final static int NO_ENERGY = 0; public final static int NOT_SUPPLIED = 1; public final static int SUPPLIED = 2; public final static int PRODUCER = 3; public final static int PARTIALLY_SUPPLIED = 4; public final static int OVER_SUPPLIED = 5; private static final int DEFAULT_GRAPH_LENGTH = 100;//TODO /* * Color of the actual state (red = no supplied, yellow = partially supplied * and green = supplied) */ @Expose private Color stateColor; /* Array of all consumers */ private ArrayList elements; /* Total of consumption */ @Expose private float currentEnergy; /* Array for tracking Production */ private float[] trackingProd; /* Array for tracking Consumption */ private float[] trackingCons; /* Total Flexibility */ private float totalFlex; @Expose private int state = 0; /** * Energy level that was supplied by other HolonObjects in the current Calculation */ private float currentSupply; /** * Percentage of supplied energy of the energy level needed to supply all elements */ private float suppliedPercentage; /** * 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); setElements(new ArrayList<>()); setState(); setTrackingProd(new float[100]); setTrackingCons(new float[100]); } /** * Contructor of a copy of an Object. * * @param obj object to be copied */ public HolonObject(AbstractCpsObject obj) { super(obj); setElements(copyElements(((HolonObject) obj).getElements())); setState(); setTrackingProd(new float[100]); setTrackingCons(new float[100]); } /** * sets the State, whether object is a producer, zero Energy, supplied, * partially or over-supplied */ public void setState() { if (getCurrentEnergy() > 0) { setState(PRODUCER); stateColor = Color.lightGray; } else { if (getCurrentEnergy() == 0) { setState(NO_ENERGY); stateColor = Color.WHITE; } else { if (checkIfPartiallySupplied(0)) { stateColor = Color.yellow; } else { stateColor = new Color(230, 120, 100); } } } } /** * Getter for all Elements in the HolonObject. * * @return the elements ArrayList */ public ArrayList getElements() { return elements; } /** * Set a new ArrayList with HolonElements into the HolonObject. * * @param elements the elements to set */ public void setElements(ArrayList elements) { this.elements = elements; } /** * adds an Element to the Object. * * @param element the Element to add */ public void addElement(HolonElement element) { elements.add(element); } /** * Doesn't take into account which timestep is watched, calculates the max * values. * * @return the currentEnergy */ public float getCurrentEnergy() { float temp = 0; for (HolonElement e : getElements()) { if (e.isActive()) { temp += e.getOverallEnergy(); } } currentEnergy = temp; return currentEnergy; } /** * Getter for the current energy at a given timestep. * * @param x timestep * @return corresponding energy */ public float getCurrentEnergyAtTimeStep(int x) { float temp = 0; float cons = 0; float prod = currentSupply; float t; for (HolonElement e : getElements()) { if (e.isActive()) { t = e.getOverallEnergyAtTimeStep(x); if(t<0){ cons+=t; }else{ prod+=t; } temp += t; } } currentEnergy = temp; suppliedPercentage = prod / -cons; return currentEnergy; } /** * Getter for the current energy at a given timestep. * * @param x timestep * @return corresponding energy */ public float getCurrentEnergyAtTimeStepWithoutFlexiblesAndResetFlexibles(int x) { float temp = 0; for (HolonElement e : getElements()) { if (e.isActive() && !e.isFlexible()) { temp += e.getOverallEnergyAtTimeStep(x); } else if (e.isFlexible()) { e.setEnergyPerElement(0); } } currentEnergy = temp; return currentEnergy; } /** * deletes Element at a given index. * * @param idx index */ public void deleteElement(int idx) { elements.remove(idx); } /** * String of all consumers in this HolonObject. * * @return all the names of this HolonObject separated by "," each object */ public String toStringElements() { String objString = "Empty"; for (HolonElement e : elements) { if (objString == "Empty") { objString = e.getEleName(); } else { objString = objString + ", " + e.getEleName(); } } return objString; } /** * Copy all Elements into a New Array. * * @param arr to copy * @return the copy of arr */ public ArrayList copyElements(ArrayList arr) { ArrayList newArr = new ArrayList<>(); for (HolonElement t : arr) { newArr.add(new HolonElement(t)); } return newArr; } /** * Get the state of the Object. * * @return state the State of the Element */ public int getState() { return this.state; } /** * Set the state of the Object. * * @param state boolean if the Object is fully supplied */ public void setState(int state) { this.state = state; switch (state) { case NO_ENERGY: stateColor = Color.WHITE; break; case NOT_SUPPLIED: stateColor = new Color(230, 120, 100); break; case SUPPLIED: stateColor = Color.GREEN; break; case PRODUCER: stateColor = Color.lightGray; break; case PARTIALLY_SUPPLIED: stateColor = Color.YELLOW; break; case OVER_SUPPLIED: // find different purple-tones at // http://www.rapidtables.com/web/color/purple-color.htm stateColor = new Color(138, 43, 226); break; } } /** * Search for the element with the name. * * @param name name of the object to be searched * @return the searched HolonElement */ public HolonElement searchElement(String name) { HolonElement ele = null; for (HolonElement e : getElements()) { if (e.getEleName().equals(name)) { ele = e; } } return ele; } /** * Search for the element with the id. * * @param id id of the element to be founded * @return the element */ public HolonElement searchElementById(int id) { HolonElement ele = null; for (HolonElement e : getElements()) { if (e.getId() == id) { ele = e; } } return ele; } /** * Check if Partially Supplied. * * @param x current Iteration * @return boolean is partially supplied */ public boolean checkIfPartiallySupplied(int x) { if (getElements().size() == 0) { return false; } float minConsum = 0; // Search for a activ element for (HolonElement e : getElements()) { if (e.isActive()) { float overallEnergy = e.getOverallEnergyAtTimeStep(x); if (overallEnergy < 0) { // Is a consumer minConsum = overallEnergy; } } } float prod = 0; float cons = 0; for (HolonElement e : getElements()) { if (e.isActive()) { float overallEnergy = e.getOverallEnergyAtTimeStep(x); if (overallEnergy > 0) { prod += overallEnergy; }else{ cons += overallEnergy; } if (minConsum < 0 && (overallEnergy > minConsum && overallEnergy < 0)) { minConsum = overallEnergy; } } } suppliedPercentage = -(prod + currentSupply)/cons; // System.out.println("minCons: " + minConsum + " prod: " + prod); if (minConsum < 0 && prod >= -minConsum) { return true; } else { return false; } /* float prod = getSelfMadeEnergy(x); float cons =-getMinEnergy(x); //cons = (cons != Float.NEGATIVE_INFINITY)? -cons : 0.f; suppliedPercentage = -(prod + currentSupply)/cons; return (prod >= cons );*/ } /**@param x TimeStep * @return */ public float getSelfMadeEnergy(int x) { return getElements().stream() .map(e ->(e.isActive() && e.getOverallEnergyAtTimeStep(x) > 0) ? e.getOverallEnergyAtTimeStep(x) : 0.0f) .reduce(0.0f, (a , b) -> a + b ); } /** * Calculates the minimumEnergy Needed to turn on atleast on device * of this HolonObject * @param x Timestep of the calculation * @return minEnergy, -inf if no Devices are consuming power */ public float getMinEnergy(int x) { if (getElements().size() == 0) { return Float.NEGATIVE_INFINITY; } float minConsum = Float.NEGATIVE_INFINITY; for (HolonElement e : getElements()) { if (e.isActive()) { float overallEnergy = e.getOverallEnergyAtTimeStep(x); if (minConsum < 0 && (overallEnergy > minConsum && overallEnergy < 0)) { minConsum = overallEnergy; } } } return minConsum; } /** * Get the Color. * * @return stateColor the Color */ public Color getColor() { return stateColor; } /** * Set the State Color. * * @param color the Color */ public void setColor(Color color) { stateColor = color; } /** * Get the Array Production */ public float[] getTrackingProd() { return this.trackingProd; } /** * Set the Array Production */ public void setTrackingProd(float[] arr) { this.trackingProd = arr; } /** * Get the Array Consumption */ public float[] getTrackingCons() { return this.trackingCons; } /** * Set the Array Consumption */ public void setTrackingCons(float[] arr) { this.trackingCons = arr; } /** * Get the Array Consumption */ public float getTotalFlex() { return totalFlex; } /** * Set the Array Consumption */ public void setTotalFlex(float totalFlex) { this.totalFlex = totalFlex; } /** * Update the totalFlex */ public void updateTotalFlex() { float tempFlex = 0; for (HolonElement e : getElements()) { if (e.isFlexible()) { tempFlex += e.getFlexibleEnergyAvailablePerElement() * e.getAmount(); } } this.totalFlex = tempFlex; } /** * calculates total flexible Production */ public float getFlexProd() { float tempFlex = 0; for (HolonElement e : getElements()) { if (e.getFlexibleEnergyAvailablePerElement() > 0) { tempFlex += e.getFlexibleEnergyAvailablePerElement() * e.getAmount(); } } return tempFlex; } /** * calculates total flexible Concumption */ public float getFlexCons() { float tempFlex = 0; for (HolonElement e : getElements()) { if (e.getFlexibleEnergyAvailablePerElement() < 0) { tempFlex += e.getFlexibleEnergyAvailablePerElement() * e.getAmount(); } } return tempFlex; } /** * If the user track any HolonObject the tracking information will be * updated. (If the HolonObject enters into the untracked state, the array * will be reseted) */ public void updateTrackingInfo() { float[] tempProd = new float[100]; float[] tempCons = new float[100]; for (int i = 0; i < 100; i++) { float valueProd = 0; float valueCons = 0; for (HolonElement e : getElements()) { if (e.isActive() && e.getSign() == '+') { valueProd = valueProd + e.getOverallEnergyAtTimeStep(i); } if (e.isActive() && e.getSign() == '-') { valueCons = valueCons + e.getOverallEnergyAtTimeStep(i); } } tempProd[i] = valueProd; tempCons[i] = valueCons; } this.trackingProd = tempProd; this.trackingCons = tempCons; } public String toString() { StringBuilder sb = new StringBuilder(); sb.append("[HolonObject: "); sb.append("id=").append(id) .append(", name=").append(name) .append(", state="); switch (state) { case NO_ENERGY: sb.append("NO_ENERGY"); break; case NOT_SUPPLIED: sb.append("NOT_SUPPLIED"); break; case SUPPLIED: sb.append("SUPPLIED"); break; case PRODUCER: sb.append("PRODUCER"); break; case PARTIALLY_SUPPLIED: sb.append("PARTIALLY_SUPPLIED"); break; case OVER_SUPPLIED: sb.append("OVER_SUPPLIED"); break; } sb.append(", elements=["); for (int i = 0; i < getElements().size(); i++) { HolonElement el = getElements().get(i); if (i != 0) { sb.append(", "); } sb.append(el.getEleName()); } sb.append("]]"); return sb.toString(); } /** * @return the {@link #currentSupply} */ public float getCurrentSupply() { return currentSupply; } /** * @param currentSupply the {@link #currentSupply} to set */ public void setCurrentSupply(float currentSupply) { this.currentSupply = currentSupply; } /** * @return {@link #suppliedPercentage} */ public float getSuppliedPercentage(){ return suppliedPercentage; } }