package blackstart; import java.awt.*; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import javax.swing.*; import api.AddOn; import classes.*; import ui.controller.Control; import ui.controller.StorageProductionController; public class controlAlgorithm implements AddOn { private boolean cancel = false; // Gui Part: private Control control; private JTextArea textArea; private JPanel content = new JPanel(); // ProgressBar private JProgressBar progressBar = new JProgressBar(); private long startTime; private Thread runThread; // Blackstart Resistance in Watt private HolonObject powerplant; private TextField blackstartEnergyrequierementTextfield; private TextField blackstartSuccessTimeTextfield; private TextField powerplantMaxOutputTextfield; private TextField blackstartStartTimeTextfield; private TextField simulationDurationTextfield; private TextField storageStartCharge; private TextField waitBetweenIterations; private int blackstartSuccessTime; private int blackstartStartTime; private int blackstartRunningCounter; private float powerplantMaxOutput; private List renewableProducers; private List consumers; private StorageProductionController SPC; public static void main(String[] args) { JFrame newFrame = new JFrame("exampleWindow"); controlAlgorithm instance = new controlAlgorithm(); newFrame.setContentPane(instance.getPanel()); newFrame.pack(); newFrame.setVisible(true); newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public controlAlgorithm() { content.setLayout(new BorderLayout()); textArea = new JTextArea(); textArea.setEditable(false); JScrollPane scrollPane = new JScrollPane(textArea); JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, createOptionPanel(), scrollPane); splitPane.setResizeWeight(0.0); content.add(splitPane, BorderLayout.CENTER); content.setPreferredSize(new Dimension(800, 800)); } public JPanel createOptionPanel() { JPanel optionPanel = new JPanel(new BorderLayout()); JScrollPane scrollPane = new JScrollPane(createParameterPanel()); scrollPane.setBorder(BorderFactory.createTitledBorder("Parameter")); optionPanel.add(scrollPane, BorderLayout.CENTER); optionPanel.add(createButtonPanel(), BorderLayout.PAGE_END); return optionPanel; } private Component createParameterPanel() { JPanel parameterPanel = new JPanel(null); parameterPanel.setPreferredSize(new Dimension(510, 300)); blackstartEnergyrequierementTextfield = new TextField("5000000"); blackstartEnergyrequierementTextfield.setBounds(10, 10, 170, 20); parameterPanel.add(blackstartEnergyrequierementTextfield); JLabel blackstartEnergyrequierementLabel = new JLabel("Blackstart Energyrequirement in Watt"); blackstartEnergyrequierementLabel.setBounds(185, 10, 300, 20); parameterPanel.add(blackstartEnergyrequierementLabel); blackstartSuccessTimeTextfield = new TextField("30"); blackstartSuccessTimeTextfield.setBounds(10, 35, 170, 20); parameterPanel.add(blackstartSuccessTimeTextfield); JLabel blackstartSuccessTimeLabel = new JLabel("Time for successfull blackstart in minutes(iterations)"); blackstartSuccessTimeLabel.setBounds(185, 35, 300, 20); parameterPanel.add(blackstartSuccessTimeLabel); blackstartStartTimeTextfield = new TextField("15"); blackstartStartTimeTextfield.setBounds(10, 60, 170, 20); parameterPanel.add(blackstartStartTimeTextfield); JLabel blackstartStartTimeLabel = new JLabel("Starttime for the blackstart"); blackstartStartTimeLabel.setBounds(185, 60, 300, 20); parameterPanel.add(blackstartStartTimeLabel); simulationDurationTextfield = new TextField("500"); simulationDurationTextfield.setBounds(10, 85, 170, 20); parameterPanel.add(simulationDurationTextfield); JLabel simulationDurationLabel = new JLabel("How long should the simulation run?"); simulationDurationLabel.setBounds(185, 85, 300, 20); parameterPanel.add(simulationDurationLabel); powerplantMaxOutputTextfield = new TextField("40000000"); powerplantMaxOutputTextfield.setBounds(10, 110, 170, 20); parameterPanel.add(powerplantMaxOutputTextfield); JLabel powerplantMaxOutputLabel = new JLabel("Powerplant Output afer Blackstart"); powerplantMaxOutputLabel.setBounds(185, 110, 300, 20); parameterPanel.add(powerplantMaxOutputLabel); storageStartCharge = new TextField("10000"); storageStartCharge.setBounds(10, 135, 170, 20); parameterPanel.add(storageStartCharge); JLabel storageStartChargeLabel = new JLabel("Storage charge at start"); storageStartChargeLabel.setBounds(185, 135, 300, 20); parameterPanel.add(storageStartChargeLabel); waitBetweenIterations = new TextField("0"); waitBetweenIterations.setBounds(10, 205, 170, 20); parameterPanel.add(waitBetweenIterations); JLabel waitBetweenIterationsLabel = new JLabel("Wait time between iterations"); waitBetweenIterationsLabel.setBounds(185, 205, 300, 20); parameterPanel.add(waitBetweenIterationsLabel); // JButton selectGroupNodeButton = new JButton("Select GroupNode"); // selectGroupNodeButton.setEnabled(false); // selectGroupNodeButton.setBounds(10, 25, 165, 20); // selectGroupNodeButton.addActionListener(actionEvent -> selectGroupNode()); // borderPanel.add(selectGroupNodeButton); // JCheckBox useGroupNodeCheckBox = new JCheckBox(); // useGroupNodeCheckBox.setSelected(false); // useGroupNodeCheckBox.setBounds(155, 1, 25, 20); // useGroupNodeCheckBox.addActionListener(actionEvent -> { // useGroupNode = useGroupNodeCheckBox.isSelected(); // selectGroupNodeButton.setEnabled(useGroupNode); // }); // borderPanel.add(useGroupNodeCheckBox); return parameterPanel; } public JPanel createButtonPanel() { JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); JButton cancelButton = new JButton("Cancel Run"); cancelButton.addActionListener(actionEvent -> cancel()); buttonPanel.add(cancelButton); JButton clearButton = new JButton("Clear Console"); clearButton.addActionListener(actionEvent -> clear()); buttonPanel.add(clearButton); JButton resetButton = new JButton("Reset"); resetButton.setToolTipText("Resets the State to before the Algorithm has runed."); resetButton.addActionListener(actionEvent -> reset()); buttonPanel.add(resetButton); JButton runButton = new JButton("Run"); runButton.addActionListener(actionEvent -> { Runnable task = this::run; runThread = new Thread(task); runThread.start(); }); buttonPanel.add(runButton); return buttonPanel; } private void cancel() { if (runThread.isAlive()) { println(""); println("Cancel run."); cancel = true; progressBar.setValue(0); } else { println("Nothing to cancel."); } } private void run() { cancel = false; disableGuiInput(true); startTimer(); initAlgo(); if (cancel) { reset(); disableGuiInput(false); return; } printElapsedTime(); disableGuiInput(false); } private void reset() { println("RESET DOES NOTHING platzhalter"); } private void disableGuiInput(boolean bool) { control.guiDisable(bool); } @Override public JPanel getPanel() { return content; } @Override public void setController(Control control) { this.control = control; } private void clear() { textArea.setText(""); } private void println(String message) { textArea.append(message + "\n"); } private void startTimer() { startTime = System.currentTimeMillis(); } private void printElapsedTime() { long elapsedMilliSeconds = System.currentTimeMillis() - startTime; println("Execution Time of Algo in Milliseconds:" + elapsedMilliSeconds); } /////////////////////////////////////////////////////////////////////////////////// /** * */ private void initAlgo() { try { // init renewableProducers = getRenewableProducers(); consumers = getConsumers(); powerplant = control.getSimManager().getPowerplant();// DANGER DONT GIVE NULL setPowerPlantBlackstartResistance(-Float.parseFloat(blackstartEnergyrequierementTextfield.getText())); SPC = new StorageProductionController(getStorageElements(), getEnergyRequiredForPowerplantBlackstart());// DANGER DONT GIVE NULL if(powerplant == null){ println("No Power Plant in Model"); return; } resistanceCalculator resistanceCalculator = new resistanceCalculator(control.getModel()); resistanceCalculator.setDistanceToCalcResistance(powerplant); blackstartRunningCounter = 0; deactivateBlackstart(); control.getModel().setCurIteration(0); // prepare model ///////// setPowerplantProduction(0); enableAllConsumers(); SPC.disableStorageDischarging(-1); //disable all storage production // TODO: prios? ///////// // Get parameters from textfields setPowerPlantBlackstartResistance(-Float.parseFloat(blackstartEnergyrequierementTextfield.getText())); blackstartSuccessTime = Integer.parseInt(blackstartSuccessTimeTextfield.getText()); powerplantMaxOutput = Float.parseFloat(powerplantMaxOutputTextfield.getText()); blackstartStartTime = Integer.parseInt(blackstartStartTimeTextfield.getText()); control.getModel().setIterations(Integer.parseInt(simulationDurationTextfield.getText())); for (StorageElement se : getStorageElements()) { se.setStateOfCharge(Integer.parseInt(storageStartCharge.getText())); } updateVisual(); if (blackstartStartTime + blackstartSuccessTime > control.getModel().getIterations() - 1) { println("No Time for the blackstart, use working numbers"); } else { blackstartMain(control.getModel().getCurIteration()); } } catch (NumberFormatException e) { println("Worng Input, only numbers please"); } } /** * * @param curIteration */ private void blackstartMain(int curIteration) { try { Thread.sleep(Integer.parseInt(waitBetweenIterations.getText())); } catch (InterruptedException e) { e.printStackTrace(); } control.getModel().setCurIteration(curIteration); if (control.getSimManager().blackstartRunning()) { if (!blackstartAlgo()) { // blackstart for this iteration was not successfull deactivateBlackstart(); updateVisual(); println("Simulation of blackstart failed in Iteration: " + curIteration); } else { // blackstart for this iteration was successfull blackstartRunningCounter++; if (blackstartRunningCounter == blackstartSuccessTime) { // blackstart was successfull for the needed iterations SPC.disableStorageDischarging(-1); deactivateBlackstart(); enableAllConsumers(); updateVisual(); println("Simulation of blackstart Successfull in Iteration: " + curIteration); } else { // blackstart not finished yet updateVisual(); blackstartMain(curIteration + 1); } } } else { // blackstart has not started yet if (curIteration == blackstartStartTime) { activateBlackstart(); disableConsumers(); blackstartMain(curIteration); } else { updateVisual(); blackstartMain(curIteration + 1); } } } /** * TODO: HOLEG UNTERVERSORGUNG CHECKEN * TODO: prios fuer elemente anschalten * TODO: elements und amount nachschauen + getEngergyPerElement anschauen * TODO: batterie status wechesel fuehrt zu unterversorgung in GUI FIX?: in storage if bei charge auskommentieren * TODO: wie soll ich unter / ueberversorgung handeln vorm blackstart * TODO: batterie modes wo nicht passiert? obwohl laden / entladen moeglich waere? * TODO: batterie laden prios? entfernung? * * @return true or false depending on whether the blackstart was successful for * this iteration */ private boolean blackstartAlgo() { if (currentRenewableProduction() < getEnergyRequiredForPowerplantBlackstart()) { // renewable energy production is not sufficient for the blackstart if (SPC.currentPossibleStorageProduction() >= getEnergyRequiredForPowerplantBlackstart() - currentRenewableProduction()) {// is there currently enough power available from storage? SPC.disableStorageDischarging(-1);// emergency fix SPC.enableStorageDischarging(getEnergyRequiredForPowerplantBlackstart() - currentRenewableProduction()); rampUpPowerplant(); enableConsumers(getPowerplantProduction()); return true; } else { // blackstart has failed SPC.disableStorageDischarging(-1);//TODO:disable all println("Not enough storage energy available"); return false; } } else { //TODO: disable storage? // renewable energy production is sufficient for the blackstart rampUpPowerplant(); enableConsumers( currentRenewableProduction() - getEnergyRequiredForPowerplantBlackstart() + getPowerplantProduction()); return true; } } //TODO: das ist ja eigentlich doppelt private ArrayList getStorageElements() { ArrayList storageElements = new ArrayList<>(); for (HolonObject holonObject : control.getModel().getAllHolonObjectsOnCanvas()) { for (HolonElement ele : holonObject.getElements()) { if(ele instanceof StorageElement){ storageElements.add((StorageElement) ele); } } } return storageElements; } private void disableConsumers() { // TODO: disableBatteryLoading? will ich das wirklich? // SPC.disableStorageProduction(); for (HolonObject consumer : consumers) { for (HolonElement ele : consumer.getElements()) { if (ele.isActive() && ele.isConsumer()) { ele.setActive(false); } } } } private void enableConsumers(float energyAvailable) { println("currenctrenewable: " + currentRenewableProduction()); println("currenctpossiblestorage: " + SPC.currentPossibleStorageProduction()); println("blackstart resi: " + getEnergyRequiredForPowerplantBlackstart()); println("current pp production: " + getPowerplantProduction()); println("energy available for consumers" + energyAvailable); // Damit wir immer die gleiche ausgangslage haben //TODO: wirklich? disableConsumers(); // TODO: das ganze lieber mit prirotaeten for (HolonObject consumer : consumers) { for (HolonElement ele : consumer.getElements()) { if (energyAvailable > 0 && energyAvailable - Math.abs(ele.getEnergyPerElement() * ele.getAmount()) >= 0) {//TODO: getenergy ist hier falsch if (!ele.isActive()) { ele.setActive(true); energyAvailable = energyAvailable - Math.abs(ele.getEnergyPerElement() * ele.getAmount());// + // since // its // negative // System.out.println("Element " + ele.getId() + " was enabled Energy left: "+ energyAvailable); } } else { return; } } } // if (!SPC.batteriesFull()) { // // TODO: load unused batteries // } else { // // } } private void enableAllConsumers() { for (HolonObject consumer : consumers) { for (HolonElement ele : consumer.getElements()) { if (!ele.isActive() && ele.isConsumer()) { ele.setActive(true); } }//TODO: storage? } } private float currentRenewableProduction() { float production = 0; for (HolonObject house : renewableProducers) { for (HolonElement ele : house.getElements()) { if (ele.getEleName().equals("Solar Panels")) {// TODO: hier muss noch mehr dazu production = production + ele.getEnergyAtTimeStep(control.getModel().getCurIteration()); } } } return production; } private void rampUpPowerplant() { for (HolonElement ele : powerplant.getElements()) { if (ele.getEleName().equals("Power")) { ele.setEnergyPerElement(ele.getEnergyPerElement() + powerplantMaxOutput / blackstartSuccessTime); } } } private float getPowerplantProduction() { float totalProduction = 0; for (HolonElement ele : powerplant.getElements()) { if (ele.getEleName().equals("Power")) { totalProduction = ele.getEnergyPerElement(); } } return totalProduction; } private void setPowerplantProduction(float power) { for (HolonElement ele : powerplant.getElements()) { if (ele.getEleName().equals("Power")) { ele.setEnergyPerElement(power); } } } private float getEnergyRequiredForPowerplantBlackstart() { for (HolonElement ele : powerplant.getElements()) { if (ele.getEleName().equals("Blackstart")) { return -ele.getEnergyPerElement(); } } return 0; } private void setPowerPlantBlackstartResistance(float resistance) { for (HolonElement ele : powerplant.getElements()) { if (ele.getEleName().equals("Blackstart")) { ele.setEnergyPerElement(resistance); } } } private void activateBlackstart() { for (HolonElement ele : powerplant.getElements()) { if (ele.getEleName().equals("Blackstart")) { ele.setActive(true); } } } private void deactivateBlackstart() { for (HolonElement ele : powerplant.getElements()) { if (ele.getEleName().equals("Blackstart")) { ele.setActive(false); } } } private LinkedList getRenewableProducers() { LinkedList list = new LinkedList<>(); for (HolonObject holonObject : control.getModel().getAllHolonObjectsOnCanvas()) { if (holonObject.getObjName().contentEquals("House")) {// TODO: das reicht so nicht da muss noch gecheckt // werden ob es renewables gibt list.add(holonObject); } } return list; } private LinkedList getConsumers() { LinkedList list = new LinkedList<>(); for (HolonObject holonObject : control.getModel().getAllHolonObjectsOnCanvas()) { if (holonObject.getObjName().contentEquals("House")) {// TODO: das reicht so nicht da muss noch gecheckt // werden ob es consumer gibt list.add(holonObject); } } return list; } /** * To let the User See the current state without touching the Canvas. */ private void updateVisual() { System.out.println("Start updateVisual in Iteration: " + control.getModel().getCurIteration()); control.calculateStateAndVisualForCurrentTimeStep(); control.updateCanvas(); System.out.println("Finish updateVisual in Iteration: " + control.getModel().getCurIteration()); } }