This release is a pre-release and may not be stable for production use.
modsim
modsim is a standalone Modbus simulator for device integration and testing. The v2 development source reads WoT Thing Models (TM), instantiates device descriptions (TD), and runs independent simulated devices on one Modbus TCP listener. Models, scenarios, the simulator and the client remain separate.
This README describes the v2 development branch. The published 2.0.0a1
preview predates the managed deployment commands shown below; do not assume an
existing latest image or installed package contains the current source.
Stable and preview releases are independent. See preview notes
and release process.
Install from source
The v2 managed deployment commands are available in the development source;
they are not included in the published 2.0.0a1 release. Clone the v2
branch and install its dependencies with uv:
git clone --branch v2 https://github.com/top-maker/modsim.git
cd modsim
uv sync --all-groups
Run locally
From the root directory, start the example deployment and check its status:
uv run modsim up -d
uv run modsim ps
The commands use examples/deployment.yaml by default. The example starts two
virtual ADAM devices: Unit 1 exposes ADAM-5017UH raw inputs; Unit 2 exposes
ADAM-6024 raw I/O with synthetic AO→AI and DO→DI loopback. These are simulation
values, not verified physical measurements. Models, scenarios and source
information are in modbus-models.
The deployment binds to all interfaces by default; set server.bind to
127.0.0.1 in examples/deployment.yaml to restrict a direct local run.
Useful commands for managing the deployment:
uv run modsim logs -f
uv run modsim up --dry-run
uv run modsim reset --device adam-5017uh
uv run modsim export
uv run modsim down
Export writes all TDs to output/ in the root directory by default; this
directory is ignored by Git. Use -o FILE for one TD or --output-dir DIR to
choose another directory.
Use -f FILE to select another deployment. In logs, -f follows output;
use --file FILE to select the deployment. up runs in the foreground by
default; -d runs it in the background. Ctrl+C stops a service started by a
foreground up, but only detaches from an existing deployment or logs -f.
Background services do not restart after a machine reboot unless managed by a
process manager. Managed commands require POSIX (Linux/macOS/WSL); see
managed deployments.
modsim export reads the current deployment file and does not require a
running simulator. Use --running only when you need the last successfully
applied configuration instead of current file contents. That option connects to
the managed runtime in the same project environment; for Docker Compose, run it
inside the container.
Run with Docker Compose
From the examples/ directory, build and start the current source:
docker compose up -d --build
docker compose logs -f
Compose publishes Modbus TCP only on host 127.0.0.1:5020 and restarts the
container unless stopped. Each restart resets simulation state. TDs advertise
127.0.0.1 by default; configure the advertised host and port mapping when
clients connect from another machine.
The deployment and model/scenario files are mounted from the repository.
docker compose up -d starts the configured deployment; do not run modsim up
again just to start it. After editing the mounted deployment file, apply the
updated configuration to the running simulator with:
docker compose exec modsim python -m modsim up -f /app/examples/deployment.yaml -d
An unchanged device keeps its state; a changed device is replaced. Listener
changes require a container restart. If you replace the deployment file itself,
run docker compose up -d --force-recreate to refresh its bind mount. Export
all running TDs directly into the host's examples/td/ directory. The Compose
file maps the default output directory to that host directory. Run this from
the examples/ directory:
docker compose exec modsim python -m modsim export --running
This creates one *.td.json file per device in examples/td/.
Stop the Compose deployment with docker compose down.
Example: test modpoll against modsim
This example uses modpoll v2 (modpoll==2.0.0a2) and the local modsim source.
Export all TDs from the current deployment file. Run from the root directory;
modsim does not need to be running:
uv run modsim export
In another terminal, from the root directory, read the exported TD:
modpoll --once --interval 0 --tcp 127.0.0.1 --tcp-port 5020 \
--config ./output/adam-6024.td.json --export ./adam-6024-snapshot.json
If you need the last applied configuration from a Docker Compose deployment,
use the Compose export command above and point modpoll to
./examples/td/adam-6024.td.json instead.
The TD selects Unit ID 2. On a fresh deployment, adam6024_raw reports
AO0_RAW: 100 and AI0_RAW: 100; values may differ if previously written.
The command reads the exported TD and connects to modsim on the host port.
Optional: write via MQTT
Start a temporary local broker and a continuously running modpoll process:
docker run --rm -d --name modpoll-demo-mqtt -p 127.0.0.1:1883:1883 \
eclipse-mosquitto:2 mosquitto -c /mosquitto-no-auth.conf
modpoll --interval 0 --rate 1 --tcp 127.0.0.1 --tcp-port 5020 \
--config ./adam-6024.td.json --mqtt-host 127.0.0.1 --mqtt-port 1883
After modpoll connects, publish a non-retained write to the topic named for
the TD's title (adam6024_raw):
docker exec modpoll-demo-mqtt mosquitto_pub -h 127.0.0.1 \
-t modpoll/adam6024_raw/set \
-m '{"object_type":"holding_register","address":10,"value":432}'
Run the one-shot modpoll command again. AO0_RAW and loopback AI0_RAW
should both read 432. This synthetic raw value does not verify the physical
device's range or behavior. The example broker has no authentication and is
published only on host loopback; port 1883 must be available.
Stop modpoll with Ctrl+C, stop the broker if used (docker stop modpoll-demo-mqtt), then stop modsim with uv run modsim down or stop the
Compose deployment with docker compose down.
Models and scenarios
A deployment has a stable ID per device, a TM path, instance parameters and an
optional scenario. TD IDs and Modbus Unit IDs must be unique. Scenarios define
initial values, seeded generators and bindings; local Python behavior requires
--allow-scripts. They do not duplicate the model's register mapping. See
model configuration for the supported profile,
codecs, constraints and behavior hooks.
For a single device without a managed deployment:
uv run python tools/fetch-models.py
uv run modsim --config examples/models/advantech/adam-5017uh/adam-5017uh.tm.json \
--unit-id 1 --port 5020 \
--scenario examples/models/advantech/adam-5017uh/simulation/adam-5017uh.sim.json
The single-device model runtime currently supports TCP. The unconfigured demo
also supports TCP, UDP, TLS, RTU and ASCII; its datastore is shared by all Unit
IDs. TLS loads certificates/pymodbus.crt and certificates/pymodbus.key from
the working directory. See transport details.
The checked-in ADAM-6024 TD and its source hash can be checked with
uv run python tools/generate-td.py --check; omit --check to regenerate.
Development
See CONTRIBUTING.md for the v2 workflow and checks. The repository keeps v1 and v2 release lines separate; no release is implied by a source change.
Pinned public model inputs
Device data and optional scenarios are maintained only in
modbus-models.
examples/model-source.yaml pins data release modbus-models-v2 to its full
commit and individual SHA-256 hashes. Prepare examples with
uv run python tools/fetch-models.py; this downloads verified local inputs to
ignored examples/models/, never executes downloaded Python, and does not copy
an interpreter. Re-run after updating the lock through a reviewed PR.
The application keeps its independent modpoll-wot 0.2.0a2 dependency.
Single-device mode can read a fixed HTTPS TM URL directly. Optional scenarios
remain local; scripts require explicit --allow-scripts. Managed deployments
use Unix sockets and require POSIX; native Windows should use single-device
foreground mode or WSL. Independent-wheel CI verifies single-device remote-TM
startup, raw reads and process shutdown on Linux, macOS and native Windows.
It does not certify managed commands on Windows or every OS/Python combination.
The pinned preparation also includes the scoped L2 product record and its data-owned schema, so its input hashes and limits can be inspected alongside the local models. These are verification metadata, not executable simulator instructions.
Metadata
Release files for modsim 2.0.0a3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| modsim-2.0.0a3.tar.gz | 28.2 kB | Without provenance | Details for modsim-2.0.0a3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| modsim-2.0.0a3-py3-none-any.whl | Python 3 | none | any | Details for modsim-2.0.0a3-py3-none-any.whl |
Total release size: 61.6 kB
Release files / modsim-2.0.0a3.tar.gz
| Download URL | modsim-2.0.0a3.tar.gz |
|---|---|
| Size | 28.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2a9a09eb0f9bca19cbd69cd4671b4fd566d0084468a7b78624b4965c278c79c2
|
|
BLAKE2b-256 checksum How to use checksums |
18f815e90af6534357d1f57f612ab37c949c0324269ea6fad3e4e8d7296cf6a4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / modsim-2.0.0a3-py3-none-any.whl
| Download URL | modsim-2.0.0a3-py3-none-any.whl |
|---|---|
| Size | 33.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7b2e545cdbafa3ac19783452a59c7dbb46d29bb41581916f4b2a6c7bdb4123fa
|
|
BLAKE2b-256 checksum How to use checksums |
6c2e38f92c1c4352de8caeab5d58604ffc5d983af41736fba4de2f4f616d642e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for modsim 2.0.0a3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.