controlAlgorithm.java 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  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 : getStorageElements()) {
  218. if ("Car".equals(se.getEleName())) {
  219. se.setStateOfCharge(Float.parseFloat(carStartCharge.getText()));
  220. } else {
  221. se.setStateOfCharge(Float.parseFloat(storageStartCharge.getText()));
  222. }
  223. }
  224. updateVisual();
  225. if (blackstartStartTime + blackstartSuccessTime > control.getModel().getIterations() - 1) {
  226. println("No Time for the blackstart, use working numbers");
  227. } else {
  228. blackstartMain(control.getModel().getCurIteration());
  229. }
  230. } catch (NumberFormatException e) {
  231. println("Worng Input, only numbers please");
  232. }
  233. }
  234. private void blackstartMain(int curIteration) {
  235. try {
  236. Thread.sleep(Integer.parseInt(waitBetweenIterations.getText()));
  237. } catch (InterruptedException e) {
  238. e.printStackTrace();
  239. }
  240. control.getModel().setCurIteration(curIteration);
  241. if (control.getSimManager().blackstartRunning()) {
  242. if (!blackstartAlgo()) {
  243. // blackstart for this iteration was not successfull
  244. deactivateBlackstart();
  245. updateVisual();
  246. println("Simulation of blackstart failed in Iteration: " + curIteration);
  247. } else {
  248. // blackstart for this iteration was successfull
  249. blackstartRunningCounter++;
  250. if (blackstartRunningCounter == blackstartSuccessTime) {
  251. // blackstart was successfull for the needed iterations
  252. SPC.setAllStorageToStandy();
  253. deactivateBlackstart();
  254. enableAllConsumers();
  255. updateVisual();
  256. println("Simulation of blackstart Successfull in Iteration: " + curIteration);
  257. } else {
  258. // blackstart not finished yet
  259. updateVisual();
  260. blackstartMain(curIteration + 1);
  261. }
  262. }
  263. } else {
  264. // blackstart has not started yet
  265. if (curIteration == blackstartStartTime) {
  266. activateBlackstart();
  267. disableConsumers();
  268. blackstartMain(curIteration);
  269. } else {
  270. updateVisual();
  271. blackstartMain(curIteration + 1);
  272. }
  273. }
  274. }
  275. /**
  276. * TODO: HOLEG UNTERVERSORGUNG CHECKEN
  277. * TODO: global resistance calculator?
  278. * TODO: entladen besser verteilen
  279. *
  280. *
  281. * maybes:
  282. * * TODO: prios fuer elemente anschalten
  283. * * TODO: batterie status wechesel fuehrt zu unterversorgung in GUI FIX?: in storage if bei charge auskommentieren
  284. * * TODO: batterie laden prios? entfernung? doppelt sortieren
  285. *
  286. * @return true or false depending on whether the blackstart was successful for
  287. * this iteration
  288. */
  289. private boolean blackstartAlgo() {
  290. printCurrentEnergyState();
  291. if (currentRenewableProduction() < getEnergyRequiredForPowerplantBlackstart()) {
  292. // renewable energy production is not sufficient for the blackstart
  293. if (SPC.currentPossibleStorageProduction() >= getEnergyRequiredForPowerplantBlackstart()
  294. - currentRenewableProduction()) {// is there currently enough power available from storage?
  295. SPC.setAllStorageToStandy();//TODO: placement
  296. SPC.enableStorageDischarging(getEnergyRequiredForPowerplantBlackstart() - currentRenewableProduction());
  297. rampUpPowerplant();
  298. enableConsumers(getPowerplantProduction());
  299. return true;
  300. } else {
  301. // blackstart has failed
  302. SPC.setAllStorageToStandy();
  303. println("Not enough storage energy available");
  304. return false;
  305. }
  306. } else {
  307. //TODO: disable storage?
  308. // renewable energy production is sufficient for the blackstart
  309. rampUpPowerplant();
  310. enableConsumers(
  311. currentRenewableProduction() - getEnergyRequiredForPowerplantBlackstart() + getPowerplantProduction());
  312. return true;
  313. }
  314. }
  315. private ArrayList<StorageElement> getStorageElements() {
  316. ArrayList<StorageElement> storageElements = new ArrayList<>();
  317. for (HolonObject holonObject : control.getModel().getAllHolonObjectsOnCanvas()) {
  318. for (HolonElement ele : holonObject.getElements()) {
  319. if(ele instanceof StorageElement){
  320. storageElements.add((StorageElement) ele);
  321. }
  322. }
  323. }
  324. return storageElements;
  325. }
  326. private void disableConsumers() {
  327. // TODO: disableBatteryLoading? will ich das wirklich?
  328. // SPC.disableStorageProduction();
  329. for (HolonObject consumer : consumers) {
  330. for (HolonElement ele : consumer.getElements()) {
  331. if (ele.isActive() && ele.isConsumer()) {
  332. ele.setActive(false);
  333. }
  334. }
  335. }
  336. }
  337. private void enableConsumers(float energyAvailable) {
  338. // println("current pp production: " + getPowerplantProduction());
  339. // println("energy available for consumers" + energyAvailable);
  340. // Damit wir immer die gleiche ausgangslage haben //TODO: wirklich?
  341. disableConsumers();
  342. // TODO: das ganze lieber mit prirotaeten
  343. for (HolonObject consumer : consumers) {
  344. for (HolonElement ele : consumer.getElements()) {
  345. if (energyAvailable > 0
  346. && energyAvailable - Math.abs(ele.getEnergyPerElement() * ele.getAmount()) >= 0) {//TODO: getenergy ist hier falsch
  347. if (!ele.isActive()) {
  348. ele.setActive(true);
  349. energyAvailable = energyAvailable - Math.abs(ele.getEnergyPerElement() * ele.getAmount());// +
  350. // since
  351. // its
  352. // negative
  353. }
  354. } else {
  355. return;
  356. }
  357. }
  358. }
  359. }
  360. private void enableAllConsumers() {
  361. for (HolonObject consumer : consumers) {
  362. for (HolonElement ele : consumer.getElements()) {
  363. if (!ele.isActive() && ele.isConsumer()) {
  364. ele.setActive(true);
  365. }
  366. }//TODO: storage?
  367. }
  368. }
  369. private void setRenewableElements(float energy){
  370. for (HolonObject house : renewableProducers) {
  371. for (HolonElement ele : house.getElements()) {
  372. if (ele.getEleName().equals("Solar Panels")) {// TODO: hier muss noch mehr dazu
  373. ele.setEnergyPerElement(
  374. control.getModel().getResistanceCalculator().calcEnergyAfterResistance(
  375. energy,
  376. ele.getLowDistance(),
  377. ele.getHighDistance(),
  378. getEnergyRequiredForPowerplantBlackstart()));
  379. }
  380. }
  381. }
  382. }
  383. private float currentRenewableProduction() {
  384. float production = 0;
  385. for (HolonObject house : renewableProducers) {
  386. for (HolonElement ele : house.getElements()) {
  387. if (ele.getEleName().equals("Solar Panels")) {// TODO: hier muss noch mehr dazu
  388. production = production + ele.getEnergyAtTimeStep(control.getModel().getCurIteration());
  389. }
  390. }
  391. }
  392. return production;
  393. }
  394. private void rampUpPowerplant() {
  395. for (HolonElement ele : powerplant.getElements()) {
  396. if (ele.getEleName().equals("Power")) {
  397. ele.setEnergyPerElement(ele.getEnergyPerElement() + powerplantMaxOutput / blackstartSuccessTime);
  398. }
  399. }
  400. }
  401. private float getPowerplantProduction() {
  402. float totalProduction = 0;
  403. for (HolonElement ele : powerplant.getElements()) {
  404. if (ele.getEleName().equals("Power")) {
  405. totalProduction = ele.getEnergyPerElement();
  406. }
  407. }
  408. return totalProduction;
  409. }
  410. private void disablePowerplantProduction() {
  411. for (HolonElement ele : powerplant.getElements()) {
  412. if (ele.getEleName().equals("Power")) {
  413. ele.setEnergyPerElement(0);
  414. }
  415. }
  416. }
  417. private float getEnergyRequiredForPowerplantBlackstart() {
  418. for (HolonElement ele : powerplant.getElements()) {
  419. if (ele.getEleName().equals("Blackstart")) {
  420. return -ele.getEnergyPerElement();
  421. }
  422. }
  423. return 0;
  424. }
  425. private void setPowerPlantBlackstartResistance(float resistance) {
  426. for (HolonElement ele : powerplant.getElements()) {
  427. if (ele.getEleName().equals("Blackstart")) {
  428. ele.setEnergyPerElement(resistance);
  429. }
  430. }
  431. }
  432. private void activateBlackstart() {
  433. for (HolonElement ele : powerplant.getElements()) {
  434. if (ele.getEleName().equals("Blackstart")) {
  435. ele.setActive(true);
  436. }
  437. }
  438. }
  439. private void deactivateBlackstart() {
  440. for (HolonElement ele : powerplant.getElements()) {
  441. if (ele.getEleName().equals("Blackstart")) {
  442. ele.setActive(false);
  443. }
  444. }
  445. }
  446. private LinkedList<HolonObject> getRenewableProducers() {
  447. LinkedList<HolonObject> list = new LinkedList<>();
  448. for (HolonObject holonObject : control.getModel().getAllHolonObjectsOnCanvas()) {
  449. if (holonObject.getObjName().contentEquals("House")) {// TODO: das reicht so nicht da muss noch gecheckt
  450. // werden ob es renewables gibt
  451. list.add(holonObject);
  452. }
  453. }
  454. return list;
  455. }
  456. private LinkedList<HolonObject> getConsumers() {
  457. LinkedList<HolonObject> list = new LinkedList<>();
  458. for (HolonObject holonObject : control.getModel().getAllHolonObjectsOnCanvas()) {
  459. if (holonObject.getObjName().contentEquals("House")) {// TODO: das reicht so nicht da muss noch gecheckt
  460. // werden ob es consumer gibt
  461. list.add(holonObject);
  462. }
  463. }
  464. return list;
  465. }
  466. private void printCurrentEnergyState(){
  467. println("blackstart resi: " + getEnergyRequiredForPowerplantBlackstart());
  468. println("currenctrenewable: " + currentRenewableProduction());
  469. println("currenctpossiblestorage: " + SPC.currentPossibleStorageProduction());
  470. for (StorageElement ele :
  471. getStorageElements()) {
  472. println(ele.getEleName() + " " + ele.getId() + ", soc: " + (ele.getStateOfCharge()/60)/1000 + "kWh," + " maxpower: " + ele.getMaxOutRatio() + " W, distance: " + (ele.getLowDistance()+ele.getHighDistance()));
  473. }
  474. }
  475. /**
  476. * To let the User See the current state without touching the Canvas.
  477. */
  478. private void updateVisual() {
  479. // System.out.println("Start updateVisual in Iteration: " + control.getModel().getCurIteration());
  480. control.calculateStateAndVisualForCurrentTimeStep();
  481. control.updateCanvas();
  482. // System.out.println("Finish updateVisual in Iteration: " + control.getModel().getCurIteration());
  483. }
  484. }