Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

HafasFetcher.js 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. "use strict";
  2. const moment = require("moment");
  3. const createClient = require("hafas-client");
  4. const arrayDiff = require("arr-diff");
  5. module.exports = class HafasFetcher {
  6. /**
  7. *
  8. * @param config The configuration used for this fetcher. It has the following format:
  9. * config = {
  10. * identifier: *a string identifying this fetcher, must be unique for all instances of the module*
  11. * hafasProfile: *a valid hafas-client profile name*,
  12. * stationID: *a valid station id*,
  13. * timeToStation: *an integer describing how long it takes to get to the station (in minutes)*,
  14. * timeInFuture: *an integer describing how far in the future the departure can lie*
  15. * direction: *an array of station ids*,
  16. * ignoredLines: *an array of line names which are to be ignored*,
  17. * excludedTransportationTypes: *an array of product names which are not to be shown*,
  18. * maxReachableDepartures: *an integer describing how many departures should be fetched*,
  19. * maxUnreachableDepartures: *an integer describing how many unreachable departures should be fetched*
  20. * }
  21. */
  22. constructor(config) {
  23. this.leadTime = 40; // minutes
  24. this.config = config;
  25. const profile = require("hafas-client/p/" + this.config.hafasProfile);
  26. this.hafasClient = createClient(profile, 'MMM-PublicTransportHafas');
  27. // types given by the api
  28. this.possibleTypes = [
  29. "bus",
  30. "ferry",
  31. "express",
  32. "national",
  33. "nationalExpress",
  34. "regional",
  35. "suburban",
  36. "subway",
  37. "tram",
  38. "taxi",
  39. // for SVV
  40. "bahn-s-bahn",
  41. "u-bahn",
  42. "strassenbahn",
  43. "fernbus",
  44. "regionalbus",
  45. "stadtbus",
  46. "seilbahn-zahnradbahn",
  47. "schiff",
  48. // for SBB
  49. "express-train",
  50. "international-train",
  51. "interregional-train",
  52. "regional-express-train",
  53. "watercraft",
  54. "suburban-train",
  55. "bus-taxi",
  56. "gondola",
  57. "car-train",
  58. ];
  59. this.config.includedTransportationTypes = arrayDiff(this.possibleTypes, this.config.excludedTransportationTypes);
  60. }
  61. getIdentifier() {
  62. return this.config.identifier;
  63. }
  64. getStationID() {
  65. return this.config.stationID;
  66. }
  67. fetchDepartures() {
  68. let options = {
  69. when: this.getDepartureTime(),
  70. direction: this.config.direction,
  71. duration: this.config.timeInFuture
  72. };
  73. return this.hafasClient.departures(this.config.stationID, options)
  74. .then((departures) => {
  75. let maxElements = this.config.maxReachableDepartures + this.config.maxUnreachableDepartures;
  76. let filteredDepartures = this.filterByTransportationTypes(departures);
  77. filteredDepartures = this.filterByIgnoredLines(filteredDepartures);
  78. filteredDepartures = this.departuresMarkedWithReachability(filteredDepartures);
  79. filteredDepartures = this.departuresRemovedSurplusUnreachableDepartures(filteredDepartures);
  80. filteredDepartures = filteredDepartures.slice(0, maxElements);
  81. return filteredDepartures;
  82. }).catch((e) => {
  83. throw e;
  84. });
  85. }
  86. getDepartureTime() {
  87. let departureTime = this.getReachableTime();
  88. if (this.config.maxUnreachableDepartures > 0) {
  89. departureTime = moment(departureTime).subtract(this.leadTime, "minutes");
  90. }
  91. return departureTime;
  92. }
  93. getReachableTime() {
  94. return moment().add(this.config.timeToStation, "minutes");
  95. }
  96. filterByTransportationTypes(departures) {
  97. return departures.filter((departure) => {
  98. let product = departure.line.product;
  99. let index = this.config.includedTransportationTypes.indexOf(product);
  100. return index !== -1;
  101. });
  102. }
  103. filterByIgnoredLines(departures) {
  104. return departures.filter((departure) => {
  105. let line = departure.line.name;
  106. let index = this.config.ignoredLines.indexOf(line);
  107. return index === -1;
  108. });
  109. }
  110. departuresMarkedWithReachability(departures) {
  111. return departures.map((departure) => {
  112. departure.isReachable = this.isReachable(departure);
  113. return departure;
  114. });
  115. }
  116. departuresRemovedSurplusUnreachableDepartures(departures) {
  117. let unreachableDeparturesCount = departures.filter(departure => !departure.isReachable).length;
  118. let result = departures;
  119. if (unreachableDeparturesCount > this.config.maxUnreachableDepartures) {
  120. let toBeRemoved = unreachableDeparturesCount - this.config.maxUnreachableDepartures;
  121. for (let i = 0; i < toBeRemoved; i++) {
  122. result.shift();
  123. }
  124. }
  125. return result;
  126. }
  127. isReachable(departure) {
  128. return moment(departure.when).isSameOrAfter(moment(this.getReachableTime()));
  129. }
  130. };