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:
- Install ModScanner from PyPI:
pip install modscanner
- 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;
- Scan holding registers
0through19on 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
- 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:
- Reading a block of registers.
- Accepting the block when the response is valid.
- Splitting a block when the device return a protocol-level error.
- Continuing until individual valid and invalid addresses are identified.
- 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)
| File | Size | Uploaded | |
|---|---|---|---|
| modscanner-0.1.0.tar.gz | 10.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|