Decoding S-Class Data
S-Class data is delivered as a large bit map. The number of bits varies depending on the complexity of the area covered by the describer. All my work has been on the new M1 describer in Liverpool, where the S-Class data consists of just 8 bytes or 64 bits, but some describers have a much wider range.
It is important to realise that although the S-Class messages provide the data in bytes, each byte contains 8 bits and these may refer to 8 independent pieces of signalling equipment. For example, on receipt of a message with address 02 and data e8 you need to break the e8 down into a bit map - 11101000 in this case - and then deal with the eight different values.
We need a way of labelling the bits for the purposes of documentation. I don't know how the signalling engineers do this (Anyone??) so for the time being I will number the bits of each byte from 0 to 7 with 0 being the LSB, and then append this to the address. Thus the data from the M1 describer runs from 00 0 to 07 7
Understanding the TD Data
To make use of the full TD data stream we need two things:
- A track diagram showing the location of all signals and their numbers. If you know someone on the railway they might let you see what is known as a "Yellow Peril", if not then a rover ticket and a notepad will allow you draw your own. With just this, you can now understand all the C-Class messages, and can watch trains moving about the system. You will soon notice that the berth number is closely related to the signal number - in my area berth 3585 is on the approach side of signal LL3585.
- Next, we need a list of all the signalling bits and what they mean. Again, a friend on the railway might be able to help you but if not, the information can, with a bit of effort, be deduced from the data feed, and that is what the main part of this page is about.
Deducing The S-Class Decode
Warning: So far I have only worked on the M1 describer, so it may turn out that some of my assumptions do not apply to other describers. I hope you'll let us know!
Before we start, we need a couple of things. Firstly, a track diagram showing all signals and their numbers. I'm afraid there's no substitute for this, and if you haven't got one it's time to get out with a rover ticket. Secondly, obviously, we need access to the data feed from the describer. You can develop your own software or use someone else's - Mine is open source at https://github.com/philwieland/openrail.
It is important that the software logs the messages received in some kind of human readable format. This is no use for driving a real time signalling diagram but it's essential for the decoding operation, unless you're the kind of person who can see e8 change to c8 and immediately know that bit 5 has cleared.
Here's an example of the log produced by my system:
25/08/14 15:16:33Z ] (Timestamp 25/08/14 15:16:32Z) SF: 02 = fd [fe fe fd 13 00 67 09 00] 25/08/14 15:16:55Z ] (Timestamp 25/08/14 15:16:54Z) CA: 2F39 from 3581 to 3585 25/08/14 15:16:55Z ] (Timestamp 25/08/14 15:16:55Z) SF: 01 = fa [fe fa fd 13 00 67 09 00] Bit 01 2 = 0 25/08/14 15:17:02Z ] (Timestamp 25/08/14 15:17:02Z) CA: 1E76 from E300 to E298 25/08/14 15:17:04Z ] (Timestamp 25/08/14 15:17:03Z) CA: 2F52 from 3754 to 3750 25/08/14 15:17:04Z ] (Timestamp 25/08/14 15:17:03Z) SF: 03 = 11 [fe fa fd 11 00 67 09 00] Bit 03 1 = 0 25/08/14 15:17:09Z ] (Timestamp 25/08/14 15:17:09Z) SF: 01 = fb [fe fb fd 11 00 67 09 00] Bit 01 0 = 1 25/08/14 15:17:10Z ] (Timestamp 25/08/14 15:17:09Z) SF: 00 = fe [fe fb fd 11 00 67 09 00] 25/08/14 15:17:13Z ] (Timestamp 25/08/14 15:17:12Z) CA: 2F67 from 5583 to 3593 25/08/14 15:17:14Z ] (Timestamp 25/08/14 15:17:13Z) SF: 03 = 01 [fe fb fd 01 00 67 09 00] Bit 03 4 = 0
As you can see, we have the system time followed by the timestamp extracted from the message and then the message name. On the second line is a CA message showing train 2F39 moving from berth 3581 to berth 3585. On the third line we have an SF message setting address 01 to value fa. Then in square brackets is a list of all the signalling bytes. Finally, the software appends a list of the bits that have changed - You can see by comparing lines 1 and 3 that address 01 has changed from fe to fa (11111110 to 11111010), thus in my numbering scheme address 01 bit 2 has changed to 0 so we say Bit 01 2 = 0.
Breaking The Code - Part I
(I'm beginning to feel like I should be in Bletchley Park!)
Now comes the simple but tedious part!
In the log extract above you can see on line 2 that 2F39 has moved from 3581 to 3585, thereby passing signal 3581 (Don't forget, the berth is on the approach side of the signal.) so we would expect that signal to go red. There on line 3 of the log, just one second later, we see Bit 01 2 changing to 0. Maybe that's it. What you have to do now is trawl through the log file for other occasions of a train moving from 3581 to 3585 and see if the same change occurs. If it does then we've probably cracked it. As a check, see if you can find any place where a train makes this move but bit 01 2 was already 0. If you can then we might be wrong after all.
In area M1 I only get one bit per signal, with 0 for red and 1 for everything else ("Off"), it might be different in your area.
Repeat the above process for every possible berth move and before you know it you've got every signal nailed down. Well, almost every signal - If there are any rarely used reversing facilities you'll just have to wait until a train uses them - It took a couple of months for me to capture the last signal on M1.
You'll notice I've only talked about the bit changing to zero (red). This is because a change the other way can happen for many reasons (Signalman clicks his mouse, train clears the overlap of the signal ahead, etc. etc.) and so it's harder to correlate the change with a berth movement.
Breaking The Code - Part II
That's the easy part over, now comes the route settings.
Route setting bits are set to indicate that a particular route has been selected by the signalman, where trains can be signalled to different routes. (They are not the same as point states which some describers provide, but not M1.) Where trains can be signalled in one of two ways there will be two signalling bits, one for each option. They might not be adjacent in the bitmap, nor even in the same byte. Both at 0 means that neither route has been selected, and both set to 1 indicates that you've probably got your decode wrong!
Deducing these is a little more difficult than deducing the signals, as they may be set up well in advance. They may not clear every time a train passes, but they often do and you should be able to find a correlation.
Out Of Area Berths
In the fourth line of the log extract above, you can see 1E76 moving from berth E300 to berth E298. These are berths in the area controlled by Edge Hill box and are provided in this describer so that the signaller has advance warning of approaching trains. There are no signals corresponding to these in our describer feed. (It is left as an exercise for the reader, to decode the Edge Hill feed and fill in these missing signals!)
When you've worked out your decode, please share it on the wiki.
|Network Rail Open Data Feeds|
|Data Feeds||About the Feeds • Account States • Durable Subscriptions • Example Code ( PHP / C# / Java / Ruby / Node.js) • Advanced Uses • FAQ • Release Notes|
|Train Movements||Train Movements Feed • Train Activation • Train Cancellation • Train Movement • Train Reinstatement • Change of Origin • Change of Identity • Change of Location • TSPEED Field • Planned Cancellations • Cancellation Codes|
|TD||TD Feed • C-Class Messages • S-Class Messages • Train Describers • TD Berths|
|TSR||TSR Feed • Route Codes|
|SCHEDULE||SCHEDULE Feed • Schedule and Location Records • Association Records • CIF Codes • How Scheduling Works • Allowances|
|Reference Data||Reference Data Feed • TOC Codes • CIF Codes • Delay Attribution Codes • Identifying Locations (STANOX, TIPLOC, NLC and 3-Alpha Codes) • STANOX Geographical Areas • Train Planning data|