Counting Planes with PHP
Tim Bond
October 23, 2025
Longhorn PHP Lightning Talks
This talk is as much about radios and airplanes as it is about PHP

- Automatic
- Dependent
- Surveillance
- Broadcast
ADS-B
- dump1090 exposes a TCP server
- data is streamed in SBS-1 format
- Try watching from the command line:
netcat 192.168.1.pi 30003
- Not a traditional HTTP request/response
Streaming data
Typical HTTP Request/Response
Open connection
Connected
<!DOCTYPE ...
Close connection
GET /index.html
Streaming
Open connection
Connected
data
🕐
data
MSG,4,5,211,4CA2D6,10057,2008/11/28,14:53:49.986,2008/11/28,14:58:51.153,,,408.3,146.4,,,64,,,,,
MSG,8,5,211,4CA2D6,10057,2008/11/28,14:53:50.391,2008/11/28,14:58:51.153,,,,,,,,,,,,0
MSG,4,5,211,4CA2D6,10057,2008/11/28,14:53:50.391,2008/11/28,14:58:51.153,,,408.3,146.4,,,64,,,,,
MSG,3,5,211,4CA2D6,10057,2008/11/28,14:53:50.594,2008/11/28,14:58:51.153,,37000,,,51.45735,-1.02826,,,0,0,0,0
MSG,8,5,812,ABBEE3,10095,2008/11/28,14:53:50.594,2008/11/28,14:58:51.153,,,,,,,,,,,,0
MSG,3,5,276,4010E9,10088,2008/11/28,14:53:49.986,2008/11/28,14:58:51.153,,28000,,,53.02551,-2.91389,,,0,0,0,0
MSG,4,5,276,4010E9,10088,2008/11/28,14:53:50.188,2008/11/28,14:58:51.153,,,459.4,20.2,,,64,,,,,
MSG,8,5,276,4010E9,10088,2008/11/28,14:53:50.594,2008/11/28,14:58:51.153,,,,,,,,,,,,0
MSG,3,5,276,4010E9,10088,2008/11/28,14:53:50.594,2008/11/28,14:58:51.153,,28000,,,53.02677,-2.91310,,,0,0,0,0
MSG,4,5,769,4CA2CB,10061,2008/11/28,14:53:50.188,2008/11/28,14:58:51.153,,,367.7,138.6,,,-2432,,,,,
MSG,8,5,769,4CA2CB,10061,2008/11/28,14:53:50.391,2008/11/28,14:58:51.153,,,,,,,,,,,,0
MSG,1,1,256,7404F2,11267,2008/11/28,14:58:18.611,2008/11/28,14:58:19.161,RJA1118,,,,,,,,,,,
MSG,2,4,603,400CB6,13168,2008/10/13,14:58:32.414,2008/11/28,14:58:52.074,,,0,6.4,58.3,54.05735,-4.38826,,,,,,0
MSG,3,4,211,4CA2D6,10057,2008/11/28,14:58:50.594,2008/11/28,14:58:51.153,,37000,,,51.45735,-1.02826,,,0,0,0,0
MSG,4,4,469,4CA767,27854,2008/11/28,17:58:13.039,2008/11/28,17:58:13.368,,,288.6,103.2,,,-832,,,,,
MSG,5,4,329,394A65,27868,2008/11/28,17:58:12.644,2008/11/28,17:58:13.368,,10000,,,,,,,0,,0,0
MSG,6,4,237,4CA215,27864,2008/11/28,17:58:12.846,2008/11/28,17:58:13.368,,33325,,,,,,0271,0,0,0,0
MSG,7,4,742,51106E,27929,2008/11/28,17:58:36.523,2008/11/28,17:58:37.054,,3775,,,,,,,,,,0
MSG,8,4,194,405F4E,27884,2008/11/28,17:58:13.244,2008/11/28,17:58:13.368,,,,,,,,,,,,0- Unique Identifier
- Altitude
- Speed
- Vertical
- Ground
- Track (heading)
- Latitude/Longitude
- Squawk Code
What's in a message?
Between 0.1 - 2 Hz
- 24 bit hex code
AA0EE3 - NOT the tail number
- Store the hex code, look up the aircraft later
- We can get a database that has:
- Hex code
- Registration (tail number)
- Model
- Type code
- More
Each Plane's Unique ID
- Can't use file_get_contents or curl
- Use built-in PHP stream methods (or PSR-7)
Drink From The Firehose
$handle = stream_socket_client('tcp://192.168.1.pi:30003');
while(($buffer = fgets($stream)) !== false) {
echo $buffer;
}MSG,4,5,211,4CA2D6,10057,2008/11/28,14:53:49.986,2008/11/28,14:58:51.153,,,408.3,146.4,,,64,,,,,- DIY or PIE?
afk11/sbs1
Parse Each Message
$streamReader = new StreamReader();
$redis = new Redis();
foreach(
$streamReader->readTcpStream(
lineReader: $lineReader,
host: '192.168.1.pi',
port: 30003
) as $line) {
if(
$line->getMessageType()->getId() === MessageType::MSG
&& $line->getHexIdent()
) {
// do something with the hex code
}
}
- Hash - works the same as a PHP array
- Key is the hex code
-
Value could be nothing, or anything
- We'll store the number of messages we've seen
Store The Data in Redis
HINCRBY adsb:planes:2025-10-23 AA0EE3 1
$redis->HINCRBY(
key: 'adsb:planes:' . date('Y-m-d'),
field: $line->getHexIdent(),
value: 1,
);
Put It All Together
<?php
$lineReader = new LineReader(
new MessageTypeRegistryFactory()->create(),
new TransmissionTypeRegistryFactory()->create(),
);
$streamReader = new StreamReader();
$redis = new Redis();
foreach($streamReader->readTcpStream($lineReader, '192.168.1.pi', 30003) as $line) {
if($line->getMessageType()->getId() === MessageType::MSG && $line->getHexIdent()) {
$redis->HINCRBY('adsb:planes:' . date('Y-m-d'), $line->getHexIdent(), 1);
}
}
Retrieve Data in Redis
A8BD1B |
4540 |
A44CA0 |
6421 |
A45F59 |
5324 |
Array ( [A8BD1B] => 4540 [A44CA0] => 6421 [A45F59] => 5324 )
HGETALL adsb:planes:2025-10-23
Correlate the types
A8BD1B |
E75L |
A44CA0 |
B738 |
A45F59 |
B738 |
- Look at multiple fields:
- Speed is < 250 knots
- Altitude is below 10,000 feet
- Heading is Northerly
- Positive vertical rate
- Lat/Lon is just north of Renton
- 👆Probably a 737 on its maiden flight
Other Use Cases
github.com/cookieguru/php-plane-counter
- Aviation technical talks
- DEFCON Aerospace Village
- ADSB feeder image
- https://adsb.im/
- SBS-1 decoder, description
- https://packagist.org/packages/lnx85/php-sbs-reader
- http://woodair.net/sbs/article/barebones42_socket_data.htm
- Aircraft database
- https://github.com/wiedehopf/tar1090-db/
- Sourced from https://www.mictronics.de/aircraft-database/
- https://github.com/wiedehopf/tar1090-db/
Further Reading
Counting Planes with PHP
By Tim Bond
Counting Planes with PHP
Longhorn PHP Lightning Talks - October 23, 2025
- 26