6 Commits

130 changed files with 1100 additions and 650 deletions

View File

@@ -91,6 +91,7 @@ dotnet_naming_style.prefix_underscore.required_prefix = _
[*.cs]
csharp_preferred_modifier_order = public, private, protected, internal, static, extern, new, virtual, abstract, sealed, override, readonly, unsafe, volatile, async:suggestion
csharp_style_prefer_primary_constructors = false
# Only use "var" when it's obvious what the variable type is
csharp_style_var_for_built_in_types = false:warning
@@ -157,3 +158,6 @@ csharp_space_between_square_brackets = false
[*.{xml,csproj,targets,props,json,yml}]
indent_size = 2
indent_style = space
[*.{json,yml}]
end_of_line = lf

3
.gitignore vendored
View File

@@ -2,6 +2,9 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
docs/api
docs/_site
# User-specific files
*.suo
*.user

View File

@@ -22,8 +22,7 @@ build-debug:
script:
- shopt -s globstar
- mkdir ./artifacts
- dotnet restore --no-cache --force
- dotnet build -c Debug --nologo --no-restore --no-incremental
- dotnet build -c Debug --nologo
- mv ./**/*.nupkg ./artifacts/
- mv ./**/*.snupkg ./artifacts/
artifacts:
@@ -65,7 +64,7 @@ deploy-debug:
tags:
- docker
- lnx
- 64bit
- server
rules:
- if: $CI_COMMIT_TAG == null
script:
@@ -84,8 +83,7 @@ build-release:
script:
- shopt -s globstar
- mkdir ./artifacts
- dotnet restore --no-cache --force
- dotnet build -c Release --nologo --no-restore --no-incremental
- dotnet build -c Release --nologo
- mv ./**/*.nupkg ./artifacts/
- mv ./**/*.snupkg ./artifacts/
artifacts:
@@ -104,7 +102,6 @@ test-release:
- amd64
rules:
- if: $CI_COMMIT_TAG != null
coverage: /Branch coverage[\s\S].+%/
before_script:
- dotnet tool install dotnet-reportgenerator-globaltool --tool-path /dotnet-tools
script:
@@ -127,8 +124,34 @@ deploy-release:
tags:
- docker
- lnx
- 64bit
- server
rules:
- if: $CI_COMMIT_TAG != null
script:
- dotnet nuget push -k $NUGET_APIKEY -s https://api.nuget.org/v3/index.json --skip-duplicate artifacts/*.nupkg
publish-docs:
variables:
DOCFX_SOURCE_REPOSITORY_URL: "https://github.com/AM-WD/AMWD.Protocols.Modbus"
stage: deploy
tags:
- docker
- lnx
- server
rules:
- if: $CI_COMMIT_TAG != null
before_script:
- apt-get update
- apt-get -y install zip unzip
- dotnet tool install docfx --tool-path /dotnet-tools
script:
# Build the docs
- dotnet build -c Release --nologo
- /dotnet-tools/docfx metadata docs/docfx.json
- /dotnet-tools/docfx build docs/docfx.json
# Deploy the docs
- cd docs/_site
- zip -r ../docs.zip *
- curl --user "$DOCS_DEPLOY_USER:$DOCS_DEPLOY_PASS" -F docs=modbus -F dump=@../docs.zip "$DOCS_DEPLOY_URL"

View File

@@ -1,30 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net6.0;net8.0</TargetFrameworks>
<PackageId>AMWD.Protocols.Modbus.Tcp</PackageId>
<AssemblyName>amwd-modbus-tcp</AssemblyName>
<RootNamespace>AMWD.Protocols.Modbus.Tcp</RootNamespace>
<Product>Modbus TCP Protocol</Product>
<Description>Implementation of the Modbus protocol communicating via TCP.</Description>
<PackageTags>Modbus Protocol Network TCP LAN</PackageTags>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(SolutionDir)/AMWD.Protocols.Modbus.Common/Extensions/ArrayExtensions.cs" Link="Extensions/ArrayExtensions.cs" />
<Compile Include="$(SolutionDir)/AMWD.Protocols.Modbus.Common/Extensions/ReaderWriterLockSlimExtensions.cs" Link="Extensions/ReaderWriterLockSlimExtensions.cs" />
<Compile Include="$(SolutionDir)/AMWD.Protocols.Modbus.Common/Utils/AsyncQueue.cs" Link="Utils/AsyncQueue.cs" />
<Compile Include="$(SolutionDir)/AMWD.Protocols.Modbus.Common/Utils/RequestQueueItem.cs" Link="Utils/RequestQueueItem.cs" />
</ItemGroup>
<ItemGroup>
<None Include="README.md" Pack="true" PackagePath="/" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)\AMWD.Protocols.Modbus.Common\AMWD.Protocols.Modbus.Common.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,32 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<CollectCoverage>true</CollectCoverage>
<CoverletOutputFormat>Cobertura</CoverletOutputFormat>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<GenerateDocumentationFile>false</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.msbuild" Version="6.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="MSTest.TestAdapter" Version="3.7.2" />
<PackageReference Include="MSTest.TestFramework" Version="3.7.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)\AMWD.Protocols.Modbus.Common\AMWD.Protocols.Modbus.Common.csproj" />
<ProjectReference Include="$(SolutionDir)\AMWD.Protocols.Modbus.Serial\AMWD.Protocols.Modbus.Serial.csproj" />
<ProjectReference Include="$(SolutionDir)\AMWD.Protocols.Modbus.Tcp\AMWD.Protocols.Modbus.Tcp.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,5 +0,0 @@
global using System;
global using System.Linq;
global using AMWD.Protocols.Modbus.Common;
global using AMWD.Protocols.Modbus.Common.Contracts;
global using Microsoft.VisualStudio.TestTools.UnitTesting;

View File

@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34525.116
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AMWD.Protocols.Modbus.Common", "AMWD.Protocols.Modbus.Common\AMWD.Protocols.Modbus.Common.csproj", "{2B7689D8-9E56-4DEB-B40E-F70DB4A6F250}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AMWD.Protocols.Modbus.Common", "src\AMWD.Protocols.Modbus.Common\AMWD.Protocols.Modbus.Common.csproj", "{2B7689D8-9E56-4DEB-B40E-F70DB4A6F250}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0C43172F-63F3-455A-A5FC-CAE7492A969B}"
EndProject
@@ -29,15 +29,30 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{C8065AE3
Directory.Build.props = Directory.Build.props
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AMWD.Protocols.Modbus.Tests", "AMWD.Protocols.Modbus.Tests\AMWD.Protocols.Modbus.Tests.csproj", "{146070C4-E922-4F5A-AD6F-9A899186E26E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AMWD.Protocols.Modbus.Tests", "test\AMWD.Protocols.Modbus.Tests\AMWD.Protocols.Modbus.Tests.csproj", "{146070C4-E922-4F5A-AD6F-9A899186E26E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AMWD.Protocols.Modbus.Tcp", "AMWD.Protocols.Modbus.Tcp\AMWD.Protocols.Modbus.Tcp.csproj", "{8C888A84-CD09-4087-B5DA-67708ABBABA2}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AMWD.Protocols.Modbus.Tcp", "src\AMWD.Protocols.Modbus.Tcp\AMWD.Protocols.Modbus.Tcp.csproj", "{8C888A84-CD09-4087-B5DA-67708ABBABA2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AMWD.Protocols.Modbus.Serial", "AMWD.Protocols.Modbus.Serial\AMWD.Protocols.Modbus.Serial.csproj", "{D966826F-EE6C-4BC0-9185-C2A9A50FD586}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AMWD.Protocols.Modbus.Serial", "src\AMWD.Protocols.Modbus.Serial\AMWD.Protocols.Modbus.Serial.csproj", "{D966826F-EE6C-4BC0-9185-C2A9A50FD586}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CliClient", "CliClient\CliClient.csproj", "{B0E53462-B0ED-4685-8AA5-948DC160EE27}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CliClient", "tool\CliClient\CliClient.csproj", "{B0E53462-B0ED-4685-8AA5-948DC160EE27}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CliProxy", "CliProxy\CliProxy.csproj", "{AC922E80-E9B6-493D-B1D1-752527E883ED}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CliProxy", "tool\CliProxy\CliProxy.csproj", "{AC922E80-E9B6-493D-B1D1-752527E883ED}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
ProjectSection(SolutionItems) = preProject
src\Directory.Build.props = src\Directory.Build.props
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{0C2CC421-9808-4CA2-BEA8-11493467DBCE}"
ProjectSection(SolutionItems) = preProject
test\Directory.Build.props = test\Directory.Build.props
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tool", "tool", "{3429CE19-211E-4AFA-9629-D7E1A360B7AC}"
ProjectSection(SolutionItems) = preProject
tool\Directory.Build.props = tool\Directory.Build.props
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -74,9 +89,15 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{2B7689D8-9E56-4DEB-B40E-F70DB4A6F250} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{A5A9AEA2-3AFF-4536-9FF9-34663DA4D0AD} = {0C43172F-63F3-455A-A5FC-CAE7492A969B}
{2ED08B2B-1F72-4E1E-9586-1DC6BEFD7BA7} = {0C43172F-63F3-455A-A5FC-CAE7492A969B}
{C8065AE3-BA87-49AC-8100-C85D6DF7E436} = {0C43172F-63F3-455A-A5FC-CAE7492A969B}
{146070C4-E922-4F5A-AD6F-9A899186E26E} = {0C2CC421-9808-4CA2-BEA8-11493467DBCE}
{8C888A84-CD09-4087-B5DA-67708ABBABA2} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{D966826F-EE6C-4BC0-9185-C2A9A50FD586} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{B0E53462-B0ED-4685-8AA5-948DC160EE27} = {3429CE19-211E-4AFA-9629-D7E1A360B7AC}
{AC922E80-E9B6-493D-B1D1-752527E883ED} = {3429CE19-211E-4AFA-9629-D7E1A360B7AC}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E4FD8EF0-3594-4994-BE80-5FADA5EE17B4}

View File

@@ -7,7 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
_nothing changed yet_
### Added
- New automatic documentation generation using docfx.
- Additional articles for the documentation.
### Changed
- Reorganized folder structure to allow documentation generation.
## [v0.4.2] (2025-02-07)
### Fixed
- Fixing issue with R/W timeouts while processing client requests on the `ModbusTcpProxy`.
## [v0.4.1] (2025-02-06)
@@ -87,7 +102,8 @@ So this tag is only here for documentation purposes of the NuGet Gallery.
[Unreleased]: https://github.com/AM-WD/AMWD.Protocols.Modbus/compare/v0.4.1...HEAD
[Unreleased]: https://github.com/AM-WD/AMWD.Protocols.Modbus/compare/v0.4.2...HEAD
[v0.4.2]: https://github.com/AM-WD/AMWD.Protocols.Modbus/compare/v0.4.1...v0.4.2
[v0.4.1]: https://github.com/AM-WD/AMWD.Protocols.Modbus/compare/v0.4.0...v0.4.1
[v0.4.0]: https://github.com/AM-WD/AMWD.Protocols.Modbus/compare/v0.3.2...v0.4.0
[v0.3.2]: https://github.com/AM-WD/AMWD.Protocols.Modbus/compare/v0.3.1...v0.3.2

View File

@@ -1,34 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<AssemblyName>modbus-client</AssemblyName>
<RootNamespace>AMWD.Protocols.Modbus.CliClient</RootNamespace>
<Product>Modbus CLI client</Product>
<Description>Small CLI client for Modbus communication.</Description>
<IsPackable>false</IsPackable>
<SignAssembly>false</SignAssembly>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
<ItemGroup>
<None Remove="$(SolutionDir)/package-icon.png" />
<None Remove="$(SolutionDir)/LICENSE.txt" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.IO.Ports" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)\AMWD.Protocols.Modbus.Serial\AMWD.Protocols.Modbus.Serial.csproj" />
<ProjectReference Include="$(SolutionDir)\AMWD.Protocols.Modbus.Tcp\AMWD.Protocols.Modbus.Tcp.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,34 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<AssemblyName>modbus-proxy</AssemblyName>
<RootNamespace>AMWD.Protocols.Modbus.CliProxy</RootNamespace>
<Product>Modbus CLI proxy</Product>
<Description>Small CLI proxy to forward messages.</Description>
<IsPackable>false</IsPackable>
<SignAssembly>false</SignAssembly>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
<ItemGroup>
<None Remove="$(SolutionDir)/package-icon.png" />
<None Remove="$(SolutionDir)/LICENSE.txt" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.IO.Ports" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)\AMWD.Protocols.Modbus.Serial\AMWD.Protocols.Modbus.Serial.csproj" />
<ProjectReference Include="$(SolutionDir)\AMWD.Protocols.Modbus.Tcp\AMWD.Protocols.Modbus.Tcp.csproj" />
</ItemGroup>
</Project>

View File

@@ -3,60 +3,18 @@
<LangVersion>12.0</LangVersion>
<NrtRevisionFormat>{semvertag:main}{!:-dev}</NrtRevisionFormat>
<AppendTargetFrameworkToOutputPath>true</AppendTargetFrameworkToOutputPath>
<CopyRefAssembliesToPublishDirectory>false</CopyRefAssembliesToPublishDirectory>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/AM-WD/AMWD.Protocols.Modbus.git</RepositoryUrl>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<EmbedUntrackedSources>false</EmbedUntrackedSources>
<PackageIcon>package-icon.png</PackageIcon>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
<Title>Modbus Protocol for .NET</Title>
<Company>AM.WD</Company>
<Authors>Andreas Müller</Authors>
<Copyright>© {copyright:2018-} AM.WD</Copyright>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>$(SolutionDir)/AMWD.Protocols.Modbus.snk</AssemblyOriginatorKeyFile>
<PublicKey>0024000004800000940000000602000000240000525341310004000001000100adcc4f9f5bb3ac73cb30661f6f35772b8f90a74412925764a960af06ef125bdcec05ed1d139503d5203fb72aa3fa74bab58e82ac2a6cd4b650f8cbf7086a71bc2dfc67e95b8d26d776d60856acf3121f831529b1a4dee91b34ac84f95f71a1165b7783edb591929ba2a684100c92bbed8859c7266fb507f6f55bb6f7fcac80b4</PublicKey>
<MoqPublicKey>0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7</MoqPublicKey>
</PropertyGroup>
<PropertyGroup Condition="'$(GITLAB_CI)' == 'true'">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>
<ItemGroup Condition="'$(SignAssembly)' != 'true'">
<InternalsVisibleTo Include="AMWD.Protocols.Modbus.Tests" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
</ItemGroup>
<ItemGroup Condition="'$(SignAssembly)' == 'true'">
<InternalsVisibleTo Include="AMWD.Protocols.Modbus.Tests" PublicKey="0024000004800000940000000602000000240000525341310004000001000100adcc4f9f5bb3ac73cb30661f6f35772b8f90a74412925764a960af06ef125bdcec05ed1d139503d5203fb72aa3fa74bab58e82ac2a6cd4b650f8cbf7086a71bc2dfc67e95b8d26d776d60856acf3121f831529b1a4dee91b34ac84f95f71a1165b7783edb591929ba2a684100c92bbed8859c7266fb507f6f55bb6f7fcac80b4" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" PublicKey="0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7" />
</ItemGroup>
<ItemGroup Condition="'$(GITLAB_CI)' == 'true'">
<SourceLinkGitLabHost Include="$(CI_SERVER_HOST)" Version="$(CI_SERVER_VERSION)" />
<PackageReference Include="Microsoft.SourceLink.GitLab" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<None Include="$(SolutionDir)/package-icon.png" Pack="true" PackagePath="/" />
<None Include="$(SolutionDir)/LICENSE.txt" Pack="true" PackagePath="/" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AMWD.NetRevisionTask" Version="1.2.1">
<PackageReference Include="AMWD.NetRevisionTask" Version="1.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -39,13 +39,12 @@ It uses a specific TCP connection implementation and plugs all things from the C
Published under [MIT License] (see [choose a license])
[![Buy me a Coffee](https://shields.io/badge/PayPal-Buy_me_a_Coffee-yellow?style=flat&logo=paypal)](https://link.am-wd.de/donate)
[![built with Codeium](https://codeium.com/badges/main)](https://link.am-wd.de/codeium)
[see here]: https://github.com/andreasAMmueller/Modbus
[Common]: AMWD.Protocols.Modbus.Common/README.md
[Serial]: AMWD.Protocols.Modbus.Serial/README.md
[TCP]: AMWD.Protocols.Modbus.Tcp/README.md
[Common]: src/AMWD.Protocols.Modbus.Common/README.md
[Serial]: src/AMWD.Protocols.Modbus.Serial/README.md
[TCP]: src/AMWD.Protocols.Modbus.Tcp/README.md
[MIT License]: LICENSE.txt
[choose a license]: https://choosealicense.com/licenses/mit/

View File

@@ -0,0 +1,106 @@
# Getting Started
To begin, you need at least the [Common] package.
In this package you'll find everything you need to implement you own client as the package contains the protocol implementations (`TCP`, `RTU` and `ASCII`).
The [`ModbusClientBase`](~/api/AMWD.Protocols.Modbus.Common.Contracts.ModbusClientBase.yml) is the place, where most of the magic happens.
In this base client you have all known (and implemented) methods to request a device.
The Protocol implementations are the other magic place to be, as there the request will be converted into bits and bytes, before they get transfered.
## Using a TCP client
To use a TCP Modbus client, you need the [Common] package and the [TCP] package installed.
```cs
using AMWD.Protocols.Modbus.Common;
using AMWD.Protocols.Modbus.Common.Contracts;
using AMWD.Protocols.Modbus.Common.Protocols;
using AMWD.Protocols.Modbus.Tcp;
namespace ConsoleApp;
internal class Program
{
string hostname = "modbus-device.internal";
int port = 502;
byte unitId = 5;
ushort startAddress = 19000;
ushort count = 2;
using var client = new ModbusTcpClient(hostname, port);
await client.ConnectAsync(CancellationToken.None);
var holdingRegisters = await client.ReadHoldingRegistersAsync(unitId, startAddress, count);
float voltage = holdingRegisters.GetSingle();
Console.WriteLine($"The voltage of the device #{unitId} between L1 and N is {voltage:N2}V.");
}
```
This will automatically create a TCP client using the TCP protocol.
If you want to change the protocol sent over TCP, you can specify it:
```cs
// [...] other code
using var client = new ModbusTcpClient(hostname, port)
{
Protocol = new RtuProtocol()
};
// [...] other code
```
## Using a Serial client
To use a Serial Modbus client, you need the [Common] package and the [Serial] package installed.
```cs
using AMWD.Protocols.Modbus.Common;
using AMWD.Protocols.Modbus.Common.Contracts;
using AMWD.Protocols.Modbus.Common.Protocols;
using AMWD.Protocols.Modbus.Serial;
namespace ConsoleApp;
internal class Program
{
string serialPort = "/dev/ttyUSB0";
byte unitId = 5;
ushort startAddress = 19000;
ushort count = 2;
using var client = new ModbusSerialClient(serialPort);
await client.ConnectAsync(CancellationToken.None);
var holdingRegisters = await client.ReadHoldingRegistersAsync(unitId, startAddress, count);
float voltage = holdingRegisters.GetSingle();
Console.WriteLine($"The voltage of the device #{unitId} between L1 and N is {voltage:N2}V.");
}
```
This will automatically create a Serial client using the RTU protocol.
If you want to change the protocol sent over serial line, you can specify it:
```cs
// [...] other code
using var client = new ModbusSerialClient(serialPort)
{
Protocol = new AsciiProtocol()
};
// [...] other code
```
[Common]: https://www.nuget.org/packages/AMWD.Protocols.Modbus.Common
[Serial]: https://www.nuget.org/packages/AMWD.Protocols.Modbus.Serial
[TCP]: https://www.nuget.org/packages/AMWD.Protocols.Modbus.Tcp

View File

@@ -0,0 +1,20 @@
# Introduction
During my training, I came into contact with the Modbus protocol.
The implementation I developed at that time was very cumbersome and rigid.
There were huge inheritance hierarchies and the design was very confusing.
In 2018, I wanted to do better and completely redesigned the library.
After changing companies, this library could be integrated and tested under real-world conditions.
This quickly led to new challenges and some specific requirements were implemented.
This was the first time that both TCP and the RTU protocol were fully implemented.
However, the structure of the library also revealed problems and was too rigid for the requirements.
Therefore, in 2024, there was a new development from scratch, which now exists and has already been tested by some eager people THANK YOU SO MUCH!
The focus is, of course, on the development of the protocol and the clients. However, a server implementation (TCP/RTU) is also available.
For detailed changes of the current development, see the [CHANGELOG].
[CHANGELOG]: https://github.com/AM-WD/AMWD.Protocols.Modbus/blob/main/CHANGELOG.md

8
docs/articles/toc.yml Normal file
View File

@@ -0,0 +1,8 @@
- name: Introduction
href: introduction.md
- name: Getting Started
href: getting-started.md
- name: GitHub
href: https://github.com/AM-WD/AMWD.Protocols.Modbus
- name: NuGet
href: https://www.nuget.org/packages?q=AMWD.Protocols.Modbus

63
docs/docfx.json Normal file
View File

@@ -0,0 +1,63 @@
{
"$schema": "https://raw.githubusercontent.com/dotnet/docfx/main/schemas/docfx.schema.json",
"metadata": [
{
"src": [
{
"src": "../",
"files": [
"src/AMWD.Protocols.Modbus.Common/bin/Release/netstandard2.0/amwd-modbus-common.dll",
"src/AMWD.Protocols.Modbus.Serial/bin/Release/netstandard2.0/amwd-modbus-serial.dll",
"src/AMWD.Protocols.Modbus.Tcp/bin/Release/netstandard2.0/amwd-modbus-tcp.dll"
]
}
],
"dest": "api",
"outputFormat": "apiPage"
}
],
"build": {
"content": [
{
"files": [ "**/*.{md,yml}" ],
"exclude": [ "_site/**", "obj/**" ]
}
],
"resource": [
{
"files": [ "images/**" ],
"exclude": [ "_site/**", "obj/**" ]
}
],
"output": "_site",
"template": [ "default", "modern", "templates/amwd" ],
"postProcessors": ["ExtractSearchIndex"],
"globalMetadata": {
"_appName": "Protocol for .NET",
"_appTitle": "Modbus Protocol for .NET",
"_appFooter": "<span>&copy; AM.WD &mdash; Docs generated using <a href=\"https://dotnet.github.io/docfx\" target=\"_blank\">docfx</a>.</span>",
"_appLogoPath": "images/logo.svg",
"_appFaviconPath": "images/favicon.ico",
"_disableBreadcrumb": true,
"_disableContribution": true,
"_enableSearch": true,
"_enableNewTab": true,
"pdf": false
},
"markdownEngineName": "markdig",
"markdownEngineProperties": {
"alerts": {
"TODO": "alert alert-secondary"
}
},
"sitemap": {
"baseUrl": "https://docs.am-wd.de/modbus",
"priority": 0.5,
"changefreq": "weekly"
},
"noLangKeyword": false,
"keepFileLink": false,
"cleanupCacheHistory": false,
"disableGitFeatures": true
}
}

BIN
docs/images/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

168
docs/images/logo.svg Normal file
View File

@@ -0,0 +1,168 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="103.59954"
height="35"
viewBox="0 0 172.52591 58.286041"
version="1.1"
id="svg17631"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
sodipodi:docname="Logo of Modbus.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview17633"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="0.64052329"
inkscape:cx="352.0559"
inkscape:cy="108.50503"
inkscape:window-width="1850"
inkscape:window-height="1136"
inkscape:window-x="70"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs17628">
<clipPath
id="clip1">
<path
d="M 54,12.761719 H 76 V 34 H 54 Z m 0,0"
id="path619" />
</clipPath>
<clipPath
id="clip2">
<path
d="M 71,73 H 93 V 94.441406 H 71 Z m 0,0"
id="path622" />
</clipPath>
<clipPath
id="clip3">
<path
d="M 32.160156,35 H 54 V 57 H 32.160156 Z m 0,0"
id="path625" />
</clipPath>
<clipPath
id="clip4">
<path
d="m 247,46 h 26.92578 V 67 H 247 Z m 0,0"
id="path628" />
</clipPath>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-11.970621,-119.59261)">
<path
style="fill:#f5911c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.713609"
d="m 61.396335,149.27146 c 0,11.04421 -8.9452,20.00055 -19.983825,20.00055 -11.035839,0 -19.983816,-8.95634 -19.983816,-20.00055 0,-11.04698 8.947977,-20.00054 19.983816,-20.00054 11.038625,0 19.983825,8.95356 19.983825,20.00054"
id="path944" />
<path
style="fill:#fdbf0c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.713609"
d="m 64.409645,132.37902 c 0.14496,4.13949 -3.09137,7.61274 -7.22807,7.7577 -4.13669,0.14503 -7.60717,-3.09416 -7.75212,-7.23365 -0.14217,-4.13947 3.09416,-7.61275 7.22807,-7.7577 4.1367,-0.14504 7.60718,3.09415 7.75212,7.23365"
id="path946" />
<path
style="fill:#fdbf0c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.713609"
d="m 33.038765,164.56666 c 0.144956,4.13949 -3.091374,7.61274 -7.22807,7.7577 -4.136699,0.14503 -7.607177,-3.09416 -7.752129,-7.23365 -0.144956,-4.13949 3.091375,-7.61275 7.228071,-7.7577 4.136698,-0.14504 7.607177,3.09415 7.752128,7.23365"
id="path948" />
<g
clip-path="url(#clip1)"
clip-rule="nonzero"
id="g952"
transform="matrix(0.7136082,0,0,0.7136082,-10.979154,110.48574)">
<path
style="fill:#fdbf0c;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 69.574219,13.992188 c 5.121093,2.726562 7.066406,9.089843 4.339843,14.214843 -2.722656,5.125 -9.078124,7.070313 -14.199218,4.34375 -5.121094,-2.722656 -7.066406,-9.085937 -4.34375,-14.210937 2.722656,-5.125 9.082031,-7.074219 14.203125,-4.347656"
id="path950" />
</g>
<g
clip-path="url(#clip2)"
clip-rule="nonzero"
id="g956"
transform="matrix(0.7136082,0,0,0.7136082,-10.979154,110.48574)">
<path
style="fill:#fdbf0c;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 86.625,74.648438 c 5.121094,2.722656 7.0625,9.085937 4.339844,14.214843 -2.722656,5.121094 -9.078125,7.070313 -14.199219,4.34375 -5.121094,-2.722656 -7.066406,-9.089843 -4.34375,-14.214843 2.722656,-5.125 9.082031,-7.070313 14.203125,-4.34375"
id="path954" />
</g>
<g
clip-path="url(#clip3)"
clip-rule="nonzero"
id="g960"
transform="matrix(0.7136082,0,0,0.7136082,-10.979154,110.48574)">
<path
style="fill:#fdbf0c;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 37.097656,36.910156 c 4.917969,-3.074218 11.398438,-1.578125 14.472656,3.34375 3.074219,4.925782 1.578126,11.40625 -3.34375,14.484375 -4.917968,3.074219 -11.394531,1.578125 -14.46875,-3.34375 -3.074218,-4.921875 -1.578124,-11.40625 3.339844,-14.484375"
id="path958" />
</g>
<path
style="fill:#fdbf0c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.713609"
d="m 59.032505,147.92229 c 3.5095,-2.19377 8.13401,-1.12616 10.3278,2.38613 2.191,3.51229 1.12338,8.13959 -2.38613,10.33618 -3.5095,2.19377 -8.13123,1.12617 -10.32501,-2.38613 -2.19379,-3.51229 -1.12617,-8.13959 2.38334,-10.33618"
id="path962" />
<path
style="fill:#008cc7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.713609"
d="m 86.963565,148.26516 c -0.76378,0.61047 -1.06761,1.52758 -1.22094,2.44188 -0.15333,0.91711 -0.30662,2.14084 0,2.60077 0.30385,0.45436 1.83143,0.61046 1.83143,0.61046 h 3.5095 c 0,0 1.68087,0 2.44467,-0.45993 0.76377,-0.45715 0.91429,-1.37703 1.21814,-2.5952 0.30941,-1.22373 0.15333,-1.98751 0,-2.44467 -0.1505,-0.45993 -1.67809,-0.61047 -1.67809,-0.61047 h -3.96667 c 0,0 -1.37424,-0.15333 -2.13804,0.45716 z m 2.13804,-4.20359 h 5.03708 c 0,0 3.66282,-0.22858 5.03706,1.37704 1.374245,1.60562 0.68574,3.89418 0.45716,5.4998 -0.22858,1.60283 -0.68573,3.89418 -2.28856,5.27122 -1.60283,1.37425 -4.50186,1.45231 -5.64755,1.6781 -1.14567,0.23137 -6.94653,-0.0753 -6.94653,-0.0753 0,0 -2.67324,-0.0752 -4.35133,-1.8342 -0.65228,-0.68295 0,-3.43702 0.45716,-5.4998 0.45994,-2.05999 1.37425,-4.35132 2.7485,-5.27122 1.37425,-0.91709 5.49701,-1.14567 5.49701,-1.14567"
id="path964" />
<path
style="fill:#008cc7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.713609"
d="m 107.37108,148.28468 c -0.76377,0.61047 -1.07039,1.52756 -1.22093,2.44467 -0.15333,0.91709 -0.30383,2.13803 0,2.59518 0.30385,0.45996 1.8314,0.61327 1.8314,0.61327 h 3.50951 c 0,0 1.68088,0 2.44466,-0.45996 0.7638,-0.45715 0.91432,-1.37424 1.22094,-2.59518 0.30385,-1.22373 0.1505,-1.98751 0,-2.44467 -0.1505,-0.45995 -1.68089,-0.61326 -1.68089,-0.61326 h -3.96664 c 0,0 -1.37704,-0.1505 -2.13805,0.45995 z m 11.29229,-9.59748 h 4.73323 l -3.97222,19.09738 h -4.73323 l 0.15616,-1.9875 c 0,0 -0.092,0.61882 -1.8342,1.22373 -2.15755,0.74984 -3.8245,0.85298 -3.8245,0.85298 l -4.72485,-0.24252 c 0,0 -1.67531,0 -2.44188,-1.22093 -0.76101,-1.22373 -0.30385,-4.12556 0,-5.34929 0.30662,-1.22373 1.12338,-4.97295 2.7485,-6.11027 1.15404,-0.80838 2.44187,-1.0704 3.20567,-1.0704 0.76378,0 5.03706,0 5.03706,0 0,0 2.13805,0 2.74852,0.76378 0.61324,0.76378 1.0676,1.52756 1.0676,1.52756 l 1.8342,-7.48452"
id="path966" />
<path
style="fill:#008cc7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.713609"
d="m 130.42119,147.97804 c -0.76378,0.61047 -1.06763,1.52758 -1.22094,2.44467 -0.15333,0.91711 -0.30384,2.13805 0,2.59798 0.30383,0.45715 1.83141,0.61046 1.83141,0.61046 h 3.51229 c 0,0 1.6781,0 2.44188,-0.45993 0.76099,-0.45715 0.91709,-1.37424 1.22094,-2.59518 0.30383,-1.22373 0.1505,-1.98753 0,-2.44467 -0.15333,-0.45716 -1.6781,-0.61326 -1.6781,-0.61326 h -3.96945 c 0,0 -1.37425,-0.1505 -2.13803,0.45993 z m -2.44746,9.34661 -5.03706,0.15333 4.12277,-19.09459 h 4.73044 l -1.6781,7.63783 c 0,0 1.22094,-1.22652 2.59519,-1.68089 1.37147,-0.45993 4.57992,-0.61047 4.57992,-0.61047 0,0 3.51229,-0.15333 4.88375,0.7638 1.37425,0.9143 2.13802,1.83418 1.06763,5.95974 -1.06763,4.12276 -1.7422,5.2322 -2.89904,6.10748 -0.87807,0.669 -3.66281,1.37703 -5.80365,1.37703 -2.13246,0 -4.27328,0.1505 -6.10469,-2.59797 l -0.45716,1.98473"
id="path968" />
<path
style="fill:#008cc7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.713609"
d="m 146.64742,144.14798 h 5.03706 l -1.37425,6.45593 c -0.17558,1.02859 -0.87807,2.89066 0.68574,3.30601 1.98471,0.52964 5.94023,0.6272 7.19183,-1.87601 0.64393,-1.28783 2.04884,-7.88593 2.04884,-7.88593 h 4.73044 l -2.74851,13.6366 h -4.88654 l 0.76377,-2.59797 c 0,0 -0.91429,0.76378 -2.13523,1.37424 -1.22373,0.61327 -2.59521,1.53037 -5.80086,1.37704 -3.20845,-0.15333 -5.64755,-1.37704 -5.3437,-3.66837 0.30383,-2.29136 1.83141,-10.12154 1.83141,-10.12154"
id="path970" />
<g
clip-path="url(#clip4)"
clip-rule="nonzero"
id="g974"
transform="matrix(0.7136082,0,0,0.7136082,-10.979154,110.48574)">
<path
style="fill:#008cc7;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 267.16016,52.363281 h 6.63281 c 0,0 0.63281,-2.773437 -0.85156,-3.851562 -2.12891,-1.542969 -3.64063,-1.925781 -6.41797,-1.925781 -2.78516,0 -7.70313,0 -7.70313,0 0,0 -2.46484,0.08984 -5.13281,1.070312 -1.90625,0.699219 -3.42578,2.140625 -3.85156,5.136719 -0.42969,2.996093 0,4.710937 2.99218,5.351562 2.9961,0.644531 7.0625,0 7.0625,0 0,0 5.5586,-0.210937 6.41797,0.859375 0.85157,1.070313 0.42578,1.710938 -0.85937,2.351563 -1.28516,0.640625 -3.63281,0.855469 -5.5586,0.855469 -1.92578,0 -4.70703,0 -5.13671,-0.855469 -0.42579,-0.855469 -0.42579,-1.5 -0.42579,-1.5 h -6.41796 c 0,0 -1.07032,3 -0.21485,3.855469 0.85938,0.855468 0.85938,2.570312 8.98438,2.785156 8.1289,0.210937 8.14453,-0.234375 9.84375,-0.429688 1.69922,-0.199218 4.48437,-1.285156 5.5625,-3.640625 1.0664,-2.351562 1.37109,-5.894531 0.85547,-6.636719 -0.95704,-1.367187 -3.21094,-1.925781 -5.13672,-1.925781 -1.92578,0 -9.62891,-0.214843 -9.62891,-0.214843 0,0 -2.13672,0.214843 -1.92187,-1.285157 0.21093,-1.5 2.99609,-1.5 4.92187,-1.5 1.92188,0 5.13281,0.214844 5.77344,0.859375 0.64062,0.640625 0.21094,0.640625 0.21094,0.640625"
id="path972" />
</g>
<path
style="fill:#2bb34a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.713609"
d="m 40.481474,142.70405 c 0.730335,1.32964 1.87601,0.10033 1.87601,0.10033 l -1.485754,4.06981 -3.336677,-2.75966 c 0,0 1.608406,0.47945 1.569382,-1.03697 -0.04181,-1.51641 -1.970785,-8.63018 -2.701119,-9.95706 -0.730333,-1.32964 -1.876009,-0.10316 -1.876009,-0.10316 l 1.485753,-4.06701 3.336677,2.75687 c 0,0 -1.608406,-0.47666 -1.566592,1.03975 0.03902,1.51364 1.967998,8.62741 2.698329,9.95708"
id="path976" />
<path
style="fill:#2bb34a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.713609"
d="m 46.577808,165.27748 c 0.730337,1.32964 1.876007,0.10316 1.876007,0.10316 l -1.48575,4.06979 -3.336678,-2.75966 c 0,0 1.608406,0.47667 1.56938,-1.03974 -0.04181,-1.51364 -1.970786,-8.62741 -2.701119,-9.95708 -0.727546,-1.32685 -1.87601,-0.10033 -1.87601,-0.10033 l 1.485756,-4.06699 3.336675,2.75687 c 0,0 -1.608406,-0.47947 -1.56938,1.03696 0.04181,1.51641 1.970785,8.63018 2.701119,9.95706"
id="path978" />
<path
style="fill:#2bb34a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.713609"
d="m 46.608472,145.07624 c -0.786085,1.29618 0.850193,1.67807 0.850193,1.67807 l -4.264921,0.74428 0.719184,-4.27049 c 0,0 0.390254,1.6335 1.683669,0.84182 1.290628,-0.79444 6.481008,-6.02106 7.264308,-7.32004 0.78608,-1.29621 -0.8502,-1.6781 -0.8502,-1.6781 l 4.26493,-0.74428 -0.71919,4.27049 c 0,0 -0.39025,-1.63349 -1.68088,-0.83902 -1.29341,0.79165 -6.4838,6.02106 -7.267093,7.31727"
id="path980" />
<path
style="fill:#2bb34a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.713609"
d="m 30.123007,161.6481 c -0.786085,1.29621 0.847408,1.6781 0.847408,1.6781 l -4.262136,0.74707 0.719184,-4.2733 c 0,0 0.390254,1.63349 1.680882,0.84184 1.290628,-0.79445 6.48101,-6.02107 7.267095,-7.32007 0.786084,-1.2962 -0.850196,-1.6753 -0.850196,-1.6753 l 4.262136,-0.74705 -0.719184,4.27049 c 0,0 -0.387466,-1.63349 -1.680882,-0.84184 -1.290626,0.79446 -6.481012,6.02385 -7.264307,7.32006"
id="path982" />
<path
style="fill:#2bb34a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.713609"
d="m 47.617555,151.57117 c -1.516416,-0.0307 -1.02581,1.57497 -1.02581,1.57497 l -2.779169,-3.31996 4.055859,-1.51083 c 0,0 -1.218152,1.15402 0.11429,1.87601 1.33244,0.72197 8.4518,2.60633 9.96543,2.63979 1.51642,0.0307 1.0286,-1.57775 1.0286,-1.57775 l 2.77638,3.32274 -4.05586,1.51085 c 0,0 1.21815,-1.15405 -0.11429,-1.87601 -1.33244,-0.72199 -8.4518,-2.60635 -9.96543,-2.63981"
id="path984" />
<path
style="fill:#2bb34a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.713609"
d="m 25.03576,145.56963 c -1.516418,-0.0334 -1.028599,1.57495 -1.028599,1.57495 l -2.77917,-3.32274 4.055858,-1.51085 c 0,0 -1.21815,1.15405 0.11429,1.87601 1.335227,0.72197 8.451798,2.60913 9.968214,2.63979 1.51363,0.0334 1.025811,-1.57495 1.025811,-1.57495 l 2.776384,3.32273 -4.05586,1.51085 c 0,0 1.22094,-1.15404 -0.111498,-1.8788 -1.332442,-0.71917 -8.451798,-2.60633 -9.965428,-2.63699"
id="path986" />
<path
style="fill:#008cc7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.713609"
d="m 44.501097,157.93789 h 5.954168 l 2.97708,-13.51952 5.03707,13.29094 h 5.03708 l 10.76544,-13.29094 -2.7485,13.51952 h 5.49422 l 4.35134,-19.01932 h -9.15983 l -9.61698,11.68534 -4.34856,-11.91671 h -9.61977 l -4.122758,19.25069"
id="path988" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

26
docs/index.md Normal file
View File

@@ -0,0 +1,26 @@
---
_layout: landing
---
# Modbus Protocol for .NET
This library implements the basic Modbus protocol specified at [modbus.org](https://modbus.org/tech.php).
The aim was to include all necessary steps to have a fully working client, which is capable of the common protocol versions.
## NuGet packages
Here is an overview of the latest packages.
| Package Url | Version | Short description |
|-------------|---------|-------------------|
| [AMWD.Protocols.Modbus.Common] | ![NuGet Version: Common](https://img.shields.io/nuget/v/AMWD.Protocols.Modbus.Common?style=flat-square&logo=nuget) | Common data for Modbus protocol. |
| [AMWD.Protocols.Modbus.Serial] | ![NuGet Version: Serial](https://img.shields.io/nuget/v/AMWD.Protocols.Modbus.Serial?style=flat-square&logo=nuget) | Implementation of the Modbus protocol communicating via serial line using RTU or ASCII encoding. |
| [AMWD.Protocols.Modbus.Tcp] | ![NuGet Version: TCP](https://img.shields.io/nuget/v/AMWD.Protocols.Modbus.Tcp?style=flat-square&logo=nuget) | Implementation of the Modbus protocol communicating via TCP. |
[AMWD.Protocols.Modbus.Common]: https://www.nuget.org/packages/AMWD.Protocols.Modbus.Common
[AMWD.Protocols.Modbus.Serial]: https://www.nuget.org/packages/AMWD.Protocols.Modbus.Serial
[AMWD.Protocols.Modbus.Tcp]: https://www.nuget.org/packages/AMWD.Protocols.Modbus.Tcp

3
docs/templates/amwd/public/main.css vendored Normal file
View File

@@ -0,0 +1,3 @@
#logo {
margin-right: 8px;
}

4
docs/toc.yml Normal file
View File

@@ -0,0 +1,4 @@
- name: API
href: api/
- name: Articles
href: articles/

View File

@@ -1,8 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net6.0;net8.0</TargetFrameworks>
<PackageId>AMWD.Protocols.Modbus.Common</PackageId>
<AssemblyName>amwd-modbus-common</AssemblyName>
<RootNamespace>AMWD.Protocols.Modbus.Common</RootNamespace>
@@ -12,8 +10,4 @@
<PackageTags>Modbus Protocol</PackageTags>
</PropertyGroup>
<ItemGroup>
<None Include="README.md" Pack="true" PackagePath="/" />
</ItemGroup>
</Project>

View File

@@ -1,8 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net6.0;net8.0</TargetFrameworks>
<PackageId>AMWD.Protocols.Modbus.Serial</PackageId>
<AssemblyName>amwd-modbus-serial</AssemblyName>
<RootNamespace>AMWD.Protocols.Modbus.Serial</RootNamespace>
@@ -13,14 +11,10 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="$(SolutionDir)/AMWD.Protocols.Modbus.Common/Extensions/ArrayExtensions.cs" Link="Extensions/ArrayExtensions.cs" />
<Compile Include="$(SolutionDir)/AMWD.Protocols.Modbus.Common/Extensions/ReaderWriterLockSlimExtensions.cs" Link="Extensions/ReaderWriterLockSlimExtensions.cs" />
<Compile Include="$(SolutionDir)/AMWD.Protocols.Modbus.Common/Utils/AsyncQueue.cs" Link="Utils/AsyncQueue.cs" />
<Compile Include="$(SolutionDir)/AMWD.Protocols.Modbus.Common/Utils/RequestQueueItem.cs" Link="Utils/RequestQueueItem.cs" />
</ItemGroup>
<ItemGroup>
<None Include="README.md" Pack="true" PackagePath="/" />
<Compile Include="../AMWD.Protocols.Modbus.Common/Extensions/ArrayExtensions.cs" Link="Extensions/ArrayExtensions.cs" />
<Compile Include="../AMWD.Protocols.Modbus.Common/Extensions/ReaderWriterLockSlimExtensions.cs" Link="Extensions/ReaderWriterLockSlimExtensions.cs" />
<Compile Include="../AMWD.Protocols.Modbus.Common/Utils/AsyncQueue.cs" Link="Utils/AsyncQueue.cs" />
<Compile Include="../AMWD.Protocols.Modbus.Common/Utils/RequestQueueItem.cs" Link="Utils/RequestQueueItem.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
@@ -36,7 +30,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)\AMWD.Protocols.Modbus.Common\AMWD.Protocols.Modbus.Common.csproj" />
<ProjectReference Include="..\AMWD.Protocols.Modbus.Common\AMWD.Protocols.Modbus.Common.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PackageId>AMWD.Protocols.Modbus.Tcp</PackageId>
<AssemblyName>amwd-modbus-tcp</AssemblyName>
<RootNamespace>AMWD.Protocols.Modbus.Tcp</RootNamespace>
<Product>Modbus TCP Protocol</Product>
<Description>Implementation of the Modbus protocol communicating via TCP.</Description>
<PackageTags>Modbus Protocol Network TCP LAN</PackageTags>
</PropertyGroup>
<ItemGroup>
<Compile Include="../AMWD.Protocols.Modbus.Common/Extensions/ArrayExtensions.cs" Link="Extensions/ArrayExtensions.cs" />
<Compile Include="../AMWD.Protocols.Modbus.Common/Extensions/ReaderWriterLockSlimExtensions.cs" Link="Extensions/ReaderWriterLockSlimExtensions.cs" />
<Compile Include="../AMWD.Protocols.Modbus.Common/Utils/AsyncQueue.cs" Link="Utils/AsyncQueue.cs" />
<Compile Include="../AMWD.Protocols.Modbus.Common/Utils/RequestQueueItem.cs" Link="Utils/RequestQueueItem.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AMWD.Protocols.Modbus.Common\AMWD.Protocols.Modbus.Common.csproj" />
</ItemGroup>
</Project>

View File

@@ -213,23 +213,32 @@ namespace AMWD.Protocols.Modbus.Tcp
{
var requestBytes = new List<byte>();
// Waiting for next request
byte[] headerBytes = await stream.ReadExpectedBytesAsync(6, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
requestBytes.AddRange(headerBytes);
ushort length = headerBytes
.Skip(4).Take(2).ToArray()
.GetBigEndianUInt16();
// Waiting for the remaining required data
using (var cts = new CancellationTokenSource(ReadWriteTimeout))
using (cancellationToken.Register(cts.Cancel))
{
byte[] headerBytes = await stream.ReadExpectedBytesAsync(6, cts.Token).ConfigureAwait(continueOnCapturedContext: false);
requestBytes.AddRange(headerBytes);
ushort length = headerBytes
.Skip(4).Take(2).ToArray()
.GetBigEndianUInt16();
byte[] bodyBytes = await stream.ReadExpectedBytesAsync(length, cts.Token).ConfigureAwait(continueOnCapturedContext: false);
requestBytes.AddRange(bodyBytes);
}
byte[] responseBytes = await HandleRequestAsync([.. requestBytes], cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
if (responseBytes != null)
await stream.WriteAsync(responseBytes, 0, responseBytes.Length, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
{
// Write response when available
using (var cts = new CancellationTokenSource(ReadWriteTimeout))
using (cancellationToken.Register(cts.Cancel))
{
await stream.WriteAsync(responseBytes, 0, responseBytes.Length, cts.Token).ConfigureAwait(continueOnCapturedContext: false);
}
}
}
}
catch

50
src/Directory.Build.props Normal file
View File

@@ -0,0 +1,50 @@
<Project>
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net6.0;net8.0</TargetFrameworks>
<AppendTargetFrameworkToOutputPath>true</AppendTargetFrameworkToOutputPath>
<CopyRefAssembliesToPublishDirectory>false</CopyRefAssembliesToPublishDirectory>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/AM-WD/AMWD.Protocols.Modbus.git</RepositoryUrl>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<EmbedUntrackedSources>false</EmbedUntrackedSources>
<PackageIcon>package-icon.png</PackageIcon>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
<PackageProjectUrl>https://modbus.org/tech.php</PackageProjectUrl>
<AssemblyOriginatorKeyFile>../../AMWD.Protocols.Modbus.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition="'$(GITLAB_CI)' == 'true'">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>
<ItemGroup Condition="'$(GITLAB_CI)' == 'true'">
<SourceLinkGitLabHost Include="$(CI_SERVER_HOST)" Version="$(CI_SERVER_VERSION)" />
<PackageReference Include="Microsoft.SourceLink.GitLab" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<None Include="../../package-icon.png" Pack="true" PackagePath="/" />
<None Include="../../LICENSE.txt" Pack="true" PackagePath="/" />
<None Include="README.md" Pack="true" PackagePath="/" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="AMWD.Protocols.Modbus.Tests" PublicKey="$(PublicKey)" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" PublicKey="$(MoqPublicKey)" />
</ItemGroup>
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)\..'))" />
</Project>

View File

@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup />
<ItemGroup>
<ProjectReference Include="..\..\src\AMWD.Protocols.Modbus.Serial\AMWD.Protocols.Modbus.Serial.csproj" />
<ProjectReference Include="..\..\src\AMWD.Protocols.Modbus.Tcp\AMWD.Protocols.Modbus.Tcp.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,8 +1,7 @@
using System.Collections.Generic;
using System.Text;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Moq;
using AMWD.Protocols.Modbus.Common.Contracts;
namespace AMWD.Protocols.Modbus.Tests.Common.Contracts
{
@@ -111,10 +110,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Contracts
IModbusConnection connection = null;
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => new ModbusClientBaseWrapper(connection));
Assert.ThrowsExactly<ArgumentNullException>(() => new ModbusClientBaseWrapper(connection));
}
[DataTestMethod]
[TestMethod]
[DataRow(true)]
[DataRow(false)]
public void ShouldAlsoDisposeConnection(bool disposeConnection)
@@ -159,7 +158,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Contracts
client.Dispose();
// Act + Assert
await Assert.ThrowsExceptionAsync<ObjectDisposedException>(() => client.ReadCoilsAsync(UNIT_ID, START_ADDRESS, READ_COUNT));
await Assert.ThrowsExactlyAsync<ObjectDisposedException>(() => client.ReadCoilsAsync(UNIT_ID, START_ADDRESS, READ_COUNT));
}
[TestMethod]
@@ -170,7 +169,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Contracts
client.Protocol = null;
// Act + Assert
await Assert.ThrowsExceptionAsync<ArgumentNullException>(() => client.ReadCoilsAsync(UNIT_ID, START_ADDRESS, READ_COUNT));
await Assert.ThrowsExactlyAsync<ArgumentNullException>(() => client.ReadCoilsAsync(UNIT_ID, START_ADDRESS, READ_COUNT));
}
#endregion Common/Connection/Assertions

View File

@@ -47,7 +47,7 @@
HoldingRegister[] registers = null;
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => registers.GetSingle(0));
Assert.ThrowsExactly<ArgumentNullException>(() => registers.GetSingle(0));
}
[TestMethod]
@@ -60,10 +60,10 @@
};
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => registers.GetSingle(0));
Assert.ThrowsExactly<ArgumentException>(() => registers.GetSingle(0));
}
[DataTestMethod]
[TestMethod]
[DataRow(1)]
[DataRow(-1)]
public void ShouldThrowArgumentOutOfRangeOnGetSingle(int startIndex)
@@ -76,7 +76,7 @@
};
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => registers.GetSingle(startIndex));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => registers.GetSingle(startIndex));
}
[TestMethod]
@@ -90,7 +90,7 @@
};
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => registers.GetSingle(0));
Assert.ThrowsExactly<ArgumentException>(() => registers.GetSingle(0));
}
[TestMethod]
@@ -139,7 +139,7 @@
HoldingRegister[] registers = null;
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => registers.GetDouble(0));
Assert.ThrowsExactly<ArgumentNullException>(() => registers.GetDouble(0));
}
[TestMethod]
@@ -154,10 +154,10 @@
};
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => registers.GetDouble(0));
Assert.ThrowsExactly<ArgumentException>(() => registers.GetDouble(0));
}
[DataTestMethod]
[TestMethod]
[DataRow(1)]
[DataRow(-1)]
public void ShouldThrowArgumentOutOfRangeOnGetDouble(int startIndex)
@@ -172,7 +172,7 @@
};
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => registers.GetDouble(startIndex));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => registers.GetDouble(startIndex));
}
[TestMethod]
@@ -188,7 +188,7 @@
};
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => registers.GetDouble(0));
Assert.ThrowsExactly<ArgumentException>(() => registers.GetDouble(0));
}
#endregion Modbus to value

View File

@@ -36,7 +36,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Extensions
Coil coil = null;
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => coil.GetBoolean());
Assert.ThrowsExactly<ArgumentNullException>(() => coil.GetBoolean());
}
[TestMethod]
@@ -98,7 +98,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Extensions
HoldingRegister[] list = null;
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => list.GetString(2));
Assert.ThrowsExactly<ArgumentNullException>(() => list.GetString(2));
}
[TestMethod]
@@ -108,10 +108,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Extensions
var registers = Array.Empty<HoldingRegister>();
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => registers.GetString(2));
Assert.ThrowsExactly<ArgumentException>(() => registers.GetString(2));
}
[DataTestMethod]
[TestMethod]
[DataRow(1)]
[DataRow(-1)]
public void ShouldThrowArgumentOutOfRangeOnString(int startIndex)
@@ -124,7 +124,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Extensions
};
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => registers.GetString(2, startIndex));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => registers.GetString(2, startIndex));
}
[TestMethod]
@@ -138,7 +138,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Extensions
};
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => registers.GetString(2));
Assert.ThrowsExactly<ArgumentException>(() => registers.GetString(2));
}
#endregion Modbus to value
@@ -263,7 +263,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Extensions
string str = null;
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => str.ToRegisters(100).ToArray());
Assert.ThrowsExactly<ArgumentNullException>(() => str.ToRegisters(100).ToArray());
}
#endregion Value to Modbus

View File

@@ -38,7 +38,7 @@
HoldingRegister register = null;
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => register.GetSByte());
Assert.ThrowsExactly<ArgumentNullException>(() => register.GetSByte());
}
[TestMethod]
@@ -48,7 +48,7 @@
var obj = new Coil();
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => obj.GetSByte());
Assert.ThrowsExactly<ArgumentException>(() => obj.GetSByte());
}
[TestMethod]
@@ -84,7 +84,7 @@
HoldingRegister register = null;
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => register.GetInt16());
Assert.ThrowsExactly<ArgumentNullException>(() => register.GetInt16());
}
[TestMethod]
@@ -94,7 +94,7 @@
var obj = new Coil();
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => obj.GetInt16());
Assert.ThrowsExactly<ArgumentException>(() => obj.GetInt16());
}
[TestMethod]
@@ -139,7 +139,7 @@
HoldingRegister[] registers = null;
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => registers.GetInt32(0));
Assert.ThrowsExactly<ArgumentNullException>(() => registers.GetInt32(0));
}
[TestMethod]
@@ -152,10 +152,10 @@
};
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => registers.GetInt32(0));
Assert.ThrowsExactly<ArgumentException>(() => registers.GetInt32(0));
}
[DataTestMethod]
[TestMethod]
[DataRow(1)]
[DataRow(-1)]
public void ShouldThrowArgumentOutOfRangeOnGetInt32(int startIndex)
@@ -168,7 +168,7 @@
};
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => registers.GetInt32(startIndex));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => registers.GetInt32(startIndex));
}
[TestMethod]
@@ -182,7 +182,7 @@
};
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => registers.GetInt32(0));
Assert.ThrowsExactly<ArgumentException>(() => registers.GetInt32(0));
}
[TestMethod]
@@ -231,7 +231,7 @@
HoldingRegister[] registers = null;
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => registers.GetInt64(0));
Assert.ThrowsExactly<ArgumentNullException>(() => registers.GetInt64(0));
}
[TestMethod]
@@ -246,10 +246,10 @@
};
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => registers.GetInt64(0));
Assert.ThrowsExactly<ArgumentException>(() => registers.GetInt64(0));
}
[DataTestMethod]
[TestMethod]
[DataRow(1)]
[DataRow(-1)]
public void ShouldThrowArgumentOutOfRangeOnGetInt64(int startIndex)
@@ -264,7 +264,7 @@
};
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => registers.GetInt64(startIndex));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => registers.GetInt64(startIndex));
}
[TestMethod]
@@ -280,7 +280,7 @@
};
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => registers.GetInt64(0));
Assert.ThrowsExactly<ArgumentException>(() => registers.GetInt64(0));
}
#endregion Modbus to value

View File

@@ -38,7 +38,7 @@
HoldingRegister register = null;
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => register.GetByte());
Assert.ThrowsExactly<ArgumentNullException>(() => register.GetByte());
}
[TestMethod]
@@ -48,7 +48,7 @@
var obj = new Coil();
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => obj.GetByte());
Assert.ThrowsExactly<ArgumentException>(() => obj.GetByte());
}
[TestMethod]
@@ -84,7 +84,7 @@
HoldingRegister register = null;
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => register.GetUInt16());
Assert.ThrowsExactly<ArgumentNullException>(() => register.GetUInt16());
}
[TestMethod]
@@ -94,7 +94,7 @@
var obj = new Coil();
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => obj.GetUInt16());
Assert.ThrowsExactly<ArgumentException>(() => obj.GetUInt16());
}
[TestMethod]
@@ -139,7 +139,7 @@
HoldingRegister[] registers = null;
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => registers.GetUInt32(0));
Assert.ThrowsExactly<ArgumentNullException>(() => registers.GetUInt32(0));
}
[TestMethod]
@@ -152,10 +152,10 @@
};
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => registers.GetUInt32(1));
Assert.ThrowsExactly<ArgumentException>(() => registers.GetUInt32(1));
}
[DataTestMethod]
[TestMethod]
[DataRow(1)]
[DataRow(-1)]
public void ShouldThrowArgumentOutOfRangeOnGetUInt32(int startIndex)
@@ -168,7 +168,7 @@
};
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => registers.GetUInt32(startIndex));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => registers.GetUInt32(startIndex));
}
[TestMethod]
@@ -182,7 +182,7 @@
};
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => registers.GetUInt32(0));
Assert.ThrowsExactly<ArgumentException>(() => registers.GetUInt32(0));
}
[TestMethod]
@@ -231,7 +231,7 @@
HoldingRegister[] registers = null;
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => registers.GetUInt64(0));
Assert.ThrowsExactly<ArgumentNullException>(() => registers.GetUInt64(0));
}
[TestMethod]
@@ -246,10 +246,10 @@
};
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => registers.GetUInt64(0));
Assert.ThrowsExactly<ArgumentException>(() => registers.GetUInt64(0));
}
[DataTestMethod]
[TestMethod]
[DataRow(1)]
[DataRow(-1)]
public void ShouldThrowArgumentOutOfRangeOnGetUInt64(int startIndex)
@@ -264,7 +264,7 @@
};
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => registers.GetUInt64(startIndex));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => registers.GetUInt64(startIndex));
}
[TestMethod]
@@ -280,7 +280,7 @@
};
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => registers.GetUInt64(0));
Assert.ThrowsExactly<ArgumentException>(() => registers.GetUInt64(0));
}
#endregion Modbus to value

View File

@@ -87,7 +87,7 @@
Assert.IsFalse(success);
}
[DataTestMethod]
[TestMethod]
[DataRow(0xFF)]
[DataRow(0x00)]
public void ShouldPrintPrettyString(int highByte)

View File

@@ -87,7 +87,7 @@
Assert.IsFalse(success);
}
[DataTestMethod]
[TestMethod]
[DataRow(0xFF)]
[DataRow(0x00)]
public void ShouldPrintPrettyString(int highByte)

View File

@@ -1,6 +1,5 @@
using System.Collections.Generic;
using AMWD.Protocols.Modbus.Common.Models;
using System.Reflection;
using AMWD.Protocols.Modbus.Common.Models;
namespace AMWD.Protocols.Modbus.Tests.Common.Models
{

View File

@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Text;
using System.Text;
using AMWD.Protocols.Modbus.Common.Protocols;
namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
@@ -29,7 +28,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
CollectionAssert.AreEqual(expectedBytes, bytes.ToArray());
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(2001)]
public void ShouldThrowOutOfRangeForCountOnSerializeReadCoils(int count)
@@ -38,7 +37,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadCoils(UNIT_ID, 19, (ushort)count));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadCoils(UNIT_ID, 19, (ushort)count));
}
[TestMethod]
@@ -48,7 +47,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadCoils(UNIT_ID, ushort.MaxValue, 2));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadCoils(UNIT_ID, ushort.MaxValue, 2));
}
[TestMethod]
@@ -92,7 +91,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.DeserializeReadCoils(responseBytes));
Assert.ThrowsExactly<ModbusException>(() => protocol.DeserializeReadCoils(responseBytes));
}
#endregion Read Coils
@@ -117,7 +116,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
CollectionAssert.AreEqual(expectedBytes, bytes.ToArray());
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(2001)]
public void ShouldThrowOutOfRangeForCountOnSerializeReadDiscreteInputs(int count)
@@ -126,7 +125,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadDiscreteInputs(UNIT_ID, 19, (ushort)count));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadDiscreteInputs(UNIT_ID, 19, (ushort)count));
}
[TestMethod]
@@ -136,7 +135,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadDiscreteInputs(UNIT_ID, ushort.MaxValue, 2));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadDiscreteInputs(UNIT_ID, ushort.MaxValue, 2));
}
[TestMethod]
@@ -180,7 +179,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.DeserializeReadDiscreteInputs(responseBytes));
Assert.ThrowsExactly<ModbusException>(() => protocol.DeserializeReadDiscreteInputs(responseBytes));
}
#endregion Read Discrete Inputs
@@ -205,7 +204,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
CollectionAssert.AreEqual(expectedBytes, bytes.ToArray());
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(2001)]
public void ShouldThrowOutOfRangeForCountOnSerializeReadHoldingRegisters(int count)
@@ -214,7 +213,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadHoldingRegisters(UNIT_ID, 19, (ushort)count));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadHoldingRegisters(UNIT_ID, 19, (ushort)count));
}
[TestMethod]
@@ -224,7 +223,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadHoldingRegisters(UNIT_ID, ushort.MaxValue, 2));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadHoldingRegisters(UNIT_ID, ushort.MaxValue, 2));
}
[TestMethod]
@@ -262,7 +261,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.DeserializeReadHoldingRegisters(responseBytes));
Assert.ThrowsExactly<ModbusException>(() => protocol.DeserializeReadHoldingRegisters(responseBytes));
}
#endregion Read Holding Registers
@@ -287,7 +286,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
CollectionAssert.AreEqual(expectedBytes, bytes.ToArray());
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(2001)]
public void ShouldThrowOutOfRangeForCountOnSerializeReadInputRegisters(int count)
@@ -296,7 +295,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadInputRegisters(UNIT_ID, 19, (ushort)count));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadInputRegisters(UNIT_ID, 19, (ushort)count));
}
[TestMethod]
@@ -306,7 +305,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadInputRegisters(UNIT_ID, ushort.MaxValue, 2));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadInputRegisters(UNIT_ID, ushort.MaxValue, 2));
}
[TestMethod]
@@ -344,14 +343,14 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.DeserializeReadInputRegisters(responseBytes));
Assert.ThrowsExactly<ModbusException>(() => protocol.DeserializeReadInputRegisters(responseBytes));
}
#endregion Read Input Registers
#region Read Device Identification
[DataTestMethod]
[TestMethod]
[DataRow(ModbusDeviceIdentificationCategory.Basic)]
[DataRow(ModbusDeviceIdentificationCategory.Regular)]
[DataRow(ModbusDeviceIdentificationCategory.Extended)]
@@ -380,10 +379,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadDeviceIdentification(UNIT_ID, (ModbusDeviceIdentificationCategory)10, ModbusDeviceIdentificationObject.ProductCode));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadDeviceIdentification(UNIT_ID, (ModbusDeviceIdentificationCategory)10, ModbusDeviceIdentificationObject.ProductCode));
}
[DataTestMethod]
[TestMethod]
[DataRow(false)]
[DataRow(true)]
public void ShouldDeserializeReadDeviceIdentification(bool moreAndIndividual)
@@ -420,7 +419,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.DeserializeReadDeviceIdentification(responseBytes));
Assert.ThrowsExactly<ModbusException>(() => protocol.DeserializeReadDeviceIdentification(responseBytes));
}
[TestMethod]
@@ -434,7 +433,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.DeserializeReadDeviceIdentification(responseBytes));
Assert.ThrowsExactly<ModbusException>(() => protocol.DeserializeReadDeviceIdentification(responseBytes));
}
#endregion Read Device Identification
@@ -467,7 +466,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => protocol.SerializeWriteSingleCoil(UNIT_ID, null));
Assert.ThrowsExactly<ArgumentNullException>(() => protocol.SerializeWriteSingleCoil(UNIT_ID, null));
}
[TestMethod]
@@ -519,7 +518,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => protocol.SerializeWriteSingleHoldingRegister(UNIT_ID, null));
Assert.ThrowsExactly<ArgumentNullException>(() => protocol.SerializeWriteSingleHoldingRegister(UNIT_ID, null));
}
[TestMethod]
@@ -578,10 +577,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, null));
Assert.ThrowsExactly<ArgumentNullException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, null));
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(1969)]
public void ShouldThrowOutOfRangeForCountOnSerializeWriteMultipleCoils(int count)
@@ -594,7 +593,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, coils));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, coils));
}
[TestMethod]
@@ -609,7 +608,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, coils));
Assert.ThrowsExactly<ArgumentException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, coils));
}
[TestMethod]
@@ -624,7 +623,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, coils));
Assert.ThrowsExactly<ArgumentException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, coils));
}
[TestMethod]
@@ -679,10 +678,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, null));
Assert.ThrowsExactly<ArgumentNullException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, null));
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(124)]
public void ShouldThrowOutOfRangeForCountOnSerializeWriteMultipleHoldingRegisters(int count)
@@ -695,7 +694,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers));
}
[TestMethod]
@@ -710,7 +709,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers));
Assert.ThrowsExactly<ArgumentException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers));
}
[TestMethod]
@@ -725,7 +724,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers));
Assert.ThrowsExactly<ArgumentException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers));
}
[TestMethod]
@@ -792,7 +791,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
Assert.IsFalse(complete);
}
[DataTestMethod]
[TestMethod]
[DataRow(0x01)]
[DataRow(0x02)]
[DataRow(0x03)]
@@ -809,7 +808,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
protocol.ValidateResponse(Encoding.ASCII.GetBytes(request), Encoding.ASCII.GetBytes(response));
}
[DataTestMethod]
[TestMethod]
[DataRow(0x05)]
[DataRow(0x06)]
[DataRow(0x0F)]
@@ -836,7 +835,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(Encoding.ASCII.GetBytes(request), Encoding.ASCII.GetBytes(response)));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(Encoding.ASCII.GetBytes(request), Encoding.ASCII.GetBytes(response)));
}
[TestMethod]
@@ -848,7 +847,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(Encoding.ASCII.GetBytes(request), Encoding.ASCII.GetBytes(response)));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(Encoding.ASCII.GetBytes(request), Encoding.ASCII.GetBytes(response)));
}
[TestMethod]
@@ -861,7 +860,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(Encoding.ASCII.GetBytes(request), Encoding.ASCII.GetBytes(response)));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(Encoding.ASCII.GetBytes(request), Encoding.ASCII.GetBytes(response)));
}
[TestMethod]
@@ -873,7 +872,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(Encoding.ASCII.GetBytes(request), Encoding.ASCII.GetBytes(response)));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(Encoding.ASCII.GetBytes(request), Encoding.ASCII.GetBytes(response)));
}
[TestMethod]
@@ -886,7 +885,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(Encoding.ASCII.GetBytes(request), Encoding.ASCII.GetBytes(response)));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(Encoding.ASCII.GetBytes(request), Encoding.ASCII.GetBytes(response)));
}
[TestMethod]
@@ -899,10 +898,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(Encoding.ASCII.GetBytes(request), Encoding.ASCII.GetBytes(response)));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(Encoding.ASCII.GetBytes(request), Encoding.ASCII.GetBytes(response)));
}
[DataTestMethod]
[TestMethod]
[DataRow(0x01)]
[DataRow(0x02)]
[DataRow(0x03)]
@@ -916,10 +915,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(Encoding.ASCII.GetBytes(request), Encoding.ASCII.GetBytes(response)));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(Encoding.ASCII.GetBytes(request), Encoding.ASCII.GetBytes(response)));
}
[DataTestMethod]
[TestMethod]
[DataRow(0x05)]
[DataRow(0x06)]
[DataRow(0x0F)]
@@ -933,7 +932,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new AsciiProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(Encoding.ASCII.GetBytes(request), Encoding.ASCII.GetBytes(response)));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(Encoding.ASCII.GetBytes(request), Encoding.ASCII.GetBytes(response)));
}
[TestMethod]
@@ -949,7 +948,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
Assert.AreEqual("F7", lrc);
}
[DataTestMethod]
[TestMethod]
[DataRow(null)]
[DataRow("")]
[DataRow(" ")]
@@ -959,10 +958,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
// Arrange
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => AsciiProtocol.LRC(msg));
Assert.ThrowsExactly<ArgumentNullException>(() => AsciiProtocol.LRC(msg));
}
[DataTestMethod]
[TestMethod]
[DataRow(-1)]
[DataRow(4)]
public void ShouldThrowArgumentOutOfRangeExceptionForStartOnLrc(int start)
@@ -971,10 +970,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
string msg = "0207";
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => AsciiProtocol.LRC(msg, start));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => AsciiProtocol.LRC(msg, start));
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(5)]
public void ShouldThrowArgumentOutOfRangeExceptionForLengthOnLrc(int length)
@@ -983,7 +982,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
string msg = "0207";
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => AsciiProtocol.LRC(msg, 0, length));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => AsciiProtocol.LRC(msg, 0, length));
}
[TestMethod]
@@ -993,7 +992,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
string msg = "0207";
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => AsciiProtocol.LRC(msg));
Assert.ThrowsExactly<ArgumentException>(() => AsciiProtocol.LRC(msg));
}
#endregion Validation

View File

@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Reflection;
using System.Reflection;
using AMWD.Protocols.Modbus.Common.Protocols;
namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
@@ -52,7 +51,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
// CRC check will be ignored
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(2001)]
public void ShouldThrowOutOfRangeForCountOnSerializeReadCoils(int count)
@@ -61,7 +60,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadCoils(UNIT_ID, 19, (ushort)count));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadCoils(UNIT_ID, 19, (ushort)count));
}
[TestMethod]
@@ -71,7 +70,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadCoils(UNIT_ID, ushort.MaxValue, 2));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadCoils(UNIT_ID, ushort.MaxValue, 2));
}
[TestMethod]
@@ -106,7 +105,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.DeserializeReadCoils([0x00, 0x01, 0x00, 0x00, 0x00, 0x08, UNIT_ID, 0x01, 0x02, 0xCD, 0x6B, 0x05, 0x00, 0x00]));
Assert.ThrowsExactly<ModbusException>(() => protocol.DeserializeReadCoils([0x00, 0x01, 0x00, 0x00, 0x00, 0x08, UNIT_ID, 0x01, 0x02, 0xCD, 0x6B, 0x05, 0x00, 0x00]));
}
#endregion Read Coils
@@ -154,7 +153,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
// CRC check will be ignored
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(2001)]
public void ShouldThrowOutOfRangeForCountOnSerializeReadDiscreteInputs(int count)
@@ -163,7 +162,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadDiscreteInputs(UNIT_ID, 19, (ushort)count));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadDiscreteInputs(UNIT_ID, 19, (ushort)count));
}
[TestMethod]
@@ -173,7 +172,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadDiscreteInputs(UNIT_ID, ushort.MaxValue, 2));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadDiscreteInputs(UNIT_ID, ushort.MaxValue, 2));
}
[TestMethod]
@@ -208,7 +207,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.DeserializeReadDiscreteInputs([0x00, 0x01, 0x00, 0x00, 0x00, 0x08, UNIT_ID, 0x02, 0x02, 0xCD, 0x6B, 0x05, 0x00, 0x00]));
Assert.ThrowsExactly<ModbusException>(() => protocol.DeserializeReadDiscreteInputs([0x00, 0x01, 0x00, 0x00, 0x00, 0x08, UNIT_ID, 0x02, 0x02, 0xCD, 0x6B, 0x05, 0x00, 0x00]));
}
#endregion Read Discrete Inputs
@@ -256,7 +255,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
// CRC check will be ignored
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(126)]
public void ShouldThrowOutOfRangeForCountOnSerializeReadHoldingRegisters(int count)
@@ -265,7 +264,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadHoldingRegisters(UNIT_ID, 19, (ushort)count));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadHoldingRegisters(UNIT_ID, 19, (ushort)count));
}
[TestMethod]
@@ -275,7 +274,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadHoldingRegisters(UNIT_ID, ushort.MaxValue, 2));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadHoldingRegisters(UNIT_ID, ushort.MaxValue, 2));
}
[TestMethod]
@@ -305,7 +304,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.DeserializeReadHoldingRegisters([0x00, 0x01, 0x00, 0x00, 0x00, 0x08, UNIT_ID, 0x03, 0x04, 0x02, 0x2B, 0x00, 0x00]));
Assert.ThrowsExactly<ModbusException>(() => protocol.DeserializeReadHoldingRegisters([0x00, 0x01, 0x00, 0x00, 0x00, 0x08, UNIT_ID, 0x03, 0x04, 0x02, 0x2B, 0x00, 0x00]));
}
#endregion Read Holding Registers
@@ -353,7 +352,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
// CRC check will be ignored
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(126)]
public void ShouldThrowOutOfRangeForCountOnSerializeReadInputRegisters(int count)
@@ -362,7 +361,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadInputRegisters(UNIT_ID, 19, (ushort)count));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadInputRegisters(UNIT_ID, 19, (ushort)count));
}
[TestMethod]
@@ -372,7 +371,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadInputRegisters(UNIT_ID, ushort.MaxValue, 2));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadInputRegisters(UNIT_ID, ushort.MaxValue, 2));
}
[TestMethod]
@@ -402,14 +401,14 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.DeserializeReadInputRegisters([0x00, 0x01, 0x00, 0x00, 0x00, 0x08, UNIT_ID, 0x04, 0x04, 0x02, 0x2B, 0x00, 0x00]));
Assert.ThrowsExactly<ModbusException>(() => protocol.DeserializeReadInputRegisters([0x00, 0x01, 0x00, 0x00, 0x00, 0x08, UNIT_ID, 0x04, 0x04, 0x02, 0x2B, 0x00, 0x00]));
}
#endregion Read Input Registers
#region Read Device Identification
[DataTestMethod]
[TestMethod]
[DataRow(ModbusDeviceIdentificationCategory.Basic)]
[DataRow(ModbusDeviceIdentificationCategory.Regular)]
[DataRow(ModbusDeviceIdentificationCategory.Extended)]
@@ -463,10 +462,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadDeviceIdentification(UNIT_ID, (ModbusDeviceIdentificationCategory)10, ModbusDeviceIdentificationObject.ProductCode));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadDeviceIdentification(UNIT_ID, (ModbusDeviceIdentificationCategory)10, ModbusDeviceIdentificationObject.ProductCode));
}
[DataTestMethod]
[TestMethod]
[DataRow(false)]
[DataRow(true)]
public void ShouldDeserializeReadDeviceIdentification(bool moreAndIndividual)
@@ -497,7 +496,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.DeserializeReadDeviceIdentification(response));
Assert.ThrowsExactly<ModbusException>(() => protocol.DeserializeReadDeviceIdentification(response));
}
[TestMethod]
@@ -508,7 +507,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.DeserializeReadDeviceIdentification(response));
Assert.ThrowsExactly<ModbusException>(() => protocol.DeserializeReadDeviceIdentification(response));
}
#endregion Read Device Identification
@@ -565,7 +564,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => protocol.SerializeWriteSingleCoil(UNIT_ID, null));
Assert.ThrowsExactly<ArgumentNullException>(() => protocol.SerializeWriteSingleCoil(UNIT_ID, null));
}
[TestMethod]
@@ -638,7 +637,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => protocol.SerializeWriteSingleHoldingRegister(UNIT_ID, null));
Assert.ThrowsExactly<ArgumentNullException>(() => protocol.SerializeWriteSingleHoldingRegister(UNIT_ID, null));
}
[TestMethod]
@@ -724,10 +723,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, null));
Assert.ThrowsExactly<ArgumentNullException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, null));
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(1969)]
public void ShouldThrowOutOfRangeForCountOnSerializeWriteMultipleCoils(int count)
@@ -740,7 +739,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, coils));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, coils));
}
[TestMethod]
@@ -755,7 +754,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, coils));
Assert.ThrowsExactly<ArgumentException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, coils));
}
[TestMethod]
@@ -770,7 +769,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, coils));
Assert.ThrowsExactly<ArgumentException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, coils));
}
[TestMethod]
@@ -855,10 +854,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, null));
Assert.ThrowsExactly<ArgumentNullException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, null));
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(124)]
public void ShouldThrowOutOfRangeForCountOnSerializeWriteMultipleHoldingRegisters(int count)
@@ -871,7 +870,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers));
}
[TestMethod]
@@ -886,7 +885,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers));
Assert.ThrowsExactly<ArgumentException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers));
}
[TestMethod]
@@ -901,7 +900,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers));
Assert.ThrowsExactly<ArgumentException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers));
}
[TestMethod]
@@ -991,7 +990,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
protocol.ValidateResponse(request, response);
}
[DataTestMethod]
[TestMethod]
[DataRow(0x00, 0x00)]
[DataRow(0x01, 0x01)]
public void ShouldThrowForTransactionIdOnValidateResponse(int hi, int lo)
@@ -1003,10 +1002,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(request, response));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(request, response));
}
[DataTestMethod]
[TestMethod]
[DataRow(0x00, 0x01)]
[DataRow(0x01, 0x00)]
public void ShouldThrowForProtocolIdOnValidateResponse(int hi, int lo)
@@ -1018,7 +1017,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(request, response));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(request, response));
}
[TestMethod]
@@ -1031,7 +1030,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(request, response));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(request, response));
}
[TestMethod]
@@ -1044,7 +1043,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(request, response));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(request, response));
}
[TestMethod]
@@ -1057,7 +1056,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(request, response));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(request, response));
}
[TestMethod]
@@ -1070,10 +1069,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(request, response));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(request, response));
}
[DataTestMethod]
[TestMethod]
[DataRow(0x59, 0x6C)]
[DataRow(0x58, 0x6B)]
public void ShouldThrowForCrcOnValidateResponse(int hi, int lo)
@@ -1084,7 +1083,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuOverTcpProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(request, response));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(request, response));
}
#endregion Validation

View File

@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Text;
using System.Text;
using AMWD.Protocols.Modbus.Common.Protocols;
namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
@@ -40,7 +39,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
// CRC check will be ignored
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(2001)]
public void ShouldThrowOutOfRangeForCountOnSerializeReadCoils(int count)
@@ -49,7 +48,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadCoils(UNIT_ID, 19, (ushort)count));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadCoils(UNIT_ID, 19, (ushort)count));
}
[TestMethod]
@@ -59,7 +58,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadCoils(UNIT_ID, ushort.MaxValue, 2));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadCoils(UNIT_ID, ushort.MaxValue, 2));
}
[TestMethod]
@@ -94,7 +93,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.DeserializeReadCoils([UNIT_ID, 0x01, 0x02, 0xCD, 0x6B, 0x05, 0x00, 0x00]));
Assert.ThrowsExactly<ModbusException>(() => protocol.DeserializeReadCoils([UNIT_ID, 0x01, 0x02, 0xCD, 0x6B, 0x05, 0x00, 0x00]));
}
#endregion Read Coils
@@ -130,7 +129,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
// CRC check will be ignored
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(2001)]
public void ShouldThrowOutOfRangeForCountOnSerializeReadDiscreteInputs(int count)
@@ -139,7 +138,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadDiscreteInputs(UNIT_ID, 19, (ushort)count));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadDiscreteInputs(UNIT_ID, 19, (ushort)count));
}
[TestMethod]
@@ -149,7 +148,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadDiscreteInputs(UNIT_ID, ushort.MaxValue, 2));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadDiscreteInputs(UNIT_ID, ushort.MaxValue, 2));
}
[TestMethod]
@@ -184,7 +183,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.DeserializeReadDiscreteInputs([UNIT_ID, 0x02, 0x02, 0xCD, 0x6B, 0x05, 0x00, 0x00]));
Assert.ThrowsExactly<ModbusException>(() => protocol.DeserializeReadDiscreteInputs([UNIT_ID, 0x02, 0x02, 0xCD, 0x6B, 0x05, 0x00, 0x00]));
}
#endregion Read Discrete Inputs
@@ -220,7 +219,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
// CRC check will be ignored
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(126)]
public void ShouldThrowOutOfRangeForCountOnSerializeReadHoldingRegisters(int count)
@@ -229,7 +228,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadHoldingRegisters(UNIT_ID, 19, (ushort)count));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadHoldingRegisters(UNIT_ID, 19, (ushort)count));
}
[TestMethod]
@@ -239,7 +238,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadHoldingRegisters(UNIT_ID, ushort.MaxValue, 2));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadHoldingRegisters(UNIT_ID, ushort.MaxValue, 2));
}
[TestMethod]
@@ -269,7 +268,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.DeserializeReadHoldingRegisters([UNIT_ID, 0x03, 0x04, 0x02, 0x2B, 0x00, 0x00]));
Assert.ThrowsExactly<ModbusException>(() => protocol.DeserializeReadHoldingRegisters([UNIT_ID, 0x03, 0x04, 0x02, 0x2B, 0x00, 0x00]));
}
#endregion Read Holding Registers
@@ -305,7 +304,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
// CRC check will be ignored
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(126)]
public void ShouldThrowOutOfRangeForCountOnSerializeReadInputRegisters(int count)
@@ -314,7 +313,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadInputRegisters(UNIT_ID, 19, (ushort)count));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadInputRegisters(UNIT_ID, 19, (ushort)count));
}
[TestMethod]
@@ -324,7 +323,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadInputRegisters(UNIT_ID, ushort.MaxValue, 2));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadInputRegisters(UNIT_ID, ushort.MaxValue, 2));
}
[TestMethod]
@@ -354,14 +353,14 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.DeserializeReadInputRegisters([UNIT_ID, 0x04, 0x04, 0x02, 0x2B, 0x00, 0x00]));
Assert.ThrowsExactly<ModbusException>(() => protocol.DeserializeReadInputRegisters([UNIT_ID, 0x04, 0x04, 0x02, 0x2B, 0x00, 0x00]));
}
#endregion Read Input Registers
#region Read Device Identification
[DataTestMethod]
[TestMethod]
[DataRow(ModbusDeviceIdentificationCategory.Basic)]
[DataRow(ModbusDeviceIdentificationCategory.Regular)]
[DataRow(ModbusDeviceIdentificationCategory.Extended)]
@@ -403,10 +402,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeReadDeviceIdentification(UNIT_ID, (ModbusDeviceIdentificationCategory)10, ModbusDeviceIdentificationObject.ProductCode));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeReadDeviceIdentification(UNIT_ID, (ModbusDeviceIdentificationCategory)10, ModbusDeviceIdentificationObject.ProductCode));
}
[DataTestMethod]
[TestMethod]
[DataRow(false)]
[DataRow(true)]
public void ShouldDeserializeReadDeviceIdentification(bool moreAndIndividual)
@@ -437,7 +436,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.DeserializeReadDeviceIdentification(response));
Assert.ThrowsExactly<ModbusException>(() => protocol.DeserializeReadDeviceIdentification(response));
}
[TestMethod]
@@ -448,7 +447,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.DeserializeReadDeviceIdentification(response));
Assert.ThrowsExactly<ModbusException>(() => protocol.DeserializeReadDeviceIdentification(response));
}
#endregion Read Device Identification
@@ -493,7 +492,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => protocol.SerializeWriteSingleCoil(UNIT_ID, null));
Assert.ThrowsExactly<ArgumentNullException>(() => protocol.SerializeWriteSingleCoil(UNIT_ID, null));
}
[TestMethod]
@@ -554,7 +553,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => protocol.SerializeWriteSingleHoldingRegister(UNIT_ID, null));
Assert.ThrowsExactly<ArgumentNullException>(() => protocol.SerializeWriteSingleHoldingRegister(UNIT_ID, null));
}
[TestMethod]
@@ -628,10 +627,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, null));
Assert.ThrowsExactly<ArgumentNullException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, null));
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(1969)]
public void ShouldThrowOutOfRangeForCountOnSerializeWriteMultipleCoils(int count)
@@ -644,7 +643,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, coils));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, coils));
}
[TestMethod]
@@ -659,7 +658,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, coils));
Assert.ThrowsExactly<ArgumentException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, coils));
}
[TestMethod]
@@ -674,7 +673,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, coils));
Assert.ThrowsExactly<ArgumentException>(() => protocol.SerializeWriteMultipleCoils(UNIT_ID, coils));
}
[TestMethod]
@@ -747,10 +746,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, null));
Assert.ThrowsExactly<ArgumentNullException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, null));
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(124)]
public void ShouldThrowOutOfRangeForCountOnSerializeWriteMultipleHoldingRegisters(int count)
@@ -763,7 +762,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers));
}
[TestMethod]
@@ -778,7 +777,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers));
Assert.ThrowsExactly<ArgumentException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers));
}
[TestMethod]
@@ -793,7 +792,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ArgumentException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers));
Assert.ThrowsExactly<ArgumentException>(() => protocol.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers));
}
[TestMethod]
@@ -857,7 +856,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
Assert.IsTrue(complete);
}
[DataTestMethod]
[TestMethod]
[DataRow(0x01)] // Read Coils
[DataRow(0x02)] // Read Discrete Inputs
[DataRow(0x03)] // Read Holding Registers
@@ -875,7 +874,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
Assert.IsFalse(complete);
}
[DataTestMethod]
[TestMethod]
[DataRow(0x01)] // Read Coils
[DataRow(0x02)] // Read Discrete Inputs
[DataRow(0x03)] // Read Holding Registers
@@ -893,7 +892,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
Assert.IsTrue(complete);
}
[DataTestMethod]
[TestMethod]
[DataRow(0x05)] // Write Single Coil
[DataRow(0x06)] // Write Single Register
[DataRow(0x0F)] // Write Multiple Coils
@@ -911,7 +910,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
Assert.IsFalse(complete);
}
[DataTestMethod]
[TestMethod]
[DataRow(0x05)] // Write Single Coil
[DataRow(0x06)] // Write Single Register
[DataRow(0x0F)] // Write Multiple Coils
@@ -999,7 +998,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
Assert.IsTrue(complete);
}
[DataTestMethod]
[TestMethod]
[DataRow(0x01)]
[DataRow(0x02)]
[DataRow(0x03)]
@@ -1016,7 +1015,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
protocol.ValidateResponse(request, response);
}
[DataTestMethod]
[TestMethod]
[DataRow(0x05)]
[DataRow(0x06)]
[DataRow(0x0F)]
@@ -1043,10 +1042,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(request, response));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(request, response));
}
[DataTestMethod]
[TestMethod]
[DataRow(0x57, 0x6C)]
[DataRow(0x58, 0x6B)]
public void ShouldThrowForCrcOnValidateResponse(int hi, int lo)
@@ -1057,7 +1056,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(request, response));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(request, response));
}
[TestMethod]
@@ -1070,7 +1069,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(request, response));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(request, response));
}
[TestMethod]
@@ -1083,10 +1082,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(request, response));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(request, response));
}
[DataTestMethod]
[TestMethod]
[DataRow(0x01)]
[DataRow(0x02)]
[DataRow(0x03)]
@@ -1100,10 +1099,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(request, response));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(request, response));
}
[DataTestMethod]
[TestMethod]
[DataRow(0x05)]
[DataRow(0x06)]
[DataRow(0x0F)]
@@ -1117,7 +1116,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
var protocol = new RtuProtocol();
// Act + Assert
Assert.ThrowsException<ModbusException>(() => protocol.ValidateResponse(request, response));
Assert.ThrowsExactly<ModbusException>(() => protocol.ValidateResponse(request, response));
}
[TestMethod]
@@ -1137,7 +1136,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
Assert.AreEqual(0x12, crc[1]);
}
[DataTestMethod]
[TestMethod]
[DataRow(null)]
[DataRow(new byte[0])]
public void ShuldThrowArgumentNullExceptionForBytesOnCrc16(byte[] bytes)
@@ -1145,10 +1144,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
// Arrange
// Act + Assert
Assert.ThrowsException<ArgumentNullException>(() => RtuProtocol.CRC16(bytes));
Assert.ThrowsExactly<ArgumentNullException>(() => RtuProtocol.CRC16(bytes));
}
[DataTestMethod]
[TestMethod]
[DataRow(-1)]
[DataRow(10)]
public void ShouldThrowArgumentOutOfRangeForStartOnCrc16(int start)
@@ -1157,10 +1156,10 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
byte[] bytes = Encoding.UTF8.GetBytes("0123456789");
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => RtuProtocol.CRC16(bytes, start));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => RtuProtocol.CRC16(bytes, start));
}
[DataTestMethod]
[TestMethod]
[DataRow(0)]
[DataRow(11)]
public void ShouldThrowArgumentOutOfRangeForLengthOnCrc16(int length)
@@ -1169,7 +1168,7 @@ namespace AMWD.Protocols.Modbus.Tests.Common.Protocols
byte[] bytes = Encoding.UTF8.GetBytes("0123456789");
// Act + Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() => RtuProtocol.CRC16(bytes, 0, length));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => RtuProtocol.CRC16(bytes, 0, length));
}
#endregion Validation

Some files were not shown because too many files have changed in this diff Show More