Skip to content

Commit

Permalink
Merge pull request #1 from wazzamatazz/initial-implementation
Browse files Browse the repository at this point in the history
Initial implementation
  • Loading branch information
wazzamatazz authored Aug 2, 2024
2 parents 84beec0 + 2fb3b1d commit 7c6eb62
Show file tree
Hide file tree
Showing 22 changed files with 3,812 additions and 63 deletions.
7 changes: 3 additions & 4 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@
<Import Project="$(ParentProject)" Condition=" '$(ParentProject)' != '' " />

<PropertyGroup>
<Authors>{{AUTHORS}}</Authors>
<Company>{{COMPANY_NAME}}</Company>
<PackageProjectUrl>https://github.com/{{GITHUB_USER_OR_ORG_NAME}}/{{REPO_NAME}}</PackageProjectUrl>
<Authors>Graham Watts</Authors>
<PackageProjectUrl>https://github.com/wazzamatazz/opcua-json-encoder</PackageProjectUrl>
<PackageOutputPath>$(MSBuildThisFileDirectory)artifacts\packages\$(Configuration)</PackageOutputPath>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<NeutralLanguage>en</NeutralLanguage>
<CopyrightStartYear>{{COPYRIGHT_START_YEAR}}</CopyrightStartYear>
<CopyrightStartYear>2024</CopyrightStartYear>
</PropertyGroup>

<!-- Set copyright notice based on CopyrightStartYear property. -->
Expand Down
7 changes: 3 additions & 4 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
<Project>

<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<EnablePackageVersionOverride>false</EnablePackageVersionOverride>
<NoWarn>NU1507;$(NoWarn)</NoWarn>
</PropertyGroup>

<ItemGroup>
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="Microsoft.NET.Test.SDK" Version="17.9.0" />
<PackageVersion Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" />
<PackageVersion Include="MSTest.TestAdapter" Version="3.3.1" />
<PackageVersion Include="MSTest.TestFramework" Version="3.3.1" />
<PackageVersion Include="System.Text.Json" Version="8.0.4" />
<PackageVersion Include="Workstation.UaClient" Version="3.2.3" />
</ItemGroup>

</Project>
</Project>
26 changes: 22 additions & 4 deletions RENAME-ME.sln → Jaahas.OpcUa.JsonEncoding.sln
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
VisualStudioVersion = 17.1.32407.343
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{10A2813D-C970-4F6F-9A59-94F7C972257F}"
ProjectSection(SolutionItems) = preProject
src\README.md = src\README.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{C4C50D71-6AAC-45A9-9257-5D02A42B61DC}"
ProjectSection(SolutionItems) = preProject
Expand All @@ -33,7 +30,6 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{ADFADB4B-0729-40E6-B241-6E1B89A8731C}"
ProjectSection(SolutionItems) = preProject
test\Directory.Build.props = test\Directory.Build.props
test\README.md = test\README.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{9EC81ADF-5CE2-4140-96BC-958CB9E0365C}"
Expand All @@ -42,10 +38,32 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{9EC8
samples\README.md = samples\README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jaahas.OpcUa.JsonEncoding", "src\Jaahas.OpcUa.JsonEncoding\Jaahas.OpcUa.JsonEncoding.csproj", "{4FA7C4AB-B9DC-4249-A934-B82801181248}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EncoderExample", "samples\EncoderExample\EncoderExample.csproj", "{5111A6DA-81F0-47CD-AEEB-C82397492625}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4FA7C4AB-B9DC-4249-A934-B82801181248}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4FA7C4AB-B9DC-4249-A934-B82801181248}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4FA7C4AB-B9DC-4249-A934-B82801181248}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4FA7C4AB-B9DC-4249-A934-B82801181248}.Release|Any CPU.Build.0 = Release|Any CPU
{5111A6DA-81F0-47CD-AEEB-C82397492625}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5111A6DA-81F0-47CD-AEEB-C82397492625}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5111A6DA-81F0-47CD-AEEB-C82397492625}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5111A6DA-81F0-47CD-AEEB-C82397492625}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{4FA7C4AB-B9DC-4249-A934-B82801181248} = {10A2813D-C970-4F6F-9A59-94F7C972257F}
{5111A6DA-81F0-47CD-AEEB-C82397492625} = {9EC81ADF-5CE2-4140-96BC-958CB9E0365C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {94DF2EE3-033D-46CD-9EC3-7BC808B13372}
EndGlobalSection
Expand Down
118 changes: 81 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,89 @@
# C# Repository Template
# OPC UA JSON Encoding for Workstation.UaClient

Repository template for a C# project.
This repository defines OPC UA JSON encoder and decoder classes for the [Workstation.UaClient](https://github.com/convertersystems/opc-ua-client) .NET OPC UA client library using System.Text.Json.

The encoder uses [Utf8JsonWriter](https://learn.microsoft.com/en-us/dotnet/api/system.text.json.utf8jsonwriter) for maximum performance. The decoder uses [JsonDocument](https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsondocument) to allow properties on OPC UA data types to be decoded from JSON in an order-agnostic way.


# Getting Started

- Create a new repository on GitHub and choose this repository as the template, or click on the _"Use this template"_ button on the repository home page.
- Rename the solution file in the root of the repository ([RENAME-ME.sln](/RENAME-ME.sln)).
- Update [Directory.Build.props](/Directory.Build.props) in the root folder and replace the placeholder values in the shared project properties (e.g. `{{COPYRIGHT_START_YEAR}}`).
- Update [build.cake](/build.cake) in the root folder and replace the `DefaultSolutionFile` constant at the start of the file with the name of your solution file.
- Create new library and application projects in the `src` folder.
- Create test and benchmarking projects in the `test` folder.
- Create example projects that demonstrate the library and application projects in the `samples` folder.


# Repository Structure

The repository is organised as follows:

- `[root]`
- `.editorconfig` - Code style rules (see [here](https://editorconfig.org/) for details).
- `.gitattributes`
- `.gitignore`
- `build.cake` - [Cake](https://cakebuild.net/) script for building the projects.
- `build.ps1` - PowerShell script to bootstrap and run the Cake script.
- `build.sh` - Bash shell script to bootstrap and run the Cake script.
- `Directory.Build.props` - Common MSBuild properties and targets (see [here](https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build) for details).
- `Directory.Build.targets` - Common MSBuild properties and targets (see [here](https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build) for details).
- `Directory.Packages.props` - Common NuGet package versions (see [here](https://devblogs.microsoft.com/nuget/introducing-central-package-management/) for details).
- `LICENSE` - Licence details.
- `README.md`
- `RENAME-ME.sln` - Visual Studio solution file.
- `[build]` - Resources for building the solution.
- `Copyright.props` - Sets the copyright message for all projects in the solution.
- `NetFX.targets` - Adds package references for building projects that target .NET Framework on non-Windows systems.
- `version.json` - Defines version numbers used when building the projects.
- `[samples]` - Example projects to demonstrate the usage of the repository libraries and applications.
- `Directory.Build.props` - Common MSBuild properties and targets related to example projects (see [here](https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build) for details).
- `[src]` - Source code for repository libraries and applications.
- `[test]` - Test and benchmarking projects.
- `Directory.Build.props` - Common MSBuild properties and targets related to test projects (see [here](https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build) for details).
Install the [Jaahas.OpcUa.JsonEncoding](https://www.nuget.org/packages/Jaahas.OpcUa.JsonEncoding) NuGet package.

The `JsonEncoder` and `JsonDecoder` classes implement the `Workstation.UaClient` `IEncoder` and `IDecoder` interfaces respectively. The `JsonEncodingProvider` class implements `IEncodingProvider`.

Example:

```csharp
var provider = new JsonEncodingProvider(encoderOptions: new JsonEncoderOptions() {
UseReversibleEncoding = false,
WriteIndented = true
});

using var ms = new MemoryStream();

using (var encoder = provider.CreateEncoder(ms, context: null, keepStreamOpen: true)) {
encoder.WriteRequest(new ReadRequest() {
MaxAge = 1000,
NodesToRead = [
new ReadValueId() {
NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.UInt32"),
AttributeId = AttributeIds.Value
},
new ReadValueId() {
NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.String"),
AttributeId = AttributeIds.Value
}
],
TimestampsToReturn = TimestampsToReturn.Both,
RequestHeader = new RequestHeader() {
AuditEntryId = "Test",
RequestHandle = 42
}
});
}

Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
```

The above code produces the following output using the [non-reversible form](https://reference.opcfoundation.org/Core/Part6/v105/docs/5.4.1) of the OPC UA JSON encoding:

```json
{
"RequestHeader": {
"AuthenticationToken": null,
"Timestamp": "0001-01-01T00:00:00",
"RequestHandle": 42,
"ReturnDiagnostics": 0,
"AuditEntryId": "Test",
"TimeoutHint": 0,
"AdditionalHeader": null
},
"MaxAge": 1000,
"TimestampsToReturn": "Both_2",
"NodesToRead": [
{
"NodeId": {
"IdType": 1,
"Id": "Demo.Static.Scalar.UInt32",
"Namespace": 2
},
"AttributeId": 13,
"IndexRange": null,
"DataEncoding": null
},
{
"NodeId": {
"IdType": 1,
"Id": "Demo.Static.Scalar.String",
"Namespace": 2
},
"AttributeId": 13,
"IndexRange": null,
"DataEncoding": null
}
]
}
```


# Building the Solution
Expand Down
2 changes: 1 addition & 1 deletion build.cake
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Use build.ps1 or build.sh to run the build script. Command line arguments are documented below.
///////////////////////////////////////////////////////////////////////////////////////////////////

const string DefaultSolutionFile = "./RENAME-ME.sln";
const string DefaultSolutionFile = "./Jaahas.OpcUa.JsonEncoding.sln";
const string VersionFile = "./build/version.json";

///////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
2 changes: 1 addition & 1 deletion build/version.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"Major": 0,
"Minor": 1,
"Patch": 0,
"PreRelease": "alpha"
"PreRelease": ""
}
14 changes: 14 additions & 0 deletions samples/EncoderExample/EncoderExample.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Jaahas.OpcUa.JsonEncoding\Jaahas.OpcUa.JsonEncoding.csproj" />
</ItemGroup>

</Project>
35 changes: 35 additions & 0 deletions samples/EncoderExample/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Text;

using Jaahas.OpcUa.JsonEncoding;

using Workstation.ServiceModel.Ua;

using var ms = new MemoryStream();

var provider = new JsonEncodingProvider(new JsonEncoderOptions() {
UseReversibleEncoding = false,
WriteIndented = true
});

using (var encoder = provider.CreateEncoder(ms, context: null, keepStreamOpen: true)) {
encoder.WriteRequest(new ReadRequest() {
MaxAge = 1000,
NodesToRead = [
new ReadValueId() {
NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.UInt32"),
AttributeId = AttributeIds.Value
},
new ReadValueId() {
NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.String"),
AttributeId = AttributeIds.Value
}
],
TimestampsToReturn = TimestampsToReturn.Both,
RequestHeader = new RequestHeader() {
AuditEntryId = "Test",
RequestHandle = 42
}
});
}

Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
51 changes: 51 additions & 0 deletions src/Jaahas.OpcUa.JsonEncoding/Jaahas.OpcUa.JsonEncoding.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.1;netstandard2.0</TargetFrameworks>
<LangVersion>10.0</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NeutralLanguage>en</NeutralLanguage>
<Description>OPC UA JSON encoder and decoder for Workstation.UaClient</Description>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Text.Json" />
<PackageReference Include="Workstation.UaClient" />
</ItemGroup>

<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>

<ItemGroup>
<None Update="StatusCodeExtensions.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>StatusCodeExtensions.generated.cs</LastGenOutput>
</None>
<Compile Update="StatusCodeExtensions.generated.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>StatusCodeExtensions.tt</DependentUpon>
</Compile>
</ItemGroup>

<ItemGroup>
<Compile Update="Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<EmbeddedResource Update="Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>

<ItemGroup>
<None Include="PACKAGE_README.md" Pack="true" PackagePath="README.md" />
</ItemGroup>

</Project>
Loading

0 comments on commit 7c6eb62

Please sign in to comment.