HolonObject.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  1. package classes;
  2. import com.google.gson.annotations.Expose;
  3. import java.awt.*;
  4. import java.util.ArrayList;
  5. import javafx.util.converter.PercentageStringConverter;
  6. /**
  7. * The class HolonObject represents any Object on the system which capability of
  8. * injecting or consuming energy on the network, for instance a house or a power
  9. * plant.
  10. *
  11. * @author Gruppe14
  12. */
  13. public class HolonObject extends AbstractCpsObject {
  14. /*
  15. * the constants showing a HolonObject's current state
  16. * (whether it needs no energy, whether it is not supplied, fully supplied,
  17. * a producer, partially supplied or over-supplied)
  18. */
  19. //TODO: enum
  20. enum State{
  21. NO_ENERGY, NOT_SUPPLIED, SUPPLIED, PRODUCER, PARTIALLY_SUPPLIED, OVER_SUPPLIED
  22. }
  23. public final static int NO_ENERGY = 0;
  24. public final static int NOT_SUPPLIED = 1;
  25. public final static int SUPPLIED = 2;
  26. public final static int PRODUCER = 3;
  27. public final static int PARTIALLY_SUPPLIED = 4;
  28. public final static int OVER_SUPPLIED = 5;
  29. /*
  30. * Color of the actual state (red = no supplied, yellow = partially supplied
  31. * and green = supplied)
  32. */
  33. @Expose
  34. private Color stateColor; //TODO: to draw function
  35. /* Array of all consumers */
  36. private ArrayList<HolonElement> elements;
  37. /* Total of consumption */
  38. @Expose
  39. private float currentEnergy;
  40. /* Array for tracking Production */
  41. private float[] trackingProd;
  42. /* Array for tracking Consumption */
  43. private float[] trackingCons;
  44. /* Total Flexibility */
  45. private float totalFlex;
  46. @Expose
  47. private int state = 0;
  48. /**
  49. * Energy level that was supplied by other HolonObjects in the current Calculation
  50. */
  51. private float currentSupply;
  52. /** TODO: outsourcing
  53. * Percentage of supplied energy of the energy level needed to supply all elements
  54. */
  55. private float suppliedPercentage;
  56. /**
  57. * Constructor Set by default the name of the object equals to the category
  58. * name, until the user changes it.
  59. *
  60. * @param objName name of the Object
  61. */
  62. public HolonObject(String objName) {
  63. super(objName);
  64. setElements(new ArrayList<>());
  65. setState();
  66. setTrackingProd(new float[100]);
  67. setTrackingCons(new float[100]);
  68. }
  69. /**
  70. * Contructor of a copy of an Object.
  71. *
  72. * @param obj object to be copied
  73. */
  74. public HolonObject(AbstractCpsObject obj) {
  75. super(obj);
  76. setElements(copyElements(((HolonObject) obj).getElements()));
  77. setState();
  78. setTrackingProd(new float[100]);
  79. setTrackingCons(new float[100]);
  80. }
  81. /**
  82. * sets the State, whether object is a producer, zero Energy, supplied,
  83. * partially or over-supplied
  84. */
  85. public void setState() {
  86. if (getMaxActiveEnergy() > 0) {
  87. setState(PRODUCER);
  88. stateColor = Color.lightGray;
  89. } else {
  90. if (getMaxActiveEnergy() == 0) {
  91. setState(NO_ENERGY);
  92. stateColor = Color.WHITE;
  93. } else {
  94. if (checkIfPartiallySupplied(0)) {
  95. stateColor = Color.yellow;
  96. } else {
  97. stateColor = new Color(230, 120, 100);
  98. }
  99. }
  100. }
  101. }
  102. /**
  103. * Getter for all Elements in the HolonObject.
  104. *
  105. * @return the elements ArrayList
  106. */
  107. public ArrayList<HolonElement> getElements() {
  108. return elements;
  109. }
  110. /**
  111. * Set a new ArrayList with HolonElements into the HolonObject.
  112. *
  113. * @param elements the elements to set
  114. */
  115. public void setElements(ArrayList<HolonElement> elements) {
  116. this.elements = elements;
  117. }
  118. /**
  119. * adds an Element to the Object.
  120. *
  121. * @param element the Element to add
  122. */
  123. public void addElement(HolonElement element) {
  124. elements.add(element);
  125. }
  126. /**
  127. * deletes Element at a given index.
  128. *
  129. * @param idx index
  130. */
  131. public void deleteElement(int idx) {
  132. elements.remove(idx);
  133. }
  134. /**
  135. * Calculate the maximum energy a holonObject can consume from all object that are aktive this moment;
  136. *
  137. * @return the maximal active energy possibel
  138. */
  139. public float getMaxActiveEnergy() {
  140. float temp = 0;
  141. for (HolonElement e : getElements()) {
  142. if (e.isActive()) {
  143. temp += e.getOverallEnergy();
  144. }
  145. }
  146. currentEnergy = temp;
  147. return temp;
  148. }
  149. /**
  150. * Getter for the current energy at a given timestep.
  151. *
  152. * @param x timestep
  153. * @return corresponding energy
  154. */
  155. public float getCurrentEnergyAtTimeStep(int x) {
  156. float cons = 0;
  157. float prod = currentSupply;
  158. float t;
  159. for (HolonElement e : getElements()) {
  160. if (e.isActive()) {
  161. t = e.getOverallEnergyAtTimeStep(x);
  162. if(t<0){
  163. cons+=t;
  164. }else{
  165. prod+=t;
  166. }
  167. }
  168. }
  169. currentEnergy = prod + cons;
  170. suppliedPercentage = prod / -cons;
  171. return currentEnergy;
  172. }
  173. /**
  174. * Getter for the current energy at a given timestep.
  175. *
  176. * @param x timestep
  177. * @return corresponding energy
  178. */
  179. public float getCurrentEnergyAtTimeStepWithoutFlexiblesAndResetFlexibles(int x) {
  180. float temp = 0;
  181. for (HolonElement e : getElements()) {
  182. if (e.isActive() && !e.isFlexible()) {
  183. temp += e.getOverallEnergyAtTimeStep(x);
  184. } else if (e.isFlexible()) {
  185. e.setEnergyPerElement(0);
  186. }
  187. }
  188. currentEnergy = temp;
  189. return currentEnergy;
  190. }
  191. /**
  192. * String of all consumers in this HolonObject.
  193. *
  194. * @return all the names of this HolonObject separated by "," each object
  195. */
  196. public String toStringElements() {
  197. String objString = "Empty";
  198. for (HolonElement e : elements) {
  199. if (objString == "Empty") {
  200. objString = e.getEleName();
  201. } else {
  202. objString = objString + ", " + e.getEleName();
  203. }
  204. }
  205. return objString;
  206. }
  207. /**
  208. * Copy all Elements into a New Array.
  209. *
  210. * @param arr to copy
  211. * @return the copy of arr
  212. */
  213. public ArrayList<HolonElement> copyElements(ArrayList<HolonElement> arr) {
  214. ArrayList<HolonElement> newArr = new ArrayList<>();
  215. for (HolonElement t : arr) {
  216. newArr.add(new HolonElement(t));
  217. }
  218. return newArr;
  219. }
  220. /**
  221. * Get the state of the Object.
  222. *
  223. * @return state the State of the Element
  224. */
  225. public int getState() {
  226. return this.state;
  227. }
  228. /**
  229. * Set the state of the Object.
  230. *
  231. * @param state boolean if the Object is fully supplied
  232. */
  233. public void setState(int state) {
  234. this.state = state;
  235. switch (state) {
  236. case NO_ENERGY:
  237. stateColor = Color.WHITE;
  238. break;
  239. case NOT_SUPPLIED:
  240. stateColor = new Color(230, 120, 100);
  241. break;
  242. case SUPPLIED:
  243. stateColor = Color.GREEN;
  244. break;
  245. case PRODUCER:
  246. stateColor = Color.lightGray;
  247. break;
  248. case PARTIALLY_SUPPLIED:
  249. stateColor = Color.YELLOW;
  250. break;
  251. case OVER_SUPPLIED:
  252. // find different purple-tones at
  253. // http://www.rapidtables.com/web/color/purple-color.htm
  254. stateColor = new Color(138, 43, 226);
  255. break;
  256. }
  257. }
  258. /**
  259. * Search for the first element with the name.
  260. *
  261. * @param name name of the object to be searched
  262. * @return the searched HolonElement
  263. */
  264. public HolonElement searchElement(String name) {
  265. HolonElement ele = null;
  266. for (HolonElement e : getElements()) {
  267. if (e.getEleName().equals(name)) {
  268. ele = e;
  269. break;
  270. }
  271. }
  272. return ele;
  273. }
  274. /**
  275. * Search for the element with the id.
  276. *
  277. * @param id id of the element to be founded
  278. * @return the element
  279. */
  280. public HolonElement searchElementById(int id) {
  281. HolonElement ele = null;
  282. for (HolonElement e : getElements()) {
  283. if (e.getId() == id) {
  284. ele = e;
  285. break;
  286. }
  287. }
  288. return ele;
  289. }
  290. /**
  291. * Check if Partially Supplied.
  292. *
  293. * @param x current Iteration
  294. * @return boolean is partially supplied
  295. */
  296. public boolean checkIfPartiallySupplied(int x) {
  297. if (getElements().size() == 0) {
  298. return false;
  299. }
  300. float minConsum = 0;
  301. // Search for a activ element
  302. for (HolonElement e : getElements()) {
  303. if (e.isActive()) {
  304. float overallEnergy = e.getOverallEnergyAtTimeStep(x);
  305. if (overallEnergy < 0) {
  306. // Is a consumer
  307. minConsum = overallEnergy;
  308. }
  309. }
  310. }
  311. float prod = 0;
  312. float cons = 0;
  313. for (HolonElement e : getElements()) {
  314. if (e.isActive()) {
  315. float overallEnergy = e.getOverallEnergyAtTimeStep(x);
  316. if (overallEnergy > 0) {
  317. prod += overallEnergy;
  318. }else{
  319. cons += overallEnergy;
  320. }
  321. if (minConsum < 0 && (overallEnergy > minConsum && overallEnergy < 0)) {
  322. minConsum = overallEnergy;
  323. }
  324. }
  325. }
  326. suppliedPercentage = -(prod + currentSupply)/cons;
  327. // System.out.println("minCons: " + minConsum + " prod: " + prod);
  328. if (minConsum < 0 && prod >= -minConsum) {
  329. return true;
  330. } else {
  331. return false;
  332. }
  333. }
  334. /**
  335. *
  336. * @param x
  337. * @return
  338. */
  339. public float getSelfMadeEnergy(int x)
  340. {
  341. return getElements().stream()
  342. .map(e ->(e.isActive() && e.getOverallEnergyAtTimeStep(x) > 0) ? e.getOverallEnergyAtTimeStep(x) : 0.0f)
  343. .reduce(0.0f, (a , b) -> a + b );
  344. }
  345. /**
  346. * Calculates the minimumEnergy Needed to turn on atleast on device
  347. * of this HolonObject
  348. * @param timestep Timestep of the calculation
  349. * @return minEnergy, -inf if no Devices are consuming power
  350. */
  351. public float getMinEnergy(int timestep) {
  352. if (getElements().size() == 0) {
  353. return Float.NEGATIVE_INFINITY;
  354. }
  355. float minConsum = Float.NEGATIVE_INFINITY;
  356. for (HolonElement e : getElements()) {
  357. if (e.isActive()) {
  358. float overallEnergy = e.getOverallEnergyAtTimeStep(timestep);
  359. if (minConsum < 0 && (overallEnergy > minConsum && overallEnergy < 0)) {
  360. minConsum = overallEnergy;
  361. }
  362. }
  363. }
  364. return minConsum;
  365. }
  366. //New Methods:
  367. /**
  368. * This Method returns the smallest consuming HolonElement that is ACTIVE.
  369. * If the HolonObject has no Consumer its return null.
  370. * @param timestep is the TimeStep to compare the HolonElements.
  371. * @return The smallest consuming HolonElement or null.
  372. */
  373. public HolonElement getMinimumConsumingElement(int timestep){
  374. return getElements().stream().filter(element -> element.isActive() && (element.getEnergyAtTimeStep(timestep) < 0) ).max((lhs,rhs) -> Float.compare(lhs.getEnergyAtTimeStep(timestep), rhs.getEnergyAtTimeStep(timestep))).orElse(null);
  375. }
  376. /**
  377. * This Method returns the smallest consuming HolonElement'Energy that is ACTIVE.
  378. * If the HolonObject has no Consumer its return 0.
  379. * @param timestep is the TimeStep to compare the HolonElements.
  380. * @return The smallest consuming HolonElement or 0.
  381. */
  382. public float getMinimumConsumingElementEnergy(int timestep){
  383. return getElements().stream().filter(element -> element.isActive() && (element.getEnergyAtTimeStep(timestep) < 0) ).map(element -> -element.getEnergyAtTimeStep(timestep)).min((lhs,rhs) ->Float.compare(lhs, rhs)).orElse(0.0f);
  384. }
  385. /**
  386. * This Method returns the Energy of a HolonObject. Its sums all Energies from the HolonElements of the HolonObject that are ACTIVE.
  387. * If the HolonObject have no HolonElement its return 0;
  388. * Is the returned Energy negative then the HolonObject need Energy because its consuming HolonElements need more Energy then the producing HolonElements.
  389. * Is the returned Energy positive its reversed.
  390. * @param timestep is the TimeStep to compare the HolonElements.
  391. * @return The Energy of the HolonObject.
  392. */
  393. public float getEnergyAtTimeStep(int timestep)
  394. {
  395. return getElements().stream().filter(element -> element.isActive()).map(element -> element.getEnergyAtTimeStep(timestep)).reduce(0.0f, (a, b) -> a + b);
  396. }
  397. /**
  398. * This Method returns the Energy that all HolonElements from the HolonObject produce by itself. Its sums all Energies from the HolonElements of the HolonObject that are ACTIVE and are Producer.
  399. * If the HolonObject have no HolonElement its return 0;
  400. * @param timestep is the TimeStep to compare the HolonElements.
  401. * @return The Energy of the producing HolonElements.
  402. */
  403. public float getEnergySelfProducingFromProducingElements(int timestep) {
  404. return getElements().stream().filter(element -> element.isActive() && (element.getEnergyAtTimeStep(timestep) > 0)).map(element -> element.getEnergyAtTimeStep(timestep)).reduce(0.0f, (a, b) -> a + b);
  405. }
  406. /**
  407. * This Method returns the Energy of all HolonElements from the HolonObject that are consuming. Its sums all Energies from the HolonElements of the HolonObject that are ACTIVE and are Consumer.
  408. * If the HolonObject have no HolonElement its return 0;
  409. * @param timestep is the TimeStep to compare the HolonElements.
  410. * @return The Energy of the consuming HolonElements.
  411. */
  412. public float getEnergyNeededFromConsumingElements(int timestep) {
  413. return getElements().stream().filter(element -> element.isActive() && (element.getEnergyAtTimeStep(timestep) < 0)).map(element -> -element.getEnergyAtTimeStep(timestep)).reduce(0.0f, (a, b) -> a + b);
  414. }
  415. /**
  416. * This Method calculate the amount of HolonElements that are consuming Energy and are ACTIVE.
  417. * @param timestep is the TimeStep to compare the HolonElements.
  418. * @return The amount of HolonElements that are consuming Energy.
  419. */
  420. public int countConsumingElements(int timestep) {
  421. return (int) getElements().stream().filter(element -> element.isActive() && (element.getEnergyAtTimeStep(timestep) < 0)).count();
  422. }
  423. /**
  424. * This Method calculate the amount of HolonElements that are producing Energy and are ACTIVE.
  425. * @param timestep is the TimeStep to compare the HolonElements.
  426. * @return The amount of HolonElements that are producing Energy.
  427. */
  428. public int countProducingElements(int timestep) {
  429. return (int) getElements().stream().filter(element -> element.isActive() && (element.getEnergyAtTimeStep(timestep) > 0)).count();
  430. }
  431. /**
  432. * Get the Color.
  433. *
  434. * @return stateColor the Color
  435. */
  436. public Color getColor() {
  437. return stateColor;
  438. }
  439. /**
  440. * Set the State Color.
  441. *
  442. * @param color the Color
  443. */
  444. public void setColor(Color color) {
  445. stateColor = color;
  446. }
  447. /**
  448. * Get the Array Production
  449. */
  450. public float[] getTrackingProd() {
  451. return this.trackingProd;
  452. }
  453. /**
  454. * Set the Array Production
  455. */
  456. public void setTrackingProd(float[] arr) {
  457. this.trackingProd = arr;
  458. }
  459. /**
  460. * Get the Array Consumption
  461. */
  462. public float[] getTrackingCons() {
  463. return this.trackingCons;
  464. }
  465. /**
  466. * Set the Array Consumption
  467. */
  468. public void setTrackingCons(float[] arr) {
  469. this.trackingCons = arr;
  470. }
  471. /**
  472. * Get the Array Consumption
  473. */
  474. public float getTotalFlex() {
  475. return totalFlex;
  476. }
  477. /**
  478. * Set the Array Consumption
  479. */
  480. public void setTotalFlex(float totalFlex) {
  481. this.totalFlex = totalFlex;
  482. }
  483. /**
  484. * Update the totalFlex
  485. */
  486. public void updateTotalFlex() {
  487. float tempFlex = 0;
  488. for (HolonElement e : getElements()) {
  489. if (e.isFlexible()) {
  490. tempFlex += e.getFlexibleEnergyAvailablePerElement() * e.getAmount();
  491. }
  492. }
  493. this.totalFlex = tempFlex;
  494. }
  495. /**
  496. * calculates total flexible Production
  497. */
  498. public float getFlexProd() {
  499. float tempFlex = 0;
  500. for (HolonElement e : getElements()) {
  501. if (e.getFlexibleEnergyAvailablePerElement() > 0) {
  502. tempFlex += e.getFlexibleEnergyAvailablePerElement() * e.getAmount();
  503. }
  504. }
  505. return tempFlex;
  506. }
  507. /**
  508. * calculates total flexible Concumption
  509. */
  510. public float getFlexCons() {
  511. float tempFlex = 0;
  512. for (HolonElement e : getElements()) {
  513. if (e.getFlexibleEnergyAvailablePerElement() < 0) {
  514. tempFlex += e.getFlexibleEnergyAvailablePerElement() * e.getAmount();
  515. }
  516. }
  517. return tempFlex;
  518. }
  519. /**
  520. * If the user track any HolonObject the tracking information will be
  521. * updated. (If the HolonObject enters into the untracked state, the array
  522. * will be reseted)
  523. */
  524. public void updateTrackingInfo() {
  525. float[] tempProd = new float[100];
  526. float[] tempCons = new float[100];
  527. for (int i = 0; i < 100; i++) {
  528. float valueProd = 0;
  529. float valueCons = 0;
  530. for (HolonElement e : getElements()) {
  531. if (e.isActive() && e.isProducer()) {
  532. valueProd += e.getOverallEnergyAtTimeStep(i);
  533. }
  534. if (e.isActive() && e.isConsumer()) {
  535. valueCons += e.getOverallEnergyAtTimeStep(i);
  536. }
  537. }
  538. tempProd[i] = valueProd;
  539. tempCons[i] = valueCons;
  540. }
  541. this.trackingProd = tempProd;
  542. this.trackingCons = tempCons;
  543. }
  544. public String toString() {
  545. StringBuilder sb = new StringBuilder();
  546. sb.append("[HolonObject: ");
  547. sb.append("id=").append(id)
  548. .append(", name=").append(name)
  549. .append(", state=");
  550. switch (state) {
  551. case NO_ENERGY:
  552. sb.append("NO_ENERGY");
  553. break;
  554. case NOT_SUPPLIED:
  555. sb.append("NOT_SUPPLIED");
  556. break;
  557. case SUPPLIED:
  558. sb.append("SUPPLIED");
  559. break;
  560. case PRODUCER:
  561. sb.append("PRODUCER");
  562. break;
  563. case PARTIALLY_SUPPLIED:
  564. sb.append("PARTIALLY_SUPPLIED");
  565. break;
  566. case OVER_SUPPLIED:
  567. sb.append("OVER_SUPPLIED");
  568. break;
  569. }
  570. sb.append(", elements=[");
  571. for (int i = 0; i < getElements().size(); i++) {
  572. HolonElement el = getElements().get(i);
  573. if (i != 0) {
  574. sb.append(", ");
  575. }
  576. sb.append(el.getEleName());
  577. }
  578. sb.append("]]");
  579. return sb.toString();
  580. }
  581. /**
  582. * @return the {@link #currentSupply}
  583. */
  584. public float getCurrentSupply() {
  585. return currentSupply;
  586. }
  587. /**
  588. * @param currentSupply the {@link #currentSupply} to set
  589. */
  590. public void setCurrentSupply(float currentSupply) {
  591. this.currentSupply = currentSupply;
  592. }
  593. /**
  594. * @return {@link #suppliedPercentage}
  595. */
  596. public float getSuppliedPercentage(){
  597. return suppliedPercentage;
  598. }
  599. }