<# .SYNOPSIS Launches the pymodbus simulator with one of the integration-test profiles (Standard or DL205). Foreground process — Ctrl+C to stop. .PARAMETER Profile Which simulator profile to run: 'standard' or 'dl205'. Both bind TCP 5020 by default so they can't run simultaneously on the same box. .PARAMETER HttpPort Port for pymodbus's optional web UI / REST API. Default 8080. Pass 0 to disable (passes --no_http). .EXAMPLE .\serve.ps1 -Profile standard Starts the standard server on TCP 5020 with web UI on 8080. .EXAMPLE .\serve.ps1 -Profile dl205 -HttpPort 0 Starts the DL205 server on TCP 5020, no web UI. #> [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateSet('standard', 'dl205')] [string]$Profile, [int]$HttpPort = 8080 ) $ErrorActionPreference = 'Stop' $here = $PSScriptRoot # Confirm pymodbus.simulator is on PATH — clearer message than the # 'CommandNotFoundException' dotnet style. $cmd = Get-Command pymodbus.simulator -ErrorAction SilentlyContinue if (-not $cmd) { Write-Error "pymodbus.simulator not found. Install with: pip install 'pymodbus[simulator]==3.13.0'" exit 1 } $jsonFile = Join-Path $here "$Profile.json" if (-not (Test-Path $jsonFile)) { Write-Error "Profile config not found: $jsonFile" exit 1 } $args = @( '--modbus_server', 'srv', '--modbus_device', 'dev', '--json_file', $jsonFile ) if ($HttpPort -gt 0) { $args += @('--http_port', $HttpPort) Write-Host "Web UI will be at http://localhost:$HttpPort" } else { $args += '--no_http' } Write-Host "Starting pymodbus simulator: profile=$Profile TCP=localhost:5020" Write-Host "Ctrl+C to stop." & pymodbus.simulator @args