berlin_vbb_updates.lua 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. -- SPDX-FileCopyrightText: Adam Evyčędo
  2. --
  3. -- SPDX-License-Identifier: AGPL-3.0-or-later
  4. ---@diagnostic disable-next-line: unused-local, lowercase-global
  5. function getUpdates(tripID, sequence, stopID, stopCode)
  6. local http = require("http")
  7. local json = require("json")
  8. local error_struct = {
  9. httpResponseCode = 0,
  10. message = "",
  11. willNextRequestFail = false
  12. }
  13. local platform = ""
  14. local dhid = ""
  15. local i = 0
  16. for m in string.gmatch(stopCode, "([^_]+)") do
  17. if i == 0 then
  18. dhid = m
  19. end
  20. if i == 1 then
  21. platform = m
  22. break
  23. end
  24. i = i + 1
  25. end
  26. local ibnr = ""
  27. i = 0
  28. for m in string.gmatch(dhid, "([^:]+)") do
  29. if i == 2 then
  30. ibnr = m
  31. break
  32. end
  33. i = i + 1
  34. end
  35. local response, error_message = http.get("https://v6.vbb.transport.rest/stops/" .. ibnr .. "/departures", {
  36. query = "duration=60&results=144&pretty=false",
  37. timeout = "30s"
  38. })
  39. if response == nil then
  40. error_struct.message = "while getting updates: " .. error_message
  41. local error_json, _ = json.encode(error_struct)
  42. return "", error_json
  43. end
  44. if response.status_code ~= 200 then
  45. error_struct.message = "api returned code " .. response.status_code .. "; " .. response.body
  46. error_struct.httpResponseCode = response.status_code
  47. error_struct.willNextRequestFail = true
  48. local error_json, _ = json.encode(error_struct)
  49. return "", error_json
  50. end
  51. ---@diagnostic disable-next-line: redefined-local
  52. local struct, error_message = json.decode(response.body)
  53. if struct == nil then
  54. error_struct.message = "while decoding updates: " .. error_message
  55. local error_json, _ = json.encode(error_struct)
  56. return "", error_json
  57. end
  58. local updates = {
  59. areTripsInTimetable = false,
  60. updates = {},
  61. alerts = {}
  62. }
  63. updates.updates[''] = {
  64. time = "000000",
  65. stopID = stopCode,
  66. delay = 0,
  67. timetableRelationship = 1,
  68. vehicleStatus = {
  69. lineName = "",
  70. headsign = ""
  71. }
  72. }
  73. updates.alerts[''] = { {
  74. timeRanges = {
  75. { startDate = '0001-01-01T00:00:00.000Z', endDate = '9999-12-31T23:59:59.999Z' }
  76. },
  77. headers = {
  78. und = ''
  79. },
  80. descriptions = {
  81. und = ''
  82. },
  83. urls = {
  84. und = ''
  85. },
  86. cause = 0,
  87. effect = 0
  88. } }
  89. for _, entry in ipairs(struct.departures) do
  90. local stationIBNR = ""
  91. i = 0
  92. for m in string.gmatch(entry.stop.stationDHID, "([^:]+)") do
  93. if i == 2 then
  94. stationIBNR = m
  95. break
  96. end
  97. i = i + 1
  98. end
  99. if stationIBNR == ibnr and entry.platform == platform then
  100. updates.updates[entry.tripId] = {
  101. time = string.sub(entry.when, 12, 13) .. string.sub(entry.when, 15, 16) .. string.sub(entry.when, 18, 19),
  102. stopID = stopCode,
  103. delay = entry.delay,
  104. timetableRelationship = 1,
  105. vehicleStatus = {
  106. lineName = entry.line.name,
  107. headsign = entry.destination.name,
  108. }
  109. }
  110. local j = 1
  111. for _, remark in ipairs(entry.remarks) do
  112. if remark.type == 'warning' then
  113. if updates.alerts[entry.tripId] == nil then
  114. updates.alerts[entry.tripId] = {}
  115. end
  116. updates.alerts[entry.tripId][j] = {
  117. timeRanges = {
  118. {
  119. startDate = string.sub(remark.validFrom, 1, 19) .. '.000' .. string.sub(remark.validFrom, 20, 25),
  120. endDate = string.sub(remark.validUntil, 1, 19) .. '.000' .. string.sub(remark.validUntil, 20, 25)
  121. }
  122. },
  123. headers = {
  124. und = remark.summary
  125. },
  126. descriptions = {
  127. und = remark.text
  128. }
  129. }
  130. j = j + 1
  131. end
  132. end
  133. if entry.currentTripPosition ~= nil then
  134. updates.updates[entry.tripId].vehicleStatus.latitude = entry.currentTripPosition.latitude
  135. updates.updates[entry.tripId].vehicleStatus.longitude = entry.currentTripPosition.longitude
  136. end
  137. end
  138. end
  139. ---@diagnostic disable-next-line: redefined-local
  140. local result, error_message = json.encode(updates)
  141. if result == nil then
  142. error_struct.message = "while encoding result: " .. error_message
  143. local error_json, _ = json.encode(error_struct)
  144. return "", error_json
  145. end
  146. return result, ""
  147. end