Skip to main content

iec60870-parser

A pure-Python, zero-runtime-dependency parser and validator for IEC 60870-5-101, -103, and -104 telemetry frames. It consumes one raw byte buffer at a time and returns a structured ParseResult with VALID, INCOMPLETE, or CORRUPTED status.

Install

python -m pip install iec60870-parser

For a source checkout:

python -m pip install -e .

API

from iec60870 import FrameStatus, FrameStream, T104Session, parse_frame

result = parse_frame(raw_bytes, protocol="t104")
if result.status is FrameStatus.VALID:
    print(result.frame_type, result.fields)
elif result.status is FrameStatus.INCOMPLETE:
    # Retain the buffer and read more bytes.
    pass
else:
    print(result.error)

protocol accepts t101, t103, t104, or auto. Explicit protocol selection is preferred for short/incomplete buffers. T101 uses a one-byte link address by default; T103 uses two bytes. Override either with link_address_size=1 or 2.

For a stream connection, T104Session checks the receive sequence number of I-format APDUs and advances it after each valid telemetry frame:

session = T104Session()
result = session.parse(apdu_bytes)

For serial reads or TCP recv chunks, use FrameStream when a read may contain partial or multiple frames:

stream = FrameStream(protocol="t104")
for chunk in socket_like_source:
    for result in stream.feed(chunk):
        if result.status is FrameStatus.VALID:
            consume(result)

FrameStream.buffered_bytes exposes a trailing partial frame. Corrupted input produces a CORRUPTED result and the tokenizer advances one byte to resync at the next possible start character.

Wire formats

T101 and T103 FT1.2

Variable frames are 68 L L 68 [control] [link address] [ASDU] [CS] 16. L is the number of bytes from control through ASDU, and CS is the sum of those bytes modulo 256. Fixed frames are 10 [control] [link address] [CS] 16; the fixed-frame helper uses the one-byte control/address layout defined by this package API.

T103 uses the same FT1.2 framing and checksum but defaults to a two-byte link address. Fixed frames honor the selected one- or two-byte link address width. Companion-standard ASDU variations that are not Type 1 or Type 30 remain available through raw frame fields and can be decoded with parse_asdu using the relevant address widths.

T104 APCI

An APDU is 68 L [four APCI control bytes] [ASDU]. I-format control fields expose send_sequence and receive_sequence; S-format exposes the receive sequence; U-format exposes STARTDT, STOPDT, and TESTFR activation/confirmation names. APCI integers are decoded in little-endian wire order and sequence values are 15-bit values.

ASDU schema

parse_asdu returns a dictionary containing type_id, vsq, count, sequence, cot, common_address, and information_objects. Type 1 objects decode a one-byte single-point value. Type 30 objects decode the one-byte value, the seven raw CP56Time2a bytes, and a decoded calendar dictionary. decode_cp56time2a is also available directly and returns year, month, day, hour, minute, second, and millisecond fields without timezone conversion. Unknown type identifiers are validated at the header/address level and leave their remaining bytes in unparsed.

The parser validates bounds before every read, rejects trailing bytes when parsing a single frame, and does not perform socket or stream I/O.

Development

python -m pip install pytest build
python -m pytest
python -m build

Release files for iec60870-parser 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for iec60870-parser 0.1.1
File Interpreter ABI Platform
iec60870_parser-0.1.1-py3-none-any.whl Python 3 none any Details

Release files / iec60870_parser-0.1.1-py3-none-any.whl

Download URL iec60870_parser-0.1.1-py3-none-any.whl
Size 7.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8d998d68004fa8fdf22db8cfd4e9458294f760b6d9d2e1c50a438463dbb7c655
BLAKE2b-256 checksum
How to use checksums
c888aec4240610bcccf404a07abb752e2ea0aa534633df1412a5657582da424d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

0.1.1 This release

1 release file

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page