atom14/tsr-feed
Composer 安装命令:
composer require atom14/tsr-feed
包简介
Get TSRs from Rail Data Marketplace
README 文档
README
A small PHP library for consuming the National Rail "NWR Temporary Speed Restrictions (TSR)" feed from the Rail Data Marketplace over Kafka.
It gives you the consuming mechanism (FeedConsumer), the connection factory (KafkaConfig), an offset tool (OffsetRewinder) and typed domain models (Tsr, RouteWon). What you do with each message is up to you: implement MessageHandler and inject it. The runnable scripts under examples/ show one end-to-end wiring.
Rail Data Marketplace
Register for an account at https://raildata.org.uk/dashboard
Add a subscription for "NWR Temporary Speed Restrictions (TSR)"
Installation
composer require atom14/tsr-feed
The library itself depends only on PHP 8.3+, longlang/phpkafka and a PSR-3 logger (psr/log). Monolog and PHPDotEnv are used by the examples/tests only, so they are dev dependencies — bring your own logger and configuration in your own project.
Library usage
Implement MessageHandler to decide what happens to each raw message, then hand it to FeedConsumer:
use Atom14\TsrFeed\FeedConsumer;
use Atom14\TsrFeed\KafkaConfig;
use Atom14\TsrFeed\Interfaces\MessageHandler;
final class MyHandler implements MessageHandler
{
public function handle(string $value): void
{
// $value is the raw JSON message. Parse it, store it, publish it...
// Throw to leave it uncommitted so it is retried on the next run.
$won = \Atom14\TsrFeed\Models\RouteWon::fromJson($value);
// ...
}
}
$kafka = new KafkaConfig($user, $password, $group, $client);
$consumer = new FeedConsumer(
$kafka,
new MyHandler(),
$logger, // any Psr\Log\LoggerInterface
'/var/run/tsr', // writable working directory for the run-lock
);
exit($consumer->run());
run() makes a single drain-and-exit pass guarded by a file lock, committing each offset only after the handler returns successfully (at-least-once). It returns a process exit code — FeedConsumer::EXIT_OK (0), EXIT_SETUP (1) or EXIT_PROCESS (2) — suitable for exit() so cron can alert on failure.
Credentials
The four credentials passed to KafkaConfig come from the RDM "Pub/Sub" tab. The examples load them from a .env file via PHPDotEnv — copy the keys from .env.sample and populate them as shown below:

Running the examples
The scripts under examples/ are reference wiring, not part of the published library. examples/consume.php uses FileMessageHandler to store each message as a separate JSON file under ./data, with progress logged to ./log:
composer run consume # php examples/consume.php
This is designed to run as a scheduled task / cron job. It only needs to run on a Friday from 6am.
Data Source and Format
The feed utilises Kafka (https://en.wikipedia.org/wiki/Apache_Kafka), "a unified, high-throughput, low-latency platform for handling real-time data feeds"
The data is provided in JSON format.
Although Kafka allows for replaying previous messages, this feed is configured to only keep them for 1 hour.
You can use "composer run seek-offset" (php examples/seek-offset.php) to validate this.
Weekly Operating Notice (WON)
The WON is issued weekly to inform interested parties of planned work over the following week. It comes out at 6am (UK time or GMT?) on a Friday.
This feed provides all the Temporary Speed Restrictions (TSRs) that are in the WON (i.e. those already in force or those coming into force during the week, see ValidFromDate).
Messages
There is a message for each route. These are saved into a date+time stamped JSON file in the ./data folder ready for further processing such as adding to a database.
Message Structure
We have provided 'model' classes for the 'won_route' and 'tsr'
TSR Item
The "Tsr" class models an individual TSR as below.
NOTE: TSRID is NOT unique! But a combination of RouteCode+TSRID should be.
{
"RouteGroupName": "Anglia",
"RouteCode": "EA1010",
"RouteOrder": "10",
"TSRReference": "T2026/232801",
"FromLocation": "Romford",
"ToLocation": "Harold Wood",
"LineName": "Down Main",
"SubunitType": "chains",
"MileageFrom": "13",
"SubunitFrom": "5",
"MileageTo": "14",
"SubunitTo": "21",
"MovingMileage": "false",
"PassengerSpeed": "50",
"FreightSpeed": "50",
"ValidFromDate": "1776830400000",
"ValidToDate": "1790740800000",
"Reason": "Track - Other",
"Requestor": "Network Rail Maintenance (Romford)",
"Comments": "EXTENDING EXISTING TSR T2025/230371 ON THE DOWN MAIN AT GIDEA PARK",
"Direction": "down",
"TSRID": "232801",
"creationDate": "1776059873000",
"publishDate": "1781244005000",
"publishEvent": "nonSpecific"
}
Won Item
The "RouteWon" class models the content of "TSRBatchMsg", the other properties do not seem useful.
{
"TSRBatchMsgV1": {
"TSRBatchMsg": {
"tsr": [ ... ],
"routeGroup": "Anglia",
"routeGroupCode": "2652",
"publishDate": "1781244005000",
"publishSource": "WON_2627_12_F",
"routeGroupCoverage": "full",
"batchPublishEvent": "publishWON",
"WONStartDate": "1781910060000",
"WONEndDate": "1782514740000"
},
"Sender": {
"organisation": "Network Rail",
"application": "HUB",
"applicationDomain": "net"
},
"Publication": {
"TopicID": "TSR/2652"
},
"classification": "industry",
"timestamp": "1781241001000",
"owner": "Network Rail",
"originMsgId": "2026-06-12T07:10:02.087+01:00-2652@PPS",
"systemEnvironmentCode": "Production"
}
}
License
This project is licensed under the MIT License. See the LICENSE file for details.
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-20