controlAlgorithm.java 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  1. package blackstart;
  2. import java.awt.*;
  3. import java.util.ArrayList;
  4. import java.util.LinkedList;
  5. import java.util.List;
  6. import javax.swing.*;
  7. import api.AddOn;
  8. import classes.*;
  9. import ui.controller.Control;
  10. import ui.controller.StorageProductionController;
  11. public class controlAlgorithm implements AddOn {
  12. // Gui Part:
  13. private Control control;
  14. private JTextArea textArea;
  15. private JPanel content = new JPanel();
  16. // ProgressBar
  17. private long startTime;
  18. private Thread runThread;
  19. private HolonObject powerplant;
  20. private TextField blackstartEnergyrequierementTextfield;
  21. private TextField blackstartSuccessTimeTextfield;
  22. private TextField powerplantMaxOutputTextfield;
  23. private TextField blackstartStartTimeTextfield;
  24. private TextField simulationDurationTextfield;
  25. private TextField storageStartCharge;
  26. private TextField carStartCharge;
  27. private TextField waitBetweenIterations;
  28. private TextField lowVolatageTextfield;
  29. private TextField highVolatageTextfield;
  30. private TextField renewableTextfield;
  31. private int blackstartSuccessTime;
  32. private int blackstartStartTime;
  33. private int blackstartRunningCounter;
  34. private float powerplantMaxOutput;
  35. private List<HolonObject> renewableProducers;
  36. private List<HolonObject> consumers;
  37. private StorageProductionController SPC;
  38. public static void main(String[] args) {
  39. JFrame newFrame = new JFrame("exampleWindow");
  40. controlAlgorithm instance = new controlAlgorithm();
  41. newFrame.setContentPane(instance.getPanel());
  42. newFrame.pack();
  43. newFrame.setVisible(true);
  44. newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  45. }
  46. public controlAlgorithm() {
  47. content.setLayout(new BorderLayout());
  48. textArea = new JTextArea();
  49. textArea.setEditable(false);
  50. JScrollPane scrollPane = new JScrollPane(textArea);
  51. JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, createOptionPanel(), scrollPane);
  52. splitPane.setResizeWeight(0.0);
  53. content.add(splitPane, BorderLayout.CENTER);
  54. content.setPreferredSize(new Dimension(1000, 800));
  55. }
  56. public JPanel createOptionPanel() {
  57. JPanel optionPanel = new JPanel(new BorderLayout());
  58. JScrollPane scrollPane = new JScrollPane(createParameterPanel());
  59. scrollPane.setBorder(BorderFactory.createTitledBorder("Parameter"));
  60. optionPanel.add(scrollPane, BorderLayout.CENTER);
  61. optionPanel.add(createButtonPanel(), BorderLayout.PAGE_END);
  62. return optionPanel;
  63. }
  64. private Component createParameterPanel() {
  65. JPanel parameterPanel = new JPanel(null);
  66. parameterPanel.setPreferredSize(new Dimension(510, 300));
  67. blackstartEnergyrequierementTextfield = new TextField("5000000");
  68. blackstartEnergyrequierementTextfield.setBounds(10, 10, 95, 20);
  69. parameterPanel.add(blackstartEnergyrequierementTextfield);
  70. JLabel blackstartEnergyrequierementLabel = new JLabel("Blackstart Energyrequirement in Watt");
  71. blackstartEnergyrequierementLabel.setBounds(110, 10, 300, 20);
  72. parameterPanel.add(blackstartEnergyrequierementLabel);
  73. blackstartSuccessTimeTextfield = new TextField("30");
  74. blackstartSuccessTimeTextfield.setBounds(10, 35, 95, 20);
  75. parameterPanel.add(blackstartSuccessTimeTextfield);
  76. JLabel blackstartSuccessTimeLabel = new JLabel("Time for successfull blackstart in minutes");
  77. blackstartSuccessTimeLabel.setBounds(110, 35, 300, 20);
  78. parameterPanel.add(blackstartSuccessTimeLabel);
  79. blackstartStartTimeTextfield = new TextField("15");
  80. blackstartStartTimeTextfield.setBounds(10, 60, 95, 20);
  81. parameterPanel.add(blackstartStartTimeTextfield);
  82. JLabel blackstartStartTimeLabel = new JLabel("Starttime for the blackstart");
  83. blackstartStartTimeLabel.setBounds(110, 60, 300, 20);
  84. parameterPanel.add(blackstartStartTimeLabel);
  85. simulationDurationTextfield = new TextField("500");
  86. simulationDurationTextfield.setBounds(10, 85, 95, 20);
  87. parameterPanel.add(simulationDurationTextfield);
  88. JLabel simulationDurationLabel = new JLabel("How long should the simulation run?");
  89. simulationDurationLabel.setBounds(110, 85, 300, 20);
  90. parameterPanel.add(simulationDurationLabel);
  91. powerplantMaxOutputTextfield = new TextField("40000000");
  92. powerplantMaxOutputTextfield.setBounds(10, 110, 95, 20);
  93. parameterPanel.add(powerplantMaxOutputTextfield);
  94. JLabel powerplantMaxOutputLabel = new JLabel("Powerplant Output afer Blackstart");
  95. powerplantMaxOutputLabel.setBounds(110, 110, 300, 20);
  96. parameterPanel.add(powerplantMaxOutputLabel);
  97. storageStartCharge = new TextField("25");
  98. storageStartCharge.setBounds(10, 135, 95, 20);
  99. parameterPanel.add(storageStartCharge);
  100. JLabel storageStartChargeLabel = new JLabel("Storage soc at start in %");
  101. storageStartChargeLabel.setBounds(110, 135, 300, 20);
  102. parameterPanel.add(storageStartChargeLabel);
  103. carStartCharge = new TextField("50");
  104. carStartCharge.setBounds(10, 160, 95, 20);
  105. parameterPanel.add(carStartCharge);
  106. JLabel carStartChargeLabel = new JLabel("Car soc at start in %");
  107. carStartChargeLabel.setBounds(110, 160, 300, 20);
  108. parameterPanel.add(carStartChargeLabel);
  109. waitBetweenIterations = new TextField("0");
  110. waitBetweenIterations.setBounds(10, 205, 95, 20);
  111. parameterPanel.add(waitBetweenIterations);
  112. JLabel waitBetweenIterationsLabel = new JLabel("Wait time between iterations");
  113. waitBetweenIterationsLabel.setBounds(110, 205, 300, 20);
  114. parameterPanel.add(waitBetweenIterationsLabel);
  115. ////////collums
  116. lowVolatageTextfield = new TextField("230");
  117. lowVolatageTextfield.setBounds(425, 10, 95, 20);
  118. parameterPanel.add(lowVolatageTextfield);
  119. JLabel lowVolatageLabel = new JLabel("low voltage in volt");
  120. lowVolatageLabel.setBounds(530, 10, 300, 20);
  121. parameterPanel.add(lowVolatageLabel);
  122. highVolatageTextfield = new TextField("20000");
  123. highVolatageTextfield.setBounds(425, 35, 95, 20);
  124. parameterPanel.add(highVolatageTextfield);
  125. JLabel highVolatageLabel = new JLabel("high voltage in volt");
  126. highVolatageLabel.setBounds(530, 35, 300, 20);
  127. parameterPanel.add(highVolatageLabel);
  128. renewableTextfield = new TextField("300");
  129. renewableTextfield.setBounds(425, 60, 95, 20);
  130. parameterPanel.add(renewableTextfield);
  131. JLabel renewableLabel = new JLabel("renewable power per element in watt");
  132. renewableLabel.setBounds(530, 60, 300, 20);
  133. parameterPanel.add(renewableLabel);
  134. return parameterPanel;
  135. }
  136. public JPanel createButtonPanel() {
  137. JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
  138. JButton runButton = new JButton("Run");
  139. runButton.addActionListener(actionEvent -> {
  140. Runnable task = this::run;
  141. runThread = new Thread(task);
  142. runThread.start();
  143. });
  144. buttonPanel.add(runButton);
  145. return buttonPanel;
  146. }
  147. private void run() {
  148. clear();
  149. disableGuiInput(true);
  150. startTimer();
  151. initAlgo();
  152. printElapsedTime();
  153. disableGuiInput(false);
  154. }
  155. private void disableGuiInput(boolean bool) {
  156. control.guiDisable(bool);
  157. }
  158. @Override
  159. public JPanel getPanel() {
  160. return content;
  161. }
  162. @Override
  163. public void setController(Control control) {
  164. this.control = control;
  165. }
  166. private void clear() {
  167. textArea.setText("");
  168. }
  169. private void println(String message) {
  170. textArea.append(message + "\n");
  171. }
  172. private void startTimer() {
  173. startTime = System.currentTimeMillis();
  174. }
  175. private void printElapsedTime() {
  176. long elapsedMilliSeconds = System.currentTimeMillis() - startTime;
  177. println("Execution Time of Algo in Milliseconds:" + elapsedMilliSeconds);
  178. }
  179. ///////////////////////////////////////////////////////////////////////////////////
  180. /**
  181. *
  182. */
  183. private void initAlgo() {
  184. try {
  185. // init
  186. renewableProducers = getRenewableProducers();
  187. consumers = getConsumers();
  188. powerplant = control.getSimManager().getPowerplant();// DANGER DONT GIVE NULL
  189. setPowerPlantBlackstartResistance(-Float.parseFloat(blackstartEnergyrequierementTextfield.getText()));
  190. SPC = new StorageProductionController(getStorageElements(), getEnergyRequiredForPowerplantBlackstart());// DANGER DONT GIVE NULL
  191. if(powerplant == null){
  192. println("No Power Plant in Model");
  193. return;
  194. }
  195. control.getModel().setResistanceCalculator(new resistanceCalculator(
  196. Integer.parseInt(lowVolatageTextfield.getText()),
  197. Integer.parseInt(highVolatageTextfield.getText()),
  198. 10, 25,0.017, 0.017));
  199. control.getModel().getResistanceCalculator().setDistancesToCalcResistance(powerplant);
  200. blackstartRunningCounter = 0;
  201. deactivateBlackstart();
  202. control.getModel().setCurIteration(0);
  203. // prepare model
  204. /////////
  205. setRenewableElements(Float.parseFloat(renewableTextfield.getText()));
  206. disablePowerplantProduction();
  207. enableAllConsumers();
  208. SPC.setAllStorageToStandy();
  209. // TODO: prios?
  210. /////////
  211. // Get parameters from textfields
  212. setPowerPlantBlackstartResistance(-Float.parseFloat(blackstartEnergyrequierementTextfield.getText()));
  213. blackstartSuccessTime = Integer.parseInt(blackstartSuccessTimeTextfield.getText());
  214. powerplantMaxOutput = Float.parseFloat(powerplantMaxOutputTextfield.getText());
  215. blackstartStartTime = Integer.parseInt(blackstartStartTimeTextfield.getText());
  216. control.getModel().setIterations(Integer.parseInt(simulationDurationTextfield.getText()));
  217. for (StorageElement se :
  218. getStorageElements()) {
  219. switch (se.getEleName()){
  220. case "Storage":
  221. se.setStateOfCharge(Float.parseFloat(storageStartCharge.getText()));
  222. break;
  223. case "Car":
  224. se.setStateOfCharge(Float.parseFloat(carStartCharge.getText()));
  225. break;
  226. }
  227. }
  228. updateVisual();
  229. if (blackstartStartTime + blackstartSuccessTime > control.getModel().getIterations() - 1) {
  230. println("No Time for the blackstart, use working numbers");
  231. } else {
  232. blackstartMain(control.getModel().getCurIteration());
  233. }
  234. } catch (NumberFormatException e) {
  235. println("Worng Input, only numbers please");
  236. }
  237. }
  238. private void blackstartMain(int curIteration) {
  239. try {
  240. Thread.sleep(Integer.parseInt(waitBetweenIterations.getText()));
  241. } catch (InterruptedException e) {
  242. e.printStackTrace();
  243. }
  244. control.getModel().setCurIteration(curIteration);
  245. if (control.getSimManager().blackstartRunning()) {
  246. if (!blackstartAlgo()) {
  247. // blackstart for this iteration was not successfull
  248. deactivateBlackstart();
  249. updateVisual();
  250. println("Simulation of blackstart failed in Iteration: " + curIteration);
  251. } else {
  252. // blackstart for this iteration was successfull
  253. blackstartRunningCounter++;
  254. if (blackstartRunningCounter == blackstartSuccessTime) {
  255. // blackstart was successfull for the needed iterations
  256. SPC.setAllStorageToStandy();
  257. deactivateBlackstart();
  258. enableAllConsumers();
  259. updateVisual();
  260. println("Simulation of blackstart Successfull in Iteration: " + curIteration);
  261. } else {
  262. // blackstart not finished yet
  263. updateVisual();
  264. blackstartMain(curIteration + 1);
  265. }
  266. }
  267. } else {
  268. // blackstart has not started yet
  269. if (curIteration == blackstartStartTime) {
  270. activateBlackstart();
  271. disableConsumers();
  272. blackstartMain(curIteration);
  273. } else {
  274. updateVisual();
  275. blackstartMain(curIteration + 1);
  276. }
  277. }
  278. }
  279. /**
  280. * TODO: HOLEG UNTERVERSORGUNG CHECKEN
  281. * TODO: global resistance calculator?
  282. * TODO: entladen besser verteilen
  283. *
  284. *
  285. * maybes:
  286. * * TODO: prios fuer elemente anschalten
  287. * * TODO: batterie status wechesel fuehrt zu unterversorgung in GUI FIX?: in storage if bei charge auskommentieren
  288. * * TODO: batterie laden prios? entfernung? doppelt sortieren
  289. *
  290. * @return true or false depending on whether the blackstart was successful for
  291. * this iteration
  292. */
  293. private boolean blackstartAlgo() {
  294. printCurrentEnergyState();
  295. if (currentRenewableProduction() < getEnergyRequiredForPowerplantBlackstart()) {
  296. // renewable energy production is not sufficient for the blackstart
  297. if (SPC.currentPossibleStorageProduction() >= getEnergyRequiredForPowerplantBlackstart()
  298. - currentRenewableProduction()) {// is there currently enough power available from storage?
  299. SPC.setAllStorageToStandy();//TODO: placement
  300. SPC.enableStorageDischarging(getEnergyRequiredForPowerplantBlackstart() - currentRenewableProduction());
  301. rampUpPowerplant();
  302. enableConsumers(getPowerplantProduction());
  303. return true;
  304. } else {
  305. // blackstart has failed
  306. SPC.setAllStorageToStandy();
  307. println("Not enough storage energy available");
  308. return false;
  309. }
  310. } else {
  311. //TODO: disable storage?
  312. // renewable energy production is sufficient for the blackstart
  313. rampUpPowerplant();
  314. enableConsumers(
  315. currentRenewableProduction() - getEnergyRequiredForPowerplantBlackstart() + getPowerplantProduction());
  316. return true;
  317. }
  318. }
  319. private ArrayList<StorageElement> getStorageElements() {
  320. ArrayList<StorageElement> storageElements = new ArrayList<>();
  321. for (HolonObject holonObject : control.getModel().getAllHolonObjectsOnCanvas()) {
  322. for (HolonElement ele : holonObject.getElements()) {
  323. if(ele instanceof StorageElement){
  324. storageElements.add((StorageElement) ele);
  325. }
  326. }
  327. }
  328. return storageElements;
  329. }
  330. private void disableConsumers() {
  331. // TODO: disableBatteryLoading? will ich das wirklich?
  332. // SPC.disableStorageProduction();
  333. for (HolonObject consumer : consumers) {
  334. for (HolonElement ele : consumer.getElements()) {
  335. if (ele.isActive() && ele.isConsumer()) {
  336. ele.setActive(false);
  337. }
  338. }
  339. }
  340. }
  341. private void enableConsumers(float energyAvailable) {
  342. // println("current pp production: " + getPowerplantProduction());
  343. // println("energy available for consumers" + energyAvailable);
  344. // Damit wir immer die gleiche ausgangslage haben //TODO: wirklich?
  345. disableConsumers();
  346. // TODO: das ganze lieber mit prirotaeten
  347. for (HolonObject consumer : consumers) {
  348. for (HolonElement ele : consumer.getElements()) {
  349. if (energyAvailable > 0
  350. && energyAvailable - Math.abs(ele.getEnergyPerElement() * ele.getAmount()) >= 0) {//TODO: getenergy ist hier falsch
  351. if (!ele.isActive()) {
  352. ele.setActive(true);
  353. energyAvailable = energyAvailable - Math.abs(ele.getEnergyPerElement() * ele.getAmount());// +
  354. // since
  355. // its
  356. // negative
  357. }
  358. } else {
  359. return;
  360. }
  361. }
  362. }
  363. // if (!SPC.batteriesFull()) {
  364. // // TODO: load unused batteries
  365. // } else {
  366. //
  367. // }
  368. }
  369. private void enableAllConsumers() {
  370. for (HolonObject consumer : consumers) {
  371. for (HolonElement ele : consumer.getElements()) {
  372. if (!ele.isActive() && ele.isConsumer()) {
  373. ele.setActive(true);
  374. }
  375. }//TODO: storage?
  376. }
  377. }
  378. private void setRenewableElements(float energy){
  379. for (HolonObject house : renewableProducers) {
  380. for (HolonElement ele : house.getElements()) {
  381. if (ele.getEleName().equals("Solar Panels")) {// TODO: hier muss noch mehr dazu
  382. ele.setEnergyPerElement(
  383. control.getModel().getResistanceCalculator().calcEnergyAfterResistance(
  384. energy,
  385. ele.getLowDistance(),
  386. ele.getHighDistance(),
  387. getEnergyRequiredForPowerplantBlackstart()));
  388. }
  389. }
  390. }
  391. }
  392. private float currentRenewableProduction() {
  393. float production = 0;
  394. for (HolonObject house : renewableProducers) {
  395. for (HolonElement ele : house.getElements()) {
  396. if (ele.getEleName().equals("Solar Panels")) {// TODO: hier muss noch mehr dazu
  397. production = production + ele.getEnergyAtTimeStep(control.getModel().getCurIteration());
  398. }
  399. }
  400. }
  401. return production;
  402. }
  403. private void rampUpPowerplant() {
  404. for (HolonElement ele : powerplant.getElements()) {
  405. if (ele.getEleName().equals("Power")) {
  406. ele.setEnergyPerElement(ele.getEnergyPerElement() + powerplantMaxOutput / blackstartSuccessTime);
  407. }
  408. }
  409. }
  410. private float getPowerplantProduction() {
  411. float totalProduction = 0;
  412. for (HolonElement ele : powerplant.getElements()) {
  413. if (ele.getEleName().equals("Power")) {
  414. totalProduction = ele.getEnergyPerElement();
  415. }
  416. }
  417. return totalProduction;
  418. }
  419. private void disablePowerplantProduction() {
  420. for (HolonElement ele : powerplant.getElements()) {
  421. if (ele.getEleName().equals("Power")) {
  422. ele.setEnergyPerElement(0);
  423. }
  424. }
  425. }
  426. private float getEnergyRequiredForPowerplantBlackstart() {
  427. for (HolonElement ele : powerplant.getElements()) {
  428. if (ele.getEleName().equals("Blackstart")) {
  429. return -ele.getEnergyPerElement();
  430. }
  431. }
  432. return 0;
  433. }
  434. private void setPowerPlantBlackstartResistance(float resistance) {
  435. for (HolonElement ele : powerplant.getElements()) {
  436. if (ele.getEleName().equals("Blackstart")) {
  437. ele.setEnergyPerElement(resistance);
  438. }
  439. }
  440. }
  441. private void activateBlackstart() {
  442. for (HolonElement ele : powerplant.getElements()) {
  443. if (ele.getEleName().equals("Blackstart")) {
  444. ele.setActive(true);
  445. }
  446. }
  447. }
  448. private void deactivateBlackstart() {
  449. for (HolonElement ele : powerplant.getElements()) {
  450. if (ele.getEleName().equals("Blackstart")) {
  451. ele.setActive(false);
  452. }
  453. }
  454. }
  455. private LinkedList<HolonObject> getRenewableProducers() {
  456. LinkedList<HolonObject> list = new LinkedList<>();
  457. for (HolonObject holonObject : control.getModel().getAllHolonObjectsOnCanvas()) {
  458. if (holonObject.getObjName().contentEquals("House")) {// TODO: das reicht so nicht da muss noch gecheckt
  459. // werden ob es renewables gibt
  460. list.add(holonObject);
  461. }
  462. }
  463. return list;
  464. }
  465. private LinkedList<HolonObject> getConsumers() {
  466. LinkedList<HolonObject> list = new LinkedList<>();
  467. for (HolonObject holonObject : control.getModel().getAllHolonObjectsOnCanvas()) {
  468. if (holonObject.getObjName().contentEquals("House")) {// TODO: das reicht so nicht da muss noch gecheckt
  469. // werden ob es consumer gibt
  470. list.add(holonObject);
  471. }
  472. }
  473. return list;
  474. }
  475. private void printCurrentEnergyState(){
  476. println("blackstart resi: " + getEnergyRequiredForPowerplantBlackstart());
  477. println("currenctrenewable: " + currentRenewableProduction());
  478. println("currenctpossiblestorage: " + SPC.currentPossibleStorageProduction());
  479. for (StorageElement ele :
  480. getStorageElements()) {
  481. println(ele.getEleName() + " " + ele.getId() + ", soc: " + (ele.getStateOfCharge()/60)/1000 + "kWh," + " maxpower: " + ele.getMaxOutRatio() + " W, distance: " + (ele.getLowDistance()+ele.getHighDistance()));
  482. }
  483. }
  484. /**
  485. * To let the User See the current state without touching the Canvas.
  486. */
  487. private void updateVisual() {
  488. System.out.println("Start updateVisual in Iteration: " + control.getModel().getCurIteration());
  489. control.calculateStateAndVisualForCurrentTimeStep();
  490. control.updateCanvas();
  491. System.out.println("Finish updateVisual in Iteration: " + control.getModel().getCurIteration());
  492. }
  493. }