Data transfer

There are two methods of delivering SIRI data to Samtrafiken:

  • Asynchronous, publish-subscribe direct delivery. In this case, Samtrafiken initiates a subscription, after which the data provider sends continuous updates. Since the data provider can instantly push updates to Samtrafiken, this method offers the lowest latency. This means there is less delay between data being published on the provider side and data being ingested and published by Samtrafiken.

  • Synchronous fetching through polling. In this case, Samtrafiken will regularly download data from the provided URLs provided. This is easier to implement on the data-provider side, but may lead to higher latencies due to the additional wait until Samtrafikens next download.

Asynchronous: Publish/Subscribe - Direct delivery

As defined in the Nordic SIRI profile: General information SIRI | GeneralinformationSIRI Publish/Subscribe Directdelivery .

The service has been designed to continuously deliver data updates to all subscribed consumers.

All services of the publish/subscribe type must send heartbeats in accordance with the subscription-request (HeartbeatInterval), to ensure verification of service availability and operational status.

When using Direct Delivery the data is continuously streamed to all subscribers immediately after they are released into the stream. The recipient system is responsible for handling the received messages. A received message is acknowledged with a HTTP 200 "OK" success-response.

The following diagram shows the data flow in the case of asynchronous delivery. Samtrafiken is both the Requestor and the Consumer, the data provider acts as the Service.

 

bild-20241118-135350.png

Callbacks

Once samtrafiken has initiated a connection, regular updates should be delivered to the URL defined as ConsumerAddress in the subscription request. This URL changes with every new subscription. Regular heartbeats should be sent, as specified in the subscription request.

You should pay attention to the response status code sent by Samtrafiken - if the ConsumerAddress endpoints returns anything else than an HTTP 200 OK status code, the connection should be terminated.

There will only be one connection from Samtrafiken for a given datasource + data type (ET/VM/SX) at the same time. If for some reason Samtrafiken initiates a second connection, for example because the service on Samtrafikens side is restarted, the old connection may be discarded. It will be shut down automatically since Samtrafiken will no longer reply “200 OK” to incoming data on this connection.

Example subscription request (ET)

A ET subscription request from Samtrafiken looks like this

<?xml version="1.0"?> <AE:Siri xmlns:AE="http://www.siri.org.uk/siri" xmlns:AC="http://datex2.eu/schema/1_0/1_0" xmlns:AB="http://www.ifopt.org.uk/ifopt" xmlns:AD="http://www.ifopt.org.uk/acsb" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" version="2.0"> <AE:SubscriptionRequest> <AE:RequestTimestamp>yyyy-mm-ddThh:mm:ss</AE:RequestTimestamp> <!-- The current time when the request is sent --> <AE:RequestorRef>Samtrafiken</AE:RequestorRef> <!-- Requestor reference for Samtrafikens realtime system --> <AE:MessageIdentifier>Stip-realtime-import-siri:estimatedTimetableRequest:yyyy-mm-ddThh:mm:ss</AE:MessageIdentifier> <!-- An internal reference for the subscription request --> <AE:ConsumerAddress>http://siri.samtrafiken.se/2.0/et/123abc</AE:ConsumerAddress> <!-- ConsumerAddress specifies where updates should be sent to, different for each subscription --> <AE:SubscriptionContext> <AE:HeartbeatInterval>PT1M</AE:HeartbeatInterval> <!-- Heartbeat interval according to ISO8501, defining how often heartbeats should be sent. Typically between PT30S and PT2M. --> </AE:SubscriptionContext> <AE:EstimatedTimetableSubscriptionRequest> <!-- The request, which depends on the requested data type. In this case ET data is requested. --> <AE:SubscriberRef>Samtrafiken</AE:SubscriberRef> <AE:SubscriptionIdentifier>OPERATOR-CODE</AE:SubscriptionIdentifier> <!-- Used to distinguish between data sources --> <AE:InitialTerminationTime>9999-12-31T23:59:59.999</AE:InitialTerminationTime> <!-- Infinitly long in the future, the subscription should not terminate itself --> <AE:EstimatedTimetableRequest version="2.0"> <AE:RequestTimestamp>yyyy-mm-ddThh:mm:ss</AE:RequestTimestamp> <!-- The current timestamp--> <AE:PreviewInterval>PT24H</AE:PreviewInterval> <!-- For which interval data is requested, for example 24h into the future --> </AE:EstimatedTimetableRequest> <AE:IncrementalUpdates>false</AE:IncrementalUpdates> <!-- False, Samtrafiken currently requests the complete dataset in each message --> <AE:ChangeBeforeUpdates>PT15S</AE:ChangeBeforeUpdates> <!-- 15s providers can collect data for 15s before sending --> </AE:EstimatedTimetableSubscriptionRequest> </AE:SubscriptionRequest> </AE:Siri>

Example subscription request (SX)

An SX subscription request from Samtrafiken looks like this

<?xml version="1.0"?> <AE:Siri xmlns:AE="http://www.siri.org.uk/siri" xmlns:AC="http://datex2.eu/schema/1_0/1_0" xmlns:AB="http://www.ifopt.org.uk/ifopt" xmlns:AD="http://www.ifopt.org.uk/acsb" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" version="2.0"> <AE:SubscriptionRequest> <AE:RequestTimestamp>yyyy-mm-ddThh:mm:ss</AE:RequestTimestamp> <!-- now --> <AE:RequestorRef>Samtrafiken</AE:RequestorRef> <!-- Requestor reference for Samtrafikens realtime system --> <AE:MessageIdentifier>Stip-realtime-import-siri:situationExchangeRequest:yyyy-mm-ddThh:mm:ss</AE:MessageIdentifier> <!-- An internal reference for the subscription request --> <AE:ConsumerAddress>http://siri.samtrafiken.se/2.0/sx/123abc</AE:ConsumerAddress> <!-- ConsumerAddress specifies where updates should be sent to, different for each subscription --> <AE:SubscriptionContext> <AE:HeartbeatInterval>PT1M</AE:HeartbeatInterval> <!-- Heartbeat interval according to ISO8501, defining how often heartbeats should be sent. Typically between PT30S and PT2M. --> </AE:SubscriptionContext> <AE:SituationExchangeSubscriptionRequest> <!-- The request, which depends on the requested data type. In this case SX data is requested. --> <AE:SubscriberRef>Samtrafiken</AE:SubscriberRef> <AE:SubscriptionIdentifier>OPERATOR-CODE</AE:SubscriptionIdentifier> <!-- Used to distinguish between data sources --> <AE:InitialTerminationTime>9999-12-31T23:59:59.999</AE:InitialTerminationTime> <!-- Infinitly long in the future, the subscription should not terminate itself --> <AE:EstimatedTimetableRequest version="2.0"> <AE:RequestTimestamp>yyyy-mm-ddThh:mm:ss</AE:RequestTimestamp> <!-- now--> <AE:PreviewInterval>PT1Y</AE:PreviewInterval> <!-- Request data for up to 1 year in the future --> </AE:EstimatedTimetableRequest> <AE:IncrementalUpdates>false</AE:IncrementalUpdates> <!-- False, Samtrafiken currently requests the complete dataset in each message --> </AE:SituationExchangeSubscriptionRequest> </AE:SubscriptionRequest> </AE:Siri>

Example subscription request (VM)

A VM subscription request from Samtrafiken looks like this

<?xmlversion="1.0"?> <AA:Siri xmlns:AA="http://www.siri.org.uk/siri" version="2.0"> <AA:SubscriptionRequest> <AA:RequestTimestamp>yyyy-mm-ddThh:mm:ss</AE:RequestTimestamp> <!-- now --> <AA:RequestorRef>Samtrafiken</AE:RequestorRef> <!-- Samtrafikens requestor reference --> <AA:MessageIdentifier>MessageIdentifier</AA:MessageIdentifier> <AE:ConsumerAddress>http://siri.samtrafiken.se/2.0/vm/123abc</AE:ConsumerAddress> <!-- ConsumerAddress specifies where updates should be sent to, different for each subscription --> <AA:SubscriptionContext> <AE:HeartbeatInterval>PT1M</AE:HeartbeatInterval> <!-- Heartbeat interval according to ISO8501, defining how often heartbeats should be sent. Typically between PT30S and PT2M. --> </AA:SubscriptionContext> <AA:VehicleMonitoringSubscriptionRequest> <AE:SubscriberRef>Samtrafiken</AE:SubscriberRef> <AE:SubscriptionIdentifier>OPERATOR-CODE</AE:SubscriptionIdentifier> <!-- Used to distinguish between data sources --> <AE:InitialTerminationTime>9999-12-31T23:59:59.999</AE:InitialTerminationTime> <!-- Infinitly long in the future, the subscription should not terminate itself --> <AA:VehicleMonitoringRequest version="2.0"> <AE:RequestTimestamp>yyyy-mm-ddThh:mm:ss</AE:RequestTimestamp> <!-- now --> </AA:VehicleMonitoringRequest> </AA:VehicleMonitoringSubscriptionRequest> </AA:SubscriptionRequest> </AA:Siri>

Synchronous: Request / Response

Explicit fetching of datasets based on service type.

The service will be designed to deliver data per request, in accordance with the requestors filtering criteria (included in the fetch request).

The following diagram shows the data flow in the case of synchronous delivery. Samtrafiken is the consumer in this case, while the data provider is the producer.

bild-20241118-140651.png

Requests are made as HTTP 1.1 GET requests to the to Samtrafiken provided URLs. No specific headers or authorization should be required, all parameters should be in the URL. Samtrafiken will poll the provided URLs at an interval it deems suited to balance system load with sufficient data updates, e.g. once every second for vehicle positions but only once every 15 seconds for estimated timetable updates.

Your endpoint through which you provide the data should support HTTPS and have a valid SSL certificate.