Skip to main content

ModScanner

A safety-first Modbus scanning toolkit for Python.

ModScanner helps engineers inspect Modbus devices without immediately falling back to slow, one-register-at-a-time scanning. It reads registers in blocks and adaptively splits rejected blocks to identify valid and invalid addresses.

Project status: Early development. Version 0.1.0 supports only **Modbus TCP holding register scanning.

Features

  • Read-only Modbus TCP scanning
  • Holding register reads using function code 03
  • Configurable device ID, port, timeout, range, and block size
  • Adaptive block splitting when a device rejects a register range
  • Seperation of protocol errors, transport errors, and invalid responses
  • Terminal output using Rich
  • Typed Python data module
  • Transport abstraction that is built untop of PyModbus
  • Unit tested scanning behavior

Installation

Install ModScanner from PyPI using either of two(2) methods the below:

  1. Install ModScanner from PyPI:
pip install modscanner
  1. Using uv:
uv add modscanner

Verify the installation using:

modscanner --help
or
modscanner --h
or 
modscanner version

The above help shows the commands available, while the version shows the current version you have installd on your machine

Quick start

There are different ways to use the library;

  1. Scan holding registers 0 through 19 on a Modbus TCP device using the below:
modscanner scan-tcp 192.168.1.10 --device-id 1 --start 0 --count 20

The above expects you to use the IP Address of the Modbus device, so replace the 192.168.1.10 with your Modbus device

  1. Specify the TCP port, timeout, and request block size using:
modscanner scan-tcp 192.168.1.10 --port 502 --device-id 1 --start 0 --count 100 --block-size 50 --timeout 2

Run:

modscanner scan-tcp --help

to see all available options.

Addressing

ModScanner uses zero-based Modbus protocol addresses.

For example, a vendor document may label the first holding register as 40001, while its protocol address is commonly 0.

Always confirm how the device manufacturer represents register addresses before scanning.

Adaptive scanning

Some Modbus devices reject an entire request when only one address is within the requested block is invalid.

ModScanner handles this by:

  1. Reading a block of registers.
  2. Accepting the block when the response is valid.
  3. Splitting a block when the device return a protocol-level error.
  4. Continuing until individual valid and invalid addresses are identified.
  5. Avoiding recursive requests after transport failure such as timeouts.

This reduces unnecessary requests while stil supporting sparse register maps.

Safety

ModScanner 0.1.0 is read-only.

It does not write coils or registers. Future write-validation functionality will require explicit register allowlists, value limits, confirmation, readback, and audit logging.

Read-only registers should also be used carefully on production systems. Confirm the target IP address, port, device ID, and permitted register range before scanning industrial equipments.

Current limitation

Version 0.1.0 does not yet support:

  • Modbus RTU
  • Coils
  • Discrete inputs
  • Input registers
  • Automatic device ID discovery
  • JSON, CSV, or YAML exports
  • Data type decoding
  • Byte-order or word-order conversion
  • Device profiles
  • Register monitoring
  • Register writes
  • Writable-register validation

All the above are planned for future releasesa

See CONTRIBUTING.md for contribution guidelines.

Security

Do not use ModScanner to perform unauthorized scanning or testing.

Author

Developed by Davis Onyeoguzoro

Metadata

Release files for modscanner 0.1.0

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

Source distribution (sdist)

Source distribution for modscanner 0.1.0
File Size Uploaded
modscanner-0.1.0.tar.gz 10.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for modscanner 0.1.0
File Interpreter ABI Platform
modscanner-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 21.9 kB

Release files / modscanner-0.1.0.tar.gz

Download URL modscanner-0.1.0.tar.gz
Size 10.7 kB
Tags Source
SHA-256 checksum
How to use checksums
e9d8037227c4a4d11dbed69d49905bb1b560f7040eec05f5fbf994ca3f966987
BLAKE2b-256 checksum
How to use checksums
8f9d67f2d0e1a1f8b80ee062fafd8825e17bf3f80a47581c8d040eef8e533603
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.13

Release files / modscanner-0.1.0-py3-none-any.whl

Download URL modscanner-0.1.0-py3-none-any.whl
Size 11.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
40d5178184ed256ea6d23e0b90974fa45f4c671f47e5ca24ffa746cfcd56028e
BLAKE2b-256 checksum
How to use checksums
7288f1a03ff42e8d784c4d8d2e38eb3abad87501b39678a16535dd8e511badfa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.13

Release history Release notifications | RSS feed

0.2.0

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

This release

0.1.0 This release

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