Skip to content

Latest commit

 

History

630 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ModbusForge v2026.8.27

.NET Windows License GitHub release GitHub issues

A professional Modbus TCP/RTU/ASCII client/server application built with .NET 8.0 and Avalonia. ModbusForge provides comprehensive tools for testing, monitoring, and automating Modbus communications on Windows and Linux.

ModbusForge

Table of Contents


Quick Start

Get up and running with ModbusForge in 5 minutes.

1. Launch the Application

dotnet run --project ModbusForge

2. Configure Mode

Choose between Client or Server mode in appsettings.json:

{
  "ServerSettings": {
    "Mode": "Client",
    "DefaultPort": 502,
    "DefaultUnitId": 1
  }
}

3. Connect (Client Mode)

  1. Enter the IP address of your Modbus TCP server
  2. Enter the port (default: 502)
  3. Enter the Unit ID (slave ID)
  4. For RTU/ASCII connections, click the gear icon and set the COM port, baud rate, data/stop bits, parity, and RTS (RS-485)
  5. Click Connect

4. Read Data

  1. Select the Registers tab
  2. Enter the starting address and count
  3. Click Read
  4. Enable Continuous Read for automatic polling

5. Explore More

  • Options → Connection Manager: Save and manage multiple connection profiles
  • Options → Device Scanner: Discover Modbus TCP devices on your network
  • Options → Script Editor: Create automated test sequences
  • Options → Preferences: Customize application behavior
  • Help → Keyboard Shortcuts: View all available shortcuts

What's New

2026.8.29 - Visual Simulation: Data-Driven Parameters, Full Undo & a Calmer Panel

  • Data-driven function-block parameters: every block declares its parameters (BlockParameterDescriptor), and the node editor builds its parameter UI from the same descriptors the engine consumes, so the two can never drift. New Real variants (Signal Generator Real, Real math, Real compare).
  • Device blocks finalized: the valve gains a Latching option (default) with spring-return rest position, the DOL motor stops cleanly without a Fault port, and the VSD exposes Running/SpeedFeedback/AtSpeed outputs.
  • Correct port and address binding: the editor's generic connectors map onto named block ports positionally (e.g. Input1Start/Run, Output → primary output), and address binding is gated by descriptor flags so default (unedited) addresses on wire-driven nodes stay inert.
  • Stable block state: graph rebuilds reuse the per-node engine instances, so timers, counters, and valve positions survive in-place edits while the simulation is running.
  • Complete undo/redo in the editor: parameter edits (coalesced per node), renames, enable/disable toggles, Modbus address bindings, and waveform application are all undoable — and the Undo button responds immediately after an edit.
  • Calmer right panel: the two node lists merged into a single Nodes panel (name, address, enable checkbox, editable live value); the duplicated simulation controls were removed; the Selected Node panel stays reachable at the top.
  • Demo and program loads preserve the running state: a running simulation keeps running on the newly loaded program.
  • Configurable scan interval (10–10000 ms) in the toolbar, a visible local/device store indicator, loop warnings in the status bar, and single-driver validation per input connector.
  • Tests: engine port-mapping and state-preservation cases plus a new headless view-model suite (undo coalescing, demo load, connection validation).
  • Version bumped to 2026.8.29 in all projects.

2026.8.27 - Server IP in Active Profile Display

  • Active profile now shows the real server IP: when running in Server mode the top toolbar and dashboard display the actual bound IP and port (e.g. 192.168.1.100:502) instead of the loopback address, while the Interface text box still holds 127.0.0.1 or 0.0.0.0 for binding.
  • Version bumped to 2026.8.27 in all projects.

2026.8.26 - Server IP Display

  • Server mode now shows your local IP: the main toolbar displays the IP address(es) and port clients can use to connect when ModbusForge is running as a Modbus server, so you no longer need to look it up in Windows settings.
  • Version bumped to 2026.8.26 in all projects.

2026.8.25 - Chunked Modbus Reads, Large Writes & Partial-Read UI

  • Chunked register reads/writes: holding/input register reads, multi-register writes, and bulk coil writes are now automatically split into protocol-sized packets and reassembled, supporting the full 0..65535 address range.
  • Red partial-read marker: if a chunked read fails partway through, the last successfully read value appears in red with a tooltip explaining the partial result.
  • Raised register count limits: holding/input register count fields now allow up to 65536; coil/discrete counts remain capped at the Modbus maximum of 2000.
  • Partial reads help topic: a new searchable help topic explains the red value and how to clear it.
  • Version bumped to 2026.8.25 in all projects.

2026.8.24 - NumericUpDown Two-Way Binding

  • Register/coil count fix: removed the explicit DecimalToIntConverter so the NumericUpDown count/start/period values use Avalonia’s built-in int ↔ decimal? conversion, restoring reliable two-way binding.
  • Version bumped to 2026.8.24 in all projects.

2026.8.23 - NumericUpDown Converter Localisation

  • Register count fix: the DecimalToIntConverter is now declared directly in the views that use it, ensuring the NumericUpDown count/start/period values correctly write back to the view model.
  • Version bumped to 2026.8.23 in all projects.

2026.8.22 - Custom Watch Bulk Add, Auto-Monitoring & Count Binding Fixes

  • Bulk-add custom watch entries: new Add Bulk dialog creates a contiguous range with start register, count, type, area, read period and write period.
  • Per-row delete button in the Custom Watch Actions column.
  • Custom Watch auto-starts: the background loop starts automatically when any row's Read or Continuous Write is checked and stops when all are unchecked.
  • Register/coil count caps raised to the Modbus protocol limits (125 for holding/input registers, 2000 for coils/discrete inputs).
  • NumericUpDown two-way binding fixed: added a DecimalToIntConverter so count, start and period NumericUpDowns actually update the view model.
  • Version bumped to 2026.8.22 in all projects.

2026.8.21 - Connection Manager Polish & Update Popup Fix

  • Connection Manager COM port enumeration is now async: the window opens instantly while friendly port names are loaded in the background.
  • Connection Manager baud-rate dropdown is now sorted ascending (1200 → 115200).
  • No-update startup popup removed: the app now only shows the status message when already on the latest release.
  • Version bumped to 2026.8.21 in all projects.

2026.8.20 - Startup Update Check Fix

  • Check for updates on startup is now wired in the Avalonia desktop app: the existing Check for updates on startup preference is honored when the main window opens.
  • Version bumped to 2026.8.20 in all projects.

2026.8.19 - Continuous Read Grid Editing & Type/Area Binding Fixes

  • Continuous read no longer steals focus while editing register/coil values: register and coil grids are updated in place during polling, and a per-area editing guard avoids overwriting an active cell edit.
  • Custom Watch and register type/area combo boxes keep their selections after tab switching and update immediately when changed.
  • Default numeric type changed to int for new register and custom entries.
  • Version bumped to 2026.8.19 in all projects.

2026.8.18 - Headless Runtime & CI Hardening

  • Headless runtime improvements: ModbusForge.Headless now supports ConnectionProfile for TCP and RTU/ASCII serial, environment-specific appsettings.<Environment>.json, MODBUSFORGE_ environment variables, structured Serilog console and file output, MQTT publishing via MqttGatewayService, --help, CLI validation, and graceful shutdown.
  • Hardened CI/release workflow: Resolved secrets context usage in conditional steps, added environment-specific build/test jobs, and prevented recursive release runs from the github-actions[bot] tag push.
  • Avalonia-only desktop: the legacy Windows-only desktop project and assets have been fully removed; Avalonia is the only desktop UI.
  • Connection Manager serial improvements: COM port dropdown now auto-detects ports and shows device names in brackets (e.g. COM3 (MOXA ...)); a Custom port... option allows manual COM port entry; baud rate is now a preset dropdown of standard Modbus rates; and an Auto-detect settings button scans common baud/parity/data/stop-bit combinations and reports the first valid Modbus response.
  • Version bumped to 2026.8.18 in all projects.

2026.8.16 — Industrial Simulation Blocks & Engine Unification

  • Simulation engine unified in Core: VisualSimulationServiceBase and IVisualSimulationService now host the engine and block catalog in ModbusForge.Core, shared with the Avalonia desktop UI.
  • Multi-output port support: Nodes can expose named output ports (Fault, SpeedFeedback, AtSpeed, etc.) and bind each to its own Modbus address.
  • Valve block (v2026.8.13): Motorised valve with OpenCmd/CloseCmd, configurable travel time, normally-open rest position, and Fault output for simultaneous commands.
  • DOL motor block (v2026.8.14): Direct-on-line starter with Start/Stop, sealed contactor, configurable run pickup delay, and Fault output.
  • VSD block (v2026.8.15): Variable speed drive with Run, SpeedReference, ramped SpeedFeedback, AtSpeed, and Running outputs; configurable max speed, ramp up/down times, and speed tolerance.
  • Version bumped to 2026.8.16 in all projects.

2026.7.12 — Release Polish & Cross-Platform Packaging

  • Avalonia is now the primary release artifact for Windows and Linux.
  • Windows installer: New setup/ModbusForge.iss Inno Setup script builds ModbusForge-{version}-setup.exe from the self-contained publish/avalonia/win-x64 output.
  • Linux .tar.gz packaging: publish-avalonia.ps1 now creates packages/ModbusForge-{version}-linux-x64.tar.gz and packages/ModbusForge-{version}-win-x64.zip after publishing.
  • Release pipeline updates: .github/workflows/release.yml now publishes Avalonia for Windows and Linux, packages the artifacts, builds the Avalonia installer, and uploads the .zip, .tar.gz, checksums, and installer to GitHub Releases.
  • Version bumped to 2026.7.12 in all projects.

2026.7.11 — Performance & Reliability

  • Address validation: New IModbusAddressValidator / ModbusAddressValidator validates unit ID, start address, and count/range before every Modbus operation. ModbusTcpService and ModbusSerialService now reject out-of-bounds requests with ArgumentOutOfRangeException, and MainViewModel.CanRead() disables the read command for invalid ranges.
  • Correlation IDs: New ICorrelationContext / CorrelationContext with async-local storage for tracing operations across async boundaries. ConnectionManager starts a new correlation ID and adds it to ILogger scopes when connecting a profile.
  • More Avalonia unit tests: Added ModbusAddressValidatorTests, CorrelationContextTests, and PreferencesViewModelTests (plus FakeSettingsService). ModbusForge.Avalonia.Tests now has 5 tests covering the main view, preferences, and validator.

2026.7.10 — Application Shell & Preferences

  • Application menu in Avalonia: Added File, Edit, View, Tools, and Help menus to MainView with Save, Load, Exit, Read/Refresh, Preferences, Toggle Theme, Check for Updates, Help, Keyboard Shortcuts, Troubleshooting, and About commands.
  • Preferences window: Full Avalonia port with sections for Connection, Diagnostics, Console, Performance, Application, API (with API key generation), and MQTT. Persists through the existing SettingsService.
  • Help, About, Keyboard Shortcuts, and Troubleshooting windows: Avalonia windows with content reused from the previous desktop implementation and core IHelpContentService.
  • Global keyboard shortcuts: Ctrl+R / F5 read, Ctrl+T open Trends, Ctrl+S save, Ctrl+P preferences, Ctrl+Q exit, F1 help.
  • Theme toggle: Added ToggleTheme() to IThemeService with an Avalonia implementation and a test-friendly stub.
  • Auto-updater: Wired IUpdateService into Avalonia; checks GitHub releases for the latest tag and compares to the running version. On a newer release it offers to open the release page; the existing UpdateService also supports installer download and silent launch.

2026.7.9 — Visual Simulation

  • Visual Simulation tab in Avalonia: Build, edit, and run node-based PLC simulations.
  • Simulation engine and blocks moved to Core: Logic gates (AND, OR, NOT, RS), timers (TON, TOF, TP), counters (CTU, CTD, CTC), comparators, math (ADD/SUB/MUL/DIV), and signal generator blocks now run cross-platform.
  • Node palette and data grid editor: Add nodes from the palette, edit X/Y and parameters, and wire them together in a connection grid.
  • Live preview canvas: Nodes render on a scrollable canvas with current live values.
  • Run/stop simulation: The AvaloniaVisualSimulationService executes the graph against a local DataStore on a 100 ms timer.
  • .mfsim save/load: Save and load simulation programs as JSON.

2026.7.8 — Scripting & Advanced Functions

  • Avalonia Script Editor: Create, edit, run, and stop Modbus scripts with a live output log.
  • Script command types: read/write coils and registers, delay, log, plus advanced FC22 Mask Write, FC23 Read/Write Multiple, and FC43 Read Device Identification.
  • .mbscript save/load: Save and load script files as JSON.
  • Signal Generator tab: Generate ramp, sine, triangle, or square waveforms and write values to a holding register on a configurable period.
  • Core ScriptCommand and ScriptRunner extended to support the new advanced command types.

2026.7.7 — Connection, Transport & Frame Tools

  • Avalonia serial RTU/ASCII settings: Connection Manager now exposes COM port, baud rate, data bits, parity, stop bits, RTS, RTS toggle, and pre/post tx delays when a serial transport is selected.
  • Connection profile persistence: Profiles are saved and reloaded across sessions.
  • Frame Inspector tab: Live PDU/byte log with timestamp, delta, direction, unit ID, function code, and hex payload. Includes Clear and Pcap import buttons.
  • Pcap import / offline replay: Import .pcap files and view the extracted Modbus TCP frames directly in the Frame Inspector.
  • MQTT gateway tab: Configure broker host/port, client ID, credentials, topic template, QoS, retain, and publish period; connect and publish custom watch tag values.

2026.7.6 — Avalonia Trends

  • Live trend chart in Avalonia: Added a Trends tab with a LiveCharts Cartesian chart, Start/Stop/Remove/Clear controls, and a color-blind-safe palette.
  • Trend logging service integration: TrendLoggingService is now registered in the Avalonia app and starts/stops with connection state.
  • Trend from Custom Watch: Any custom entry with the Trend flag checked publishes its numeric/coil value to the trend chart while monitoring.
  • Retention and sample-rate control: Configure how many minutes of data to retain and how fast to sample.

2026.7.5 — Custom Watch & Project Save

  • Avalonia Custom Watch tab: Add/remove custom tags with name, address, area, type, value, write value, and continuous/monitor/trend flags.
  • Continuous custom monitoring: A background loop in the Avalonia app reads Monitor-enabled and writes Continuous-enabled entries on their configured periods.
  • Custom read/write: Manual read and write buttons support uint, int, real, string, and coil types, with proper byte/word handling for floats and strings.
  • Custom and project save/load: Save/load custom entry JSON files and full project .mfp/.json files that restore connection profiles, active profile, register area, and custom entries.
  • Headless --custom: ModbusForge.Headless now accepts --custom <path> to run a custom watch JSON file from the command line.

2026.7.3 — Avalonia Foundations

  • Default startup project: ModbusForge is now first in ModbusForge.sln.
  • Cross-platform CI: Added GitHub Actions workflow to build and test Avalonia on Windows and Linux.
  • Self-contained publishing: Validated win-x64 and linux-x64 single-file publishes.

2026.7.2 (v6.2.1)

  • Auto-updater CalVer fix: UpdateService now normalises 3-part release tags and 4-part assembly versions to a common 4-part form before comparing, so installed builds with AssemblyVersion=2026.7.1.0 correctly compare against the v2026.7.1 tag and future CalVer releases.
  • Added CalVer asset matching tests for UpdateService to ensure the correct ModbusForge-YYYY.M.INCREMENT-setup.exe installer is selected from GitHub releases.

2026.7.1 (v6.2.0)

  • CalVer versioning: Switched from SemVer (6.x.x) to YYYY.M.INCREMENT starting with 2026.7.1.
  • Cross-platform core extraction: New ModbusForge.Core class library targets net8.0 and contains the view-agnostic models, helpers, configuration and services (Modbus, polling, MQTT, pcap import, logging, etc.).
  • New RgbColor model: Replaced the legacy System.Windows.Media.Color in NodeDescriptors with a portable RgbColor struct; the Avalonia UI converts back when creating brushes.
  • Headless Linux runtime: New ModbusForge.Headless console app targets net8.0, uses ModbusForge.Core, and polls Modbus TCP registers/coil/discrete-input areas from the command line with --host, --port, --unit-id, --start, --count, --interval and --area options.
  • Solution restructure: ModbusForge desktop app now references ModbusForge.Core; ModbusForge.Headless and ModbusForge.Core added to the solution.

v6.1.0

  • Channels-based background polling engine: New PollingEngine runs Modbus reads off the UI thread using System.Threading.Channels. MonitoringCoordinator now enqueues PollingCommands, the worker executes the I/O, and results are drained and applied to the UI at 50ms ticks. Area commands coalesce by unit/area so only the latest pending request is processed under back-pressure.
  • Separated I/O from UI formatting: RegisterCoordinator now has Apply* methods for holding/input registers, coils and discrete inputs, letting the polling engine update collections on the UI thread without blocking it during Modbus transactions.
  • 50ms / 20-unit benchmark: Added PollingThroughputTests verifying 20 concurrent unit reads at 50ms intervals complete within one second.

v6.0.8

  • Fixed auto-updater installer asset selection and release workflow so only the versioned installer is uploaded; removed stale tracked installers/ModbusForge-2.0.2-setup.exe.

v6.0.7

  • 32/64-bit byte & word swapping endianness matrix: Added EndiannessFormat (ABCD, BADC, CDAB, DCBA) and converter methods for float, double, int, uint, long, and ulong. The legacy Swap Bytes / Swap Words flags now map to the same matrix.
  • RS-485 RTS toggle & line timing: Serial connections now support EnableRtsToggle, PreTxDelayMs, and PostTxDelayMs in ConnectionProfile, with controls in the Connection Manager.
  • Rockwell L5X, JSON and YAML register map importers: RegisterTemplateImportService now auto-detects .json, .yaml/.yml and .l5x files; L5X <Tag> arrays are expanded into sequential virtual Modbus addresses.
  • PDU/byte frame inspector: A new LoggingStreamResource captures every transmitted and received Modbus byte[] with timestamps and inter-frame timing; open it from Options > Frame Inspector.
  • MQTT publisher: MqttGatewayService publishes JSON snapshots of holding/input registers, coils, discrete inputs and custom entries to a configurable MQTT broker with auto-reconnect and topic templates; configured in Preferences.
  • Pcap import & offline replay: PcapImportService reads .pcap files (no Npcap required), extracts Modbus TCP frames on port 502 and displays them in the Frame Inspector for offline analysis.

v6.0.6

  • 32-bit float on holding and input (internal) registers: Holding and Input Register grids now decode uint, int, real (32-bit float), and string values. Input Registers get the same Swap Bytes / Swap Words controls as holding registers, and per-address Type and Swap settings are now saved in the .mfp project file.
  • Live register value refresh: Changing the global Type or Swap settings immediately re-decodes and re-displays the current register values.
  • Custom Watch continuous read: Added a Read checkbox and Read Period (ms) column for per-row continuous reads. The Custom Read toolbar toggle enables them; the existing Continuous Write column is now clearly labeled.
  • Save All: The File menu now has a Save All option that saves the entire project, including every Unit ID, IP, port and tab.
  • Continuous poll error handling: When a continuous read fails, the monitor for that area is paused and the error popup no longer re-appears immediately.
  • Custom tag add: New custom tags now inherit the previous row's Type and Area, auto-increment the name, and advance the address by 2 for uint/real types.
  • Console improvements: The console logs Modbus server requests with client IP, function code, address and count; UI register/coil writes; and visual simulation node value changes.

v6.0.5

  • Trend retention time: The Trend view Retention (min) setting now takes effect immediately when you click Apply. Existing trend data is re-trimmed to the new window and the chart values and CSV export samples stay in sync.

v6.0.4

  • Fixed startup crash (native runtime DLL EntryPointNotFoundException): Removed legacy native runtime DLLs from the installer. These DLLs are part of the shared Microsoft.WindowsDesktop.App runtime; shipping them with the app caused a mismatch when the installed .NET runtime was patched to a newer version, leading to a startup XamlParseException.

v6.0.3

  • Custom Watch separate write value: Added a new Write Value column. Value is now read-only and shows the live read value; Write Value is used for one-shot writes and continuous writes. This lets trends/global monitoring keep reading while you write a different value.

v6.0.2

  • Visual Node Editor (ADD/COMPARE constant): Const / Val values are now used when Input2 is not connected. Previously the unconnected Input2 was treated as a default coil address and read as 0.
  • One-click auto-update: When an update is found, you can now choose to download and install it automatically. The installer runs silently, closes the current application, replaces the files, and relaunches ModbusForge.

v6.0.0

  • Update checking: New Help → Check for Updates… menu item and optional Check for updates on startup preference. ModbusForge compares the running version against the latest GitHub release.
  • Script Editor: Selection theming now uses the fluent DataGrid style so selected rows remain readable.
  • Visual Node Editor (ADD block): Constant input (CompareValue) is now used when Input2 is not connected.
  • Trends tab: Trend view correctly resolves its view model when loaded, so custom tags with trending enabled render again.
  • Visual Node Editor (POU switching): Switching between programs (POUs) now saves the current nodes and wiring before loading another program, so wiring is no longer lost.

v5.9.0

  • Serial Modbus (RTU + ASCII): Added COM-port selection, baud/parity/data/stop bits, and RS-485 RTS toggle through the Connection Manager

v5.8.7

  • Updated README screenshots to reflect the current ModbusForge UI

v5.6.0 - Documentation & User Experience

  • Comprehensive Help System: New searchable help window with F1 support
  • Troubleshooting Tools: Built-in troubleshooting guide with diagnostic export
  • Improved Keyboard Shortcuts: Expanded shortcut coverage with quick reference printing
  • Modern Dialog Styling: About, Keyboard Shortcuts, Script Editor, and Troubleshooting windows now use Fluent UI
  • Tab Stability: Removed accidental tab close buttons to prevent empty panes
  • Better README: Restructured documentation with quick start, FAQ, and contributing sections

v5.3.0 - UX Quick Wins

  • Automatic Continuous Read: Trend lines now automatically enable continuous read when added
  • Enhanced Error Logging: Specific exception handling with detailed logging
  • Global Keyboard Shortcuts: Ctrl+R read, Ctrl+T trends, Ctrl+S save, F5 refresh, F1 help
  • Improved Error Messages: User-friendly messages with recovery suggestions

v5.2.0 - Resilience & Error Handling

  • Centralized Resilience: Retry policy with exponential backoff and jitter
  • Circuit Breaker Pattern: Prevents cascading connection failures
  • Startup Configuration Validation: Schema validation for appsettings.json
  • Validation Service: Input validation for IP addresses, ports, unit IDs, and registers

See FEATURE_ROADMAP.md for the full development roadmap.


Key Features

Core Functionality

  • 🔌 Client & Server Modes: Switch between Modbus TCP client and server
  • 🔗 Multiple Transports: Connect over TCP, RTU, or ASCII serial
  • 📝 Full Register Support: Read/write holding registers, input registers, coils, and discrete inputs
  • 📊 Real-time Monitoring: Continuous polling with configurable intervals
  • 🔍 Connection Diagnostics: Test TCP/serial and Modbus connectivity with latency measurements
  • 🧩 Advanced Function Codes: FC22 Mask Write Register, FC23 Read/Write Multiple Registers, FC43 Read Device Identification (client and server)

Device Discovery

  • 🛰️ Device Scanner: Sweep an IP range, a port range and unit IDs 1–247
  • FC43 device identification reports vendor, product code and revision
  • Function-code detection lists which of FC01-FC04 each unit implements
  • Optional register-range probe on each discovered unit
  • Save discovered devices straight into connection profiles, or export the scan as CSV

Multi-Device Support

  • Connect to multiple Modbus servers simultaneously
  • Save and manage connection profiles
  • Quick switching between active connections
  • Profiles persist between sessions

Scripting & Automation

  • Visual script editor for creating test sequences
  • Support for read/write operations, delays, and logging
  • Run scripts with repeat counts and configurable delays
  • Save/load scripts as .mbscript files

Data Visualization

  • 📈 Trend Charts: Real-time graphing with zoom/pan controls
  • 📤 CSV/PNG Export: Export trend data and charts
  • 🖥️ Console Logging: Real-time log of all Modbus operations

Custom Data Tab

  • Per-row configuration: Area, Type (uint/int/real/string)
  • On-demand and continuous read/write
  • Live value updates with trend integration
  • Save/Load configurations to JSON

Visual Simulation

  • 🎨 Visual Node Editor: Graphical programming for Modbus simulations
  • 📶 Signal Generators: Ramp, Sine, Triangle, and Square waveforms
  • 🔗 Node Connections: Wire nodes together to define data flow
  • 🔄 Real-time Simulation: Execute simulations and monitor values

Screenshots

Main Interface

Main Interface The main window provides a tabbed interface for registers, coils, custom data, simulation, trends, and console logging.

Connection Manager

Connection Manager Save and manage multiple Modbus connection profiles with quick connect/disconnect capabilities.

Script Editor

Script Editor Create and run automated test sequences with a visual command editor.

Visual Node Editor

Visual Node Editor The Simulation tab provides a visual node editor with a node palette and simulation controls for building signal-generation and Modbus-output simulations.

Trend Charts

Trend Charts Monitor register values over time with real-time graphing, zoom, pan, and export capabilities.


Installation

When you download and run the installer for ModbusForge, Windows Defender SmartScreen will likely show a warning because the application is not digitally signed with a commercial certificate.

To install the application, follow these steps:

  1. Run the ModbusForge-x.x.x-setup.exe installer.
  2. Windows will show a blue window titled "Windows protected your PC".
  3. Click on the More info link.
  4. The publisher will be listed as "Unknown". Click the Run anyway button to proceed with the installation.

Feature Details

Connection Manager

Access via Options → Connection Manager

  • Create, edit, and delete connection profiles
  • Choose transport: TCP, RTU, or ASCII
  • TCP profiles store: Name, IP Address, Port, Unit ID
  • Serial profiles store: Name, COM Port, Baud Rate, Data Bits, Parity, Stop Bits, RTS, Unit ID
  • Connect/disconnect individual profiles
  • Set active connection for main window operations
  • Profiles saved to %AppData%\ModbusForge\connection-profiles.json

Serial Configuration

When creating an RTU or ASCII connection:

  1. Select RTU or ASCII from the Transport dropdown
  2. Enter the COM Port your device is attached to (e.g. COM3)
  3. Set the Baud Rate (commonly 9600 or 115200)
  4. Set the Data Bits (7 or 8)
  5. Set the Parity (None, Even, Odd, Mark, or Space)
  6. Set the Stop Bits (One, OnePointFive, or Two)
  7. Enable RTS if your RS-485 adapter requires Request-to-Send toggle
  8. Enter the Unit ID and click Connect

Serial profiles use the same read/write register and coil operations as TCP profiles, with 1-based addresses converted to the 0-based Modbus protocol addresses automatically.

Device Scanner

Access via Options → Device Scanner...

Scans an inclusive IPv4 range (up to 4096 addresses) across a port range (up to 64 ports) and any subset of unit IDs 1–247, using a short-lived connection per endpoint so live polling is never disturbed.

Scan settings

  • Start/End IP, Port from/to, Unit ID from/to
  • Register type and probe address used for detection
  • Connect and response timeouts, and the number of endpoints probed in parallel
  • Read device identification (FC43) for vendor, product code and revision
  • Detect function codes (FC01-FC04) reads one item from each register space to work out which read functions a unit implements; a unit that answers illegal data address still counts as implementing the function, only illegal function excludes it
  • Scan register range to list which addresses of a discovered unit are readable

Results

  • Status per unit: Responded, RespondedWithException (device present but the address is unsupported), NoModbusResponse (port open, unit silent) or NoTcpConnection
  • Add to Profiles stores the selected device in connection-profiles.json
  • Function codes column shows the detected read functions, e.g. FC03, FC04
  • Export CSV writes one row per device plus one row per scanned register
  • Scans report progress and can be stopped at any time; results found so far are kept

Script Editor

Access via Options → Script Editor or press Ctrl+E

Supported Commands:

  • Read Holding Registers / Input Registers
  • Read Coils / Discrete Inputs
  • Write Single Register / Coil
  • Delay (configurable milliseconds)
  • Log messages

Script Settings:

  • Repeat count for looping
  • Delay between commands
  • Stop on error option

Output Log: Real-time execution feedback

See docs/SCRIPTING_GUIDE.md for detailed scripting documentation.

Preferences

Access via Options → Preferences

  • Auto-reconnect on connection loss
  • Show diagnostics on connection error
  • Console logging settings
  • Confirm before exit
  • Check for updates on startup
  • Settings saved to %AppData%\ModbusForge\settings.json

Check for Updates

Access via Help → Check for Updates…

ModbusForge checks the latest GitHub release against the running version.

  • Manual check: open the menu item at any time.
  • Automatic check: enable Check for updates on startup in Preferences.
  • When a newer version is found, choose Yes to download and install it automatically, No to open the release page in your browser, or Cancel to close the dialog.
  • The installer is downloaded to your temp folder, runs silently, closes the running application, installs the update, and relaunches ModbusForge.
  • If the app is already on the latest release or the check cannot reach GitHub, a brief message is shown.

Custom Data Tab

  • Area Types: HoldingRegister, Coil, InputRegister, DiscreteInput
  • Data Types: uint, int, real (32-bit float), string
  • On-demand Read/Write buttons per row
  • Continuous Write mode per row
  • Live reads when Global Continuous Read is enabled
  • Save/Load configurations to JSON

Register Templates (CSV / Excel Import)

Import a vendor register map from the Tag Browser → Import Template button. The preview dialog shows every parsed row, highlights rejected rows in red and warning rows in amber, and only imports the rows that validated. CSV Template writes an example file to fill in.

Supported columns (header names are matched case-insensitively, ignoring spaces, _ and -; common vendor synonyms such as Tag, Register, Register Type, Comment, EU are accepted):

Column Meaning
TagName (required) Tag name
Address (required) Register address, interpreted using the selected addressing convention
Description, Group Description and tag group
RegisterType Holding / Input / Coil / Discrete (also HR, IR, 4x, 3x, 0x, 1x)
Bit Bit index 0–15 within a packed status word
DataType Bool, Int16, UInt16, Int32, UInt32, Float/Real, Double, String
WordOrder BigEndian/ABCD or LittleEndian/CDAB (word-swapped)
Length Registers occupied; defaults to the data type width
Scale, Offset, Unit Engineering-unit conversion applied to polled and written values
Access r / ro (read-only) or rw
Enum 0=Off;1=On — displayed instead of the raw value
Default Default value
Range 0..100 (or separate Min/Max columns) — used as the alarm limits

Addressing conventions: 0-based (protocol address), 1-based (address − 1) and Modicon (40001 → holding register 0, 30001 → input register 0, 10001 → discrete input 0, 000001 → coil 0; 6-digit forms are also supported).

Example:

TagName,Description,Group,RegisterType,Address,Bit,DataType,WordOrder,Length,Scale,Offset,Unit,Access,Enum,Default,Range
VFD_OutputFreq,Output frequency,VFD,Holding,40001,,UInt16,BigEndian,1,0.01,0,Hz,r,,,0..60
VFD_Current,Motor current,VFD,Holding,40002,,Float,CDAB,2,0.1,0,A,r,,,0..120
VFD_Command,Command word,VFD,Holding,40010,,UInt16,BigEndian,1,1,0,,rw,0=Stop;1=Run;2=Jog,0,
VFD_FaultBit,Fault bit of status word,VFD,Holding,40011,5,Bool,BigEndian,1,1,0,,r,0=Ok;1=Fault,,

Imported templates are stored as JSON in %AppData%\ModbusForge\templates\ so they can be reused, edited or shared. Excel (.xlsx) files are read from the first worksheet.

Advanced Functions

Open Options → Advanced Functions... to use the protocol functions that go beyond the standard read/write set. All addresses are 1-based, exactly like the rest of the UI.

Function What it does Inputs
FC22 - Mask Write Register Atomically sets/clears bits of one holding register: result = (current AND andMask) OR (orMask AND NOT andMask) Address, AND mask, OR mask
FC23 - Read/Write Multiple Registers Writes a block of registers and reads a (possibly different) block in a single transaction; the write happens first Read address/count, write address, comma-separated values (0x prefix for hex)
FC43 / MEI 14 - Read Device Identification Queries the device identity strings (vendor, product code, revision, vendor URL, product name, model, application) Category: Basic, Regular or Extended

The result of each call, or the Modbus exception returned by the device, is shown in the status bar at the bottom of the dialog; FC43 objects are listed in a grid.

In server mode ModbusForge answers all three functions as well. The identity served by FC43 defaults to the ModbusForge vendor/product strings and the running application version.

The same operations are available programmatically through IModbusService:

ushort? result = await modbusService.MaskWriteRegisterAsync(unitId: 1, registerAddress: 5, andMask: 0x00F2, orMask: 0x0025);
ushort[]? read  = await modbusService.ReadWriteMultipleRegistersAsync(1, readStartAddress: 1, readCount: 4, writeStartAddress: 10, writeValues: new ushort[] { 1, 2 });
DeviceIdentification? id = await modbusService.ReadDeviceIdentificationAsync(1, DeviceIdObject.VendorName, DeviceIdCategory.Basic);

Trend & Logging

  • Real-time trend charts with zoom/pan
  • Adjustable retention window (1–60 minutes)
  • Export to CSV or PNG
  • Console tab shows all Modbus operations

Visual Node Editor

Access via the Simulation tab or left navigation panel.

  • Drag nodes from the palette onto the canvas
  • Connect nodes by dragging from outputs to inputs
  • Configure node parameters in the properties panel
  • Run simulations and monitor real-time values

Modes: Client vs Server

Configure in ModbusForge/ModbusForge/appsettings.json under ServerSettings:

  • Mode: Client or Server
  • DefaultPort, DefaultUnitId, etc.

Both client and server services are registered; the MainViewModel selects the IModbusService implementation at runtime based on Mode.

Client Mode

Connect to an existing Modbus TCP server. Use this for testing and monitoring real devices.

Server Mode

Act as a Modbus TCP server for testing client applications. Configure the listening port and allowed Unit IDs.


Headless Runtime

ModbusForge.Headless is a cross-platform console poller for Linux, Windows, and other environments where a GUI is not available. It supports Modbus TCP, RTU, and ASCII, polls holding/input registers or coils/discrete inputs, and can forward every value to an MQTT broker.

Configuration

Configuration is read from appsettings.json and an optional environment-specific appsettings.<Environment>.json (for example appsettings.Production.json). Settings can also be supplied as command-line switches or as environment variables prefixed with MODBUSFORGE_.

Example appsettings.json:

{
  "Logging": {
    "Console": { "UseJson": false },
    "File": {
      "Path": "logs/modbusforge-headless.log",
      "RollingInterval": "Day",
      "FileSizeLimitBytes": 10485760,
      "RollOnFileSizeLimit": true,
      "RetainedFileCountLimit": 7
    },
    "LogLevel": { "Default": "Information", "Microsoft": "Warning" }
  },
  "Connection": {
    "Transport": "Tcp",
    "Host": "127.0.0.1",
    "Port": 502,
    "UnitId": 1,
    "ComPort": "COM1",
    "BaudRate": 9600,
    "Parity": "None",
    "DataBits": 8,
    "StopBits": "One",
    "RtsEnable": false
  },
  "Polling": {
    "Area": "HoldingRegister",
    "StartAddress": 0,
    "Count": 10,
    "IntervalMs": 1000
  },
  "Mqtt": {
    "Enabled": false,
    "BrokerHost": "localhost",
    "BrokerPort": 1883,
    "ClientId": "ModbusForge-Headless",
    "TopicTemplate": "modbusforge/{UnitId}/{Tag}",
    "QualityOfService": 0,
    "RetainMessages": false,
    "PublishPeriodMs": 1000
  }
}

Set Logging:Console:UseJson to true for JSON output to the console and to the log file.

Running a Simulation

A simulation graph saved from the visual node editor (.mfsim or .json) can be executed headlessly, which is useful for CI checks of simulation logic without the GUI:

ModbusForge.Headless --simulate path/to/program.mfsim

The graph runs on its saved scan period against the private offline data store (no device connection required). Add --simulate-steps <n> to stop automatically after n ticks, and --simulate-interval <ms> to override the scan period from the file. On shutdown the headless runtime dumps the final node values and every non-default register/bit to the log:

[12:00:03 INF] === Simulation final state ===
[12:00:03 INF]   IN (in1): true, 42
[12:00:03 INF]   Scale (scale1): true, 420
[12:00:03 INF]   HR* non-default:
HR[1] = 42
HR[2] = 420
[12:00:03 INF]   IR*: all default

--simulate replaces the normal polling/custom-watch service: the host runs the simulation instead of polling, on its own offline data store.

Run ModbusForge.Headless --help for a complete list of command-line switches.

Linux systemd service

Save the following to /etc/systemd/system/modbusforge-headless.service and adjust paths and MODBUSFORGE_CONNECTION__HOST as needed:

[Unit]
Description=ModbusForge Headless Modbus Poller
After=network.target

[Service]
Type=notify
WorkingDirectory=/opt/modbusforge
ExecStart=/opt/modbusforge/ModbusForge.Headless --environment Production
Restart=always
RestartSec=10
Environment="MODBUSFORGE_CONNECTION__HOST=192.168.1.100"
Environment="MODBUSFORGE_CONNECTION__PORT=502"
Environment="MODBUSFORGE_CONNECTION__UNITID=1"

[Install]
WantedBy=multi-user.target

Then enable and start it:

sudo systemctl daemon-reload
sudo systemctl enable --now modbusforge-headless

FAQ

Q: What operating systems are supported?

A: ModbusForge runs on Windows 10/11 and Linux using Avalonia and .NET 8.0. The headless runtime works on any platform .NET 8 supports.

Q: Do I need administrator privileges?

A: Only if you use the default Modbus port 502. Windows requires admin privileges to bind to ports below 1024. You can use a higher port number (e.g., 1502) to avoid this.

Q: Can I connect to multiple devices at once?

A: Yes, use the Connection Manager to create and manage multiple profiles. You can switch between active connections.

Q: Where are my settings saved?

A: Application settings are saved to %AppData%\ModbusForge\settings.json. Connection profiles are saved to %AppData%\ModbusForge\connection-profiles.json.

Q: How do I export trend data?

A: Open the Trends tab and use the Export CSV or Export PNG buttons in the Data group. Select a pen in the pen list to export just that series, or leave none selected to export everything.

Q: What file format does the Script Editor use?

A: Scripts are saved as .mbscript files in JSON format.

Q: The application won't connect to my device. What should I check?

A: Verify the IP address, port, and Unit ID. Ensure the device is reachable on the network and that your firewall allows the connection. Use the Connection Manager diagnostics or Help → Troubleshooting for more guidance.

Q: Is ModbusForge open source?

A: Yes, ModbusForge is open source. See the LICENSE file for details.


Contributing

We welcome contributions to ModbusForge! Here are some ways you can help:

Reporting Issues

  • Check existing issues first to avoid duplicates
  • Provide detailed steps to reproduce the problem
  • Include your ModbusForge version, Windows version, and .NET version
  • Attach screenshots or logs if applicable

Suggesting Features

  • Open a GitHub issue with the enhancement label
  • Describe the feature and its use case
  • Include mockups or examples if possible

Code Contributions

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/your-feature-name
  3. Make your changes following the existing code style
  4. Add tests if applicable
  5. Commit with clear messages
  6. Push to your fork and open a Pull Request

Code Style

  • Use ILogger for all logging (no Debug.WriteLine or custom file logging)
  • Use constants for magic numbers
  • Implement proper event handler cleanup to prevent memory leaks
  • Add input validation with visual feedback for user inputs

Build and Release

Below are PowerShell commands tested on Windows to produce a Release build and package artifacts.

Prerequisites

  • .NET 8.0 SDK
  • Visual Studio 2022 (17.0 or later) with .NET desktop development workload (optional)

Build (Release)

dotnet clean
dotnet restore
dotnet build ModbusForge.sln -c Release

Publish (Avalonia, self-contained, single-file)

$version = "2026.8.27"
dotnet publish .\ModbusForge\ModbusForge.csproj -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -p:PublishTrimmed=false -o .\publish\avalonia\win-x64

Create a ZIP Artifact

$version = "2026.8.27"
Compress-Archive -Path .\publish\avalonia\win-x64\* -DestinationPath .\ModbusForge-$version-win-x64.zip -Force

Create an Installer

& "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" /DAppVersion=2026.8.27 "setup\ModbusForge.iss"

Automated GitHub Release

Pushing a v* tag triggers .github/workflows/release.yml and creates a GitHub Release with Windows/Linux Avalonia packages, the headless runtime, checksums, and the installer. See AGENTS.md for the exact tag-and-version workflow.


Versioning

  • The window title displays the application version from the assembly ProductVersion.
  • ModbusForge uses a CalVer-style scheme: YYYY.M.INCREMENT (e.g. 2026.8.27).
    • YYYY = year
    • M = month (no leading zero)
    • INCREMENT = release number within that month, starting at 1
  • Tags are prefixed with v, e.g. v2026.8.27.
  • See FEATURE_ROADMAP.md for planned releases.

Support


Built by Reinach van Nieuwenhuizen

About

ModbusForge — .NET 8 Avalonia Modbus TCP/RTU/ASCII client/server with simulation, trending, and headless runtime (Windows & Linux).

Topics

Resources

Stars

17 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages