Skip to content

Commit

Permalink
Merge commit 'e22a3f68191bd38d42a0f7fb284e752e9515b66c'
Browse files Browse the repository at this point in the history
  • Loading branch information
Apollo3zehn committed Feb 21, 2024
1 parent 0e9f2da commit 9445453
Show file tree
Hide file tree
Showing 30 changed files with 528 additions and 282 deletions.
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# How to format:
# (1) Add dotnet_diagnostic.XXXX.severity = error
# (2) Run dotnet-format: dotnet format --diagnostics XXXX

[*.cs]
# "run cleanup": https://betterprogramming.pub/enforce-net-code-style-with-editorconfig-d2f0d79091ac
# TODO: build real editorconfig file: https://github.com/dotnet/roslyn/blob/main/.editorconfig
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/build-and-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
with:
name: artifacts
path: |
artifacts/packages/
artifacts/package/release/
artifacts/tag_body.txt
outputs:
Expand All @@ -70,7 +70,7 @@ jobs:
path: artifacts

- name: Nuget package (MyGet)
run: dotnet nuget push 'artifacts/packages/*.nupkg' --api-key ${MYGET_API_KEY} --source https://www.myget.org/F/apollo3zehn-dev/api/v3/index.json
run: dotnet nuget push 'artifacts/package/release/*.nupkg' --api-key ${MYGET_API_KEY} --source https://www.myget.org/F/apollo3zehn-dev/api/v3/index.json
env:
MYGET_API_KEY: ${{ secrets.MYGET_API_KEY }}

Expand All @@ -96,6 +96,6 @@ jobs:
body_path: artifacts/tag_body.txt

- name: Nuget package (Nuget)
run: dotnet nuget push 'artifacts/packages/*.nupkg' --api-key ${NUGET_API_KEY} --source https://api.nuget.org/v3/index.json
run: dotnet nuget push 'artifacts/package/release/*.nupkg' --api-key ${NUGET_API_KEY} --source https://api.nuget.org/v3/index.json
env:
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
11 changes: 3 additions & 8 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,15 @@
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (console)",
"name": "Sample: TCP",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/artifacts/bin/SampleServerClientTcp/net6.0/SampleServerClientTcp.dll",
"program": "${workspaceFolder}/artifacts/bin/SampleServerClientTcp/SampleServerClientTcp.dll",
"args": [],
"cwd": "${workspaceFolder}/sample/SampleServerClientTcp",
"console": "internalConsole",
"console": "externalTerminal",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
## v5.1.0 - 2024-02-21

### Features
- Add option for raising event even if values of buffer have not changed (#96)
- support for WriteMultipleCoils (#111)

### Bugs Fixed
- Fixed propagation of cancellationToken (#100)
- Fixed exception for malformed messages (#101)
- typo in ModbusClient docstring (#95)
- SampleServerClientTCP broken? (#102)

## v5.0.3 - 2023-08-03

- The Modbus TCP server now returns the received unit identifier even when its own unit identifier is set to zero (the default) (solves #93).
Expand Down
13 changes: 4 additions & 9 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,16 @@

<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworkVersion>net6.0</TargetFrameworkVersion>
<TargetFrameworkVersion>net8.0</TargetFrameworkVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<LangVersion>latest</LangVersion>
<RestoreAdditionalProjectSources>
https://www.myget.org/F/apollo3zehn-dev/api/v3/index.json
</RestoreAdditionalProjectSources>
</PropertyGroup>

<PropertyGroup>
<ArtifactsPath>$([MSBuild]::NormalizePath($(MSBuildThisFileDirectory)artifacts))</ArtifactsPath>
<BaseIntermediateOutputPath>$(ArtifactsPath)/obj/$(MSBuildProjectName)</BaseIntermediateOutputPath>
<IntermediateOutputPath>$(BaseIntermediateOutputPath)/$(Configuration)</IntermediateOutputPath>
<OutputPath>$(ArtifactsPath)/bin/$(MSBuildProjectName)/$(Configuration)</OutputPath>
<PackageOutputPath>$(ArtifactsPath)/packages</PackageOutputPath>
<UseArtifactsOutput>true</UseArtifactsOutput>
<ArtifactsPath>$(MSBuildThisFileDirectory)artifacts</ArtifactsPath>
</PropertyGroup>

</Project>
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ FluentModbus is a .NET Standard library (2.0 and 2.1) that provides Modbus TCP/R
* FC06: WriteSingleRegister

#### Class 2:
* FC15: WriteMultipleCoils
* FC23: ReadWriteMultipleRegisters

Please see the [introduction](https://apollo3zehn.github.io/FluentModbus/) to get a more detailed description on how to use this library!
Expand Down
4 changes: 2 additions & 2 deletions build/print_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

build = sys.argv[1]
is_final_build = sys.argv[2] == "true"
as_pypi_version = sys.argv[3] == "true"
version_type = sys.argv[3]

if is_final_build:
build = None

print(version.get_version(build, as_pypi_version))
print(version.get_version(build, version_type))
1 change: 0 additions & 1 deletion build/release.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import itertools
import subprocess
import sys
import re
Expand Down
6 changes: 3 additions & 3 deletions build/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
from typing import Optional


def get_version(build: Optional[str], as_pypi_version: bool = False) -> str:
def get_version(build: Optional[str], version_type: str = "default") -> str:

with open("version.json", "r") as fh:
version_data = json.load(fh)

# version
version = version_data["version"]
suffix = version_data["suffix"]
Expand All @@ -17,7 +17,7 @@ def get_version(build: Optional[str], as_pypi_version: bool = False) -> str:
if build:

# PEP440 does not support SemVer versioning (https://semver.org/#spec-item-9)
if as_pypi_version:
if version_type == "pypi":
version = f"{version}{int(build):03d}"

else:
Expand Down
2 changes: 1 addition & 1 deletion doc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ client.Connect();
client.Connect(IPAddress.Parse("127.0.0.1"));

// use specified IP adress and port
client.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 502))
client.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 502));
```

## Modbus RTU client
Expand Down
2 changes: 1 addition & 1 deletion sample/SampleServerClientTcp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ static void DoClientWork(ModbusTcpClient client, ILogger logger)
Span<byte> data;

var sleepTime = TimeSpan.FromMilliseconds(100);
var unitIdentifier = 0xFF;
var unitIdentifier = 0x00;
var startingAddress = 0;
var registerAddress = 0;

Expand Down
4 changes: 3 additions & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<Project>

<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />

<Import Project="Directory.Build.props.overrides" Condition="exists('Directory.Build.props.overrides')" />

<PropertyGroup>
<DebugSymbols>true</DebugSymbols>
<DebugType>embedded</DebugType>
Expand All @@ -10,6 +11,7 @@
</PropertyGroup>

<PropertyGroup Condition="$(VERSION) != ''">
<InformationalVersion>$(VERSION)+$(GITHUB_SHA)</InformationalVersion>
<AssemblyVersion>$(VERSION.Split('.')[0]).0.0.0</AssemblyVersion>
<FileVersion>$(VERSION.Split('.')[0]).$(VERSION.Split('.')[1]).$(VERSION.Split('.')[2].Split('-')[0]).0</FileVersion>
</PropertyGroup>
Expand Down
77 changes: 53 additions & 24 deletions src/FluentModbus/Client/ModbusClient.cs
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Runtime.InteropServices;
using System.Collections;
using System.Runtime.InteropServices;

namespace FluentModbus
{
Expand Down Expand Up @@ -71,7 +72,7 @@ internal void ProcessError(ModbusFunctionCode functionCode, ModbusExceptionCode
throw new ModbusException(exceptionCode, ErrorMessage.ModbusClient_0x0B_GatewayTargetDeviceFailedToRespond);

default:
throw new ArgumentOutOfRangeException(ErrorMessage.ModbusClient_InvalidExceptionCode);
throw new ModbusException(exceptionCode, string.Format(ErrorMessage.ModbusClient_Unknown_Error, (int)exceptionCode));
}
}

Expand Down Expand Up @@ -152,12 +153,12 @@ public Span<byte> ReadHoldingRegisters(byte unitIdentifier, ushort startingAddre
writer.Write(startingAddress); // 08-09 Starting Address
writer.Write(quantity); // 10-11 Quantity of Input Registers
}
}).Slice(2);
});

if (buffer.Length < quantity * 2)
if (buffer.Length < quantity * 2 + 2)
throw new ModbusException(ErrorMessage.ModbusClient_InvalidResponseMessageLength);

return buffer;
return buffer.Slice(2);
}

/// <summary>
Expand Down Expand Up @@ -199,13 +200,11 @@ public void WriteMultipleRegisters(byte unitIdentifier, ushort startingAddress,
{
writer.WriteReverse(startingAddress); // 08-09 Starting Address
writer.WriteReverse((ushort)quantity); // 10-11 Quantity of Registers

}
else
{
writer.Write(startingAddress); // 08-09 Starting Address
writer.Write((ushort)quantity); // 10-11 Quantity of Registers

}

writer.Write((byte)(quantity * 2)); // 12 Byte Count = Quantity of Registers * 2
Expand Down Expand Up @@ -242,16 +241,16 @@ public Span<byte> ReadCoils(int unitIdentifier, int startingAddress, int quantit
writer.Write(startingAddress_converted); // 08-09 Starting Address
writer.Write(quantity_converted); // 10-11 Quantity of Coils
}
}).Slice(2);
});

if (buffer.Length < (byte)Math.Ceiling((double)quantity_converted / 8))
if (buffer.Length < (byte)Math.Ceiling((double)quantity_converted / 8) + 2)
throw new ModbusException(ErrorMessage.ModbusClient_InvalidResponseMessageLength);

return buffer;
return buffer.Slice(2);
}

/// <summary>
/// Reads the specified number of discrete inputs as byte array. Each bit of the returned array represents a single discete input.
/// Reads the specified number of discrete inputs as byte array. Each bit of the returned array represents a single discrete input.
/// </summary>
/// <param name="unitIdentifier">The unit identifier is used to communicate via devices such as bridges, routers and gateways that use a single IP address to support multiple independent Modbus end units. Thus, the unit identifier is the address of a remote slave connected on a serial line or on other buses. Use the default values 0x00 or 0xFF when communicating to a Modbus server that is directly connected to a TCP/IP network.</param>
/// <param name="startingAddress">The discrete input start address for the read operation.</param>
Expand All @@ -276,12 +275,12 @@ public Span<byte> ReadDiscreteInputs(int unitIdentifier, int startingAddress, in
writer.Write(startingAddress_converted); // 08-09 Starting Address
writer.Write(quantity_converted); // 10-11 Quantity of Coils
}
}).Slice(2);
});

if (buffer.Length < (byte)Math.Ceiling((double)quantity_converted / 8))
if (buffer.Length < (byte)Math.Ceiling((double)quantity_converted / 8) + 2)
throw new ModbusException(ErrorMessage.ModbusClient_InvalidResponseMessageLength);

return buffer;
return buffer.Slice(2);
}

/// <summary>
Expand Down Expand Up @@ -328,12 +327,12 @@ public Span<byte> ReadInputRegisters(byte unitIdentifier, ushort startingAddress
writer.Write(startingAddress); // 08-09 Starting Address
writer.Write(quantity); // 10-11 Quantity of Input Registers
}
}).Slice(2);
});

if (buffer.Length < quantity * 2)
if (buffer.Length < quantity * 2 + 2)
throw new ModbusException(ErrorMessage.ModbusClient_InvalidResponseMessageLength);

return buffer;
return buffer.Slice(2);
}

/// <summary>
Expand Down Expand Up @@ -425,12 +424,42 @@ public void WriteSingleRegister(byte unitIdentifier, ushort registerAddress, byt
// class 2

/// <summary>
/// This methdod is not implemented.
/// Writes the provided <paramref name="values"/> to the coil registers.
/// </summary>
[Obsolete("This method is not implemented.")]
public void WriteMultipleCoils()
/// <param name="unitIdentifier">The unit identifier is used to communicate via devices such as bridges, routers and gateways that use a single IP address to support multiple independent Modbus end units. Thus, the unit identifier is the address of a remote slave connected on a serial line or on other buses. Use the default values 0x00 or 0xFF when communicating to a Modbus server that is directly connected to a TCP/IP network.</param>
/// <param name="startingAddress">The coil register start address for the write operation.</param>
/// <param name="values">The values to write to the server.</param>
public void WriteMultipleCoils(int unitIdentifier, int startingAddress, bool[] values)
{
throw new NotImplementedException();
var unitIdentifier_converted = ConvertUnitIdentifier(unitIdentifier);
var startingAddress_converted = ConvertUshort(startingAddress);
var quantityOfOutputs = values.Length;
var byteCount = (quantityOfOutputs + 7) / 8;
var convertedData = new byte[byteCount];

new BitArray(values)
.CopyTo(convertedData, 0);

TransceiveFrame(unitIdentifier_converted, ModbusFunctionCode.WriteMultipleCoils, writer =>
{
writer.Write((byte)ModbusFunctionCode.WriteMultipleCoils); // 07 Function Code

if (BitConverter.IsLittleEndian)
{
writer.WriteReverse(startingAddress_converted); // 08-09 Starting Address
writer.WriteReverse((ushort)quantityOfOutputs); // 10-11 Quantity of Outputs
}

else
{
writer.Write(startingAddress_converted); // 08-09 Starting Address
writer.Write((ushort)quantityOfOutputs); // 10-11 Quantity of Outputs
}

writer.Write((byte)byteCount); // 12 Byte Count = Outputs

writer.Write(convertedData);
});
}

/// <summary>
Expand Down Expand Up @@ -529,12 +558,12 @@ public Span<byte> ReadWriteMultipleRegisters(byte unitIdentifier, ushort readSta
writer.Write((byte)(writeQuantity * 2)); // 16 Byte Count = Quantity to Write * 2

writer.Write(dataset, 0, dataset.Length);
}).Slice(2);
});

if (buffer.Length < readQuantity * 2)
if (buffer.Length < readQuantity * 2 + 2)
throw new ModbusException(ErrorMessage.ModbusClient_InvalidResponseMessageLength);

return buffer;
return buffer.Slice(2);
}

/// <summary>
Expand Down
Loading

0 comments on commit 9445453

Please sign in to comment.