package classes.holonControlUnit; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import classes.Holon; import classes.holonControlUnit.OptimizationManager.OptimizationScheme; import classes.holonControlUnit.messages.Message; import classes.holonControlUnit.messages.StateMsg; import classes.holonControlUnit.messages.StateRequestMsg; import ui.controller.FlexManager; import ui.model.DecoratedCable.CableState; import ui.model.IntermediateCableWithState; /** * aggregates all states from sub holons and forwards the resulting own state to the state assembler * @author Jonas * */ public class StateEstimator { /* indicates the current state of the holon */ public enum StateIndicator { /* everything runs as expected, all parameters are inside their tresholds */ DESIRED, /* everything is still as expected except for minor deviations, parts may be endangered/dysfunctional */ ENDANGERED, /* stability/functionality of holon is not guaranteed */ DYSFUNCTIONAL } private HolonControlUnit hcu; private StateIndicator stateInd; private float powerUsage; private float netThroughput; private HashMap childStates; private ArrayList predictedPowerUsage; // private HashMap powerUsagesInsideHolarchy; public StateEstimator(HolonControlUnit hcu) { this.hcu = hcu; this.stateInd = StateIndicator.DESIRED; // this.powerUsagesInsideHolarchy = new HashMap(); this.childStates = new HashMap(); } public StateIndicator getStateIndicator() { return stateInd; } /** * Depth-first computation * aggregate childrens state first, then compute own state */ public void computeState(int timeStep) { //check if any edge is burned for(IntermediateCableWithState icws : this.hcu.getHolon().getMinimumModel().getEdgeList()) { if(icws.getState() == CableState.Burned || icws.getModel().isBurned()) { // System.out.println(icws.getModel()+" burned"); this.hcu.getHierarchyController().removeEdge(icws.getModel()); } } //request childrens state this.childStates.clear(); requestChildStates(timeStep); calculatePowerUsage(timeStep); calculateNetThroughput(timeStep); //compute forecast this.predictedPowerUsage = this.hcu.getForecaster().computeForecast(this.childStates, timeStep); boolean b = this.hcu.matchPowerRange(powerUsage, this.hcu.getStateAssembler().getDesiredPowerUsage(), this.predictedPowerUsage, this.hcu.getOptimizer().getCurrentPowerThreshold()); boolean c = this.hcu.getOptimizer().getOptimizationScheme() != OptimizationScheme.RECOVERY; if(c) { for(StateMsg state : this.childStates.values()) { if(state.getStateInd() != StateIndicator.DESIRED) { c = false; break; } } } if(b && c) { this.stateInd = StateIndicator.DESIRED; } else if (b){ this.stateInd = StateIndicator.ENDANGERED; } else { this.stateInd = StateIndicator.DYSFUNCTIONAL; } } private void calculatePowerUsage(int timeStep) { //aggregate sub holon state this.powerUsage = 0; for(String s : this.childStates.keySet()) { float p = this.childStates.get(s).getPowerUsage(); this.powerUsage += p; // this.powerUsagesInsideHolarchy.put(s, p); } //add state from holon elements Holon holon = this.hcu.getHolon(); if(holon.isPhysical) { float p = holon.getHolonObject().getEnergyAtTimeStepFlex(timeStep); this.powerUsage += p; // this.powerUsagesInsideHolarchy.put(this.hcu.getHolon().getUniqueID(), p); } } private void calculateNetThroughput(int timeStep) { this.netThroughput = this.hcu.getHolon().getAllHolonObjects().stream() .filter(object -> object.getEnergyAtTimeStepFlex(timeStep) > 0.0f) .map(object -> object.getEnergyAtTimeStepFlex(timeStep)) .reduce(0.0f, ((a,b) -> a + b)); } public void requestChildStates(int timeStep) { List children = List.copyOf(this.hcu.getHierarchyController().getSubHolons()); if(this.childStates.size() == children.size()) return; for(String child : children) { //send request to child if(!this.childStates.containsKey(child)) { this.hcu.getCommunicator().sendMsg(child, Message.Type.STATE_REQUEST, this.hcu.getCommunicator().getGson().toJson(new StateRequestMsg(timeStep))); } } //wait for sub holons to compute state and send it if(this.childStates.size() < children.size()) { //a subholon has disappeared, remove it from child holon for(String s : children) { if(!this.childStates.containsKey(s)) { this.hcu.getHierarchyController().splitSubHolon(s, timeStep); // System.err.println(this.hcu.getHolon().getUniqueID()+" holon "+s+" has disappeared " // +this.hcu.getHierarchyController().canMerge(s, 0f)); } } } } public void receiveState(String sender, StateMsg stateMsg) { if(this.childStates == null || stateMsg == null) return; this.childStates.put(sender, stateMsg); } public float getPowerUsage() { return this.powerUsage; } /** public HashMap getPowerUsagesInsideHolarchy() { return this.powerUsagesInsideHolarchy; } */ public ArrayList getPredictedPowerUsage() { return this.predictedPowerUsage; } public HashMap getChildStates() { return this.childStates; } public float getNetThroughput() { return netThroughput; } }