ModbusDirectConnect.psm1
|
# ModbusDirectConnect PowerShell Module # This module provides PowerShell cmdlets for the ModbusDirectConnect CLI # Get the path to the mbdc executable $script:ModbusCliPath = $null function Get-ModbusCliPath { if ($null -ne $script:ModbusCliPath -and (Test-Path $script:ModbusCliPath)) { return $script:ModbusCliPath } # Try to find mbdc in PATH $cliCommand = Get-Command mbdc -ErrorAction SilentlyContinue if ($cliCommand) { $script:ModbusCliPath = $cliCommand.Source return $script:ModbusCliPath } # Try to find in module directory $moduleDir = Split-Path -Parent $PSScriptRoot $possiblePaths = @( (Join-Path $moduleDir "ModbusDirectConnect.CLI\bin\Release\net10.0\mbdc.exe"), (Join-Path $moduleDir "ModbusDirectConnect.CLI\bin\Debug\net10.0\mbdc.exe"), (Join-Path $moduleDir "mbdc.exe"), (Join-Path $moduleDir "mbdc") ) foreach ($path in $possiblePaths) { if (Test-Path $path) { $script:ModbusCliPath = $path return $script:ModbusCliPath } } throw "mbdc executable not found. Please ensure it is installed and in your PATH, or set the path using Set-ModbusCliPath." } function Set-ModbusCliPath { <# .SYNOPSIS Sets the path to the mbdc executable .PARAMETER Path Full path to the mbdc executable #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string]$Path ) if (-not (Test-Path $Path)) { throw "The specified path does not exist: $Path" } $script:ModbusCliPath = $Path } function Invoke-ModbusCli { param( [string[]]$Arguments ) $cliPath = Get-ModbusCliPath # On Windows, use .exe; on Unix, use the dll with dotnet if ($IsWindows -or $PSVersionTable.PSVersion.Major -le 5) { & $cliPath @Arguments } else { # For cross-platform, try using dotnet $dllPath = $cliPath -replace '\.exe$', '.dll' if (Test-Path $dllPath) { & dotnet $dllPath @Arguments } else { & $cliPath @Arguments } } } function Get-ProtocolArgs { param( [string]$Protocol ) if ($Protocol -eq "rtu") { return @("--rtu") } return @() } function Convert-TimeoutMsToSeconds { param( [int]$Milliseconds ) if ($Milliseconds -lt 0) { throw "Timeout must be zero or greater." } return ([double]$Milliseconds / 1000).ToString("0.###", [System.Globalization.CultureInfo]::InvariantCulture) } function Get-ModbusCoil { <# .SYNOPSIS Reads coils from a Modbus device .PARAMETER Address Starting address to read from .PARAMETER Count Number of coils to read .PARAMETER Host Modbus host address (default: localhost) .PARAMETER Port Modbus port (default: 502) .PARAMETER SlaveId Modbus slave/unit ID (default: 1) .PARAMETER Timeout Connection timeout in milliseconds (default: 5000) .PARAMETER Protocol Protocol type: tcp or rtu (default: tcp) #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [uint16]$Address, [Parameter(Mandatory=$true)] [uint16]$Count, [string]$Host = "localhost", [int]$Port = 502, [byte]$SlaveId = 1, [int]$Timeout = 5000, [ValidateSet("tcp", "rtu")] [string]$Protocol = "tcp" ) $args = @( $Host, "--read-coil", $Address, "--count", $Count, "--port", $Port, "--slave", $SlaveId, "--timeout", (Convert-TimeoutMsToSeconds -Milliseconds $Timeout) ) + (Get-ProtocolArgs -Protocol $Protocol) Invoke-ModbusCli -Arguments $args } function Get-ModbusDiscreteInput { <# .SYNOPSIS Reads discrete inputs from a Modbus device .PARAMETER Address Starting address to read from .PARAMETER Count Number of discrete inputs to read .PARAMETER Host Modbus host address (default: localhost) .PARAMETER Port Modbus port (default: 502) .PARAMETER SlaveId Modbus slave/unit ID (default: 1) .PARAMETER Timeout Connection timeout in milliseconds (default: 5000) .PARAMETER Protocol Protocol type: tcp or rtu (default: tcp) #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [uint16]$Address, [Parameter(Mandatory=$true)] [uint16]$Count, [string]$Host = "localhost", [int]$Port = 502, [byte]$SlaveId = 1, [int]$Timeout = 5000, [ValidateSet("tcp", "rtu")] [string]$Protocol = "tcp" ) $args = @( $Host, "--read-discrete", $Address, "--count", $Count, "--port", $Port, "--slave", $SlaveId, "--timeout", (Convert-TimeoutMsToSeconds -Milliseconds $Timeout) ) + (Get-ProtocolArgs -Protocol $Protocol) Invoke-ModbusCli -Arguments $args } function Get-ModbusHoldingRegister { <# .SYNOPSIS Reads holding registers from a Modbus device .PARAMETER Address Starting address to read from .PARAMETER Count Number of holding registers to read .PARAMETER Host Modbus host address (default: localhost) .PARAMETER Port Modbus port (default: 502) .PARAMETER SlaveId Modbus slave/unit ID (default: 1) .PARAMETER Timeout Connection timeout in milliseconds (default: 5000) .PARAMETER Protocol Protocol type: tcp or rtu (default: tcp) #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [uint16]$Address, [Parameter(Mandatory=$true)] [uint16]$Count, [string]$Host = "localhost", [int]$Port = 502, [byte]$SlaveId = 1, [int]$Timeout = 5000, [ValidateSet("tcp", "rtu")] [string]$Protocol = "tcp" ) $args = @( $Host, "--read-holding", $Address, "--count", $Count, "--port", $Port, "--slave", $SlaveId, "--timeout", (Convert-TimeoutMsToSeconds -Milliseconds $Timeout) ) + (Get-ProtocolArgs -Protocol $Protocol) Invoke-ModbusCli -Arguments $args } function Get-ModbusInputRegister { <# .SYNOPSIS Reads input registers from a Modbus device .PARAMETER Address Starting address to read from .PARAMETER Count Number of input registers to read .PARAMETER Host Modbus host address (default: localhost) .PARAMETER Port Modbus port (default: 502) .PARAMETER SlaveId Modbus slave/unit ID (default: 1) .PARAMETER Timeout Connection timeout in milliseconds (default: 5000) .PARAMETER Protocol Protocol type: tcp or rtu (default: tcp) #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [uint16]$Address, [Parameter(Mandatory=$true)] [uint16]$Count, [string]$Host = "localhost", [int]$Port = 502, [byte]$SlaveId = 1, [int]$Timeout = 5000, [ValidateSet("tcp", "rtu")] [string]$Protocol = "tcp" ) $args = @( $Host, "--read-inputreg", $Address, "--count", $Count, "--port", $Port, "--slave", $SlaveId, "--timeout", (Convert-TimeoutMsToSeconds -Milliseconds $Timeout) ) + (Get-ProtocolArgs -Protocol $Protocol) Invoke-ModbusCli -Arguments $args } function Set-ModbusCoil { <# .SYNOPSIS Writes a single coil to a Modbus device .PARAMETER Address Address to write to .PARAMETER Value Boolean value to write .PARAMETER Host Modbus host address (default: localhost) .PARAMETER Port Modbus port (default: 502) .PARAMETER SlaveId Modbus slave/unit ID (default: 1) .PARAMETER Timeout Connection timeout in milliseconds (default: 5000) .PARAMETER Protocol Protocol type: tcp or rtu (default: tcp) #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [uint16]$Address, [Parameter(Mandatory=$true)] [bool]$Value, [string]$Host = "localhost", [int]$Port = 502, [byte]$SlaveId = 1, [int]$Timeout = 5000, [ValidateSet("tcp", "rtu")] [string]$Protocol = "tcp" ) $dataValue = if ($Value) { "1" } else { "0" } $args = @( $Host, "--write-coil", $Address, "--data", $dataValue, "--port", $Port, "--slave", $SlaveId, "--timeout", (Convert-TimeoutMsToSeconds -Milliseconds $Timeout) ) + (Get-ProtocolArgs -Protocol $Protocol) Invoke-ModbusCli -Arguments $args } function Set-ModbusRegister { <# .SYNOPSIS Writes a single holding register to a Modbus device .PARAMETER Address Address to write to .PARAMETER Value Register value to write (0-65535) .PARAMETER Host Modbus host address (default: localhost) .PARAMETER Port Modbus port (default: 502) .PARAMETER SlaveId Modbus slave/unit ID (default: 1) .PARAMETER Timeout Connection timeout in milliseconds (default: 5000) .PARAMETER Protocol Protocol type: tcp or rtu (default: tcp) #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [uint16]$Address, [Parameter(Mandatory=$true)] [uint16]$Value, [string]$Host = "localhost", [int]$Port = 502, [byte]$SlaveId = 1, [int]$Timeout = 5000, [ValidateSet("tcp", "rtu")] [string]$Protocol = "tcp" ) $args = @( $Host, "--write-reg", $Address, "--data", $Value, "--port", $Port, "--slave", $SlaveId, "--timeout", (Convert-TimeoutMsToSeconds -Milliseconds $Timeout) ) + (Get-ProtocolArgs -Protocol $Protocol) Invoke-ModbusCli -Arguments $args } function Set-ModbusCoils { <# .SYNOPSIS Writes multiple coils to a Modbus device .PARAMETER Address Starting address to write to .PARAMETER Values Array of boolean values to write .PARAMETER Host Modbus host address (default: localhost) .PARAMETER Port Modbus port (default: 502) .PARAMETER SlaveId Modbus slave/unit ID (default: 1) .PARAMETER Timeout Connection timeout in milliseconds (default: 5000) .PARAMETER Protocol Protocol type: tcp or rtu (default: tcp) #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [uint16]$Address, [Parameter(Mandatory=$true)] [bool[]]$Values, [string]$Host = "localhost", [int]$Port = 502, [byte]$SlaveId = 1, [int]$Timeout = 5000, [ValidateSet("tcp", "rtu")] [string]$Protocol = "tcp" ) $valuesStr = ($Values | ForEach-Object { if ($_ ) { "1" } else { "0" } }) -join "," $args = @( $Host, "--write-multi-coil", $Address, "--data", $valuesStr, "--port", $Port, "--slave", $SlaveId, "--timeout", (Convert-TimeoutMsToSeconds -Milliseconds $Timeout) ) + (Get-ProtocolArgs -Protocol $Protocol) Invoke-ModbusCli -Arguments $args } function Set-ModbusRegisters { <# .SYNOPSIS Writes multiple holding registers to a Modbus device .PARAMETER Address Starting address to write to .PARAMETER Values Array of register values to write (0-65535) .PARAMETER Host Modbus host address (default: localhost) .PARAMETER Port Modbus port (default: 502) .PARAMETER SlaveId Modbus slave/unit ID (default: 1) .PARAMETER Timeout Connection timeout in milliseconds (default: 5000) .PARAMETER Protocol Protocol type: tcp or rtu (default: tcp) #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [uint16]$Address, [Parameter(Mandatory=$true)] [uint16[]]$Values, [string]$Host = "localhost", [int]$Port = 502, [byte]$SlaveId = 1, [int]$Timeout = 5000, [ValidateSet("tcp", "rtu")] [string]$Protocol = "tcp" ) $valuesStr = $Values -join "," $args = @( $Host, "--write-multi-reg", $Address, "--data", $valuesStr, "--port", $Port, "--slave", $SlaveId, "--timeout", (Convert-TimeoutMsToSeconds -Milliseconds $Timeout) ) + (Get-ProtocolArgs -Protocol $Protocol) Invoke-ModbusCli -Arguments $args } # Export module members Export-ModuleMember -Function @( 'Get-ModbusCliPath', 'Set-ModbusCliPath', 'Get-ModbusCoil', 'Get-ModbusDiscreteInput', 'Get-ModbusHoldingRegister', 'Get-ModbusInputRegister', 'Set-ModbusCoil', 'Set-ModbusRegister', 'Set-ModbusCoils', 'Set-ModbusRegisters' ) |