asyncapi: '2.0.0' info: title: Digitransit MQTT High frequency positioning version: '1.0.0' contact: name: Digitransit url: 'https://digitransit.fi/en/developers' description: "GTFS-R data on Flightradar's flight data" servers: mqtts: url: 'mqtts://mqtt.hsl.fi:8883' protocol: secure-mqtt description: "The bare MQTT protocol with TLS, lightweight." wss: url: 'wss://mqtt.hsl.fi:443/' protocol: wss description: "MQTT over WebSockets with TLS, for browsers." mqtt: url: 'mqtt://mqtt.hsl.fi:1883' protocol: mqtt description: "The bare MQTT protocol without TLS, lightweight. Prefer the port 8883 to respect the locational privacy of your users." ws: url: 'ws://mqtt.hsl.fi:1883/' protocol: ws description: "MQTT over WebSockets without TLS. Prefer the port 443 to respect the locational privacy of your users." defaultContentType: application/json channels: '{prefix}/{version}/{journeyType}/{temporalType}/{eventType}/{transportMode}/{operatorId}/{vehicleNumber}/{routeId}/{directionId}/{headsign}/{startTime}/{nextStop}/{geohashLevel}/{geohash}/{sid}/#': subscribe: summary: Vehicle and journey information operationId: receiveVehicleUpdate message: $ref: '#/components/messages/vp' parameters: prefix: $ref: '#/components/parameters/prefix' version: $ref: '#/components/parameters/version' journeyType: $ref: '#/components/parameters/journeyType' temporalType: $ref: '#/components/parameters/temporalType' eventType: $ref: '#/components/parameters/eventType' transportMode: $ref: '#/components/parameters/transportMode' operatorId: $ref: '#/components/parameters/operatorId' vehicleNumber: $ref: '#/components/parameters/vehicleNumber' routeId: $ref: '#/components/parameters/routeId' directionId: $ref: '#/components/parameters/directionId' headsign: $ref: '#/components/parameters/headsign' startTime: $ref: '#/components/parameters/startTime' nextStop: $ref: '#/components/parameters/nextStop' geohashLevel: $ref: '#/components/parameters/geohashLevel' geohash: $ref: '#/components/parameters/geohash' sid: $ref: '#/components/parameters/sid' components: messages: vp: name: vp title: Vehicle position payload: type: object properties: $ref: "#/components/schemas/desi" $ref: "#/components/schemas/dir" $ref: "#/components/schemas/oper" $ref: "#/components/schemas/veh" $ref: "#/components/schemas/tst" $ref: "#/components/schemas/tsi" $ref: "#/components/schemas/spd" $ref: "#/components/schemas/hdg" $ref: "#/components/schemas/lat" $ref: "#/components/schemas/long" $ref: "#/components/schemas/acc" $ref: "#/components/schemas/dl" $ref: "#/components/schemas/odo" $ref: "#/components/schemas/drst" $ref: "#/components/schemas/oday" $ref: "#/components/schemas/jrn" $ref: "#/components/schemas/line" $ref: "#/components/schemas/start" $ref: "#/components/schemas/loc" $ref: "#/components/schemas/stop" $ref: "#/components/schemas/route" $ref: "#/components/schemas/occu" $ref: "#/components/schemas/seq" $ref: "#/components/schemas/label" due: name: due title: Vehicle will soon arrive to a stop payload: type: object properties: $ref: "#/components/schemas/desi" $ref: "#/components/schemas/dir" $ref: "#/components/schemas/oper" $ref: "#/components/schemas/veh" $ref: "#/components/schemas/tst" $ref: "#/components/schemas/tsi" $ref: "#/components/schemas/spd" $ref: "#/components/schemas/hdg" $ref: "#/components/schemas/lat" $ref: "#/components/schemas/long" $ref: "#/components/schemas/acc" $ref: "#/components/schemas/dl" $ref: "#/components/schemas/odo" $ref: "#/components/schemas/drst" $ref: "#/components/schemas/oday" $ref: "#/components/schemas/jrn" $ref: "#/components/schemas/line" $ref: "#/components/schemas/start" $ref: "#/components/schemas/loc" $ref: "#/components/schemas/stop" $ref: "#/components/schemas/route" $ref: "#/components/schemas/occu" $ref: "#/components/schemas/seq" $ref: "#/components/schemas/label" arr: name: arr title: Vehicle arrives inside of a stop radius payload: type: object properties: $ref: "#/components/schemas/desi" $ref: "#/components/schemas/dir" $ref: "#/components/schemas/oper" $ref: "#/components/schemas/veh" $ref: "#/components/schemas/tst" $ref: "#/components/schemas/tsi" $ref: "#/components/schemas/spd" $ref: "#/components/schemas/hdg" $ref: "#/components/schemas/lat" $ref: "#/components/schemas/long" $ref: "#/components/schemas/acc" $ref: "#/components/schemas/dl" $ref: "#/components/schemas/odo" $ref: "#/components/schemas/drst" $ref: "#/components/schemas/oday" $ref: "#/components/schemas/jrn" $ref: "#/components/schemas/line" $ref: "#/components/schemas/start" $ref: "#/components/schemas/loc" $ref: "#/components/schemas/stop" $ref: "#/components/schemas/route" $ref: "#/components/schemas/occu" $ref: "#/components/schemas/seq" $ref: "#/components/schemas/label" dep: name: dep title: Vehicle departs from a stop and leaves the stop radius payload: type: object properties: $ref: "#/components/schemas/desi" $ref: "#/components/schemas/dir" $ref: "#/components/schemas/oper" $ref: "#/components/schemas/veh" $ref: "#/components/schemas/tst" $ref: "#/components/schemas/tsi" $ref: "#/components/schemas/spd" $ref: "#/components/schemas/hdg" $ref: "#/components/schemas/lat" $ref: "#/components/schemas/long" $ref: "#/components/schemas/acc" $ref: "#/components/schemas/dl" $ref: "#/components/schemas/odo" $ref: "#/components/schemas/drst" $ref: "#/components/schemas/oday" $ref: "#/components/schemas/jrn" $ref: "#/components/schemas/line" $ref: "#/components/schemas/start" $ref: "#/components/schemas/loc" $ref: "#/components/schemas/stop" $ref: "#/components/schemas/route" $ref: "#/components/schemas/occu" $ref: "#/components/schemas/seq" $ref: "#/components/schemas/label" ars: name: ars title: Vehicle has arrived to a stop payload: type: object properties: $ref: "#/components/schemas/desi" $ref: "#/components/schemas/dir" $ref: "#/components/schemas/oper" $ref: "#/components/schemas/veh" $ref: "#/components/schemas/tst" $ref: "#/components/schemas/tsi" $ref: "#/components/schemas/spd" $ref: "#/components/schemas/hdg" $ref: "#/components/schemas/lat" $ref: "#/components/schemas/long" $ref: "#/components/schemas/acc" $ref: "#/components/schemas/dl" $ref: "#/components/schemas/odo" $ref: "#/components/schemas/drst" $ref: "#/components/schemas/oday" $ref: "#/components/schemas/jrn" $ref: "#/components/schemas/line" $ref: "#/components/schemas/start" $ref: "#/components/schemas/loc" $ref: "#/components/schemas/stop" $ref: "#/components/schemas/route" $ref: "#/components/schemas/occu" $ref: "#/components/schemas/seq" $ref: "#/components/schemas/label" pde: name: pde title: Vehicle is ready to depart from a stop payload: type: object properties: $ref: "#/components/schemas/desi" $ref: "#/components/schemas/dir" $ref: "#/components/schemas/oper" $ref: "#/components/schemas/veh" $ref: "#/components/schemas/tst" $ref: "#/components/schemas/tsi" $ref: "#/components/schemas/spd" $ref: "#/components/schemas/hdg" $ref: "#/components/schemas/lat" $ref: "#/components/schemas/long" $ref: "#/components/schemas/acc" $ref: "#/components/schemas/dl" $ref: "#/components/schemas/odo" $ref: "#/components/schemas/drst" $ref: "#/components/schemas/oday" $ref: "#/components/schemas/jrn" $ref: "#/components/schemas/line" $ref: "#/components/schemas/start" $ref: "#/components/schemas/loc" $ref: "#/components/schemas/stop" $ref: "#/components/schemas/route" $ref: "#/components/schemas/occu" $ref: "#/components/schemas/seq" $ref: "#/components/schemas/label" pas: name: pas title: Vehicle passes through a stop without stopping payload: type: object properties: $ref: "#/components/schemas/desi" $ref: "#/components/schemas/dir" $ref: "#/components/schemas/oper" $ref: "#/components/schemas/veh" $ref: "#/components/schemas/tst" $ref: "#/components/schemas/tsi" $ref: "#/components/schemas/spd" $ref: "#/components/schemas/hdg" $ref: "#/components/schemas/lat" $ref: "#/components/schemas/long" $ref: "#/components/schemas/acc" $ref: "#/components/schemas/dl" $ref: "#/components/schemas/odo" $ref: "#/components/schemas/drst" $ref: "#/components/schemas/oday" $ref: "#/components/schemas/jrn" $ref: "#/components/schemas/line" $ref: "#/components/schemas/start" $ref: "#/components/schemas/loc" $ref: "#/components/schemas/stop" $ref: "#/components/schemas/route" $ref: "#/components/schemas/occu" $ref: "#/components/schemas/seq" $ref: "#/components/schemas/label" schemas: oper: type: integer description: 'Unique ID of the operator *running* the trip (i.e. this value can be different than the operator ID in the topic, for example if the service has been subcontracted to another operator). The unique ID does not have prefix zeroes here.' veh: type: integer description: 'Vehicle number that can be seen painted on the side of the vehicle, often next to the front door. Different operators may use overlapping vehicle numbers. Matches **vehicle_number** in the topic except without the prefix zeroes.' tst: type: string format: date-time description: "UTC timestamp with millisecond precision from the vehicle in ISO 8601 format (yyyy-MM-dd'T'HH:mm:ss.SSSZ)." tsi: type: integer description: 'Unix time in seconds from the vehicle.' spd: type: number format: float description: 'Speed of the vehicle, in meters per second (m/s).' hdg: type: integer description: 'Heading of the vehicle, in degrees (⁰) starting clockwise from geographic north. Valid values are on the closed interval [0, 360].' maximum: 360 minimum: 0 lat: type: number format: float description: 'WGS 84 latitude in degrees. **null** if location is unavailable.' long: type: number format: float description: 'WGS 84 longitude in degrees. **null** if location is unavailable.' acc: type: number format: float description: ' Acceleration (m/s^2), calculated from the speed on this and the previous message. Negative values indicate that the speed of the vehicle is decreasing.' odo: type: integer description: 'The odometer reading in meters (m) since the start of the trip. Currently the values not very reliable.' drst: type: integer enum: - 0 - 1 description: > Door status. **0** if all the doors are closed. **1** if any of the doors are open. loc: type: string description: > Location source, either **GPS**, **ODO**, **MAN** or **N/A**. * **GPS** - location is received from GPS * **ODO** - location is calculated based on odometer value * **MAN** - location is specified manually * **N/A** - location is unavailable enum: - GPS - ODO - MAN - N/A seq: type: integer description: > Sequence number of the unit when the journey is operated with a vehicle that consists of multiple units (e.g. metros, trains). Sequence number starts from 1. **Note**: **seq** is currently only available for metros. label: type: string description: 'User visible label that helps to identify the vehicle. Currently available only for Suomenlinna ferries with values being vessel names.' # Excludes da, dout,ba,bout desi: type: string description: 'Route number visible to passengers' dir: type: string description: 'Route direction of the trip. After type conversion matches direction_id in GTFS and the topic. Either "1" or "2".' enum: - '1' - '2' dl: type: integer description: 'Offset from the scheduled timetable in seconds (s). Negative values indicate lagging behind the schedule, positive values running ahead of schedule.' jrn: type: integer description: 'Internal journey descriptor, not meant to be useful for external use.' line: type: integer description: 'Internal line descriptor, not meant to be useful for external use.' start: type: string description: 'Scheduled start time of the trip, i.e. the scheduled departure time from the first stop of the trip. The format follows **HH:mm** in 24-hour local time, not the 30-hour overlapping operating days present in GTFS. Matches `start_time` in the topic.' stop: type: string description: > ID of the stop related to the event (e.g. ID of the stop where the vehicle departed from in case of `dep` event or the stop where the vehicle currently is in case of `vp` event). `null` if the event is not related to any stop. route: type: string description: 'ID of the route the vehicle is currently running on. Matches `route_id` in the topic.' occu: type: integer minimum: 0 maximum: 100 description: 'Integer describing passenger occupancy level of the vehicle. Valid values are on interval `[0, 100]`. However, currently only values used are `0` (= vehicle has space and is accepting passengers) and `100` (= vehicle is full and might not accept passengers)' # Excludes da/dout oday: type: string description: 'Operating day of the trip. The exact time when an operating day ends depends on the route. For most routes, the operating day ends at 4:30 AM on the next day. In that case, for example, the final moment of the operating day "2018-04-05" would be at 2018-04-06T04:30 local time.' # Excludes vp/da/dout;/ba/bout/vja/vjout ttar: type: string description: 'UTC timestamp of scheduled arrival time to the stop.' ttdep: type: string description: 'UTC timestamp of scheduled departure time from the stop.' # ONLY da/dout/ba/bout/vja/vjout dr-type: type: integer enum: - 0 - 1 description: > Type of the driver, either `0` or `1`. * `0` = service technician * `1` = normal driver # ONLY tlr/tla tlp-requestid: type: integer minimum: 0 maximum: 255 description: 'Traffic light priority request ID.' # ONLY tlr tlp-requesttype: type: string enum: - NORMAL - DOOR_CLOSE - DOOR_OPEN - ADVANCE tlp-prioritylevel: type: string description: 'Priority level of a traffic light priority request.' enum: - normal - high - norequest tlp-reason: type: string enum: - GLOBAL - AHEAD - LINE - PRIOEXEP description: 'Reason for not sending a traffic light priority request.' tlp-att-seq: type: integer description: 'Traffic light priority request attempt sequence number.' sid: type: integer description: 'Junction ID.' signal-groupid: type: integer description: 'Signal group (a group of traffic lights at a junction) ID.' tlp-signalgroupnbr: type: integer description: 'ID of the specific traffic light in a signal group. Possibly negative.' tlp-line-configid: type: integer description: 'ID of the line configuration in DOI' tlp-point-configid: type: integer description: 'Point configuration ID' tlp-frequency: type: integer description: 'Frequency used for traffic light prority request' tlp-protocol: type: string description: 'Protocol used for traffic light priority request.' enum: - MQTT - KAR-MQTT # ONLY tla tlp-decision: type: string description: 'Response for traffic light priority request. Either `ACK` or `NAK`.' # TLR Extras parameters: prefix: description: '/hfp/ is the root of the topic tree.' schema: type: string const: hfp version: description: 'v2 is the current version of the HFP topic and the payload format.' schema: type: string journeyType: description: > 'The type of the journey. Either **journey**, **deadrun** or **signoff**. **journey** refers to a vehicle that is running on a specific public transport journey. **deadrun** refers to a vehicle that is not on any specific route, but instead coming from a depot, for example. **signoff** is used when the vehicle PC is shut down.' schema: type: string temporalType: description: 'The status of the journey, **ongoing** or **upcoming**. **ongoing** describes a journey that is currently in operation. **upcoming** refers to the next expected journey of the same vehicle. **upcoming** messages are broadcasted shortly before the start of the next journey. One use of **upcoming** is to show the relevant vehicle to your users even before the driver has signed on to the journey that your users are interested in.' schema: type: string eventType: description: 'The event type.' schema: type: string enum: - vp - due - arr - dep - ars - pde - pas - wait - doo - doc - tlr - tla - da - dout - ba - bout - vja - vjout transportMode: description: 'The type of the vehicle.' schema: type: string enum: - bus - tram - train - ferry - metro - ubus - robot operatorId: description: 'The unique ID of the operator that owns the vehicle.' schema: type: number enum: - 0006 - 0012 - 0017 - 0018 - 0020 - 0021 - 0022 - 0030 - 0036 - 0040 - 0045 - 0047 - 0050 - 0051 - 0054 - 0055 - 0058 - 0060 - 0089 - 0090 vehicleNumber: description: 'The vehicle number that can be seen painted on the side of the vehicle, often next to the front door. Different operators may use overlapping vehicle numbers. **operator_id/vehicle_number** uniquely identifies the vehicle.' schema: type: integer pattern: ^[0-9][0-9][0-9][0-9][0-9] routeId: description: 'The ID of the route the vehicle is running on. This matches route_id in GTFS (field gtfsId of Route in the [routing API](https://digitransit.fi/en/developers/apis/1-routing-api/)).' schema: type: string directionId: description: 'The line direction of the trip, either 1 or 2.' schema: type: integer enum: - 1 - 2 headsign: description: 'The destination name, e.g. Aviapolis.' schema: type: string startTime: description: 'The scheduled start time of the trip, i.e. the scheduled departure time from the first stop of the trip. The format follows HH:mm in 24-hour local time.' schema: type: string pattern: ^([01]?[0-9]|2[0-3]):[0-5][0-9]$ nextStop: description: 'The ID of next stop or station. Updated on each departure from or passing of a stop. EOL (end of line) after final stop and empty if the vehicle is leaving HSL area. Matches stop_id in GTFS (value of gtfsId field, without HSL: prefix, in Stop type in the routing API).' schema: type: string geohashLevel: description: > The geohash level represents the magnitude of change in the GPS coordinates since the previous message from the same vehicle. More exactly, **geohash_level** is equal to the minimum of the digit positions of the most significant changed digit in the [latitude and the longitude](https://digitransit.fi/en/developers/apis/4-realtime-api/vehicle-positions/#payload) since the previous message. For example, if the previous message has value (60.12345, 25.12345) for (**lat**, **long**) and the current message has value (60.12499, 25.12388), then the third digit of the fractional part is the most significant changed digit and **geohash_level** has value **3**. However, **geohash_level** value **0** is overloaded. **geohash_level** is **0** if: the integer part of the latitude or the longitude has changed, the previous or the current message has **null** for coordinates or the non-location parts of the topic have changed, e.g. when a bus departs from a stop. By subscribing to specific geohash levels, you can reduce the amount of traffic into the client. By only subscribing to level **0** the client gets the most important status changes. The rough percentages of messages with a specific **geohash_level** value out of all **ongoing** messages are: * 3 % * 0.09 % * 0.9 % * 8 % * 43 % * 44 % schema: type: string geohash: description: > The latitude and the longitude of the vehicle. The digits of the integer parts are separated into their own level in the format **;**, e.g. **60;24**. The digits of the fractional parts are split and interleaved into a custom format so that e.g. (60.123, 24.789) becomes **60;24/17/28/39**. This format enables subscribing to specific geographic boundaries easily. If the coordinates are missing, **geohash_level** and **geohash** have the concatenated value **0////**. This geohash scheme is greatly simplified from [the original geohash scheme](https://en.wikipedia.org/wiki/Geohash) schema: type: string sid: description: 'Junction ID, corresponds to sid in the payload. Only available for tlr and tla event types, empty for other event types.' schema: type: string